Skip to content

Enable mgpu in FrameView classes#1

Draft
pv-nvidia wants to merge 57 commits into
fix/fabric-prepare-for-reusefrom
feat/frame-view-enable-mgpu
Draft

Enable mgpu in FrameView classes#1
pv-nvidia wants to merge 57 commits into
fix/fabric-prepare-for-reusefrom
feat/frame-view-enable-mgpu

Conversation

@pv-nvidia
Copy link
Copy Markdown
Owner

@pv-nvidia pv-nvidia commented May 4, 2026

Description

Removes the cuda:0-only restriction in FabricFrameView. USDRT SelectPrims now accepts any CUDA device index, so Fabric acceleration runs on the simulation device (e.g., cuda:1) instead of silently falling back to the slower USD path. This unblocks distributed training where each process is pinned to a specific GPU.

The change itself is small (drops the device guard in __init__, the assertion in _initialize_fabric, and the _fabric_supported_devices allowlist). The bulk of the diff is multi-GPU test coverage — three cuda:1-parameterized tests guarded by a new multi_gpu pytest marker, plus a dedicated CI job on the multi-GPU runner so regressions show up on PRs that touch FabricFrameView.

The skip-vs-fail logic in _skip_if_unavailable is intentional:

  • On a developer workstation with a single GPU, cuda:1 tests pytest.skip with a warning so local runs stay green.
  • In CI (GITHUB_ACTIONS=true), a missing cuda:1 becomes pytest.fail so a misconfigured runner is caught immediately rather than silently green-lighting every PR.

Stacked on: isaac-sim#5380. Merge that one first; this PR contains only the multi-GPU enablement on top of it.

Type of change

  • New feature (non-breaking change which adds functionality)

cuda:0 continues to work exactly as before; cuda:1+ now also works instead of silently falling back to USD. No public API surface changed.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks 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

