Skip to content

Augment 2DOF Hinged Rigid Bodies for High Fidelity Branching Dynamics #1358

Open
DavilaDawg wants to merge 3 commits intodevelopfrom
feature/hinged-branching-2dof-restore
Open

Augment 2DOF Hinged Rigid Bodies for High Fidelity Branching Dynamics #1358
DavilaDawg wants to merge 3 commits intodevelopfrom
feature/hinged-branching-2dof-restore

Conversation

@DavilaDawg
Copy link
Copy Markdown
Contributor

  • Tickets addressed: bsk-1151
  • Review: By commit
  • Merge strategy: Merge (no squash)

Description

The 2DOF restore branch expands effector branching support by allowing the dual hinged rigid body state effector to act as the parent of attached dynamic effectors, rather than requiring all child effectors to be attached directly to the spacecraft hub. This restores the intended branching architecture for articulated systems and enables forces and torques to be applied at the hinged body level, which is necessary for more realistic subsystem attachment and interaction modeling. The branch also reestablishes the correct inertial property handoff for attached effectors. In particular, the dual hinged rigid body now provides the proper position, velocity, attitude, and angular velocity references for the selected segment so downstream dynamic effectors can evaluate their loads in the correct frame and at the correct physical location. This ensures that externally applied forces and torques propagate through the hinged body chain consistently with the system geometry and equations of motion. In addition to the runtime changes, the integrated branching test coverage was changed so the 2DOF hinged rigid body path is a valid parent configuration. That gives direct verification that attachment compatibility, inertial property linking, and resulting dynamics all behave as expected. Together, these updates bring the 2DOF hinged rigid body implementation back in line with the broader branching framework.

Verification

test_effectorBranching_integrated.py was updated to allow 2DOF HRB to be a parent and setup_dualHingedRigidBodies method was added. The aerobrake scenario was used to validate the dynamics of a sc with 2DOF HRB's attached to it.

Documentation

No documentation was invalidated by the changes. bskReleaseNotes was updated to have a note on the changes made in this branch.

Future work

The NDOF HRB is next to be augmented for branching capabilities.

@DavilaDawg DavilaDawg requested a review from a team as a code owner April 14, 2026 22:34
@DavilaDawg DavilaDawg force-pushed the feature/hinged-branching-2dof-restore branch from 9034ac8 to c705b65 Compare April 14, 2026 22:37
@DavilaDawg DavilaDawg self-assigned this Apr 21, 2026
@DavilaDawg DavilaDawg force-pushed the feature/hinged-branching-2dof-restore branch from c705b65 to 0e0b122 Compare April 21, 2026 21:38
@andrewmorell andrewmorell force-pushed the feature/hinged-branching-2dof-restore branch 2 times, most recently from 36202ce to 939a9c8 Compare April 22, 2026 03:11
@andrewmorell andrewmorell added the enhancement New feature or request label Apr 22, 2026
@andrewmorell andrewmorell moved this to 👀 In review in Basilisk Apr 22, 2026
Copy link
Copy Markdown
Contributor

@andrewmorell andrewmorell left a comment

Choose a reason for hiding this comment

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

Mostly just needs some small cleanup and moving release notes to the new format.

Comment thread src/simulation/dynamics/dualHingedRigidBodies/dualHingedRigidBodyStateEffector.h Outdated
Comment thread docs/source/Support/bskReleaseNotes.rst Outdated
Comment thread src/simulation/dynamics/dualHingedRigidBodies/dualHingedRigidBodyStateEffector.h Outdated
@andrewmorell andrewmorell force-pushed the feature/hinged-branching-2dof-restore branch from 939a9c8 to b98deaf Compare April 28, 2026 18:47
@andrewmorell andrewmorell self-requested a review April 28, 2026 18:48
Copy link
Copy Markdown
Contributor

@andrewmorell andrewmorell left a comment

Choose a reason for hiding this comment

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

Everything looks good to me now!

Copy link
Copy Markdown
Contributor

@schaubh schaubh left a comment

Choose a reason for hiding this comment

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

I'm not seeing any tests here confirming angular momentum or energy is correct? As Codex found some missing DCMs, these are critical tests to add.

+ omega_PN_P.cross(this->r_H1P_P));

