Affine Body Revolute Joint External Force
#668 AffineBodyRevoluteJointExternalForce
The Affine Body Revolute Joint External Force applies a scalar external torque around the axis of a Revolute Joint. The torque drives rotational motion between the two connected affine bodies about the shared joint axis.
Torque Application
Given a scalar torque \(\tau\) and the joint axis direction \(\hat{\mathbf{e}}\), the external torque is converted into a translational force at each body's center of mass. The torque produces equal-and-opposite tangential forces on the two bodies:
where:
- \(\tau\) is the scalar torque magnitude (per edge)
- \(\hat{\mathbf{e}}_k\) is the normalized joint axis direction in body \(k\)'s current frame
- \(\mathbf{r}_k\) is the lever arm vector from the joint axis to body \(k\)'s center of mass, perpendicular to the axis
- \(\mathbf{0}_9\) denotes the nine-dimensional zero vector (no affine force component)
Axis Direction
The joint axis is defined by two points \(\mathbf{x}^0\) and \(\mathbf{x}^1\) on each body, following the Revolute Joint convention. The axis direction in world space is:
where \(\mathring{\mathbf{J}}^{\hat{e}}_k\) maps the rest-space axis direction through the current affine transform.
Lever Arm
The lever arm \(\mathbf{r}_k\) is the perpendicular distance from the joint axis to the center of mass of body \(k\):
where \(\mathbf{d}_k\) is the vector from the axis point to the center of mass in world space.
When \(\|\mathbf{r}_k\|^2 < \epsilon\) (the center of mass lies on the axis), the force contribution for that body is zero.
Sign Convention
A positive \(\tau\) applies torque to body \(j\) in the \(+\hat{\mathbf{e}}\) direction (counterclockwise when viewed along \(+\hat{\mathbf{e}}\), right-hand rule) and an equal-and-opposite reaction torque to body \(i\).
Energy Integration
The external forces are incorporated into each affine body's kinetic energy term through the predicted position \(\tilde{\mathbf{q}}\), following the same mechanism as AffineBodyExternalForce:
where \(\tilde{\mathbf{q}}\) is updated each time step to include the acceleration from the external force:
State Update
The current joint angle \(\theta_{\text{current}}\) is tracked and written back to the angle edge attribute by the base AffineBodyRevoluteJoint — not by this external-force constitution. See Angle State for the formulation.
Runtime Control
The torque can be updated at each frame through the Animator system:
- Set
external_torque/is_constrainedto1to enable the torque, or0to disable it. - Modify the
external_torqueattribute to change the torque magnitude.
Requirement
This constitution must be applied to a geometry that already has an AffineBodyRevoluteJoint (UID=18) constitution.
Attributes
On the joint geometry (1D simplicial complex), on edges (one edge per joint). The edge inherits all linking and state fields of the base Affine Body Revolute Joint: l_geo_id, r_geo_id, l_inst_id, r_inst_id, strength_ratio, angle, init_angle, and optional l_position0, l_position1, r_position0, r_position1 when created via Local create_geometry.
External-force-specific attributes on edges:
external_torque: \(\tau\) in the formulae above, scalar torque around the joint axis (one per edge)external_torque/is_constrained: enables (1) or disables (0) the external torque