List of usage examples for org.apache.commons.math3.analysis.interpolation FieldHermiteInterpolator FieldHermiteInterpolator
public FieldHermiteInterpolator()
From source file:org.orekit.utils.TimeStampedFieldAngularCoordinates.java
/** Interpolate angular coordinates. * <p>/*ww w .jav 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); }
From source file:org.orekit.utils.TimeStampedFieldPVCoordinates.java
/** Interpolate position-velocity. * <p>//from www . j a v a 2s . c om * The interpolated instance is created by polynomial Hermite interpolation * ensuring velocity remains the exact derivative of position. * </p> * <p> * Note that even if first time derivatives (velocities) * 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 positions. * </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 */ @SuppressWarnings("unchecked") public static <T extends RealFieldElement<T>> TimeStampedFieldPVCoordinates<T> interpolate( final AbsoluteDate date, final CartesianDerivativesFilter filter, final Collection<TimeStampedFieldPVCoordinates<T>> sample) { // get field properties final T prototype = sample.iterator().next().getPosition().getX(); final T zero = prototype.getField().getZero(); // set up an interpolator taking derivatives into account final FieldHermiteInterpolator<T> interpolator = new FieldHermiteInterpolator<T>(); // add sample points switch (filter) { case USE_P: // populate sample with position data, ignoring velocity for (final TimeStampedFieldPVCoordinates<T> datedPV : sample) { final FieldVector3D<T> position = datedPV.getPosition(); interpolator.addSamplePoint(zero.add(datedPV.getDate().durationFrom(date)), position.toArray()); } break; case USE_PV: // populate sample with position and velocity data for (final TimeStampedFieldPVCoordinates<T> datedPV : sample) { final FieldVector3D<T> position = datedPV.getPosition(); final FieldVector3D<T> velocity = datedPV.getVelocity(); interpolator.addSamplePoint(zero.add(datedPV.getDate().durationFrom(date)), position.toArray(), velocity.toArray()); } break; case USE_PVA: // populate sample with position, velocity and acceleration data for (final TimeStampedFieldPVCoordinates<T> datedPV : sample) { final FieldVector3D<T> position = datedPV.getPosition(); final FieldVector3D<T> velocity = datedPV.getVelocity(); final FieldVector3D<T> acceleration = datedPV.getAcceleration(); interpolator.addSamplePoint(zero.add(datedPV.getDate().durationFrom(date)), position.toArray(), velocity.toArray(), acceleration.toArray()); } break; default: // this should never happen throw new OrekitInternalError(null); } // interpolate final T[][] p = interpolator.derivatives(zero, 2); // build a new interpolated instance return new TimeStampedFieldPVCoordinates<T>(date, new FieldVector3D<T>(p[0]), new FieldVector3D<T>(p[1]), new FieldVector3D<T>(p[2])); }