I’m trying to upgrade my application from Orekit v11.0.1 to Orekit 11.1.2, but I have some problems during the propagation of the spacecraft state along with some additional states (which also affect the main states).
Following the suggestions given in Question about additional parameters for acceleration computation, this was possible by simply returning an array instead of null in the AdditionalEquations.computeDerivatives method. This array was then used to update the primary state derivatives.
However, if I understand it correctly, the recent changes seem to have precluded this possibility, as the primary derivatives are not updated anymore.
Is there anything that I am missing? Do you know if there is an alternative way to achieve the desired behavior?
You are right, this possibility has disappeared at Orekit level.
It is still available at Hipparchus level, and is still as ugly as before there.
Discussing with the local team, we could probably propose adding in the new interface AdditionalDerivativesProvider a method mainStateDerivativesIncrement(SpacecraftState) (or a better name) that would be called just after derivatives(SpacecraftState) and would provide the part to be added to the main state, just like the return value of the former AdditionalEquations interface computeDerivatives method. The internal temporary adapter that is currently used to map the former AdditionalEquations interface to the new AdditionalDerivativesProvider interface would of course also map call this method.
The drawback of this fix is that derivatives and mainStateDerivativesIncrement would be called separately, one after the other, so if computations of derivatives are intertwined, then some computation will be done twice, once in each independent calls. I don’t see any way to circumvent this drawback.
If this solution suits you, could you open an issue in the forge?
Many thanks for your quick reply. Your suggestion seems fine to me.
Maybe to avoid duplicating the computations, would it make sense to:
In the AdditionalDerivativesProvider interface, define a new method (e.g. mainStateDerivativesIncrement(SpacecraftState), as you suggested) that is called after the derivatives(SpacecraftState) call
In all the implementing classes, define a new internal variable, for instance double[] additionalPrimaryDot
In all the implementing classes, modify the derivatives method, to populate also the additionalPrimaryDot variable.
In all the implementing classes, override the mainStateDerivativesIncrement(SpacecraftState) method by returning additionalPrimaryDot
For instance in the case of AdditionalEquationsAdapter class, this would look like:
@Override
public double[] derivatives(final SpacecraftState state) {
final double[] pDot = new double[getDimension()];
additionalPrimaryDot = equations.computeDerivatives(state, pDot);
return pDot;
}
@Override
public double[] mainStateDerivativeIncrement(final SpacecraftState state) {
return additionalPrimaryDot;
}
Not sure this would work for all the other classes, though.
One other idea is to return a Pair<...>, which is the approach that MultivariateJacobianFunction uses. Could use a custom type instead of Pair for better method names. Seems like it could be done with a default method in AdditionalDeriviativesProvider to maintain backwards compatibility.
Micro, it looks like your suggestion would create an ordering requirement for calling those two methods. That tends to get confusing (leads to bugs) and it prohibits thread safety.