Skip to content

Commit bc3ebea

Browse files
authored
[Bump] Bump Newton to 1.6.0rc1 for newton#4017 (#7445)
## Summary - Bumps Newton from `1.5.1` to `1.6.0rc1`, the first release carrying [newton#4017](newton-physics/newton#4017), unblocking the MuJoCo tendon adapter that PR #7161 needs. - `warp-lang` and `mujoco`/`mujoco-warp` move with it, because `1.6.0rc1` requires them. - Pins `newton[sim]` in `[project].dependencies` as well, so a wheel built from this metadata resolves the fix rather than falling back to the newest stable. - Updates test literals in `isaaclab` and `isaaclab_newton` for Newton's new actuator class names, and asks for a determinism guarantee in the manipulation determinism test. # Description `resolve_fixed_tendon_actuator_columns` reads `mujoco.actuator_trntype` through an `ArticulationView`. Every Newton 1.5.x release rejects that with *"has custom frequency 'mujoco:actuator' which is not supported by ArticulationView"*; newton#4017 makes `ArticulationView` generic over custom frequencies. `1.6.0rc1` (published 2026-09-03) is the first release containing that fix — verified two ways: the merge commit `4055a159` is an ancestor of `v1.6.0rc1`, and `custom_frequency_label_attributes`, the symbol the fix introduces in `newton/_src/sim/model.py`, is present at `v1.6.0rc1` and absent at `v1.5.1`. No `1.6.0` final exists yet, and no 1.5.x backport carries the fix, so `1.6.0rc1` is the only released option. The release requires `warp-lang>=1.17.0` and `mujoco-warp~=3.12.0`, so those pins move too: | Package | Before | After | | --- | --- | --- | | `newton[sim]` | `1.5.1` | `1.6.0rc1` | | `warp-lang` | `1.16.0` | `1.17.0` | | `mujoco` | `3.11.0` | `3.12.0` | | `mujoco-warp` | `3.11.0` | `3.12.0` | `warp-lang` is pinned to the `1.17.0` release rather than left as `>=1.17.0`: Newton's prerelease enables prerelease resolution, and an unbounded bound then resolves to a nightly (`1.18.0.dev20260903`). ## Wheel installs get the pin too `[tool.uv].override-dependencies` only reaches `uv sync`, so it does not constrain a wheel built from this metadata. `1.6.0rc1` is a prerelease, which a default resolve skips, so a loose bound resolved `newton 1.5.1` — without newton#4017, the fix this bump exists to deliver. Since `wheel.yml` builds on every push to `develop`, that would have shipped. `[project].dependencies` now pins `newton[sim]==1.6.0rc1`, matching the override. A default resolve of the new metadata returns `1.6.0rc1` under both `uv pip compile` and `pip download`, with no `--pre` flag. `isaacsim-core==6.0.1.0` requires `newton[sim]==1.2.1`, so installing the `isaacsim` extra still needs an override — exactly as on `develop`, which carries an equally exact pin in the same place. ## Newton actuator class rename `1.6.0rc1` introduces `DrivePD` / `DriveNeuralMLP` / `DriveNeuralLSTM` alongside the existing `ControllerPD` / `ControllerNeural*`. Both names remain importable, so this is **not** a breaking API change and no production code changes. Tests in `isaaclab` and `isaaclab_newton` assert on the class name Newton *constructs with*, which switched to the `Drive*` form, so those literals are updated. ## Determinism `test_manipulation_env_determinism[cuda-Isaac-Open-Drawer-Franka]` failed on this branch in CI. Two separate questions: whether the bump caused it, and why it failed at all. **Not caused by the bump.** Each arm was run 5x on the same machine, because a single run of an intermittent test samples a coin rather than measuring it: | GPU | develop pins (`newton 1.5.1` / `warp 1.16.0` / `mujoco 3.11.0`) | this PR (`newton 1.6.0rc1` / `warp 1.17.0` / `mujoco 3.12.0`) | | --- | --- | --- | | RTX PRO 6000 Blackwell | 3 / 5 failed | 3 / 5 failed | | L40 | 3 / 3 passed | 4 / 4 passed | Both pin sets fail at the same rate on Blackwell and both are clean on L40, so the failure is hardware-dependent, not version-dependent. Intermediate Newton revisions (the commits before and at [newton#4119](newton-physics/newton#4119), the MuJoCo 3.12 bump) show the same behaviour, so neither Warp 1.17, MuJoCo 3.12, nor #4119 is implicated. **Why it failed.** The test asserted bit-reproducible rewards without ever asking for a determinism guarantee. Newton defaults to `wp.DeterministicMode.NOT_GUARANTEED`, under which Warp's atomics may accumulate in any order, so two runs of the same environment are not required to agree — the assertion was stricter than the configuration it ran under, and whether it held came down to GPU scheduling. The Newton-backed case now passes `deterministic_mode="run_to_run"`, which is exactly the guarantee this test asserts: one device, one process, run twice. `deterministic_mode` is a Newton setting, so the PhysX-backed `IsaacContrib-Lift-Cube-Franka` case leaves it unset and the helper keeps asserting that the mode is only applied to a `NewtonCfg` backend. This is a test-configuration fix, not a masking of the intermittency: the guarantee the assertion depends on is now actually requested. Related: [#7561](#7561) addresses the adjacent layer and does not overlap this PR. Newton's solvers take a per-module `deterministic` argument, which is what `deterministic_mode` reaches and what this PR sets; Newton's sensor and geometry kernels take no such argument and fall back to the `warp.config.deterministic` global, which #7561 raises from the same config field in the RL entrypoint. ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Release backport - [ ] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Validation - `uv lock --check` — clean; the relock moves exactly the four packages above, and the `[project].dependencies` pin moves exactly one further lockfile line - Default resolve of the published metadata returns `newton==1.6.0rc1` under both `uv pip compile` and `pip download`, with no `--pre` flag - `uv run --frozen python -m pytest source/isaaclab/test/cli/test_wheel_builder_metadata.py source/isaaclab/test/cli/test_uv_run_pyproject.py` — 21 passed, which enforces that the two generated `uv-overrides.txt` files match the override table and that `[tool.isaaclab.versions]` mirrors the dependency pins - `uv run isaaclab -f` — passed - Full Docker + Tests suite — **48 passed / 0 failed** on `b184335e80b`
1 parent 493ee92 commit bc3ebea

