Example usage for org.apache.commons.math3 Field getOne

List of usage examples for org.apache.commons.math3 Field getOne

Introduction

In this page you can find the example usage for org.apache.commons.math3 Field getOne.

Prototype

T getOne();

Source Link

Document

Get the multiplicative identity of the field.

Usage

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

/** Interpolate angular coordinates.
 * <p>/*  w w  w. ja  v  a 2  s  .co  m*/
 * The interpolated instance is created by polynomial Hermite interpolation
 * on Rodrigues vector ensuring FieldRotation<T> rate remains the exact derivative of FieldRotation<T>.
 * </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 FieldRotation<T>s
 * when this singularity is detected.
 * </p>
 * <p>
 * Note that even if first time derivatives (FieldRotation<T> rates)
 * 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 FieldRotation<T>s.
 * </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
 * @param <T> the type of the field elements
 * @return a new position-velocity, interpolated at specified date
 * @exception OrekitException if the number of point is too small for interpolating
 */
@SuppressWarnings("unchecked")
public static <T extends RealFieldElement<T>> TimeStampedFieldAngularCoordinates<T> interpolate(
        final AbsoluteDate date, final AngularDerivativesFilter filter,
        final Collection<TimeStampedFieldAngularCoordinates<T>> sample) throws OrekitException {

    // get field properties
    final Field<T> field = sample.iterator().next().getRotation().getQ0().getField();
    final T zero = field.getZero();
    final T one = field.getOne();

    // 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 FieldVector3D<T> meanRate;
    if (filter != AngularDerivativesFilter.USE_R) {
        FieldVector3D<T> sum = new FieldVector3D<T>(zero, zero, zero);
        for (final TimeStampedFieldAngularCoordinates<T> datedAC : sample) {
            sum = sum.add(datedAC.getRotationRate());
        }
        meanRate = new FieldVector3D<T>(1.0 / sample.size(), sum);
    } else {
        if (sample.size() < 2) {
            throw new OrekitException(OrekitMessages.NOT_ENOUGH_DATA_FOR_INTERPOLATION, sample.size());
        }
        FieldVector3D<T> sum = new FieldVector3D<T>(zero, zero, zero);
        TimeStampedFieldAngularCoordinates<T> previous = null;
        for (final TimeStampedFieldAngularCoordinates<T> datedAC : sample) {
            if (previous != null) {
                sum = sum.add(estimateRate(previous.getRotation(), datedAC.getRotation(),
                        datedAC.date.durationFrom(previous.getDate())));
            }
            previous = datedAC;
        }
        meanRate = new FieldVector3D<T>(1.0 / (sample.size() - 1), sum);
    }
    TimeStampedFieldAngularCoordinates<T> offset = new TimeStampedFieldAngularCoordinates<T>(date,
            new FieldRotation<T>(one, zero, zero, zero, false), meanRate,
            new FieldVector3D<T>(zero, zero, 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 FieldHermiteInterpolator<T> interpolator = new FieldHermiteInterpolator<T>();

        // add sample points
        final double[] previous = new double[] { 1.0, 0.0, 0.0, 0.0 };

        for (final TimeStampedFieldAngularCoordinates<T> ac : sample) {

            // remove linear offset from the current coordinates
            final T dt = zero.add(ac.date.durationFrom(date));
            final TimeStampedFieldAngularCoordinates<T> fixed = ac
                    .subtractOffset(offset.shiftedBy(dt.getReal()));

            final T[][] rodrigues = getModifiedRodrigues(fixed, previous, threshold);
            if (rodrigues == null) {
                // 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;
            }
            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 FieldAngularCoordinates<T>(
                    new FieldRotation<T>(new FieldVector3D<T>(one, zero, zero), zero.add(epsilon)),
                    new FieldVector3D<T>(zero, zero, zero), new FieldVector3D<T>(zero, zero, zero)));
        } else {
            // interpolation succeeded with the current offset
            final T[][] p = interpolator.derivatives(field.getZero(), 2);
            return createFromModifiedRodrigues(p, offset);
        }

    }

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

}