Hello,
I use additonal states to store data during the simulation. The state is updated during the simulation thanks to event handlers. The propagation works well but when I try to build the ephemerides the additional state is not reinitialized… so the state is not the one during the simulation at this time.
I may use badly ephemerides, below is the code to reproduce the problem. Any idea of what I am doing wrong ?
package space.exotrail.exoops.numerical.orekit;
import java.io.IOException;
import org.hipparchus.ode.AbstractIntegrator;
import org.hipparchus.ode.nonstiff.ClassicalRungeKuttaIntegrator;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
import org.orekit.errors.OrekitException;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.orbits.KeplerianOrbit;
import org.orekit.orbits.Orbit;
import org.orekit.orbits.PositionAngle;
import org.orekit.propagation.AdditionalStateProvider;
import org.orekit.propagation.BoundedPropagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.DateDetector;
import org.orekit.propagation.events.EventDetector;
import org.orekit.propagation.events.handlers.EventHandler;
import org.orekit.propagation.numerical.NumericalPropagator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
public class AdditionalStatesTest {
public static final String STATE_NAME = "STATE";
public static final int STATE_INDEX = 0;
public static final int STATE_START = 10;
public static final int STATE_END = -10;
public class Handler implements EventHandler<EventDetector> {
private StateProviderTest additionalStateProvider;
public Handler (StateProviderTest additionalStateProvider) {
this.additionalStateProvider = additionalStateProvider;
}
@Override
public void init(final SpacecraftState s0, final AbsoluteDate t) {
additionalStateProvider.setFirstPart(true);
}
@Override
public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing)
throws OrekitException {
additionalStateProvider.setFirstPart(false);
return Action.CONTINUE;
}
}
public class StateProviderTest implements AdditionalStateProvider {
public boolean firstPart = true;
@Override
public String getName() {
return STATE_NAME;
}
@Override
public double[] getAdditionalState(SpacecraftState state) throws OrekitException {
if (isFirstPart()) {
double[] ret = { STATE_START };
return ret;
} else {
double[] ret = { STATE_END };
return ret;
}
}
public boolean isFirstPart() {
return firstPart;
}
public void setFirstPart(boolean firstPart) {
this.firstPart = firstPart;
}
}
@Test
public void TestAdditionalStates() throws OrekitException, IOException {
// Initial orbit parameters
double a = 24396159; // semi major axis in meters
double e = 0.72831215; // eccentricity
double i = FastMath.toRadians(7); // inclination
double omega = FastMath.toRadians(180); // perigee argument
double raan = FastMath.toRadians(261); // right ascension of ascending node
double lM = 0; // mean anomaly
// Inertial frame
Frame inertialFrame = FramesFactory.getEME2000();
// Initial date in UTC time scale
TimeScale utc = TimeScalesFactory.getUTC();
AbsoluteDate initialDate = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000, utc);
// gravitation coefficient
double mu = 3.986004415e+14;
// Orbit construction as Keplerian
Orbit initialOrbit = new KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN,
inertialFrame, initialDate, mu);
// Initialize state
SpacecraftState initialState = new SpacecraftState(initialOrbit);
// Numerical propagation with no perturbation (only Keplerian movement)
// Using a very simple integrator with a fixed step: classical Runge-Kutta
double stepSize = 10; // the step is ten seconds
AbstractIntegrator integrator = new ClassicalRungeKuttaIntegrator(stepSize);
NumericalPropagator propagator = new NumericalPropagator(integrator);
// Set the propagator to ephemeris mode
propagator.setEphemerisMode();
StateProviderTest stateProvider = new StateProviderTest();
propagator.addEventDetector(new DateDetector(initialDate.shiftedBy(3000))
.withHandler(new Handler(stateProvider)));
propagator.addAdditionalStateProvider(stateProvider);
propagator.setInitialState(initialState);
// Propagation with storage of the results in an integrated ephemeris
SpacecraftState firstPartState = propagator.propagate(initialDate.shiftedBy(2000));
propagator.resetInitialState(initialState);
SpacecraftState finalState = propagator.propagate(initialDate.shiftedBy(6000));
BoundedPropagator ephemeris = propagator.getGeneratedEphemeris();
double stateAfterPropagation = finalState.getAdditionalState(STATE_NAME)[STATE_INDEX];
double stateInFirstPartOfPropagation = firstPartState
.getAdditionalState(STATE_NAME)[STATE_INDEX];
double stateInFirstPartOfEphemerides = ephemeris.propagate(initialDate.shiftedBy(1000))
.getAdditionalState(STATE_NAME)[STATE_INDEX];
double stateInSecondPartOfEphemerides = ephemeris.propagate(initialDate.shiftedBy(4000))
.getAdditionalState(STATE_NAME)[STATE_INDEX];
Assert.assertEquals(STATE_START, stateInFirstPartOfPropagation, 1e-12);
Assert.assertEquals(STATE_END, stateAfterPropagation, 1e-12);
Assert.assertEquals(STATE_START, stateInFirstPartOfEphemerides, 1e-12);
Assert.assertEquals(STATE_END, stateInSecondPartOfEphemerides, 1e-12);
}
}