C++ Module: linearTranslationOneDOFStateEffector

Executive Summary

The linear translation body class is an instantiation of the state effector abstract class. The integrated test is validating the interaction between the linear translation body module and the rigid body hub that it is attached to. In this case, a 1-DoF linear translation body has an inertia tensor and is attached to the hub by a single degree of freedom axis. The spinning axis is fixed in the body frame and the effector is rigid, which means that its center of mass location does not move in the F frame. An optional motor force can be applied on the spinning axis, and the user can also lock the axis through a command.

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.

linearTranslationOneDOFStateEffector module input and output messages

Module I/O Messages

Msg Variable Name

Msg Type

Description

translatingBodyOutMsg

LinearTranslationRigidBodyMsgPayload

Output message containing the linear translation body state displacement and displacement rate.

motorForceInMsg

ArrayMotorForceMsgPayload

(Optional) Input message of the motor force value.

motorLockInMsg

ArrayEffectorLockMsgPayload

(Optional) Input message for locking the axis.

translatingBodyRefInMsg

LinearTranslationRigidBodyMsgPayload

(Optional) Input message for prescribing the displacement and displacement rate.

translatingBodyConfigLogOutMsg

SCStatesMsgPayload

Output message containing the translating body inertial position and attitude states.

Detailed Module Description

A 1 DoF translating body has 2 states: rho and rhoDot. The displacemet and displacement rate can change due to the interaction with the hub, but also because of applied forces (control, spring and damper). The displacement remains fixed and the displacement rate is set to zero when the axis is locked.

Mathematical Modeling

See the following tech report for a detailed description of this model.

Note

P. Johnson and J. Vaz Carneiro, “Single Axis Translating Effector,” Technical Note, University of Colorado, Autonomous Vehicle Systems (AVS) Lab, Boulder, CO, March 9, 2024.

User Guide

This section is to outline the steps needed to setup a Translating Body State Effector in Python using Basilisk.

  1. Import the linearTranslatingBodyOneDOFStateEffector class:

    from Basilisk.simulation import linearTranslatingBodyOneDOFStateEffector
    
  2. Create an instantiation of a Translating body:

    translatingBody = linearTranslatingBodyOneDOFStateEffector.linearTranslatingBodyOneDOFStateEffector()
    
  3. Define all physical parameters for a Translating Body. For example:

    translatingBody.setMass(20.0)
    translatingBody.setFHat_B([[3.0 / 5.0], [4.0 / 5.0], [0.0]])
    translatingBody.setR_FcF_F([[-1.0], [1.0], [0.0]])
    translatingBody.setR_F0B_B([[-5.0], [4.0], [3.0]])
    translatingBody.setIPntFc_F([[50.0, 0.0, 0.0],
                                 [0.0, 80.0, 0.0],
                                 [0.0, 0.0, 60.0]])
    translatingBody.setDCM_FB([[0.0, -1.0, 0.0],
                               [0.0, 0.0, -1.0],
                               [1.0, 0.0, 0.0]])
    
  4. (Optional) Define initial conditions of the effector. Default values are zero states:

    translatingBody.setRhoInit(1.0)
    translatingBody.setRhoDotInit(0.05)
    
  5. (Optional) Define spring and damper coefficients. Default values are zero:

    translatingBody.setK(100.0)
    translatingBody.setC(0.0)
    
  6. (Optional) Define a unique name for each state. If you have multiple translating bodies, they each must have a unique name. If these names are not specified, then the default names are used which are incremented by the effector number:

    translatingBody.nameOfThetaState = "translatingBodyRho"
    translatingBody.nameOfThetaDotState = "translatingBodyRhoDot"
    
  7. (Optional) Connect a command force message:

    cmdArray = messaging.ArrayMotorForceMsgPayload()
    cmdArray.motorForce = [cmdForce]  # [Nm]
    cmdMsg = messaging.ArrayMotorForceMsg().write(cmdArray)
    translatingBody.motorForceInMsg.subscribeTo(cmdMsg)
    
  8. (Optional) Connect an axis-locking message (0 means the axis is free to move and 1 locks the axis):

    lockArray = messaging.ArrayEffectorLockMsgPayload()
    lockArray.effectorLockFlag = [1]
    lockMsg = messaging.ArrayEffectorLockMsg().write(lockArray)
    translatingBody.motorLockInMsg.subscribeTo(lockMsg)
    
  9. (Optional) Connect a displacement and displacement rate reference message:

    translationRef = messaging.LinearTranslationRigidBodyMsgPayload()
    translationRef.rho = 0.2
    translationRef.rhoDot = 0.0
    translationRefMsg = messaging.LinearTranslationRigidBodyMsg().write(translationRef)
    translatingBody.translatingBodyRefInMsg.subscribeTo(translationRefMsg)
    
  10. The linear states of the body are created using an output message translatingBodyOutMsg.

  11. The translating body config log state output message is translatingBodyConfigLogOutMsg.

  12. Add the effector to your spacecraft:

    scObject.addStateEffector(translatingBody)
    

    See C++ Module: spacecraft documentation on how to set up a spacecraft object.

  13. Add the module to the task list:

    unitTestSim.AddModelToTask(unitTaskName, translatingBody)
    

