Class TriggerDate
- java.lang.Object
-
- org.orekit.forces.maneuvers.jacobians.TriggerDate
-
- All Implemented Interfaces:
ManeuverTriggersResetter
,AdditionalStateProvider
public class TriggerDate extends Object implements AdditionalStateProvider, ManeuverTriggersResetter
Generator for one column of a Jacobian matrix for special case of trigger dates.Typical use cases for this are estimation of maneuver start and stop date during either orbit determination or maneuver optimization.
Let \((t_0, y_0)\) be the state at propagation start, \((t_1, y_1)\) be the state at maneuver trigger time, \((t_t, y_t)\) be the state at any arbitrary time \(t\) during propagation, and \(f_m(t, y)\) be the contribution of the maneuver to the global ODE \(\frac{dy}{dt} = f(t, y)\). We are interested in the Jacobian column \(\frac{\partial y_t}{\partial t_1}\).
There are two parts in this Jacobian: the primary part corresponds to the full contribution of the acceleration due to the maneuver as it is delayed by a small amount \(dt_1\), whereas the secondary part corresponds to change of acceleration after maneuver start as the mass depletion is delayed and therefore the spacecraft mass is different from the mass for nominal start time.
The primary part is computed as follows. After trigger time \(t_1\) (according to propagation direction), \[\frac{\partial y_t}{\partial t_1} = \pm \frac{\partial y_t}{\partial y_1} f_m(t_1, y_1)\] where the sign depends on \(t_1\) being a start or stop trigger and propagation being forward or backward.
We don't have \(\frac{\partial y_t}{\partial y_1}\) available if \(t_1 \neq t_0\), but we have \(\frac{\partial y_t}{\partial y_0}\) at any time since it can be computed by integrating variational equations for numerical propagation or by other closed form expressions for analytical propagators. We use the classical composition rule to recover the state transition matrix with respect to intermediate time \(t_1\): \[\frac{\partial y_t}{\partial y_0} = \frac{\partial y_t}{\partial y_1} \frac{\partial y_1}{\partial y_0}\] We deduce \[\frac{\partial y_t}{\partial y_1} = \frac{\partial y_t}{\partial y_0} \left(\frac{\partial y_1}{\partial y_0}\right)^{-1}\]
The contribution of the primary part to the Jacobian column can therefore be computed using the following closed-form expression: \[\frac{\partial y_t}{\partial t_1} = \pm \frac{\partial y_t}{\partial y_0} \left(\frac{\partial y_1}{\partial y_0}\right)^{-1} f_m(t_1, y_1) = \frac{\partial y_t}{\partial y_0} c_1\] where \(c_1\) is the signed contribution of maneuver at \(t_1\) and is computed at trigger time by solving \(\frac{\partial y_1}{\partial y_0} c_1 = \pm f_m(t_1, y_1)\).
As the primary part of the column is generated using a closed-form expression, this generator implements the
AdditionalStateProvider
interface and stores the column directly in the primary state during propagation.As the closed-form expression requires picking \(c_1\) at trigger time \(t_1\), it works only if propagation starts outside of the maneuver and passes over \(t_1\) during integration.
The secondary part is computed as follows. We have acceleration \(\vec{\Gamma} = \frac{\vec{F}}{m}\) and \(m = m_0 - q (t - t_s)\), where \(m\) is current mass, \(m_0\) is initial mass and \(t_s\) is maneuver trigger time. A delay \(dt_s\) on trigger time induces delaying mass depletion. We get: \[d\vec{\Gamma} = \frac{-\vec{F}}{m^2} dm = \frac{-\vec{F}}{m^2} q dt_s = -\vec{\Gamma}\frac{q}{m} dt_s\] From this total differential, we extract the partial derivative of the acceleration \[\frac{\partial\vec{\Gamma}}{\partial t_s} = -\vec{\Gamma}\frac{q}{m}\]
The contribution of the secondary part to the Jacobian column can therefore be computed by integrating the partial derivative of the acceleration, to get the partial derivative of the position.
As the secondary part of the column is generated using a differential equation, a separate underlying generator implementing the
AdditionalDerivativesProvider
interface is set up to perform the integration during propagation.This generator takes care to sum up the primary and secondary parts so the full column of the Jacobian is computed.
The implementation takes care to not resetting \(c_1\) at propagation start. This allows to get proper Jacobian if we interrupt propagation in the middle of a maneuver and restart propagation where it left.
- Since:
- 11.1
- Author:
- Luc Maisonobe
- See Also:
MedianDate
,Duration
-
-
Constructor Summary
Constructors Constructor Description TriggerDate(String stmName, String triggerName, boolean manageStart, Maneuver maneuver, double threshold)
Simple constructor.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description double[]
getAdditionalState(SpacecraftState state)
Get the additional state.MassDepletionDelay
getMassDepletionDelay()
Get the mass depletion effect processor.String
getName()
Get the name of the additional state.void
init(SpacecraftState initialState, AbsoluteDate target)
Initialize the additional state provider at the start of propagation.void
maneuverTriggered(SpacecraftState state, boolean start)
Observe a maneuver trigger.SpacecraftState
resetState(SpacecraftState state)
Reset state as a maneuver triggers.boolean
yields(SpacecraftState state)
Check if this provider should yield so another provider has an opportunity to add missing parts.
-
-
-
Constructor Detail
-
TriggerDate
public TriggerDate(String stmName, String triggerName, boolean manageStart, Maneuver maneuver, double threshold)
Simple constructor.- Parameters:
stmName
- name of State Transition Matrix statetriggerName
- name of the parameter corresponding to the trigger date columnmanageStart
- if true, we compute derivatives with respect to maneuver startmaneuver
- maneuver force modelthreshold
- event detector threshold
-
-
Method Detail
-
getName
public String getName()
Get the name of the additional state.- Specified by:
getName
in interfaceAdditionalStateProvider
- Returns:
- name of the additional state (names containing "orekit" with any case are reserved for the library internal use)
-
yields
public boolean yields(SpacecraftState state)
Check if this provider should yield so another provider has an opportunity to add missing parts.Decision to yield is often based on an additional state being
already available
in the providedstate
(but it could theoretically also depend on an additional state derivative beingalready available
, or any other criterion). If for example a provider needs the state transition matrix, it could implement this method as:public boolean yields(final SpacecraftState state) { return !state.getAdditionalStates().containsKey("STM"); }
The default implementation returns
false
, meaning that state data can begenerated
immediately.The column state can be computed only if the State Transition Matrix state is available.
- Specified by:
yields
in interfaceAdditionalStateProvider
- Parameters:
state
- state to handle- Returns:
- true if this provider should yield so another provider has an opportunity to add missing parts as the state is incrementally built up
-
getMassDepletionDelay
public MassDepletionDelay getMassDepletionDelay()
Get the mass depletion effect processor.- Returns:
- mass depletion effect processor
-
init
public void init(SpacecraftState initialState, AbsoluteDate target)
Initialize the additional state provider at the start of propagation.- Specified by:
init
in interfaceAdditionalStateProvider
- Specified by:
init
in interfaceManeuverTriggersResetter
- Parameters:
initialState
- initial state information at the start of propagationtarget
- date of propagation
-
getAdditionalState
public double[] getAdditionalState(SpacecraftState state)
Get the additional state.- Specified by:
getAdditionalState
in interfaceAdditionalStateProvider
- Parameters:
state
- spacecraft state to which additional state should correspond- Returns:
- additional state corresponding to spacecraft state
-
maneuverTriggered
public void maneuverTriggered(SpacecraftState state, boolean start)
Observe a maneuver trigger.The
start
parameter corresponds to physical flow of time from past to future, not to propagation direction which can be backward. This means that during forward propagations, the first call will havestart
set totrue
and the second call will havestart
set tofalse
, whereas in backward propagation, the first call will havestart
set tofalse
and the second call will havestart
set totrue
.- Specified by:
maneuverTriggered
in interfaceManeuverTriggersResetter
- Parameters:
state
- spacecraft state at trigger date (before applying the maneuver)start
- if true, the trigger is the start of the maneuver
-
resetState
public SpacecraftState resetState(SpacecraftState state)
Reset state as a maneuver triggers.- Specified by:
resetState
in interfaceManeuverTriggersResetter
- Parameters:
state
- spacecraft state at trigger date- Returns:
- reset state taking into account maneuver start/stop
-
-