Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/source/Support/bskReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ Version |release|
both registered their states under the same name, resulting in overwriting and a ``BSK_ERROR``.
- Added support for :ref:`hingedRigidBodyStateEffector` to be the parent for Dynamic Effectors.
- Added SWIG Eigen typemaps for passing Eigen products or returning Eigen products to/from director methods.

- Added optional prescribed 1-DOF helical screw motion to the :ref:`prescribedRotation1DOF` kinematic profiler module.
- Added a new prescribed helical screw motion example scenario. See :ref:`scenarioPrescribedScrewMotion`.

Version 2.8.0 (August 30, 2025)
-------------------------------
Expand Down
7 changes: 4 additions & 3 deletions examples/_default.rst
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,17 @@ Complex Spacecraft Dynamics Simulations
Hinged Panel Deployment <scenarioDeployingPanel>
MSM Simulation of Charged Spacecraft <scenarioTwoChargedSC>
Spacecraft with 1- or 2-DOF Panel using single effector <scenarioSpinningBodiesTwoDOF>
Prescribed Motion Rotational Solar Array Deployment <scenarioDeployingSolarArrays>
Robotic Arm Effector with Profiler <scenarioRoboticArm>
Spacecraft with an multi-link extending component <scenarioExtendingBoom>

Multi-Body Dynamics Simulations with Prescribed Motion Branching
----------------------------------------------------------------
Prescribed Motion Spacecraft Dynamics Simulations
-------------------------------------------------

.. toctree::
:maxdepth: 1

Prescribed Helical Screw Motion <scenarioPrescribedScrewMotion>
Prescribed Motion Rotational Solar Array Deployment <scenarioDeployingSolarArrays>
Prescribed Motion with Translating Effector Branching <scenarioPrescribedMotionWithTranslationBranching>
Prescribed Motion with Rotating Effector Branching <scenarioPrescribedMotionWithRotationBranching>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def run(show_plots):