Hosting a Dynamic Effector

This effector supports the branching described in Advanced: Effector Module Branching, so a compatible dynamic effector can be carried by the translating body rather than by the hub:

translatingBody.addDynamicEffector(childEffector)

This effector then makes its inertial position, velocity, attitude, and angular velocity available in place of the hub’s, and the child reads whichever of the four its model needs. Any geometry given to the child is expressed in that translating body’s frame rather than the hub body frame. Both this effector and the child are still added to the task in the usual way.

Initialization and Finite-Value Validation

Configured masses, spring and damping coefficients, initial displacements and rates, position offsets, inertia entries, and frame matrices must be finite. Existing mass bounds, inertia requirements, and rotation-matrix checks still apply.

Axis setters require finite components and a norm strictly greater than 0.01. They scale the components before normalization to preserve the direction of very large finite vectors. Mass, spring, damping, and axis setters reject invalid input before changing the prior setting.

Configuration validation runs before state or property registration, even when the effector is attached without task scheduling. Reset() repeats validation without restoring initial integrated states or clearing commands. Invalid values raise BasiliskError. See Initialization and Configuration Validation.


class LinearTranslationOneDOFStateEffector : public StateEffector, public SysModel
#include <linearTranslationOneDOFStateEffector.h>

linear spring mass damper state effector class

Public Functions

LinearTranslationOneDOFStateEffector()

Constructor.

~LinearTranslationOneDOFStateEffector()

Destructor.

void addDynamicEffector(DynamicEffector *newDynamicEffector, int segment = 1) override

This method attaches a dynamicEffector

Parameters:
  • newDynamicEffector – the dynamic effector to be attached to the translating body

  • segment – defaults to the only segment for 1DOF (base segment 1)

void setMass(double mass)

Set the translating-body mass.

setter for mass property

Parameters:

mass – [in] [kg] Mass value.

void setK(double k)

Set the translational spring coefficient.

setter for k property

Parameters:

k – [in] [N/m] Translational spring coefficient.

void setC(double c)

Set the translational damping coefficient.

setter for c property

Parameters:

c – [in] [N*s/m] Translational damping coefficient.

inline void setRhoInit(double rhoInit)

setter for rhoInit property

inline void setRhoDotInit(double rhoDotInit)

setter for rhoDotInit property

void setFHat_B(Eigen::Vector3d fHat_B)

Set the body-frame translation direction.

setter for fHat_B property

Parameters:

fHat_B – [in] Translation direction expressed in body-frame components.

inline void setR_FcF_F(Eigen::Vector3d r_FcF_F)

setter for r_FcF_F property

inline void setR_F0B_B(Eigen::Vector3d r_F0B_B)

setter for r_F0B_B property

inline void setIPntFc_F(Eigen::Matrix3d IPntFc_F)

setter for IPntFc_F property

inline void setDCM_FB(Eigen::Matrix3d dcm_FB)

setter for dcm_FB property

inline double getMass() const

setter for mass property

inline double getK() const

setter for k property

inline double getC() const

setter for c property

inline double getRhoInit() const

setter for rhoInit property

inline double getRhoDotInit() const

setter for rhoDotInit property

inline Eigen::Vector3d getFHat_B() const

setter for fHat_B property

inline Eigen::Vector3d getR_FcF_F() const

setter for r_FcF_F property

inline Eigen::Vector3d getR_F0B_B() const

setter for r_F0B_B property

inline Eigen::Matrix3d getIPntFc_F() const

setter for IPntFc_F property

inline Eigen::Matrix3d getDCM_FB() const

setter for dcm_FB property

Public Members

Message<LinearTranslationRigidBodyMsgPayload> translatingBodyOutMsg

state output message

Message<SCStatesMsgPayload> translatingBodyConfigLogOutMsg

translating body state config log message

ReadFunctor<ArrayMotorForceMsgPayload> motorForceInMsg

(optional) motor force input message

