Module: thrusterStateEffector
Executive Summary
This module provides an implementation of the behavior of thrusters. Thrusters are modeled dynamically using a first-order ordinary differential equation, which is compatible with variable time step integrators. With this module, there are now two different thruster implementations. See Module: thrusterDynamicEffector for the previous version, which implemented thrusters using on and off-ramps, although not compatible with variable time step integrators.
Message Connection Descriptions
The following table lists all the module input and output messages. The module msg variable name is set by the user from python. The msg type contains a link to the message structure definition, while the description provides information on what this message is used for.
Msg Variable Name |
Msg Type |
Description |
---|---|---|
cmdsInMsg |
(optional) input message with thruster commands. If not connected the thruster commands are set to zero. |
|
thrusterOutMsgs |
output message vector for thruster data |
Detailed Module Description
Thruster Modeling
The functionalities of this thruster implementation are identical to the ones seen in Module: thrusterDynamicEffector. For a general description of the thruster implementation in Basilisk, namely how the forces and torques are computed, see that module’s documentation.
The main difference between the two thruster implementations comes from how the thrustFactor
is computed and updated at each timestep. The thrustFactor
is a parameter specific to each thruster and ranges from 0 to 1. It defines what the current magnitude of the thrust is: at 0 the thruster is off, and at 1 the thruster is at maxThrust
. While the previous thruster module computed the thrustFactor
using on and off-ramps at the beginning and end of the thrusting maneuver, respectively, with a constant steady-state value of 1 in-between, this module updates that value through a first-order ordinary differential equation.
The state variable used in this state effector is \(\kappa\), which is a vector of thrustFactors
for each thruster. As with Module: thrusterDynamicEffector, the addThruster()
method augments the vector of thruster inside the module. However, for this module the state vector \(\kappa\) is also augmented in this method.
Let \(\kappa_i\) correspond to the thrustFactor
of the i-th thruster. It has two governing differential equations, depending on whether a thrust command is present or not. The differential equation when thrusting is given by
where \(\omega\), in rad/s, corresponds to the cutoff frequency of the first-order filter, and is thruster-specific. The differential equation when not thrusting is given by
While the value of \(\kappa_i\) for each thruster is computed numerically by integrating these ODEs, there are closed-form solutions to these equations that are used for validation and verification purposes. The solutions to each of these differential equations are given, respectively, by
where \(\kappa_{0,i}\) corresponds to the initial conditions of the thrusterFactor
variable for the i-th particular thruster.
Adding Thrusters to Auxiliary Bodies
This thruster effector does not have to only be attached to the primary spacecraft body \(B\). Rather, it is possible to attach this to a rigid body sub-component of the spacecraft where now the thruster location and orientations vary with time with respect to the \(B\) frame. However, note that currently attaching a thruster to a sub-component just determines where the thruster location and thrust direction are. The thrust does not impact the dynamics of a hinged panel, for example. Currently there is one-way coupling here where the sub-component states impact the location and orientation of the thruster, but firing the thruster does not impact the effector.
Let \(F\) be the body-fixed frame of the rigid body sub-component, such as Module: prescribedMotionStateEffector. With this effector case it is ok that the thruster does not impact the effector as the effector motion is prescribed. If the thruster is added to an auxiliary body \(F\) which is connected to the main spacecraft body \(B\), then this is accomplished using:
thrusterSet.addThruster(thruster1, bodyStatesMsg)
Here thruster1
is the thruster being added, and bodyStatesMsg
is the state output message of
the platform \(F\). In the Update()
routine the position of the platform \(F\) relative
to \(B\) is recomputed each time step.
The thruster state output message contains variables that end with _B
. These vectors are always
written with spacecraft body frame \(B\) vector components. However, the output message
states thrusterDirection
and thrusterLocation
don’t contain the _B
suffix because
they are written in either \(B\) frame components if the thruster is attached to the body
frame \(B\), and in the sub-component frame \(F\) if attached to an auxiliary spacecraft
component.
Model Assumptions and Limitations
Assumptions
The model assumes that the behavior of a thruster is represented by a first-order filter. Therefore, due to the simplicity of the model, some real-world behaviors cannot be simulated, such as overshoot or damping.
The thruster module also assumes that the thruster always thrusts along its thrust directions axis. No dispersion is added to the thrust axis with respect to the nominal thruster axis.
Limitations
One of the limitations of this model relates to the dynamic nature of this thruster implementation. The thrust is simulated through the thrust factor, which is updated by integrating a differencial equation. This means that it is not possible to reproduce on-off behavior, where the thruster goes from not thrusting to being at maximum thrust or vice-versa. Using this dynamic model, we would have to use infinite derivatives to reproduce this behavior, which is not numerically feasible. To replicate this behavior, the user should use the older version of the thruster effector (Module: thrusterDynamicEffector) with both on or off-ramps disabled.
Another limitation is that the \(I_{sp}\) used is constant throughout the simulation. This means that the mass flow rate of the thruster is constant - the thruster will lose mass as soon as the valve is open, independent of how much thrust force is being produced. If the user needs to change the \(I_{sp}\) value of any of the thrusters, the simulation needs to be stop and restarted.
Note
The dynamic behaviour of this module is governed by the cutoffFrequency
variable inside Module: THRSimConfig. Its default value is equal to 10 rad/s. All variables related to on and off-ramps have no impact on this module and are instead supposed to be used to determine the dynamic behaviour within Module: thrusterDynamicEffector.
User Guide
This section contains conceptual overviews of the code and clear examples for the prospective user.
Module Setup
To use the thruster state effector module, the user first needs to create the thruster and populate it with the necessary information, such as thruster magnitude, minimum on time, etc. This can be done with the help of the simIncludeThruster Basilisk Python library. The code to create a generic thruster is shown below:
thFactory = simIncludeThruster.thrusterFactory()
TH1 = thFactory.create('MOOG_Monarc_1',
[1, 0, 0], # location in B-frame
[0, 1, 0] # thruster force direction in B-frame
)
The code above creates the generic thruster Monarc 1. To create the thruster effector and connect the thruster to it, the code below is used:
thrustersStateEffector = thrusterStateEffector.ThrusterStateEffector()
thFactory.addToSpacecraft("Thrusters",
thrustersStateEffector,
scObject)
Assuming that the user has created a list of initial conditions called initialConditions
, then setting the initial conditions for all thrusters is done with the code below:
thrustersStateEffector.kappaInit = messaging.DoubleVector(initialConditions)
-
class ThrusterStateEffector : public StateEffector, public SysModel
- #include <thrusterStateEffector.h>
thruster dynamic effector class
Public Functions
-
ThrusterStateEffector()
The Constructor.
-
~ThrusterStateEffector()
The destructor.
-
void Reset(uint64_t CurrentSimNanos)
This method is used to reset the module.
- Returns:
void
-
bool ReadInputs()
This method is used to read the incoming command message and set the associated command structure for operating the thrusters.
- Returns:
void
-
void writeOutputStateMessages(uint64_t CurrentClock)
This method is here to write the output message structure into the specified message.
- Parameters:
CurrentClock – The current time used for time-stamping the message
- Returns:
void
-
void registerStates(DynParamManager &states)
— Method for the effector to register its states
This method allows the thruster state effector to register its state kappa with the dyn param manager
-
void linkInStates(DynParamManager &states)
— Method for the effector to get access of other states
This method is used to link the states to the thrusters
- Parameters:
states – The states to link
- Returns:
void
-
void computeDerivatives(double integTime, Eigen::Vector3d rDDot_BN_N, Eigen::Vector3d omegaDot_BN_B, Eigen::Vector3d sigma_BN)
— Method for each stateEffector to calculate derivatives
This method is used to find the derivatives for the thruster stateEffector
-
void calcForceTorqueOnBody(double integTime, Eigen::Vector3d omega_BN_B)
-
void updateContributions(double integTime, BackSubMatrices &backSubContr, Eigen::Vector3d sigma_BN, Eigen::Vector3d omega_BN_B, Eigen::Vector3d g_N)
Method to pass the forces and torques onto the hub.
-
void updateEffectorMassProps(double integTime)
This is the method for the thruster effector to add its contributions to the mass props and mass prop rates of the vehicle
-
void UpdateState(uint64_t CurrentSimNanos)
This method is the main cyclical call for the scheduled part of the thruster dynamics model. It reads the current commands array and sets the thruster configuration data based on that incoming command set. Note that the main dynamical method (ComputeDynamics()) is not called here and is intended to be called from the dynamics plant in the system
- Parameters:
CurrentSimNanos – The current simulation time in nanoseconds
- Returns:
void
-
void addThruster(THRSimConfig *newThruster)
— Add a new thruster to the thruster set
-
void addThruster(THRSimConfig *newThruster, Message<SCStatesMsgPayload> *bodyStateMsg)
— (overloaded) Add a new thruster to the thruster set connect to a body different than the hub
-
void ConfigureThrustRequests()
This method is used to read the new commands vector and set the thruster firings appropriately. It assumes that the ReadInputs method has already been run successfully. It honors all previous thruster firings if they are still active. Note that for unit testing purposes you can insert firings directly into NewThrustCmds.
- Returns:
void
-
void UpdateThrusterProperties()
This method is used to update the location and orientation of the thrusters at every UpdateState call when the thrusters are attached to a body other than the hub.
- Returns:
void
Public Members
-
ReadFunctor<THRArrayOnTimeCmdMsgPayload> cmdsInMsg
— input message with thruster commands
-
std::vector<Message<THROutputMsgPayload>*> thrusterOutMsgs
— output message vector for thruster data
-
std::vector<THRSimConfig> thrusterData
— Thruster information
-
std::vector<double> NewThrustCmds
— Incoming thrust commands
-
std::vector<double> kappaInit
[] Vector of initial thruster states
-
std::string nameOfKappaState
— Identifier for the kappa state data container
-
Eigen::MatrixXd *inertialPositionProperty
[m] r_N inertial position relative to system spice zeroBase/refBase
-
BSKLogger bskLogger
— BSK Logging
-
double mDotTotal = 0.0
[kg/s] Current mass flow rate of thrusters
Private Members
-
std::vector<THROutputMsgPayload> thrusterOutBuffer
— Message buffer for thruster data
-
THRArrayOnTimeCmdMsgPayload incomingCmdBuffer
— One-time allocation for savings
-
std::vector<ReadFunctor<SCStatesMsgPayload>> attachedBodyInMsgs
vector of body states message where the thrusters attach to
-
SCStatesMsgPayload attachedBodyBuffer
-
std::vector<BodyToHubInfo> bodyToHubInfo
-
double prevCommandTime
[s] — Time for previous valid thruster firing
Private Static Attributes
-
static uint64_t effectorID = 1
[] ID number of this panel
-
ThrusterStateEffector()