Fix MJCF D6 collapse dropping distinct axes and leaving unused D6 axes free - #751
Open
aidaodedjl wants to merge 1 commit into
Open
Fix MJCF D6 collapse dropping distinct axes and leaving unused D6 axes free#751aidaodedjl wants to merge 1 commit into
aidaodedjl wants to merge 1 commit into
Conversation
…s free When the MJCF importer collapses an over-constrained group of single-axis joints (e.g. a humanoid hip authored as three hinges) into one D6 joint, the axis of each source joint was derived from physics:axis alone. mujoco-usd-converter always exports single-axis joints x-aligned and encodes the real MJCF axis direction in localRot0/localRot1, so physics:axis is X for every joint in such a group. Consequences: - Every joint after the first collided on the rotX token and was dropped, losing its DOF even when its physical axis was distinct (and exactly representable by a D6). - The D6 frame was left unrotated, so the surviving axes rotated about the wrong directions whenever the MJCF axes were not cardinal. - The five unused D6 axes were never locked, so the collapsed joint gained spurious free translational (and sometimes rotational) DOFs in PhysX. Recover the physical axis of each source joint from localRot0/localRot1, build a right-handed orthonormal D6 basis from the group's axes via Gram-Schmidt, and assign each joint to a basis column by dot product. Joints that cannot be represented (duplicate/non-orthogonal axes) are still dropped but with a physically accurate warning. All six D6 axes are now explicitly locked except the ones backed by a source joint, and each used axis records the source MJCF joint name in mjcf:<axis>:name. Refs isaac-sim/IsaacLab#6854
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.
Description
Fixes the PhysX D6 collapse step of the MJCF import pipeline (Isaac Sim 6.0,
mjc_to_physx_conversion_utils) dropping distinct joint DOFs and leaving unused D6 axes free. Reported in isaac-sim/IsaacLab#6854.Problem
When several single-axis joints connect the same body pair (e.g. a humanoid hip/shoulder/spine authored as three hinge joints — the standard authoring style in MJCF),
_convert_overconstrained_group_to_d6()collapses them into one D6 joint. The axis of each source joint was derived fromphysics:axisalone.But
mujoco-usd-converteralways exports single-axis joints x-aligned and encodes the real MJCF axis direction inlocalRot0/localRot1. Sophysics:axisisXfor every joint in such a group. Three consequences:rotXtoken and was dropped with a "duplicates D6 axis" warning — even when its physical axis was distinct and exactly representable by a D6. A 3-hinge hip collapsed to a 1-DOF joint.Fix
localRot0/localRot1(_joint_axis_directions())._assign_axes_to_d6_basis()). The D6 frame now encodes the real axis directions.mjcf:<axis>:namefor traceability.Validation
Unit tests (
test_mjc_d6_collapse.py, plainpxr, no Kit): 8 tests covering 3-distinct-axes groups, duplicate-axis drops, mixed revolute/prismatic groups, 2-joint groups, per-axis limits/drives landing on the correct axis, unused-axis locking, andmjcf:<axis>:namemetadata.End-to-end (Linux, real pipeline:
mujoco-usd-converter0.5.0 →convert_mjc_to_physx→combine_overconstrained_joints_to_d6), original vs patched module on the issue's own repro models (ProtoMotionssoma23_humanoid.xml/smpl_humanoid.xml) plus a minimal rotated-triad case:mjcf:<axis>:namemetadataIn the rotated-triad case the old code logged
j_b duplicates D6 axis 'rotX' ... DOF will be lostfor a joint whose physical axis was perfectly distinct — with the fix all three DOFs survive with correct per-axis limits ([-45,45],[-30,60],[-90,90]), the D6 frame reproduces the diagonal world directions, and all translation axes are locked.Checklist
standalone_tests/test_mjc_d6_collapse.py, runs with plainpxr)Refs isaac-sim/IsaacLab#6854