Question about additional parameters for acceleration computation

Hello,

In a NumericalPropagator, I want to use a custom implementation of AbstractForceModel with an acceleration depending on an additional state associated with an AdditionalEquations that calculates its derivative. This additional state was added to the SpacecraftState.
Just before the propagation, the initialState of the propagator contains the additional state.
But, at the first step, when my ForceModel is called to compute the acceleration, the SpacecraftState that is given as method input does not contains any additional state.
By looking into the code, I think the disappearance comes from the method AbstractPropagator.updateAdditionalStates.
This method receives as input a SpacecraftState without any additional state, and add to it, first, additional state that are not managed (not associated with an AdditionalStateProvider or AdditionalEquations (thanks to AbstractIntegratedPropagator.isAdditionalStateManaged override), then update additional states associated with an AdditionalStateProvider.
Thus, as my additional state is managed by an AdditionalEquations and not by an AdditionalStateProvider, it is not added to the SpacecraftState.

I would like to know if I am taking the correct path to do this, or if I have to handle this type of acceleration computation in another way.

Thank you for your help,
Regards

Hi @valerian,

Welcome back to the Orekit forum!

I’m not sure this will help but did you re-initialize the propagator with the new SpacecraftState where the additional equations were added ?

There is an example in Model l.384. This is the model for batch least-squares orbit determination. In this method we add the partial derivatives equation calculation to the propagator.
On one of the final lines you’ll see that the propagator initial state is resetted with the new SpacecraftState: propagator.resetInitialState(stateWithDerivatives);

Maybe it is that line that you missed ?

Hope this helps.

Regards,
Maxime

Edit for previous message:
I just re-read your post and it seems you did add the new SpacecraftState to your propagator.

Nevertheless you may find your answer in the method I linked above.
The PartialDerivativesEquation class is indeed an AdditionalEquations and it is computed during propagation…
So maybe there is something to dig in there.

Maxime

Thank you for your answer.

I looked into the code a little further, and it seems that my problem comes from hipparchus.ExpandableODE.
in ExpandableODE.computeDerivatives(t, y) that is called by the propagator, the computation of the derivatives are actually performed in two steps.
First the primaryState derivatives are computed. in AbstractIntegratedPropagator.ConvertedMainStateEquations, a spacecraft state is built, but without additional states linked with equations.
Second, the secondary states are computed using secondary equations. Here, the additional states corresponding to the equations are available.
So, in the first computation (main state), when the acceleration is calculated, my needed additional state, as it is linked with an equation, is not present in the SpacecraftState, and seems unreachable as it is not given by the ExpandanbleODE.computeDerivatives method.

Have I correctly understood the behavior of the propagator?
In this case, would you have any idea on how I can transfer my additional state to the acceleration computation method?

Thank you,
Regards,

Valérian

Hi Valérian,

The design of primary/secondary equations in ODE is based on the idea that the primary equations computes derivatives of primary state which are based only on the state itself. Secondary (aka additional) equations can depend on both primary and secondary states, they usually compute the derivatives of secondary state.

As your equations do depend on secondary state, they belong to secondary equations, BUT they also change the primary state derivatives. In a perfect world, I would say this mean primary state is not rich enough and should be extended so your equations really belong to the mrimary state (after all, they do change primary state derivatives). However, this would clearly not suit your needs because the differential equations of the motion implemented in Orekit only depend on orbit and attitude.

However, this case despite being very rare can be handled. If you look at the javadoc for SecondaryODE.computeDerivatives, you will see that the primaryDot array can be changed by the secondary equation. The javadoc for this parameter reads:

  primaryDot array containing the derivative of the primary state vector
 (the method is allowed to change the derivatives here, when the additional
 equations do have an effect on the primary equations)

This feature is available at Orekit level too (see lines 729-733 in AbstractIntegratedPropagator). If AdditionalEquations.computeDerivatives return an array instead of returning null, then this array will be considered to be an additional contribution to the primary state derivatives (i.e. the orbit).

So instead of implementing your equations as a ForceModel, you can implement it fully as an AdditionalEquations, andhave this additional equation have a side effect on orbit because it is an acceleration. You will have to deal with the orbit type by yourself, though. If you are propagating in Cartesian parameters, it is simple: as the state is (pos, vel), the derivative of the state is (vel, acc) so your additional equation should return an array where the 3 first elements are0 and the 3 last elements are the contribution of this model to the acceleration. This vector will be added to the other known contributions (typically Keplerian attraction, gravity field, …). If you want your equation to be usable also when propagating with other orbit types, it will be more complex, you will have to use compute the Jacobian of the orbit with respect to Cartesian parameters and multiply by the (vel, acc) vector so you get the derivatives or the orbital parameters (basically this is how Gaussian equations work). You can look at the NumericalPropagator.Main internal class and its addNonKeplerianAcceleration method for a way to convert an accelration to a primary state derivative.

Thank you very much Luc for this detailed answer. We now understand the reasons for this design.

It is good to know that it is possible to make this work, however it seems like a lot of effort is required. Besides, it would require significant changes in the way that we handle maneuvers (our generic class is related to Orekit’s ForceModel).
I think we will try other approaches first, such as computing an approximate value for our additional state outside of Orekit : it would probably be sufficient to get a ForceModel accurate enough.

Thanks again, and see you soon in Darmstadt.