Skip to content

Commit fce4ebd

Browse files
committed
Bump Newton pin to v1.2.0rc1 and rename per-env labels in replication
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.
1 parent c0ae5ee commit fce4ebd

8 files changed

Lines changed: 368 additions & 21 deletions

File tree

source/isaaclab/setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030
# procedural-generation
3131
"trimesh",
3232
"pyglet>=2.1.6,<3",
33-
"mujoco==3.6.0",
34-
"mujoco-warp==3.6.0",
33+
"mujoco==3.8.0",
34+
"mujoco-warp==3.8.0.1",
3535
# image processing
3636
"transformers==4.57.6",
3737
"einops", # needed for transformers, doesn't always auto-install
38-
"warp-lang==1.12.0",
38+
"warp-lang>=1.13.0",
3939
"matplotlib>=3.10.3", # minimum version for Python 3.12 support
4040
# make sure this is consistent with isaac sim version
4141
"pillow==12.1.1",
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Changed
2+
^^^^^^^
3+
4+
* Bumped Newton pin to ``v1.2.0rc1``, which requires ``warp-lang>=1.13.0``,
5+
``mujoco==3.8.0``, and ``mujoco-warp==3.8.0.1``. Pins updated in
6+
:mod:`isaaclab`, :mod:`isaaclab_newton`, and :mod:`isaaclab_visualizers`
7+
setup. The Newton 1.2 release scopes ``parse_usd``'s custom-frequency
8+
walk to ``root_path`` natively (`newton-physics/newton#2659
9+
<https://github.com/newton-physics/newton/pull/2659>`_), removing the
10+
cross-source ``MjcTendon`` contamination IsaacLab previously had to work
11+
around at the framework layer.
12+
* Updated ``wp.math.transform_to_matrix`` to ``wp.transform_to_matrix`` in
13+
:mod:`~isaaclab_newton.physics.newton_manager` and
14+
:mod:`~isaaclab_ov.renderers.ovrtx_renderer_kernels` to match the
15+
``warp-lang`` 1.13 API (the ``wp.math`` namespace was removed).
16+
17+
Fixed
18+
^^^^^
19+
20+
* Fixed per-environment string identifiers (e.g. ``mujoco:tendon_label``)
21+
keeping the source proto path after replication.
22+
:func:`~isaaclab_newton.cloner.newton_replicate._rename_builder_labels`
23+
now also walks string-typed custom-attribute columns whose frequency
24+
declares a ``references="world"`` companion, rewriting their per-row
25+
source-path prefix to the destination world root in the same pass that
26+
handles built-in label arrays. Adds ``constraint_mimic`` to that
27+
built-in pass for completeness. The prefix match uses a
28+
path-separator boundary so a source path that is a string prefix of
29+
another (e.g. ``/Sources/protoA`` vs ``/Sources/protoAB``) does not
30+
cross-contaminate during the rename.

source/isaaclab_newton/isaaclab_newton/cloner/newton_replicate.py

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ def _rename_builder_labels(
121121
) -> None:
122122
"""Rename builder labels/keys from source roots to destination roots.
123123
124+
Walks both built-in label arrays (``body``, ``joint``, ``shape``,
125+
``articulation``, ``constraint_mimic``) and any string-typed custom-attribute
126+
column whose frequency declares a sibling world column (``references="world"``).
127+
The ``startswith(src_prefix)`` guard makes the rewrite a no-op for strings that
128+
are not paths under the source, so non-path custom string columns are passed
129+
through untouched and any future solver-registered string column is handled
130+
automatically without changes here.
131+
124132
Args:
125133
builder: Newton model builder to update in-place.
126134
sources: Source prim root paths.
@@ -130,21 +138,51 @@ def _rename_builder_labels(
130138
"""
131139
# per-source, per-world renaming (strict prefix swap), compact style preserved
132140
for i, src_path in enumerate(sources):
133-
src_prefix_len = len(src_path.rstrip("/"))
141+
# Boundary-terminated prefix prevents over-matching when one source path is a
142+
# prefix of another (e.g. ``/Sources/protoA`` vs ``/Sources/protoAB``).
143+
src_prefix = src_path.rstrip("/") + "/"
144+
src_prefix_len = len(src_prefix) - 1 # slice index keeps the leading "/" in the suffix
134145
swap = lambda name, new_root: new_root + name[src_prefix_len:] # noqa: E731
135146
world_cols = torch.nonzero(mapping[i], as_tuple=True)[0].tolist()
136147
# Map Newton world IDs (sequential) to destination paths using env_ids
137148
world_roots = {int(env_ids[c]): destinations[i].format(int(env_ids[c])) for c in world_cols}
138149