11 files changed

Lines changed: 86 additions & 55 deletions

File tree

pyproject.toml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ dependencies = [
5151
"pyglet>=2.1.6,<3",
5252
"transformers==4.57.6",
5353
"einops",
54-
"warp-lang==1.16.0",
54+
"warp-lang==1.17.0",
5555
"matplotlib>=3.10.3",
5656
# pillow: floor, not exact — an exact pin below Isaac Sim's prebundled version forces a
5757
# downgrade that deletes the prebundled copy other extensions symlink into (nvbugs 6410989).
@@ -87,8 +87,11 @@ dependencies = [
8787
"rsl-rl-lib==5.4.1", # default RL framework
8888
"onnxscript>=0.5",
8989
# ----- newton (default physics engine) -----
90-
# Pin the Newton build used by both workspace and wheel installs until the 1.6 release.
91-
"newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962",
90+
# Pin the Newton release used by both workspace and wheel installs until 1.6.0 final.
91+
# [tool.uv].override-dependencies only reaches uv sync, so a wheel built from this
92+
# metadata would otherwise resolve the newest stable (1.5.1) and miss newton#4017:
93+
# 1.6.0rc1 is a prerelease, which a default resolve skips.
94+
"newton[sim]==1.6.0rc1",
9295
# Import and mesh-processing packages used by Newton, including the ones that honoring
9396
# USD-authored ``physics:approximation`` requires. Keep these explicit instead of selecting
9497
# newton[importers], whose standalone USD dependency would overlap with usd-exchange.
@@ -222,7 +225,7 @@ torchaudio = "2.11.0"
222225
ovphysx = "0.5.11"
223226
ovrtx = "0.4.1.364340"
224227
ovstage = "0.1.1.355824"
225-
warp = "1.16.0"
228+
warp = "1.17.0"
226229

227230
[tool.ruff]
228231
line-length = 120
@@ -402,9 +405,9 @@ environments = [
402405
# Torch routes through [tool.uv.sources]. Values mirror [tool.isaaclab.versions] where applicable.
403406
override-dependencies = [
404407
"numpy>=2",
405-
"mujoco~=3.11.0",
406-
"mujoco-warp~=3.11.0",
407-
"newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962",
408+
"mujoco~=3.12.0",
409+
"mujoco-warp~=3.12.0",
410+
"newton[sim]==1.6.0rc1",
408411
# Force the Newton-matched schemas over isaacsim's ==0.2.0 pin.
409412
"newton-usd-schemas>=0.4.1",
410413
"torch==2.11.0",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Changed
2+
^^^^^^^
3+
4+
* Changed the pinned Newton version from ``1.5.1`` to ``1.6.0rc1``, the first release carrying
5+
`newton#4017 <https://github.com/newton-physics/newton/pull/4017>`_, which makes
6+
``ArticulationView`` generic over custom frequencies. Reading a MuJoCo actuator attribute such
7+
as ``mujoco.actuator_trntype`` through an articulation view previously raised *"has custom
8+
frequency 'mujoco:actuator' which is not supported by ArticulationView"*.
9+
* Changed ``warp-lang`` from ``1.16.0`` to ``1.17.0`` and ``mujoco``/``mujoco-warp`` from
10+
``3.11.0`` to ``3.12.0``, which Newton ``1.6.0rc1`` requires.

source/isaaclab/test/actuators/test_newton_adapter.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import numpy as np
99
import pytest
10-
from newton.actuators import ClampingDCMotor, ClampingMaxEffort, ClampingPositionBased, ControllerPD
10+
from newton.actuators import ClampingDCMotor, ClampingMaxEffort, ClampingPositionBased, DrivePD
1111

1212
from pxr import Usd, UsdGeom, UsdPhysics
1313

@@ -110,7 +110,7 @@ def test_from_usd_groups_by_structure_and_preserves_per_dof_values():
110110
assert len(actuators) == 4
111111

112112
pd = next(actuator for actuator in actuators if [type(c) for c in actuator.clamping] == [ClampingMaxEffort])
113-
assert type(pd.controller) is ControllerPD
113+
assert type(pd.controller) is DrivePD
114114
np.testing.assert_array_equal(pd.indices.numpy(), [0, 1, 6, 7])
115115
np.testing.assert_allclose(pd.controller.kp.numpy(), [11.0, 22.0, 11.0, 22.0])
116116
np.testing.assert_allclose(pd.controller.kd.numpy(), [1.5, 2.5, 1.5, 2.5])
@@ -119,7 +119,7 @@ def test_from_usd_groups_by_structure_and_preserves_per_dof_values():
119119
assert pd.delay.buf_depth == 4
120120

121121
dc = next(actuator for actuator in actuators if [type(c) for c in actuator.clamping] == [ClampingDCMotor])
122-
assert type(dc.controller) is ControllerPD
122+
assert type(dc.controller) is DrivePD
123123
assert dc.delay is None
124124
np.testing.assert_array_equal(dc.indices.numpy(), [2, 3, 8, 9])
125125
np.testing.assert_allclose(dc.controller.kp.numpy(), [33.0, 44.0, 33.0, 44.0])

source/isaaclab/test/install_ci/uv_pip/test_uv_pip_install_isaaclab_all_trains_cartpole.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
Reinstall AFTER the wheel install: unsafe-best-match re-resolves torch from PyPI to CPU.)
1616
- (aarch64 only) export LD_PRELOAD=/lib/aarch64-linux-gnu/libgomp.so.1
1717
Tests:
18-
- python -c "import importlib.metadata as m; assert m.version('newton') == '1.6.0.dev0'"
19-
-> verify the wheel resolves the pinned Newton 1.6 development build
18+
- python -c "import importlib.metadata as m; assert m.version('newton') == '1.6.0rc1'"
19+
-> verify the wheel resolves the pinned Newton release
2020
- uv run isaaclab train --rl_library rsl_rl --task Isaac-Cartpole-Direct --num_envs 16
2121
presets=newton_mjwarp --max_iterations 5; uv run isaaclab train --rl_library rsl_rl
2222
--task Isaac-Cartpole-Camera-Direct --num_envs 16 presets=newton_mjwarp,newton_renderer --max_iterations 2
@@ -57,7 +57,7 @@ def test_uv_pip_install_isaaclab_all_trains_cartpole(self, isaaclab_root, wheel,
5757
assert result.returncode == 0, f"uv pip install {wheel}[all] failed:\n{result.stdout}\n{result.stderr}"
5858

5959
result = self.run_in_uv_env(
60-
["python", "-c", "import importlib.metadata as m; assert m.version('newton') == '1.6.0.dev0'"],
60+
["python", "-c", "import importlib.metadata as m; assert m.version('newton') == '1.6.0rc1'"],
6161
cwd=isaaclab_root,
6262
)
6363
assert result.returncode == 0, (

source/isaaclab/test/install_ci/uv_pip/uv-overrides.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
numpy>=2
2-
mujoco~=3.11.0
3-
mujoco-warp~=3.11.0
4-
newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962
2+
mujoco~=3.12.0
3+
mujoco-warp~=3.12.0
4+
newton[sim]==1.6.0rc1
55
newton-usd-schemas>=0.4.1
66
torch==2.11.0
77
torchvision==0.26.0
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Test-only change: the actuator tests now assert Newton's new drive class names
2+
(``DrivePD``, ``DriveNeuralMLP``, ``DriveNeuralLSTM``). Newton 1.6.0rc1 still exports the
3+
old ``Controller*`` aliases, so there is no user-visible behavior change.

source/isaaclab_newton/test/assets/test_newton_actuators_newton.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ def test_has_delay(self):
598598

599599
def test_controller_is_pd(self):
600600
for a in self.result["actuator_info"]:
601-
self.assertEqual(a["controller_type"], "ControllerPD")
601+
self.assertEqual(a["controller_type"], "DrivePD")
602602

603603

604604
# ---------------------------------------------------------------------------
@@ -772,7 +772,7 @@ def test_kfe_controller_is_pd(self):
772772
kfe_acts = [a for a in self.result["actuator_info"] if "ClampingPositionBased" in a["clamping_types"]]
773773
self.assertTrue(len(kfe_acts) > 0, "No actuator with position-based clamping found")
774774
for a in kfe_acts:
775-
self.assertEqual(a["controller_type"], "ControllerPD")
775+
self.assertEqual(a["controller_type"], "DrivePD")
776776

777777
def test_kfe_has_position_based_clamping(self):
778778
kfe_acts = [a for a in self.result["actuator_info"] if "ClampingPositionBased" in a["clamping_types"]]
@@ -845,11 +845,11 @@ def test_num_actuators(self):
845845
self.assertGreaterEqual(self.result["num_actuators"], 2)
846846

847847
def test_has_neural_mlp_controller(self):
848-
mlp_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "ControllerNeuralMLP"]
848+
mlp_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "DriveNeuralMLP"]
849849
self.assertTrue(len(mlp_acts) > 0, "No NeuralMLP controller found")
850850

851851
def test_mlp_has_dc_motor_clamping(self):
852-
mlp_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "ControllerNeuralMLP"]
852+
mlp_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "DriveNeuralMLP"]
853853
for a in mlp_acts:
854854
self.assertIn("ClampingDCMotor", a["clamping_types"])
855855

@@ -890,11 +890,11 @@ def test_num_actuators(self):
890890
self.assertGreaterEqual(self.result["num_actuators"], 2)
891891

892892
def test_has_neural_lstm_controller(self):
893-
lstm_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "ControllerNeuralLSTM"]
893+
lstm_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "DriveNeuralLSTM"]
894894
self.assertTrue(len(lstm_acts) > 0, "No NeuralLSTM controller found")
895895

