Skip to content

Fix COM frame composition in mjCBody::AccumulateInertia#3250

Open
gholmes829 wants to merge 1 commit into
google-deepmind:mainfrom
gholmes829:fix/accumulate-inertia-com-frame-order
Open

Fix COM frame composition in mjCBody::AccumulateInertia#3250
gholmes829 wants to merge 1 commit into
google-deepmind:mainfrom
gholmes829:fix/accumulate-inertia-com-frame-order

Conversation

@gholmes829
Copy link
Copy Markdown

@gholmes829 gholmes829 commented Apr 29, 2026

mjCBody::AccumulateInertia calls mjuu_frameaccum with the body pose and inertial offset arguments swapped, composing body_ipose ∘ body_pose instead of the documented body_pose ∘ body_ipose. The merged center-of-mass is wrong whenever the body pose and inertial offset don't commute as transforms.

Most commonly triggered by URDF fixed-joint children with degenerate-eigenvalue inertia (typical of capsule/cylinder approximations), where mjuu_fullInertia returns a non-trivial principal-axes rotation.

Distinct from #2982, which patched the inertia-tensor rotation in the same function. #2982's reproduction (child with pos = 0) collapses both arg orders to the same answer, so it could not have caught this.

Added test fails before the fix with merged body_ipos = (0, 0, 0.5) and passes after with (0.5, 0, 0).


// Merged COM must be correct when a fused-static child has a non-identity
// inertial-frame orientation (e.g. from a degenerate diaginertia).
TEST_F(UserObjectsTest, FuseStaticWithRotatedInertial) {
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.

Hi I tried to run this test and it passes even before the bugfix, could we please modify the test such that it fails before the fix and it passes afterwards? Thanks!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @quagla thanks for the feedback.

I've re-checked on a clean worktree of current main (2b67fe3) with only the test cherry-picked in (no source change) -- test fails for me with body_ipos = {0, 0, 0.5} vs expected {0.5, 0, 0}. Cherry-picking the source change from this PR makes it pass.

Could the source change have still been applied when you tested? Or is there a different testing approach I should take?

For reference, I'm building and running with:

cmake -B build -DMUJOCO_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release .
cmake --build build --target user_objects_test -j$(nproc)
./build/bin/user_objects_test --gtest_filter="UserObjectsTest.FuseStaticWithRotatedInertial"

Platform:

  • Linux x86_64 (WSL2), gcc default, Release mode, googletest from the repo's _deps/

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.

Something probably went wrong the previous time I tested it. I confirm it fails for me too!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Awesome -- glad we're on same page, and thanks again for the timely review and approval.

At this point are we just waiting for review from @yuvaltassa? Just checking in to make sure y'all aren't waiting on me for something that I'm not realizing.


// Merged COM must be correct when a fused-static child has a non-identity
// inertial-frame orientation (e.g. from a degenerate diaginertia).
TEST_F(UserObjectsTest, FuseStaticWithRotatedInertial) {
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.

Something probably went wrong the previous time I tested it. I confirm it fails for me too!

@gholmes829
Copy link
Copy Markdown
Author

Hi @yuvaltassa @quagla, thanks again for the reviews. I am noticing the feedback/copybara failed despite all the normal tests and public repo checks passing. Just want to check in -- is there anything you need from me to remedy these, or is this something that is being handled internally?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants