public class TriggerDate extends Object implements AdditionalStateProvider, ManeuverTriggersResetter
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.
MedianDate
,
Duration
Constructor and Description |
---|
TriggerDate(String stmName,
String triggerName,
boolean manageStart,
Maneuver maneuver,
double threshold)
Simple constructor.
|
Modifier and Type | Method and 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)
Initialization method called at propagation start.
|
void |
maneuverTriggered(SpacecraftState state,
boolean start)
Observe a maneuver trigger.
|
SpacecraftState |
resetState(SpacecraftState state)
Reset state as a maneuver triggers.
|
boolean |
yield(SpacecraftState state)
Check if this provider should yield so another provider has an opportunity to add missing parts.
|
public TriggerDate(String stmName, String triggerName, boolean manageStart, Maneuver maneuver, double threshold)
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 thresholdpublic String getName()
getName
in interface AdditionalStateProvider
public boolean yield(SpacecraftState state)
Decision to yield is often based on an additional state being already available
in the provided state
(but it could theoretically also depend on
an additional state derivative being already available
, or any other criterion). If for example a provider needs the state transition
matrix, it could implement this method as:
public boolean yield(final SpacecraftState state) {
return !state.getAdditionalStates().containsKey("STM");
}
The default implementation returns false
, meaning that state data can be
generated
immediately.
The column state can be computed only if the State Transition Matrix state is available.
yield
in interface AdditionalStateProvider
state
- state to handlepublic MassDepletionDelay getMassDepletionDelay()
public void init(SpacecraftState initialState, AbsoluteDate target)
The default implementation does nothing.
init
in interface ManeuverTriggersResetter
initialState
- initial spacecraft state (at the start of propagation).target
- date of propagation. Not equal to initialState.getDate()
.public double[] getAdditionalState(SpacecraftState state)
getAdditionalState
in interface AdditionalStateProvider
state
- spacecraft state to which additional state should correspondpublic void maneuverTriggered(SpacecraftState state, boolean start)
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 have
start
set to true
and the second call will have
start
set to false
, whereas in backward propagation,
the first call will have start
set to false
and the second
call will have start
set to true
.
maneuverTriggered
in interface ManeuverTriggersResetter
state
- spacecraft state at trigger date (before applying the maneuver)start
- if true, the trigger is the start of the maneuverpublic SpacecraftState resetState(SpacecraftState state)
resetState
in interface ManeuverTriggersResetter
state
- spacecraft state at trigger dateCopyright © 2002-2022 CS GROUP. All rights reserved.