Scope USD custom-frequency parsing#2659
Conversation
Use a root_path-bounded PrimRange for custom-frequency USD callbacks so sibling subtrees do not emit rows during cloned imports. Exercise the scoped traversal through existing generic custom-frequency and MuJoCo tendon tests.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe PR scopes USD custom-frequency prim traversal to the provided Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Co-authored-by: Philipp Reist <66367163+preist-nvidia@users.noreply.github.com> Signed-off-by: adenzler-nvidia <adenzler@nvidia.com>
Per-environment string identifiers like ``mujoco:tendon_label`` were keeping their source proto path after replication, because ``_rename_builder_labels`` only walked built-in label arrays (body/joint/shape/articulation). Tendon names therefore showed ``env_0/...`` for every environment, even though the tendon counts themselves were correct. Generalize the rewrite to also walk any string-typed custom-attribute column whose frequency declares a sibling ``references="world"`` companion. This is the same data shape the solver already uses to declare per-world parameter columns, so any future solver-registered string column is handled without changes here. The existing ``startswith(src_path)`` guard makes the rewrite a no-op for non-path strings, leaving them untouched. ``constraint_mimic`` joins the built-in pass for completeness. Also add a TODO on ``_scope_custom_frequencies`` pointing at newton-physics/newton#2659 (commit 1d22547). Once the IsaacLab Newton pin includes that commit, ``parse_usd`` scopes the walk to ``root_path`` itself and the wrapper becomes a redundant identity check on already-in-scope prims; the shim can then be removed.
Per-environment string identifiers like ``mujoco:tendon_label`` were keeping their source proto path after replication, because ``_rename_builder_labels`` only walked built-in label arrays (body/joint/shape/articulation). Tendon names therefore showed ``env_0/...`` for every environment, even though the tendon counts themselves were correct. Generalize the rewrite to also walk any string-typed custom-attribute column whose frequency declares a sibling ``references="world"`` companion. This is the same data shape the solver already uses to declare per-world parameter columns, so any future solver-registered string column is handled without changes here. The existing ``startswith(src_path)`` guard makes the rewrite a no-op for non-path strings, leaving them untouched. ``constraint_mimic`` joins the built-in pass for completeness. Also add a TODO on ``_scope_custom_frequencies`` pointing at newton-physics/newton#2659 (commit 1d22547). Once the IsaacLab Newton pin includes that commit, ``parse_usd`` scopes the walk to ``root_path`` itself and the wrapper becomes a redundant identity check on already-in-scope prims; the shim can then be removed.
The Newton 1.2 release includes the upstream tendon-scoping fix (newton-physics/newton#2659), which scopes ``parse_usd``'s custom- frequency walk to ``root_path`` natively. Bumping the Newton pin removes the cross-source ``MjcTendon`` contamination IsaacLab previously had to work around at the framework layer. Pin bumps: * ``source/isaaclab/setup.py``: ``warp-lang==1.12.0`` → ``>=1.13.0``, ``mujoco==3.6.0`` → ``==3.8.0``, ``mujoco-warp==3.6.0`` → ``==3.8.0.1``. * ``source/isaaclab_newton/setup.py``: same mujoco / mujoco-warp bumps; Newton pin → ``v1.2.0rc1``. * ``source/isaaclab_visualizers/setup.py``: 3 × Newton pin → ``v1.2.0rc1``. Code adapts: * ``source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py`` and ``source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py``: ``wp.math.transform_to_matrix`` → ``wp.transform_to_matrix``. The ``wp.math`` namespace was removed in ``warp-lang`` 1.13. Per-env label rename: * ``_rename_builder_labels`` now walks string-typed custom-attribute columns whose frequency declares a ``references="world"`` companion (e.g. ``mujoco:tendon_label``), rewriting the per-row source-path prefix to the destination world root. ``constraint_mimic`` joins the built-in label pass. The prefix match uses a path-separator boundary so source paths that share a string prefix (``/Sources/protoA`` vs ``/Sources/protoAB``) do not cross- contaminate. Newton's ``add_builder`` copies labels verbatim and tracks env identity in ``*_world`` int columns; the IL rename is the structural translation between Newton's labeling model and IL's per-env USD-path model. Both passes (built-in label arrays and string custom-attribute columns) remain necessary after the Newton bump. Adds ``test_rename_builder_labels.py`` with 10 cases covering the two passes, multi-source prefix-overlap regression, sparse env ids, multi-frequency, multiple string columns at one frequency, and empty-values pass-through.
The Newton 1.2 release includes the upstream tendon-scoping fix (newton-physics/newton#2659), which scopes ``parse_usd``'s custom- frequency walk to ``root_path`` natively. Bumping the Newton pin removes the cross-source ``MjcTendon`` contamination IsaacLab previously had to work around at the framework layer. Pin bumps: * ``source/isaaclab/setup.py``: ``warp-lang==1.12.0`` → ``>=1.13.0``, ``mujoco==3.6.0`` → ``==3.8.0``, ``mujoco-warp==3.6.0`` → ``==3.8.0.1``. * ``source/isaaclab_newton/setup.py``: same mujoco / mujoco-warp bumps; Newton pin → ``v1.2.0rc1``. * ``source/isaaclab_visualizers/setup.py``: 3 × Newton pin → ``v1.2.0rc1``. Code adapts: * ``source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py`` and ``source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py``: ``wp.math.transform_to_matrix`` → ``wp.transform_to_matrix``. The ``wp.math`` namespace was removed in ``warp-lang`` 1.13. Per-env label rename: * ``_rename_builder_labels`` now walks string-typed custom-attribute columns whose frequency declares a ``references="world"`` companion (e.g. ``mujoco:tendon_label``), rewriting the per-row source-path prefix to the destination world root. ``constraint_mimic`` joins the built-in label pass. The prefix match uses a path-separator boundary so source paths that share a string prefix (``/Sources/protoA`` vs ``/Sources/protoAB``) do not cross- contaminate. Newton's ``add_builder`` copies labels verbatim and tracks env identity in ``*_world`` int columns; the IL rename is the structural translation between Newton's labeling model and IL's per-env USD-path model. Both passes (built-in label arrays and string custom-attribute columns) remain necessary after the Newton bump. Adds ``test_rename_builder_labels.py`` with 10 cases covering the two passes, multi-source prefix-overlap regression, sparse env ids, multi-frequency, multiple string columns at one frequency, and empty-values pass-through.
The Newton 1.2 release includes the upstream tendon-scoping fix (newton-physics/newton#2659), which scopes ``parse_usd``'s custom- frequency walk to ``root_path`` natively. Bumping the Newton pin removes the cross-source ``MjcTendon`` contamination IsaacLab previously had to work around at the framework layer. Pin bumps: * ``source/isaaclab/setup.py``: ``warp-lang==1.12.0`` → ``>=1.13.0``, ``mujoco==3.6.0`` → ``==3.8.0``, ``mujoco-warp==3.6.0`` → ``==3.8.0.1``. * ``source/isaaclab_newton/setup.py``: same mujoco / mujoco-warp bumps; Newton pin → ``v1.2.0rc1``. * ``source/isaaclab_visualizers/setup.py``: 3 × Newton pin → ``v1.2.0rc1``. Code adapts: * ``source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py`` and ``source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py``: ``wp.math.transform_to_matrix`` → ``wp.transform_to_matrix``. The ``wp.math`` namespace was removed in ``warp-lang`` 1.13. Per-env label rename: * ``_rename_builder_labels`` now walks string-typed custom-attribute columns whose frequency declares a ``references="world"`` companion (e.g. ``mujoco:tendon_label``), rewriting the per-row source-path prefix to the destination world root. ``constraint_mimic`` joins the built-in label pass. The prefix match uses a path-separator boundary so source paths that share a string prefix (``/Sources/protoA`` vs ``/Sources/protoAB``) do not cross- contaminate. Newton's ``add_builder`` copies labels verbatim and tracks env identity in ``*_world`` int columns; the IL rename is the structural translation between Newton's labeling model and IL's per-env USD-path model. Both passes (built-in label arrays and string custom-attribute columns) remain necessary after the Newton bump. Adds ``test_rename_builder_labels.py`` with 10 cases covering the two passes, multi-source prefix-overlap regression, sparse env ids, multi-frequency, multiple string columns at one frequency, and empty-values pass-through.
The Newton 1.2 release includes the upstream tendon-scoping fix (newton-physics/newton#2659), which scopes ``parse_usd``'s custom- frequency walk to ``root_path`` natively. Bumping the Newton pin removes the cross-source ``MjcTendon`` contamination IsaacLab previously had to work around at the framework layer. Pin bumps: * ``source/isaaclab/setup.py``: ``warp-lang==1.12.0`` → ``>=1.13.0``, ``mujoco==3.6.0`` → ``==3.8.0``, ``mujoco-warp==3.6.0`` → ``==3.8.0.1``. * ``source/isaaclab_newton/setup.py``: same mujoco / mujoco-warp bumps; Newton pin → ``v1.2.0rc1``. * ``source/isaaclab_visualizers/setup.py``: 3 × Newton pin → ``v1.2.0rc1``. Code adapts: * ``source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py`` and ``source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py``: ``wp.math.transform_to_matrix`` → ``wp.transform_to_matrix``. The ``wp.math`` namespace was removed in ``warp-lang`` 1.13. Per-env label rename: * ``_rename_builder_labels`` now walks string-typed custom-attribute columns whose frequency declares a ``references="world"`` companion (e.g. ``mujoco:tendon_label``), rewriting the per-row source-path prefix to the destination world root. ``constraint_mimic`` joins the built-in label pass. The prefix match uses a path-separator boundary so source paths that share a string prefix (``/Sources/protoA`` vs ``/Sources/protoAB``) do not cross- contaminate. Newton's ``add_builder`` copies labels verbatim and tracks env identity in ``*_world`` int columns; the IL rename is the structural translation between Newton's labeling model and IL's per-env USD-path model. Both passes (built-in label arrays and string custom-attribute columns) remain necessary after the Newton bump. Adds ``test_rename_builder_labels.py`` with 10 cases covering the two passes, multi-source prefix-overlap regression, sparse env ids, multi-frequency, multiple string columns at one frequency, and empty-values pass-through.
After Newton's add_builder copies proto rows into the merged builder
for each environment, every row's label still references the source
proto path. Newton tracks env identity in *_world int companion
columns; IsaacLab keys data flow off USD prim paths, so each row's
label needs to be rewritten to its per-env destination path.
_rename_builder_labels now walks two kinds of label-bearing columns:
* Built-in label arrays (body, joint, shape, articulation,
constraint_mimic, equality_constraint), each paired with its
matching *_world int column.
* String-typed custom-attribute columns (e.g. mujoco:tendon_label)
paired with a references="world" companion at the same frequency.
Any future solver-registered string column at a frequency that has
a references="world" companion is handled automatically.
The prefix match uses a path-separator boundary
(``src_path.rstrip("/") + "/"``) so a source path that is a string
prefix of another (``/Sources/protoA`` vs ``/Sources/protoAB``) does
not cross-contaminate when both feed the same envs.
The function raises ValueError if the parallel arrays of labels and
worlds have mismatched lengths, instead of silently truncating.
Adds test_rename_builder_labels.py with 10 cases covering both
passes, multi-source prefix-overlap regression, sparse env ids,
multi-frequency, multiple string columns at one frequency, and
empty-values pass-through.
Stacks on top of isaac-sim#5523 (Newton v1.2.0rc2 bump). The Newton 1.2
release also includes upstream newton-physics/newton#2659 which
scopes parse_usd's custom-frequency walk natively, removing the
cross-source MjcTendon contamination IsaacLab previously had to
work around at the framework layer.
After Newton's add_builder copies proto rows into the merged builder
for each environment, every row's label still references the source
proto path. Newton tracks env identity in *_world int companion
columns; IsaacLab keys data flow off USD prim paths, so each row's
label needs to be rewritten to its per-env destination path.
_rename_builder_labels now walks two kinds of label-bearing columns:
* Built-in label arrays (body, joint, shape, articulation,
constraint_mimic, equality_constraint), each paired with its
matching *_world int column.
* String-typed custom-attribute columns (e.g. mujoco:tendon_label)
paired with a references="world" companion at the same frequency.
Any future solver-registered string column at a frequency that has
a references="world" companion is handled automatically.
The prefix match uses a path-separator boundary
(src_path.rstrip("/") + "/") so a source path that is a string
prefix of another (/Sources/protoA vs /Sources/protoAB) does not
cross-contaminate when both feed the same envs.
The function raises ValueError if the parallel arrays of labels and
worlds have mismatched lengths, instead of silently truncating.
Adds test_rename_builder_labels.py with 10 cases covering both
passes, multi-source prefix-overlap regression, sparse env ids,
multi-frequency, multiple string columns at one frequency, and
empty-values pass-through.
Stacks on top of isaac-sim#5523 (Newton v1.2.0rc2 bump). The Newton 1.2
release also includes upstream newton-physics/newton#2659 which
scopes parse_usd's custom-frequency walk natively, removing the
cross-source MjcTendon contamination IsaacLab previously had to
work around at the framework layer.
## Summary Bumps the Newton pin to [`v1.2.0rc2`](https://pypi.org/project/newton/1.2.0rc2/), which pulls in IsaacLab-relevant fixes plus the upstream tendon-scoping fix. ## What's new in Newton v1.2.0rc2 vs IsaacLab's current pin (`a27277e`) The current IsaacLab Newton pin is from late April; v1.2.0rc2 is the latest release-candidate cut. Notable fixes pulled in: - **[newton-physics/newton#2659](newton-physics/newton#2659 \"Scope USD custom-frequency parsing\" — `parse_usd` now scopes the custom-frequency walk to `root_path` natively. - **[newton-physics/newton#2678](newton-physics/newton#2678 Regression fix. - **[newton-physics/newton#2720](newton-physics/newton#2720 `SolverKamino` reset under `world_mask`. - **[newton-physics/newton#2710](newton-physics/newton#2710 VRAM leak fix on example reset. - Plus 16 other smaller fixes between rc1 and rc2. ## Required dep bumps Newton 1.2.0rc2's \`pyproject.toml\` requires: - \`warp-lang==1.13.0\` - \`mujoco==3.8.0\` (was 3.6.0) - \`mujoco-warp==3.8.0.1\` (was 3.6.0) Pins updated in: | File | Change | |---|---| | \`source/isaaclab/setup.py\` | \`warp-lang==1.12.0\` → \`==1.13.0\`; \`mujoco==3.6.0\` → \`==3.8.0\`; \`mujoco-warp==3.6.0\` → \`==3.8.0.1\` | | \`source/isaaclab_newton/setup.py\` | mujoco / mujoco-warp bumps; Newton pin → \`v1.2.0rc2\` | | \`source/isaaclab_visualizers/setup.py\` | 3× Newton pin → \`v1.2.0rc2\` | | \`tools/wheel_builder/res/python_packages.toml\` | All four pins mirrored | ## Code adapts \`warp-lang\` 1.13 removed the \`wp.math\` namespace. Two IsaacLab call sites use it: - \`source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py:72\` - \`source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py:330\` Both rewritten as \`wp.math.transform_to_matrix(...)\` → \`wp.transform_to_matrix(...)\`. That's the only IsaacLab-side adapt needed. ## Test plan - [x] \`./isaaclab.sh -i newton\` clean install against the bumped pins. - [x] \`pip list\` confirms \`newton 1.2.0rc2\`, \`warp-lang 1.13.0\`, \`mujoco 3.8.0\`, \`mujoco-warp 3.8.0.1\`. - [x] Sanity smoke: Shadow-Hand-Over MAPPO (4 envs, 1 iter) runs clean — simulation init through CUDA graph capture through one training step + checkpoint save, no errors. - [x] Pre-commit clean. ## Caveat Smoke covered Shadow-Hand-Over MAPPO. Other envs with different sensors / renderers / collision setups could surface warp 1.13 or mujoco 3.8 differences the smoke didn't exercise; full PR CI catches them. --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
## Summary Bumps the Newton pin to [`v1.2.0rc2`](https://pypi.org/project/newton/1.2.0rc2/), which pulls in IsaacLab-relevant fixes plus the upstream tendon-scoping fix. ## What's new in Newton v1.2.0rc2 vs IsaacLab's current pin (`a27277e`) The current IsaacLab Newton pin is from late April; v1.2.0rc2 is the latest release-candidate cut. Notable fixes pulled in: - **[newton-physics/newton#2659](newton-physics/newton#2659 \"Scope USD custom-frequency parsing\" — `parse_usd` now scopes the custom-frequency walk to `root_path` natively. - **[newton-physics/newton#2678](newton-physics/newton#2678 Regression fix. - **[newton-physics/newton#2720](newton-physics/newton#2720 `SolverKamino` reset under `world_mask`. - **[newton-physics/newton#2710](newton-physics/newton#2710 VRAM leak fix on example reset. - Plus 16 other smaller fixes between rc1 and rc2. ## Required dep bumps Newton 1.2.0rc2's \`pyproject.toml\` requires: - \`warp-lang==1.13.0\` - \`mujoco==3.8.0\` (was 3.6.0) - \`mujoco-warp==3.8.0.1\` (was 3.6.0) Pins updated in: | File | Change | |---|---| | \`source/isaaclab/setup.py\` | \`warp-lang==1.12.0\` → \`==1.13.0\`; \`mujoco==3.6.0\` → \`==3.8.0\`; \`mujoco-warp==3.6.0\` → \`==3.8.0.1\` | | \`source/isaaclab_newton/setup.py\` | mujoco / mujoco-warp bumps; Newton pin → \`v1.2.0rc2\` | | \`source/isaaclab_visualizers/setup.py\` | 3× Newton pin → \`v1.2.0rc2\` | | \`tools/wheel_builder/res/python_packages.toml\` | All four pins mirrored | ## Code adapts \`warp-lang\` 1.13 removed the \`wp.math\` namespace. Two IsaacLab call sites use it: - \`source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py:72\` - \`source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py:330\` Both rewritten as \`wp.math.transform_to_matrix(...)\` → \`wp.transform_to_matrix(...)\`. That's the only IsaacLab-side adapt needed. ## Test plan - [x] \`./isaaclab.sh -i newton\` clean install against the bumped pins. - [x] \`pip list\` confirms \`newton 1.2.0rc2\`, \`warp-lang 1.13.0\`, \`mujoco 3.8.0\`, \`mujoco-warp 3.8.0.1\`. - [x] Sanity smoke: Shadow-Hand-Over MAPPO (4 envs, 1 iter) runs clean — simulation init through CUDA graph capture through one training step + checkpoint save, no errors. - [x] Pre-commit clean. ## Caveat Smoke covered Shadow-Hand-Over MAPPO. Other envs with different sensors / renderers / collision setups could surface warp 1.13 or mujoco 3.8 differences the smoke didn't exercise; full PR CI catches them. --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
After Newton's add_builder copies proto rows into the merged builder
for each environment, every row's label still references the source
proto path. Newton tracks env identity in *_world int companion
columns; IsaacLab keys data flow off USD prim paths, so each row's
label needs to be rewritten to its per-env destination path.
_rename_builder_labels now walks two kinds of label-bearing columns:
* Built-in label arrays (body, joint, shape, articulation,
constraint_mimic, equality_constraint), each paired with its
matching *_world int column.
* String-typed custom-attribute columns (e.g. mujoco:tendon_label)
paired with a references="world" companion at the same frequency.
Any future solver-registered string column at a frequency that has
a references="world" companion is handled automatically.
The prefix match uses a path-separator boundary
(src_path.rstrip("/") + "/") so a source path that is a string
prefix of another (/Sources/protoA vs /Sources/protoAB) does not
cross-contaminate when both feed the same envs.
The function raises ValueError if the parallel arrays of labels and
worlds have mismatched lengths, instead of silently truncating.
Adds test_rename_builder_labels.py with 10 cases covering both
passes, multi-source prefix-overlap regression, sparse env ids,
multi-frequency, multiple string columns at one frequency, and
empty-values pass-through.
Stacks on top of isaac-sim#5523 (Newton v1.2.0rc2 bump). The Newton 1.2
release also includes upstream newton-physics/newton#2659 which
scopes parse_usd's custom-frequency walk natively, removing the
cross-source MjcTendon contamination IsaacLab previously had to
work around at the framework layer.
After Newton's add_builder copies proto rows into the merged builder
for each environment, every row's label still references the source
proto path. Newton tracks env identity in *_world int companion
columns; IsaacLab keys data flow off USD prim paths, so each row's
label needs to be rewritten to its per-env destination path.
_rename_builder_labels now walks two kinds of label-bearing columns:
* Built-in label arrays (body, joint, shape, articulation,
constraint_mimic, equality_constraint), each paired with its
matching *_world int column.
* String-typed custom-attribute columns (e.g. mujoco:tendon_label)
paired with a references="world" companion at the same frequency.
Any future solver-registered string column at a frequency that has
a references="world" companion is handled automatically.
The prefix match uses a path-separator boundary
(src_path.rstrip("/") + "/") so a source path that is a string
prefix of another (/Sources/protoA vs /Sources/protoAB) does not
cross-contaminate when both feed the same envs.
The function raises ValueError if the parallel arrays of labels and
worlds have mismatched lengths, instead of silently truncating.
Adds test_rename_builder_labels.py with 10 cases covering both
passes, multi-source prefix-overlap regression, sparse env ids,
multi-frequency, multiple string columns at one frequency, and
empty-values pass-through.
Stacks on top of isaac-sim#5523 (Newton v1.2.0rc2 bump). The Newton 1.2
release also includes upstream newton-physics/newton#2659 which
scopes parse_usd's custom-frequency walk natively, removing the
cross-source MjcTendon contamination IsaacLab previously had to
work around at the framework layer.
…) (#5433) ## Summary Extends `_rename_builder_labels` in `isaaclab_newton.cloner.newton_replicate` so that every label-bearing column on the merged Newton `ModelBuilder` is rewritten to per-env USD paths after replication. Previously, only the built-in body/joint/shape/articulation columns were rewritten; tendon labels (and any other string-typed custom-attribute column) kept the source proto path on every replicated environment. ## Stack / dependencies - **Depends on #5523** (\"[Newton] Bump Newton pin to v1.2.0rc2\"). After #5523 lands, this PR rebases cleanly on develop. The Newton 1.2 release ([newton-physics/newton#2659](newton-physics/newton#2659)) also includes the upstream tendon-scoping fix that obsoletes the IsaacLab-side \`_scope_custom_frequencies\` workaround a previous version of this PR carried — that workaround has been removed in favor of relying on the Newton bump in #5523. ## Why the rename is needed Newton's \`add_builder\` copies each proto's bodies, joints, shapes, articulations, etc. into the merged builder verbatim, and tags each row with a \`*_world\` integer column to track env identity. Labels (path strings) are copied as-is. So after cloning N environments from one proto, the merged builder has N copies of every row, all with the **same proto-path string label**, distinguished only by the integer \`*_world\` column. IsaacLab keys most of its data flow off **USD prim paths** (sensor binding, event-term scope, visualization, logging). It needs labels to be unique per-env paths so a body called \`/World/envs/env_3/Robot/Forearm\` is reachable by path lookup. The rename function is the bridge: it walks every label-bearing column post-replication and rewrites the source-root prefix to the per-env destination root using each row's \`*_world\` value. Until this PR, the rename only walked **5 built-in label arrays**. Tendon labels and any string-typed custom-attribute column were missed, so e.g. \`mujoco:tendon_label\` showed \`/World/envs/env_0/...\` for every env — surfaced on Shadow Hand fixed tendons. ## What this PR changes ### \`_rename_builder_labels\` extension * **Pass 1 (built-in label arrays)** — extended from 5 to 6 entity types: \`body\`, \`joint\`, \`shape\`, \`articulation\`, \`constraint_mimic\`, **\`equality_constraint\`** (the latter was missing — would have surfaced for any env using \`MjcEquality\` constraints, currently none). * **Pass 2 (string custom-attribute columns)** — new. Walks every registered custom attribute, finds string-typed columns whose frequency has a \`references=\"world\"\` companion column, and applies the same prefix rewrite. Any future solver-registered string column at such a frequency is handled automatically without changes here. * **Path-separator boundary** on the prefix match: \`startswith(src_path.rstrip(\"/\") + \"/\")\`. Prevents source paths that are string prefixes of one another (\`/Sources/protoA\` vs \`/Sources/protoAB\`) from cross-contaminating when both feed the same envs. * **Hard error on length mismatch**: raises \`ValueError\` if the parallel \`(labels, worlds)\` arrays differ in length, instead of silently truncating. By contract Newton's \`add_builder\` keeps them in lockstep. ### Tests New \`source/isaaclab_newton/test/cloner/test_rename_builder_labels.py\` with 10 cases covering: - Both passes with built-ins and \`mujoco:tendon_label\` rewrite correctly per world. - Cross-pass consistency: every renamed label lives under the per-env root. - Guards: non-path strings pass through untouched; rows whose world id is not in \`env_ids\` keep their original label. - \`test_sparse_env_ids\` — non-contiguous env ids \`[10, 20, 30]\`. - \`TestRenamePass2Generality\` — multiple coexisting custom frequencies, multiple string columns at one frequency, registered-but-empty string column. - \`TestRenameMultiSource::test_prefix_overlap_does_not_cross_contaminate\` — explicit regression for the \`/Sources/protoA\` vs \`/Sources/protoAB\` boundary fix; both sources feed the same envs so the world-id guard cannot mask the boundary bug. Fails without the fix; passes with it. ## Test plan - [x] All 10 unit tests pass. - [x] \`./isaaclab.sh -f\` clean (pre-commit hooks). - [x] Verified the boundary-prefix regression test fails when the boundary terminator is removed and passes when it's restored. - [x] Smoke (Shadow-Hand-Over MAPPO 4 envs / iter 1) shows tendon labels go from \`/World/envs/env_0/.../T_FFJ\` (every env) to \`/World/envs/env_<wid>/.../T_FFJ\` (per-env paths) after the rename. --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
Description
Scope USD custom-frequency parsing to the
root_pathpassed toModelBuilder.add_usd().The standard USD import walks already use a subtree-bounded
Usd.PrimRange; the custom-frequency walk was the outlier and traversed the whole stage. In cloned or multi-builder imports, that let siblingMjcTendon/ custom-frequency prims emit rows for builders that did not import those subtrees.This keeps
Usd.TraverseInstanceProxies()behavior while using the same root-bounded traversal shape as the rest ofparse_usd.Checklist
CHANGELOG.mdhas been updated (if user-facing change)Test plan
Bug fix
Steps to reproduce:
/World/RobotAand/World/RobotB.usd_prim_filterthat matches those prims.builder.add_usd(stage, root_path="/World/RobotA")./World/RobotB.Minimal reproduction:
The modified tests exercise this with both a generic custom-frequency row count and MuJoCo fixed-tendon rows:
Summary by CodeRabbit
Bug Fixes
Documentation