896896
def test_lstm_has_dc_motor_clamping(self):
897-
lstm_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "ControllerNeuralLSTM"]
897+
lstm_acts = [a for a in self.result["actuator_info"] if a["controller_type"] == "DriveNeuralLSTM"]
898898
for a in lstm_acts:
899899
self.assertIn("ClampingDCMotor", a["clamping_types"])
900900

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Fixed
2+
^^^^^
3+
4+
* Fixed ``test_manipulation_env_determinism`` asserting bit-reproducible rewards without requesting
5+
a determinism guarantee. Newton defaults to ``wp.DeterministicMode.NOT_GUARANTEED``, under which
6+
Warp's atomics may accumulate in any order, so the test failed intermittently depending on GPU
7+
scheduling. It now passes ``deterministic_mode="run_to_run"``, as the Newton cartpole cases
8+
already did.

source/isaaclab_tasks/test/core/test_environment_determinism.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,20 @@ def setup_environment():
3636

3737

3838
@pytest.mark.parametrize(
39-
"task_name",
39+
("task_name", "deterministic_mode"),
4040
[
41-
"Isaac-Open-Drawer-Franka",
42-
"IsaacContrib-Lift-Cube-Franka",
41+
# Newton defaults to ``wp.DeterministicMode.NOT_GUARANTEED``, under which Warp's atomics may
42+
# accumulate in any order, so two runs are not bit-reproducible. ``run_to_run`` is exactly
43+
# the guarantee this test asserts: one device, one process, run twice. ``deterministic_mode``
44+
# is a Newton setting, so the PhysX-backed task leaves it unset.
45+
("Isaac-Open-Drawer-Franka", "run_to_run"),
46+
("IsaacContrib-Lift-Cube-Franka", None),
4347
],
4448
)
4549
@pytest.mark.parametrize("device", ["cuda", "cpu"])
46-
def test_manipulation_env_determinism(task_name, device):
50+
def test_manipulation_env_determinism(task_name, deterministic_mode, device):
4751
"""Check deterministic environment creation for manipulation."""
48-
_test_environment_determinism(task_name, device)
52+
_test_environment_determinism(task_name, device, deterministic_mode=deterministic_mode)
4953

5054

5155
@pytest.mark.parametrize(

tools/wheel_builder/uv-overrides.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
numpy>=2
2-
mujoco~=3.11.0
3-
mujoco-warp~=3.11.0
4-
newton[sim] @ git+https://github.com/newton-physics/newton.git@24bd863528d6b91137408930d0fbe8fa216ad962
2+
mujoco~=3.12.0
3+
mujoco-warp~=3.12.0
4+
newton[sim]==1.6.0rc1
55
newton-usd-schemas>=0.4.1
66
torch==2.11.0
77
torchvision==0.26.0

0 commit comments

Comments
 (0)