if vizSupport.vizFound:
viz = vizSupport.enableUnityVisualization(sc_sim, data_rec_task_name, sc_body_list,
saveFile=filename
#saveFile=filename
)
vizSupport.createCustomModel(viz
, simBodiesToModify=[sc_object.ModelTag]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def run(show_plots):

if vizSupport.vizFound:
viz = vizSupport.enableUnityVisualization(sc_sim, data_rec_task_name, sc_body_list,
saveFile=filename
#saveFile=filename
)
vizSupport.createCustomModel(viz
, simBodiesToModify=[sc_object.ModelTag]
Expand Down
448 changes: 448 additions & 0 deletions examples/scenarioPrescribedScrewMotion.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
void PrescribedRotation1DOF::SelfInit() {
HingedRigidBodyMsg_C_init(&this->spinningBodyOutMsgC);
PrescribedRotationMsg_C_init(&this->prescribedRotationOutMsgC);
PrescribedTranslationMsg_C_init(&this->prescribedTranslationOutMsgC);
}

/*! This method resets required module variables and checks the input messages to ensure they are linked.
Expand Down Expand Up @@ -663,6 +664,19 @@ void PrescribedRotation1DOF::writeOutputMessages(uint64_t callTime) {
this->prescribedRotationOutMsg.write(&prescribedRotationOut, moduleID, callTime);
HingedRigidBodyMsg_C_write(&spinningBodyOut, &spinningBodyOutMsgC, this->moduleID, callTime);
PrescribedRotationMsg_C_write(&prescribedRotationOut, &prescribedRotationOutMsgC, this->moduleID, callTime);

if (this->c_screw != 0.0) {
// Write the prescribed translation output message if screw motion is configured
PrescribedTranslationMsgPayload prescribedTranslationOut;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write
PrescribedTranslationMsgPayload prescribedTranslationOut = {} to define this variable and have the structure zero'd in one step.

prescribedTranslationOut = PrescribedTranslationMsgPayload();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can remove this line if you implement the above suggestion.

Eigen::Vector3d r_PM_M = (this->rhoInit + this->c_screw * this->theta) * this->rotHat_M;
Eigen::Vector3d rPrime_PM_M = this->c_screw * this->thetaDot * this->rotHat_M;
Eigen::Vector3d rPrimePrime_PM_M = this->c_screw * this->thetaDDot * this->rotHat_M;
eigenVector3d2CArray(r_PM_M, prescribedTranslationOut.r_PM_M);
eigenVector3d2CArray(rPrime_PM_M, prescribedTranslationOut.rPrime_PM_M);
eigenVector3d2CArray(rPrimePrime_PM_M, prescribedTranslationOut.rPrimePrime_PM_M);
this->prescribedTranslationOutMsg.write(&prescribedTranslationOut, moduleID, callTime);
}
}

/*! This method computes the current spinning body MRP attitude relative to the mount frame: sigma_PM
Expand Down Expand Up @@ -768,3 +782,33 @@ double PrescribedRotation1DOF::getThetaDDotMax() const {
double PrescribedRotation1DOF::getThetaInit() const {
return this->thetaInit;
}

/*! Setter method for the initial linear displacement if screw motion is selected.

@param initDisplacement Initial linear displacement
*/
void PrescribedRotation1DOF::setInitDisplacement(const double initDisplacement) {
this->rhoInit = initDisplacement;
}

/*! Setter method for the screw constant for modeling prescribed screw motion.

@param screwConstant Screw slope constant
*/
void PrescribedRotation1DOF::setScrewConstant(const double screwConstant) {
this->c_screw = screwConstant;
}

/*! Getter method for the initial linear displacement if screw motion is selected.
@return double
*/
double PrescribedRotation1DOF::getInitDisplacement() const {
return this->rhoInit;
}

/*! Getter method for the screw constant.
@return double
*/
double PrescribedRotation1DOF::getScrewConstant() const {
return this->c_screw;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "architecture/utilities/bskLogging.h"
#include "cMsgCInterface/HingedRigidBodyMsg_C.h"
#include "cMsgCInterface/PrescribedRotationMsg_C.h"
#include "cMsgCInterface/PrescribedTranslationMsg_C.h"
#include <Eigen/Dense>
#include <cstdint>

Expand All @@ -47,11 +48,19 @@ class PrescribedRotation1DOF: public SysModel{
double getThetaDDotMax() const; //!< Getter for the bang segment scalar angular acceleration
double getThetaInit() const; //!< Getter for the initial spinning body angle

// Method for optional prescribed screw motion
void setInitDisplacement(const double initDisplacement); //!< Setter for the initial linear displacement
void setScrewConstant(const double screwConstant); //!< Setter for the screw motion constant
double getScrewConstant() const; //!< Getter for the screw motion constant
double getInitDisplacement() const; //!< Getter for the initial linear displacement

ReadFunctor<HingedRigidBodyMsgPayload> spinningBodyInMsg; //!< Input msg for the spinning body reference angle and angle rate
Message<HingedRigidBodyMsgPayload> spinningBodyOutMsg; //!< Output msg for the spinning body angle and angle rate
Message<PrescribedRotationMsgPayload> prescribedRotationOutMsg; //!< Output msg for the spinning body prescribed rotational states
Message<PrescribedTranslationMsgPayload> prescribedTranslationOutMsg; //!< Output msg for the prescribed translational states if screw motion is configured
HingedRigidBodyMsg_C spinningBodyOutMsgC = {}; //!< C-wrapped output msg for the spinning body angle and angle rate
PrescribedRotationMsg_C prescribedRotationOutMsgC = {}; //!< C-wrapped output msg for the spinning body prescribed rotational states
PrescribedTranslationMsg_C prescribedTranslationOutMsgC = {}; //!< C-wrapped output msg for the prescribed translational states if screw motion is configured

BSKLogger *bskLogger; //!< BSK Logging

Expand Down Expand Up @@ -85,10 +94,12 @@ class PrescribedRotation1DOF: public SysModel{
Eigen::Vector3d computeSigma_PM(); //!< Method for computing the current spinning body MRP attitude relative to the mount frame: sigma_PM

/* User-configurable variables */
double rhoInit{}; //!< [m] Initial displacement from frame M to frame P along rotHat_M
double coastOptionBangDuration; //!< [s] Time used for the coast option bang segment
double smoothingDuration; //!< [s] Time the acceleration is smoothed to the given maximum acceleration value
double thetaDDotMax; //!< [rad/s^2] Maximum angular acceleration of spinning body used in the bang segments
Eigen::Vector3d rotHat_M; //!< Spinning body rotation axis in M frame components
double c_screw{}; //!< Screw slope constant for modeling prescribed screw motion (1-DOF rotation with coupled translation)

/* Scalar rotational states */
double thetaInit; //!< [rad] Initial spinning body angle from frame M to frame P about rotHat_M
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ from Basilisk.architecture.swig_common_model import *
struct HingedRigidBodyMsg_C;
%include "architecture/msgPayloadDefC/PrescribedRotationMsgPayload.h"
struct PrescribedRotationMsg_C;
%include "architecture/msgPayloadDefC/PrescribedTranslationMsgPayload.h"
struct PrescribedTranslationMsg_C;

%pythoncode %{
import sys
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ The module defaults to the non-smoothed bang-bang option with no coast period. I
user must set the module variable ``coastOptionBangDuration`` to a nonzero value. If smoothing is desired,
the module variable ``smoothingDuration`` must be set to a nonzero value.

An optional feature of this module enables simulation of 1 DOF helical screw motion, where translation and rotation are
both profiled about a single axis. The translational states are coupled with the rotational states through a slope
constant. The rotational profile is scaled by the slope constant to generate the translational states. If this option
is enabled, the module outputs both the :ref:`PrescribedRotationMsgPayload` message and an additional
:ref:`PrescribedTranslationMsgPayload` message.

.. important::
Note that this module assumes the initial and final spinning body hub-relative angular rates are zero.

Expand All @@ -28,6 +34,12 @@ are not set by the user, the module defaults to the non-smoothed bang-bang profi
``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are
set to nonzero values, the smoothed bang-coast-bang profiler is selected.

.. important::
To configure 1 DOF helical screw motion, two additional module variables ``c_screw`` and ``rhoInit`` must be
configured. ``rhoInit`` is the initial translational displacement of the :math:`\mathcal{P}` frame relative to the
:math:`\mathcal{M}` frame along the spin axis ``rotHat_M``. ``c_screw`` is the slope constant which scales the
rotational states to obtain the translational states.

.. important::
To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector`
dynamics module. This ensures the spinning body's states are correctly incorporated into the spacecraft dynamics.
Expand Down Expand Up @@ -63,6 +75,12 @@ provides information on what the message is used for.
* - prescribedRotationOutMsgC
- :ref:`PrescribedRotationMsgPayload`
- C-wrapped output message with the prescribed spinning body rotational states
* - prescribedTranslationalOutMsg
- :ref:`PrescribedRotationMsgPayload`
- (optional) output message with the prescribed translational states if helical screw motion is configured
* - prescribedRotationOutMsgC
- :ref:`PrescribedRotationMsgPayload`
- (optional) C-wrapped output message with the prescribed translational states if helical screw motion is configured

Detailed Module Description
---------------------------
Expand Down Expand Up @@ -448,6 +466,12 @@ are not set by the user, the module defaults to the non-smoothed bang-bang profi
``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are
set to nonzero values, the smoothed bang-coast-bang profiler is selected.

.. important::
To configure 1 DOF helical screw motion, two additional module variables ``c_screw`` and ``rhoInit`` must be
configured. ``rhoInit`` is the initial translational displacement of the :math:`\mathcal{P}` frame relative to the
:math:`\mathcal{M}` frame along the spin axis ``rotHat_M``. ``c_screw`` is the slope constant which scales the
rotational states to obtain the translational states.

This section is to outline the steps needed to set up the prescribed rotational 1 DOF module in python using Basilisk.

#. Import the prescribedRotation1DOF class::
Expand Down
1 change: 1 addition & 0 deletions src/tests/test_scenarioTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
, 'scenarioExtendingBoom'
, 'scenarioPrescribedMotionWithRotationBranching'
, 'scenarioPrescribedMotionWithTranslationBranching'
, 'scenarioPrescribedScrewMotion'
])
@pytest.mark.scenarioTest
def test_scenarioBskScenarios(show_plots, scenarioCase):
Expand Down