Skip to content

Fix joint ordering in MjSpec.to_xml() for attached models - #3402

Open
anishesg wants to merge 1 commit into
google-deepmind:mainfrom
proudhare:fix/ph-issue-3401
Open

Fix joint ordering in MjSpec.to_xml() for attached models#3402
anishesg wants to merge 1 commit into
google-deepmind:mainfrom
proudhare:fix/ph-issue-3401

Conversation

@anishesg

Copy link
Copy Markdown

The XML writer in mjXWriter::Body() now sorts joints and bodies by their compiled id before writing them to the output XML. Previously, joints and bodies were written in the order they appeared in the internal vectors, which could differ from the compiled model's ordering after attach operations.

When a modular MJCF model uses <attach> to compose sub-models, the internal ordering of joints in body->joints may not match the compiled model's joint ordering (stored in joint->id). This caused MjSpec.to_xml() to export XML that would compile with different joint indices, violating the documented guarantee that exported XML compiles to an equivalent model.

The fix sorts joints and bodies by their compiled id values in xml_native_writer.cc before serializing them to XML. This ensures the exported XML will compile with the same joint and body ordering as the original model, preserving qpos/qvel indices and state vector layout.

Fixes #3401

The XML writer in `mjXWriter::Body()` now sorts joints and bodies by their compiled id before writing them to the output XML. Previously, joints and bodies were written in the order they appeared in the internal vectors, which could differ from the compiled model's ordering after attach operations.

Signed-off-by: anish <anishesg@users.noreply.github.com>
@quagla

quagla commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Hi, thank you for your contribution! I think the bug should not be addresses only at compile time, but during attach. Could you make it such that the joints are ordering at the end of the mjs_attach function? That probably requires calling mjCModel::ProcessList() at the end of mjCModel::operator+=()? Or if you understand why the ordering mismatch happens, you can try to prevent it, but it may be difficult. Also, when you do that we probably need a test in user_api_test. Thanks!

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.

MjSpec.to_xml changes joint/state-vector ordering after attach round-trip

2 participants