Skip to content

Commit de53a5b

Browse files
committed
Update prescribed motion documentation
1 parent 5f7072f commit de53a5b

File tree

2 files changed

+95
-70
lines changed

2 files changed

+95
-70
lines changed

src/simulation/dynamics/prescribedMotion/prescribedMotionStateEffector.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -583,56 +583,48 @@ void PrescribedMotionStateEffector::addStateEffector(StateEffector* newStateEffe
583583
}
584584

585585
/*! Setter method for the effector mass.
586-
@return void
587586
@param mass [kg] Effector mass
588587
*/
589588
void PrescribedMotionStateEffector::setMass(const double mass) { this->mass = mass; }
590589

591590
/*! Setter method for IPntPc_P.
592-
@return void
593591
@param IPntPc_P [kg-m^2] Effector's inertia matrix about its center of mass point Pc expressed in P frame components
594592
*/
595593
void PrescribedMotionStateEffector::setIPntPc_P(const Eigen::Matrix3d IPntPc_P) { this->IPntPc_P = IPntPc_P; }
596594

597595
/*! Setter method for r_PcP_P.
598-
@return void
599596
@param r_PcP_P [m] Position vector of the effector's center of mass point Pc relative to the effector's body frame
600597
origin point P expressed in P frame components
601598
*/
602599
void PrescribedMotionStateEffector::setR_PcP_P(const Eigen::Vector3d r_PcP_P) { this->r_PcP_P = r_PcP_P; }
603600

604601
/*! Setter method for r_PM_M.
605-
@return void
606602
@param r_PM_M [m] Position vector of the effector's body frame origin point P relative to the hub-fixed mount frame
607603
origin point M expressed in M frame components
608604
*/
609605
void PrescribedMotionStateEffector::setR_PM_M(const Eigen::Vector3d r_PM_M) { this->r_PM_M = r_PM_M; }
610606

611607
/*! Setter method for rPrime_PM_M.
612-
@return void
613608
@param rPrime_PM_M [m/s] B frame time derivative of r_PM_M expressed in M frame components
614609
*/
615610
void PrescribedMotionStateEffector::setRPrime_PM_M(const Eigen::Vector3d rPrime_PM_M) {
616611
this->rPrime_PM_M = rPrime_PM_M;
617612
}
618613

619614
/*! Setter method for rPrimePrime_PM_M.
620-
@return void
621615
@param rPrimePrime_PM_M [m/s^2] B frame time derivative of rPrime_PM_M expressed in M frame components
622616
*/
623617
void PrescribedMotionStateEffector::setRPrimePrime_PM_M(const Eigen::Vector3d rPrimePrime_PM_M) {
624618
this->rPrimePrime_PM_M = rPrimePrime_PM_M;
625619
}
626620

627621
/*! Setter method for omega_PM_P.
628-
@return void
629622
@param omega_PM_P [rad/s] Angular velocity of the effector body frame P relative to the hub-fixed mount frame M
630623
expressed in P frame components
631624
*/
632625
void PrescribedMotionStateEffector::setOmega_PM_P(const Eigen::Vector3d omega_PM_P) { this->omega_PM_P = omega_PM_P; }
633626

634627
/*! Setter method for omegaPrime_PM_P.
635-
@return void
636628
@param omegaPrime_PM_P [rad/s^2] Angular acceleration of the effector body frame P relative to the hub-fixed mount
637629
frame M expressed in P frame components
638630
*/
@@ -641,20 +633,17 @@ void PrescribedMotionStateEffector::setOmegaPrime_PM_P(const Eigen::Vector3d ome
641633
}
642634

643635
/*! Setter method for sigma_PM.
644-
@return void
645636
@param sigma_PM MRP attitude of the effector's body frame P relative to the hub-fixed mount frame M
646637
*/
647638
void PrescribedMotionStateEffector::setSigma_PM(const Eigen::MRPd sigma_PM) { this->sigma_PM = sigma_PM; }
648639

