Example usage for org.apache.commons.math3.geometry.euclidean.threed Rotation IDENTITY

List of usage examples for org.apache.commons.math3.geometry.euclidean.threed Rotation IDENTITY

Introduction

In this page you can find the example usage for org.apache.commons.math3.geometry.euclidean.threed Rotation IDENTITY.

Prototype

Rotation IDENTITY

To view the source code for org.apache.commons.math3.geometry.euclidean.threed Rotation IDENTITY.

Click Source Link

Document

Identity rotation.

Usage

From source file:org.orekit.utils.AngularCoordinatesTest.java

@Test
public void testShiftWithoutAcceleration() throws OrekitException {
    double rate = 2 * FastMath.PI / (12 * 60);
    AngularCoordinates ac = new AngularCoordinates(Rotation.IDENTITY, new Vector3D(rate, Vector3D.PLUS_K),
            Vector3D.ZERO);//w w w.j  a  v a2 s.c o  m
    Assert.assertEquals(rate, ac.getRotationRate().getNorm(), 1.0e-10);
    double dt = 10.0;
    double alpha = rate * dt;
    AngularCoordinates shifted = ac.shiftedBy(dt);
    Assert.assertEquals(rate, shifted.getRotationRate().getNorm(), 1.0e-10);
    Assert.assertEquals(alpha, Rotation.distance(ac.getRotation(), shifted.getRotation()), 1.0e-15);

    Vector3D xSat = shifted.getRotation().applyInverseTo(Vector3D.PLUS_I);
    Assert.assertEquals(0.0, xSat.subtract(new Vector3D(FastMath.cos(alpha), FastMath.sin(alpha), 0)).getNorm(),
            1.0e-15);
    Vector3D ySat = shifted.getRotation().applyInverseTo(Vector3D.PLUS_J);
    Assert.assertEquals(0.0,
            ySat.subtract(new Vector3D(-FastMath.sin(alpha), FastMath.cos(alpha), 0)).getNorm(), 1.0e-15);
    Vector3D zSat = shifted.getRotation().applyInverseTo(Vector3D.PLUS_K);
    Assert.assertEquals(0.0, zSat.subtract(Vector3D.PLUS_K).getNorm(), 1.0e-15);

}

From source file:org.orekit.utils.AngularCoordinatesTest.java

@Test
public void testShiftWithAcceleration() throws OrekitException {
    double rate = 2 * FastMath.PI / (12 * 60);
    double acc = 0.001;
    double dt = 1.0;
    int n = 2000;
    final AngularCoordinates quadratic = new AngularCoordinates(Rotation.IDENTITY,
            new Vector3D(rate, Vector3D.PLUS_K), new Vector3D(acc, Vector3D.PLUS_J));
    final AngularCoordinates linear = new AngularCoordinates(quadratic.getRotation(),
            quadratic.getRotationRate(), Vector3D.ZERO);

    final FirstOrderDifferentialEquations ode = new FirstOrderDifferentialEquations() {
        public int getDimension() {
            return 4;
        }//from   ww w .ja  v  a  2  s .c  o m

        public void computeDerivatives(final double t, final double[] q, final double[] qDot) {
            final double omegaX = quadratic.getRotationRate().getX()
                    + t * quadratic.getRotationAcceleration().getX();
            final double omegaY = quadratic.getRotationRate().getY()
                    + t * quadratic.getRotationAcceleration().getY();
            final double omegaZ = quadratic.getRotationRate().getZ()
                    + t * quadratic.getRotationAcceleration().getZ();
            qDot[0] = 0.5 * MathArrays.linearCombination(-q[1], omegaX, -q[2], omegaY, -q[3], omegaZ);
            qDot[1] = 0.5 * MathArrays.linearCombination(q[0], omegaX, -q[3], omegaY, q[2], omegaZ);
            qDot[2] = 0.5 * MathArrays.linearCombination(q[3], omegaX, q[0], omegaY, -q[1], omegaZ);
            qDot[3] = 0.5 * MathArrays.linearCombination(-q[2], omegaX, q[1], omegaY, q[0], omegaZ);
        }
    };
    FirstOrderIntegrator integrator = new DormandPrince853Integrator(1.0e-6, 1.0, 1.0e-12, 1.0e-12);
    integrator.addStepHandler(new StepNormalizer(dt / n, new FixedStepHandler() {
        public void init(double t0, double[] y0, double t) {
        }

        public void handleStep(double t, double[] y, double[] yDot, boolean isLast) {
            Rotation reference = new Rotation(y[0], y[1], y[2], y[3], true);

            // the error in shiftedBy taking acceleration into account is cubic
            double expectedCubicError = 1.4544e-6 * t * t * t;
            Assert.assertEquals(expectedCubicError,
                    Rotation.distance(reference, quadratic.shiftedBy(t).getRotation()),
                    0.0001 * expectedCubicError);

            // the error in shiftedBy not taking acceleration into account is quadratic
            double expectedQuadraticError = 5.0e-4 * t * t;
            Assert.assertEquals(expectedQuadraticError,
                    Rotation.distance(reference, linear.shiftedBy(t).getRotation()),
                    0.00001 * expectedQuadraticError);

        }
    }));

    double[] y = new double[] { quadratic.getRotation().getQ0(), quadratic.getRotation().getQ1(),
            quadratic.getRotation().getQ2(), quadratic.getRotation().getQ3() };
    integrator.integrate(ode, 0, y, dt, y);

}

