Commit b1bdbec8 authored by Luc Maisonobe's avatar Luc Maisonobe
Browse files

Streamline computation of trajectories around Lagrange points.

parent d3e0f6e8
......@@ -22,17 +22,12 @@ import org.hipparchus.ode.events.Action;
import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
import org.hipparchus.util.FastMath;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.attitudes.AttitudeProvider;
import org.orekit.attitudes.InertialProvider;
import org.orekit.bodies.CR3BPSystem;
import org.orekit.data.DataContext;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.EventDetector;
import org.orekit.propagation.events.HaloXZPlaneCrossingDetector;
import org.orekit.propagation.events.handlers.EventHandler;
import org.orekit.propagation.numerical.NumericalPropagator;
import org.orekit.propagation.numerical.cr3bp.CR3BPForceModel;
import org.orekit.propagation.numerical.cr3bp.STMEquations;
......@@ -52,6 +47,18 @@ import org.orekit.utils.PVCoordinates;
*/
public class CR3BPDifferentialCorrection {
/** Maximum number of iterations. */
private static final int MAX_ITER = 30;
/** Max check interval for crossing plane. */
private static final double CROSSING_MAX_CHECK = 3600.0;
/** Convergence tolerance for plane crossing time. */
private static final double CROSSING_TOLERANCE = 1.0e-10;
/** Arbitrary start date. */
private static final AbsoluteDate START_DATE = AbsoluteDate.ARBITRARY_EPOCH;
/** Boolean return true if the propagated trajectory crosses the plane. */
private boolean cross;
......@@ -67,24 +74,18 @@ public class CR3BPDifferentialCorrection {
/** orbitalPeriod Orbital Period of the required orbit. */
private double orbitalPeriod;
/** Propagator. */
private final NumericalPropagator propagator;
/** UTC time scale. */
private final TimeScale utc;
/** Simple Constructor.
* <p> Standard constructor using DormandPrince853 integrator for the differential correction </p>
* @param firstguess first guess PVCoordinates of the point to start differential correction
* @param syst CR3BP System considered
* @param orbitalPeriod Orbital Period of the required orbit
*/
@DefaultDataContext
public CR3BPDifferentialCorrection(final PVCoordinates firstguess,
final CR3BPSystem syst, final double orbitalPeriod) {
this(firstguess, syst, orbitalPeriod,
InertialProvider.of(syst.getRotatingFrame()),
DataContext.getDefault().getTimeScales().getUTC());
this.firstGuess = firstguess;
this.syst = syst;
this.orbitalPeriodApprox = orbitalPeriod;
}
/** Simple Constructor.
......@@ -92,18 +93,24 @@ public class CR3BPDifferentialCorrection {
* @param firstguess first guess PVCoordinates of the point to start differential correction
* @param syst CR3BP System considered
* @param orbitalPeriod Orbital Period of the required orbit
* @param attitudeProvider the attitude law for the numerocal propagator
* @param attitudeProvider the attitude law for the numerical propagator
* @param utc UTC time scale
* @deprecated as of 11.1, replaced by {@link #CR3BPDifferentialCorrection(PVCoordinates, CR3BPSystem, double)}
*/
@Deprecated
public CR3BPDifferentialCorrection(final PVCoordinates firstguess,
final CR3BPSystem syst,
final double orbitalPeriod,
final AttitudeProvider attitudeProvider,
final TimeScale utc) {
this.firstGuess = firstguess;
this.syst = syst;
this.orbitalPeriodApprox = orbitalPeriod;
this.utc = utc;
this(firstguess, syst, orbitalPeriod);
}
/** Build the propagator.
* @return propagator
* @since 11.1
*/
private NumericalPropagator buildPropagator() {
// Adaptive stepsize boundaries
final double minStep = 1E-12;
......@@ -122,27 +129,7 @@ public class CR3BPDifferentialCorrection {
vecRelativeTolerances);
// Propagator definition
this.propagator = new NumericalPropagator(integrator, attitudeProvider);
}
/**
* Return the real starting PVCoordinates on the Libration orbit type
* after differential correction from a first guess.
* @param type libration orbit type
* @return pv Position-Velocity of the starting point on the Halo Orbit
*/
public PVCoordinates compute(final LibrationOrbitType type) {
// Event detector settings
final double maxcheck = 10;
final double threshold = 1E-10;
// Event detector definition
final EventDetector XZPlaneCrossing =
new HaloXZPlaneCrossingDetector(maxcheck, threshold).withHandler(new PlaneCrossingHandler());
// Additional equations set in order to compute the State Transition Matrix along the propagation
final STMEquations stm = new STMEquations(syst);
final NumericalPropagator propagator = new NumericalPropagator(integrator);
// CR3BP has no defined orbit type
propagator.setOrbitType(null);
......@@ -153,50 +140,55 @@ public class CR3BPDifferentialCorrection {
// Add CR3BP Force Model to the propagator
propagator.addForceModel(new CR3BPForceModel(syst));
// Add previously set additional equations to the propagator
propagator.addAdditionalDerivativesProvider(stm);
// Add event detector for crossing plane
propagator.addEventDetector(new HaloXZPlaneCrossingDetector(CROSSING_MAX_CHECK, CROSSING_TOLERANCE).
withHandler((state, detector, increasing) -> {
cross = true;
return Action.STOP;
}));
// Add previously set event detector to the propagator
propagator.addEventDetector(XZPlaneCrossing);
return propagator;
return type == LibrationOrbitType.HALO ? computeHalo(stm) : computeLyapunov(stm);
}
/** Return the real starting PVCoordinates on the Halo orbit after
* differential correction from a first guess.
* @param stm additional equations
/**
* Return the real starting PVCoordinates on the Libration orbit type
* after differential correction from a first guess.
* @param type libration orbit type
* @return pv Position-Velocity of the starting point on the Halo Orbit
*/
private PVCoordinates computeHalo(final STMEquations stm) {
// number of iteration
double iHalo = 0;
public PVCoordinates compute(final LibrationOrbitType type) {
return type == LibrationOrbitType.HALO ? computeHalo() : computeLyapunov();
}
// Time settings (this date has no effect on the result, this is only for code structure purpose)
final AbsoluteDate startDateHalo = new AbsoluteDate(1996, 06, 25, 0, 0, 00.000, utc);
/** Return the real starting PVCoordinates on the Halo orbit after differential correction from a first guess.
* @return pv Position-Velocity of the starting point on the Halo Orbit
*/
private PVCoordinates computeHalo() {
// Initializing PVCoordinates with first guess
PVCoordinates pvHalo = firstGuess;
// Start a new differentially corrected propagation until it converges to a Halo Orbit
do {
// Converge within 1E-8 tolerance and under 5 iterations
for (int iHalo = 0; iHalo < MAX_ITER; ++iHalo) {
// SpacecraftState initialization
final AbsolutePVCoordinates initialAbsPVHalo = new AbsolutePVCoordinates(syst.getRotatingFrame(), startDateHalo, pvHalo);
final AbsolutePVCoordinates initialAbsPVHalo = new AbsolutePVCoordinates(syst.getRotatingFrame(), START_DATE, pvHalo);
final SpacecraftState initialStateHalo = new SpacecraftState(initialAbsPVHalo);
// Additional equations initialization
final SpacecraftState augmentedInitialStateHalo = stm.setInitialPhi(initialStateHalo);
// setup propagator
final NumericalPropagator propagator = buildPropagator();
final STMEquations stm = new STMEquations(syst);
propagator.addAdditionalDerivativesProvider(stm);
propagator.setInitialState(stm.setInitialPhi(initialStateHalo));
// boolean changed to true by crossing XZ plane during propagation. Has to be true for the differential correction to converge
cross = false;
// Propagator initialization
propagator.setInitialState(augmentedInitialStateHalo);
// Propagate until trajectory crosses XZ Plane
final SpacecraftState finalStateHalo =
propagator.propagate(startDateHalo.shiftedBy(orbitalPeriodApprox));
propagator.propagate(START_DATE.shiftedBy(orbitalPeriodApprox));
// Stops computation if trajectory did not cross XZ Plane after one full orbital period
if (cross == false) {
......@@ -210,87 +202,77 @@ public class CR3BPDifferentialCorrection {
final double dvxf = -finalStateHalo.getPVCoordinates().getVelocity().getX();
final double dvzf = -finalStateHalo.getPVCoordinates().getVelocity().getZ();
orbitalPeriod = 2 * finalStateHalo.getDate().durationFrom(startDateHalo);
orbitalPeriod = 2 * finalStateHalo.getDate().durationFrom(START_DATE);
if (FastMath.abs(dvxf) > 1E-8 || FastMath.abs(dvzf) > 1E-8) {
// Y axis velocity
final double vy =
finalStateHalo.getPVCoordinates().getVelocity().getY();
// Spacecraft acceleration
final Vector3D acc = finalStateHalo.getPVCoordinates().getAcceleration();
final double accx = acc.getX();
final double accz = acc.getZ();
// Compute A coefficients
final double a11 = phiHalo.getEntry(3, 0) - accx * phiHalo.getEntry(1, 0) / vy;
final double a12 = phiHalo.getEntry(3, 4) - accx * phiHalo.getEntry(1, 4) / vy;
final double a21 = phiHalo.getEntry(5, 0) - accz * phiHalo.getEntry(1, 0) / vy;
final double a22 = phiHalo.getEntry(5, 4) - accz * phiHalo.getEntry(1, 4) / vy;
// A determinant used for matrix inversion
final double aDet = a11 * a22 - a21 * a12;
// Correction to apply to initial conditions
final double deltax0 = (a22 * dvxf - a12 * dvzf) / aDet;
final double deltavy0 = (-a21 * dvxf + a11 * dvzf) / aDet;
// Computation of the corrected initial PVCoordinates
final double newx = pvHalo.getPosition().getX() + deltax0;
final double newvy = pvHalo.getVelocity().getY() + deltavy0;
pvHalo = new PVCoordinates(new Vector3D(newx,
pvHalo.getPosition().getY(),
pvHalo.getPosition().getZ()),
new Vector3D(pvHalo.getVelocity().getX(),
newvy,
pvHalo.getVelocity().getZ()));
++iHalo;
} else {
if (FastMath.abs(dvxf) <= 1E-8 && FastMath.abs(dvzf) <= 1E-8) {
break;
}
} while (iHalo < 30); // Converge within 1E-8 tolerance and under 5 iterations
// Y axis velocity
final double vy = finalStateHalo.getPVCoordinates().getVelocity().getY();
// Spacecraft acceleration
final Vector3D acc = finalStateHalo.getPVCoordinates().getAcceleration();
final double accx = acc.getX();
final double accz = acc.getZ();
// Compute A coefficients
final double a11 = phiHalo.getEntry(3, 0) - accx * phiHalo.getEntry(1, 0) / vy;
final double a12 = phiHalo.getEntry(3, 4) - accx * phiHalo.getEntry(1, 4) / vy;
final double a21 = phiHalo.getEntry(5, 0) - accz * phiHalo.getEntry(1, 0) / vy;
final double a22 = phiHalo.getEntry(5, 4) - accz * phiHalo.getEntry(1, 4) / vy;
// A determinant used for matrix inversion
final double aDet = a11 * a22 - a21 * a12;
// Correction to apply to initial conditions
final double deltax0 = (a22 * dvxf - a12 * dvzf) / aDet;
final double deltavy0 = (-a21 * dvxf + a11 * dvzf) / aDet;
// Computation of the corrected initial PVCoordinates
final double newx = pvHalo.getPosition().getX() + deltax0;
final double newvy = pvHalo.getVelocity().getY() + deltavy0;
pvHalo = new PVCoordinates(new Vector3D(newx,
pvHalo.getPosition().getY(),
pvHalo.getPosition().getZ()),
new Vector3D(pvHalo.getVelocity().getX(),
newvy,
pvHalo.getVelocity().getZ()));
}
// Return
return pvHalo;
}
/** Return the real starting PVCoordinates on the Lyapunov orbit after
* differential correction from a first guess.
* @param stm additional equations
/** Return the real starting PVCoordinates on the Lyapunov orbit after differential correction from a first guess.
* @return pv Position-Velocity of the starting point on the Lyapunov Orbit
*/
public PVCoordinates computeLyapunov(final STMEquations stm) {
// number of iteration
double iLyapunov = 0;
// Time settings (this date has no effect on the result, this is only for code structure purpose)
final AbsoluteDate startDateLyapunov = new AbsoluteDate(1996, 06, 25, 0, 0, 00.000, utc);
public PVCoordinates computeLyapunov() {
// Initializing PVCoordinates with first guess
PVCoordinates pvLyapunov = firstGuess;
// Start a new differentially corrected propagation until it converges to a Halo Orbit
do {
// Converge within 1E-8 tolerance and under 5 iterations
for (int iLyapunov = 0; iLyapunov < MAX_ITER; ++iLyapunov) {
// SpacecraftState initialization
final AbsolutePVCoordinates initialAbsPVLyapunov = new AbsolutePVCoordinates(syst.getRotatingFrame(), startDateLyapunov, pvLyapunov);
final AbsolutePVCoordinates initialAbsPVLyapunov = new AbsolutePVCoordinates(syst.getRotatingFrame(), START_DATE, pvLyapunov);
final SpacecraftState initialStateLyapunov = new SpacecraftState(initialAbsPVLyapunov);
// Additional equations initialization
final SpacecraftState augmentedInitialStateLyapunov = stm.setInitialPhi(initialStateLyapunov);
// setup propagator
final NumericalPropagator propagator = buildPropagator();
final STMEquations stm = new STMEquations(syst);
propagator.addAdditionalDerivativesProvider(stm);
propagator.setInitialState(stm.setInitialPhi(initialStateLyapunov));
// boolean changed to true by crossing XZ plane during propagation. Has to be true for the differential correction to converge
cross = false;
// Propagator initialization
propagator.setInitialState(augmentedInitialStateLyapunov);
// Propagate until trajectory crosses XZ Plane
final SpacecraftState finalStateLyapunov =
propagator.propagate(startDateLyapunov.shiftedBy(orbitalPeriodApprox));
propagator.propagate(START_DATE.shiftedBy(orbitalPeriodApprox));
// Stops computation if trajectory did not cross XZ Plane after one full orbital period
if (cross == false) {
......@@ -303,34 +285,32 @@ public class CR3BPDifferentialCorrection {
// Gap from desired y position and x velocity value ()
final double dvxf = -finalStateLyapunov.getPVCoordinates().getVelocity().getX();
orbitalPeriod = 2 * finalStateLyapunov.getDate().durationFrom(startDateLyapunov);
orbitalPeriod = 2 * finalStateLyapunov.getDate().durationFrom(START_DATE);
if (FastMath.abs(dvxf) > 1E-14) {
// Y axis velocity
final double vy = finalStateLyapunov.getPVCoordinates().getVelocity().getY();
if (FastMath.abs(dvxf) <= 1E-14) {
break;
}
// Spacecraft acceleration
final double accy = finalStateLyapunov.getPVCoordinates().getAcceleration().getY();
// Y axis velocity
final double vy = finalStateLyapunov.getPVCoordinates().getVelocity().getY();
// Compute A coefficients
final double deltavy0 = dvxf / (phi.getEntry(3, 4) - accy * phi.getEntry(1, 4) / vy);
// Spacecraft acceleration
final double accy = finalStateLyapunov.getPVCoordinates().getAcceleration().getY();
// Computation of the corrected initial PVCoordinates
final double newvy = pvLyapunov.getVelocity().getY() + deltavy0;
// Compute A coefficients
final double deltavy0 = dvxf / (phi.getEntry(3, 4) - accy * phi.getEntry(1, 4) / vy);
pvLyapunov = new PVCoordinates(new Vector3D(pvLyapunov.getPosition().getX(),
pvLyapunov.getPosition().getY(),
0),
new Vector3D(pvLyapunov.getVelocity().getX(),
newvy,
0));
// Computation of the corrected initial PVCoordinates
final double newvy = pvLyapunov.getVelocity().getY() + deltavy0;
++iLyapunov;
} else {
break;
}
pvLyapunov = new PVCoordinates(new Vector3D(pvLyapunov.getPosition().getX(),
pvLyapunov.getPosition().getY(),
0),
new Vector3D(pvLyapunov.getVelocity().getX(),
newvy,
0));
} while (iLyapunov < 30); // Converge within 1E-8 tolerance and under 5 iterations
}
// Return
return pvLyapunov;
......@@ -343,17 +323,4 @@ public class CR3BPDifferentialCorrection {
return orbitalPeriod;
}
/**
* Static class for event detection.
*/
private class PlaneCrossingHandler implements EventHandler<HaloXZPlaneCrossingDetector> {
/** {@inheritDoc} */
public Action eventOccurred(final SpacecraftState s,
final HaloXZPlaneCrossingDetector detector,
final boolean increasing) {
cross = true;
return Action.STOP;
}
}
}
......@@ -20,11 +20,8 @@ import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.linear.EigenDecomposition;
import org.hipparchus.linear.RealMatrix;
import org.hipparchus.linear.RealVector;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.attitudes.AttitudeProvider;
import org.orekit.attitudes.InertialProvider;
import org.orekit.bodies.CR3BPSystem;
import org.orekit.data.DataContext;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.numerical.cr3bp.STMEquations;
import org.orekit.time.TimeScale;
......@@ -88,10 +85,10 @@ public abstract class LibrationOrbit {
* {@link #orbitalPeriod} parameters.
* </p>
*/
@DefaultDataContext
public void applyDifferentialCorrection() {
applyDifferentialCorrection(InertialProvider.of(syst.getRotatingFrame()),
DataContext.getDefault().getTimeScales().getUTC());
final CR3BPDifferentialCorrection diff = new CR3BPDifferentialCorrection(initialPV, syst, orbitalPeriod);
initialPV = applyCorrectionOnPV(diff);
orbitalPeriod = diff.getOrbitalPeriod();
}
/** Apply differential correction.
......@@ -101,12 +98,11 @@ public abstract class LibrationOrbit {
* </p>
* @param attitudeProvider the attitude law for the numerocal propagator
* @param utc UTC time scale
* @deprecated as of 11.1, replaced by {@link #applyDifferentialCorrection()}
*/
public void applyDifferentialCorrection(final AttitudeProvider attitudeProvider,
final TimeScale utc) {
final CR3BPDifferentialCorrection diff = new CR3BPDifferentialCorrection(initialPV, syst, orbitalPeriod, attitudeProvider, utc);
initialPV = applyCorrectionOnPV(diff);
orbitalPeriod = diff.getOrbitalPeriod();
@Deprecated
public void applyDifferentialCorrection(final AttitudeProvider attitudeProvider, final TimeScale utc) {
applyDifferentialCorrection();
}
/** Return a manifold direction from one position on a libration Orbit.
......
......@@ -50,7 +50,7 @@ public class CR3BPMultipleShooter extends AbstractMultipleShooting {
* @param additionalEquations list of additional equations linked to propagatorList.
* @param arcDuration initial guess of the duration of each arc.
* @param tolerance convergence tolerance on the constraint vector
* @deprecated as of 11.1, replaced by {@link #CR3BPMultipleShooter(List, List, double, List, double)}
* @deprecated as of 11.1, replaced by {@link #CR3BPMultipleShooter(List, List, List, double, double, int)}
*/
@Deprecated
public CR3BPMultipleShooter(final List<SpacecraftState> initialGuessList, final List<NumericalPropagator> propagatorList,
......@@ -65,17 +65,17 @@ public class CR3BPMultipleShooter extends AbstractMultipleShooting {
* <p> Standard constructor for multiple shooting which can be used with the CR3BP model.</p>
* @param initialGuessList initial patch points to be corrected.
* @param propagatorList list of propagators associated to each patch point.
* @param arcDuration initial guess of the duration of each arc.
* @param stmEquations list of additional derivatives providers linked to propagatorList.
* @param arcDuration initial guess of the duration of each arc.
* @param tolerance convergence tolerance on the constraint vector
* @param maxIter maximum number of iterations
*/
public CR3BPMultipleShooter(final List<SpacecraftState> initialGuessList, final List<NumericalPropagator> propagatorList,
final double arcDuration, final List<STMEquations> stmEquations,
final List<STMEquations> stmEquations, final double arcDuration,
final double tolerance, final int maxIter) {
super(initialGuessList, propagatorList, arcDuration, tolerance, maxIter, STM);
this.stmEquations = stmEquations;
this.npoints = initialGuessList.size();
this.npoints = initialGuessList.size();
}
/** {@inheritDoc} */
......@@ -88,17 +88,15 @@ public class CR3BPMultipleShooter extends AbstractMultipleShooting {
final Map<Integer, Double> mapConstraints = getConstraintsMap();
final boolean isClosedOrbit = isClosedOrbit();
// Number of additional constraints
final int n = mapConstraints.size() + (isClosedOrbit ? 6 : 0);
final int n = mapConstraints.size() + (isClosedOrbit() ? 6 : 0);
final int ncolumns = getNumberOfFreeVariables() - 1;
final double[][] M = new double[n][ncolumns];
int k = 0;
if (isClosedOrbit) {
if (isClosedOrbit()) {
// The Jacobian matrix has the following form:
//
// [-1 0 0 ... 1 0 ]
......@@ -145,20 +143,19 @@ public class CR3BPMultipleShooter extends AbstractMultipleShooting {
// [vyni - vy1i] |
// [vzni - vz1i]----
// [ y1i - y1d ]---- other constraints (component of
// [ ... ] | a patch point eaquals to a
// [ ... ] | a patch point equals to a
// [vz2i - vz2d]---- desired value)
final Map<Integer, Double> mapConstraints = getConstraintsMap();
final boolean isClosedOrbit = isClosedOrbit();
// Number of additional constraints
final int n = mapConstraints.size() + (isClosedOrbit ? 6 : 0);
final int n = mapConstraints.size() + (isClosedOrbit() ? 6 : 0);
final List<SpacecraftState> patchedSpacecraftStates = getPatchedSpacecraftState();
final double[] fxAdditionnal = new double[n];
int i = 0;
if (isClosedOrbit) {
if (isClosedOrbit()) {
final AbsolutePVCoordinates apv1i = patchedSpacecraftStates.get(0).getAbsPVA();
final AbsolutePVCoordinates apvni = patchedSpacecraftStates.get(npoints - 1).getAbsPVA();
......
......@@ -74,14 +74,9 @@ public class STMEquations
public SpacecraftState setInitialPhi(final SpacecraftState s) {
final int stateDimension = 36;
final double[] phi = new double[stateDimension];
for (int i = 0; i < stateDimension; ++i) {
phi[i] = 0.0;
}
for (int i = 0; i < stateDimension; i = i + 7) {
phi[i] = 1.0;
}
return s.addAdditionalState(name, phi);
}
......
......@@ -209,9 +209,12 @@ public abstract class AbstractMultipleShooting implements MultipleShooting {
final RealMatrix M = computeJacobianMatrix(propagatedSP);
final RealVector fx = MatrixUtils.createRealVector(computeConstraint(propagatedSP));
// Solve linear system
final RealMatrix MMt = M.multiply(M.transpose());
final RealVector dx = M.transpose().multiply(MatrixUtils.inverse(MMt)).operate(fx);
// Solve linear system using minimum norm approach
// (i.e. minimize difference between solutions from successive iterations,
// in other word try to stay close to initial guess; this is *not* a least squares solution)
// see equation 3.12 in Pavlak's thesis
final RealMatrix MMt = M.multiplyTransposed(M);
final RealVector dx = M.transposeMultiply(MatrixUtils.inverse(MMt)).operate(fx);
// Apply correction from the free variable vector to all the variables (propagation time, pacthSpaceraftState)
updateTrajectory(dx);
......@@ -220,7 +223,7 @@ public abstract class AbstractMultipleShooting implements MultipleShooting {
iter++;
} while (fxNorm > tolerance && iter < maxIter); // Converge within tolerance and under 10 iterations
} while (fxNorm > tolerance && iter < maxIter); // Converge within tolerance and under max iterations
return patchedSpacecraftStates;
}
......@@ -627,6 +630,7 @@ public abstract class AbstractMultipleShooting implements MultipleShooting {
@Deprecated
protected SpacecraftState getAugmentedInitialState(final SpacecraftState initialState,
final org.orekit.propagation.integration.AdditionalEquations additionalEquations2) {
// should never be called, only implementations by derived classes should be called
throw new UnsupportedOperationException();
}
......@@ -638,6 +642,7 @@ public abstract class AbstractMultipleShooting implements MultipleShooting {
protected SpacecraftState getAugmentedInitialState(final int i) {
// FIXME: this base implementation is only intended for version 11.1 to delegate to a deprecated method
// it should be removed in 12.0 when getAugmentedInitialState(SpacecraftState, AdditionalDerivativesProvider) is removed
// and the method should remain abstract in this class and be implemented by derived classes only
return getAugmentedInitialState(patchedSpacecraftStates.get(i), additionalEquations.get(i));
}
......