Hi,
Recently I met with a problem that might be a bug in Orekit. And I would like to hear your opinions.
The problem occurs when determining orbits of multiple satellites. In the current software, MeasurementHandler.handleStep
only checks the currentDate
of interpolator 0 (from line 73 to 78):
> // Current state date for interpolator 0
> final AbsoluteDate currentDate = interpolators.get(0).getCurrentState().getDate();
> if (model.isForwardPropagation() && next.getDate().compareTo(currentDate) > 0 ||
> !model.isForwardPropagation() && next.getDate().compareTo(currentDate) < 0) {
> return;
> }
However, when there are more than one satellites, although PropagatorsParallelizer
will ensure them to propagate with the same step, there is still a minor time gap (maybe only a few milliseconds) among the satellites. Because they run independently and may not have exactly the same speed and ends strictly at the same moment. So, there is a chance that satellite 0 finishes this step first and triggers MeasurementHandler
to process a measurement that has nothing to do with it.
Let me explain this in an example. Say I need to determine two satellite (0 and 1) orbits simultaneously. The next measurement that needs to process in MeasurementHandler.handleStep
is a range observation from satellite 1 at time t0. While PropagatorsParallelizer
ensures them to propagate simultaneously to the next step t0, the thread of satellite 0 finishes propagation first (a few milliseconds ahead of satellite 1), it will trigger MeasurementHandler.handleStep
. And since the currentDate
of interpolators.get(0)
indeed reaches t0, it will pass the if-clause above and start to process this range measurement that belongs to satellite 1.
The reason I found this is that I sometimes met with a strange situation that the theta
in AbstractODEStateInterpolator.getInterpolatedState
is even larger than 1. I traced back to this and I think this part of MeasurementHandler
causes the problem. Because the situation above happens, when it starts to process this range measurement, actually the satellite 1 hasn’t reached to t0 yet. So the interpolation will process a step that even larger than interpolation step, and cause theta
larger than 1. Although in Orekit it allows to accept theta
larger than 1, it still causes the loss of accuracy and requires longer time to process.
What I think would be a fix is to check currentDate
of all relevant interpolators (in case more than one satellite involved like inter-satellite range) instead of only check interpolator 0. Something like moving the above if-clause to line 85:
> // get the observed measurement
> final ObservedMeasurement<?> observed = next.getMeasurement();
> // estimate the theoretical measurement
> final SpacecraftState[] states = new SpacecraftState[observed.getSatellites().size()];
> for (int i = 0; i < states.length; ++i) {
> final ObservableSatellite satellite = observed.getSatellites().get(i);
> final int satInd = satellite.getPropagatorIndex();
> final AbsoluteDate currentDate = interpolators.get(satInd).getCurrentState().getDate();
> if ((model.isForwardPropagation() && (next.getDate().compareTo(currentDate) > 0)) ||
> (!model.isForwardPropagation() && (next.getDate().compareTo(currentDate) < 0))) {
> return;
> }
> states[i] = interpolators.get(satInd).getInterpolatedState(next.getDate());
> }
I hope I explain this clearly. And I wonder if I get this correct.
Best regards,
Xingchi