From source file:org.orekit.utils.AngularCoordinatesTest.java

@Test
public void testRodriguesSpecialCases() {

    // identity/* w w  w .  j  av a 2 s  .co  m*/
    double[][] identity = new AngularCoordinates(Rotation.IDENTITY, Vector3D.ZERO, Vector3D.ZERO)
            .getModifiedRodrigues(1.0);
    for (double[] row : identity) {
        for (double element : row) {
            Assert.assertEquals(0.0, element, Precision.SAFE_MIN);
        }
    }
    AngularCoordinates acId = AngularCoordinates.createFromModifiedRodrigues(identity);
    Assert.assertEquals(0.0, acId.getRotation().getAngle(), Precision.SAFE_MIN);
    Assert.assertEquals(0.0, acId.getRotationRate().getNorm(), Precision.SAFE_MIN);

    // PI angle rotation (which is singular for non-modified Rodrigues vector)
    RandomGenerator random = new Well1024a(0x2158523e6accb859l);
    for (int i = 0; i < 100; ++i) {
        Vector3D axis = randomVector(random, 1.0);
        AngularCoordinates original = new AngularCoordinates(new Rotation(axis, FastMath.PI), Vector3D.ZERO,
                Vector3D.ZERO);
        AngularCoordinates rebuilt = AngularCoordinates
                .createFromModifiedRodrigues(original.getModifiedRodrigues(1.0));
        Assert.assertEquals(FastMath.PI, rebuilt.getRotation().getAngle(), 1.0e-15);
        Assert.assertEquals(0.0, FastMath.sin(Vector3D.angle(axis, rebuilt.getRotation().getAxis())), 1.0e-15);
        Assert.assertEquals(0.0, rebuilt.getRotationRate().getNorm(), 1.0e-16);
    }

}

From source file:org.orekit.utils.TimeStampedAngularCoordinates.java

/** Interpolate angular coordinates.
 * <p>/*from ww  w  . ja  va2  s  .c  om*/
 * The interpolated instance is created by polynomial Hermite interpolation
 * on Rodrigues vector ensuring rotation rate remains the exact derivative of rotation.
 * </p>
 * <p>
 * This method is based on Sergei Tanygin's paper <a
 * href="http://www.agi.com/downloads/resources/white-papers/Attitude-interpolation.pdf">Attitude
 * Interpolation</a>, changing the norm of the vector to match the modified Rodrigues
 * vector as described in Malcolm D. Shuster's paper <a
 * href="http://www.ladispe.polito.it/corsi/Meccatronica/02JHCOR/2011-12/Slides/Shuster_Pub_1993h_J_Repsurv_scan.pdf">A
 * Survey of Attitude Representations</a>. This change avoids the singularity at .
 * There is still a singularity at 2, which is handled by slightly offsetting all rotations
 * when this singularity is detected.
 * </p>
 * <p>
 * Note that even if first and second time derivatives (rotation rates and acceleration)
 * from sample can be ignored, the interpolated instance always includes
 * interpolated derivatives. This feature can be used explicitly to
 * compute these derivatives when it would be too complex to compute them
 * from an analytical formula: just compute a few sample points from the
 * explicit formula and set the derivatives to zero in these sample points,
 * then use interpolation to add derivatives consistent with the rotations.
 * </p>
 * @param date interpolation date
 * @param filter filter for derivatives from the sample to use in interpolation
 * @param sample sample points on which interpolation should be done
 * @return a new position-velocity, interpolated at specified date
 * @exception OrekitException if the number of point is too small for interpolating
 */