ReadFunctor<LinearTranslationRigidBodyMsgPayload> translatingBodyRefInMsg

(optional) reference state input message

ReadFunctor<ArrayEffectorLockMsgPayload> motorLockInMsg

(optional) lock flag input message

Private Functions

void Reset(uint64_t CurrentClock) override

Reset the effector.

Parameters:

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

void validateConfiguration()

Method to reject a configuration the equations of motion cannot represent.

This method runs every configuration check. Spacecraft initialization always reaches it through registerStates(), whereas Reset() runs only when the effector is also added to a task

void registerStates(DynParamManager &states) override

Register the effector dynamics states.

Parameters:

states – [inout] Dynamic parameter manager used to register states or properties.

void linkInStates(DynParamManager &states) override

Link the required dynamics states.

Parameters:

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

void registerProperties(DynParamManager &states) override

This method registers the SB inertial properties with the dynamic parameter manager and links them into dependent dynamic effectors

Parameters:

states – [inout] Dynamic parameter manager used to register states or properties.

void linkInPrescribedMotionProperties(DynParamManager &states) override

Link the prescribed-motion properties.

Parameters:

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

void writeOutputStateMessages(uint64_t CurrentSimNanos) override

Write the effector state output messages.

Parameters:

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

void updateEffectorMassProps(double integTime) override

Update the effector mass properties.

Parameters:

integTime – [in] [s] Current integration time.

void updateContributions(double integTime, BackSubMatrices &backSubContr, Eigen::MRPd sigma_BN, Eigen::Vector3d omega_BN_B, Eigen::Vector3d g_N) override

Update the effector Backsubstitution contributions.

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

  • backSubContr – [inout] Backsubstitution contributions.

  • sigma_BN – [in] Hub attitude relative to the inertial frame.

  • omega_BN_B – [in] [rad/s] Hub angular velocity expressed in body-frame components.

  • g_N – [in] [m/s^2] Gravitational acceleration expressed in inertial-frame components.

void updateEnergyMomContributions(double integTime, Eigen::Vector3d &rotAngMomPntCContr_B, double &rotEnergyContr, Eigen::Vector3d omega_BN_B) override

Update the effector energy and momentum contributions.

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

  • rotAngMomPntCContr_B – [inout] [kg*m^2/s] Rotational angular momentum contribution.

  • rotEnergyContr – [inout] [J] Rotational energy contribution.

  • omega_BN_B – [in] [rad/s] Hub angular velocity expressed in body-frame components.

void computeDerivatives(double integTime, Eigen::Vector3d rDDot_BN_N, Eigen::Vector3d omegaDot_BN_B, Eigen::MRPd sigma_BN) override

Compute the effector state derivatives.

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

  • rDDot_BN_N – [in] [m/s^2] Hub translational acceleration expressed in inertial-frame components.

  • omegaDot_BN_B – [in] [rad/s^2] Hub angular acceleration expressed in body-frame components.

  • sigma_BN – [in] Hub attitude relative to the inertial frame.

void UpdateState(uint64_t CurrentSimNanos) override

Update the scheduled effector state.

Parameters:

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

void computeTranslatingBodyInertialStates()
void computeBackSubContributions(BackSubMatrices &backSubContr, const Eigen::Vector3d &F_g, double integTime)

Compute the Backsubstitution contributions.

Parameters:
  • backSubContr – [inout] Backsubstitution contributions.

  • F_g – [in] Generalized gravitational-force vector.

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

void readInputMessages()
void addPrescribedMotionCouplingContributions(BackSubMatrices &backSubContr) override

Method for adding coupling contributions for state effector branching on prescribed motion.

Add prescribed-motion coupling terms.

Parameters:

backSubContr – [inout] Backsubstitution contributions.

template<typename Type>
inline void assignStateParamNames(Type effector)

Assign the state engine parameter names

Private Members

double mass = 1.0

[kg] mass of effector

double k = 0

[N/m] linear spring constant

double c = 0

[N-s/m] linear damping term

double rhoInit = 0

[m] initial displacement offset

double rhoDotInit = 0

[m/s] Initial displacement rate offset

Eigen::Vector3d fHat_B = {1.0, 0.0, 0.0}

unit vector axis of translation in B frame components.

Eigen::Vector3d r_FcF_F = Eigen::Vector3d::Zero()

[m] vector pointing from location F to FC in F frame components

Eigen::Vector3d r_F0B_B = Eigen::Vector3d::Zero()

[m] vector pointing from body frame B origin to point to F0 origin of F frame in B frame components

Eigen::Matrix3d IPntFc_F = Eigen::Matrix3d::Identity()