// H1 is fixed in body frame, so v_H1N_N = v_PN_N + omega_PN x r_H1P_P
*this->v_HN_N[0] = Eigen::Vector3d(v_PN_N + omega_PN_P.cross(this->r_H1P_P));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here you are adding a vector with N-frame components to a vector in P-frame components. You need a DCM!

Eigen::Vector3d externalForcePan1_P = this->dcm_S1P.transpose() * attBodyForce_S1;
Eigen::Vector3d externalForcePan2_P = this->dcm_S2P.transpose() * attBodyForce_S2;
Eigen::Vector3d externalTorquePan1PntS1_P = this->dcm_S1P.transpose() * attBodyTorquePntS1_S1;
Eigen::Vector3d externalTorquePan2PntS2_P = this->dcm_S2P.transpose() * attBodyTorquePntS2_S2;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Attached dynamic effectors can produce forceExternal_N, and ExtForceTorque exposes that path, but this accumulation only uses forceExternal_B. The PR marks External Force Torque support as green, so an inertial force command attached to a dual hinged body would be silently dropped from both translation and torque-arm contributions. Transform the inertial force into the parent frame and include it alongside the body-frame force.

hingedBody = dualHingedRigidBodyStateEffector.DualHingedRigidBodyStateEffector()

# Define properties of HRB
hingedBody.mass1 = 200
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The new test setup assigns physical quantities without the required trailing unit comments from this repo’s AGENTS.md rules. For example, masses, inertias, distances, stiffness, damping, angles, and angular rates in this block should use comments like # [kg], # [kgm^2], # [m], # [Nm/rad], # [Nms/rad], and # [rad].

+ omega_PN_P.cross(this->r_H1P_P));
Eigen::Vector3d omega_S2N_P = this->theta2Dot * this->sHat22_P + omega_S1N_P;
this->v_SN_N[1] = (Eigen::Vector3d)(*this->inertialVelocityProperty)
this->v_SN_N[1] = (Eigen::Vector3d)(v_PN_N
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The same frame issue also affects the panel COM velocity outputs. v_SN_N is written to an SCStatesMsgPayload as an inertial-frame velocity, but the relative cross-product terms are still in P-frame components before being added to v_PN_N. This should rotate the relative velocity contribution through dcm_NP, otherwise panel velocity logs are wrong for non-identity hub attitude.

Eigen::Vector3d v_PN_N = (Eigen::Vector3d)(*this->inertialVelocityProperty);
Eigen::Vector3d omega_S1N_P = this->theta1Dot * this->sHat12_P + omega_PN_P;
this->v_SN_N[0] = (Eigen::Vector3d)(*this->inertialVelocityProperty)
this->v_SN_N[0] = (Eigen::Vector3d)(v_PN_N
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The same frame issue also affects the panel COM velocity outputs. v_SN_N is written to an SCStatesMsgPayload as an inertial-frame velocity, but the relative cross-product terms are still in P-frame components before being added to v_PN_N. This should rotate the relative velocity contribution through dcm_NP, otherwise panel velocity logs are wrong for non-identity hub attitude.


// H2 position relative to P: r_H2P_P = r_H1P_P - l1 * sHat11_P
// But sHat11_P rotates with theta1, so H2 does move relative to B
*this->v_HN_N[1] = Eigen::Vector3d(v_PN_N
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For r_H2P_P = r_H1P_P - l1 * sHat11_P, the body-relative derivative should be +l1 * theta1Dot * sHat13_P, matching the module’s own rPrimeS2P_P expression above. The new H2 inertial velocity property uses the negative sign, so segment-2 children see the wrong attachment velocity even when the hub attitude is identity.

Please check the signs of this.

dcm_S1H1 = rbk.euler2(hingedBody.theta1Init)
dcm_S2H1 = rbk.euler2(hingedBody.theta2Init) @ dcm_S1H1
s1_hat = np.array([[-1.0],[0.0],[0.0]])
mr_ScB_B = -((hingedBody.r_H1B_B + np.transpose(hingedBody.dcm_H1B) @
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The test’s second-body COM offset leaves the l1 * s1_hat H2 offset unrotated by dcm_S1H1, while the production kinematics compute r_H2P_P = r_H1P_P - l1 * sHat11_P and the test’s own r_PB_B calculation below does apply that rotation. This means the hub COM offset used to make B and C coincide is slightly wrong for nonzero theta1Init, weakening the constraint and conservation setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

3 participants