use of org.hipparchus.geometry.euclidean.threed.Rotation in project Orekit by CS-SI.
the class CelestialBodyPointed method getAttitude.
/**
* {@inheritDoc}
*/
public Attitude getAttitude(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) throws OrekitException {
final PVCoordinates satPV = pvProv.getPVCoordinates(date, celestialFrame);
// compute celestial references at the specified date
final PVCoordinates bodyPV = pointedBody.getPVCoordinates(date, celestialFrame);
final PVCoordinates pointing = new PVCoordinates(satPV, bodyPV);
final Vector3D pointingP = pointing.getPosition();
final double r2 = Vector3D.dotProduct(pointingP, pointingP);
// evaluate instant rotation axis due to sat and body motion only (no phasing yet)
final Vector3D rotAxisCel = new Vector3D(1 / r2, Vector3D.crossProduct(pointingP, pointing.getVelocity()));
// fix instant rotation to take phasing constraint into account
// (adding a rotation around pointing axis ensuring the motion of the phasing axis
// is constrained in the pointing-phasing plane)
final Vector3D v1 = Vector3D.crossProduct(rotAxisCel, phasingCel);
final Vector3D v2 = Vector3D.crossProduct(pointingP, phasingCel);
final double compensation = -Vector3D.dotProduct(v1, v2) / v2.getNormSq();
final Vector3D phasedRotAxisCel = new Vector3D(1.0, rotAxisCel, compensation, pointingP);
// compute transform from celestial frame to satellite frame
final Rotation celToSatRotation = new Rotation(pointingP, phasingCel, pointingSat, phasingSat);
// build transform combining rotation and instant rotation axis
Transform transform = new Transform(date, celToSatRotation, celToSatRotation.applyTo(phasedRotAxisCel));
if (frame != celestialFrame) {
// prepend transform from specified frame to celestial frame
transform = new Transform(date, frame.getTransformTo(celestialFrame, date), transform);
}
// build the attitude
return new Attitude(date, frame, transform.getRotation(), transform.getRotationRate(), transform.getRotationAcceleration());
}
use of org.hipparchus.geometry.euclidean.threed.Rotation in project Orekit by CS-SI.
the class Attitude method interpolate.
/**
* {@inheritDoc}
* <p>
* The interpolated instance is created by polynomial Hermite interpolation
* on Rodrigues vector ensuring rotation rate remains the exact derivative of rotation.
* </p>
* <p>
* As this implementation of interpolation is polynomial, it should be used only
* with small samples (about 10-20 points) in order to avoid <a
* href="http://en.wikipedia.org/wiki/Runge%27s_phenomenon">Runge's phenomenon</a>
* and numerical problems (including NaN appearing).
* </p>
* @exception OrekitException if the number of point is too small for interpolating
*/
public Attitude interpolate(final AbsoluteDate interpolationDate, final Stream<Attitude> sample) throws OrekitException {
final List<TimeStampedAngularCoordinates> datedPV = sample.map(attitude -> attitude.orientation).collect(Collectors.toList());
final TimeStampedAngularCoordinates interpolated = TimeStampedAngularCoordinates.interpolate(interpolationDate, AngularDerivativesFilter.USE_RR, datedPV);
return new Attitude(referenceFrame, interpolated);
}
use of org.hipparchus.geometry.euclidean.threed.Rotation in project Orekit by CS-SI.
the class ConstantThrustManeuverTest method testForwardAndBackward.
@Test
public void testForwardAndBackward() throws OrekitException {
final double isp = 318;
final double mass = 2500;
final double a = 24396159;
final double e = 0.72831215;
final double i = FastMath.toRadians(7);
final double omega = FastMath.toRadians(180);
final double OMEGA = FastMath.toRadians(261);
final double lv = 0;
final double duration = 3653.99;
final double f = 420;
final double delta = FastMath.toRadians(-7.4978);
final double alpha = FastMath.toRadians(351);
final AttitudeProvider law = new InertialProvider(new Rotation(new Vector3D(alpha, delta), Vector3D.PLUS_I));
final AbsoluteDate initDate = new AbsoluteDate(new DateComponents(2004, 01, 01), new TimeComponents(23, 30, 00.000), TimeScalesFactory.getUTC());
final Orbit orbit = new KeplerianOrbit(a, e, i, omega, OMEGA, lv, PositionAngle.TRUE, FramesFactory.getEME2000(), initDate, mu);
final SpacecraftState initialState = new SpacecraftState(orbit, law.getAttitude(orbit, orbit.getDate(), orbit.getFrame()), mass);
final AbsoluteDate fireDate = new AbsoluteDate(new DateComponents(2004, 01, 02), new TimeComponents(04, 15, 34.080), TimeScalesFactory.getUTC());
final ConstantThrustManeuver maneuver = new ConstantThrustManeuver(fireDate, duration, f, isp, Vector3D.PLUS_I);
Assert.assertEquals(f, maneuver.getThrust(), 1.0e-10);
Assert.assertEquals(isp, maneuver.getISP(), 1.0e-10);
double[][] tol = NumericalPropagator.tolerances(1.0, orbit, OrbitType.KEPLERIAN);
AdaptiveStepsizeIntegrator integrator1 = new DormandPrince853Integrator(0.001, 1000, tol[0], tol[1]);
integrator1.setInitialStepSize(60);
final NumericalPropagator propagator1 = new NumericalPropagator(integrator1);
propagator1.setInitialState(initialState);
propagator1.setAttitudeProvider(law);
propagator1.addForceModel(maneuver);
final SpacecraftState finalState = propagator1.propagate(fireDate.shiftedBy(3800));
AdaptiveStepsizeIntegrator integrator2 = new DormandPrince853Integrator(0.001, 1000, tol[0], tol[1]);
integrator2.setInitialStepSize(60);
final NumericalPropagator propagator2 = new NumericalPropagator(integrator2);
propagator2.setInitialState(finalState);
propagator2.setAttitudeProvider(law);
propagator2.addForceModel(maneuver);
final SpacecraftState recoveredState = propagator2.propagate(orbit.getDate());
final Vector3D refPosition = initialState.getPVCoordinates().getPosition();
final Vector3D recoveredPosition = recoveredState.getPVCoordinates().getPosition();
Assert.assertEquals(0.0, Vector3D.distance(refPosition, recoveredPosition), 30.0);
Assert.assertEquals(initialState.getMass(), recoveredState.getMass(), 1.5e-10);
}
use of org.hipparchus.geometry.euclidean.threed.Rotation in project Orekit by CS-SI.
the class UpdatableFrameTest method randomTransform.
private Transform randomTransform(Random random) {
Transform transform = Transform.IDENTITY;
for (int i = random.nextInt(10); i > 0; --i) {
if (random.nextBoolean()) {
Vector3D u = new Vector3D(random.nextDouble() * 1000.0, random.nextDouble() * 1000.0, random.nextDouble() * 1000.0);
transform = new Transform(transform.getDate(), transform, new Transform(transform.getDate(), u));
} else {
double q0 = random.nextDouble() * 2 - 1;
double q1 = random.nextDouble() * 2 - 1;
double q2 = random.nextDouble() * 2 - 1;
double q3 = random.nextDouble() * 2 - 1;
double q = FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
Rotation r = new Rotation(q0 / q, q1 / q, q2 / q, q3 / q, false);
transform = new Transform(transform.getDate(), transform, new Transform(transform.getDate(), r));
}
}
return transform;
}
use of org.hipparchus.geometry.euclidean.threed.Rotation in project Orekit by CS-SI.
the class TransformTest method testRotation.
@Test
public void testRotation() {
RandomGenerator rnd = new Well19937a(0x73d5554d99427af0l);
for (int i = 0; i < 10; ++i) {
Rotation r = randomRotation(rnd);
Vector3D axis = r.getAxis(RotationConvention.VECTOR_OPERATOR);
double angle = r.getAngle();
Transform transform = new Transform(AbsoluteDate.J2000_EPOCH, r);
for (int j = 0; j < 10; ++j) {
Vector3D a = new Vector3D(rnd.nextDouble(), rnd.nextDouble(), rnd.nextDouble());
Vector3D b = transform.transformVector(a);
Assert.assertEquals(Vector3D.angle(axis, a), Vector3D.angle(axis, b), 1.0e-14);
Vector3D aOrtho = Vector3D.crossProduct(axis, a);
Vector3D bOrtho = Vector3D.crossProduct(axis, b);
Assert.assertEquals(angle, Vector3D.angle(aOrtho, bOrtho), 1.0e-14);
Vector3D c = transform.transformPosition(a);
Assert.assertEquals(0, c.subtract(b).getNorm(), 1.0e-14);
}
}
}
Aggregations