C++ Module: ExtPulsedTorque

Executive Summary

C++ Module: dynamicEffector Class used to provide a direct pulsed external torque on body The module PDF Description contains further information on this module’s function, how to run it, as well as testing. The current timing and reset semantics are specified below.

Message Connection Descriptions

This module has no input or output messages. It is a pure dynamic effector.

Pulse Timing

The sequence is anchored at simulation time zero and consists of a positive pulse, a negative pulse of equal duration, and an optional off period. pulseInterval specifies the duration of one count in seconds and defaults to one second. Each positive or negative pulse lasts countOnPulse * pulseInterval seconds. The following off period lasts countOff * pulseInterval seconds, after which the sequence repeats.

For example:

pulse = ExtPulsedTorque.ExtPulsedTorque()
pulse.pulsedTorqueExternalPntB_B = [0.1, 0.0, 0.0]  # [N*m]
pulse.countOnPulse = 2
pulse.countOff = 3
pulse.pulseInterval = 0.125  # [s]

This configuration applies positive torque for \(0 \leq t < 0.25\) seconds, negative torque for \(0.25 \leq t < 0.5\) seconds, and zero torque for \(0.5 \leq t < 0.875\) seconds. At each transition, evaluation selects the segment beginning at that time. Times within floating-point roundoff of a transition also select the new segment, so decimal intervals such as 0.1 seconds do not delay a boundary by one evaluation. The roundoff window uses the evaluation time and the relevant transition time; a long future off period does not enlarge the window around the initial pulse transitions.

computeForceTorque() uses its integration time in seconds. Its timeStep argument does not set the pulse interval. Repeated evaluations, intermediate integrator stages, and evaluations at earlier times return the torque for the supplied time without advancing internal pulse state. Choose an integration step and error tolerance that resolve the pulse transitions; the torque is discontinuous at those transitions.

Existing configurations that express pulse counts in units of a nominal integration step should set pulseInterval to that step duration in seconds. This replaces the historical behavior that advanced the sequence on every dynamics evaluation, including intermediate integrator stages.

Initialization and Reset

The torque and both counts default to zero, so an unconfigured effector applies no load. countOnPulse and countOff must be non-negative; a zero countOnPulse disables the torque. Torque components and pulseInterval must be finite, the interval must be strictly positive, and the combined cycle duration must remain finite. Invalid configuration raises BasiliskError.

Validation runs during spacecraft attachment through linkInStates(), from Reset(), and before every dynamics evaluation. The effector therefore works without task scheduling. Reset() preserves the phase anchored at simulation time zero and leaves the last output unchanged until the next dynamics evaluation. UpdateState() does not advance the pulse. Changing pulse parameters selects the corresponding waveform with the same time-zero origin. See Initialization and Configuration Validation.


class ExtPulsedTorque : public SysModel, public DynamicEffector
#include <ExtPulsedTorque.h>

external pulsed torque module class

Public Functions

ExtPulsedTorque()

This is the constructor. It sets some default initializers that can be overridden by the user.

~ExtPulsedTorque() override

The destructor. Nothing of note is performed here

void Reset(uint64_t CurrentSimNanos) override

Validate pulse configuration without changing its phase relative to simulation time.

Parameters:

CurrentSimNanos – [ns] Scheduler reset time; it does not shift the pulse sequence.

void UpdateState(uint64_t CurrentSimNanos) override

Module update method

Parameters:

CurrentSimNanos – [in] [ns] Current simulation time.

void linkInStates(DynParamManager &statesIn) override

link the states

Parameters:

statesIn – [in] Dynamic parameter manager containing the required states.

void writeOutputMessages(uint64_t currentClock)

This module does not write any output messages.

Parameters:

currentClock – The current time used for time-stamping the message

void readInputMessages()

This method is used to read the incoming message and set the associated buffer structure.

void computeForceTorque(double integTime, double timeStep) override

This method is used to compute the RHS forces and torques. Note: the module can set any of these three vectors, or a subset. Regarding the external force, the matrix representations in the body (B) and inertial (N) frame components are treated as 2 separate vectors. Only set both if you mean to, as both vectors will be included.

Parameters:
  • integTime – [in] [s] Current integration time.

  • timeStep – [in] [s] Integration time step; unused because pulse timing uses pulseInterval.

Public Members

Eigen::Vector3d pulsedTorqueExternalPntB_B = Eigen::Vector3d::Zero()

[N*m] pulsed torque about B in B components

int countOnPulse = 0

Number of pulse intervals for each positive and negative pulse; zero disables the torque.

int countOff = 0

Number of pulse intervals with no torque between pulse pairs.

double pulseInterval = 1.0

[s] Duration of one pulse-count interval, independent of the integrator step

BSKLogger bskLogger

BSK Logging.

Private Functions

void validateConfiguration()

Validate the torque, pulse counts, and interval duration.

Validate pulse parameters before attachment, reset, or torque evaluation.