Additional State not resetted in event handler
When trying to use an Event Handler to reset an additional state (called "A"), changing its value from -1 to +1 when the event is detected. The new state built inside the handler contains the proper value (+1), however, when the propagator goes on, it seems to ignore it and keeps its original value of "-1". Console output looks like this:
2000-01-01T00:00:00.000 A -1.0
2000-01-01T00:00:01.000 A -1.0
Additional state A set to +1
2000-01-01T00:00:02.000 A -1.0
2000-01-01T00:00:03.000 A -1.0
2000-01-01T00:00:04.000 A -1.0
2000-01-01T00:00:05.000 A -1.0
Here is the code to reproduce the results (Orekit version is 9.1):
public static void main(String[] args) throws OrekitException {
// Load Orekit data
DataProvidersManager.getInstance().
addProvider(new DirectoryCrawler(new File("OREKIT_DATA_LOCATION_HERE")));
// Build orbit
AbsoluteDate date0 = new AbsoluteDate(2000, 1, 1, TimeScalesFactory.getUTC());
Orbit orbit = new KeplerianOrbit(7.1E6, 0, 0, 0, 0, 0,
PositionAngle.TRUE, FramesFactory.getGCRF(), date0,
Constants.WGS84_EARTH_MU);
// Build propagator
ODEIntegrator odeIntegrator = new DormandPrince853Integrator(1E-3, 1E3, 1E-6, 1E-6);
NumericalPropagator propagator = new NumericalPropagator(odeIntegrator);
// Instantiate additional states
Map<String, double[]> additionalStates = new HashMap<String, double[]>();
additionalStates.put("A", new double[] { -1 });
// Create initial state and add it to the propagator
SpacecraftState initialState = new SpacecraftState(orbit, additionalStates);
propagator.setInitialState(initialState);
// Create date detector and handler
DateDetector dateDetector = new DateDetector(date0.shiftedBy(3)).
withHandler(new EventHandler<DateDetector>() {
@Override
public Action eventOccurred(SpacecraftState s,
DateDetector detector,
boolean increasing)
throws OrekitException {
return Action.RESET_STATE;
}
@Override
public SpacecraftState resetState(DateDetector detector,
SpacecraftState oldState) {
Map<String, double[]> newAdditionalStates =
new HashMap<String, double[]>();
newAdditionalStates.put("A", new double[] { +1 });
SpacecraftState newSpacecraftState =
new SpacecraftState(oldState.getOrbit(),
oldState.getAttitude(),
oldState.getMass(),
newAdditionalStates);
System.out.println("Additional state A set to +1");
return newSpacecraftState;
}
});
propagator.addEventDetector(dateDetector);
// Set the propagator mode
propagator.setMasterMode(1, new OrekitFixedStepHandler() {
@Override
public void handleStep(SpacecraftState currentState, boolean isLast)
throws OrekitException {
String line = currentState.getDate().toString();
for (Entry<String, double[]> entry :
currentState.getAdditionalStates().entrySet()) {
line += " " + entry.getKey();
for (double d : entry.getValue()) {
line += " " + d;
}
}
System.out.println(line);
}
});
// Propagate
propagator.propagate(date0, date0.shiftedBy(5));
}
For additional info, this was Luc's reponse:
"...The value -1 at 00:00:02.000 is normal. The state is really
changed
at 00:00:03.000. the fact the print statement from event handler
and the print statement from step handler are out of order is a
know limitation of Orekit which we cannot fix.
2000-01-01T00:00:03.000 A -1.0
2000-01-01T00:00:04.000 A -1.0
The value -1 at 00:00:03.000 could be considered normal, as at
that
time the value changes, so both -1 or +1 could be acceptable.
The value -1 at 00:00:04.000 is a bug! It is due to the fact this
additional state as no corresponding provider. I.E. it was set up
un the initial state, but theaddAdditionalStateProvider method from
the Propagator interface was never called. Therefore, the propagator
considers the additional state is fixed and that when creating
complete states throughout the propagation it simply copies the
value from initial state. This is done in the protected method
updateAdditionalStates in the AbstractPropagator class."
(from redmine: issue id 483, created on 2018-07-11)