test_effectorBranching_integrated
- test_effectorBranching_integrated.test_effectorBranchingIntegratedTest(show_plots, stateEffector, isParent, dynamicEffector, isChild)[source]
Validation Test Description
This integrated test sets up combinations of dynamic effector attached to a state effector.
Description of Variables Being Tested
In this file we are checking first for branching compatibility, as not every state effector is set up to host dependent effectors (isParent), and not every dynamic effector is set up to be attached to a state effector (isChild). The state effector compatibility is checked when the addDynamicEffector() method is called. The dynamic effector compatibility is checked at simulation initialization when linkInProperties() is called.
A summary of which state effectors and dynamic effectors are expected to be able to act as a parent or child effector to another is summarized in Advanced: Effector Module Branching.
Note that the constraint effector is tested in two configurations: once where one vehicle’s state effector is attached to the hub on another vehicle (
constraintEffectorOneHub), and once where both vehicles’ state effectors are attached to each other (constraintEffectorNoHubs). Additionally, a test with multiple dynamic effectors attached to a single state effector is included (multiEffector). Finally, at least one non-compatible state effector and one non-compatible dynamic effector are included to check that the error handling catches as expected.Note that the center of mass of the hub is adjusted to balance the shift in total vehicle COM due to the addition of the state effector’s mass. This adjustment is calculated such that at simulation initialization the total center of mass of the vehicle is coincident with the hub’s body frame B (r_BN_N = r_CN_N). This greatly simplifies the setup of the constraint effector branching scenarios. This calculation is performed by calculating the parameter mr_PcB_B in each state effector’s setup method which for the state effector’s series of \(i\) bodies is:
\[\sum_i m_{P_i} {}^{\mathcal{B}}\mathbf{r}_{Pc_i/B}\]Where P is the state effector’s designation as “parent”, with each of its \(i\) segments having segment body fixed frame \(\mathcal{P}_i\), origin \(P_i\), and segment center of mass \(Pc_i\). Then used to compute the hub center of mass offset scObject.hub.r_BcB_B as:
\[{}^{\mathcal{B}}\mathbf{r}_{Bc/B} = \frac{- \sum_i m_{P_i} {}^{\mathcal{B}}\mathbf{r}_{Pc_i/B}} {\sum_i m_{Bc}}\]In the case of a permissible combination, we then check that properties are being handed correctly from the state effector to dynamic effector.
These variables include:
inertialPositionPropertyinertialVelocityPropertyinertialAttitudePropertyinertialAngVelocityProperty
Finally, we simultaneously check that a) the applied force and torque are being handed correctly from the dynamic effector to state effector, and b) that these forces and torques are implemented correctly in the state effector’s equations of motion. We do this by isolating each case where a state effector has the C++ Module: extForceTorque effector attached to it. Using the explicitly defined
forceExternal_BandtorqueExternalPntB_Band the logged inertial position and attitude properties of the state effector, we manually compute the total external force on the vehicle about the combined center of mass and the accumulated delta V of the vehicle’s combined center of mass. The torque is then integrated using a trapezoid rule and compared against the spacecraft’s internally computed angular momentum.\[\begin{split}{}^{\mathcal{N}}\!\Delta\mathbf{H}_{C} & = \int_{t_0}^{t} {}^{\mathcal{N}}\!\boldsymbol{\tau}_{\text{ext},C}(t)\,dt \\ & = \int_{t_0}^{t} \text{Pure Torque + Force Relative to COM} \\ & = \int_{t_0}^{t} [\mathcal{NP}_j] {}^{\mathcal{P}_j}\!\boldsymbol{\tau}_{\text{ext},P_j} + \left( {}^{\mathcal{N}}\mathbf{r}_{Pc_j/N} - [\mathcal{NP}_j] {}^{\mathcal{P}_j}\mathbf{r}_{Pc_j/P_j} - {}^{\mathcal{N}}\mathbf{r}_{C/N} \right) \times \left( [\mathcal{NP}_j] {}^{\mathcal{P}_j}\mathbf{F}_{P_j} \right)\end{split}\]Where \(j\) is the segment that the dynamic effector is attached to. The sim ‘truth’ \({}^{\mathcal{N}}\!\Delta\mathbf{H}_{C}\) (scObject.totOrbAngMomPntN_N) and \({}^{\mathcal{N}}\mathbf{r}_{C/N}\) are logged from the spacecraft module. Exerted \({}^{\mathcal{P}_j}\!\boldsymbol{\tau}_{\text{ext},P_j}\) and \({}^{\mathcal{P}_j}\mathbf{F}_{P_j}\) are from the extForceTorque effector module. \({}^{\mathcal{N}}\mathbf{r}_{Pc_j/N}\), \([\mathcal{NP}_j]\), and \({}^{\mathcal{P}_j}\mathbf{r}_{Pc_j/P_j}\) come from the state effector module.
Neither of those checks can see an error inside the parent’s own equations of motion. The parent’s back-substitution stays internally consistent even when one of its terms is wrong, so the momentum it hands the hub still matches the momentum its own coordinates lose. Energy is not blind in the same way: a wrong generalized force does work that the applied load does not account for. All state effector dampers are therefore set to zero, and the change in the vehicle’s rotational energy is compared against the work the child does about the vehicle center of mass,
\[\Delta T_{\text{rot}} = \int_{t_0}^{t} \left[ [\mathcal{NP}_j] {}^{\mathcal{P}_j}\!\boldsymbol{\tau}_{\text{ext},P_j} \cdot {}^{\mathcal{N}}\boldsymbol{\omega}_{\mathcal{P}_j/\mathcal{N}} + [\mathcal{NP}_j] {}^{\mathcal{P}_j}\mathbf{F}_{P_j} \cdot \left( {}^{\mathcal{N}}\mathbf{v}_{P_j/N} - {}^{\mathcal{N}}\mathbf{v}_{C/N} \right) \right] dt\]where the attachment point velocity is recovered from the logged segment center of mass, \(\mathbf{v}_{P_j/N} = \mathbf{v}_{Pc_j/N} + \boldsymbol{\omega}_{\mathcal{P}_j/\mathcal{N}} \times \left( - [\mathcal{NP}_j] {}^{\mathcal{P}_j}\mathbf{r}_{Pc_j/P_j} \right)\).
Asserting only that this residual is small would be weak: the residual also carries discretization error, so the tolerance has a floor and any defect smaller than that floor is invisible unless the applied loads are raised until it clears. The test therefore asserts convergence instead. The residual is dominated by the trapezoid rule used for the work integral above, which is second order, so halving the step must drop it to roughly a quarter. A wrong term in the equations of motion contributes a residual that does not shrink with the step at all, and the ratio moves from a quarter towards one. The ratio is therefore required to sit near 0.25 rather than merely to decrease. The lower bound matters too: a ratio well under 0.25 means the residual is falling faster than a trapezoid allows, which in practice means it has reached a floor and the check has stopped measuring the equations of motion. This criterion is independent of the load magnitude, so it does not have to be re-tuned when the loads or the step change.
The accumulated delta V is compared against the internally computed delta V of the spacecraft center of mass.
\[{}^{\mathcal{N}}\!\Delta v_{accum,C} = \int_{t_0}^{t} \frac{[\mathcal{NP}_j] {}^{\mathcal{P}_j}\mathbf{F}_{P_j}} {m_{Bc} + \sum_i m_{P_i}} dt\]where again \(j\) is the segment that the dynamic effector is attached to among all \(i\) segments. The sim ‘truth’ \({}^{\mathcal{N}}\!\Delta v_{accum,C}\) is logged from the spacecraft module.
- test_effectorBranching_integrated.test_parentPublishesCurrentVelocityToChild(stateEffector)[source]
Validation Test Description
This test checks that a branching parent’s published inertial velocity is current at the integrator substep on which its child evaluates, rather than at the previous task step.
Description of Variables Being Tested
The conservation checks in the test above cannot see an error here. They drive the parent with C++ Module: extForceTorque, whose load is constant, so a wrong published velocity reaches neither the trajectory nor the work integral. This test therefore attaches a child whose load is a function of that velocity, namely a C++ Module: constraintDynamicEffector between the parent’s first segment and the hub of the same spacecraft, with its stiffness suppressed so that only the velocity feedback term contributes,
\[\boldsymbol{\psi}' = {}^{\mathcal{N}}\dot{\mathbf{r}}_{P_2/P_1} - \boldsymbol{\omega}_{\mathcal{P}_1/\mathcal{N}} \times \mathbf{r}_{P_2/P_1}\]The parent’s first segment is locked and started at rest, which makes that segment and the hub one rigid body. Both attachment points are then fixed in that body and \(\boldsymbol{\omega}_{\mathcal{P}_1/\mathcal{N}}\) equals the hub rate, so the two terms cancel identically and the constraint force is zero for any hub attitude and rate. A published velocity that lags the current substep leaves the cancellation incomplete, and the residual appears as a force of order \(|\boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}}| \, |\mathbf{r}_{P_1/B}|\). The assertion is therefore against zero rather than against a tolerance scaled to the step size or to the applied load.
The hinged rigid bodies are absent because they expose no lock, so their panel always rotates relative to the hub and no such rigid configuration exists.