649640
/*! Setter method for r_MB_B.
650-
@return void
651641
@param r_MB_B [m] Position vector describing the hub-fixed mount frame origin point M location relative to the hub
652642
frame origin point B expressed in B frame components
653643
*/
654644
void PrescribedMotionStateEffector::setR_MB_B(const Eigen::Vector3d r_MB_B) { this->r_MB_B = r_MB_B; }
655645

656646
/*! Setter method for sigma_MB.
657-
@return void
658647
@param sigma_MB MRP attitude of the hub-fixed frame M relative to the hub body frame B
659648
*/
660649
void PrescribedMotionStateEffector::setSigma_MB(const Eigen::MRPd sigma_MB) { this->sigma_MB = sigma_MB; }
Lines changed: 95 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11

22
Executive Summary
33
-----------------
4-
The prescribed motion class is an instantiation of the state effector abstract class. This module describes the dynamics
5-
of a six-degree of freedom (6 DOF) prescribed rigid body connected to a central rigid spacecraft hub. The body frame
6-
for the prescribed body is designated by the frame :math:`\mathcal{P}`. The prescribed body is mounted onto a hub-fixed
7-
interface described by a mount frame :math:`\mathcal{M}`. The prescribed body may be commanded to translate and rotate
8-
in three-dimensional space with respect to the interface it is mounted on. Accordingly, the prescribed states for
9-
the secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states are:
4+
The prescribed motion state effector class is an instantiation of the state effector abstract class. This module
5+
is used to connect a prescribed motion component to the spacecraft hub. The states of the prescribed component are
6+
purely prescribed, meaning there are no free degrees of freedom associated with its motion and hence there are no
7+
states integrated in this module. Instead, the states of the prescribed component are externally profiled using
8+
a kinematic profiler module and are provided as input messages to the prescribed state effector class.
9+
10+
The body frame for the prescribed body is designated by the frame :math:`\mathcal{P}`. The prescribed body is attached
11+
to the hub through a hub-fixed mount interface described by the mount frame :math:`\mathcal{M}`. The prescribed body
12+
hub-relative motion is profiled with respect to the mount frame :math:`\mathcal{M}`. The prescribed states are:
1013
``r_PM_M``, ``rPrime_PM_M``, ``rPrimePrime_PM_M``, ``omega_PM_P``, ``omegaPrime_PM_P``, and ``sigma_PM``.
1114

1215
The states of the prescribed body are not defined in this module. Therefore, separate kinematic profiler modules must
1316
be connected to this module's :ref:`PrescribedTranslationMsgPayload` and :ref:`PrescribedRotationMsgPayload`
14-
input messages to profile the prescribed body's states as a function of time. These message connections are required
15-
to provide the prescribed body's states to this dynamics module. Note that either a single profiler can be connected to
16-
these input messages or two separate profiler modules can be used; where one profiles the prescribed body's
17-
translational states and the other profiles the prescribed body's rotational states. See the example script
18-
:ref:`scenarioDeployingSolarArrays` for more information about how to set up hub-relative
17+
input messages to profile the prescribed body's states as a function of time. If neither message is connected to the
18+
module, the prescribed body will not move with respect to the hub. If the prescribed body should only rotate, then only
19+
the rotational message needs to be subscribed to the module and the translational message can be ignored. Similarly,
20+
if the prescribed component should only translate, the rotational message can be ignored. Note that either a single
21+
profiler module can be used to connect both messages to this module, or two separate profiler modules can be used;
22+
where one profiles the translational states and the other profiles the rotational states.
23+
See the example script :ref:`scenarioDeployingSolarArrays` for more information about how to set up hub-relative
1924
multi-body prescribed motion using this state effector module and the associated kinematic profiler modules.
2025

