Repository navigation
Conversation
…-of-mass The linear velocity of a dynamic multibody root is the velocity of its center-of-mass, but its free joint stores the pose of the rigid-body origin and applied the rotation around that origin. A root whose local center-of-mass isn't at its origin therefore drifted: a pure torque translated the whole assembly.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A dynamic multibody root whose local center-of-mass isn't at its origin drifts: a pure torque translates the whole assembly, even with no gravity or contacts.
For example, a root of mass 2 with its local center-of-mass at
(0.2, 0, 0), welded with a multibody fixed joint to a link of mass 1, driven by a 1 N·m torque for one second (60 steps) moves the assembly's center-of-mass by ~8.85 cm. The same bodies joined by an impulse joint, or merged into a single rigid-body, don't move (≤ 1e-7).Cause
The root's generalized linear velocity is the velocity of its center-of-mass (
Multibody::update_velocitieswrites the root joint velocity directly intorb.vels, and children are offset fromworld_com). But the root's free joint stores the pose of the rigid-body origin, andMultibodyJoint::integrateappliescoords += linvel * dtthen rotates around that origin. With a non-zero local center-of-massr, each step moves the center-of-mass by an extra(R_before - R_after) * r, and every link follows the root.Regular rigid-bodies don't have this problem:
RigidBodyVelocity::integraterotates around the center-of-mass.Fix
Multibody::integratenow takes theRigidBodySet. For a dynamic root with a free joint, it compensates the root origin translation byR_before * local_com - R_after * local_com, so the rotation is applied around the center-of-mass, consistent withRigidBodyVelocity::integrate. Non-root links and fixed/kinematic roots are unchanged.Tests
multibody_root_with_offset_center_of_mass_rotates_around_it. It fails without the fix (drift0.0885for a root com of(0.2, 0, 0)) and passes with it.cargo test -p rapier2d -p rapier2d-f64 -p rapier3d -p rapier3d-f64, theenhanced-determinismdeterminism/parity/snapshot tests,cargo fmt --checkandcargo clippypass.AI assistance (Claude) was used to investigate, write the fix and the regression test, and I reviewed the results.