public static TimeStampedAngularCoordinates interpolate(final AbsoluteDate date,
        final AngularDerivativesFilter filter, final Collection<TimeStampedAngularCoordinates> sample)
        throws OrekitException {

    // set up safety elements for 2 singularity avoidance
    final double epsilon = 2 * FastMath.PI / sample.size();
    final double threshold = FastMath.min(-(1.0 - 1.0e-4), -FastMath.cos(epsilon / 4));

    // set up a linear model canceling mean rotation rate
    final Vector3D meanRate;
    if (filter != AngularDerivativesFilter.USE_R) {
        Vector3D sum = Vector3D.ZERO;
        for (final TimeStampedAngularCoordinates datedAC : sample) {
            sum = sum.add(datedAC.getRotationRate());
        }
        meanRate = new Vector3D(1.0 / sample.size(), sum);
    } else {
        if (sample.size() < 2) {
            throw new OrekitException(OrekitMessages.NOT_ENOUGH_DATA_FOR_INTERPOLATION, sample.size());
        }
        Vector3D sum = Vector3D.ZERO;
        TimeStampedAngularCoordinates previous = null;
        for (final TimeStampedAngularCoordinates datedAC : sample) {
            if (previous != null) {
                sum = sum.add(estimateRate(previous.getRotation(), datedAC.getRotation(),
                        datedAC.date.durationFrom(previous.date)));
            }
            previous = datedAC;
        }
        meanRate = new Vector3D(1.0 / (sample.size() - 1), sum);
    }
    TimeStampedAngularCoordinates offset = new TimeStampedAngularCoordinates(date, Rotation.IDENTITY, meanRate,
            Vector3D.ZERO);

    boolean restart = true;
    for (int i = 0; restart && i < sample.size() + 2; ++i) {

        // offset adaptation parameters
        restart = false;

        // set up an interpolator taking derivatives into account
        final HermiteInterpolator interpolator = new HermiteInterpolator();

        // add sample points
        double sign = +1.0;
        Rotation previous = Rotation.IDENTITY;

        for (final TimeStampedAngularCoordinates ac : sample) {

            // remove linear offset from the current coordinates
            final double dt = ac.date.durationFrom(date);
            final TimeStampedAngularCoordinates fixed = ac.subtractOffset(offset.shiftedBy(dt));

            // make sure all interpolated points will be on the same branch
            final double dot = MathArrays.linearCombination(fixed.getRotation().getQ0(), previous.getQ0(),
                    fixed.getRotation().getQ1(), previous.getQ1(), fixed.getRotation().getQ2(),
                    previous.getQ2(), fixed.getRotation().getQ3(), previous.getQ3());
            sign = FastMath.copySign(1.0, dot * sign);
            previous = fixed.getRotation();

            // check modified Rodrigues vector singularity
            if (fixed.getRotation().getQ0() * sign < threshold) {
                // the sample point is close to a modified Rodrigues vector singularity
                // we need to change the linear offset model to avoid this
                restart = true;
                break;
            }

            final double[][] rodrigues = fixed.getModifiedRodrigues(sign);
            switch (filter) {
            case USE_RRA:
                // populate sample with rotation, rotation rate and acceleration data
                interpolator.addSamplePoint(dt, rodrigues[0], rodrigues[1], rodrigues[2]);
                break;
            case USE_RR:
                // populate sample with rotation and rotation rate data
                interpolator.addSamplePoint(dt, rodrigues[0], rodrigues[1]);
                break;
            case USE_R:
                // populate sample with rotation data only
                interpolator.addSamplePoint(dt, rodrigues[0]);
                break;
            default:
                // this should never happen
                throw new OrekitInternalError(null);
            }
        }

        if (restart) {
            // interpolation failed, some intermediate rotation was too close to 2
            // we need to offset all rotations to avoid the singularity
            offset = offset.addOffset(new AngularCoordinates(new Rotation(Vector3D.PLUS_I, epsilon),
                    Vector3D.ZERO, Vector3D.ZERO));
        } else {
            // interpolation succeeded with the current offset
            final DerivativeStructure zero = new DerivativeStructure(1, 2, 0, 0.0);
            final DerivativeStructure[] p = interpolator.value(zero);
            final AngularCoordinates ac = createFromModifiedRodrigues(
                    new double[][] { { p[0].getValue(), p[1].getValue(), p[2].getValue() },
                            { p[0].getPartialDerivative(1), p[1].getPartialDerivative(1),
                                    p[2].getPartialDerivative(1) },
                            { p[0].getPartialDerivative(2), p[1].getPartialDerivative(2),
                                    p[2].getPartialDerivative(2) } });
            return new TimeStampedAngularCoordinates(offset.getDate(), ac.getRotation(), ac.getRotationRate(),
                    ac.getRotationAcceleration()).addOffset(offset);
        }

    }

    // this should never happen
    throw new OrekitInternalError(null);

}