Note on the changelog item: this PR uses a fragment file at source/isaaclab_physx/changelog.d/feat-frame-view-enable-mgpu.rst per the new fragment-based changelog system (isaac-sim#5434). CHANGELOG.rst and config/extension.toml are intentionally not edited directly — the nightly CI workflow compiles them from fragments.

Test plan

Three new tests, all marked @pytest.mark.multi_gpu and parameterized with ["cuda:1"]:

  • test_fabric_cuda1_world_pose_roundtripset_world_posesget_world_poses returns the same values on a non-primary CUDA device.
  • test_fabric_cuda1_no_usd_writeback — Fabric writes on cuda:1 do not write back to USD (atol=0.0 — equality, not approximate).
  • test_fabric_cuda1_scales_roundtrip — covers the set_scales write path on cuda:1, since both Fabric write paths now run on self._device.

A new CI job, test-fabric-multi-gpu, runs in .github/workflows/test-multi-gpu.yaml on the existing [self-hosted, linux, x64, gpu, multi-gpu] runner. The job pre-flights with ./isaaclab.sh -p -c "import torch; print(torch.cuda.device_count())" and fails loudly with ::error:: if the runner regresses to a single GPU. Triggered automatically on PRs that touch source/isaaclab_physx/isaaclab_physx/sim/views/fabric_frame_view.py or its test file.

To verify locally on a multi-GPU machine:

./isaaclab.sh -p -m pytest -m multi_gpu \
    source/isaaclab_physx/test/sim/test_views_xform_prim_fabric.py -v

To verify the cuda:0 path is unchanged:

./isaaclab.sh -p -m pytest -m "not multi_gpu" \
    source/isaaclab_physx/test/sim/test_views_xform_prim_fabric.py -v

@pv-nvidia pv-nvidia changed the title Feat/frame view enable mgpu Enable mgpu in FrameView classes May 4, 2026
@pv-nvidia pv-nvidia marked this pull request as draft May 4, 2026 14:43
@pv-nvidia pv-nvidia self-assigned this May 4, 2026
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from f3ecad1 to 297dc09 Compare May 4, 2026 14:53
matthewtrepte and others added 4 commits May 5, 2026 13:13
…m#5473)

# 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.
-->

Extend debug Visualization Markers, which are supported in the Kit
Visualizer, to the Newton Visualizers.

These Visualization Markers are various shapes and models which can be
added to envs for debugging / showing extra information.

Also added filtering for partial visualization (when we filtered which
envs are shown the in the visualizer, we also filter the markers)

For general USD mesh marker support in Newton, a followup PR will be
required, once a Newton API for general USD -> Newton Mesh conversion is
added (see newton-physics/newton#2667)

Checked velocity arrows, dexcubes, raycasts, frames, goal markers


<!-- 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. -->

- New feature (non-breaking change which adds functionality)
- 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
-->

---------

Signed-off-by: matthewtrepte <mtrepte@nvidia.com>
# Description

- Increase the CI startup-hang grace period from 45s to 120s so slow but
valid Kit startup is not killed prematurely.
- Make `SurfaceGripper` fail fast on non-CPU simulation backends before
loading the surface gripper extension.
- Skip the CI-only `SurfaceGripperView` CPU initialization path that can
deadlock, while keeping CUDA fail-fast coverage.

## 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
-->
…isaac-sim#5478)

Follow-up to isaac-sim#5434 (fragment-based changelog system). Two
contributor-facing references still pointed at the old "edit
CHANGELOG.rst directly" workflow:

- **`docs/source/refs/contributing.rst`** — *Maintaining a changelog and
extension.toml* section described per-version editing of CHANGELOG.rst
with manual SemVer bumps.
- **`.github/PULL_REQUEST_TEMPLATE.md`** — checklist asked contributors
to update the changelog and bump extension.toml directly.

Replaced only the parts that talk about direct editing; section/style
guidance (Added/Changed/Deprecated/Removed/Fixed, past tense, the sample
bullets themselves) stays intact.

## Test plan

- [x] Pre-commit clean
- [ ] Verify Build Latest Docs CI step renders the new section correctly

cc @kellyguo11 — addresses the doc gaps flagged after isaac-sim#5434 merged.
# Description

Mark all RTX-based rendering test cases flaky until they can produce
deterministic low-res camera outputs that pass golden image testing on
every CI run.

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

- Test change

## 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
-->

---------

Signed-off-by: HuiDong Chen <huidongc@nvidia.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from 297dc09 to 25e958f Compare May 6, 2026 15:30
…ic_write (isaac-sim#5380)

## Summary

Replace the `sync_usd_on_fabric_write` workaround in `FabricFrameView`
with proper `PrepareForReuse()` calls on the Fabric `PrimSelection`.
This tells the renderer (FSD/Storm) that Fabric data has changed, so the
next rendered frame reflects updated transforms — eliminating the need
to copy Fabric writes back to USD.

## Motivation

The existing `sync_usd_on_fabric_write` flag worked by mirroring every
Fabric write back to USD, which defeated the performance benefits of
Fabric. With `PrepareForReuse()`, the rendering pipeline is properly
notified of Fabric data changes without any USD writeback.

Additionally, the old code incorrectly fell back to USD for CPU devices
— Warp handles CPU Fabric buffers correctly, so the fallback was
unnecessary.

This addresses two of the issues raised in @pbarejko Piotr's review of
PR isaac-sim#4923:
- **Issue #1** (USD write-back): Fabric writes no longer sync back to
USD
- **Issue isaac-sim#4** (PrepareForReuse): Renderer notification via
`PrepareForReuse()` instead of USD writeback

## Changes

### Core (FabricFrameView)
- Call `_prepare_for_reuse()` in write paths (`set_world_poses`,
`set_scales`) to notify the renderer
- Remove `sync_usd_on_fabric_write` parameter (accepted via `**kwargs`
for backward compat)
- Remove incorrect CPU/device fallback warnings — Warp handles CPU
Fabric buffers correctly
- Add `_rebuild_fabric_arrays()` for topology change recovery when
`PrepareForReuse()` returns True, with assertion guarding the prim-count
invariant

### Camera
- Remove `sync_usd_on_fabric_write=True` from FrameView construction in
`camera.py`

## Benchmark Results

1024 prims, 50 iterations, NVIDIA L40 GPU:

| Operation | USD (ms) | Fabric (ms) | Speedup |
|---|---|---|---|
| Get World Poses | 14.71 | 0.07 | **203x** |
| Set World Poses | 40.75 | 0.16 | **259x** |
| Interleaved Set→Get | 55.90 | 0.24 | **232x** |
| Get Local Poses | 11.08 | 11.12 | 1.0x |
| Set Local Poses | 16.14 | 16.28 | 1.0x |

Local poses fall back to USD (expected — Fabric only accelerates world
poses via `omni:fabric:worldMatrix`).

## Tests Added

| Test | What it validates |
|------|------------------|
| `test_camera_pose_update_reflected_in_render` | Camera pose changes
propagate to rendered depth (close vs far) for CPU/GPU, tiled/non-tiled
|
| `test_fabric_set_world_does_not_write_back_to_usd` | Fabric writes
stay in Fabric, USD prim unchanged |
| `test_set_world_updates_local` (xfail) | Documents Issue isaac-sim#5:
`set_world_poses` doesn't update local pose in Fabric mode |

## Test Results

| Test Suite | Passed | Skipped | Xfailed | Total |
|---|---|---|---|---|
| Fabric contract tests (`test_views_xform_prim_fabric.py`) | 17 | 16 |
1 | 34 |
| USD contract tests (`test_views_xform_prim.py`) | 45 | 0 | 0 | 45 |
| Camera render test (`test_tiled_camera.py`) | 8 | 0 | 0 | 8 |

## Type of change

- Performance improvement (removes redundant USD writeback on Fabric
operations)

## 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
- [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

*No doc changes needed (parameter wasn't referenced in any docs)*
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from 3d7335a to ce0aaa0 Compare May 6, 2026 16:46
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 6, 2026
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from ce0aaa0 to a6cd73e Compare May 6, 2026 17:10
…tation (isaac-sim#5506)

# Description

This PR changes the PyTorch3d installation command in the
locomanipulation SDG policy training / rollout to use git and install
pytorch3d from source.

Fixes # (issue)

NV bug 6115836

## 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
-->
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from a6cd73e to 2c619fe Compare May 7, 2026 08:44
r-schmitt and others added 12 commits May 7, 2026 11:53
# Description

the camera config was importing `isaaclab_physx.renderers` because the
default render_cfg was set to that config. this PR sets that to
RendererConfig to remove the import, but provides a
get_default_render_config method to the backend_utils to lazily import
the config if needed. this is called __post_init__ on the camera config
to replace the generic config as soon as possible to avoid downstream
issues referencing the renderer config. this action can be moved to the
factory if downstream references are cleaned up.

## Type of change

- Refactor to remove imports in cfg class

## 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: nvsekkin <72572910+nvsekkin@users.noreply.github.com>
…ields (isaac-sim#5275)

# Description

Splits IsaacLab's USD-physics cfg classes into solver-common base
classes and backend-specific subclasses, and refactors the writers
(`modify_*_properties`, `spawn_rigid_body_material`) so that schema
application is data-driven rather than hard-coded per-class. Prepares
the schema layer for multi-backend support (PhysX today, Newton/Mjc
next) without polluting base classes with silently-ignored fields or
stamping backend-specific schemas onto prims that didn't opt in.

## Architecture

Two layered concepts:

1. **Per-declaring-class routing.** Each cfg field's USD namespace is
determined by the class that declares it (walking the MRO). Base-class
fields write under `physics:*`; subclass fields write under their own
namespace (`physxRigidBody:*`, etc.). When a
`PhysxRigidBodyPropertiesCfg` instance is written, base fields still go
under `physics:*` because `_usd_namespace` is read from the declaring
class via `__dict__`, not via `getattr` (which would hit the subclass
override).
2. **Per-field exceptions.** Some "universal physics" fields have no USD
path except through a backend-namespaced attribute today (e.g.,
`disable_gravity` only exists at `physxRigidBody:disableGravity`). These
are declared as `_usd_field_exceptions = {applied_schema: (namespace,
[fields...])}` on the base class; the writer applies the exception
schema only when one of the listed fields is non-None.

The single helper `_apply_namespaced_schemas(prim, cfg, cfg_dict)` in
`schemas.py` does both passes for every writer (rigid body, collision,
articulation root, joint drive, mesh collision, rigid-body material).

## Design constraints

**One cfg class per spawner slot.** Spawners (`UsdFileCfg`,
`MeshCuboidCfg`, etc.) carry a single field for each property group:
`rigid_props: RigidBodyBaseCfg | None`, `collision_props:
CollisionBaseCfg | None`, `joint_drive_props: JointDriveBaseCfg | None`,
etc. The user cannot pass two cfgs into the same slot, so the cfg class
hierarchy must be **single-rooted per spawner field** — one base class
per group, with backend-specific subclasses below.

This rules out a "PhysX cfg sits next to a Newton cfg as siblings"
design and drives several placement decisions:

| Constraint | Consequence |
|---|---|
| Universal-physics fields must be reachable from any backend's cfg |
Goes on the **base** class, not a sibling backend cfg. Users on
Newton-only deployments can use `RigidBodyBaseCfg(disable_gravity=True)`
without importing `isaaclab_physx`. |
| A PhysX-namespaced field whose semantics are universal (e.g.,
`disable_gravity`) | Lives on the base but routes to the PhysX namespace
via `_usd_field_exceptions`. The base stays backend-clean; the writer
dispatches the PhysX write only when the field is non-None. |
| Writer logic must not branch on cfg subclass | Every writer is the
same code path regardless of subclass. The cfg metadata
(`_usd_namespace`, `_usd_applied_schema`, `_usd_field_exceptions`)
drives behavior; the writer is a pure data interpreter. |
| Adding a new backend (Newton, Mjc) | Requires a new subclass with its
own `_usd_namespace` / `_usd_applied_schema`. No spawner-side changes,
no writer-side changes, no base-cfg-side changes. |
| A field has multiple USD paths today (one PhysX-namespaced, one
Newton-namespaced) | Belongs on the **PhysX subclass**, not the base. A
future `NewtonArticulationRootPropertiesCfg` will own the same
conceptual field on the Newton side. ("Rule 2" — e.g.,
`enabled_self_collisions`.) |
| A field has only one USD path today, namespaced under PhysX, but the
conceptual quantity is universal | Belongs on the **base** with an
`_usd_field_exceptions` entry. ("Rule 1" — e.g., `disable_gravity`,
`articulation_enabled`, `contact_offset`, `rest_offset`,
`max_joint_velocity`.) When Newton ships its own native attribute, the
exception namespace switches transparently with no API change. |

## Field placement

### Base (solver-common) classes — `physics:*` namespace via
`UsdPhysics.*API`

| Cfg class | Field | USD attribute |
|---|---|---|
| `RigidBodyBaseCfg` | `rigid_body_enabled` | `physics:rigidBodyEnabled`
|
| `RigidBodyBaseCfg` | `kinematic_enabled` | `physics:kinematicEnabled`
|
| `CollisionBaseCfg` | `collision_enabled` | `physics:collisionEnabled`
|
| `MassPropertiesCfg` | `mass` | `physics:mass` |
| `MassPropertiesCfg` | `density` | `physics:density` |
| `RigidBodyMaterialBaseCfg` | `static_friction` |
`physics:staticFriction` |
| `RigidBodyMaterialBaseCfg` | `dynamic_friction` |
`physics:dynamicFriction` |
| `RigidBodyMaterialBaseCfg` | `restitution` | `physics:restitution` |
| `JointDriveBaseCfg` | `drive_type` | `drive:<axis>:physics:type` |
| `JointDriveBaseCfg` | `max_force` | `drive:<axis>:physics:maxForce` |
| `JointDriveBaseCfg` | `stiffness` | `drive:<axis>:physics:stiffness` |
| `JointDriveBaseCfg` | `damping` | `drive:<axis>:physics:damping` |
| `MeshCollisionBaseCfg` | `mesh_approximation_name` |
`physics:approximation` (token) |
| `ArticulationRootBaseCfg` | `fix_root_link` | (synthesizes
`UsdPhysics.FixedJoint`) |

`JointDriveBaseCfg` and `MeshCollisionBaseCfg` use the typed
`UsdPhysics.DriveAPI` / `UsdPhysics.MeshCollisionAPI` accessors at the
writer level (multi-instance namespace and `TfToken` with
`allowedTokens`, respectively); all other base fields flow through the
helper's per-class routing.

### PhysX subclasses — `physx*:*` namespaces, `Physx*API` schemas

| Cfg class | `_usd_namespace` | `_usd_applied_schema` | Adds fields |
|---|---|---|---|
| `PhysxRigidBodyPropertiesCfg` | `physxRigidBody` | `PhysxRigidBodyAPI`
| `linear_damping`, `angular_damping`, `max_linear_velocity`,
`max_angular_velocity`, `max_depenetration_velocity`,
`max_contact_impulse`, `enable_gyroscopic_forces`,
`retain_accelerations`, solver iter counts, sleep / stabilization
thresholds |
| `PhysxCollisionPropertiesCfg` | `physxCollision` | `PhysxCollisionAPI`
| `torsional_patch_radius`, `min_torsional_patch_radius` |
| `PhysxArticulationRootPropertiesCfg` | `physxArticulation` |
`PhysxArticulationAPI` | `enabled_self_collisions`, solver iter counts,
sleep / stabilization thresholds |
| `PhysxJointDrivePropertiesCfg` | `physxJoint` | `PhysxJointAPI` |
(currently empty; reserved for future PhysX-only knobs) |
| `PhysxRigidBodyMaterialCfg` | `physxMaterial` | `PhysxMaterialAPI` |
`compliant_contact_stiffness`, `compliant_contact_damping`,
`friction_combine_mode`, `restitution_combine_mode` |
| `PhysxConvexHullPropertiesCfg` | `physxConvexHullCollision` |
`PhysxConvexHullCollisionAPI` | `hull_vertex_limit`, `min_thickness` |
| `PhysxConvexDecompositionPropertiesCfg` |
`physxConvexDecompositionCollision` |
`PhysxConvexDecompositionCollisionAPI` | hull / voxel / shrink-wrap
tunables |
| `PhysxTriangleMeshPropertiesCfg` | `physxTriangleMeshCollision` |
`PhysxTriangleMeshCollisionAPI` | `weld_tolerance` |
| `PhysxTriangleMeshSimplificationPropertiesCfg` |
`physxTriangleMeshSimplificationCollision` |
`PhysxTriangleMeshSimplificationCollisionAPI` | `simplification_metric`,
`weld_tolerance` |
| `PhysxSDFMeshPropertiesCfg` | `physxSDFMeshCollision` |
`PhysxSDFMeshCollisionAPI` | `sdf_margin`, `sdf_narrow_band_thickness`,
`sdf_resolution`, etc. |

### `_usd_field_exceptions` table

These fields are declared on a *base* class but the only USD path today
goes through a non-base namespace. Each entry says: "if any listed field
on this cfg is non-None, apply the exception schema and write that one
attribute under the exception namespace." All other fields on the cfg
follow the per-declaring-class routing rule.

| Base cfg class | Exception schema | Namespace | Field(s) | Why on the
base |
|---|---|---|---|---|
| `RigidBodyBaseCfg` | `PhysxRigidBodyAPI` | `physxRigidBody` |
`disable_gravity` | Per-body gravity exclusion is universal physics;
PhysX honors per-body, Newton consumes the same attribute via the bridge
resolver (scene-level today; per-body fix is a Newton-side kernel
change, not a cfg-API change) |
| `CollisionBaseCfg` | `PhysxCollisionAPI` | `physxCollision` |
`contact_offset`, `rest_offset` | Collision-pair generation distance and
rest gap are universal physics; Newton importer consumes both via PhysX
bridge to populate `Model.shape_collision_radius` / `_thickness`
(`import_usd.py:2104, 2111`) |
| `ArticulationRootBaseCfg` | `PhysxArticulationAPI` |
`physxArticulation` | `articulation_enabled` | PhysX honors at sim time;
IsaacLab Newton wrapper reads it as a spawn-time guard at
`rigid_object.py:1035`. Universal user-facing intent |
| `JointDriveBaseCfg` | `PhysxJointAPI` | `physxJoint` |
`max_joint_velocity` | Sole USD path to `Model.joint_velocity_limit` in
Newton (no `newton:*` equivalent today). The exception namespace
switches transparently when Newton ships `newton:maxJointVelocity` as a
registered applied API |

When any exception field is non-None, the corresponding `Physx*API`
schema is applied to the prim. When all exception fields are None, no
PhysX schema is stamped — Newton-targeted prims authored from `*BaseCfg`
stay free of PhysX schemas they didn't opt in to.

## Field renames (with deprecation aliases)

To enforce the convention that python `snake_case` cfg field names map
identity-style to USD `camelCase` attribute names, two legacy fields
were renamed. Both keep the old name as a deprecation alias forwarded
via `__post_init__` (emits `DeprecationWarning`, scheduled for removal
in 5.0).

| Old name | New name | USD attribute |
|---|---|---|
| `JointDriveBaseCfg.max_velocity` | `max_joint_velocity` |
`physxJoint:maxJointVelocity` |
| `JointDriveBaseCfg.max_effort` | `max_force` |
`drive:<axis>:physics:maxForce` |

## Type of change

- New feature (non-breaking change which adds functionality)
- Breaking change (existing functionality will not work without user
modification)

The split is non-breaking at the spawner-cfg level — every base-class
type accepts any subclass via polymorphism, and every legacy
`RigidBodyPropertiesCfg` / `JointDrivePropertiesCfg` /
`CollisionPropertiesCfg` / `ArticulationRootPropertiesCfg` /
`MeshCollisionPropertiesCfg` / `RigidBodyMaterialCfg` /
`FixedTendonPropertiesCfg` / `SpatialTendonPropertiesCfg` import path
continues to work via deprecation-alias subclasses and `__getattr__`
shims on `isaaclab.sim`, `isaaclab.sim.schemas`, and
`isaaclab.sim.schemas.schemas_cfg`. Direct attribute access to the
renamed fields still works through deprecation aliases. Removal
scheduled for 5.0.

The breaking aspect: cfg classes in `isaaclab_physx.sim.schemas` and
`isaaclab_physx.sim.spawners.materials` are physically relocated. Anyone
importing from internal paths (rather than `isaaclab.sim`) needs to
update.

## Migration

```python
# Before
import isaaclab.sim as sim_utils
rigid_props = sim_utils.RigidBodyPropertiesCfg(disable_gravity=True, linear_damping=0.1)
joint_props = sim_utils.JointDrivePropertiesCfg(max_effort=80.0, max_velocity=5.0)
collision_props = sim_utils.CollisionPropertiesCfg(contact_offset=0.02, torsional_patch_radius=1.0)
material = sim_utils.RigidBodyMaterialCfg(static_friction=0.7, compliant_contact_stiffness=1000.0)

# After (PhysX-targeted)
import isaaclab.sim as sim_utils
from isaaclab_physx.sim.schemas import (
    PhysxRigidBodyPropertiesCfg,
    PhysxJointDrivePropertiesCfg,
    PhysxCollisionPropertiesCfg,
)
from isaaclab_physx.sim.spawners.materials import PhysxRigidBodyMaterialCfg

rigid_props = PhysxRigidBodyPropertiesCfg(disable_gravity=True, linear_damping=0.1)
joint_props = PhysxJointDrivePropertiesCfg(max_force=80.0, max_joint_velocity=5.0)
collision_props = PhysxCollisionPropertiesCfg(contact_offset=0.02, torsional_patch_radius=1.0)
material = PhysxRigidBodyMaterialCfg(static_friction=0.7, compliant_contact_stiffness=1000.0)

# After (Newton-targeted — base classes only, no PhysX schemas applied)
from isaaclab.sim.schemas import RigidBodyBaseCfg, JointDriveBaseCfg, CollisionBaseCfg
from isaaclab.sim.spawners.materials import RigidBodyMaterialBaseCfg

rigid_props = RigidBodyBaseCfg(disable_gravity=True)  # only base + exception fields available
joint_props = JointDriveBaseCfg(max_force=80.0, max_joint_velocity=5.0)
material = RigidBodyMaterialBaseCfg(static_friction=0.7)
```

Spawner type annotations remain unchanged — they accept any subclass via
polymorphism.

## Internal helper

```python
def _apply_namespaced_schemas(prim, cfg, cfg_dict):
    # 1. Per-field exceptions: pop listed fields, apply exception schema if any non-None,
    #    write under exception namespace.
    # 2. Per-declaring-class routing: walk MRO to find each remaining field's owner class;
    #    write under that class's _usd_namespace; apply that class's _usd_applied_schema.
```

Used by all five `modify_*_properties` writers and
`spawn_rigid_body_material`. Replaced ~125 lines of duplicated gating
logic with a single ~30-line helper.

## Side change: configclass

`source/isaaclab/isaaclab/utils/configclass.py:_process_mutable_types`
now detects string-form `ClassVar` annotations under PEP 563 (`from
__future__ import annotations`) so it doesn't wrap `ClassVar[dict]`
defaults in `field(default_factory=...)`. Matches Python stdlib
`dataclasses` semantics. No pre-existing IsaacLab class used `ClassVar`
inside a `@configclass` block, so the change has no effect on existing
code; it enables the `ClassVar` metadata pattern this PR introduces.

## Test plan

- [x] `test_schemas.py` (38 → 40 tests): all schema-cfg classes write
correct attributes under the right namespace; PhysX schemas are NOT
applied when only base/UsdPhysics fields are set; deprecation aliases
(`max_velocity` → `max_joint_velocity`, `max_effort` → `max_force`)
forward correctly and emit `DeprecationWarning`. **40 passed.**
- [x] `test_schemas_shim.py`: legacy import paths
(`isaaclab.sim.schemas.RigidBodyPropertiesCfg` etc.) resolve via
`__getattr__` shims. **All passing.**
- [x] `test_articulation.py`, `test_rigid_object_iface.py`,
`test_valid_configs.py`, `test_spawn_*` — no regressions.
- [x] Full suite (`./isaaclab.sh -t`): 8768/9205 pass, 437 unrelated
baseline failures (rendering, `omni.physics.tensors.api` missing, OSC
controller, `install_ci`, `pyglet`, Newton env-path, Anymal-C
determinism). Zero new regressions; +123 passing tests vs. earlier
state.
- [x] `./isaaclab.sh -f` (pre-commit) clean.

## Supersedes

Together with isaac-sim#5276, supersedes isaac-sim#4847 and isaac-sim#5203 with a cleaner
schema-layer design.

## 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 (changelog
fragments under `source/isaaclab/changelog.d/`)
- [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 (fragment-based system) 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: ooctipus <zhengyuz@nvidia.com>
…c-sim#5301)

Updates docs for using nurec background in locomanipulation sdg

## Type of change

- Documentation update

## Checklist

- [ ] 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
- [ ] 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>
Bumped packages:
- isaaclab: 4.6.28 → 4.7.0
- isaaclab_newton: 0.5.26 → 0.6.0
- isaaclab_ov: 0.1.3 → 0.1.4
- isaaclab_ovphysx: 0.1.2 → 0.1.3
- isaaclab_physx: 0.5.29 → 0.6.0
- isaaclab_rl: 0.5.1 → 0.5.2
- isaaclab_tasks: 1.5.34 → 1.5.35
- isaaclab_teleop: 0.3.9 → 0.3.10
## Summary

Bumps the Newton pin to
[`v1.2.0rc2`](https://pypi.org/project/newton/1.2.0rc2/), which pulls in
IsaacLab-relevant fixes plus the upstream tendon-scoping fix.

## What's new in Newton v1.2.0rc2 vs IsaacLab's current pin (`a27277e`)

The current IsaacLab Newton pin is from late April; v1.2.0rc2 is the
latest release-candidate cut. Notable fixes pulled in:

-
**[newton-physics/newton#2659](newton-physics/newton#2659
\"Scope USD custom-frequency parsing\" — `parse_usd` now scopes the
custom-frequency walk to `root_path` natively.
-
**[newton-physics/newton#2678](newton-physics/newton#2678
Regression fix.
-
**[newton-physics/newton#2720](newton-physics/newton#2720
`SolverKamino` reset under `world_mask`.
-
**[newton-physics/newton#2710](newton-physics/newton#2710
VRAM leak fix on example reset.
- Plus 16 other smaller fixes between rc1 and rc2.

## Required dep bumps

Newton 1.2.0rc2's \`pyproject.toml\` requires:

- \`warp-lang==1.13.0\`
- \`mujoco==3.8.0\` (was 3.6.0)
- \`mujoco-warp==3.8.0.1\` (was 3.6.0)

Pins updated in:

| File | Change |
|---|---|
| \`source/isaaclab/setup.py\` | \`warp-lang==1.12.0\` → \`==1.13.0\`;
\`mujoco==3.6.0\` → \`==3.8.0\`; \`mujoco-warp==3.6.0\` → \`==3.8.0.1\`
|
| \`source/isaaclab_newton/setup.py\` | mujoco / mujoco-warp bumps;
Newton pin → \`v1.2.0rc2\` |
| \`source/isaaclab_visualizers/setup.py\` | 3× Newton pin →
\`v1.2.0rc2\` |
| \`tools/wheel_builder/res/python_packages.toml\` | All four pins
mirrored |

## Code adapts

\`warp-lang\` 1.13 removed the \`wp.math\` namespace. Two IsaacLab call
sites use it:

-
\`source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py:72\`
-
\`source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_renderer_kernels.py:330\`

Both rewritten as \`wp.math.transform_to_matrix(...)\` →
\`wp.transform_to_matrix(...)\`. That's the only IsaacLab-side adapt
needed.

## Test plan

- [x] \`./isaaclab.sh -i newton\` clean install against the bumped pins.
- [x] \`pip list\` confirms \`newton 1.2.0rc2\`, \`warp-lang 1.13.0\`,
\`mujoco 3.8.0\`, \`mujoco-warp 3.8.0.1\`.
- [x] Sanity smoke: Shadow-Hand-Over MAPPO (4 envs, 1 iter) runs clean —
simulation init through CUDA graph capture through one training step +
checkpoint save, no errors.
- [x] Pre-commit clean.

## Caveat

Smoke covered Shadow-Hand-Over MAPPO. Other envs with different sensors
/ renderers / collision setups could surface warp 1.13 or mujoco 3.8
differences the smoke didn't exercise; full PR CI catches them.

---------

Co-authored-by: Kelly Guo <kellyg@nvidia.com>
Bumped packages:
- isaaclab: 4.7.0 → 4.8.0
- isaaclab_mimic: 1.2.5 → 1.2.6
- isaaclab_newton: 0.6.0 → 0.7.0
- isaaclab_ov: 0.1.4 → 0.1.5
- isaaclab_physx: 0.6.0 → 0.6.1
# Description

Clarifies the articulation joint friction API docs across the base,
PhysX, and Newton implementations.

The base API now warns that joint friction semantics are
backend-specific. The PhysX docs distinguish legacy
unitless coefficients from PhysX 5 static/dynamic friction efforts and
viscous coefficients. The Newton docs now
identify joint friction as an absolute force/torque value and include an
MJWarp example mapping the value to
MuJoCo Warp's `dof_frictionloss`.

Fixes isaac-sim/IsaacLab-Internal#875

## Type of change

- Documentation update

## Screenshots

Not applicable.

## Checklist

- [ ] 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 (not applicable: docs-only change)
- [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` — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
# Description

Reduce higher-level dependency on packed state tensors in targeted
IsaacLab call sites without changing existing task observation keys.

This PR:
- changes Pink IK to read `body_link_pose_w` directly instead of slicing
`body_link_state_w`;
- changes Dexsuite orientation rewards to use `root_link_quat_w`
directly instead of slicing `root_state_w`;
- adds explicit pick-place helpers for robot link pose and velocity;
- keeps `get_all_robot_link_state()` available for compatibility, but
marks it deprecated for removal in IsaacLab 4.0;
- keeps existing `robot_links_state` task config entries unchanged.

Fixes # (issue)

## Type of change

- Bug fix (non-breaking change which fixes an issue)
- Documentation update

## Screenshots

N/A

## Test Plan

- `./isaaclab.sh -p -m py_compile
source/isaaclab/isaaclab/envs/mdp/__init__.pyi
source/isaaclab/isaaclab/envs/mdp/actions/pink_task_space_actions.py
source/isaaclab/isaaclab/envs/mdp/observations.py
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/mdp/__init__.pyi
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/mdp/observations.py
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/dexsuite/mdp/rewards.py`
- `./isaaclab.sh -f`
- `git diff --check origin/develop..HEAD`
- `rg -n "body_link_state_w|root_state_w"
source/isaaclab/isaaclab/envs/mdp/actions/pink_task_space_actions.py
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/mdp/observations.py
source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/dexsuite/mdp/rewards.py`
(no matches)
- Existing/new MDP pytest not run locally. Per review, new MDP tests
were removed and should be added in a separate PR. Local pytest
collection is also blocked in this worktree because `./isaaclab.sh -p`
selects `/usr/bin/python3.12` without `torch`.

## 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
- [ ] 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

Notes:
- The unchecked warning item is intentional: this PR adds a
`DeprecationWarning` to `get_all_robot_link_state()` so users can
migrate before IsaacLab 4.0.
- The unchecked test item follows review feedback: MDP tests should be
added in a separate PR.
## Summary
- Updated PhysX and Newton backend tests to use the current root-state,
joint-state, contact-sensor, and wrench-composer API names.
- Updated the Newton contact sensor adapter to use the current
SensorContact constructor and force/metadata fields.
- Bumped matching PhysX and Newton extension changelog/version files.

## Test Plan
- [x] ./isaaclab.sh -p -m py_compile
source/isaaclab_physx/test/sensors/test_frame_transformer.py
source/isaaclab_newton/test/sensors/test_frame_transformer.py
source/isaaclab_physx/test/sensors/test_contact_sensor.py
source/isaaclab_newton/isaaclab_newton/physics/newton_manager.py
source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor.py
source/isaaclab_newton/isaaclab_newton/sensors/contact_sensor/contact_sensor_kernels.py
- [x] ./isaaclab.sh -f
- [x] Focused deprecation scan: 118 matches on origin/develop, 0 matches
on this branch
- [ ] Targeted GPU pytest on NvidiaWorkstation-WiFi: attempted in
isaac-lab-base-pr5304:latest, but the PhysX container timed out after
3600s during pytest collection before tests ran
## Summary
- Migrates core test and MDP callers off deprecated state/read/write
helper APIs.
- Updates the test_pose_inv tensor-to-NumPy conversion for NumPy 2.0.
- Bumps the isaaclab changelog/version because core MDP source changed.

## Verification
- ./isaaclab.sh -f
- Scoped deprecated-call-site search: assigned core matches removed.

Rebased onto develop after PR isaac-sim#5304 merged.
# Description

Adds the missing core-concepts sensor documentation for the ground-truth
PVA
sensor and joint wrench sensor. The sensor overview now links both
pages, the
public `isaaclab.sensors` API page includes `Pva`, `PvaData`, and
`PvaCfg`, and
the sensor module table documents the joint wrench sensor prim-path
expectation.

Fixes isaac-sim/IsaacLab-Internal#880

Validation:

- `./isaaclab.sh -f`
- `git diff --check`
- Verified `origin/develop` did not list `pva` or `joint_wrench_sensor`
from
`docs/source/overview/core-concepts/sensors/index.rst`, and this branch
does.
- Parsed the two new RST pages with `docutils` using local stubs for
  Sphinx-only directives and roles.
- `make -C docs current-docs` was attempted locally but could not run
because
  `sphinx-build` is not installed in this environment.

## Type of change

- Documentation update

## Screenshots

N/A; documentation text update.

## 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
- [ ] 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 added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump `extension.toml` -- CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
isaac-sim#5538)

## Summary

Two unrelated CI breakages on develop, bundled here so develop turns
green in one PR.

### 1. Skip the failing viewergl test

`test_cartpole_newton_visualizer_viewergl_rgb_motion[physx,newton]`
started returning all-black frames on develop after
`nvcr.io/nvidian/isaac-sim:latest-develop` flipped to a Kit 110.1.1 +
USD 25.11 base. The failure has been deterministic across multiple PRs
(isaac-sim#5523, isaac-sim#5495, isaac-sim#5408, …).

Investigation so far has ruled out:
- PR isaac-sim#5521 (revert in
isaac-sim#5539 still failed)
- Newton 1.0 → 1.2.0rc2 viewer code regression (only 7-line addition;
ViewerGL alone yields 1.08M nonzero pixels)
- warp 1.12 → 1.13 RegisteredGLBuffer ABI (byte-identical)
- Module-load side effects of `isaaclab_physx.renderers`
- CUDA-GL interop (PR isaac-sim#5540 diagnostic confirms direct CPU FBO readback
also returns zeros, with `GL_NO_ERROR`)
- GL context-currency (PR isaac-sim#5541 H6 attempt: still fails)
- GL/CUDA sync (PR isaac-sim#5542 H4 attempt: still fails)

Diagnostic output (PR isaac-sim#5540 v2):
```
[VIZDIAG] fbo=c_uint(8)  pbo=None  size=600x600
[VIZDIAG] glGetError before: GL_NO_ERROR
[VIZDIAG] CPU-readback: nonzero=0/1080000  max=0  err=GL_NO_ERROR
[VIZDIAG] PBO-result: nonzero=0/1080000  max=0
```

The FBO itself is empty — Newton's pyglet/EGL renderer is not depositing
pixels under Kit 110.1.1, even though `tiled_camera_rgb_non_black` (Kit
RTX path) on the same env passes. Underlying root cause still being
chased; this PR ships the skip to unblock develop.

### 2. Fix warp intersphinx 404 in docs build

`https://nvidia.github.io/warp/objects.inv` started returning 404 —
Warp's `objects.inv` only lives at `/stable/` and `/latest/` now. With
Sphinx's `warnings_treated_as_errors`, the broken intersphinx fetch
fails the docs build on every PR. Pinning to `/stable/` (matches the
existing PyTorch `/docs/2.11/` workaround pattern in the same file).

Verified `https://nvidia.github.io/warp/stable/objects.inv` returns 200.

## Test plan

- [x] CI `isaaclab_visualizers` on this branch — was passing earlier
with the skip; will re-verify with the bundled docs fix
- [ ] CI `Build Latest Docs` on this branch — must turn green (was
failing on every recent PR before this fix)

## Re-enable plan

Once the underlying viewergl bug is identified and fixed, drop the
`@pytest.mark.skip` decorator and remove the
`jichuanh-disable-viewergl-flaky.skip` fragment.
ooctipus and others added 11 commits May 9, 2026 14:57
# Description

Pink IK uses DAQP through `qpsolvers`, but the install-time dependency
repair only
verified that Pinocchio could be imported. In environments where
`pin-pink` or
`qpsolvers` is present but DAQP is missing, unregistered, or too old for
`qpsolvers` warm-start arguments, `solve_ik(..., solver="daqp")` can
fail and
fall back to current joint targets. The controller then reports a
misleading
end-effector position error in `test_pink_ik.py`.

This change makes the installer probe the full Pink IK stack:
`pinocchio`, DAQP
registration in `qpsolvers`, and the `daqp.solve` API shape required by
current
`qpsolvers` (`primal_start`). It also aligns the IsaacLab dependency pin
with
the compatible DAQP release, `daqp==0.8.5`.

Runtime handling stays narrow: ordinary IK failures keep the existing
fallback,
while missing DAQP or the specific `primal_start` API mismatch is
surfaced with
an actionable install message instead of being swallowed as an IK
fallback.

The docs config also mocks `qpsolvers`, matching the existing docs
treatment for
optional Pink IK dependencies such as `pink` and `pinocchio`, so API
docs can be
built without the runtime solver stack installed.

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Test Plan

- `./isaaclab.sh -p -m py_compile
source/isaaclab/isaaclab/cli/commands/install.py
source/isaaclab/isaaclab/controllers/pink_ik/pink_ik.py
source/isaaclab/setup.py docs/conf.py`
- `./isaaclab.sh -p -c "import inspect, pinocchio, daqp, qpsolvers;
assert 'daqp' in qpsolvers.available_solvers; assert 'primal_start' in
inspect.signature(daqp.solve).parameters; print('pink ik dependency
probe passed')"`
- `./isaaclab.sh -p -c "..."` small monkeypatch check that
`TypeError("solve() got an unexpected keyword argument 'primal_start'")`
raises the new DAQP compatibility `RuntimeError`
- `./isaaclab.sh -p -m pytest
source/isaaclab/test/controllers/test_pink_ik.py::test_movement_types -k
"GR1T2-Abs-v0 and stay_still" -q --tb=short -s -x`
- `./isaaclab.sh -p -m pytest
source/isaaclab/test/controllers/test_pink_ik.py -q --tb=short -x` (`23
passed, 1 skipped`)
-
`VIRTUAL_ENV=/home/zhengyuz/Projects/IsaacLab.wt/feature-heterogeneous_dexsuite/env_isaaclab
PATH=/home/zhengyuz/Projects/IsaacLab.wt/feature-heterogeneous_dexsuite/env_isaaclab/bin:$PATH
make current-docs` from `docs/`
-
`VIRTUAL_ENV=/home/zhengyuz/Projects/IsaacLab.wt/feature-heterogeneous_dexsuite/env_isaaclab
./isaaclab.sh -f`

## Screenshots

N/A.

## 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 - docs
config only)
- [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 added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump `extension.toml` -- CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
Bumped packages:
- isaaclab: 4.8.1 → 4.8.2
# Description
This PR a lot simplify cloner logic:
Refactors scene cloning so `InteractiveScene` builds a `ClonePlan`
directly from asset configuration, rewrites spawner configs to spawn
representative sources in their selected environment paths, and then
replicates directly from those sources to the remaining destinations.
This removes the previous template round trip and hard-deletes
`clone_from_template`.

This also updates the cloner API around `CloneCfg` and
`make_clone_plan`, adds explicit `spawn_paths` support for multi-asset
spawners, tightens rigid object collection spawning invariants, and
refreshes docs, tests, and changelog coverage for the new planning flow.

Fixes # N/A

Dependencies: none.

## Type of change

- New feature (non-breaking change which adds functionality)
- Breaking change (existing functionality will not work without user
modification)
- Documentation update

## Screenshots

N/A.

## Test plan

Focused tests were run individually while developing this branch:

- `source/isaaclab/test/scene/test_interactive_scene.py`
- `source/isaaclab/test/sim/test_cloner.py`
- `source/isaaclab/test/sim/test_spawn_wrappers.py`
- `source/isaaclab_physx/test/sim/test_cloner.py`
- `py_compile` checks for touched Python modules

## 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 added a changelog fragment under
`source/<pkg>/changelog.d/` for every touched package (do **not** edit
`CHANGELOG.rst` or bump `extension.toml` — CI handles that)
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Bumped packages:
- isaaclab: 4.8.2 → 5.0.0
- isaaclab_newton: 0.7.1 → 0.7.2
- isaaclab_physx: 0.6.2 → 0.6.3
…5564)

# Description

When benchmarking scripts are executed with num_iterations set to below
the threshold for reward logging, the run can produce missing reward
data. However, the scripts are hardcoded to always parse rewards from
tensorboard, which may not exist in these cases. This change patches the
RL benchmarking scripts to only process rewards logging if they were
written to tensorboard.

## 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
- [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

<!--
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
-->
# 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. -->

- 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
-->
# 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
-->
This PR improves IsaacLab Teleop retargeting performance and
installation reliability.

- Added configurable IsaacTeleop retargeting execution via
`IsaacTeleopCfg.retargeting_execution`.
- Enabled deadline-paced pipelined retargeting by default, so
IsaacTeleop retargeting work can overlap with Isaac Lab simulation
stepping.
- Preserved synchronous retargeting as an opt-in mode for exact
current-frame behavior.
- Added an extension-level `pip_upgrade_dependencies` setting in
`extension.toml` so `./isaaclab.sh --install` can explicitly upgrade
selected `install_requires` dependencies after editable install.
- Used that mechanism for `isaaclab_teleop` to upgrade to the latest
compatible `isaacteleop` without duplicating the version spec outside
`setup.py`.

## Why

The pipelined retargeting path reduces Python-side frame pressure by
returning the latest completed retargeting output while the current
frame is submitted in parallel.

The install change fixes CI/local environments where an older compatible
`isaacteleop` version is already installed. Since `pip install -e
source/isaaclab_teleop` does not upgrade already-satisfied dependencies
by default, which could keep using a stale IsaacTeleop package. The new
targeted upgrade keeps the version range in `setup.py` as the source of
truth while still allowing the install command to refresh `isaacteleop`.

# 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. -->

- New feature (non-breaking change which adds functionality)

## 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
-->
# Description

Adds the **Assemble Trocar** manipulation task for the Unitree G1
(29-DoF + Dex3), with RLinf support.

Key additions:
- **Task MDP**: observations (body + Dex3 joint states), reward
functions (4-stage sparse), termination conditions (timeout, success,
object drop), and reset events (scene reset, task stage reset, random
tray rotation).
- **Camera presets**: front camera and left/right wrist cameras
(TiledCamera, 224×224) configured for GR00T visual input.
- **Robot presets**: G1 29-DoF + Dex3 articulation configuration.
- **GR00T data config**: `IsaacLabDataConfig` defining
video/state/action modality keys, transforms (SinCos state encoding,
min-max action normalization, color jitter), and model-specific
settings.
- **RLinf extension update**: minor update to
`isaaclab_contrib/rl/rlinf/extension.py` to support the new task
registration.

## 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`
- [ ] 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

---------

Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…aac-sim#5276)

# Description

Adds Newton-native and MuJoCo-specific schema cfg classes to
`isaaclab_newton.sim.schemas`,
following the base/subclass framework from isaac-sim#5275. All new cfgs use the
per-declaring-class
MRO routing in `_apply_namespaced_schemas` — no backend-specific
branching in any writer.

Depends on isaac-sim#5275.

## New cfgs

### MuJoCo (Newton MuJoCo kernel, `mjc:*` namespace)

| Class | Field | USD attribute | Applied schema |
|---|---|---|---|
| `MujocoRigidBodyPropertiesCfg` | `gravcomp` | `mjc:gravcomp` | None
(raw attr) |
| `MujocoJointDrivePropertiesCfg` | `actuatorgravcomp` |
`mjc:actuatorgravcomp` | `MjcJointAPI` |

Body-level `gravcomp` must be set for joint-level `actuatorgravcomp` to
have any effect.
The spawner auto-enables `MujocoRigidBodyPropertiesCfg(gravcomp=1.0)`
when joint-level
actuator gravcomp is requested without body-level gravcomp.

### Newton-native (`newton:*` namespace)

| Class | Fields | USD attributes | Applied schema |
|---|---|---|---|
| `NewtonCollisionPropertiesCfg` | `contact_margin`, `contact_gap` |
`newton:contactMargin`, `newton:contactGap` | `NewtonCollisionAPI` |
| `NewtonMeshCollisionPropertiesCfg` | `max_hull_vertices` |
`newton:maxHullVertices` | `NewtonMeshCollisionAPI` |
| `NewtonMaterialPropertiesCfg` | `torsional_friction`,
`rolling_friction` | `newton:torsionalFriction`,
`newton:rollingFriction` | `NewtonMaterialAPI` |
| `NewtonArticulationRootPropertiesCfg` | `self_collision_enabled` |
`newton:selfCollisionEnabled` | `NewtonArticulationRootAPI` |

## Design constraints

Same single-cfg-per-spawner-slot rule as isaac-sim#5275. Newton cfgs subclass the
same base classes
as PhysX cfgs; each declares `_usd_namespace`/`_usd_applied_schema`
(ClassVar) and fields
that auto-camelCase to their USD attr names. Per-declaring-class MRO
routing handles mixed
PhysX+Newton cfg hierarchies correctly.

## Field renames (with deprecation aliases through 5.0)

| Old | New | Reason |
|---|---|---|
| `gravity_compensation_scale` | `gravcomp` | Single word identity:
`gravcomp` → `mjc:gravcomp` |
| `gravity_compensation` | `actuatorgravcomp` | Single word identity:
`actuatorgravcomp` → `mjc:actuatorgravcomp` |

## Type of change

- New feature (non-breaking)

Forwarding shims on `isaaclab.sim.schemas` keep existing imports
working.
Deprecation aliases keep old field names working through 5.0.

## Test plan

- [x] MuJoCo tests: `mjc:gravcomp` / `mjc:actuatorgravcomp` written when
set, not written when None
- [x] Newton collision, material, articulation-root: attrs written,
schemas applied only when non-None
- [x] Deprecation alias tests for renamed fields
- [x] `test_schemas.py` 46/46 pass — no regressions
- [x] Pre-commit clean

## Supersedes

Together with isaac-sim#5275, supersedes isaac-sim#4847 and isaac-sim#5203.

---------

Co-authored-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: Antoine RICHARD <antoiner@nvidia.com>
Bumped packages:
- isaaclab: 5.0.0 → 5.1.0
- isaaclab_assets: 0.3.3 → 0.3.4
- isaaclab_contrib: 0.3.1 → 0.3.2
- isaaclab_experimental: 0.0.3 → 0.0.4
- isaaclab_newton: 0.7.2 → 0.8.0
- isaaclab_ov: 0.1.6 → 0.1.7
- isaaclab_tasks: 1.5.36 → 1.5.37
- isaaclab_teleop: 0.3.10 → 0.3.11
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from 93f83eb to f8ca684 Compare May 12, 2026 15:46
ooctipus and others added 6 commits May 12, 2026 10:28
## Summary
- ``docs/source/setup/ecosystem.rst``: ``https://robosuite.ai/`` now
returns 404. Updated the RoboSuite reference link to the project's
GitHub repo (``https://github.com/ARISE-Initiative/robosuite``).
- ``docs/source/how-to/cloudxr_teleoperation.rst``:
``https://github.com/NVIDIA/IsaacTeleop/blob/main/src/plugins/manus/README.md``
is gone (404). The IsaacTeleop repo root still resolves, so the Manus
plugin reference now points there until the upstream doc is republished.

These were the two failures from the ``Documentation Links`` CI job;
everything else lychee reported was a 301/302 redirect already in the
accept list.

## Test plan
- [x] ``pre-commit run --files
docs/source/how-to/cloudxr_teleoperation.rst
docs/source/setup/ecosystem.rst`` — passes.
- [ ] Re-run ``Documentation Links`` on the PR — expect zero ``[ERROR]``
entries.

Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: Kelly Guo <kellyg@nvidia.com>
…pers (isaac-sim#5579)

## Summary

`FabricNoticeBindings.initialize` and `CubricBindings.initialize`
retried `tryAcquireInterfaceWithClient` with `clientName=None` when the
first attempt returned null. Carbonite has rejected null client names
since 2018, so the retry only emitted:

```
[Error][carb] Client passed into the framework is nullptr.
```

and always returned null. This surfaces in any IsaacLab run that touches
Carbonite outside a full Kit context — for example, a remote asset path
that pulls in `omni.client` (and therefore a partial Carb framework)
before `_isaac_sim` is loaded.

## Changes

- Removed the `tryAcquire(None, ...)` fallback in both helpers.
- Replaced the first-attempt client name
`"carb.scripting-python.plugin"` with the same identity each helper
already passes to `acquireFramework`: `"isaaclab.cloner"` and
`"isaaclab.cubric"`. Refcount tracking is now attributed to IsaacLab
rather than to Kit's Python scripting host.

`clientName` is not used by Carbonite to gate interface lookup — any
non-null string is accepted — so the in-Kit success path is
byte-for-byte equivalent and the cloning speedup (Fabric notice listener
suspension) is preserved.

## Test plan

- [x] `./isaaclab.sh -f` clean on both commits.
- [x] Confirmed locally that removing the null fallback removes the
`[Error][carb]` log line in the repro that triggered this (rc41 + Ant
remote asset path, no Kit loaded).
- [ ] Smoke test a normal in-Kit cloning run (e.g. any Newton/PhysX env
with `num_envs >= 64`) and confirm `Cloner.clone()` wall-time is
unchanged before vs after this PR.
# Description

This PR enables heterogeneous dexsuite with newton backend

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
-->
# Description

Reverts CI image to previous Isaac Sim image from 05/11 as the new image
is causing timeouts in our CI.
TODO: investigate failing cause of the new image.

## 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
-->
Bumped packages:
- isaaclab: 5.1.0 → 5.1.1
- isaaclab_newton: 0.8.0 → 0.8.1
- isaaclab_ov: 0.1.7 → 0.1.8
- isaaclab_physx: 0.6.3 → 0.6.4
- isaaclab_tasks: 1.5.37 → 1.5.38
# Description

Fixes partial migration of metadata access in isaac-sim#5418 

<!--
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
-->

---------

Co-authored-by: Kelly Guo <kellyg@nvidia.com>
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from ada2608 to c1254cd Compare May 13, 2026 10:54
AntoineRichard and others added 10 commits May 13, 2026 13:04
## 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>
…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
-->
- Allow FabricFrameView to run on cuda:N for any N; USDRT SelectPrims
  no longer needs cuda:0.
- Refactor the Fabric write path into a single _compose_fabric_transform
  helper shared by set_world_poses, set_scales, and the initial
  USD->Fabric sync, collapsing the sync to one kernel launch with one
  PrepareForReuse.
- Replace the topology-invariant assert with RuntimeError so it survives
  python -O.
- Add multi_gpu pytest marker plus cuda:1 unit-test coverage for both
  Fabric write paths, and run them in the existing test-multi-gpu CI
  job (one extra step, no new job).
The standard pytest invocation in CI runs the fabric test file without
filtering on the ``multi_gpu`` marker, so the ``cuda:1`` tests get
scheduled on every runner including the single-GPU ones.  Previously
``_skip_if_unavailable`` hard-failed via ``pytest.fail`` whenever
``GITHUB_ACTIONS=true`` and the requested device was missing, on the
theory that this would catch a misconfigured multi-GPU runner.  In
practice it just broke the standard CI: the dedicated
``test-fabric-multi-gpu`` workflow already pre-flights
``torch.cuda.device_count() >= 2`` before invoking pytest, so a
genuinely misconfigured multi-GPU runner is already caught there.

Always skip rather than fail when the requested ``cuda:N`` index isn't
available.  Drop the now-unused ``import os``.
Kit's CLI parser reads sys.argv directly at startup and segfaults on
pytest flags that collide with its own short options.  Running

    pytest -m multi_gpu source/isaaclab_physx/test/sim/test_views_xform_prim_fabric.py

crashes during collection because Kit sees ``-m multi_gpu`` and exits
with ``Ill formed parameter: -m`` followed by SIGSEGV (exit code 245)
inside ``simulation_app._start_app``.

Strip sys.argv to argv[0] before instantiating AppLauncher.  The test
file takes no CLI arguments of its own, mirroring the broader pattern
used by ``test_tiled_camera_env.py`` which assigns
``sys.argv[1:] = args_cli.unittest_args`` after argparse.
wp.to_torch on a ProxyArray is deprecated in favor of the .torch
accessor.  Switch the three call sites that consume the ProxyArray
returned by get_world_poses; leave get_scales call sites alone since
that method still returns a raw wp.array (no .torch accessor).
- Add a GPU-count pre-flight step to the test-fabric-multi-gpu CI job
  so a runner regression to a single GPU fails the workflow instead of
  silently skipping every cuda:1 test. This is what the comment in
  _skip_if_unavailable already promised existed.
- Note that the sys.argv strip in test_views_xform_prim_fabric.py must
  stay between the AppLauncher import and its instantiation; any CLI
  parser or reordering re-exposes Kit to pytest argv and segfaults at
  startup.
- Document the _fabric_usd_sync_done side effect on
  _compose_fabric_transform so callers can see why subsequent getters
  stop pulling from USD.
The class docstring and __init__ device-param doc still claimed
``cuda:0`` only.  Refresh both to note that Fabric acceleration runs on
any CUDA index, so the autodoc API page reflects the actual contract.
Move the test-fabric-multi-gpu job out of test-multi-gpu.yaml and into
a dedicated test-fabric-multi-gpu.yaml.  The two workflows share the
same runner label, install step, and GPU pre-flight, but trigger on
disjoint path sets so changes to FabricFrameView no longer gate the
distributed-training validation and vice versa.

test-multi-gpu.yaml is now byte-identical to upstream/develop.
@pv-nvidia pv-nvidia force-pushed the feat/frame-view-enable-mgpu branch from c1254cd to 1c2e02d Compare May 13, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.