26+
2127
Message Connection Descriptions
2228
-------------------------------
2329
The following table lists all the module input and output messages. The module msg variable name is set by the
@@ -49,84 +55,114 @@ provides information on what this message is used for.
4955
- Output message containing the effector's inertial position and attitude states
5056

5157

52-
Detailed Module Description
53-
---------------------------
58+
Module Overview
59+
---------------
60+
61+
Module Basic Capability
62+
^^^^^^^^^^^^^^^^^^^^^^^
63+
The basic capability of this module is to connect a prescribed motion component to the spacecraft hub. An in-depth
64+
discussion of the functionality of this module and the dynamics derivation required to simulate this type of component
65+
motion is provided in the following journal paper
66+
67+
.. note::
68+
69+
`"Spacecraft Backsubstitution Dynamics with General Multibody Prescribed Subcomponents" <https://www.researchgate.net/publication/392662137_Spacecraft_Backsubstitution_Dynamics_with_General_Multibody_Prescribed_Subcomponents>`_,
70+
Leah Kiner, Hanspeter Schaub, and Cody Allard
71+
Journal of Aerospace Information Systems 2025 22:8, 703-715
5472

55-
Mathematical Modeling
56-
^^^^^^^^^^^^^^^^^^^^^
57-
See Kiner et al.'s paper: `Spacecraft Simulation Software Implementation of General Prescribed Motion Dynamics of Two Connected Rigid Bodies <http://hanspeterschaub.info/Papers/Kiner2023.pdf>`__
58-
for a detailed description of the derived prescribed dynamics.
73+
Branching Capability
74+
^^^^^^^^^^^^^^^^^^^^
75+
An additional feature of this module is the ability to attach other state effectors to the prescribed motion component.
76+
Doing so creates a chain, where the prescribed component is wedged between the hub and its attached state effector.
77+
This capability enables select component branching relative to the spacecraft hub. A detailed discussion of this
78+
capability is provided in the following conference paper
5979

60-
The translational equations of motion are:
80+
.. note::
6181

62-
.. math::
63-
m_{\text{sc}} \left [ \ddot{\boldsymbol{r}}_{B/N} + \boldsymbol{c}^{''} + 2 \left ( \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c}^{'} \right ) + \left ( \dot{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c} \right ) + \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \left ( \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c} \right ) \right ] = \sum \boldsymbol{F}_{\text{ext}}
82+
L. Kiner, and H. Schaub, `“Backsubstitution Method For Prescribed Motion Actuators With Attached Dynamic Sub-Components” <https://www.researchgate.net/publication/394150919_Backsubstitution_Method_for_Prescribed_Motion_Actuators_with_Attached_Dynamic_Sub-Components>`_,
83+
AAS Astrodynamics Specialist Conference, Boston, Massachusetts, August 10–14, 2025
6484

65-
The rotational equations of motion are:
85+
Currently, this branching capability has only been configured for the spinningBodyOneDOF, spinningBodyTwoDOF, and
86+
linearTranslationOneDOF state effectors. See the User Guide section for how to connect these effectors to the
87+
prescribed motion effector. The scenario scripts :ref:`scenarioPrescribedMotionWithRotationBranching`
88+
and :ref:`scenarioPrescribedMotionWithTranslationBranching` are more complex examples demonstrating how to connect
89+
multiple state effectors to the prescribed motion effector.
6690

67-
.. math::
68-
m_{\text{sc}} [\tilde{\boldsymbol{c}}] \ddot{\boldsymbol{r}}_{B/N} + [I_{\text{sc},B}] \dot{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}} = \boldsymbol{L}_B - m_{\text{P}} [\tilde{\boldsymbol{r}}_{P_c/B}] \boldsymbol{r}^{''}_{P_c/B} - \left ( [I^{'}_{\text{sc},B}] + [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}][I_{\text{sc},B}] \right ) \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \\ - \left ( [I^{'}_{\text{P},P_c}] + [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}] [I_{\text{P},P_c}] \right ) \boldsymbol{\omega}_{\mathcal{P}/\mathcal{B}} \ - \ [I_{\text{P},P_c}] \boldsymbol{\omega}^{'}_{\mathcal{P}/\mathcal{B}} \ - \ m_{\text{P}} [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}] [\tilde{\boldsymbol{r}}_{P_c/B}] \boldsymbol{r}^{'}_{P_c/B}
6991