From source file:org.orekit.utils.TimeStampedAngularCoordinatesTest.java

@Test
public void testShift() throws OrekitException {
    double rate = 2 * FastMath.PI / (12 * 60);
    TimeStampedAngularCoordinates ac = new TimeStampedAngularCoordinates(AbsoluteDate.J2000_EPOCH,
            Rotation.IDENTITY, new Vector3D(rate, Vector3D.PLUS_K), Vector3D.ZERO);
    Assert.assertEquals(rate, ac.getRotationRate().getNorm(), 1.0e-10);
    double dt = 10.0;
    double alpha = rate * dt;
    TimeStampedAngularCoordinates shifted = ac.shiftedBy(dt);
    Assert.assertEquals(rate, shifted.getRotationRate().getNorm(), 1.0e-10);
    Assert.assertEquals(alpha, Rotation.distance(ac.getRotation(), shifted.getRotation()), 1.0e-10);

    Vector3D xSat = shifted.getRotation().applyInverseTo(Vector3D.PLUS_I);
    Assert.assertEquals(0.0, xSat.subtract(new Vector3D(FastMath.cos(alpha), FastMath.sin(alpha), 0)).getNorm(),
            1.0e-10);/*  w  ww .  j a v a  2  s. c o  m*/
    Vector3D ySat = shifted.getRotation().applyInverseTo(Vector3D.PLUS_J);
    Assert.assertEquals(0.0,
            ySat.subtract(new Vector3D(-FastMath.sin(alpha), FastMath.cos(alpha), 0)).getNorm(), 1.0e-10);
    Vector3D zSat = shifted.getRotation().applyInverseTo(Vector3D.PLUS_K);
    Assert.assertEquals(0.0, zSat.subtract(Vector3D.PLUS_K).getNorm(), 1.0e-10);

}

From source file:org.orekit.utils.TimeStampedAngularCoordinatesTest.java

@Test
public void testInterpolationNeedOffsetWrongRate() throws OrekitException {
    AbsoluteDate date = AbsoluteDate.GALILEO_EPOCH;
    double omega = 2.0 * FastMath.PI;
    TimeStampedAngularCoordinates reference = new TimeStampedAngularCoordinates(date, Rotation.IDENTITY,
            new Vector3D(omega, Vector3D.MINUS_K), Vector3D.ZERO);

    List<TimeStampedAngularCoordinates> sample = new ArrayList<TimeStampedAngularCoordinates>();
    for (double dt : new double[] { 0.0, 0.25, 0.5, 0.75, 1.0 }) {
        TimeStampedAngularCoordinates shifted = reference.shiftedBy(dt);
        sample.add(new TimeStampedAngularCoordinates(shifted.getDate(), shifted.getRotation(), Vector3D.ZERO,
                Vector3D.ZERO));/*from   ww  w. jav a 2 s  . c o  m*/
    }

    for (TimeStampedAngularCoordinates s : sample) {
        TimeStampedAngularCoordinates interpolated = TimeStampedAngularCoordinates.interpolate(s.getDate(),
                AngularDerivativesFilter.USE_RR, sample);
        Rotation r = interpolated.getRotation();
        Vector3D rate = interpolated.getRotationRate();
        Assert.assertEquals(0.0, Rotation.distance(s.getRotation(), r), 2.0e-14);
        Assert.assertEquals(0.0, Vector3D.distance(s.getRotationRate(), rate), 2.0e-13);
    }

}