[OVPHYSX] Articulation rewrite (data class + asset class + kernels)#10
Draft
AntoineRichard wants to merge 53 commits into
Draft
[OVPHYSX] Articulation rewrite (data class + asset class + kernels)#10AntoineRichard wants to merge 53 commits into
AntoineRichard wants to merge 53 commits into
Conversation
394ade8 to
f72c5f4
Compare
2b8cc8d to
26a442b
Compare
da3653e to
e3a782e
Compare
Add Articulation and ArticulationData for the OVPhysX backend, mirroring the PhysX/Newton public API. Resolves PR isaac-sim#5459. Articulation ^^^^^^^^^^^^ * index/mask split for every state writer, simulation-parameter writer, setter, and tendon setter; OVPhysX exposes both _index and _mask as first-class paths and intentionally drops the PhysX-specific ``full_data`` kwarg. * Dedicated dynamic + viscous friction setters (write_joint_{dynamic,viscous}_friction_coefficient_to_sim_{index,mask}) that touch only their slot of the combined (N, J, 3) DOF_FRICTION_PROPERTIES buffer. The combined write_joint_friction_coefficient_to_sim_index/_mask still accepts all three components as kwargs (Coulomb static + dynamic + optional viscous) for source-compatible PhysX call sites. * Deprecated non-indexed shorthand shims for friction (x3) and root / joint state (x4), forwarding to the index variants with a DeprecationWarning, matching PhysX's deprecated section. * Wrench-composer return types tightened to non-None (instantaneous_wrench_composer / permanent_wrench_composer); composers are always set in _create_buffers, mirroring PhysX/Newton. * Section organisation matches PhysX exactly: Properties -> Operations -> Operations - Finders -> Operations - State Writers -> Operations - Simulation Parameters Writers -> Operations - Setters -> Operations - Tendons -> Internal helper -> Internal simulation callbacks -> Internal helpers -- Actuators -> Internal helpers -- Debugging -> Deprecated methods. Section delimiters use bare """Section.""" docstring blocks (Newton/PhysX convention). ArticulationData ^^^^^^^^^^^^^^^^ * Pull-on-demand timestamped buffers; CPU-only bindings route through pinned-host staging (PR isaac-sim#5329 pattern). * Property names match PhysX exactly: joint_friction_coeff, joint_dynamic_friction_coeff, joint_viscous_friction_coeff (no *_static / *_dynamic / *_viscous renames). * SI units annotated on every public property docstring ([m or rad, depending on joint type], [m/s or rad/s, ...], [N*m], [kg], etc.) per AGENTS.md. * binding_getter parameter on __init__ typed as Callable[[int], Any] | None. * Section organisation matches PhysX (Defaults -> Joint commands -> Joint properties -> Fixed tendon -> Spatial tendon -> Root state -> Body state -> Joint state -> Derived -> Sliced -> Internal helpers -> Deprecated properties). Kernels ^^^^^^^ * Articulation-specific kernels in isaaclab_ovphysx/assets/articulation/kernels.py (soft-limit clamp, friction-data writer, finite-difference joint-acc helper, body-CoM pose composer); shared kernels promoted to isaaclab_ovphysx/assets/kernels.py. * Per-kernel docstrings document purpose, shape/dtype/SI units, and divergence notes where the OVPhysX implementation differs (e.g. _fd_joint_acc takes inv_dt rather than dt to avoid per-element division). Tests ^^^^^ * Real-backend test_articulation.py mirrors isaaclab_physx 1-to-1 under run_ovphysx.sh; 99 tests pass on each of CPU + CUDA. * test_articulation_helpers.py covers the kitless-only helpers (tendon scoping, mock binding shapes). * Cross-backend test_articulation_iface.py runs the OVPhysX path: 544 tests pass, 16 skipped, 0 failed on each of CPU + CUDA. Brings the iface helper up to the actual ArticulationData constructor signature and broadcasts scalar inputs across joint / fixed-tendon / spatial-tendon mask setters that previously rejected them. OVPhysX-only surface dropped ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Articulation: set_external_force_and_torque_{index,mask} (use instantaneous_wrench_composer.add_forces_and_torques_*), set_spatial_tendon_limit_{index,mask}, and set_spatial_tendon_rest_length_{index,mask} (NotImplementedError stubs PhysX never had). * ArticulationData: body_pose_w / body_lin_vel_w / body_ang_vel_w / body_acc_w / body_link_acc_w (base class provides matching defaults), body_inv_mass / body_inv_inertia, fixed_tendon_limit (PhysX exposes only fixed_tendon_pos_limits), spatial_tendon_limit / spatial_tendon_rest_length (no PhysX equivalent).
e3a782e to
4d05d9d
Compare
Adds ``ovphysx`` to both preset classes in ``allegro_hand_env_cfg.py``: * ``ObjectCfg`` — cube uses ``RigidObjectCfg`` (same as the ``physx`` preset, since OVPhysX ships RigidObject support). * ``PhysicsCfg`` — ``OvPhysxCfg()`` with defaults. Validated with RSL-RL: 300 iterations clean on cuda:0. Exercises both the articulation (Allegro hand, 16 DOFs) and the rigid object (cube) backends in the same scene.
4d05d9d to
18c90dc
Compare
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Use the same `Articulation-specific warp functions/kernels` section headers, drop the verbose absent-kernel module docstring, and tighten kernel docstrings to match PhysX conventions (SI units in `[unit]` notation, full Args sections with shapes, `:paramref:` instead of `:attr:` for kernel arguments). No behavior changes; kernel names and import paths are unchanged.
Reorder the public Articulation properties to match the PhysX/Newton section ordering (data, num_instances, is_fixed_base, num_joints, num_fixed_tendons, num_spatial_tendons, num_bodies, joint_names, fixed_tendon_names, spatial_tendon_names, body_names, root_view, *_wrench_composer). Align find_*, reset, write_data_to_sim, and _initialize_impl docstrings/comments with the PhysX style: * drop the verbose `Step N:` annotations from `_initialize_impl`, keeping only WHY-comments around non-obvious invariants * remove `# Mirrors PhysX (articulation.py:NNN)` line-number cross-references that aged poorly * tighten `reset`, `write_data_to_sim`, and `update` docstrings to match the PhysX wording No behavior changes.
Replace the OVPhysX-implementation-flavored module docstring and class
docstring with the same domain-level prose used by the PhysX/Newton
ArticulationData, plus an OVPhysX-specific note about pinned-host CPU
staging for CPU-only bindings. Reword internal `__init__` comments to
drop dev-cruft references ("post-audit RigidObjectData demotion",
"PR isaac-sim#5329 pattern") and group fields the way PhysX does (timestamp,
constants, buffers). Reword `update()` to mirror PhysX phrasing.
No behavior changes.
Replace the OVPhysX-implementation-flavored module/class docstring with the same domain-level prose used by the PhysX and Newton Articulation classes, plus a short OVPhysX-specific paragraph about per-tensor-type ``TensorBinding`` objects and pinned-host CPU staging. Drop "the wheel" backend-internal slang from comments and docstrings in favor of "binding" / "simulation". Remove leftover "PR isaac-sim#5329 pattern" references and other dev cruft. No behavior changes.
Replace the OVPhysX-implementation-flavored module/class docstring with the domain-level prose used by the PhysX and Newton Articulation classes, plus a short OVPhysX-specific paragraph about per-tensor-type ``TensorBinding`` objects and pinned-host CPU staging. Add the pyright header that the PhysX/Newton files carry.
Remove the two orphan callers of `_read_binding_into_view` (a method that was never defined on this branch, leaving an AttributeError on every read through `_read_binding_into_buf` and `_read_spatial_vector_binding`) and restore the original `self._get_binding(tensor_type).read(view)` pattern used elsewhere. Add `cls._physx.update_articulations_kinematic()` to `OvPhysxManager.step()` so link transforms reflect the freshly integrated joint state, matching the PhysX backend's behavior. This relies on the FK API exposed by ovphysx 0.4. Unblocks ~80 articulation tests previously failing with `'ArticulationData' object has no attribute '_read_binding_into_view'`.
The `body_incoming_joint_wrench_b` property reads into `self._body_incoming_joint_wrench_buf` and wraps it in a `ProxyArray`, but `_create_buffers` never allocated the buffer and `_pin_proxy_arrays` never declared the corresponding `_ta` slot. The first access raised AttributeError on the missing buffer. Allocate it next to the other body-state buffers (shape `(N, L)`, dtype `wp.spatial_vectorf`, matching the property docstring) and declare its `ProxyArray` cache slot in `_pin_proxy_arrays`.
The latest develop merge renamed `JointDrivePropertiesCfg.max_velocity` → `JointDriveBaseCfg.max_joint_velocity` and `max_effort` → `max_force`. The constructor still accepts the old kwargs as deprecation aliases, but `__post_init__` forwards the value to the canonical name and **blanks the alias**, so reads through the old name return None. Update the three test sites that resolve the USD default limit to use the canonical field names.
Mirror the PhysX backend's FK-on-demand pattern (see ``isaaclab_physx.assets.articulation_data:732``): when ``body_link_pose_w`` finds its buffer stale, call ``ovphysx.PhysX.update_articulations_kinematic`` before reading the LINK_POSE binding. This ensures body link poses reflect joint state written via ``write_joint_position_to_sim_*`` without requiring a sim step, closing the gap that previously xfailed ``test_write_joint_state_data_consistency`` on GPU sims. Drop the now-obsolete ``_FK_ON_DEMAND_GAP_REASON`` xfail marker and constant in the test file.
## Summary Implements `RigidObject` and `RigidObjectData` for the OVPhysX backend (issue isaac-sim#5316), satisfying the `BaseRigidObject` and `BaseRigidObjectData` contracts. Mirrors the PhysX `RigidObject` and the existing OVPhysX `Articulation` patterns; runs kitless via the standard `SimulationContext` + `UsdFileCfg(usd_path=…)` pipeline. - New: `source/isaaclab_ovphysx/isaaclab_ovphysx/assets/rigid_object/{rigid_object.py, rigid_object_data.py, __init__.py, __init__.pyi}` (~1900 lines). - New: `source/isaaclab_ovphysx/isaaclab_ovphysx/assets/kernels.py` — shared Warp kernels relocated from `articulation/kernels.py` so both asset types use them; new `_compose_root_link_pose_from_com` for COM→link write conversion; ported Newton's `derive_body_acceleration_from_body_com_velocities` to FD acceleration locally (no wheel `RIGID_BODY_ACCELERATION` dependency). - New `RIGID_BODY_*` `TensorType` aliases in `isaaclab_ovphysx/tensor_types.py` — six already-shipping types as direct imports, three forward-compat aliases (`ACCELERATION`, `INV_MASS`, `INV_INERTIA`) gated by `try/except AttributeError` so the module loads cleanly today. - Allegro env hookup (`source/isaaclab_tasks/.../allegro_hand/allegro_hand_env_cfg.py`): adds `ovphysx` variants to `ObjectCfg` and `PhysicsCfg`, mirroring the Cartpole/Ant pattern. Enables running `Isaac-Repose-Cube-Allegro-Direct-v0` against OVPhysX via `./scripts/run_ovphysx.sh`. - Cross-backend interface tests: `BACKENDS.append(\"ovphysx\")` + `create_ovphysx_rigid_object` factory in `source/isaaclab/test/assets/test_rigid_object_iface.py`. - Versioning: `isaaclab_ovphysx 0.1.2 → 0.2.0`, `isaaclab_tasks 1.5.29 → 1.5.30`. ## Test plan ### Real-backend rigid-object tests (kitless, via `run_ovphysx.sh`) ``` ./scripts/run_ovphysx.sh -m pytest source/isaaclab_ovphysx/test/assets/test_rigid_object.py -v ``` Current state: **61 passed, 14 xfailed**. The 61 passing tests are real-backend (live `ovphysx.PhysX` instance, real `TensorBinding` reads, real sim steps) — port of the PhysX `test_rigid_object.py` structure with the canonical `SimulationContext` + `UsdFileCfg(ISAAC_NUCLEUS_DIR/Props/Blocks/DexCube/dex_cube_instanceable.usd)` pattern Cartpole/Newton already use. Catches two production bugs the previous mock-based suite missed (\`hasattr\` swallow on \`body_names\`, \`self._device\` always falling back to \`cuda:0\`). ### Cross-backend interface tests ``` ./scripts/run_ovphysx.sh -m pytest source/isaaclab/test/assets/test_rigid_object_iface.py -v -k ovphysx ``` Current state: **252 passed, 120 fixed shape-mismatch failures fixed in this branch** (4 distinct bugs caught: full-write row-count guard, 1-D mask src normalization, COM-pose row-count guard, two unimplemented \`default_root_pose/vel\` stubs). ### Existing articulation regression check ``` ./scripts/run_ovphysx.sh -m pytest source/isaaclab_ovphysx/test/assets/test_articulation.py source/isaaclab_ovphysx/test/assets/test_articulation_data.py -v ``` Verifies the kernel relocation in Task 2 didn't break existing articulation tests. Recommended before merge. ### Manual end-to-end (Kit + Nucleus) \`Isaac-Repose-Cube-Allegro-Direct-v0\` with the new \`ovphysx\` preset — manual smoke test (Kit-required, requires Nucleus access): ``` ./scripts/run_ovphysx.sh source/isaaclab_tasks/isaaclab_tasks/direct/allegro_hand/allegro_hand_env.py --num_envs 4 --headless ``` ## Wheel-side gaps (for @marcodiiga) The 14 remaining xfails split as follows; only **10 are wheel-side blockers** (all in the same category): | Category | xfailed | Owner | |---|---|---| | Material-properties API (`RIGID_BODY_MATERIAL` TensorType or view helper) | 10 | Wheel — see [docs/superpowers/specs/2026-04-28-ovphysx-wheel-gaps-for-marco.md](https://github.com/AntoineRichard/IsaacLab/blob/antoiner/feat/ovphysx_rigidobject/docs/superpowers/specs/2026-04-28-ovphysx-wheel-gaps-for-marco.md) for the proposed contract | | `test_initialization_with_no_rigid_body` (RuntimeError on missing prim) | 2 | IsaacLab follow-up — error-handling polish | | `test_initialization_with_articulation_root` (out-of-scope per spec) | 2 | IsaacLab follow-up — explicit \`NotImplementedError\` stub | Three additional wheel-side `RIGID_BODY_*` TensorTypes (`ACCELERATION`, `INV_MASS`, `INV_INERTIA`) are forward-compat — declared via `try/except AttributeError` aliases on the IsaacLab side, no IsaacLab consumers depend on them today, but they auto-activate when the wheel ships them. ## Notes - IsaacLab side is wheel-update-agnostic: `tensor_types.py` defensive aliases let \`isaaclab_ovphysx\` import cleanly against today's \`ovphysx 0.3.7\`. - Local docs at \`docs/superpowers/specs/\` (gitignored) include the original design spec, the corrected Marco-feedback gap spec, and the test-gaps follow-up. - Branch contains 30 commits including Marco's contract corrections (renames \`RIGID_BODY_ROOT_POSE\` → \`RIGID_BODY_POSE\`, \`MASS\` shape \`(N, 1)\` → \`(N,)\`). --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…ysx_articulation # Conflicts: # source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/articulation.py # source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/articulation_data.py # source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/kernels.py # source/isaaclab_ovphysx/isaaclab_ovphysx/assets/kernels.py # source/isaaclab_ovphysx/isaaclab_ovphysx/tensor_types.py
Adopt the RigidObjectData / PhysX pattern: derive instance / body / joint / tendon counts from the binding metadata (``next(iter(bindings.values()))``), and assign name lists as class-level attributes filled in by ``Articulation._initialize_impl`` after construction. The constructor signature collapses from twelve arguments to ``(bindings, device)``. Drop the ``binding_getter`` callable. Bindings the data container reads (LINK_POSE, LINK_VELOCITY, LINK_ACCELERATION, LINK_INCOMING_JOINT_FORCE, ROOT_VELOCITY, and the fixed / spatial tendon set when counts > 0) are eagerly created in ``_initialize_impl`` instead of looked up via a callback, so ``ArticulationData._get_binding`` reduces to a dict lookup. Guard the forward-kinematics call in ``body_link_pose_w`` against a missing ``OvPhysxManager`` instance, so the mocked cross-backend iface tests no longer trip ``WrenchComposer``'s ``hasattr`` probe. Drop ``test_articulation_data.py`` (covered by real-backend tests) and the two ``_data`` tendon-name assertions in ``test_articulation_helpers.py`` (propagation now lives in ``_initialize_impl``, not ``_process_tendons``). Articulation tests: 101 real-backend + 2 helpers + 1080 iface = 1183 passed.
The isaaclab_ov CI job's glob collects all ``test/`` files under
``source/isaaclab_ov*``, including the isaaclab_ovphysx tests. The
sibling ovphysx test files already guard their isaaclab_ovphysx imports
with ``pytest.importorskip("ovphysx.types", reason="ovphysx wheel not
installed")``; only ``test_articulation.py`` went straight to top-level
``from isaaclab_ovphysx.assets import Articulation``, which raised
``ModuleNotFoundError`` at collection time and failed the entire
isaaclab_ov job in the CI image (where the ovphysx wheel is not
installed).
Add the same ``importorskip`` guard so the file is skipped cleanly in
that environment, matching the established pattern from
test_articulation_helpers.py and the rigid-object fix in isaac-sim#5426.
Also add a ``.skip`` changelog fragment for the isaaclab core package
covering the iface test factory tweak in the prior commit.
c6ea8c7 to
3430279
Compare
The recent OVPhysX preset hookup for the Allegro Repose direct task adds
``from isaaclab_ovphysx.physics import OvPhysxCfg`` at module top in
``source/isaaclab_tasks/.../allegro_hand/allegro_hand_env_cfg.py``.
When sphinx walks ``isaaclab_mimic.datagen`` for autodoc, the chain
``generation.py`` → ``isaaclab_tasks.utils.parse_cfg`` →
``isaaclab_tasks.__init__.import_packages`` recursively imports every
task package's ``__init__.py``. ``isaaclab_ovphysx/tensor_types.py``
does ``from ovphysx.types import TensorType`` at module load; the
``ovphysx`` wheel is not in ``docs/requirements.txt``, so the import
raises ``ModuleNotFoundError`` and sphinx reports the failure at the
outermost autodoc'd module:
WARNING: Failed to import isaaclab_mimic.datagen.
Possible hints:
* AttributeError: module 'isaaclab_mimic' has no attribute 'datagen'
* TypeError: unsupported operand type(s) for *: 'float' and 'pi'
(the ``float * pi`` hint is the assemble_trocar ``np.pi`` mock issue
surfacing as a sphinx fallback; not the primary cause.)
Add ``ovphysx`` to ``autodoc_mock_imports`` so sphinx mocks the wheel
during doc build, mirroring how ``omni`` / ``carb`` / ``isaacsim`` are
handled. No source-side change needed.
…5400) ## 1. Summary Make IK / OSC / RMPFlow task-space controllers backend-agnostic so Franka manipulation envs run under Newton. The action terms previously called PhysX-only methods on `asset.root_view` directly, which crashed under Newton with `AttributeError`. The Franka reach envs worked around this by hardcoding `self.sim.physics = PhysxCfg(...)` with the comment *"{IK,OSC} control is not supported with Newton physics; use PhysX only"*. This PR removes that workaround. End-to-end result: `Isaac-Reach-Franka-{IK-Abs,IK-Rel,OSC}-v0` run on either backend, picked via `presets=newton`. ## 2. Design Four new properties on `BaseArticulationData`: - `body_link_jacobian_w` — geometric Jacobian, linear rows at the link origin (USD prim frame). What IK / OSC consumers want. - `body_com_jacobian_w` — geometric Jacobian, linear rows at the center of mass. Engine-natural form; useful for dynamics reasoning. - `mass_matrix` — joint-space generalized mass matrix `M(q)`. - `gravity_compensation_forces` — joint-space gravity-loading torques `g(q)`. Plus one metadata property on `BaseArticulation`: - `num_base_dofs` — number of free DoFs of the floating base. `0` for fixed-base, `6` for floating-base. Maps an actuated-joint id `j` to its column in J / M / g via `j + num_base_dofs`. All four data properties are concrete-with-`NotImplementedError` defaults; backends override what they support. ### 2.1 DoF axis: `num_joints + num_base_dofs` (industry-standard) The DoF axis prepends `num_base_dofs` columns at the front of the joint axis: `0` for fixed-base, `6` for floating-base. The 6 columns are the floating-base spatial velocity in world frame, ordered `[lin_x, lin_y, lin_z, ang_x, ang_y, ang_z]`. This matches every major rigid-body library: | Library | Floating-base layout | |---------|----------------------| | Pinocchio | Free-flyer joint contributes 6 to `nv`; reduced-coordinate `nv = 6 + n_actuated`. `pinocchio::computeJointJacobians` writes `(6, nv)`. | | Drake | `MultibodyPlant` ephemeral floating joint; `MultibodyPlant::CalcJacobianSpatialVelocity` returns `(6, nv)` with leading 6 free-floating cols. | | MuJoCo | `<freejoint/>` introduces 6 DoFs at the front of `qvel`; `mj_jac*` returns `(_, nv)`. | | RBDL | `JointTypeFloatingBase` adds 6 to `dof_count`; `CalcPointJacobian` returns `(_, dof_count)`. | | OCS2 | `generalizedCoordinatesNum = 6 + actuatedJointsNum` for floating-base robots. | | iDynTree | `getFreeFloatingMassMatrix` returns `(6 + dofs, 6 + dofs)`. | Consumers operating in actuated-joint space (action terms keyed by `joint_ids`) compute `[j + asset.num_base_dofs for j in joint_ids]` once at init — same application-level reduction as every surveyed library. ### 2.2 Output shapes by backend Concrete shapes for each engine output and the wrapper transform applied. `N` = num_instances, `B` = num_bodies (full count incl. root), `J` = num_joints (actuated only). "Default" is the engine-native per-view shape (post-gather). "passthrough" = wrapper applies no shape change. The COM→origin shift is values-only (does not change shape). | Property | Base | Newton (default ⟶ transform) | PhysX (default ⟶ transform) | Aligned | |---|---|---|---|---| | `body_link_jacobian_w` | fixed | `(N, B, 6, J)` ⟶ drop fixed-root row + COM→origin shift | `(N, B−1, 6, J)` ⟶ COM→origin shift | `(N, B−1, 6, J)` | | `body_link_jacobian_w` | floating | `(N, B, 6, J+6)` ⟶ COM→origin shift | `(N, B, 6, J+6)` ⟶ COM→origin shift | `(N, B, 6, J+6)` | | `body_com_jacobian_w` | fixed | `(N, B, 6, J)` ⟶ drop fixed-root row | `(N, B−1, 6, J)` ⟶ passthrough | `(N, B−1, 6, J)` | | `body_com_jacobian_w` | floating | `(N, B, 6, J+6)` ⟶ passthrough | `(N, B, 6, J+6)` ⟶ passthrough | `(N, B, 6, J+6)` | | `mass_matrix` | fixed | `(N, J, J)` ⟶ passthrough | `(N, J, J)` ⟶ passthrough | `(N, J, J)` | | `mass_matrix` | floating | `(N, J+6, J+6)` ⟶ passthrough | `(N, J+6, J+6)` ⟶ passthrough | `(N, J+6, J+6)` | | `gravity_compensation_forces` | fixed | (no upstream primitive) ⟶ `NotImplementedError` | `(N, J)` ⟶ passthrough | `(N, J)` | | `gravity_compensation_forces` | floating | (no upstream primitive) ⟶ `NotImplementedError` | `(N, J+6)` ⟶ passthrough | `(N, J+6)` | The aligned column collapses across base type using two derived symbols: - `num_base_dofs` = `0` fixed | `6` floating — exposed as `BaseArticulation.num_base_dofs` - `num_jacobi_bodies` = `B − 1` fixed | `B` floating — fixed-root row excluded for fixed-base | Property | Aligned (generalized) | |---|---| | `body_link_jacobian_w`, `body_com_jacobian_w` | `(N, num_jacobi_bodies, 6, J + num_base_dofs)` | | `mass_matrix` | `(N, J + num_base_dofs, J + num_base_dofs)` | | `gravity_compensation_forces` | `(N, J + num_base_dofs)` | Two observations: 1. The only body-axis asymmetry is **Newton's fixed-base Jacobian**: Newton's `eval_jacobian` includes a zero row for the fixed-root joint that the wrapper drops. PhysX's engine already drops it. 2. The DoF axis is in the industry-standard `J + num_base_dofs` form on both engines natively. The only DoF-axis asymmetry is `gravity_compensation_forces` (Newton NIE pending upstream primitive). ### 2.3 Why on `BaseArticulationData`, not `BaseArticulation` `BaseArticulationData` already exposes per-body / per-joint state as cached lazy `@property` accessors with `TimestampedBuffer` invalidation (`body_link_pose_w`, `joint_pos`, etc.). The four new accessors fit the same shape — read-only state indexed by body / joint, refreshed per sim step — so they reuse that infrastructure and let consumer code stay symmetric: ```python # IK action term ee_pose = articulation.data.body_link_pose_w.torch[:, ee_idx] ee_jac = articulation.data.body_link_jacobian_w.torch[:, ee_jac_idx] # same prefix ``` ## 3. Fixed: latent PhysX IK / OSC frame mismatch PhysX's `_root_view.get_jacobians()` returns linear rows referenced at each body's **center of mass**, not the link origin. Undocumented behavior — verified empirically by bypassing the IsaacLab wrapper and confirming `J · q̇` matches `body_com_lin_vel_w` to 1e-8 and differs from `body_link_lin_vel_w` by exactly `ω × r_com_world` (the rigid-body shift). The PhysX data layer already encoded this convention for velocities: `body_com_vel_w` is the raw passthrough of `_root_view.get_link_velocities()`; `body_link_vel_w` is **derived** via a shift kernel. Before this PR, IK / OSC / RMPFlow action terms on PhysX consumed `_root_view.get_jacobians()` directly while using `data.body_link_pose_w` as the EE pose setpoint. The frame mismatch contributes `ω × r_com_world` per body to the linear-row contract — undetected in CI because no existing test compared `J · q̇` against `body_link_lin_vel_w` directly. The new contract test `test_get_jacobians_link_origin_contract` parametrized to `anymal` catches it explicitly: 0.32 m/s residual on PhysX without the fix. After this PR, PhysX's `body_link_jacobian_w` applies the same COM→origin shift kernel that Newton uses, mirroring the existing `body_link_vel_w` derivation. Both backends now satisfy `body_link_jacobian_w · q̇ == body_link_vel_w` to numerical precision (test tolerance 5e-3 absolute, 1e-2 relative). The COM-referenced sibling `body_com_jacobian_w` is exposed for callers that intentionally want the engine-native form (e.g. dynamics-side reasoning at the COM). Also: the three PhysX passthrough properties (`body_com_jacobian_w`, `mass_matrix`, `gravity_compensation_forces`) now pin a single `ProxyArray` in `_create_buffers` instead of allocating one per property read. PhysX tensor-view getters return pointer-stable buffers for the articulation's lifetime — verified manually across `sim.step`, a manual joint write, and `sim.reset`. ## 4. Newton-side details ### 4.1 Pre-allocation for capture safety Dynamics-scratch allocation is grouped in a private `ArticulationData._create_jacobian_buffers(model)` helper called from `_create_buffers`. The helper is sectioned by which property each buffer feeds, and names reflect each buffer's physical role: - **Shared scratch** (eval_jacobian output, reused as eval_mass_matrix's `J` input to skip a re-compute): `_jacobian_buf_flat`, `_joint_S_s_buf` (Featherstone motion subspace — shared between the two evals, hence the property-prefix-free name). - **Per-view gather config**: `_jacobian_link_offset` (fixed-base row-0 skip), `_jacobian_view_art_ids` (flattened view-to-model index map). - **`body_com_jacobian_w`**: `_jacobian_buf` (zero-copy 4-D view of `_jacobian_buf_flat`, kernel input) and `_body_com_jacobian_w_buf` (gather output, per-view). - **`body_link_jacobian_w`**: `_body_link_jacobian_w_buf` (Center-Of-Mass-to-link-origin shift kernel output, per-view). - **`mass_matrix`**: `_mass_matrix_full_buf` (model-wide `H` scratch — Composite Rigid Body Algorithm (CRBA) output), `_mass_matrix_body_I_s_buf` (Featherstone per-body spatial inertia aux, CRBA-only), `_mass_matrix_buf` (gather output, per-view). Properties are allocation-free at step time. The kernel-launch sequence runs against fixed buffer pointers, which is what makes the per-step path safe under CUDA-graph capture. ### 4.2 View-level row gather Newton's `eval_jacobian` / `eval_mass_matrix` write every articulation in the model into a single buffer (shape includes `model.articulation_count`), regardless of which `ArticulationView` invoked them. PhysX returns view-scoped data already. Two Warp kernels (`gather_jacobian_rows` 4-D, `gather_mass_matrix_rows` 3-D) gather just this view's rows into a contiguous view-sized destination so the caller-facing shape contract matches PhysX. The view-to-model index map is reused across both gathers. ### 4.3 `eval_mass_matrix` "J as input" gotcha Newton's `eval_mass_matrix(state, H, J=None, body_I_s=None, joint_S_s=None)` treats `J` as **input** when provided — it skips the internal `eval_jacobian` and uses the buffer as-is. Passing an empty pre-allocated `J` produces `H = J^T·M·J = 0` → singular → `LinAlgError` in OSC's `torch.inverse(mass_matrix)`. The wrapper explicitly populates `J` by calling `eval_jacobian` first; we reuse `_jacobian_buf_flat` (same shape) so no separate scratch is needed. ### 4.4 COM→origin shift on `body_link_jacobian_w` Newton's `eval_jacobian` writes linear-velocity rows at each link's **center of mass**. After `gather_jacobian_rows`, the `shift_jacobian_com_to_origin` Warp kernel applies `v_origin = v_com - ω × (R · body_com_pos_b)` per `(env, body, dof)` thread, writing to `_body_link_jacobian_w_buf`. The COM-referenced source buffer is reused as-is for `body_com_jacobian_w` and `mass_matrix`. ### 4.5 FK staleness `eval_jacobian` and `eval_mass_matrix` read `state.body_q` (per-body world transforms). After a manual `write_joint_position_to_sim_*` (no sim step), `state.joint_q` is updated but `state.body_q` is stale until `eval_fk` runs. The new properties match the existing `body_link_pose_w` convention — refresh FK lazily via `_ensure_fk_fresh()` (Python-guarded `SimulationManager.forward()`) before invoking the eval kernels. PhysX has its own internal refresh on the equivalent getters (verified empirically by the new manual-write tests passing on PhysX without an explicit trigger). ## 5. Action-term gating `OperationalSpaceControllerAction._compute_dynamic_quantities` previously fetched mass matrix and gravity-compensation forces unconditionally on every step. Under the new abstraction this would still call Newton's gravity-comp stub even when the user disabled gravity compensation in the controller config. The fetches are now gated to match what the controller actually consumes: - Mass matrix fetched when `inertial_dynamics_decoupling=True` **or** `nullspace_control != "none"` (the null-space torque term in `OperationalSpaceController.compute()` consumes mass matrix independently of inertial decoupling). - Gravity comp fetched only when `gravity_compensation=True`. Side benefit: skips a per-step engine call on PhysX when neither flag is set. ## 6. Known limitation: gravity compensation on Newton Newton's `ArticulationView` has no gravity-compensation primitive (only `eval_fk` / `eval_jacobian` / `eval_mass_matrix`). `gravity_compensation_forces` raises `NotImplementedError` on Newton; OSC users on Newton must set `gravity_compensation=False` until upstream lands the primitive (newton-physics/newton#2497, isaac-sim#2529, isaac-sim#2625). The strict-xfail test `test_get_gravity_compensation_forces_not_implemented_on_newton` flips to XPASS when that happens, signaling the maintainer to remove the wrapper stub and OSC guidance. ## 7. Reach-env cfg cleanup Removed the `self.sim.physics = PhysxCfg(bounce_threshold_velocity=0.2)` override from `Isaac-Reach-Franka-{IK-Abs,IK-Rel,OSC}-v0`. Tasks now inherit the parent `ReachPhysicsCfg` preset, so `presets=newton` selects `NewtonCfg` and `presets=physx` (the default) keeps the previous behavior — same `bounce_threshold_velocity=0.2` lives on `ReachPhysicsCfg.default = PhysxCfg(bounce_threshold_velocity=0.2)`. No information lost. ## 8. Test plan ### 8.1 Existing controller tests migrated - [x] `test_differential_ik.py` migrated to `robot.data.body_link_jacobian_w.torch`. Passes on PhysX (2/2). - [x] `test_operational_space.py` migrated to `robot.data.body_link_jacobian_w.torch`, `robot.data.mass_matrix.torch`, `robot.data.gravity_compensation_forces.torch`. PhysX (12/18 — the 6 failures are pre-existing `ContactSensor` env issues unrelated to this PR; affected tests fail on `omni.physics.tensors.api` import which is independent of the bridge). - [x] `test_floating_base_osc_action_term_indexing` cfg unchanged. ### 8.2 New tests in this PR **Shape contracts** — lock the public DoF / body axes: | Test | Backend | Purpose | Result | |------|---------|---------|--------| | `test_get_jacobians_shape_fixed_base` | PhysX + Newton | `body_link_jacobian_w` drops the fixed-root row → `(N, B−1, 6, J)`. | PASSES | | `test_get_jacobians_shape_floating_base` | PhysX + Newton | Floating base keeps root row + prepends 6 base cols → `(N, B, 6, J+6)`. | PASSES | | `test_get_mass_matrix_shape_and_nonsingular_fixed_base` | PhysX + Newton | `(N, J, J)` + strictly positive diagonal (catches the model-wide-padding bug that masks heterogeneous-scene mismatch as a singular matrix). | PASSES | | `test_get_mass_matrix_shape_floating_base` | Newton | `(N, J+6, J+6)` — floating-base includes the 6 free-root DoFs. | PASSES | | `test_heterogeneous_scene_per_view_shapes` | Newton | Mixed Franka+Anymal scene: each view returns its OWN asset shape, not `model.max_*`. Direct regression test for the heterogeneous-padding bug. | PASSES | **Math / physics contracts** — values, not just shapes: | Test | Backend | Purpose | Result | |------|---------|---------|--------| | `test_get_jacobians_link_origin_contract[panda \| anymal]` | PhysX | `J · q̇ == body_link_lin_vel_w` identity (sharp J reference-point check). Anymal exercise catches the latent COM/link mismatch this PR fixes. | PASSES | | `test_get_jacobians_link_origin_contract[panda \| anymal]` | Newton | Same identity, ground truth from `state.body_qd` minus the COM offset shift. | PASSES | | `test_get_mass_matrix_symmetry_pd[panda \| anymal]` | PhysX + Newton | `M(q)` is square, symmetric, positive-definite. | PASSES (4/4) | **Freshness contracts** — Forward Kinematics (FK) refresh after manual writes: | Test | Backend | Purpose | Result | |------|---------|---------|--------| | `test_jacobian_refreshes_after_manual_joint_write[panda \| anymal]` | PhysX + Newton | After `write_joint_position_to_sim_index` (no sim step), reading the Jacobian reflects the new joint state. Locks in the FK-staleness contract on the manual-write code path. | PASSES (4/4) | | `test_mass_matrix_refreshes_after_manual_joint_write[panda \| anymal]` | PhysX + Newton | Same contract for mass matrix. | PASSES (4/4) | **Gravity compensation** — accessor + Operational Space Control (OSC) integration + negative control: | Test | Backend | Purpose | Result | |------|---------|---------|--------| | `test_get_gravity_compensation_forces_static_equilibrium` | PhysX | Apply only `τ_gc` to a non-trivial Franka pose; assert it stays static. Pins the accessor in isolation, no controller masking. | PASSES | | `test_franka_osc_gravity_compensation_holds_under_gravity` | PhysX | OSC + `gravity=g(q)` under scene gravity holds the EE pose. Pins (a) `_jacobi_joint_idx + num_base_dofs` indexing, (b) `OSC.compute(gravity=...)` torque math, (c) reachability through the action-term pipeline. | PASSES | | `test_franka_osc_no_gravity_compensation_sags_under_gravity` | PhysX | Negative control — OSC **without** gravity comp DOES drift under gravity. Proves the with-comp test isn't passing because `g(q)=0`. | PASSES | | `test_get_gravity_compensation_forces_not_implemented_on_newton` | Newton | Strict-xfail pin for the upstream Newton gap. Flips to XPASS when upstream lands the primitive. | XFAIL (correct) | **End-to-end Inverse Kinematics (IK) and OSC accuracy** — production sentinels: | Test | Backend | Purpose | Result | |------|---------|---------|--------| | `test_franka_ik_tracking_accuracy` | PhysX + Newton | Damped-Least-Squares IK convergence sentinel via the new accessors. | PASSES (PhysX 0.01 mm, Newton 0.00 mm) | | `test_franka_osc_tracking_accuracy` | PhysX + Newton | OSC convergence sentinel via Jacobian + mass matrix. | PASSES (both at machine precision) | Latest CI: `isaaclab_physx` and `isaaclab_newton` both green on the most recent push. ### 8.3 Determinism and stability The accuracy sentinels are bit-for-bit deterministic on both backends at the 5 cm short-target setup: 20× consecutive runs each give the same `pos_mean` to 5 decimal places. Both tests assert on tail mean rather than tail min — the latter is the bottom of any oscillation envelope and can pass spuriously while the actual tracking error is much larger. Tight regression sentinels rather than flaky bounds. No `pytest-rerunfailures` retry decoration — a CI failure should be a real regression, not noise to retry away. ### 8.4 Smoke runs - [x] `random_agent` on `Isaac-Reach-Franka-IK-Abs-v0` under Newton: 5,205 physics substeps zero-error. - [x] `random_agent` on `Isaac-Reach-Franka-IK-Rel-v0` under Newton: 306 substeps zero-error. - [x] `random_agent` on `Isaac-Reach-Franka-OSC-v0` under Newton: 290 substeps zero-error. ### 8.5 Test-setup notes The accuracy tests need two fixes that the standalone path doesn't get for free (production envs do): - Teleport to `init_state.joint_pos` post-`sim.reset()`. Without it, the robot sits at the URDF-neutral pose where Franka's wrist axes nearly align — rank-deficient Jacobian, multi-cm DLS plateau. - Override `sim_cfg.gravity = (0, 0, 0)` in the Newton `sim` fixture (`build_simulation_context(gravity_enabled=False)` is silently ignored when an explicit `sim_cfg` is passed). The OSC test additionally zeros actuator PD gains so OSC's joint-effort output isn't opposed by `kp·(target − q)` (same way OSC is wired in production action terms). With these in place, Newton hits machine precision and PhysX hits ~10 µm. Newton's PD does have a real `g_torque/kp` gravity-sag that PhysX's TGS masks via constraint projection — surfaces only when gravity is on without gravity compensation, which is the upstream gap in § 6. ## 9. Files Touched five extensions; per-package changelog fragments under `source/<pkg>/changelog.d/jichuanh-ik-newton-compat-mvp*.rst`: - `isaaclab` (minor): four new properties on `BaseArticulationData`; `num_base_dofs` on `BaseArticulation`; controller-action gating + migration to data-layer accessors; doc updates. - `isaaclab_physx`: data-layer impls + `shift_jacobian_com_to_origin` kernel; docs the latent frame-mismatch fix. - `isaaclab_newton` (minor): data-layer impls (eval + gather + shift); model-sized scratch and view-sized output buffers migrated from articulation to data layer; gravity-comp NIE stub. - `isaaclab_ovphysx`: bridge methods removed (inherits NIE). - `isaaclab_tasks`: hardcoded `PhysxCfg` removals + direct-workflow caller migrations to data-layer accessors. --------- Signed-off-by: aravind s kumar <aravikumar@nvidia.com> Co-authored-by: aravind s kumar <aravikumar@nvidia.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com>
# Description The timeout retry logic is doing more harm than good as it's causing tests to run extremely long and does not actually resolve any of the timeout issues. Reverting the change to default to 0 retries on timeouts. ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task -->
…c-sim#5167) # Description PR [isaac-sim#4142](isaac-sim#4142) added 10 typed RT2 (`RealTimePathTracing`) fields to `RenderCfg` to expose the carb settings that actually control rendering quality under the RT2 mode that has been default since Isaac Sim 4.5. The PhysicsManager refactor in PR [isaac-sim#4564](isaac-sim#4564) (commit `0ba9c5cb`) accidentally removed all 10 of these fields during a large `simulation_cfg.py` rewrite, while the `.kit` preset files that reference the same carb paths were left intact. This PR restores the removed fields and their `field_to_setting` mappings, along with test coverage. **Restored fields:** | Field | Carb Path | |-------|-----------| | `max_bounces` | `/rtx/rtpt/maxBounces` | | `split_glass` | `/rtx/rtpt/splitGlass` | | `split_clearcoat` | `/rtx/rtpt/splitClearcoat` | | `split_rough_reflection` | `/rtx/rtpt/splitRoughReflection` | | `ambient_light_intensity` | `/rtx/sceneDb/ambientLightIntensity` | | `ambient_occlusion_denoiser_mode` | `/rtx/ambientOcclusion/denoiserMode` | | `subpixel_mode` | `/rtx/raytracing/subpixel/mode` | | `enable_cached_raytracing` | `/rtx/raytracing/cached/enabled` | | `max_samples_per_launch` | `/rtx/pathtracing/maxSamplesPerLaunch` | | `view_tile_limit` | `/rtx/viewTile/limit` | Without these fields, users can only reach RT2 quality knobs through the `carb_settings` escape-hatch dict, while the existing named fields (`samples_per_pixel`, `enable_translucency`, `enable_reflections`, `enable_direct_lighting`) map to RT1 Legacy carb paths that RT2 ignores entirely. ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Signed-off-by: Nicholas Blauch <nblauch@gmail.com> Co-authored-by: ooctipus <zhengyuz@nvidia.com> Co-authored-by: Antoine RICHARD <antoiner@nvidia.com> Co-authored-by: isaaclab-review-bot[bot] <270793704+isaaclab-review-bot[bot]@users.noreply.github.com>
CommandManager terms call self._env.extras during reset().
LeappDeploymentEnv bypasses the standard ManagerBasedRLEnv init path and
never initializes this dict, causing an AttributeError on the first
reset() call.
Add self.extras: dict = {} to __init__ to fix the crash.
# Description
<!--
Thank you for your interest in sending a pull request. Please make sure
to check the contribution guidelines.
Link:
https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html
💡 Please try to keep PRs small and focused. Large PRs are harder to
review and merge.
-->
Please include a summary of the change and which issue is fixed. Please
also include relevant motivation and context.
List any dependencies that are required for this change.
Fixes # (issue)
<!-- As a practice, it is recommended to open an issue to have
discussions on the proposed pull request.
This makes it easier for the community to keep track of what is being
developed or added, and if a given feature
is demanded by more than one party. -->
## Type of change
<!-- As you go through the list, delete the ones that are not
applicable. -->
- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (existing functionality will not work without user
modification)
- Documentation update
## Screenshots
Please attach before and after screenshots of the change if applicable.
<!--
Example:
| Before | After |
| ------ | ----- |
| _gif/png before_ | _gif/png after_ |
To upload images to a PR -- simply drag and drop an image while in edit
mode and it should upload the image directly. You can then paste that
source into the above before/after sections.
-->
## Checklist
- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
<!--
As you go through the checklist above, you can mark something as done by
putting an x character in it
For example,
- [x] I have done this task
- [ ] I have not done this task
-->
Fixes some nvbugs: - NVBug 6141356: added `pip` to `environment.yml` so aarch64 conda envs (e.g. DGX Spark) get pip seeded, which conda-forge does not pull in transitively. - NVBug 6129956: wrapped the four command blocks in the kitless install page in synced Linux / Windows tab-sets so Windows users have copy-paste commands. - NVBug 5984996: `isaaclab.bat` and `isaaclab.sh` now warn when `_isaac_sim` is present but `setup_conda_env.bat` is missing; shipping the file is a Sim-side follow-up. - NVBug 6125054 (follow-up): moved `viser` to an opt-in extra in `python_packages.toml` since `viser>=1.0.16` pulls `websockets>=13.1` which collides with `isaacsim==6.0.0.0`'s `websockets==12.0`. Also fixed a broken link surfaced by the docs link checker: `https://robosuite.ai/` (404) -> `https://robosuite.ai/docs/overview.html` in `ecosystem.rst`. Drive-by: removed `numpy` from `autodoc_mock_imports` in `docs/conf.py` since it's already in `docs/requirements.txt`; fixes pre-existing `Build Latest Docs` regression from PR#5082. ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] I have added a changelog fragment under `source/<pkg>/changelog.d/` for every touched package (do **not** edit `CHANGELOG.rst` or bump `extension.toml` since CI handles that) - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Signed-off-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…saac-sim#5566) ## Summary - `mujoco` and `mujoco-warp` are already declared under Newton's `[sim]` optional-dependency extra. Re-listing them in IsaacLab's `setup.py` was redundant and pinned them at IsaacLab's chosen versions instead of Newton's. - The pins also lived in `source/isaaclab/setup.py`'s top-level `INSTALL_REQUIRES`, so users installing only the PhysX or Kit backends were forced to pull MuJoCo even though nothing in `isaaclab` core imports it. - Switch the Newton spec to `newton[sim] @ git+...` and remove the direct pins from both setup.py files plus the wheel builder manifest. Newton becomes the single source of truth for those versions. ## Verification - `grep -rn "import mujoco\|import mujoco_warp\|MjModel\|MjData"` across the repo: zero direct usages. The Newton backend uses `newton.solvers.SolverMuJoCo` (transitive). MJCF asset import goes through Isaac Sim's `isaacsim.asset.importer.mjcf`, not the `mujoco` Python package. - Newton's [`pyproject.toml`](https://github.com/newton-physics/newton/blob/v1.2.0rc2/pyproject.toml) `[sim]` extra: `mujoco~=3.8.0`, `mujoco-warp>=3.8.0.1,~=3.8.0`. Newton's compatible-release spec already covers the patch versions IsaacLab was hard-pinning. - All other install pathways (`./isaaclab.sh -i`, `cli/commands/install.py`, `docker/Dockerfile.*`, `environment.yml`, root `pyproject.toml`, per-package `pyproject.toml`) read deps from these three files; no other version pins exist. - `./isaaclab.sh -f` passes. ## Test plan - [ ] Fresh `./isaaclab.sh -i --install newton` install resolves Newton, `mujoco`, and `mujoco-warp` transitively. - [ ] Smoke-test a Newton-backed task to confirm the MuJoCo Warp solver still loads. - [ ] Wheel build with `tools/wheel_builder` produces wheels with the same set of MuJoCo packages as before. --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…sim#5433) (isaac-sim#5437) ## Summary Adds Newton backend support for \`Isaac-Shadow-Hand-Over-Direct-v0\` (multi-agent MAPPO/IPPO). Selectable via \`--preset newton\` / Hydra preset resolution; PhysX path unchanged. The headline calibration finding: Newton needs \`ImplicitActuatorCfg(stiffness=20.0, damping=2.0)\` on the Shadow Hand fingers — vs PhysX's \`1.0/0.1\` on fingers and \`5.0/0.5\` on wrists — because PhysX layers \`fixed_tendons_props(limit_stiffness=30, damping=0.1)\` and runs \`solver_position_iteration_count=8\` per substep. Both amplify the effective torque per unit nominal gain. Newton's MJWarp implicit-PD path has neither, so larger nominal gains are needed for comparable joint authority. With the bump, MAPPO mean reward at iter 200 / 2048 envs goes from ~27 (no catch learned) to ~777, vs the PhysX baseline of ~247. ## Stack Builds on top of: - **isaac-sim#5433** [Newton] Rename per-env labels in physics replication — required for Shadow Hand fixed tendons to parse correctly under Newton. After isaac-sim#5433 merges, this PR's diff vs develop drops to the 3 shadow-hand-specific files. ## What this PR does ### Newton port wiring (\`shadow_hand_over_env_cfg.py\`) The Newton variant of the Shadow Hand articulation is built as a **delta of the single-agent \`ShadowHandRobotCfg.newton_mjwarp\`** (cross-task import from \`direct/shadow_hand\`), parameterized per-robot \`prim_path\` / \`init_pos\` / \`init_rot\`. Reuses the single-agent's USD path, \`rot\` reapplication workaround, effort limits, and joint regex. Two \`ImplicitActuatorCfg\` overrides on top of the single-agent cfg: * **\`fingers\`** (wrist + per-finger joints): \`stiffness=20.0\` / \`damping=2.0\`. The catch-task gain calibration fix. * **\`distal_passive\`** (the four \`robot0_(FF|MF|RF|LF)J0\` joints): \`stiffness=10.0\` / \`damping=0.1\`. The Newton USD bakes \`stiffness=286 / damping=57\` on these joints from the MJCF→USD translation (which fights the \`MjcTendon\` coupling and bounces the ball). \`stiffness=10\` keeps the joints near-passive while the tendon constraint dominates. PhysX uses tendon coupling on these joints directly and does not need an analogous override. \`PresetCfg\` subclasses follow the established \`physx\`/\`newton_mjwarp\`/\`default=physx\` pattern — same shape as the single-agent Shadow Hand port already on develop. Newton \`ObjectCfg\` drops PhysX-only \`rigid_props\` knobs (per-shape solver iterations, sleep thresholds, max depenetration velocity, custom physics material). Newton scene cloning sets \`clone_in_fabric=False\`. ### Backend portability fix (\`shadow_hand_over_env.py\`) One line: \`self.right_hand.root_view.get_dof_limits()\` → \`self.right_hand.data.joint_limits\`. \`root_view\` is PhysX-only; \`data.joint_limits\` is the backend-portable accessor available on both PhysX and Newton articulations. ### Drift alignment with develop * Newton-preset slot name \`newton_mjwarp\` (matches develop's current convention). * \`PhysxCfg(bounce_threshold_velocity=0.2, gpu_max_rigid_contact_count=2**23, gpu_max_rigid_patch_count=2**23)\` — matches single-agent Shadow Hand's contact-buffer sizing for 2048-env scale. ## Numbers (200 iter / 2048 envs / seed 42 / MAPPO) Captured from tfevents in \`~/workspaces/IsaacLab/logs/skrl/shadow_hand_over/\`: | Setting | Stiffness | Damping | Reward (mean) | Catch learned? | |---|---:|---:|---:|:---:| | PhysX baseline | 1.0 (5.0 wrist) | 0.1 (0.5 wrist) + tendon=30/0.1 | **246.7** | yes | | Newton, develop default | 1.0 | 0.1 | 23.4 | **no** | | Newton, pinned default | 1.0 | 0.1 | 27.7 | **no** | | Newton, h1 probe | 50.0 | 5.0 | 617.8 | yes | | **Newton, this PR** | **20.0** | **2.0** | **777.1** | yes | 20/2 was chosen because it stays closer to the nominal effort-limit budget while still providing enough control authority. Anything in roughly \`[10, 50]\` works. ## Test plan - [x] PhysX 200-iter baseline at 2048 envs (mean 246.7). - [x] Newton 200-iter at stiffness 20/2 — mean 777.1, catch learned. - [x] Newton 200-iter at stiffness 50/5 cross-check — mean 617.8, catch learned. - [x] \`./isaaclab.sh -f\` clean (pre-commit hooks). - [x] Changelog fragment under \`source/isaaclab_tasks/changelog.d/jichuanh-shadow-hand-newton-parity.minor.rst\` (CI-driven version bump on merge; no per-PR \`extension.toml\` edit). ## Out of scope (follow-ups) - **\`EventCfg\` not wired into the env class.** The multi-agent's \`EventCfg\` is defined but never referenced by \`ShadowHandOverEnvCfg.events\` — single-agent's pattern (\`events: ShadowHandEventCfg = ShadowHandEventCfg()\` with PhysX/Newton variants) hasn't been ported. Independent feature add; not a parity blocker. - **Migrating Shadow Hand Newton USD to the \`mujoco-usd-converter\`-produced asset in \`newton-physics/newton-assets/shadow_hand/usd_structured/\`.** That asset uses \`MjcActuator + MjcTendon\` natively (no baked stiffness=286 problem). Switching would let the \`distal_passive\` override be deleted. Requires Nucleus/S3 asset migration + matching the right-hand asset (newton-assets has only left); separate work. - **Behavior-level parity** beyond shaped reward (catch rate, drop rate, ball-trajectory smoothness) is left for a follow-up evaluation.
Bumped packages: - isaaclab: 5.1.1 → 5.2.0 - isaaclab_mimic: 1.2.6 → 1.2.7 - isaaclab_newton: 0.8.1 → 0.9.0 - isaaclab_ov: 0.1.8 → 0.1.9 - isaaclab_ovphysx: 0.1.4 → 1.0.0 - isaaclab_physx: 0.6.4 → 0.7.0 - isaaclab_tasks: 1.5.38 → 1.6.0
# Description <!-- Thank you for your interest in sending a pull request. Please make sure to check the contribution guidelines. Link: https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html 💡 Please try to keep PRs small and focused. Large PRs are harder to review and merge. --> Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. Fixes # (issue) <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (existing functionality will not work without user modification) - Documentation update ## Screenshots Please attach before and after screenshots of the change if applicable. <!-- Example: | Before | After | | ------ | ----- | | _gif/png before_ | _gif/png after_ | To upload images to a PR -- simply drag and drop an image while in edit mode and it should upload the image directly. You can then paste that source into the above before/after sections. --> ## Checklist - [ ] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task -->
…ents (isaac-sim#5611) ## Summary `Build Latest Docs` is failing on every open PR with: ``` source/isaaclab/docs/CHANGELOG.rst:35: ERROR: Unexpected indentation. [docutils] build finished with problems, 1 warning (with warnings treated as errors). ``` (failing job: https://github.com/isaac-sim/IsaacLab/actions/runs/25847575509/job/75946304877) The 2026-05-14 auto-version-bump (`b65a1ac2b73`) compiled fragment `source/isaaclab/changelog.d/jichuanh-ik-newton-compat-mvp.minor.rst` verbatim into the new `5.2.0` block. That fragment contained a flush-left paragraph inside the `Added` bullet list, which Sphinx `-W` rejects. ## Fix 1. **Repromote the orphan paragraph to a `*` bullet** in `source/isaaclab/docs/CHANGELOG.rst` so the bullet list under `Added` stays well-formed. 2. **Catch the same shape in future fragments**: `Fragment.validate()` now scans every section body and rejects any non-blank line that is neither a `* ` bullet start nor a continuation (leading whitespace). The error message points back at the exact offending line so the contributor sees it in the `Changelog Fragment Check` PR gate output before merge. Replayed the new check against all 131 historical fragments — it flags exactly one, the one that caused this incident. Zero false positives elsewhere. ## Test plan - [x] `pytest tools/changelog/test/` — 83 pass (24 prior validate tests + 1 new orphan-paragraph fixture test). - [x] Validator on the historical bad fragment returns the new orphan-paragraph error message. - [x] `pre-commit run` on all touched files — clean. - [x] `Build Latest Docs` will pass on this PR (the `Unexpected indentation` line is gone). ## Files - `source/isaaclab/docs/CHANGELOG.rst` — bullet-prefix the orphan paragraph. - `tools/changelog/cli.py` — orphan-paragraph rejection in `Fragment.validate()`. - `tools/changelog/test/test_validate.py` + `test/invalid_content/3004.rst` — fixture + test for the new rule. - `source/isaaclab/changelog.d/jichuanh-fix-docs-changelog-indentation.skip` — satisfies the gate (CHANGELOG-only edit, no user-visible entry needed).
…saac-sim#5609) # Description When calculating the "look-at" quaternion for a camera, an **orthonormal** rotation matrix is first calculated using the camera's eye position, look-at target, and world up vectors: - `forward = target - eye` *("camera forward")* - `camera_z = -normalize(forward)` *("camera backward")* - `camera_x = world_up × camera_z ` *("camera right")* - `camera_y = camera_z × camera_x` *("camera up")* - return `R = [camera_x, camera_y, camera_z ]` *(OpenGL convention)* However, if `forward` is parallel to `world_up` then the cross product `camera_x` is zero, leading to a **singular** non-invertible matrix returned from `create_rotation_matrix_from_view()`. Then `quat_from_matrix()` would silently convert this to a non-unit quaternion and return this garbage back to the caller. This change fixes both issues as follows: **`create_rotation_matrix_from_view`:** - When the cross product collapses, it falls back on the world X-axis as an alternate `world_up` vector and re-calculates the matrix. - Previously, `camera_y × camera_z` was used as the fallback, which was already zero due to the problem described above. - X-axis is guaranteed to be perpendicular to `world_up` since `world_up` is restricted to Y or Z. - When truly undefined input is provided (`eye == target` or non-finite values) it now returns per-row `NaN` that the caller can detect and handle. **`quat_from_matrix`:** - Now returns `NaN` when the input is not a valid rotation matrix (singular, reflection, or non-orthonormal). All callers in IsaacLab have been updated to detect `NaN` where appropriate and fail gracefully, or avoid passing degenerate input altogether where possible. Added 11 new unit tests and removed the 0.1 x-nudge workaround from the integration tests (PR isaac-sim#5470 and isaac-sim#5380) ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there
Bumped packages: - isaaclab: 5.2.0 → 5.2.1 - isaaclab_newton: 0.9.0 → 0.9.1 - isaaclab_physx: 0.7.0 → 0.7.1
# Description This PR is based on and includes the changes from isaac-sim#5620, then adds one CI fix on top: it unsets `HUB__ARGS__DETECT_ONLY` inside the Docker test container before running Isaac Lab commands. Some base images set this flag, which prevents OmniHub from starting and makes cold Nucleus asset retrieval fall back to slow repeated retries. This was reproduced from the failing Actions job: https://github.com/isaac-sim/IsaacLab/actions/runs/25904143763/job/76158743634 The affected `test_rsl_rl_export_flow.py` Dexsuite Kuka-Allegro export timed out at 600 s with the flag set, then completed in about 73 s with the flag unset after clearing the local KukaAllegro mirror. Fixes # N/A ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Screenshots N/A - CI-only change. ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation (N/A - CI-only change) - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works (validated with the affected Docker export test) - [x] I have added a changelog fragment under `source/<pkg>/changelog.d/` for every touched package (N/A for the CI-only commit; isaac-sim#5620 carries its own changelog fragments) - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there ## Test Plan - `./isaaclab.sh -f` - Docker reproduction with `HUB__ARGS__DETECT_ONLY=true`: `test_export_flow[Isaac-Dexsuite-Kuka-Allegro-Reorient-v0]` timed out after 600 s. - Docker reproduction with `HUB__ARGS__DETECT_ONLY` unset after clearing the KukaAllegro mirror: `test_export_flow[Isaac-Dexsuite-Kuka-Allegro-Reorient-v0]` passed in 72.75 s. --------- Co-authored-by: Piotr Barejko <pbarejko@nvidia.com>
…c-sim#5613) ## Summary - Training/playing the drone-ARL skrl tasks (`Isaac-TrackPositionNoObstacles-ARL-Robot-1-*`, `Isaac-Navigation-3DObstacles-ARL-Robot-1-*`) crashed at `Runner(env, agent_cfg)` with `AttributeError: 'NoneType' object has no attribute 'shape'` in `LazyLinear.initialize_parameters`. - Root cause: the two drone-ARL skrl YAMLs declare `input: STATES` for the policy and value networks. In skrl 2.0 the model instantiator now resolves `STATES` against `state_space`, which is `None` for single-agent envs, so the generated `compute()` calls `self.mlp_container(None)` and the first `LazyLinear` raises on `input.shape[-1]`. - Switched both configs to `input: OBSERVATIONS`, matching every other single-agent skrl config in IsaacLab. The two multi-agent MAPPO configs that legitimately use `STATES` (`direct/shadow_hand_over`, `direct/cart_double_pendulum`) are unaffected. ## Files changed - `source/isaaclab_tasks/.../drone_arl/track_position_state_based/config/arl_robot_1/agents/skrl_ppo_cfg.yaml` - `source/isaaclab_tasks/.../drone_arl/navigation/config/arl_robot_1/agents/skrl_rough_ppo_cfg.yaml` - `source/isaaclab_tasks/changelog.d/proth-fix-skrl-drone-arl-states-input.rst` (patch fragment) ## Test plan - [x] Reproduced the exact stack trace (`<string>` line 48 → `container.py:253` → `lazy.py:263` → `linear.py:323`) with `input: STATES` using a standalone skrl `shared_model` instantiation against a single-agent obs/action space. - [x] After the YAML change, the same standalone instantiation loads both edited YAMLs from disk and successfully runs `init_state_dict(role='policy')` and `init_state_dict(role='value')` on a `SharedModel`. - [x] `./isaaclab.sh -f` (pre-commit) passes locally. - [ ] Full end-to-end `train.py`/`play.py` smoke test against: - `Isaac-TrackPositionNoObstacles-ARL-Robot-1-v0` - `Isaac-TrackPositionNoObstacles-ARL-Robot-1-Play-v0 --use_pretrained_checkpoint` - `Isaac-Navigation-3DObstacles-ARL-Robot-1-v0` Co-authored-by: Kelly Guo <kellyg@nvidia.com>
# Description Adds a permanent, decoupled CI entry-point for replaying captured teleop sessions against an Isaac Lab environment. Replaces the runtime patch the `teleop-cicd` pipeline currently applies to `scripts/environments/teleoperation/teleop_se3_agent.py` so the user-journey script is no longer mutated at CI time. Fixes # (issue) <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change - New feature (non-breaking change which adds functionality) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Co-authored-by: Andrei Aristarkhov <aaristarkhov@nvidia.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com>
# Description Fixed rlinf install docs to run RLinf RL posting training ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task -->
…ual environments (isaac-sim#5623) # Description This PR refactors the reinforcement learning train/play scripts into unified entry points while preserving the existing library folder structure and adding a lightweight `uv` workflow for fresh source checkouts. The main changes are: - Added unified RL entrypoints: - `scripts/reinforcement_learning/train.py --library <library>` - `scripts/reinforcement_learning/play.py --library <library>` - Added library-specific implementation files under the existing library folders, for example: - `scripts/reinforcement_learning/rsl_rl/train_rsl_rl.py` - `scripts/reinforcement_learning/rsl_rl/play_rsl_rl.py` - Kept the old per-library `train.py` and `play.py` scripts intact, with deprecation warnings and migration examples. - Added shared RL entrypoint utilities in `scripts/reinforcement_learning/common.py`. - Added direct Isaac Lab CLI commands: - `./isaaclab.sh train --library <library> ...` - `./isaaclab.sh play --library <library> ...` - Kept bare script aliases for `./isaaclab.sh -p train.py ...` and `./isaaclab.sh -p play.py ...`. - Added Python package entry points so installed environments can run: - `train --library <library> ...` - `play --library <library> ...` - Added a root source-checkout `pyproject.toml` project so a fresh clone can run kitless Newton training with: - `uv run train --library rsl_rl --task Isaac-Cartpole-Direct-v0 presets=newton_mjwarp --num_envs 4096` - Pinned the source-checkout `uv` environment to the same PyTorch family used by the Isaac Lab installer to avoid CUDA stack churn when users switch between `uv run` and `./isaaclab.sh`. - Updated docs, tests, tools, and pretrained checkpoint helpers to use the unified train/play entrypoints. - Fixed CLI Python discovery so `./isaaclab.sh` prefers an active or repo-local virtual environment before falling back to system Python. - Fixed `./isaaclab.sh --install` in uv-created virtual environments that do not include the `pip` module by using `uv pip` for venv-targeted pip operations. Motivation: The previous RL scripts duplicated substantial train/play setup logic across libraries. This made behavior harder to keep consistent and increased maintenance cost when updating shared functionality. The new structure keeps library-specific logic in each library folder while centralizing shared dispatch and common helpers. The `uv` workflow gives users a fast path from a fresh clone to kitless Newton training without manually creating an environment first. Isaac Sim / Kit workflows, including PhysX, continue to use the existing full installation path. Dependencies: No new required runtime dependencies are added to Isaac Lab packages. The root source-checkout `pyproject.toml` describes the local development environment used by `uv run`. Fixes # N/A ## Type of change - New feature (non-breaking change which adds functionality) - Documentation update ## Screenshots Not applicable. ## Validation Ran: - `uv lock` - `uv lock --check` - `uv run --frozen train --help` - `./isaaclab.sh --install` - `./isaaclab.sh -p -m pytest source/isaaclab/test/cli/test_install.py -q` - `./isaaclab.sh -p -m pytest source/isaaclab/test/cli/test_install.py::TestGetPipCommand source/isaaclab/test/cli/test_install.py::TestExtractPythonExe -q` - Help smoke tests for unified train/play entrypoints and `./isaaclab.sh -p train.py --help` / `./isaaclab.sh -p play.py --help` ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…ac-sim#5523) (isaac-sim#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 isaac-sim#5523** (\"[Newton] Bump Newton pin to v1.2.0rc2\"). After isaac-sim#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 isaac-sim#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>
…c-sim#5394) # Description <!-- Thank you for your interest in sending a pull request. Please make sure to check the contribution guidelines. Link: https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html 💡 Please try to keep PRs small and focused. Large PRs are harder to review and merge. --> Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. In Isaac Sim, we have added more capabilities to handle joint presets, fixed joints, and other properties to the importers, so we can simplify the isaac lab importer workflow. Fixes # (issue) <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (existing functionality will not work without user modification) - Documentation update ## Screenshots Please attach before and after screenshots of the change if applicable. <!-- Example: | Before | After | | ------ | ----- | | _gif/png before_ | _gif/png after_ | To upload images to a PR -- simply drag and drop an image while in edit mode and it should upload the image directly. You can then paste that source into the above before/after sections. --> ## Checklist - [ ] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…m#5587) ## Summary Adds typed preset selection via Hydra-style tokens — `physics=NAME` / `renderer=NAME` / `presets=NAME[,...]` — that fold into the existing `presets=<csv>` Hydra-decorator flow. Makes `--task=X --help` list the actual `PresetCfg` variants present in that task's env_cfg, bucketed by typed target. Adopted in all 16 Hydra-using scripts (`rl_games/sb3/skrl/rsl_rl` train+play, `environments/*`, `benchmarks/*`, `sim2sim_transfer`, `leapp/rsl_rl/export`). ## API shape ```python parser = argparse.ArgumentParser(...) # ... script-specific args ... add_launcher_args(parser) args_cli, hydra_args = setup_preset_cli(parser) sys.argv = [sys.argv[0]] + hydra_args ``` `setup_preset_cli` returns `(args, hydra_argv)` without mutating `sys.argv`. It registers no argparse flags for preset selection — the typed selectors are recognized as Hydra-style tokens in the `parse_known_args` remainder and folded into `hydra_argv[0]` as a single `presets=<csv>` token. ## Grammar ``` python train.py --task=X physics=newton_mjwarp renderer=newton_renderer presets=albedo,depth ``` - `physics=NAME` — typed selector for `PhysicsCfg` variants - `renderer=NAME` — typed selector for `RendererCfg` variants - `presets=NAME[,NAME,...]` — broadcast: applied to every matching `PresetCfg` All three fold into one `presets=<csv>` token: `presets=newton_mjwarp,newton_renderer,albedo,depth`. The grammar matches Hydra's, so the same line can carry path-targeted overrides (`env.sim.dt=0.001`) that flow through untouched. ## Namespace contract No preset selector is registered with argparse, so the parsed `args` namespace gains no `physics` / `renderer` / `presets` attribute. AppLauncher's name-based forwarding (`set(_SIM_APP_CFG_TYPES) & set(vars(args))`, `app_launcher.py:681`) therefore cannot pick up a preset value and push it into `SimulationApp.config` — the historical `--renderer` → `config["renderer"]` → `None.lower()` crash class is structurally impossible. Two regression tests lock the contract. ## Help text layout `--task=Isaac-Cartpole-v0 --help` renders each selector with its available variants inline directly below it (bullets aligned with the description column): ``` preset selection: Select named PresetCfg alternatives via Hydra-style overrides (key=value, no leading dashes): physics=NAME (typed) selects a PhysicsCfg variant. Available: - newton_kamino - newton_mjwarp - physx renderer=NAME (typed) selects a RendererCfg variant. Available: (none) presets=NAME[,NAME,...] broadcast: applied to every matching PresetCfg. Available: (none) Hydra also accepts path-targeted overrides like env.sim.physics=NAME. ``` Typed variants appear only under their own typed selector. The `presets=` listing shows only DOMAIN-bucket variants (cfgs whose type doesn't subclass any typed target's base class). Without `--task`, each row shows just the selector + description and the section adds a `Pass --task=X` hint on its own paragraph. ## Test plan - [x] `pytest source/isaaclab_tasks/test/test_preset_cli.py` — 24 tests pass. Coverage: enum wiring, token folding/dedupe/passthrough, `_ArgvHelper` semantics, type-based bucketing, all four help-text branches (parametrized), no-`sys.argv`-mutation contract, namespace-clean contract, AppLauncher intersection contract, `hydra_args[0]` preserves the `presets=` token for benchmark telemetry. - [x] `pytest source/isaaclab_tasks/test/test_hydra.py` — 76 tests pass; legacy-alias `FutureWarning` behavior unchanged. - [x] `pre-commit` clean. - [x] Manual: `--task=Isaac-Cartpole-v0 --help` and `--task=Isaac-Cartpole-RGB-Camera-Direct-v0 --help` render correctly. - [x] Manual: `physics=newton_mjwarp renderer=newton_renderer presets=albedo` folds into one `presets=<csv>` token at `hydra_argv[0]`. - [x] Manual: unknown name → grouped error from resolver; legacy alias `newton` → `FutureWarning` and resolves to `newton_mjwarp`. --------- Co-authored-by: ooctipus <zhengyuz@nvidia.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com>
## Summary Bumps the Newton pin from `v1.2.0rc2` (current develop) directly to the [`v1.2.0` stable release](https://github.com/newton-physics/newton/releases/tag/v1.2.0) across all five pin sites, keeping the canonical `newton[sim] @ git+...` form everywhere. Per Kelly Guo's suggestion: skip the rc bump and go straight to stable. Upstream published `v1.2.0` on 2026-05-12. **Alternative**: [isaac-sim#5614](isaac-sim#5614) (rc3 bump) — pick whichever target based on CI signal. This one is the most forward target. > Branch is still named `jichuanh/newton-1.2.0rc4-bump` from when this PR was originally proposing rc4 — the branch name doesn't match the current target but the diff is correct. Force-pushing the rename would close/reopen the PR, which adds noise without changing the artifact. ## What's new in Newton v1.2.0 vs v1.2.0rc2 Full release notes: [newton-physics/newton release v1.2.0](https://github.com/newton-physics/newton/releases/tag/v1.2.0). Notable IsaacLab-relevant fixes: - [newton-physics/newton#2651](newton-physics/newton#2651) — MPR/GJK no longer assumes convex hulls are centered around the origin. - [newton-physics/newton#2703](newton-physics/newton#2703) — Kamino FK solver performance. - [newton-physics/newton#2721](newton-physics/newton#2721) — HDR color output for tiled camera sensors. - [newton-physics/newton#2743](newton-physics/newton#2743) — Collada textures in URDF import. - [newton-physics/newton#2823](newton-physics/newton#2823) — Gravity-data device allocation in Kamino (multi-GPU). - [newton-physics/newton#2632](newton-physics/newton#2632) — CollisionPipeline small fixes. - [newton-physics/newton#2734](newton-physics/newton#2734) — `DelassusOperator` attribute refactor. Not used in IsaacLab source today (verified by grep), no adapt needed. - SolverMuJoCo fixes: planar meshes, contact-anchor computation, distance conversion. ## Required dep bumps None on the IsaacLab side. The `mjwarp 3.8.0.1 → 3.8.0.3` bump flows in transitively through `newton[sim]`, since [isaac-sim#5566](isaac-sim#5566) dropped IsaacLab's explicit `mujoco` / `mujoco-warp` pins. `warp-lang` stays at `1.13.0` (set by [isaac-sim#5523](isaac-sim#5523)). ## Pins updated | File | Change | |---|---| | `source/isaaclab_newton/setup.py` | `v1.2.0rc2` → `v1.2.0` | | `source/isaaclab_physx/setup.py` | `v1.2.0rc2` → `v1.2.0` | | `source/isaaclab_visualizers/setup.py` | 3× `v1.2.0rc2` → `v1.2.0` | | `tools/wheel_builder/res/python_packages.toml` | `v1.2.0rc2` → `v1.2.0` | ## Test plan - [x] Pre-commit clean. - [ ] CI smoke verifies clean install picks up `newton 1.2.0` and downstream `mjwarp 3.8.0.3`.
…isaac-sim#5596) # Make locomanipulation SDG GR00T flow runnable without flash-attn ## Summary Two small fixes that let users finetune and roll out the locomanipulation SDG GR00T policy on hardware where `flash-attn` is unavailable (e.g. Blackwell, or any environment where the wheel fails to build). ## Changes - **`scripts/imitation_learning/locomanipulation_sdg/gr00t/no_flash_attn.patch`** (new): patch against the Isaac-GR00T repo that switches the bundled Eagle 2.5 VL model from `flash_attention_2` to PyTorch SDPA, and guards the RADIO vision module's `flash_attn` imports so the package becomes importable without flash-attn installed. SigLIP path works; RADIO path is unsupported without flash-attn (documented in the patch). - **`docs/source/overview/imitation-learning/humanoids_imitation.rst`**: adds a note in the GR00T install section explaining when to apply the patch (build failure, or `RuntimeError: FlashAttention only supports Ampere GPUs or newer`) and how to apply it from the sibling Isaac-GR00T checkout. - **`scripts/imitation_learning/locomanipulation_sdg/gr00t/rollout_policy.py`**: override `env_cfg.recorders` with `ActionStateRecorderManagerCfg()` so the rollout doesn't try to record `env._locomanipulation_sdg_output_data`, which is only populated by the data-generation state machine in `generate_data.py` and is absent during policy rollout. Without this, the recorder raises `AttributeError` on the first pre-step. <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) ## Screenshots Please attach before and after screenshots of the change if applicable. <!-- Example: | Before | After | | ------ | ----- | | _gif/png before_ | _gif/png after_ | To upload images to a PR -- simply drag and drop an image while in edit mode and it should upload the image directly. You can then paste that source into the above before/after sections. --> ## Checklist - [ ] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
# Description Background: The _cubric.py ctypes shim was pinned to IAdapter v0.1 vtable offsets, but newer Kit builds ship v0.2 — compute calls were silently landing on unbind, disabling cubric's GPU transform hierarchy propagation. carb accepts the version mismatch with only a stderr warning. Originally, this change updated offsets to the v0.2 layout, requested v0.2 from the framework, and added a runtime InterfaceDesc check that refused to acquire on any unexpected version. The kit team is fixing the ABI-breaking semver contract violation upstream, so it won't actually make it into a release. So the pinned version in Isaac Lab remains on v0.1 but keeps the validation code as a safety net. This problem will go away once we have official python bindings for cubric in a future kit release. If usdrt eventually exposes the required `eRigidBody` options via the `IFabricHierarchy` API then that would massively simplify the implementation of newton manager. Will pursue a feature request. ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation *(N/A)* - [ ] My changes generate no new warnings *(New warnings on ABI mismatch are intentional)* - [ ] I have added tests that prove my fix is effective or that my feature works *(N/A - spoofing kit versions for unit test would be non-trivial; verified manually)* - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
## Summary * Fixed an invalid inline `::` comment in the Windows batch code block on the kit-less installation page. In Windows batch, `::` only works as a comment at the start of a line — when placed inline after a command, the tokens are passed as arguments, causing a runtime error. Moved the shorthand hint (`or: isaaclab.bat -i`) to its own comment line. ## Test plan - [ ] Verify the rendered docs page shows the corrected batch snippet. - [ ] Confirm the `isaaclab.bat --install` command runs without unexpected extra arguments on Windows. Co-authored-by: Kelly Guo <kellyg@nvidia.com>
# Description <!-- Thank you for your interest in sending a pull request. Please make sure to check the contribution guidelines. Link: https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html 💡 Please try to keep PRs small and focused. Large PRs are harder to review and merge. --> This PR adds a deterministic training path and documentation for Isaac Lab RL workflows. - Added apps/isaaclab.python.headless.determinism.kit as a deterministic headless rendering experience. - Updated scripts/reinforcement_learning/rl_games/train.py to add opt-in --deterministic and use configure_seed(env_cfg.seed, args_cli.deterministic). - Updated docs/source/features/reproducibility.rst to document --experience isaaclab.python.headless.determinism.kit and clarify that strict PyTorch determinism is currently exposed only for RL-Games. Test command example: ./isaaclab.sh -p scripts/reinforcement_learning/rl_games/train.py --task Isaac-Cartpole-RGB-v0 --enable_cameras --headless --seed 42 --max_iteration 20 **--deterministic --experience isaaclab.python.headless.determinism.kit** Fixes # (issue) <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> isaac-sim#3505 Non-reproducible training results in vision-based tasks with identical seeds ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) ## Screenshots | Before | After | | ------ | ----- | | <img width="200" height="250" alt="Before" src="https://github.com/user-attachments/assets/57b52d82-ed32-4f79-8ac2-db19b32df54a" /> | <img width="200" height="250" alt="After" src="https://github.com/user-attachments/assets/5da0b220-7fef-445a-8efb-f0e1c6dab6a3" /> | <!-- Example: | Before | After | | ------ | ----- | | _gif/png before_ | _gif/png after_ | To upload images to a PR -- simply drag and drop an image while in edit mode and it should upload the image directly. You can then paste that source into the above before/after sections. --> ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> --------- Co-authored-by: r-schmitt <139814266+r-schmitt@users.noreply.github.com> Co-authored-by: nvsekkin <72572910+nvsekkin@users.noreply.github.com> Co-authored-by: vidurv-nvidia <vidurv@nvidia.com> Co-authored-by: ooctipus <zhengyuz@nvidia.com> Co-authored-by: Yuchen Deng <yuchenkit@gmail.com> Co-authored-by: Kelly Guo <kellyg@nvidia.com> Co-authored-by: isaaclab-bot[bot] <282401363+isaaclab-bot[bot]@users.noreply.github.com> Co-authored-by: hujc <jichuanh@nvidia.com> Co-authored-by: Antoine RICHARD <antoiner@nvidia.com>
## Description Fixes `OVRTXRenderer` crash on multi-GPU systems when `sim.device` is not `cuda:0`. **Root cause:** A hardcoded `DEVICE = "cuda:0"` constant in `ovrtx_renderer_kernels.py` was imported and used for all Warp kernel launches and buffer allocations. Additionally, `AttributeBinding.map()` calls used `device_id=0`, pinning attribute mapping to GPU 0 regardless of the simulation device. **Fix:** - Remove the `DEVICE` constant and use `self._device` (set from `CameraRenderSpec.device`) for all Warp operations (11 locations) - Add `_device_id` property to extract the CUDA device index from the device string - Pass `device_id=self._device_id` to `AttributeBinding.map()` calls (2 locations: object binding and camera binding) **Note on `RenderVarOutput.map()` calls:** These remain unchanged (`device=Device.CUDA` only) because the OVRTX C API for render output mapping (`ovrtx_map_output_description_t`) does not accept a `device_id` parameter — the output is inherently mapped on whichever GPU OVRTX rendered on. **Total:** 13 hardcoded GPU-0 references fixed (11 Warp + 2 AttributeBinding). This is the same bug class fixed for `NewtonRenderer` in isaac-sim#5019 — OVRTX was not updated at that time. ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Checklist - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog and added my name to the [`CONTRIBUTORS.md`](https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md) or my organization to the [`CONTRIBUTORS.md`](https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md) list --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
# Description * Added :func:`~isaaclab.cloner.cloner_utils.is_homogeneous` to detect whether a :class:`~isaaclab.cloner.ClonePlan` assigns every environment from every source (a homogeneous clone mask). * Fixed cloned environments disappearing from tiled camera output if :attr:`~isaaclab_ov.renderers.OVRTXRendererCfg.use_ovrtx_cloning` is set to ``True``, by correcting scene-partition attribute creation on env roots and cameras. * Renamed the ``use_cloning`` field on :class:`~isaaclab_ov.renderers.OVRTXRendererCfg` to ``use_ovrtx_cloning``. Changed its default value to ``True``. This will bring notable speedup for the total startup time (Launch to Train), esp. for large-scale env setups. On Isaac-Dexsuite-Kuka-Allegro-Lift-v0 with 1024 env clones, the total startup time dropped from ~78s to ~43s. Note that if ``use_ovrtx_cloning`` is enabled but the env setup is heterogeneous, the OVRTX renderer will disable the internal cloning path and logs a warning, exporting the full multi-environment stage instead (same effect as setting ``use_ovrtx_cloning`` to ``False`` for that run). ## Type of change - Bug fix (non-breaking change which fixes an issue) ## Screenshots Please attach before and after screenshots of the change if applicable. <!-- Example: | Before | After | | ------ | ----- | | _gif/png before_ | _gif/png after_ | To upload images to a PR -- simply drag and drop an image while in edit mode and it should upload the image directly. You can then paste that source into the above before/after sections. --> ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [x] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> --------- Co-authored-by: Kelly Guo <kellyg@nvidia.com>
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
Drastic rewrite of OVPhysX
ArticulationandArticulationDataso they follow the same shape as the post-refactor OVPhysXRigidObject(PR isaac-sim#5426 on isaac-sim/IsaacLab), with the API surface mirroringNewton Articulationand behavior parity withPhysX Articulation. Single-PR atomic rewrite, clean break (no deprecation aliases for OVPhysX-introduced renames; framework-inherited deprecated shims kept).The OVPhysX articulation diverged significantly from the rest of the framework conventions. This PR brings it back in line: same docstring template, same section ordering, same naming, same internal patterns, same lifecycle.
This PR is stacked on the rigid-object refactor (
antoiner/feat/ovphysx_rigidobject, isaac-sim PR isaac-sim#5426). Once isaac-sim#5426 merges todevelop, the upstream PR for this work will be retargeted todevelop.Status: draft. Implementation is complete (all writers, setters, properties, lifecycle, actuator pipeline); the verbatim PhysX test mirror that already lives in tree (
test_articulation.py, ~210 parametrizations) currently shows 104 failures from a single root-cause bug —_binding_read(TT.BODY_COM_POSE, ...)during_initialize_implis not routing through pinned-host staging despite the type being in_CPU_ONLY_TYPES. Iterating on that bug + remaining triage in a fresh-context follow-up session.Fixes # (none — internal refactor; no associated issue)
Design references
docs/superpowers/specs/2026-04-30-ovphysx-articulation-rewrite-design.md(gitignored, local).docs/superpowers/plans/2026-04-30-ovphysx-articulation-rewrite-plan.md(gitignored, local).source/isaaclab_ovphysx/test/assets/test_articulation.pyis a verbatim 1-to-1 mirror ofisaaclab_physx.test.assets.test_articulation(~210 parametrizations) — landed in the rigid-object PR [OVPHYSX] RigidObject + RigidObjectData asset isaac-sim/IsaacLab#5426. The_ovphysx_session_patchesand_ovphysx_skip_other_deviceautouse fixtures bridge the kitless invocation gap (see the rigid-object test header).Architectural changes
OVPhysX RigidObject is the design template. It has navigated the hybrid OVPhysX surface — Newton-style mask+index dual API + PhysX-style CPU-only bindings via pinned-host staging à la isaac-sim#5329 + pull-to-refresh
binding.read(target):TimestampedBufferWarpallocation in_create_buffers(single source of truth — no_invalidate_caches/_ensure_*_buffers/_ensure_root_buffersmachinery)._binding_read/_binding_write/_stage_to_pinned_cpuhelpers route CPU-only types through pinned-host memory.ProxyArray(warp + torch dual view); rawwp.arrayfor one-shot config buffers.num_instances,num_bodies,num_joints,body_names,joint_names, ...) demoted from@propertyto plain instance attributes.*_indexaccepts partial data;*_maskaccepts full data with awp.boolmask).write_*/set_*parameters are kwarg-only after*,. No positional. Nofull_dataflag anywhere._write_body_stateplumbing layer is removed; deprecated state-writer shims (write_root_state_to_sim, etc.) call the publicwrite_*_to_sim_indexmethods directly, mirroring RigidObject.Articulation-specific surface mirrors Newton 1-to-1: joint-state writers, joint-property writers (CPU-only), body-property setters (multi-body shape), joint-command target setters, external-wrench setters via
WrenchComposer, fixed/spatial tendon setters, deprecated state-writer shims, full actuator pipeline (compute,_apply_actuator_model,_process_actuators_cfg).Files changed
source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/articulation.py— full rewrite (~3863 lines, matches Newton).source/isaaclab_ovphysx/isaaclab_ovphysx/assets/articulation/articulation_data.py— full rewrite (~2504 lines).source/isaaclab_ovphysx/isaaclab_ovphysx/assets/kernels.py— gained 6 articulation kernels migrated from the stop-gapkernels_old.py(now deleted):_compose_root_com_pose,_compute_heading,_copy_first_body,_projected_gravity,_world_vel_to_body_ang,_world_vel_to_body_lin. Plus 2 new joint-property kernels (write_joint_position_limit_to_buffer_index/maskfor trailing-dim-2 limits,write_joint_friction_to_buffer_index/maskfor the broadcast-coefficient pattern).source/isaaclab_ovphysx/isaaclab_ovphysx/assets/kernels_old.py— deleted.Type of change
0.2.x, clean break is acceptable per semver-on-0.x; no deprecation aliases for OVPhysX-introduced renames).Validation
Verifications happen in three layers (Tasks 16-19 of the implementation plan, deferred to fresh-context follow-up):
Real-backend port —
test_articulation.py(already in tree, verbatim PhysX mirror). Run on GPU and CPU separately via./scripts/run_ovphysx.sh -m pytest <path> -k 'cuda:0'and... -k 'cpu'(the wheel's process-global device-mode lock makes a single invocation lock to one device). Expected end state: each pass shows<X> passed, <Y> xfailed, 0 failed.Yis bounded by the wheel-gaps spec; everyxfailcarries areasonpointing at the spec entry.Cross-backend interface —
source/isaaclab/test/assets/test_articulation_iface.pywill gain anovphysxbackend, mirroring the rigid-object iface treatment from [OVPHYSX] RigidObject + RigidObjectData asset isaac-sim/IsaacLab#5426 (commitb340a551f6c). Run on both devices.API consistency audit — per-method side-by-side checklist comparing Newton, RigidObject (post-refactor), and the rewritten Articulation; verifies method name, kwarg-only signature, parameter order, return type, docstring template (one-liner →
.. note::→.. tip::→Args:), section-header placement.Outstanding
_binding_read(TT.BODY_COM_POSE, ...)during_initialize_impldoes not route through pinned-host staging despiteBODY_COM_POSEbeing inTT._CPU_ONLY_TYPES. Likely a single bug in the read path; fix unblocks ~80% of failures.0.2.x→0.3.0.Type of change
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfile (Task 20)CONTRIBUTORS.mdor my name already exists there