7092
Module Testing
93+
--------------
94+
There are two unit test scripts for this module. The first tests the basic functionality of the module, while
95+
the second test checks the branching capability of the module. Both tests are integrated tests with the
96+
:ref:`prescribedRotation1DOF` and :ref:`prescribedLinearTranslation` profiler modules.
97+
98+
Basic Test
99+
^^^^^^^^^^
100+
The basic test script for this module profiles simultaneous translation and rotation for the prescribed body relative
101+
to the hub using the :ref:`prescribedRotation1DOF` and :ref:`prescribedLinearTranslation` profiler modules. The initial
102+
and reference attitude and displacement of the prescribed body relative to the hub are varied in the test. The test
103+
checks that the quantities of spacecraft orbital angular momentum, rotational angular momentum, and orbital energy
104+
are conserved for the duration of the simulation to verify the module dynamics.
105+
106+
Branching Test
71107
^^^^^^^^^^^^^^
72-
The unit test for this module is an integrated test with two kinematic profiler modules. This is required
73-
because the dynamics module must be connected to kinematic profiler modules to define the states of the
74-
prescribed secondary body that is connected to the rigid spacecraft hub. The integrated test for this module has
75-
two simple scenarios it is testing. The first scenario prescribes a 1 DOF rotation for the
76-
prescribed body using the :ref:`prescribedRotation1DOF` profiler module. The second scenario prescribes a 1 DOF
77-
linear translation for the prescribed body using the :ref:`prescribedLinearTranslation` profiler module.
78-
79-
The unit test ensures that the profiled 1 DOF rotation is properly computed for a series of
80-
initial and reference PRV angles and maximum angular accelerations. The final prescribed angle ``theta_PM_Final``
81-
and angular velocity magnitude ``thetaDot_Final`` are compared with the reference values ``theta_Ref`` and
82-
``thetaDot_Ref``, respectively. The unit test also ensures that the profiled translation is properly computed for a
83-
series of initial and reference positions and maximum accelerations. The final prescribed position magnitude
84-
``r_PM_M_Final`` and velocity magnitude ``rPrime_PM_M_Final`` are compared with the reference values ``r_PM_M_Ref``
85-
and ``rPrime_PM_M_Ref``, respectively. Additionally for each scenario, the conservation quantities of orbital angular
86-
momentum, rotational angular momentum, and orbital energy are checked to verify the module dynamics.
108+
The branching test script for this module has three separate test functions. All tests configure an identical spacecraft
109+
hub an actuating prescribed motion component. The first test connects a free :ref:`spinningBodyOneDOFStateEffector`
110+
to the prescribed component. The second test connects a free :ref:`spinningBodyTwoDOFStateEffector` to the
111+
prescribed component. The third test connects a free :ref:`linearTranslationOneDOFStateEffector` to the prescribed
112+
component. All tests check that the quantities of spacecraft orbital energy, orbital angular momentum, rotational
113+
angular momentum are conserved for the duration of the simulation.
114+
87115

88116
User Guide
89117
----------
90-
This section is to outline the steps needed to setup a Prescribed Motion State Effector in python using Basilisk.
118+
This section outlines how to set up the prescribed motion module in python using Basilisk.
91119

92120
#. Import the prescribedMotionStateEffector class::
93121

94122
from Basilisk.simulation import prescribedMotionStateEffector
95123

96-
#. Create the prescribed body state effector::
124+
#. Create the prescribed motion state effector::
97125

