use of org.orekit.frames.FieldTransform in project Orekit by CS-SI.
the class TurnAroundRangeAnalytic method theoreticalEvaluationValidation.
/**
* Added for validation
* @param iteration
* @param evaluation
* @param state
* @return
* @throws OrekitException
*/
protected EstimatedMeasurement<TurnAroundRange> theoreticalEvaluationValidation(final int iteration, final int evaluation, final SpacecraftState state) throws OrekitException {
// Stations & DSFactory attributes from parent TurnArounsRange class
final GroundStation masterGroundStation = getMasterStation();
final GroundStation slaveGroundStation = getSlaveStation();
int nbParams = 6;
final Map<String, Integer> indices = new HashMap<>();
for (ParameterDriver driver : getParametersDrivers()) {
// as one set only (they are combined together by the estimation engine)
if (driver.isSelected() && !indices.containsKey(driver.getName())) {
indices.put(driver.getName(), nbParams++);
}
}
final DSFactory dsFactory = new DSFactory(nbParams, 1);
final Field<DerivativeStructure> field = dsFactory.getDerivativeField();
final FieldVector3D<DerivativeStructure> zero = FieldVector3D.getZero(field);
// Coordinates of the spacecraft expressed as a derivative structure
final TimeStampedFieldPVCoordinates<DerivativeStructure> pvaDS = getCoordinates(state, 0, dsFactory);
// The path of the signal is divided in two legs.
// Leg1: Emission from master station to satellite in masterTauU seconds
// + Reflection from satellite to slave station in slaveTauD seconds
// Leg2: Reflection from slave station to satellite in slaveTauU seconds
// + Reflection from satellite to master station in masterTaudD seconds
// The measurement is considered to be time stamped at reception on ground
// by the master station. All times are therefore computed as backward offsets
// with respect to this reception time.
//
// Two intermediate spacecraft states are defined:
// - transitStateLeg2: State of the satellite when it bounced back the signal
// from slave station to master station during the 2nd leg
// - transitStateLeg1: State of the satellite when it bounced back the signal
// from master station to slave station during the 1st leg
// Compute propagation time for the 2nd leg of the signal path
// --
// Time difference between t (date of the measurement) and t' (date tagged in spacecraft state)
// (if state has already been set up to pre-compensate propagation delay,
// we will have delta = masterTauD + slaveTauU)
final AbsoluteDate measurementDate = getDate();
final FieldAbsoluteDate<DerivativeStructure> measurementDateDS = new FieldAbsoluteDate<>(field, measurementDate);
final double delta = measurementDate.durationFrom(state.getDate());
// transform between master station topocentric frame (east-north-zenith) and inertial frame expressed as DerivativeStructures
// The components of master station's position in offset frame are the 3 third derivative parameters
final FieldTransform<DerivativeStructure> masterToInert = masterGroundStation.getOffsetToInertial(state.getFrame(), measurementDateDS, dsFactory, indices);
// Master station PV in inertial frame at measurement date
final FieldVector3D<DerivativeStructure> QMaster = masterToInert.transformPosition(zero);
// Compute propagation times
final DerivativeStructure masterTauD = signalTimeOfFlight(pvaDS, QMaster, measurementDateDS);
// Elapsed time between state date t' and signal arrival to the transit state of the 2nd leg
final DerivativeStructure dtLeg2 = masterTauD.negate().add(delta);
// Transit state where the satellite reflected the signal from slave to master station
final SpacecraftState transitStateLeg2 = state.shiftedBy(dtLeg2.getValue());
// Transit state pv of leg2 (re)computed with derivative structures
final TimeStampedFieldPVCoordinates<DerivativeStructure> transitStateLeg2PV = pvaDS.shiftedBy(dtLeg2);
// transform between slave station topocentric frame (east-north-zenith) and inertial frame expressed as DerivativeStructures
// The components of slave station's position in offset frame are the 3 last derivative parameters
final FieldAbsoluteDate<DerivativeStructure> approxReboundDate = measurementDateDS.shiftedBy(-delta);
final FieldTransform<DerivativeStructure> slaveToInertApprox = slaveGroundStation.getOffsetToInertial(state.getFrame(), approxReboundDate, dsFactory, indices);
// Slave station PV in inertial frame at approximate rebound date on slave station
final TimeStampedFieldPVCoordinates<DerivativeStructure> QSlaveApprox = slaveToInertApprox.transformPVCoordinates(new TimeStampedFieldPVCoordinates<>(approxReboundDate, zero, zero, zero));
// Uplink time of flight from slave station to transit state of leg2
final DerivativeStructure slaveTauU = signalTimeOfFlight(QSlaveApprox, transitStateLeg2PV.getPosition(), transitStateLeg2PV.getDate());
// Total time of flight for leg 2
final DerivativeStructure tauLeg2 = masterTauD.add(slaveTauU);
// Compute propagation time for the 1st leg of the signal path
// --
// Absolute date of rebound of the signal to slave station
final FieldAbsoluteDate<DerivativeStructure> reboundDateDS = measurementDateDS.shiftedBy(tauLeg2.negate());
final FieldTransform<DerivativeStructure> slaveToInert = slaveGroundStation.getOffsetToInertial(state.getFrame(), reboundDateDS, dsFactory, indices);
// Slave station PV in inertial frame at rebound date on slave station
final FieldVector3D<DerivativeStructure> QSlave = slaveToInert.transformPosition(zero);
// Downlink time of flight from transitStateLeg1 to slave station at rebound date
final DerivativeStructure slaveTauD = signalTimeOfFlight(transitStateLeg2PV, QSlave, reboundDateDS);
// Elapsed time between state date t' and signal arrival to the transit state of the 1st leg
final DerivativeStructure dtLeg1 = dtLeg2.subtract(slaveTauU).subtract(slaveTauD);
// Transit state pv of leg2 (re)computed with derivative structures
final TimeStampedFieldPVCoordinates<DerivativeStructure> transitStateLeg1PV = pvaDS.shiftedBy(dtLeg1);
// transform between master station topocentric frame (east-north-zenith) and inertial frame expressed as DerivativeStructures
// The components of master station's position in offset frame are the 3 third derivative parameters
final FieldAbsoluteDate<DerivativeStructure> approxEmissionDate = measurementDateDS.shiftedBy(-2 * (slaveTauU.getValue() + masterTauD.getValue()));
final FieldTransform<DerivativeStructure> masterToInertApprox = masterGroundStation.getOffsetToInertial(state.getFrame(), approxEmissionDate, dsFactory, indices);
// Master station PV in inertial frame at approximate emission date
final TimeStampedFieldPVCoordinates<DerivativeStructure> QMasterApprox = masterToInertApprox.transformPVCoordinates(new TimeStampedFieldPVCoordinates<>(approxEmissionDate, zero, zero, zero));
// Uplink time of flight from master station to transit state of leg1
final DerivativeStructure masterTauU = signalTimeOfFlight(QMasterApprox, transitStateLeg1PV.getPosition(), transitStateLeg1PV.getDate());
// Total time of flight for leg 1
final DerivativeStructure tauLeg1 = slaveTauD.add(masterTauU);
// --
// Evaluate the turn-around range value and its derivatives
// --------------------------------------------------------
// The state we use to define the estimated measurement is a middle ground between the two transit states
// This is done to avoid calling "SpacecraftState.shiftedBy" function on long duration
// Thus we define the state at the date t" = date of rebound of the signal at the slave station
// Or t" = t -masterTauD -slaveTauU
// The iterative process in the estimation ensures that, after several iterations, the date stamped in the
// state S in input of this function will be close to t"
// Therefore we will shift state S by:
// - +slaveTauU to get transitStateLeg2
// - -slaveTauD to get transitStateLeg1
final EstimatedMeasurement<TurnAroundRange> estimated = new EstimatedMeasurement<>(this, iteration, evaluation, new SpacecraftState[] { transitStateLeg2.shiftedBy(-slaveTauU.getValue()) }, null);
// Turn-around range value = Total time of flight for the 2 legs divided by 2 and multiplied by c
final double cOver2 = 0.5 * Constants.SPEED_OF_LIGHT;
final DerivativeStructure turnAroundRange = (tauLeg2.add(tauLeg1)).multiply(cOver2);
estimated.setEstimatedValue(turnAroundRange.getValue());
// Turn-around range partial derivatives with respect to state
final double[] derivatives = turnAroundRange.getAllDerivatives();
estimated.setStateDerivatives(0, Arrays.copyOfRange(derivatives, 1, 7));
// (beware element at index 0 is the value, not a derivative)
for (final ParameterDriver driver : getParametersDrivers()) {
final Integer index = indices.get(driver.getName());
if (index != null) {
estimated.setParameterDerivatives(driver, derivatives[index + 1]);
}
}
// ----------
// VALIDATION: Using analytical version to compare
// -----------
// Computation of the value without DS
// ----------------------------------
// Time difference between t (date of the measurement) and t' (date tagged in spacecraft state)
// (if state has already been set up to pre-compensate propagation delay,
// we will have delta = masterTauD + slaveTauU)
// Master station PV at measurement date
final Transform masterTopoToInert = masterGroundStation.getOffsetToInertial(state.getFrame(), measurementDate);
final TimeStampedPVCoordinates QMt = masterTopoToInert.transformPVCoordinates(new TimeStampedPVCoordinates(measurementDate, PVCoordinates.ZERO));
// Slave station PV at measurement date
final Transform slaveTopoToInert = slaveGroundStation.getOffsetToInertial(state.getFrame(), measurementDate);
final TimeStampedPVCoordinates QSt = slaveTopoToInert.transformPVCoordinates(new TimeStampedPVCoordinates(measurementDate, PVCoordinates.ZERO));
// Downlink time of flight from master station at t to spacecraft at t'
final double tMd = signalTimeOfFlight(state.getPVCoordinates(), QMt.getPosition(), measurementDate);
// Transit state from which the satellite reflected the signal from slave to master station
final SpacecraftState state2 = state.shiftedBy(delta - tMd);
final AbsoluteDate transitDateLeg2 = transitStateLeg2.getDate();
// Slave station PV at transit state leg2 date
final Transform slaveTopoToInertTransitLeg2 = slaveGroundStation.getOffsetToInertial(state.getFrame(), transitDateLeg2);
final TimeStampedPVCoordinates QSdate2PV = slaveTopoToInertTransitLeg2.transformPVCoordinates(new TimeStampedPVCoordinates(transitDateLeg2, PVCoordinates.ZERO));
// Uplink time of flight from slave station to transit state leg2
final double tSu = signalTimeOfFlight(QSdate2PV, state2.getPVCoordinates().getPosition(), transitDateLeg2);
// Total time of flight for leg 2
final double t2 = tMd + tSu;
// Compute propagation time for the 1st leg of the signal path
// --
// Absolute date of arrival of the signal to slave station
final AbsoluteDate tQSA = measurementDate.shiftedBy(-t2);
// Slave station position in inertial frame at date tQSA
final Transform slaveTopoToInertArrivalDate = slaveGroundStation.getOffsetToInertial(state.getFrame(), tQSA);
final Vector3D QSA = slaveTopoToInertArrivalDate.transformPosition(Vector3D.ZERO);
// Dowlink time of flight from transitStateLeg1 to slave station at slaveStationArrivalDate
final double tSd = signalTimeOfFlight(state2.getPVCoordinates(), QSA, tQSA);
// Transit state from which the satellite reflected the signal from master to slave station
final SpacecraftState state1 = state.shiftedBy(delta - tMd - tSu - tSd);
final AbsoluteDate transitDateLeg1 = transitStateLeg1PV.getDate().toAbsoluteDate();
// Master station PV at transit state date of leg1
final Transform masterTopoToInertTransitLeg1 = masterGroundStation.getOffsetToInertial(state.getFrame(), transitDateLeg1);
final TimeStampedPVCoordinates QMdate1PV = masterTopoToInertTransitLeg1.transformPVCoordinates(new TimeStampedPVCoordinates(transitDateLeg1, PVCoordinates.ZERO));
// Uplink time of flight from master station to transit state leg1
final double tMu = signalTimeOfFlight(QMdate1PV, state1.getPVCoordinates().getPosition(), transitDateLeg1);
// Total time of flight for leg 1
final double t1 = tSd + tMu;
// Total time of flight
final double t = t1 + t2;
// Turn-around range value
final double TAR = t * cOver2;
// Diff with DS
final double dTAR = turnAroundRange.getValue() - TAR;
// tMd derivatives / state
// -----------------------
// QMt_PV = Master station PV at tmeas = t = signal arrival at master station
final Vector3D vel = state.getPVCoordinates().getVelocity();
final PVCoordinates QMt_PV = masterTopoToInert.transformPVCoordinates(PVCoordinates.ZERO);
final Vector3D QMt_V = QMt_PV.getVelocity();
final Vector3D pos2 = state2.getPVCoordinates().getPosition();
final Vector3D P2_QMt = QMt_PV.getPosition().subtract(pos2);
final double dMDown = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * tMd - Vector3D.dotProduct(P2_QMt, vel);
// derivatives of the downlink time of flight
final double dtMddPx = -P2_QMt.getX() / dMDown;
final double dtMddPy = -P2_QMt.getY() / dMDown;
final double dtMddPz = -P2_QMt.getZ() / dMDown;
final double dt = delta - tMd;
final double dtMddVx = dtMddPx * dt;
final double dtMddVy = dtMddPy * dt;
final double dtMddVz = dtMddPz * dt;
// From the DS
final double dtMddPxDS = masterTauD.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMddPyDS = masterTauD.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMddPzDS = masterTauD.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMddVxDS = masterTauD.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMddVyDS = masterTauD.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
final double dtMddVzDS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Difference
final double d_dtMddPx = dtMddPxDS - dtMddPx;
final double d_dtMddPy = dtMddPyDS - dtMddPy;
final double d_dtMddPz = dtMddPzDS - dtMddPz;
final double d_dtMddVx = dtMddVxDS - dtMddVx;
final double d_dtMddVy = dtMddVyDS - dtMddVy;
final double d_dtMddVz = dtMddVzDS - dtMddVz;
// tSu derivatives / state
// -----------------------
// QSt = slave station PV at tmeas = t = signal arrival at master station
// final Transform FSt = slaveStation.getOffsetFrame().getTransformTo(state.getFrame(), measurementDate);
// final PVCoordinates QSt = FSt.transformPVCoordinates(PVCoordinates.ZERO);
final Vector3D QSt_V = QSt.getVelocity();
// QSt2 = slave station PV at t-t2 = signal arrival at slave station
final PVCoordinates QSt2 = slaveTopoToInertArrivalDate.transformPVCoordinates(PVCoordinates.ZERO);
final Vector3D QSt2_P2 = pos2.subtract(QSt2.getPosition());
final double dSUp = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * tSu - Vector3D.dotProduct(QSt2_P2, QSt_V);
final double alphaSu = 1. / dSUp * QSt2_P2.dotProduct(QSt_V.subtract(vel));
final double dtSudPx = 1. / dSUp * QSt2_P2.getX() + alphaSu * dtMddPx;
final double dtSudPy = 1. / dSUp * QSt2_P2.getY() + alphaSu * dtMddPy;
final double dtSudPz = 1. / dSUp * QSt2_P2.getZ() + alphaSu * dtMddPz;
final double dtSudVx = dtSudPx * dt;
final double dtSudVy = dtSudPy * dt;
final double dtSudVz = dtSudPz * dt;
// From the DS
final double dtSudPxDS = slaveTauU.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSudPyDS = slaveTauU.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSudPzDS = slaveTauU.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSudVxDS = slaveTauU.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSudVyDS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
final double dtSudVzDS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Difference
final double d_dtSudPx = dtSudPxDS - dtSudPx;
final double d_dtSudPy = dtSudPyDS - dtSudPy;
final double d_dtSudPz = dtSudPzDS - dtSudPz;
final double d_dtSudVx = dtSudVxDS - dtSudVx;
final double d_dtSudVy = dtSudVyDS - dtSudVy;
final double d_dtSudVz = dtSudVzDS - dtSudVz;
// t2 derivatives / state
// -----------------------
// t2 = Time leg 2
double dt2dPx = dtSudPx + dtMddPx;
double dt2dPy = dtSudPy + dtMddPy;
double dt2dPz = dtSudPz + dtMddPz;
double dt2dVx = dtSudVx + dtMddVx;
double dt2dVy = dtSudVy + dtMddVy;
double dt2dVz = dtSudVz + dtMddVz;
// With DS
double dt2dPxDS = tauLeg2.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dt2dPyDS = tauLeg2.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dt2dPzDS = tauLeg2.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dt2dVxDS = tauLeg2.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
double dt2dVyDS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
double dt2dVzDS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Diff
final double d_dt2dPx = dt2dPxDS - dt2dPx;
final double d_dt2dPy = dt2dPyDS - dt2dPy;
final double d_dt2dPz = dt2dPzDS - dt2dPz;
final double d_dt2dVx = dt2dVxDS - dt2dVx;
final double d_dt2dVy = dt2dVyDS - dt2dVy;
final double d_dt2dVz = dt2dVzDS - dt2dVz;
// tSd derivatives / state
// -----------------------
final Vector3D pos1 = state1.getPVCoordinates().getPosition();
final Vector3D P1_QSt2 = QSt2.getPosition().subtract(pos1);
final double dSDown = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * tSd - Vector3D.dotProduct(P1_QSt2, vel);
// derivatives w/r to state
final double alphaSd = 1. / dSDown * P1_QSt2.dotProduct(vel.subtract(QSt_V));
final double dtSddPx = -1. / dSDown * P1_QSt2.getX() + alphaSd * dt2dPx;
final double dtSddPy = -1. / dSDown * P1_QSt2.getY() + alphaSd * dt2dPy;
final double dtSddPz = -1. / dSDown * P1_QSt2.getZ() + alphaSd * dt2dPz;
final double dt2 = delta - t2 - tSd;
final double dtSddVx = -dt2 / dSDown * P1_QSt2.getX() + alphaSd * dt2dVx;
final double dtSddVy = -dt2 / dSDown * P1_QSt2.getY() + alphaSd * dt2dVy;
final double dtSddVz = -dt2 / dSDown * P1_QSt2.getZ() + alphaSd * dt2dVz;
// From the DS
final double dtSddPxDS = slaveTauD.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSddPyDS = slaveTauD.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSddPzDS = slaveTauD.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSddVxDS = slaveTauD.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtSddVyDS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
final double dtSddVzDS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Difference
final double d_dtSddPx = dtSddPxDS - dtSddPx;
final double d_dtSddPy = dtSddPyDS - dtSddPy;
final double d_dtSddPz = dtSddPzDS - dtSddPz;
final double d_dtSddVx = dtSddVxDS - dtSddVx;
final double d_dtSddVy = dtSddVyDS - dtSddVy;
final double d_dtSddVz = dtSddVzDS - dtSddVz;
// tMu derivatives / state
// -----------------------
// QMt1 = Master station position at t1 = t - tau = signal departure from master station
final Transform FMt1 = masterGroundStation.getOffsetToInertial(state.getFrame(), measurementDate.shiftedBy(-t1 - t2));
final PVCoordinates QMt1 = FMt1.transformPVCoordinates(PVCoordinates.ZERO);
final Vector3D QMt1_P1 = pos1.subtract(QMt1.getPosition());
final double dMUp = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * tMu - Vector3D.dotProduct(QMt1_P1, QMt_V);
// derivatives w/r to state
final double alphaMu = 1. / dMUp * QMt1_P1.dotProduct(QMt_V.subtract(vel));
final double dtMudPx = 1. / dMUp * QMt1_P1.getX() + alphaMu * (dt2dPx + dtSddPx);
final double dtMudPy = 1. / dMUp * QMt1_P1.getY() + alphaMu * (dt2dPy + dtSddPy);
final double dtMudPz = 1. / dMUp * QMt1_P1.getZ() + alphaMu * (dt2dPz + dtSddPz);
final double dtMudVx = dt2 / dMUp * QMt1_P1.getX() + alphaMu * (dt2dVx + dtSddVx);
final double dtMudVy = dt2 / dMUp * QMt1_P1.getY() + alphaMu * (dt2dVy + dtSddVy);
final double dtMudVz = dt2 / dMUp * QMt1_P1.getZ() + alphaMu * (dt2dVz + dtSddVz);
// From the DS
final double dtMudPxDS = masterTauU.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMudPyDS = masterTauU.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMudPzDS = masterTauU.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMudVxDS = masterTauU.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtMudVyDS = masterTauU.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
final double dtMudVzDS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Difference
final double d_dtMudPx = dtMudPxDS - dtMudPx;
final double d_dtMudPy = dtMudPyDS - dtMudPy;
final double d_dtMudPz = dtMudPzDS - dtMudPz;
final double d_dtMudVx = dtMudVxDS - dtMudVx;
final double d_dtMudVy = dtMudVyDS - dtMudVy;
final double d_dtMudVz = dtMudVzDS - dtMudVz;
// t1 derivatives / state
// -----------------------
// t1 = Time leg 1
double dt1dPx = dtSddPx + dtMudPx;
double dt1dPy = dtSddPy + dtMudPy;
double dt1dPz = dtSddPz + dtMudPz;
double dt1dVx = dtSddVx + dtMudVx;
double dt1dVy = dtSddVy + dtMudVy;
double dt1dVz = dtSddVz + dtMudVz;
// With DS
double dt1dPxDS = tauLeg1.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dt1dPyDS = tauLeg1.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dt1dPzDS = tauLeg1.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dt1dVxDS = tauLeg1.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
double dt1dVyDS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
double dt1dVzDS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Diff
final double d_dt1dPx = dt1dPxDS - dt1dPx;
final double d_dt1dPy = dt1dPyDS - dt1dPy;
final double d_dt1dPz = dt1dPzDS - dt1dPz;
final double d_dt1dVx = dt1dVxDS - dt1dVx;
final double d_dt1dVy = dt1dVyDS - dt1dVy;
final double d_dt1dVz = dt1dVzDS - dt1dVz;
// TAR derivatives / state
// -----------------------
// R = TAR
double dRdPx = (dt1dPx + dt2dPx) * cOver2;
double dRdPy = (dt1dPy + dt2dPy) * cOver2;
double dRdPz = (dt1dPz + dt2dPz) * cOver2;
double dRdVx = (dt1dVx + dt2dVx) * cOver2;
double dRdVy = (dt1dVy + dt2dVy) * cOver2;
double dRdVz = (dt1dVz + dt2dVz) * cOver2;
// With DS
double dRdPxDS = turnAroundRange.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dRdPyDS = turnAroundRange.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dRdPzDS = turnAroundRange.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
double dRdVxDS = turnAroundRange.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
double dRdVyDS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
double dRdVzDS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
// Diff
final double d_dRdPx = dRdPxDS - dRdPx;
final double d_dRdPy = dRdPyDS - dRdPy;
final double d_dRdPz = dRdPzDS - dRdPz;
final double d_dRdVx = dRdVxDS - dRdVx;
final double d_dRdVy = dRdVyDS - dRdVy;
final double d_dRdVz = dRdVzDS - dRdVz;
// tMd derivatives / stations
// --------------------------
// Master station rotation and angular speed at tmeas
final AngularCoordinates acM = masterTopoToInert.getAngular().revert();
final Rotation rotationMasterTopoToInert = acM.getRotation();
final Vector3D OmegaM = acM.getRotationRate();
// Slave station rotation and angular speed at tmeas
final AngularCoordinates acS = slaveTopoToInert.getAngular().revert();
final Rotation rotationSlaveTopoToInert = acS.getRotation();
final Vector3D OmegaS = acS.getRotationRate();
// Master station - Inertial frame
final double dtMddQMx_I = P2_QMt.getX() / dMDown;
final double dtMddQMy_I = P2_QMt.getY() / dMDown;
final double dtMddQMz_I = P2_QMt.getZ() / dMDown;
// Slave station - Inertial frame
final double dtMddQSx_I = 0.;
final double dtMddQSy_I = 0.;
final double dtMddQSz_I = 0.;
// Topo frames
final Vector3D dtMddQM = rotationMasterTopoToInert.applyTo(new Vector3D(dtMddQMx_I, dtMddQMy_I, dtMddQMz_I));
final Vector3D dtMddQS = rotationSlaveTopoToInert.applyTo(new Vector3D(dtMddQSx_I, dtMddQSy_I, dtMddQSz_I));
// With DS
double dtMddQMx_DS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dtMddQMy_DS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dtMddQMz_DS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dtMddQSx_DS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dtMddQSy_DS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dtMddQSz_DS = masterTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dtMddQMx = dtMddQMx_DS - dtMddQM.getX();
final double d_dtMddQMy = dtMddQMy_DS - dtMddQM.getY();
final double d_dtMddQMz = dtMddQMz_DS - dtMddQM.getZ();
final double d_dtMddQSx = dtMddQSx_DS - dtMddQS.getX();
final double d_dtMddQSy = dtMddQSy_DS - dtMddQS.getY();
final double d_dtMddQSz = dtMddQSz_DS - dtMddQS.getZ();
// tSu derivatives / stations
// --------------------------
// Master station - Inertial frame
final double dtSudQMx_I = dtMddQMx_I * alphaSu;
final double dtSudQMy_I = dtMddQMy_I * alphaSu;
final double dtSudQMz_I = dtMddQMz_I * alphaSu;
// Slave station - Inertial frame
final double dtSudQSx_I = 1. / dSUp * QSt2_P2.dotProduct(Vector3D.MINUS_I.add(OmegaS.crossProduct(Vector3D.PLUS_I).scalarMultiply(t2)));
final double dtSudQSy_I = 1. / dSUp * QSt2_P2.dotProduct(Vector3D.MINUS_J.add(OmegaS.crossProduct(Vector3D.PLUS_J).scalarMultiply(t2)));
final double dtSudQSz_I = 1. / dSUp * QSt2_P2.dotProduct(Vector3D.MINUS_K.add(OmegaS.crossProduct(Vector3D.PLUS_K).scalarMultiply(t2)));
// Topo frames
final Vector3D dtSudQM = rotationMasterTopoToInert.applyTo(new Vector3D(dtSudQMx_I, dtSudQMy_I, dtSudQMz_I));
final Vector3D dtSudQS = rotationSlaveTopoToInert.applyTo(new Vector3D(dtSudQSx_I, dtSudQSy_I, dtSudQSz_I));
// With DS
double dtSudQMx_DS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dtSudQMy_DS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dtSudQMz_DS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dtSudQSx_DS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dtSudQSy_DS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dtSudQSz_DS = slaveTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dtSudQMx = dtSudQMx_DS - dtSudQM.getX();
final double d_dtSudQMy = dtSudQMy_DS - dtSudQM.getY();
final double d_dtSudQMz = dtSudQMz_DS - dtSudQM.getZ();
final double d_dtSudQSx = dtSudQSx_DS - dtSudQS.getX();
final double d_dtSudQSy = dtSudQSy_DS - dtSudQS.getY();
final double d_dtSudQSz = dtSudQSz_DS - dtSudQS.getZ();
// t2 derivatives / stations
// --------------------------
final double dt2dQMx_I = dtMddQMx_I + dtSudQMx_I;
final double dt2dQMy_I = dtMddQMy_I + dtSudQMy_I;
final double dt2dQMz_I = dtMddQMz_I + dtSudQMz_I;
final double dt2dQSx_I = dtMddQSx_I + dtSudQSx_I;
final double dt2dQSy_I = dtMddQSy_I + dtSudQSy_I;
final double dt2dQSz_I = dtMddQSz_I + dtSudQSz_I;
final Vector3D dt2dQM = dtSudQM.add(dtMddQM);
final Vector3D dt2dQS = dtSudQS.add(dtMddQS);
// With DS
double dt2dQMx_DS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dt2dQMy_DS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dt2dQMz_DS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dt2dQSx_DS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dt2dQSy_DS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dt2dQSz_DS = tauLeg2.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dt2dQMx = dt2dQMx_DS - dt2dQM.getX();
final double d_dt2dQMy = dt2dQMy_DS - dt2dQM.getY();
final double d_dt2dQMz = dt2dQMz_DS - dt2dQM.getZ();
final double d_dt2dQSx = dt2dQSx_DS - dt2dQS.getX();
final double d_dt2dQSy = dt2dQSy_DS - dt2dQS.getY();
final double d_dt2dQSz = dt2dQSz_DS - dt2dQS.getZ();
// tSd derivatives / stations
// --------------------------
// Master station - Inertial frame
final double dtSddQMx_I = dt2dQMx_I * alphaSd;
final double dtSddQMy_I = dt2dQMy_I * alphaSd;
final double dtSddQMz_I = dt2dQMz_I * alphaSd;
// Slave station - Inertial frame
final double dtSddQSx_I = dt2dQSx_I * alphaSd + 1. / dSDown * P1_QSt2.dotProduct(Vector3D.PLUS_I.subtract(OmegaS.crossProduct(Vector3D.PLUS_I).scalarMultiply(t2)));
final double dtSddQSy_I = dt2dQSy_I * alphaSd + 1. / dSDown * P1_QSt2.dotProduct(Vector3D.PLUS_J.subtract(OmegaS.crossProduct(Vector3D.PLUS_J).scalarMultiply(t2)));
final double dtSddQSz_I = dt2dQSz_I * alphaSd + 1. / dSDown * P1_QSt2.dotProduct(Vector3D.PLUS_K.subtract(OmegaS.crossProduct(Vector3D.PLUS_K).scalarMultiply(t2)));
// Topo frames
final Vector3D dtSddQM = rotationMasterTopoToInert.applyTo(new Vector3D(dtSddQMx_I, dtSddQMy_I, dtSddQMz_I));
final Vector3D dtSddQS = rotationSlaveTopoToInert.applyTo(new Vector3D(dtSddQSx_I, dtSddQSy_I, dtSddQSz_I));
// With DS
double dtSddQMx_DS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dtSddQMy_DS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dtSddQMz_DS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dtSddQSx_DS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dtSddQSy_DS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dtSddQSz_DS = slaveTauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dtSddQMx = dtSddQMx_DS - dtSddQM.getX();
final double d_dtSddQMy = dtSddQMy_DS - dtSddQM.getY();
final double d_dtSddQMz = dtSddQMz_DS - dtSddQM.getZ();
final double d_dtSddQSx = dtSddQSx_DS - dtSddQS.getX();
final double d_dtSddQSy = dtSddQSy_DS - dtSddQS.getY();
final double d_dtSddQSz = dtSddQSz_DS - dtSddQS.getZ();
// tMu derivatives / stations
// --------------------------
// Master station - Inertial frame
final double dtMudQMx_I = -QMt1_P1.getX() / dMUp + alphaMu * (dt2dQMx_I + dtSddQMx_I) + t / dMUp * QMt1_P1.dotProduct(OmegaM.crossProduct(Vector3D.PLUS_I));
final double dtMudQMy_I = -QMt1_P1.getY() / dMUp + alphaMu * (dt2dQMy_I + dtSddQMy_I) + t / dMUp * QMt1_P1.dotProduct(OmegaM.crossProduct(Vector3D.PLUS_J));
final double dtMudQMz_I = -QMt1_P1.getZ() / dMUp + alphaMu * (dt2dQMz_I + dtSddQMz_I) + t / dMUp * QMt1_P1.dotProduct(OmegaM.crossProduct(Vector3D.PLUS_K));
// Slave station - Inertial frame
final double dtMudQSx_I = alphaMu * (dt2dQSx_I + dtSddQSx_I);
final double dtMudQSy_I = alphaMu * (dt2dQSy_I + dtSddQSy_I);
final double dtMudQSz_I = alphaMu * (dt2dQSz_I + dtSddQSz_I);
// Topo frames
final Vector3D dtMudQM = rotationMasterTopoToInert.applyTo(new Vector3D(dtMudQMx_I, dtMudQMy_I, dtMudQMz_I));
final Vector3D dtMudQS = rotationSlaveTopoToInert.applyTo(new Vector3D(dtMudQSx_I, dtMudQSy_I, dtMudQSz_I));
// With DS
double dtMudQMx_DS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dtMudQMy_DS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dtMudQMz_DS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dtMudQSx_DS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dtMudQSy_DS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dtMudQSz_DS = masterTauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dtMudQMx = dtMudQMx_DS - dtMudQM.getX();
final double d_dtMudQMy = dtMudQMy_DS - dtMudQM.getY();
final double d_dtMudQMz = dtMudQMz_DS - dtMudQM.getZ();
final double d_dtMudQSx = dtMudQSx_DS - dtMudQS.getX();
final double d_dtMudQSy = dtMudQSy_DS - dtMudQS.getY();
final double d_dtMudQSz = dtMudQSz_DS - dtMudQS.getZ();
// t1 derivatives / stations
// --------------------------
final Vector3D dt1dQM = dtMudQM.add(dtSddQM);
final Vector3D dt1dQS = dtMudQS.add(dtSddQS);
// With DS
double dt1dQMx_DS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dt1dQMy_DS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dt1dQMz_DS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dt1dQSx_DS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dt1dQSy_DS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dt1dQSz_DS = tauLeg1.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dt1dQMx = dt1dQMx_DS - dt1dQM.getX();
final double d_dt1dQMy = dt1dQMy_DS - dt1dQM.getY();
final double d_dt1dQMz = dt1dQMz_DS - dt1dQM.getZ();
final double d_dt1dQSx = dt1dQSx_DS - dt1dQS.getX();
final double d_dt1dQSy = dt1dQSy_DS - dt1dQS.getY();
final double d_dt1dQSz = dt1dQSz_DS - dt1dQS.getZ();
// TAR derivatives / stations
// --------------------------
final Vector3D dRdQM = (dt1dQM.add(dt2dQM)).scalarMultiply(cOver2);
final Vector3D dRdQS = (dt1dQS.add(dt2dQS)).scalarMultiply(cOver2);
// With DS
double dRdQMx_DS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
double dRdQMy_DS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
double dRdQMz_DS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
double dRdQSx_DS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
double dRdQSy_DS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
double dRdQSz_DS = turnAroundRange.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dRdQMx = dRdQMx_DS - dRdQM.getX();
final double d_dRdQMy = dRdQMy_DS - dRdQM.getY();
final double d_dRdQMz = dRdQMz_DS - dRdQM.getZ();
final double d_dRdQSx = dRdQSx_DS - dRdQS.getX();
final double d_dRdQSy = dRdQSy_DS - dRdQS.getY();
final double d_dRdQSz = dRdQSz_DS - dRdQS.getZ();
// Print results to avoid warning
final boolean printResults = false;
if (printResults) {
System.out.println("dTAR = " + dTAR);
System.out.println("d_dtMddPx = " + d_dtMddPx);
System.out.println("d_dtMddPy = " + d_dtMddPy);
System.out.println("d_dtMddPz = " + d_dtMddPz);
System.out.println("d_dtMddVx = " + d_dtMddVx);
System.out.println("d_dtMddVy = " + d_dtMddVy);
System.out.println("d_dtMddVz = " + d_dtMddVz);
System.out.println("d_dtSudPx = " + d_dtSudPx);
System.out.println("d_dtSudPy = " + d_dtSudPy);
System.out.println("d_dtSudPz = " + d_dtSudPz);
System.out.println("d_dtSudVx = " + d_dtSudVx);
System.out.println("d_dtSudVy = " + d_dtSudVy);
System.out.println("d_dtSudVz = " + d_dtSudVz);
System.out.println("d_dt2dPx = " + d_dt2dPx);
System.out.println("d_dt2dPy = " + d_dt2dPy);
System.out.println("d_dt2dPz = " + d_dt2dPz);
System.out.println("d_dt2dVx = " + d_dt2dVx);
System.out.println("d_dt2dVy = " + d_dt2dVy);
System.out.println("d_dt2dVz = " + d_dt2dVz);
System.out.println("d_dtSddPx = " + d_dtSddPx);
System.out.println("d_dtSddPy = " + d_dtSddPy);
System.out.println("d_dtSddPz = " + d_dtSddPz);
System.out.println("d_dtSddVx = " + d_dtSddVx);
System.out.println("d_dtSddVy = " + d_dtSddVy);
System.out.println("d_dtSddVz = " + d_dtSddVz);
System.out.println("d_dtMudPx = " + d_dtMudPx);
System.out.println("d_dtMudPy = " + d_dtMudPy);
System.out.println("d_dtMudPz = " + d_dtMudPz);
System.out.println("d_dtMudVx = " + d_dtMudVx);
System.out.println("d_dtMudVy = " + d_dtMudVy);
System.out.println("d_dtMudVz = " + d_dtMudVz);
System.out.println("d_dt1dPx = " + d_dt1dPx);
System.out.println("d_dt1dPy = " + d_dt1dPy);
System.out.println("d_dt1dPz = " + d_dt1dPz);
System.out.println("d_dt1dVx = " + d_dt1dVx);
System.out.println("d_dt1dVy = " + d_dt1dVy);
System.out.println("d_dt1dVz = " + d_dt1dVz);
System.out.println("d_dRdPx = " + d_dRdPx);
System.out.println("d_dRdPy = " + d_dRdPy);
System.out.println("d_dRdPz = " + d_dRdPz);
System.out.println("d_dRdVx = " + d_dRdVx);
System.out.println("d_dRdVy = " + d_dRdVy);
System.out.println("d_dRdVz = " + d_dRdVz);
System.out.println("d_dtMddQMx = " + d_dtMddQMx);
System.out.println("d_dtMddQMy = " + d_dtMddQMy);
System.out.println("d_dtMddQMz = " + d_dtMddQMz);
System.out.println("d_dtMddQSx = " + d_dtMddQSx);
System.out.println("d_dtMddQSy = " + d_dtMddQSy);
System.out.println("d_dtMddQSz = " + d_dtMddQSz);
System.out.println("d_dtSudQMx = " + d_dtSudQMx);
System.out.println("d_dtSudQMy = " + d_dtSudQMy);
System.out.println("d_dtSudQMz = " + d_dtSudQMz);
System.out.println("d_dtSudQSx = " + d_dtSudQSx);
System.out.println("d_dtSudQSy = " + d_dtSudQSy);
System.out.println("d_dtSudQSz = " + d_dtSudQSz);
System.out.println("d_dt2dQMx = " + d_dt2dQMx);
System.out.println("d_dt2dQMy = " + d_dt2dQMy);
System.out.println("d_dt2dQMz = " + d_dt2dQMz);
System.out.println("d_dt2dQSx = " + d_dt2dQSx);
System.out.println("d_dt2dQSy = " + d_dt2dQSy);
System.out.println("d_dt2dQSz = " + d_dt2dQSz);
System.out.println("d_dtSddQMx = " + d_dtSddQMx);
System.out.println("d_dtSddQMy = " + d_dtSddQMy);
System.out.println("d_dtSddQMz = " + d_dtSddQMz);
System.out.println("d_dtSddQSx = " + d_dtSddQSx);
System.out.println("d_dtSddQSy = " + d_dtSddQSy);
System.out.println("d_dtSddQSz = " + d_dtSddQSz);
System.out.println("d_dtMudQMx = " + d_dtMudQMx);
System.out.println("d_dtMudQMy = " + d_dtMudQMy);
System.out.println("d_dtMudQMz = " + d_dtMudQMz);
System.out.println("d_dtMudQSx = " + d_dtMudQSx);
System.out.println("d_dtMudQSy = " + d_dtMudQSy);
System.out.println("d_dtMudQSz = " + d_dtMudQSz);
System.out.println("d_dt1dQMx = " + d_dt1dQMx);
System.out.println("d_dt1dQMy = " + d_dt1dQMy);
System.out.println("d_dt1dQMz = " + d_dt1dQMz);
System.out.println("d_dt1dQSx = " + d_dt1dQSx);
System.out.println("d_dt1dQSy = " + d_dt1dQSy);
System.out.println("d_dt1dQSz = " + d_dt1dQSz);
System.out.println("d_dRdQMx = " + d_dRdQMx);
System.out.println("d_dRdQMy = " + d_dRdQMy);
System.out.println("d_dRdQMz = " + d_dRdQMz);
System.out.println("d_dRdQSx = " + d_dRdQSx);
System.out.println("d_dRdQSy = " + d_dRdQSy);
System.out.println("d_dRdQSz = " + d_dRdQSz);
}
// Dummy return
return estimated;
}
use of org.orekit.frames.FieldTransform in project Orekit by CS-SI.
the class EstimationTestUtils method geoStationnaryContext.
public static Context geoStationnaryContext(final String dataRoot) throws OrekitException {
Utils.setDataRoot(dataRoot);
Context context = new Context();
context.conventions = IERSConventions.IERS_2010;
context.utc = TimeScalesFactory.getUTC();
context.ut1 = TimeScalesFactory.getUT1(context.conventions, true);
context.displacements = new StationDisplacement[0];
String Myframename = "MyEarthFrame";
final AbsoluteDate datedef = new AbsoluteDate(2000, 1, 1, 12, 0, 0.0, context.utc);
final double omega = Constants.WGS84_EARTH_ANGULAR_VELOCITY;
final Vector3D rotationRate = new Vector3D(0.0, 0.0, omega);
TransformProvider MyEarthFrame = new TransformProvider() {
private static final long serialVersionUID = 1L;
public Transform getTransform(final AbsoluteDate date) {
final double rotationduration = date.durationFrom(datedef);
final Vector3D alpharot = new Vector3D(rotationduration, rotationRate);
final Rotation rotation = new Rotation(Vector3D.PLUS_K, -alpharot.getZ(), RotationConvention.VECTOR_OPERATOR);
return new Transform(date, rotation, rotationRate);
}
public <T extends RealFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
final T rotationduration = date.durationFrom(datedef);
final FieldVector3D<T> alpharot = new FieldVector3D<>(rotationduration, rotationRate);
final FieldRotation<T> rotation = new FieldRotation<>(FieldVector3D.getPlusK(date.getField()), alpharot.getZ().negate(), RotationConvention.VECTOR_OPERATOR);
return new FieldTransform<>(date, rotation, new FieldVector3D<>(date.getField(), rotationRate));
}
};
Frame FrameTest = new Frame(FramesFactory.getEME2000(), MyEarthFrame, Myframename, true);
// Earth is spherical, rotating in one sidereal day
context.earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, 0.0, FrameTest);
context.sun = CelestialBodyFactory.getSun();
context.moon = CelestialBodyFactory.getMoon();
context.radiationSensitive = new IsotropicRadiationClassicalConvention(2.0, 0.2, 0.8);
context.dragSensitive = new IsotropicDrag(2.0, 1.2);
GravityFieldFactory.addPotentialCoefficientsReader(new GRGSFormatReader("grim4s4_gr", true));
AstronomicalAmplitudeReader aaReader = new AstronomicalAmplitudeReader("hf-fes2004.dat", 5, 2, 3, 1.0);
DataProvidersManager.getInstance().feed(aaReader.getSupportedNames(), aaReader);
Map<Integer, Double> map = aaReader.getAstronomicalAmplitudesMap();
GravityFieldFactory.addOceanTidesReader(new FESCHatEpsilonReader("fes2004-7x7.dat", 0.01, FastMath.toRadians(1.0), OceanLoadDeformationCoefficients.IERS_2010, map));
context.gravity = GravityFieldFactory.getNormalizedProvider(20, 20);
// semimajor axis for a geostationnary satellite
double da = FastMath.cbrt(context.gravity.getMu() / (omega * omega));
// context.stations = Arrays.asList(context.createStation( 0.0, 0.0, 0.0, "Lat0_Long0"),
// context.createStation( 62.29639, -7.01250, 880.0, "Slættaratindur")
// );
context.stations = Arrays.asList(context.createStation(0.0, 0.0, 0.0, "Lat0_Long0"));
// Station position & velocity in EME2000
final Vector3D geovelocity = new Vector3D(0., 0., 0.);
// Compute the frames transformation from station frame to EME2000
Transform topoToEME = context.stations.get(0).getBaseFrame().getTransformTo(FramesFactory.getEME2000(), new AbsoluteDate(2000, 1, 1, 12, 0, 0.0, context.utc));
// Station position in EME2000 at reference date
Vector3D stationPositionEME = topoToEME.transformPosition(Vector3D.ZERO);
// Satellite position and velocity in Station Frame
final Vector3D sat_pos = new Vector3D(0., 0., da - stationPositionEME.getNorm());
final Vector3D acceleration = new Vector3D(-context.gravity.getMu(), sat_pos);
final PVCoordinates pv_sat_topo = new PVCoordinates(sat_pos, geovelocity, acceleration);
// satellite position in EME2000
final PVCoordinates pv_sat_iner = topoToEME.transformPVCoordinates(pv_sat_topo);
// Geo-stationary Satellite Orbit, tightly above the station (l0-L0)
context.initialOrbit = new KeplerianOrbit(pv_sat_iner, FramesFactory.getEME2000(), new AbsoluteDate(2000, 1, 1, 12, 0, 0.0, context.utc), context.gravity.getMu());
context.stations = Arrays.asList(context.createStation(10.0, 45.0, 0.0, "Lat10_Long45"));
// Turn-around range stations
// Map entry = master station
// Map value = slave station associated
context.TARstations = new HashMap<GroundStation, GroundStation>();
context.TARstations.put(context.createStation(41.977, 13.600, 671.354, "Fucino"), context.createStation(43.604, 1.444, 263.0, "Toulouse"));
context.TARstations.put(context.createStation(49.867, 8.65, 144.0, "Darmstadt"), context.createStation(-25.885, 27.707, 1566.633, "Pretoria"));
return context;
}
use of org.orekit.frames.FieldTransform in project Orekit by CS-SI.
the class Geoid method getIntersectionPoint.
/**
* {@inheritDoc}
*
* <p> The intersection point is computed using a line search along the
* specified line. This is accurate when the geoid is slowly varying.
*/
@Override
public <T extends RealFieldElement<T>> FieldGeodeticPoint<T> getIntersectionPoint(final FieldLine<T> lineInFrame, final FieldVector3D<T> closeInFrame, final Frame frame, final FieldAbsoluteDate<T> date) throws OrekitException {
final Field<T> field = date.getField();
/*
* It is assumed that the geoid is slowly varying over it's entire
* surface. Therefore there will one local intersection.
*/
// transform to body frame
final Frame bodyFrame = this.getBodyFrame();
final FieldTransform<T> frameToBody = frame.getTransformTo(bodyFrame, date);
final FieldVector3D<T> close = frameToBody.transformPosition(closeInFrame);
final FieldLine<T> lineInBodyFrame = frameToBody.transformLine(lineInFrame);
// set the line's direction so the solved for value is always positive
final FieldLine<T> line;
if (lineInBodyFrame.getAbscissa(close).getReal() < 0) {
line = lineInBodyFrame.revert();
} else {
line = lineInBodyFrame;
}
final ReferenceEllipsoid ellipsoid = this.getEllipsoid();
// calculate end points
// distance from line to center of earth, squared
final T d2 = line.pointAt(0.0).getNormSq();
// the minimum abscissa, squared
final double n = ellipsoid.getPolarRadius() + MIN_UNDULATION;
final T minAbscissa2 = d2.negate().add(n * n);
// smaller end point of the interval = 0.0 or intersection with
// min_undulation sphere
final T lowPoint = minAbscissa2.getReal() < 0 ? field.getZero() : minAbscissa2.sqrt();
// the maximum abscissa, squared
final double x = ellipsoid.getEquatorialRadius() + MAX_UNDULATION;
final T maxAbscissa2 = d2.negate().add(x * x);
// larger end point of the interval
final T highPoint = maxAbscissa2.sqrt();
// line search function
final RealFieldUnivariateFunction<T> heightFunction = z -> {
try {
final FieldGeodeticPoint<T> geodetic = transform(line.pointAt(z), bodyFrame, date);
return geodetic.getAltitude();
} catch (OrekitException e) {
// due to frame transform -> re-throw
throw new RuntimeException(e);
}
};
// compute answer
if (maxAbscissa2.getReal() < 0) {
// ray does not pierce bounding sphere -> no possible intersection
return null;
}
// solve line search problem to find the intersection
final FieldBracketingNthOrderBrentSolver<T> solver = new FieldBracketingNthOrderBrentSolver<>(field.getZero().add(1.0e-14), field.getZero().add(1.0e-6), field.getZero().add(1.0e-15), 5);
try {
final T abscissa = solver.solve(MAX_EVALUATIONS, heightFunction, lowPoint, highPoint, AllowedSolution.ANY_SIDE);
// return intersection point
return this.transform(line.pointAt(abscissa), bodyFrame, date);
} catch (MathRuntimeException e) {
// no intersection
return null;
}
}
use of org.orekit.frames.FieldTransform in project Orekit by CS-SI.
the class LofOffsetPointing method getTargetPV.
/**
* {@inheritDoc}
*/
public <T extends RealFieldElement<T>> TimeStampedFieldPVCoordinates<T> getTargetPV(final FieldPVCoordinatesProvider<T> pvProv, final FieldAbsoluteDate<T> date, final Frame frame) throws OrekitException {
// sample intersection points in current date neighborhood
final double h = 0.1;
final List<TimeStampedFieldPVCoordinates<T>> sample = new ArrayList<>();
FieldTransform<T> centralRefToBody = null;
for (int i = -1; i < 2; ++i) {
final FieldAbsoluteDate<T> shifted = date.shiftedBy(i * h);
// transform from specified reference frame to spacecraft frame
final FieldTransform<T> refToSc = new FieldTransform<>(shifted, new FieldTransform<>(shifted, pvProv.getPVCoordinates(shifted, frame).negate()), new FieldTransform<>(shifted, attitudeLaw.getAttitude(pvProv, shifted, frame).getOrientation()));
// transform from specified reference frame to body frame
final FieldTransform<T> refToBody = frame.getTransformTo(shape.getBodyFrame(), shifted);
if (i == 0) {
centralRefToBody = refToBody;
}
sample.add(losIntersectionWithBody(new FieldTransform<>(shifted, refToSc.getInverse(), refToBody)));
}
// use interpolation to compute properly the time-derivatives
final TimeStampedFieldPVCoordinates<T> targetBody = TimeStampedFieldPVCoordinates.interpolate(date, CartesianDerivativesFilter.USE_P, sample);
// convert back to caller specified frame
return centralRefToBody.getInverse().transformPVCoordinates(targetBody);
}
use of org.orekit.frames.FieldTransform in project Orekit by CS-SI.
the class RangeAnalytic method theoreticalEvaluationValidation.
/**
* Added for validation
* Compares directly numeric and analytic computations
* @param iteration
* @param evaluation
* @param state
* @return
* @throws OrekitException
*/
protected EstimatedMeasurement<Range> theoreticalEvaluationValidation(final int iteration, final int evaluation, final SpacecraftState state) throws OrekitException {
// Station & DSFactory attributes from parent Range class
final GroundStation groundStation = getStation();
// get the number of parameters used for derivation
int nbParams = 6;
final Map<String, Integer> indices = new HashMap<>();
for (ParameterDriver driver : getParametersDrivers()) {
if (driver.isSelected()) {
indices.put(driver.getName(), nbParams++);
}
}
final DSFactory dsFactory = new DSFactory(nbParams, 1);
final Field<DerivativeStructure> field = dsFactory.getDerivativeField();
final FieldVector3D<DerivativeStructure> zero = FieldVector3D.getZero(field);
// Range derivatives are computed with respect to spacecraft state in inertial frame
// and station position in station's offset frame
// -------
//
// Parameters:
// - 0..2 - Px, Py, Pz : Position of the spacecraft in inertial frame
// - 3..5 - Vx, Vy, Vz : Velocity of the spacecraft in inertial frame
// - 6..8 - QTx, QTy, QTz: Position of the station in station's offset frame
// Coordinates of the spacecraft expressed as a derivative structure
final TimeStampedFieldPVCoordinates<DerivativeStructure> pvaDS = getCoordinates(state, 0, dsFactory);
// transform between station and inertial frame, expressed as a derivative structure
// The components of station's position in offset frame are the 3 last derivative parameters
final AbsoluteDate downlinkDate = getDate();
final FieldAbsoluteDate<DerivativeStructure> downlinkDateDS = new FieldAbsoluteDate<>(field, downlinkDate);
final FieldTransform<DerivativeStructure> offsetToInertialDownlink = groundStation.getOffsetToInertial(state.getFrame(), downlinkDateDS, dsFactory, indices);
// Station position in inertial frame at end of the downlink leg
final TimeStampedFieldPVCoordinates<DerivativeStructure> stationDownlink = offsetToInertialDownlink.transformPVCoordinates(new TimeStampedFieldPVCoordinates<>(downlinkDateDS, zero, zero, zero));
// Compute propagation times
// (if state has already been set up to pre-compensate propagation delay,
// we will have offset == downlinkDelay and transitState will be
// the same as state)
// Downlink delay
final DerivativeStructure tauD = signalTimeOfFlight(pvaDS, stationDownlink.getPosition(), downlinkDateDS);
// Transit state
final double delta = downlinkDate.durationFrom(state.getDate());
final DerivativeStructure tauDMDelta = tauD.negate().add(delta);
final SpacecraftState transitState = state.shiftedBy(tauDMDelta.getValue());
// Transit state position (re)computed with derivative structures
final TimeStampedFieldPVCoordinates<DerivativeStructure> transitStateDS = pvaDS.shiftedBy(tauDMDelta);
// Station at transit state date (derivatives of tauD taken into account)
final TimeStampedFieldPVCoordinates<DerivativeStructure> stationAtTransitDate = stationDownlink.shiftedBy(tauD.negate());
// Uplink delay
final DerivativeStructure tauU = signalTimeOfFlight(stationAtTransitDate, transitStateDS.getPosition(), transitStateDS.getDate());
// Prepare the evaluation
final EstimatedMeasurement<Range> estimated = new EstimatedMeasurement<Range>(this, iteration, evaluation, new SpacecraftState[] { transitState }, null);
// Range value
final DerivativeStructure tau = tauD.add(tauU);
final double cOver2 = 0.5 * Constants.SPEED_OF_LIGHT;
final DerivativeStructure range = tau.multiply(cOver2);
estimated.setEstimatedValue(range.getValue());
// Range partial derivatives with respect to state
final double[] derivatives = range.getAllDerivatives();
estimated.setStateDerivatives(0, Arrays.copyOfRange(derivatives, 1, 7));
// (beware element at index 0 is the value, not a derivative)
for (final ParameterDriver driver : getParametersDrivers()) {
final Integer index = indices.get(driver.getName());
if (index != null) {
estimated.setParameterDerivatives(driver, derivatives[index + 1]);
}
}
// ----------
// VALIDATION
// -----------
// Computation of the value without DS
// ----------------------------------
// Time difference between t (date of the measurement) and t' (date tagged in spacecraft state)
// Station position at signal arrival
final Transform topoToInertDownlink = groundStation.getOffsetToInertial(state.getFrame(), downlinkDate);
final PVCoordinates QDownlink = topoToInertDownlink.transformPVCoordinates(PVCoordinates.ZERO);
// Downlink time of flight from spacecraft to station
final double td = signalTimeOfFlight(state.getPVCoordinates(), QDownlink.getPosition(), downlinkDate);
final double dt = delta - td;
// Transit state position
final AbsoluteDate transitT = state.getDate().shiftedBy(dt);
final SpacecraftState transit = state.shiftedBy(dt);
final Vector3D transitP = transitState.getPVCoordinates().getPosition();
// Station position at signal departure
// First guess
// AbsoluteDate uplinkDate = downlinkDate.shiftedBy(-getObservedValue()[0] / cOver2);
// final Transform topoToInertUplink =
// station.getOffsetFrame().getTransformTo(state.getFrame(), uplinkDate);
// TimeStampedPVCoordinates QUplink = topoToInertUplink.
// transformPVCoordinates(new TimeStampedPVCoordinates(uplinkDate, PVCoordinates.ZERO));
// Station position at transit state date
final Transform topoToInertAtTransitDate = groundStation.getOffsetToInertial(state.getFrame(), transitT);
TimeStampedPVCoordinates QAtTransitDate = topoToInertAtTransitDate.transformPVCoordinates(new TimeStampedPVCoordinates(transitT, PVCoordinates.ZERO));
// Uplink time of flight
final double tu = signalTimeOfFlight(QAtTransitDate, transitP, transitT);
// Total time of flight
final double t = td + tu;
// Real date and position of station at signal departure
AbsoluteDate uplinkDate = downlinkDate.shiftedBy(-t);
TimeStampedPVCoordinates QUplink = topoToInertDownlink.shiftedBy(-t).transformPVCoordinates(new TimeStampedPVCoordinates(uplinkDate, PVCoordinates.ZERO));
// Range value
double r = t * cOver2;
double dR = r - range.getValue();
// td derivatives / state
// -----------------------
// Qt = Master station position at tmeas = t = signal arrival at master station
final Vector3D vel = state.getPVCoordinates().getVelocity();
final Vector3D Qt_V = QDownlink.getVelocity();
final Vector3D Ptr = transit.getPVCoordinates().getPosition();
final Vector3D Ptr_Qt = QDownlink.getPosition().subtract(Ptr);
final double dDown = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * td - Vector3D.dotProduct(Ptr_Qt, vel);
// Derivatives of the downlink time of flight
final double dtddPx = -Ptr_Qt.getX() / dDown;
final double dtddPy = -Ptr_Qt.getY() / dDown;
final double dtddPz = -Ptr_Qt.getZ() / dDown;
final double dtddVx = dtddPx * dt;
final double dtddVy = dtddPy * dt;
final double dtddVz = dtddPz * dt;
// From the DS
final double dtddPxDS = tauD.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtddPyDS = tauD.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0);
final double dtddPzDS = tauD.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0);
final double dtddVxDS = tauD.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0);
final double dtddVyDS = tauD.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0);
final double dtddVzDS = tauD.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0);
// Difference
final double d_dtddPx = dtddPxDS - dtddPx;
final double d_dtddPy = dtddPyDS - dtddPy;
final double d_dtddPz = dtddPzDS - dtddPz;
final double d_dtddVx = dtddVxDS - dtddVx;
final double d_dtddVy = dtddVyDS - dtddVy;
final double d_dtddVz = dtddVzDS - dtddVz;
// tu derivatives / state
// -----------------------
final Vector3D Qt2_Ptr = Ptr.subtract(QUplink.getPosition());
final double dUp = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * tu - Vector3D.dotProduct(Qt2_Ptr, Qt_V);
// test
// // Speed of the station at tmeas-t
// // Note: Which one to use in the calculation of dUp ???
// final Vector3D Qt2_V = QUplink.getVelocity();
// final double dUp = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT * tu -
// Vector3D.dotProduct(Qt2_Ptr, Qt2_V);
// test
// tu derivatives
final double dtudPx = 1. / dUp * Qt2_Ptr.dotProduct(Vector3D.PLUS_I.add((Qt_V.subtract(vel)).scalarMultiply(dtddPx)));
final double dtudPy = 1. / dUp * Qt2_Ptr.dotProduct(Vector3D.PLUS_J.add((Qt_V.subtract(vel)).scalarMultiply(dtddPy)));
final double dtudPz = 1. / dUp * Qt2_Ptr.dotProduct(Vector3D.PLUS_K.add((Qt_V.subtract(vel)).scalarMultiply(dtddPz)));
final double dtudVx = dtudPx * dt;
final double dtudVy = dtudPy * dt;
final double dtudVz = dtudPz * dt;
// From the DS
final double dtudPxDS = tauU.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0);
final double dtudPyDS = tauU.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0);
final double dtudPzDS = tauU.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0);
final double dtudVxDS = tauU.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0);
final double dtudVyDS = tauU.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0);
final double dtudVzDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0);
// Difference
final double d_dtudPx = dtudPxDS - dtudPx;
final double d_dtudPy = dtudPyDS - dtudPy;
final double d_dtudPz = dtudPzDS - dtudPz;
final double d_dtudVx = dtudVxDS - dtudVx;
final double d_dtudVy = dtudVyDS - dtudVy;
final double d_dtudVz = dtudVzDS - dtudVz;
// Range derivatives / state
// -----------------------
// R = Range
double dRdPx = (dtddPx + dtudPx) * cOver2;
double dRdPy = (dtddPy + dtudPy) * cOver2;
double dRdPz = (dtddPz + dtudPz) * cOver2;
double dRdVx = (dtddVx + dtudVx) * cOver2;
double dRdVy = (dtddVy + dtudVy) * cOver2;
double dRdVz = (dtddVz + dtudVz) * cOver2;
// With DS
double dRdPxDS = range.getPartialDerivative(1, 0, 0, 0, 0, 0, 0, 0, 0);
double dRdPyDS = range.getPartialDerivative(0, 1, 0, 0, 0, 0, 0, 0, 0);
double dRdPzDS = range.getPartialDerivative(0, 0, 1, 0, 0, 0, 0, 0, 0);
double dRdVxDS = range.getPartialDerivative(0, 0, 0, 1, 0, 0, 0, 0, 0);
double dRdVyDS = range.getPartialDerivative(0, 0, 0, 0, 1, 0, 0, 0, 0);
double dRdVzDS = range.getPartialDerivative(0, 0, 0, 0, 0, 1, 0, 0, 0);
// Diff
final double d_dRdPx = dRdPxDS - dRdPx;
final double d_dRdPy = dRdPyDS - dRdPy;
final double d_dRdPz = dRdPzDS - dRdPz;
final double d_dRdVx = dRdVxDS - dRdVx;
final double d_dRdVy = dRdVyDS - dRdVy;
final double d_dRdVz = dRdVzDS - dRdVz;
// td derivatives / station
// -----------------------
final AngularCoordinates ac = topoToInertDownlink.getAngular().revert();
final Rotation rotTopoToInert = ac.getRotation();
final Vector3D omega = ac.getRotationRate();
final Vector3D dtddQI = Ptr_Qt.scalarMultiply(1. / dDown);
final double dtddQIx = dtddQI.getX();
final double dtddQIy = dtddQI.getY();
final double dtddQIz = dtddQI.getZ();
final Vector3D dtddQ = rotTopoToInert.applyTo(dtddQI);
// With DS
double dtddQxDS = tauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0);
double dtddQyDS = tauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0);
double dtddQzDS = tauD.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dtddQx = dtddQxDS - dtddQ.getX();
final double d_dtddQy = dtddQyDS - dtddQ.getY();
final double d_dtddQz = dtddQzDS - dtddQ.getZ();
// tu derivatives / station
// -----------------------
// Inertial frame
final double dtudQIx = 1 / dUp * Qt2_Ptr.dotProduct(Vector3D.MINUS_I.add((Qt_V.subtract(vel)).scalarMultiply(dtddQIx)).subtract(Vector3D.PLUS_I.crossProduct(omega).scalarMultiply(t)));
final double dtudQIy = 1 / dUp * Qt2_Ptr.dotProduct(Vector3D.MINUS_J.add((Qt_V.subtract(vel)).scalarMultiply(dtddQIy)).subtract(Vector3D.PLUS_J.crossProduct(omega).scalarMultiply(t)));
final double dtudQIz = 1 / dUp * Qt2_Ptr.dotProduct(Vector3D.MINUS_K.add((Qt_V.subtract(vel)).scalarMultiply(dtddQIz)).subtract(Vector3D.PLUS_K.crossProduct(omega).scalarMultiply(t)));
// // test
// final double dtudQIx = 1/dUp*Qt2_Ptr
// // .dotProduct(Vector3D.MINUS_I);
// // .dotProduct((Qt_V.subtract(vel)).scalarMultiply(dtddQIx));
// .dotProduct(Vector3D.MINUS_I.crossProduct(omega).scalarMultiply(t));
// final double dtudQIy = 1/dUp*Qt2_Ptr
// // .dotProduct(Vector3D.MINUS_J);
// // .dotProduct((Qt_V.subtract(vel)).scalarMultiply(dtddQIy));
// .dotProduct(Vector3D.MINUS_J.crossProduct(omega).scalarMultiply(t));
// final double dtudQIz = 1/dUp*Qt2_Ptr
// // .dotProduct(Vector3D.MINUS_K);
// // .dotProduct((Qt_V.subtract(vel)).scalarMultiply(dtddQIz));
// .dotProduct(Vector3D.MINUS_K.crossProduct(omega).scalarMultiply(t));
//
// double dtu_dQxDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0);
// double dtu_dQyDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0);
// double dtu_dQzDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1);
// final Vector3D dtudQDS = new Vector3D(dtu_dQxDS, dtu_dQyDS, dtu_dQzDS);
// final Vector3D dtudQIDS = rotTopoToInert.applyInverseTo(dtudQDS);
// double dtudQIxDS = dtudQIDS.getX();
// double dtudQIyDS = dtudQIDS.getY();
// double dtudQIxzS = dtudQIDS.getZ();
// // test
// Topocentric frame
final Vector3D dtudQI = new Vector3D(dtudQIx, dtudQIy, dtudQIz);
final Vector3D dtudQ = rotTopoToInert.applyTo(dtudQI);
// With DS
double dtudQxDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0);
double dtudQyDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0);
double dtudQzDS = tauU.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dtudQx = dtudQxDS - dtudQ.getX();
final double d_dtudQy = dtudQyDS - dtudQ.getY();
final double d_dtudQz = dtudQzDS - dtudQ.getZ();
// Range derivatives / station
// -----------------------
double dRdQx = (dtddQ.getX() + dtudQ.getX()) * cOver2;
double dRdQy = (dtddQ.getY() + dtudQ.getY()) * cOver2;
double dRdQz = (dtddQ.getZ() + dtudQ.getZ()) * cOver2;
// With DS
double dRdQxDS = range.getPartialDerivative(0, 0, 0, 0, 0, 0, 1, 0, 0);
double dRdQyDS = range.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 1, 0);
double dRdQzDS = range.getPartialDerivative(0, 0, 0, 0, 0, 0, 0, 0, 1);
// Diff
final double d_dRdQx = dRdQxDS - dRdQx;
final double d_dRdQy = dRdQyDS - dRdQy;
final double d_dRdQz = dRdQzDS - dRdQz;
// Print results to avoid warning
final boolean printResults = false;
if (printResults) {
System.out.println("dR = " + dR);
System.out.println("d_dtddPx = " + d_dtddPx);
System.out.println("d_dtddPy = " + d_dtddPy);
System.out.println("d_dtddPz = " + d_dtddPz);
System.out.println("d_dtddVx = " + d_dtddVx);
System.out.println("d_dtddVy = " + d_dtddVy);
System.out.println("d_dtddVz = " + d_dtddVz);
System.out.println("d_dtudPx = " + d_dtudPx);
System.out.println("d_dtudPy = " + d_dtudPy);
System.out.println("d_dtudPz = " + d_dtudPz);
System.out.println("d_dtudVx = " + d_dtudVx);
System.out.println("d_dtudVy = " + d_dtudVy);
System.out.println("d_dtudVz = " + d_dtudVz);
System.out.println("d_dRdPx = " + d_dRdPx);
System.out.println("d_dRdPy = " + d_dRdPy);
System.out.println("d_dRdPz = " + d_dRdPz);
System.out.println("d_dRdVx = " + d_dRdVx);
System.out.println("d_dRdVy = " + d_dRdVy);
System.out.println("d_dRdVz = " + d_dRdVz);
System.out.println("d_dtddQx = " + d_dtddQx);
System.out.println("d_dtddQy = " + d_dtddQy);
System.out.println("d_dtddQz = " + d_dtddQz);
System.out.println("d_dtudQx = " + d_dtudQx);
System.out.println("d_dtudQy = " + d_dtudQy);
System.out.println("d_dtudQz = " + d_dtudQz);
System.out.println("d_dRdQx = " + d_dRdQx);
System.out.println("d_dRdQy = " + d_dRdQy);
System.out.println("d_dRdQz = " + d_dRdQz);
}
// Dummy return
return estimated;
}
Aggregations