C++ Module: windBase
Executive Summary
Abstract base class for atmospheric wind models. WindBase reads spacecraft
state input messages and writes wind velocity output messages in the inertial frame.
Concrete subclasses implement evaluateWindModel() to fill the
WindMsgPayload for each tracked spacecraft. The module supports multiple
spacecraft through the addSpacecraftToModel() method.
Module Description
Multi-spacecraft support.
WindBase supports multiple spacecraft through the addSpacecraftToModel()
method. Each call to this method subscribes to a spacecraft’s state message and
creates a corresponding wind output message. The module processes all connected
spacecraft in each update cycle, computing wind velocities for each spacecraft’s
position.
Planet-relative position.
At every time step, WindBase computes r_BP_N as each spacecraft’s position
relative to the planet center in the inertial frame. r_BN_N is read from
SCStatesMsgPayload and r_PN_N (stored as PositionVector) is read
from SpicePlanetStateMsgPayload:
This correctly handles simulations where the planet is not at the inertial origin (e.g., heliocentric simulations).
Planet angular velocity.
WindBase provides two modes for the planet angular velocity used in co-rotation calculations,
selected via setUseSpiceOmegaFlag():
SPICE mode (default,
True): angular velocity is derived fromJ20002Pfix_doteach time step. Falls back to the manually set value only whenplanetPosInMsghas not been written to.Manual mode (
False): the value set viasetPlanetOmega_N()is always used (default: Earth rotation rate).
Epoch handling.
For time-dependent empirical wind models, WindBase maintains an epochDateTime
structure (struct tm) initialised to the Basilisk standard epoch (2019-01-01
00:00:00). During Reset():
If
epochInMsgis linked, the epoch is read from that message. It is interpreted as UTC, independent of the time zone of the computer.Otherwise,
customSetEpochFromVariable()is called, giving subclasses the opportunity to set the epoch from a module-level variable.
Message Connection Descriptions
The following table lists all the module input and output messages.
Msg Variable Name |
Msg Type |
Description |
|---|---|---|
scStateInMsgs |
Spacecraft state input messages (vector). Use |
|
envOutMsgs |
Atmospheric wind velocity output messages (vector). Automatically created when spacecraft are added via |
|
planetPosInMsg |
Planet SPICE state input message. Provides |
|
epochInMsg |
(Optional) Epoch date/time message. When connected, overrides the default Basilisk epoch stored in |
Spacecraft State Timing
The module is normally executed before the spacecraft within a task, so the spacecraft state message it reads was written
at the end of the previous step. By default the message is used as written. To avoid an output that lags the interval it is applied
to, the extrapolation can be enabled with setExtrapolateScStateToStepMidpoint(True). The spacecraft position is
then advanced with the message velocity by half of the message age, which is the middle of the interval that the next
spacecraft update integrates. It is skipped for a message that was written at the current time and for a stale
message that was written before the previous update of the module, for example a state written once at the start of
the simulation.
Warning
The extrapolation requires that the module is updated with the same task period as the spacecraft, so that the state message written by the spacecraft at the previous module update is exactly one module interval old. If the task periods differ, whether the spacecraft is faster or slower than the module, half of the message age is not the middle of the module interval. The state is then not extrapolated to the midpoint: the spacecraft stay at the epoch of their messages, and the planets are moved to that epoch if all the spacecraft messages were written at the previous module update (they are left as written otherwise), so that every spacecraft is evaluated against the same planet epoch. A warning is logged once when a spacecraft message is found not to have been written at the previous module update. A task period mismatch is not always detectable this way: a message written at the current module update, for example by a faster spacecraft that runs before the module, is used as written and gives no warning. No message that is not the output of the previous module update is ever extrapolated. A task period that changes during the simulation has the same effect. The extrapolation only starts once two write times of the spacecraft state message have been observed and their interval equals the module update interval, so the first updates are not extrapolated. Until then the spacecraft state is used as written and the planet is moved back to the epoch of that state, so the relative geometry stays consistent. Run the module in the same task as the spacecraft, or at the same period.
When the extrapolation is enabled the position and the orientation of the planet (or of the sun and the planets for the eclipse) are advanced, or moved back, with their message velocity and angular rate to the same middle of the interval as the spacecraft, so that the relative geometry is evaluated at a single epoch. Time-dependent models, such as the local solar time or the decimal year of the epoch, are evaluated at the same epoch as the geometry: the middle of the interval if the extrapolation applies, the epoch of the previous update while the spacecraft state is not yet extrapolated, and the current time otherwise. Inputs read from messages, such as a space weather sample, are not shifted. As in the gravity effector, the planet is advanced by the time since its message was written, whatever the age of the message, so a planet message written once with a non-zero velocity is projected forward over the whole simulation.
-
class WindBase : public SysModel
- #include <windBase.h>
Abstract base class for atmospheric wind models.
WindBase reads spacecraft state input messages and writes wind velocity output messages. Concrete subclasses implement evaluateWindModel() to fill the WindMsgPayload for each tracked spacecraft. The module supports multiple spacecraft through the addSpacecraftToModel() method.
Public Functions
-
WindBase()
This method initializes some basic parameters for the module.
-
~WindBase()
Destructor.
-
void Reset(uint64_t CurrentSimNanos) override
Reset: resolves the epoch and calls customReset() for subclass-specific initialization.
- Parameters:
CurrentSimNanos – Current simulation time (ns).
-
void UpdateState(uint64_t CurrentSimNanos) override
Main update method: reads messages, evaluates wind model, writes output.
- Parameters:
CurrentSimNanos – Current simulation time (ns).
-
void addSpacecraftToModel(Message<SCStatesMsgPayload> *tmpScMsg)
Adds a spacecraft to the model by subscribing to its state message and creating an output message.
- Parameters:
tmpScMsg – Spacecraft state message to subscribe to.
-
Eigen::Vector3d getPlanetOmega_N() const
Returns the planet angular velocity vector in the inertial frame.
- Returns:
Planet angular velocity [rad/s] in N frame.
-
void setPlanetOmega_N(const Eigen::Vector3d &omega)
Sets the planet angular velocity vector in the inertial frame.
This method sets the manual planet angular velocity and disables SPICE-derived omega. To re-enable SPICE-derived omega, call setUseSpiceOmegaFlag(true).
- Parameters:
omega – Planet angular velocity [rad/s] in N frame.
- Throws:
BSK_ERROR – if input contains NaN or infinite values.
-
bool getUseSpiceOmegaFlag() const
Gets the current useSpiceOmega flag.
- Returns:
true if SPICE-derived omega is being used when available.
-
void setUseSpiceOmegaFlag(bool useSpice)
Sets the useSpiceOmega flag.
- Parameters:
useSpice – If true, use SPICE-derived omega when available, fallback to manual otherwise.
-
void setExtrapolateScStateToStepMidpoint(bool enable)
Enables or disables the extrapolation of the spacecraft state to the middle of the interval the next spacecraft update integrates, see extrapolateScStateToStepMidpoint(). It is disabled by default and assumes that the module and the spacecraft run at the same task rate with a constant spacecraft step. A warning is logged once if a spacecraft message was not written at the previous module update, which is typically a task rate mismatch. A mismatch is not always detectable, but a message that is not the output of the previous module update is never extrapolated.
- Parameters:
enable – If true, extrapolate the spacecraft state.
-
bool getExtrapolateScStateToStepMidpoint() const
Returns whether the spacecraft state extrapolation is enabled.
- Returns:
true if the spacecraft state is extrapolated.
Public Members
-
std::vector<ReadFunctor<SCStatesMsgPayload>> scStateInMsgs = {}
Spacecraft state input messages.
-
std::vector<Message<WindMsgPayload>*> envOutMsgs = {}
Wind velocity output messages.
-
ReadFunctor<SpicePlanetStateMsgPayload> planetPosInMsg = {}
Planet SPICE state input message.
-
ReadFunctor<EpochMsgPayload> epochInMsg = {}
(optional) epoch date/time input message
-
BSKLogger bskLogger = {}
— BSK Logging
Protected Functions
-
void writeMessages(uint64_t CurrentClock)
Writes the wind output messages for each spacecraft.
- Parameters:
CurrentClock – Current simulation time (ns).
-
bool readMessages(uint64_t CurrentSimNanos)
Reads the spacecraft and planet state messages. If enabled with setExtrapolateScStateToStepMidpoint(), the spacecraft state is extrapolated to the middle of the interval the next spacecraft update integrates, see extrapolateScStateToStepMidpoint().
- Parameters:
CurrentSimNanos – Current simulation time (ns).
- Returns:
true if all required messages were successfully read.
-
Eigen::Vector3d computeRelativePos(const SpicePlanetStateMsgPayload &planetState, const SCStatesMsgPayload &scState) const
Computes
r_BP_Nfrom spacecraft and planet positions.- Parameters:
planetState – Planet state message.
scState – Spacecraft state message.
- Returns:
Spacecraft position relative to planet in inertial frame [m].
-
void updateLocalWind(double currentTime)
Computes
r_BP_N, then calls evaluateWindModel() for each spacecraft.- Parameters:
currentTime – Current simulation time (s).
-
virtual void evaluateWindModel(WindMsgPayload *msg, const Eigen::Vector3d &r_BP_N, const Eigen::Vector3d &v_corotatingAir_N, double currentTime) = 0
Pure-virtual method that each concrete wind model must implement.
- Parameters:
msg – Output wind message to fill.
r_BP_N – Spacecraft position relative to planet in inertial frame [m].
v_corotatingAir_N – Co-rotating atmosphere velocity [m/s] in N frame.
currentTime – Current simulation time (s).
-
virtual void customReset(uint64_t CurrentClock)
Optional subclass reset hook.
- Parameters:
CurrentClock – Current simulation time (ns).
-
virtual void customWriteMessages(uint64_t CurrentClock)
Optional subclass write hook.
- Parameters:
CurrentClock – Current simulation time (ns).
-
virtual bool customReadMessages()
Optional subclass read hook.
- Returns:
true if successful.
-
virtual void customSetEpochFromVariable()
Optional hook called from Reset() when epochInMsg is not linked. Subclasses can override this to set epochDateTime from a module variable.
-
void updatePlanetOmegaFromSpice()
Updates
spiceOmega_NfromJ20002Pfix_dotwhen SPICE provides it.With
C = J20002Pfix(maps inertial N to planet-fixed P), the kinematic equation givesskew_PN_P = -C_dot * C^T. spiceOmega_N is extracted from that skew-symmetric matrix and rotated to the inertial frame:spiceOmega_N = C^T * omega_PN_P. The update is skipped whenJ20002Pfix_dotis zero (SPICE did not compute orientation derivatives), preserving the manually set value.
Protected Attributes
-
std::vector<WindMsgPayload> envOutBuffer = {}
Message write buffer for each spacecraft.
-
std::vector<SCStatesMsgPayload> scStates = {}
Cached spacecraft state messages.
-
uint64_t previousUpdateNanos = 0
[ns] Time of the previous module update, used to detect stale spacecraft messages
-
ScStateExtrapolation scStateExtrapolation = {}
Opt-in extrapolation of the spacecraft state to the step midpoint.
-
SpicePlanetStateMsgPayload planetState = {}
Cached planet state message.
Private Members
-
bool useSpiceOmega = true
[bool] If true, use SPICE-derived omega; if false, use manually set value
-
Eigen::Vector3d planetOmega_N = {0.0, 0.0, OMEGA_EARTH}
[rad/s] Planet angular velocity in inertial frame (default: Earth rotation rate)
-
Eigen::Vector3d spiceOmega_N = {0.0, 0.0, 0.0}
[rad/s] Planet angular velocity derived from SPICE DCM derivatives
-
std::vector<std::unique_ptr<Message<WindMsgPayload>>> ownedEnvOutMsgs
Storage for envOutMsgs.
-
struct epochDateTime
- #include <windBase.h>
Epoch date/time (Gregorian) for time-dependent models.
-
WindBase()