98-
platform = prescribedMotionStateEffector.PrescribedMotionStateEffector()
126+
prescribed_body = prescribedMotionStateEffector.PrescribedMotionStateEffector()
99127

100-
#. Define the state effector module parameters::
128+
#. Set the prescribed motion module parameters::
101129

102-
platform.setMass(100.0)
103-
platform.setIPntPc_P([[50.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 50.0]])
104-
platform.setR_MB_B(np.array([0.0, 0.0, 0.0]))
105-
platform.setR_PcP_P(np.array([0.0, 0.0, 0.0]))
106-
platform.setR_PM_M(np.array([1.0, 0.0, 0.0]))
107-
platform.setRPrime_PM_M(np.array([0.0, 0.0, 0.0]))
108-
platform.setRPrimePrime_PM_M(np.array([0.0, 0.0, 0.0]))
109-
platform.setOmega_PM_P(np.array([0.0, 0.0, 0.0]))
110-
platform.setOmegaPrime_PM_P(np.array([0.0, 0.0, 0.0]))
111-
platform.setSigma_PM(np.array([0.0, 0.0, 0.0]))
112-
platform.setSigma_MB(np.array([0.0, 0.0, 0.0]))
113-
platform.ModelTag = "Platform"
130+
prescribed_body.setMass(100.0)
131+
prescribed_body.setIPntPc_P([[50.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 50.0]])
132+
prescribed_body.setR_MB_B(np.array([0.0, 0.0, 0.0]))
133+
prescribed_body.setR_PcP_P(np.array([0.0, 0.0, 0.0]))
134+
prescribed_body.setR_PM_M(np.array([1.0, 0.0, 0.0]))
135+
prescribed_body.setRPrime_PM_M(np.array([0.0, 0.0, 0.0]))
136+
prescribed_body.setRPrimePrime_PM_M(np.array([0.0, 0.0, 0.0]))
137+
prescribed_body.setOmega_PM_P(np.array([0.0, 0.0, 0.0]))
138+
prescribed_body.setOmegaPrime_PM_P(np.array([0.0, 0.0, 0.0]))
139+
prescribed_body.setSigma_PM(np.array([0.0, 0.0, 0.0]))
140+
prescribed_body.setSigma_MB(np.array([0.0, 0.0, 0.0]))
141+
prescribed_body.ModelTag = "prescribedBody"
114142

115-
Do this for all of the public parameters in the prescribed motion state effector module. Note that if these parameters
116-
are not set by the user, all scalar and vector quantities are set to zero and all matrices are set to identity by
117-
default.
118143

119144
#. Add the prescribed state effector to your spacecraft::
120145

121-
scObject.addStateEffector(platform)
146+
scObject.addStateEffector(prescribed_body)
122147

123148
See :ref:`spacecraft` documentation on how to set up a spacecraft object.
124149

125150
#. Make sure to connect the required messages for this module.
126151

127152
#. Add the module to the task list::
128153

129-
unitTestSim.AddModelToTask(unitTaskName, platform)
154+
unitTestSim.AddModelToTask(unitTaskName, prescribed_body)
130155

131156
See the example script :ref:`scenarioDeployingSolarArrays` for more information about how to set up hub-relative
132157
multi-body prescribed motion using this state effector module and the associated kinematic profiler modules.
158+
159+
If you'd like to connect a state effector to the prescribed state effector instead of the spacecraft hub,
160+
the states of the attached effector must be written with respect to the prescribed body frame instead of the hub
161+
body frame. After creating the attached state effector, make sure to connect it to the prescribed motion effector
162+
rather than the hub::
163+
164+
prescribed_body.addStateEffector(attached_state_effector)
165+
166+
See the example scripts :ref:`scenarioPrescribedMotionWithRotationBranching`
167+
and :ref:`scenarioPrescribedMotionWithTranslationBranching` for more information about how to connect
168+
multiple state effectors to the prescribed motion effector.

0 commit comments

Comments
 (0)