[kg-m^2] Inertia of pc about point Fc in F frame component

Eigen::Matrix3d dcm_FB = Eigen::Matrix3d::Identity()

DCM from the body frame to the F frame.

std::string nameOfRhoState = {}

Identifier for the rho state data container.

std::string nameOfRhoDotState = {}

Identifier for the rhoDot state data container.

std::string nameOfInertialPositionProperty

identifier for the inertial position property

std::string nameOfInertialVelocityProperty

identifier for the inertial velocity property

std::string nameOfInertialAttitudeProperty

identifier for the inertial attitude property

std::string nameOfInertialAngVelocityProperty

identifier for the inertial angular velocity property

std::vector<DynamicEffector*> dynEffectors

Vector of dynamic effectors attached.

bool isAxisLocked = false

flag for locking the translation axis

double rho = 0.0

[m] displacement from equilibrium

double rhoDot = 0.0

[m/s] time derivative of displacement from equilibrium

double rhoRef = 0.0

[m] translating body reference position

double rhoDotRef = 0.0

[m/s] translating body reference velocity

double motorForce = 0.0

[N] optional motor force

Eigen::Vector3d r_FcB_B = Eigen::Vector3d::Zero()

[m] position vector from B to center of mass location of effector

Eigen::Vector3d r_FcF0_B = Eigen::Vector3d::Zero()

[m] vector pointing from point p0 origin of F frame to center of mass location of effector in B frame components

Eigen::Matrix3d rTilde_FcF_B = Eigen::Matrix3d::Zero()

[m] tilde matrix of r_FcF_B

Eigen::Vector3d rPrime_FcF_B = Eigen::Vector3d::Zero()

[m/s] Body time derivative of r_FcF_B

Eigen::Matrix3d rPrimeTilde_FcF_B = Eigen::Matrix3d::Zero()

[m/s] Tilde matrix of rPrime_FcF_B

Eigen::Matrix3d rTilde_FcB_B = Eigen::Matrix3d::Zero()

[m] tilde matrix of r_FcB_B

Eigen::Vector3d rPrime_FcB_B = Eigen::Vector3d::Zero()

[m/s] Body time derivative of r_FcB_B

Eigen::Matrix3d rPrimeTilde_FcB_B = Eigen::Matrix3d::Zero()

[m/s] Tilde matrix of rPrime_FcB_B

Eigen::Matrix3d IPntFc_B = Eigen::Matrix3d::Identity()

[kg-m^2] Inertia of Fc about point B in B frame components

Eigen::Matrix3d dcm_BN = Eigen::Matrix3d::Identity()

DCM from the B frame to the N frame.

Eigen::Vector3d omega_BN_B = Eigen::Vector3d::Zero()

[rad/s] angular velocity of the B frame wrt the N frame in B frame components.

Eigen::Vector3d aRho = Eigen::Vector3d::Zero()

Term needed for back-sub method.

Eigen::Vector3d bRho = Eigen::Vector3d::Zero()

Term needed for back-sub method.

double cRho = 0.0

Term needed for back-sub method.

StateData *rhoState = nullptr

state data for displacement from equilibrium

StateData *rhoDotState = nullptr

state data for time derivative of rho;

Eigen::MatrixXd *g_N = nullptr

[m/s^2] gravitational acceleration in N frame components

StateData *hubSigmaState = nullptr

hub attitude state, read live for the published kinematics

Eigen::MatrixXd *inertialPositionProperty = nullptr

[m] r_N inertial position relative to system spice zeroBase/refBase

Eigen::MatrixXd *inertialVelocityProperty = nullptr

[m] v_N inertial velocity relative to system spice zeroBase/refBase

Eigen::Vector3d r_FcN_N = Eigen::Vector3d::Zero()

[m] position vector of translating body’s center of mass Fc relative to the inertial frame origin N

Eigen::Vector3d v_FcN_N = Eigen::Vector3d::Zero()

[m/s] inertial velocity vector of Fc relative to inertial frame

Eigen::MatrixXd *r_FN_N = nullptr

[m] position vector of translating body’s frame origin F relative to the inertial frame origin N

Eigen::MatrixXd *v_FN_N = nullptr

[m/s] inertial velocity vector of F relative to inertial frame

Eigen::MatrixXd *sigma_FN = nullptr

MRP attitude of frame F relative to inertial frame.

Eigen::MatrixXd *omega_FN_F = nullptr

[rad/s] inertial translating body frame angular velocity vector

StateData *hubOmega

[rad/s] hub inertial angular velocity vector

Private Static Attributes

static uint64_t effectorID = 1

ID number of this panel.