139-
for t in ("body", "joint", "shape", "articulation"):
140-
labels = getattr(builder, f"{t}_label", None)
141-
if labels is None:
142-
labels = getattr(builder, f"{t}_key")
143-
worlds_arr = getattr(builder, f"{t}_world")
144-
for k, w in enumerate(worlds_arr):
145-
world_id = int(w)
146-
if world_id in world_roots and labels[k].startswith(src_path):
147-
labels[k] = swap(labels[k], world_roots[world_id])
150+
def _rename_pair(values, worlds):
151+
# ``values`` and ``worlds`` are required to be the same length by the call
152+
# sites; ``min`` is defensive against a future builder oddity.
153+
n = min(len(values), len(worlds))
154+
for k in range(n):
155+
world_id = int(worlds[k])
156+
if world_id in world_roots and isinstance(values[k], str) and values[k].startswith(src_prefix):
157+
values[k] = swap(values[k], world_roots[world_id])
158+
159+
# Pass 1: built-in label arrays. Each has a paired ``*_world`` int column.
160+
for t in ("body", "joint", "shape", "articulation", "constraint_mimic"):
161+
labels = getattr(builder, f"{t}_label", None) or getattr(builder, f"{t}_key", None)
162+
worlds_arr = getattr(builder, f"{t}_world", None)
163+
if labels is None or worlds_arr is None:
164+
continue
165+
_rename_pair(labels, worlds_arr)
166+
167+
# Pass 2: string-typed custom-attribute columns (e.g. ``mujoco:tendon_label``)
168+
# paired with a world companion declared via ``references="world"``. Index
169+
# world companions by frequency for O(1) lookup, then walk the str columns.
170+
custom = builder.custom_attributes
171+
world_by_freq: dict[str, ModelBuilder.CustomAttribute] = {}
172+
for attr in custom.values():
173+
if getattr(attr, "references", None) == "world":
174+
world_by_freq[attr.frequency] = attr
175+
for attr in custom.values():
176+
if attr.dtype is not str:
177+
continue
178+
world_attr = world_by_freq.get(attr.frequency)
179+
if world_attr is None:
180+
continue
181+
values = attr.values
182+
worlds = world_attr.values
183+
if not values or not worlds:
184+
continue
185+
_rename_pair(values, worlds)
148186

149187

150188
def newton_physics_replicate(

source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def _set_fabric_transforms(
6969
i = int(wp.tid())
7070
idx = int(newton_indices[i])
7171
transform = newton_body_q[idx]
72-
fabric_transforms[i] = wp.transpose(wp.mat44d(wp.math.transform_to_matrix(transform)))
72+
fabric_transforms[i] = wp.transpose(wp.mat44d(wp.transform_to_matrix(transform)))
7373

7474

7575
@wp.kernel(enable_backward=False)

source/isaaclab_newton/setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ def run(self):
3838
EXTRAS_REQUIRE = {
3939
"all": [
4040
"prettytable==3.3.0",
41-
"mujoco==3.6.0",
42-
"mujoco-warp==3.6.0",
41+
"mujoco==3.8.0",
42+
"mujoco-warp==3.8.0.1",
4343
"PyOpenGL-accelerate==3.1.10",
44-
"newton @ git+https://github.com/newton-physics/newton.git@a27277ed49d6f307b8a1e4c394be7e1d14965a62",
44+
"newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc1",
4545
],
4646
}
4747

0 commit comments

Comments
 (0)