On version 12.0-SNAPSHOT, I try to propagate on a certain time range with the generation of a BoundedPropagator. The epoch of my initial state is inside the interval of propagation and isn’t the beginning of the interval.
After the propagation, when I retrieve the ephemeris, the minDate of the BoundedPropagator is the epoch of my initial state and not the start date of my propagation…
Example:
propagator.setInitialState(initialState); // with epoch ti and t0 < ti < tf
final EphemerisGenerator generator = propagator.getEphemerisGenerator();
propagator.propagate(t0, tf);
BoundedPropagator ephemeris = generator.getGeneratedEphemeris();
the minDate is ti and not t0 as I expected.
Is this a bug, the expected behavior or I did it incorrectly ?
I have another question still related to the use of BoundedPropagator.
I did a propagation with the propagation of the covariance and generation of a BoundedPropagator.
final MatricesHarvester harvester = propagator.setupMatricesComputation("stm", null, null);
final StateCovarianceMatrixProvider covarianceProvider =
new StateCovarianceMatrixProvider("cov", "stm", harvester, covariance);
propagator.addAdditionalStateProvider(covarianceProvider);
final EphemerisGenerator generator = propagator.getEphemerisGenerator();
propagator.propagate(startDate, targetDate);
final BoundedPropagator ephemeris = generator.getGeneratedEphemeris();
The finalCovariance is incorrect and different from the value obtained by a direct propagation.
Is it expected that the covariance propagation doesn’t work with BoundedPropagator, is it a bug or is it a problem with the way I did it ?
I think an IntegratedEphemeris behaves like any other analytical propagator and resets its state at the end of a propagation. So each time you call propagate directly or indirectly (as with getPVCoordinates), you change the initial date. Edit: I’m not sure this is what you’re talking about, I might have misunderstood. The actual minDate may be the earliest one ever used by the propagator, I need to check the code.
The discrepancy you are seeing in the covariance might be due to differences in integration and interpolation noise.
From what I understood, the minDate and maxDate in a BoundedPropagator represent the interval where the trajectory is available. After the propagation between t0 and tf to create the ephemeris, I was expecting the minDate to be t0 and not the epoch of the initial state.
To summarize, after my propagation on [ t0, tf ] to generate the ephemeris, I can only use the BoundedPropagator on the interval [ ti, tf ] with ti the epoch of the initial state. That’s what surprised me.
For the propagation of the covariance with a BoundedPropagator, the covariance from the BoundedPropagator is very different from the covariance obtained from the direct propagation at the same epoch. Not sure that it’s only linked to interpolation noise or differences in integration.
But if these mechanisms should work, I’ll check on my side to see if I’ve made a mistake.
I couldn’t reproduce the behavior you experienced.
I used Orekit on branch develop, tutorials on branch 12.0-testing, and the tutorial propagation\EphemerisMode.
In this tutorial I changed:
propagator.setInitialState(initialState);
final SpacecraftState finalState = propagator.propagate(initialDate.shiftedBy(6000));
With:
propagator.setInitialState(initialState);
final AbsoluteDate ti = initialState.getDate();
final AbsoluteDate t0 = ti.shiftedBy(-6000.);
final AbsoluteDate tf = ti.shiftedBy(6000.);
System.out.println("t0 = " + t0);
System.out.println("ti = " + ti);
System.out.println("tf = " + tf);
// Propagation with storage of the results in an integrated ephemeris
final SpacecraftState finalState = propagator.propagate(t0, tf);
And the output is:
t0 = 2004-01-01T21:50:00.000Z
ti = 2004-01-01T23:30:00.000Z
tf = 2004-01-02T01:10:00.000Z
Numerical propagation:
Final date: 2004-01-02T01:10:00.000Z
equinoctial parameters: {a: 2.4396159E7; ex: 0.11393312156755062; ey: 0.719345418868777; hx: -0.009567941763699867; hy: -0.06040960680288257; lv: 583.1250344407321;}
Ephemeris defined from 2004-01-01T21:50:00.000Z to 2004-01-02T01:10:00.000Z
So I do have an ephemeris defined on [t0, tf]…
I’ll have a look at the covariance issue, but since StateCovarianceMatrixProvider is an AdditionalStateProviderand the initial state in the ephemeris is at t0, I’m not surprised the results are inconsistent.
I’ve tested it on the tutorial CovariancePropagation and this time I could reproduce the experienced behavior.
When using
The covariance I get is actually the initial covariance.
This happens because additional states are not managed and are simply copied in IntegratedEphemeris (which is the class used by the ephemeris generator).
However, additional equations are managed by IntegratedEphemeris.
public StateCovariance getStateCovariance(final SpacecraftState state) {
// Get the current propagated covariance
final RealMatrix covarianceMatrix = toRealMatrix(state.getAdditionalState(additionalName));
[...]
Here we extract the “covariance” as an additional state from the SpacecraftState, but this covariance is equal to its initial value since additional states are un-managed in the ephemeris.
But if we do this instead:
public StateCovariance getStateCovariance(final SpacecraftState state) {
// Get the current propagated covariance
final RealMatrix covarianceMatrix = toRealMatrix(getAdditionalState(state));
[...]
This time we call a function that uses the MatricesHarvester, which is an additional equation that is managed by the ephemeris.
And with just that our final covariance from the ephemeris is the same as the one propagated numerically.
I’d say it’s a bug but I’d like to have @bcazabonne and @luc thoughts on this.
I’m not sure it’s not an expected behavior, although it seems counter-intuitive.
My main doubt is that it would create some performance issues to call on the additional state derivatives each time we need the covariance.
For the first case, I will try to understand where my problem comes from and, eventually, I will try to extract a simple example that reproduces the problem - if the problem is not myself -
I understood where my first problem comes from (problem with the minDate of the bounded propagator).
It is linked with the usage of the method setResetAtEnd of the propagator. Before the propagation, if I call setResetAtEnd with false, the minDate of the BoundedPropagator is not correct and is equal to the epoch of my initial orbit.
After the initial backward propagation, it seems that it resets the propagator to the initial state and so, restarts from the date of the initial state: in this case, the reset is not done at the end of the complete propagation. The method setResetAtEnd seems incompatible with a backward propagation.
Here is a small example that reproduces this behavior:
You will get the same issue, without backward propagation.
The problem comes from AbstractIntegratedPropagator.propagate(final AbsoluteDate tStart, final AbsoluteDate tEnd) method.
Here a first integration is done if tStart is different from initial state date. But neither the event detectors nor the ephemeris generator are set up yet during this integration.
If resetAtEnd=false then this first integration is “thrown away” entirely (I think, maybe some internal states of the integrator are modified…).
If resetAtEnd=true, the initial state is reset to the one at tStart.
Then, in a second time, the dynamics is integrated from initial state date to final date, with event detectors and ephemeris generators activated.
So technically, if resetAtEnd=false then the result of: propagate(tStart, tEnd)
seems striclty equivalent to: propagate(tEnd)
Maybe it’s an intended behavior but I think it’s a bug. Because, depending on the value of resetAtEnd the results of propagate(tStart, tEnd) are different (in your example, you need to add a force model to make it appear).
And this is not, in my opinion, what a user would expect.
This was not intentional. I agree the bug lies probably here.
The idea of the two integrations propagation was that the first integration is there to be sure we start where we want to start, therefore we must use the end of the first integration as the start of the second one, event if resetAtEnd=false.
I created issues #1253 and #1254 where I tried to explain correctly the problems.
I let you update the description of the problems if what I wrote is not clear enough.