Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions source/isaaclab/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
# procedural-generation
"trimesh",
"pyglet>=2.1.6,<3",
"mujoco==3.6.0",
"mujoco-warp==3.6.0",
"mujoco==3.8.0",
"mujoco-warp==3.8.0.1",
# image processing
"transformers==4.57.6",
"einops", # needed for transformers, doesn't always auto-install
"warp-lang==1.12.0",
"warp-lang>=1.13.0",
"matplotlib>=3.10.3", # minimum version for Python 3.12 support
# make sure this is consistent with isaac sim version
"pillow==12.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Changed
^^^^^^^

* Bumped Newton pin to ``v1.2.0rc1``, which requires ``warp-lang>=1.13.0``,
``mujoco==3.8.0``, and ``mujoco-warp==3.8.0.1``. Pins updated in
:mod:`isaaclab`, :mod:`isaaclab_newton`, and :mod:`isaaclab_visualizers`
setup. The Newton 1.2 release scopes ``parse_usd``'s custom-frequency
walk to ``root_path`` natively (`newton-physics/newton#2659
<https://github.com/newton-physics/newton/pull/2659>`_), removing the
cross-source ``MjcTendon`` contamination IsaacLab previously had to work
around at the framework layer.
* Updated ``wp.math.transform_to_matrix`` to ``wp.transform_to_matrix`` in
:mod:`~isaaclab_newton.physics.newton_manager` and
:mod:`~isaaclab_ov.renderers.ovrtx_renderer_kernels` to match the
``warp-lang`` 1.13 API (the ``wp.math`` namespace was removed).

Fixed
^^^^^

* Fixed per-environment string identifiers (e.g. ``mujoco:tendon_label``)
keeping the source proto path after replication.
:func:`~isaaclab_newton.cloner.newton_replicate._rename_builder_labels`
now also walks string-typed custom-attribute columns whose frequency
declares a ``references="world"`` companion, rewriting their per-row
source-path prefix to the destination world root in the same pass that
handles built-in label arrays. Adds ``constraint_mimic`` to that
built-in pass for completeness. The prefix match uses a
path-separator boundary so a source path that is a string prefix of
another (e.g. ``/Sources/protoA`` vs ``/Sources/protoAB``) does not
cross-contaminate during the rename.
58 changes: 48 additions & 10 deletions source/isaaclab_newton/isaaclab_newton/cloner/newton_replicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ def _rename_builder_labels(
) -> None:
"""Rename builder labels/keys from source roots to destination roots.

Walks both built-in label arrays (``body``, ``joint``, ``shape``,
``articulation``, ``constraint_mimic``) and any string-typed custom-attribute
column whose frequency declares a sibling world column (``references="world"``).
The ``startswith(src_prefix)`` guard makes the rewrite a no-op for strings that
are not paths under the source, so non-path custom string columns are passed
through untouched and any future solver-registered string column is handled
automatically without changes here.

Args:
builder: Newton model builder to update in-place.
sources: Source prim root paths.
Expand All @@ -130,21 +138,51 @@ def _rename_builder_labels(
"""
# per-source, per-world renaming (strict prefix swap), compact style preserved
for i, src_path in enumerate(sources):
src_prefix_len = len(src_path.rstrip("/"))
# Boundary-terminated prefix prevents over-matching when one source path is a
# prefix of another (e.g. ``/Sources/protoA`` vs ``/Sources/protoAB``).
src_prefix = src_path.rstrip("/") + "/"
src_prefix_len = len(src_prefix) - 1 # slice index keeps the leading "/" in the suffix
swap = lambda name, new_root: new_root + name[src_prefix_len:] # noqa: E731
world_cols = torch.nonzero(mapping[i], as_tuple=True)[0].tolist()
# Map Newton world IDs (sequential) to destination paths using env_ids
world_roots = {int(env_ids[c]): destinations[i].format(int(env_ids[c])) for c in world_cols}

for t in ("body", "joint", "shape", "articulation"):
labels = getattr(builder, f"{t}_label", None)
if labels is None:
labels = getattr(builder, f"{t}_key")
worlds_arr = getattr(builder, f"{t}_world")
for k, w in enumerate(worlds_arr):
world_id = int(w)
if world_id in world_roots and labels[k].startswith(src_path):
labels[k] = swap(labels[k], world_roots[world_id])
def _rename_pair(values, worlds):
# ``values`` and ``worlds`` are required to be the same length by the call
# sites; ``min`` is defensive against a future builder oddity.
n = min(len(values), len(worlds))
for k in range(n):
world_id = int(worlds[k])
if world_id in world_roots and isinstance(values[k], str) and values[k].startswith(src_prefix):
values[k] = swap(values[k], world_roots[world_id])

# Pass 1: built-in label arrays. Each has a paired ``*_world`` int column.
for t in ("body", "joint", "shape", "articulation", "constraint_mimic"):
labels = getattr(builder, f"{t}_label", None) or getattr(builder, f"{t}_key", None)
worlds_arr = getattr(builder, f"{t}_world", None)
if labels is None or worlds_arr is None:
continue
_rename_pair(labels, worlds_arr)

# Pass 2: string-typed custom-attribute columns (e.g. ``mujoco:tendon_label``)
# paired with a world companion declared via ``references="world"``. Index
# world companions by frequency for O(1) lookup, then walk the str columns.
custom = builder.custom_attributes
world_by_freq: dict[str, ModelBuilder.CustomAttribute] = {}
for attr in custom.values():
if getattr(attr, "references", None) == "world":
world_by_freq[attr.frequency] = attr
for attr in custom.values():
if attr.dtype is not str:
continue
world_attr = world_by_freq.get(attr.frequency)
if world_attr is None:
continue
values = attr.values
worlds = world_attr.values
if not values or not worlds:
continue
_rename_pair(values, worlds)


def newton_physics_replicate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _set_fabric_transforms(
i = int(wp.tid())
idx = int(newton_indices[i])
transform = newton_body_q[idx]
fabric_transforms[i] = wp.transpose(wp.mat44d(wp.math.transform_to_matrix(transform)))
fabric_transforms[i] = wp.transpose(wp.mat44d(wp.transform_to_matrix(transform)))


@wp.kernel(enable_backward=False)
Expand Down
6 changes: 3 additions & 3 deletions source/isaaclab_newton/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ def run(self):
EXTRAS_REQUIRE = {
"all": [
"prettytable==3.3.0",
"mujoco==3.6.0",
"mujoco-warp==3.6.0",
"mujoco==3.8.0",
"mujoco-warp==3.8.0.1",
"PyOpenGL-accelerate==3.1.10",
"newton @ git+https://github.com/newton-physics/newton.git@a27277ed49d6f307b8a1e4c394be7e1d14965a62",
"newton @ git+https://github.com/newton-physics/newton.git@v1.2.0rc1",
],
}

Expand Down
Loading
Loading