Skip to content

[Warp] Part 7/8: Add a Shadow Hand reorientation Warp twin and fix the Allegro twin - #6582

Draft
hujc7 wants to merge 76 commits into
isaac-sim:mainfrom
hujc7:jichuanh/task-cleanup-dex-warp-exp
Draft

hujc7 wants to merge 76 commits into
isaac-sim:mainfrom
hujc7:jichuanh/task-cleanup-dex-warp-exp

Conversation

@hujc7

@hujc7 hujc7 commented Jul 17, 2026 •

Copy link
Copy Markdown
Collaborator

Review Map

PR Status Depends on Exact changes
#8821 Part 1/8: shared id and mask helpers, mask writers without host sync — —
#8824 Part 2/8: PhysX tendon mask setters through the masks #8821 link
#6646 Part 3/8: mask-correct partial resets #8821 link
#8783 Part 4/8: shared Warp RNG state #6646 link
#6607 Part 5/8: per-term capture, stable stepping parity #8783 link
#8228 Part 6/8: Warp commands, Rough tasks, live term changes #6607 link
📌 #6582 Part 7/8: Shadow Warp twin, Allegro twin fixes #6607 link
#7012 Part 8/8: --video on the Warp frontend — —

Summary

Isaac-Reorient-Cube-Shadow-Direct runs under --frontend warp and trains like the stable task (last-50-iteration success 0.946 vs 0.941, 3 seeds each), and the Allegro Warp twin's orientation error (~π for identical orientations on main) and swapped object-velocity observation are fixed.
Scope is narrower than the original PR: Shadow only; the handover twin and the camera change are dropped.

Description

Update (2026-10-26): merged #6607 and, through it, #8821 and main dae8b799146; this PR's own diff is unchanged.

Update (2026-10-22): merged #6607 after #8783 (the shared Warp RNG state) was split out of #6646; this PR's own diff is unchanged.

Update (2026-10-20): merged #6607 and, through it, main 2dbb6146d75 (the default branch, renamed from develop; "main" below means main without this PR, measured at aa9bafef8a0). #8474 made the stable reorient goal_marker_position optional (None follows the hand); the Warp twin now does the same instead of failing to construct. After the merge, test_reorient_warp_env.py (4) and the capture tests pass, Allegro steps 300 and Shadow 1000 times under --frontend warp, and the environment browser is regenerated.

Update (2026-09-30) — rescoped: rebuilt on #6607 against develop (synced to f2f11b3f608). The handover Warp twin is parked (there is no Warp multi-agent environment), the camera commit is dropped (superseded by #7133), and the older dexterous commits already landed through #6413. No -Warp task IDs are registered.

1. Changes

  1. Allegro twin fixes (main):
    • rotation_distance read (y, z, w) of an xyzw quaternion, so identical orientations gave ~π and the rotation reward, success flag and goal resampling differed from stable.
    • The full observation swapped the object's linear and angular velocity (columns 39–44 differed from stable by up to 45.1).
  2. Shared reorient base: success computed once in _get_dones, resets through the public mask writers, constants from the config, Metrics/success_rate; asymmetric_obs raises NotImplementedError instead of silently omitting the critic observations.
  3. Shadow twin: ShadowHandDirectWarpEnv(ReorientDirectWarpEnv) commands the four finger tendons from the last four action columns, like the stable task; it is registered through the Warp frontend, with docs and the environment browser updated.

2. Evidence (MEASURED)

  • Same-state parity against the stable task, 64 envs × 120 steps (910a0ba9b90): Allegro observations within 2.4e-7, rewards 3.6e-5, 9/9 goal resamples match; Shadow observations 2.4e-7, rewards 7.8e-5; dones, successes and success_rate identical. Shadow joint trajectories were within 2.4e-5 rad before the main sync.
  • Over 40 captured steps with resets (9 on Shadow, 27 on Allegro), neither twin activates a wrench composer, so the captured reset stage never depends on the composer's host-side reset flag.
  • Training, rsl_rl, 8192 envs, Newton MJWarp, L40, configured iterations (Shadow 3000, Allegro 10000); last-50-iteration means:
Task Arm Success per seed Mean success Mean reward
Shadow Warp 0.943 / 0.945 / 0.950 0.946 6538
Shadow stable 0.942 / 0.937 / 0.945 0.941 6455
Allegro Warp 0.864 / 0.747 / 0.854 / 0.857 / 0.874 0.839 1556
Allegro stable 0.882 / 0.862 / 0.833 / 0.877 / 0.871 0.865 1808
  • Allegro: one Warp seed (0.747) falls below the stable range; Mann–Whitney two-sided exact p = 0.31 (success) and 0.55 (reward), so no difference is detectable at 5 seeds. Shadow: 3 seeds per arm, overlapping ranges.
  • The runs used earlier tips of this branch (0df4fd8981c; Allegro seeds 1–3 e2a36b3752c), before [Warp] Part 5/8: Capture Warp stages per term without warm-up and step like the stable environments #6607's log-copy fix, so the Warp arm's per-iteration success metric is the iteration's last value rather than its mean. Mean reward comes from rsl_rl's episode-return buffer and is unaffected. Parity was re-measured after each rebase.
  • test_reorient_warp_env.py fails on main (observation diff 5.79; rotation-mutation reward diff 0.60); at this tip it and the frontend, config-conversion and scene tests pass.
  • Docs build: sphinx-build -W --keep-going (the CI flags) on all five parts merged onto develop f2f11b3f608 succeeded with 0 warnings.

3. Out of scope / follow-ups

  • Handover Warp twin: needs a Warp multi-agent environment.
  • The Diagnostics/episode_min_orientation_error_* metrics of the stable task are not ported.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Release backport

  • Backport this pull request to the active release branch after it merges into main

Screenshots

Not applicable.

Checklist

Docker and GPU tests run on demand. Push the commits you want tested, then
comment run-ci on the pull request.

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with uv run isaaclab --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have validated the changed behavior with focused coverage and applied the test-audit criteria to any test changes
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump package versions — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@github-actions github-actions Bot added the isaac-lab Related to Isaac Lab team label Jul 17, 2026
@hujc7
hujc7 force-pushed the jichuanh/task-cleanup-dex-warp-exp branch from 4ec232a to 2047011 Compare July 18, 2026 11:10
hujc7 added a commit that referenced this pull request Jul 22, 2026
…isualizer teardown (#6411)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution.
- Links pin specific SHAs and can go stale after a branch update — the
table on #6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| #6410 [Docs] Environment overview regen |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| — | — |
| 📌 #6411 Part 1/8: Newton cloner/cubric/visualizer fixes (this PR) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | — |
| #6412 Part 2/8: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | — |
| #6413 Part 3/8: Reorient Direct, torch |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — | — |
| #6414 Part 4/8: MARL-to-single-agent fix + handover/camera Direct |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6414/changes/6e8a63e4e028b2d43676ea30c446b9dc9068c7b5..5cb00e7cb5cc813b202521272e043007cd255194)
|
| #6418 Part 5/8: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/79f87501ac4c81de93a71dab00dc443da62113aa..e7c9a9a3fae3a7972b0c5165ae683abffb7d0e0f)
|
| #6421 Part 6/8: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| #6413, #6414, #6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/01c9f4d8c5c35a5688b2a5bb90209e16b8f81b99..835a5815ec49b11aada1d20a76c177054505e6e7)
|
| #6415 Part 7/8: Benchmark success-rate utilities + docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| #6413, #6414, #6418, #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/e1abb6b1790ccc57af42551eebccf743633f1f13..d6348539aa8032d9668c20a8fea462c5d88d3af9)
|
| #6582 Part 8/8: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/21dbb1769c4e30c8e9e5b0f563c2dae24c230349..83e1587cadd9712a60615ed2a3cb2d177c2ac24d)
|
| #6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

- Fixes Newton cloner label rows, the cubric IAdapter version audit
(exact-match fallback to the CPU hierarchy path), and visualizer
teardown.
- Retains an in-tree `ignore_paths` workaround for custom-frequency USD
traversal; it becomes redundant once the Newton pin advance
(#6584) merges — this PR then
only needs a rebase.

## Stacking

- Independent; based on `develop`.

## Review history

- Approved. The Newton pin + MuJoCo overrides were split out to
#6584 via revert commits
(2026-07-17) so this PR's CI runs against develop's pins.
@hujc7
hujc7 force-pushed the jichuanh/task-cleanup-dex-warp-exp branch from 83e1587 to 167c285 Compare July 23, 2026 21:35
@github-actions github-actions Bot added the asset New asset feature or request label Jul 23, 2026
@hujc7 hujc7 changed the title [Task Clean-up] Dexterous Part 8/8: Move the warp Direct task variants to isaaclab_tasks_experimental [Task Clean-up] Dexterous Part 8/9: Move the warp Direct task variants to isaaclab_tasks_experimental Jul 23, 2026
@hujc7 hujc7 changed the title [Task Clean-up] Dexterous Part 8/9: Move the warp Direct task variants to isaaclab_tasks_experimental [Task Clean-up] Dexterous Part 9/9: Move the warp Direct task variants to isaaclab_tasks_experimental Jul 23, 2026
hujc7 added a commit that referenced this pull request Jul 24, 2026
…eorientation Direct tasks (#6413)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution.
- Links pin specific SHAs and can go stale after a branch update — the
table on #6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| #6411 Part 1/9: Newton cloner/cubric/visualizer fixes |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | merged |
| #6412 Part 2/9: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | merged |
| 📌 #6413 Part 3/9: Reorient Direct, torch (this PR) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6413/changes/f4895f0f9ee..d29afc75e71)
|
| #6414 Part 4/9: MARL-to-single-agent fix + handover/camera Direct |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6414/changes/d29afc75e71..b10a84948f8)
|
| #6418 Part 5/9: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/d29afc75e71..707d37f8f99)
|
| #6421 Part 6/9: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| #6413, #6414, #6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/707d37f8f99..b50ac8906fc)
|
| #6410 Part 7/9: Environment overview docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d)
|
| #6415 Part 8/9: Benchmark success-rate utilities |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b)
|
| #6582 Part 9/9: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3)
|
| #6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

- Adds a behavioral `Metrics/success_rate` signal (goal-reach streaks
per episode) and threshold-independent episode orientation-error
diagnostics to the Direct reorientation environments; success gates task
health, reward stays diagnostic.
- Task logic is **torch-first** per the mainline convention (plain torch
buffers; `.torch` accessors only at the core-lib boundary). This
supersedes the earlier warp-first revision of this PR; the warp
implementation moved to `isaaclab_tasks_experimental`
(#6582).
- Lands shared helpers in `isaaclab_tasks.core.utils`
(`EpisodeErrorRecorder`, `sample_joint_positions_within_limits`) with
torch math tests; fixes hand resets below lower joint limits.

## Stacking

- First stack PR; based on `develop`.

## Validation

- Kit-free torch math + utils tests green; Direct state training on
Newton: success rate 0.85–1.00, reward ≈3600–3900 at 2000 iterations,
frame-verified policy video. Full integrated evidence: #6324.

## Review history

- The earlier warp-era review rounds on this PR are superseded by the
torch restack (2026-07-16); the warp implementation and its
review-polished kernels live on in
#6582.

@AntoineRichard AntoineRichard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] Requesting changes. The current Part 9 head is not merge-ready: the new Gym registrations and environment modules contain stale imports, and the camera PhysX-default override is ineffective under the current PresetCfg resolution rules. The kernel tests are useful and pass on CPU/CUDA in CI, but they do not instantiate the registered environments; the current isaaclab_tasks [3/3] CI shard is red on the three Shadow Warp config loads.

Before re-review, please also tighten the source comments to durable functional constraints, remove hot-loop duplication/conversions called out inline, use concrete Warp array annotations on public launchers, and add an isaaclab_tasks changelog fragment for the camera-default change.

entry_point=reorient_warp_entry,
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{stable_shadow}.shadow_hand_env_cfg:ShadowHandEnvCfg",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] Blocking: shadow_hand_env_cfg.py no longer exists. All three Shadow Warp registrations in this file use this stale module name, and the current isaaclab_tasks [3/3] CI shard fails exactly these three config loads. Point them to shadow_hand_direct_env_cfg, then add a registry/config-load test covering every new ID so a successful kernel-only suite cannot mask broken entry points.

from isaaclab.sim.spawners.from_files import GroundPlaneCfg, spawn_ground_plane
from isaaclab.utils.math import sample_uniform

from isaaclab_tasks.core.reorient.reorient_task_base import GOAL_MARKER_POSITION, IN_HAND_POS_OFFSET

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] Blocking: reorient_task_base was removed; these constants now live in reorient_common. The TYPE_CHECKING import below also still names the removed shadow_hand_env_cfg instead of shadow_hand_direct_env_cfg. Once the registration strings are fixed, importing this environment will fail here, so please update both stale references and add an environment-entry import smoke test.

from isaaclab.utils.math import sample_uniform

from isaaclab_tasks.core.handover.handover_env_cfg import HandoverEnvCfg
from isaaclab_tasks.core.handover.handover_task_base import GOAL_POSITION_OFFSET

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] Blocking: handover_task_base.py does not exist in this head, and GOAL_POSITION_OFFSET has no current definition. This makes the new handover entry point fail on import. Please put the goal definition at a genuine shared boundary (configuration or a small common module used by both torch and Warp implementations) rather than restoring a single-consumer “task base,” and cover the registered entry point with a smoke test.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] The stable implementation currently hard-codes the goal at handover_env.py:73-77. That is the concrete duplication to remove: define one environment-frame GOAL_POSITION in handover_env_cfg.py or a handover_common.py, then make both HandoverEnv and HandoverWarpEnv consume it. Do not recreate the deleted handover_task_base.py solely to satisfy this import.

# for the depth-only Newton-warp-renderer benchmark path (``presets=newton_renderer``).
super().__post_init__()
for backend_cfg in (self.sim.physics, self.robot_cfg, self.object_cfg):
backend_cfg.default = backend_cfg.physx

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] Blocking: assigning default on these PresetCfg instances does not change preset resolution. _preset_fields() explicitly prefers the class attribute, so the inherited class-level Newton defaults still win and the camera remains Newton-default. Define camera-specific preset types or declarative preset(...) fields whose class-level default is PhysX, and add a collect_presets(ShadowHandCameraEnvCfg()) assertion for physics, robot, and object defaults. The preceding seven-line rationale should also become one functional sentence, e.g. “Isaac RTX tiled cameras require the PhysX Fabric cloning path”; benchmark CLI history belongs in tests/docs, not this method.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] The exact precedence rule is in _preset_fields(): getattr(type(preset_obj), field_name) wins over the instance field. The existing regression test_collect_fields_prefers_class_attr_over_instance codifies that behavior. Add the new camera-specific assertion beside the shadow_hand_camera_presets fixture, checking that sim.physics.default, robot_cfg.default, and object_cfg.default resolve to their PhysX alternatives.

# the goal-reset flags, success counts, and moving average update in place.
# passing the time-out flags alone is exact here: the kernel ORs in the
# fallen-object condition itself, and that is this env's only other reset
reorient_reward(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] The comment immediately above says reward reuses the success flags and orientation distances computed in _get_dones, but this call passes object/goal quaternions and reorient_reward_kernel recomputes _rotation_distance and the tolerance comparison. This is both misleading documentation and duplicate GPU hot-loop work. Pass success_flags and orientation_error_buf into the reward path, matching the torch implementation, and remove the redundant quaternion evaluation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] The stable torch path shows the intended API: ReorientDirectEnv._get_rewards() passes _success_flags and _orientation_error_buf into reorient_reward. By contrast, the Warp kernel recomputes both at reorient_kernels.py:283-288. Concretely, replace the object/target quaternion plus tolerance inputs with goal_reached: wp.array(dtype=wp.bool) and rotation_distance: wp.array(dtype=wp.float32), then use those values for the reset, bonus, and inverse-error reward.

ema_actuation_kernel,
dim=(self.num_envs, self._actuated_dof_ids_wp.shape[0]),
inputs=[
wp.from_torch(self.actions[agent]),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] The initialization comment claims the hot loop launches kernels without conversions, but wp.from_torch(self.actions[agent]) is created here and again in _hand_proprio_obs for both agents every step. Use persistent per-agent action tensors, copy incoming actions into them in _pre_physics_step, and cache their Warp views once, as the reorientation variant already does.

self.right_hand.write_joint_position_to_sim_index(position=dof_pos, env_ids=env_ids)
self.right_hand.write_joint_velocity_to_sim_index(velocity=dof_vel, env_ids=env_ids)

# reset left hand

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] The left-hand reset block duplicates the right-hand block above almost statement-for-statement. Please extract a _reset_hand(hand, prev_targets, curr_targets, env_ids) helper (or iterate a per-agent state map). This is exactly the kind of copied lifecycle code that drifts during follow-up fixes and is avoidable within this PR.



def reorient_reward(
reset_buf: wp.array,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] This public launcher uses generic wp.array annotations for every array argument, contrary to the repository requirement to annotate Warp arrays with concrete dimensionality and dtype. Please specify the actual contracts here (wp.bool, wp.float32, wp.vec3f, wp.quatf, and 2D float actions) and on the return type. compute_cube_keypoints() has the same issue.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] The concrete annotation map is: reset_buf/goal_resets → wp.array(dtype=wp.bool), successes/consecutive_successes → wp.array(dtype=wp.float32), positions/origins → wp.array(dtype=wp.vec3f), quaternions → wp.array(dtype=wp.quatf), actions → wp.array2d(dtype=wp.float32), and the return → wp.array(dtype=wp.float32). For compute_cube_keypoints, use wp.array2d(dtype=wp.float32) for poses and wp.array2d(dtype=wp.vec3f) for keypoints. This makes the public launcher contract match the typed kernel signatures instead of discarding their information.


"""Warp kernels and device math for the reorientation task family.

This is the family's math root: the experimental Direct environments and the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] Please reduce this module docstring to the module’s functional purpose. The long “math root”/step-order narrative is maintenance-heavy, and it claims manager terms consume these kernels even though the current tree only imports them from the experimental environments/tests. Keep execution contracts beside the relevant launcher; remove historical validation and aspirational dependency narration.


"""Warp kernels for the handover task family.

This is the family's math root: the experimental Direct environment launches

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review] This “math root” and “reverse dependency never exists” prose is architectural narration rather than a functional kernel contract. A concise module description plus precise function-level frame/unit comments is enough. In particular, retain useful invariants such as world-frame versus environment-frame positions, but remove commentary about how the codebase is intended to be organized.

@AntoineRichard AntoineRichard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Follow-up pass covering every comment/docstring block that violates the requested standard. Each inline note identifies the exact narration, restatement, stale claim, or hard-coded dimensional prose to remove or rewrite. Comments that encode coordinate frames, zero-copy lifetime, unavailable-sensor behavior, sticky state, or synchronization constraints are intentionally left untouched.

Comment on lines +125 to +131
# The vision env renders through the Isaac RTX tiled camera, whose render
# products require the Fabric cloning path. The Newton backend disables Fabric
# cloning (see the base env's ``clone_in_fabric`` scene preset), so under Newton
# the ``rgb`` annotator has no render products for ``num_envs > 1`` and the
# default RGB/depth/semantic render fails. Default the vision env to PhysX so it
# renders out of the box; Newton stays selectable via ``physics=newton_mjwarp``
# for the depth-only Newton-warp-renderer benchmark path (``presets=newton_renderer``).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Replace this seven-line narrative with one durable functional constraint: # Isaac RTX tiled cameras require the PhysX Fabric cloning path. The failure history, num_envs scenario, CLI spelling, and benchmark path belong in the regression test or user documentation, not in __post_init__.

Comment on lines +8 to +9
Experimental counterpart of the torch-first mainline implementation in
:mod:`isaaclab_tasks.core.handover`; see the reorient variant for the conventions.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Make this module docstring self-contained. “See the reorient variant for the conventions” forces readers to inspect an unrelated module and does not describe a functional contract. A single sentence such as Warp Direct environment for the Shadow handover task. is sufficient.

Comment on lines +49 to +91
# buffers for position targets
self.right_hand_prev_targets = torch.zeros(
(self.num_envs, self.num_hand_dofs), dtype=torch.float, device=self.device
)
self.right_hand_curr_targets = torch.zeros(
(self.num_envs, self.num_hand_dofs), dtype=torch.float, device=self.device
)
self.left_hand_prev_targets = torch.zeros(
(self.num_envs, self.num_hand_dofs), dtype=torch.float, device=self.device
)
self.left_hand_curr_targets = torch.zeros(
(self.num_envs, self.num_hand_dofs), dtype=torch.float, device=self.device
)

# list of actuated joints
self.actuated_dof_indices, _ = self.right_hand.find_joints(cfg.actuated_joint_names)
if len(self.actuated_dof_indices) != len(cfg.actuated_joint_names):
raise ValueError(
f"Expected {len(cfg.actuated_joint_names)} actuated joints, found {len(self.actuated_dof_indices)}."
)

# finger bodies
self.finger_bodies, _ = self.right_hand.find_bodies(self.cfg.fingertip_body_names)
if len(self.finger_bodies) != len(self.cfg.fingertip_body_names):
raise ValueError(
f"Expected {len(self.cfg.fingertip_body_names)} fingertip bodies, found {len(self.finger_bodies)}."
)
self.num_fingertips = len(self.finger_bodies)

# joint limits
joint_pos_limits = self.right_hand.data.joint_limits.torch.to(self.device)
self.hand_dof_lower_limits = joint_pos_limits[..., 0]
self.hand_dof_upper_limits = joint_pos_limits[..., 1]

# default goal positions
self.goal_rot = torch.zeros((self.num_envs, 4), dtype=torch.float, device=self.device)
self.goal_rot[:, 3] = 1.0 # identity quaternion in (x, y, z, w) layout
self.goal_pos = torch.zeros((self.num_envs, 3), dtype=torch.float, device=self.device)
# goal = object default position + shared offset (mirrors HandoverCommand.__init__)
self.goal_pos[:, :] = self.object.data.default_root_pose.torch[:, :3].to(self.device) + torch.tensor(
GOAL_POSITION_OFFSET, dtype=torch.float, device=self.device
)
# initialize goal marker

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Remove the labels on lines 49, 63, 70, 78, 83, and 91; each merely repeats the immediately following variable lookup/allocation. Also drop the historical mirrors HandoverCommand.__init__ clause on line 87. Once the goal definition is moved to a shared config/common boundary, its name should carry that relationship; if a comment remains, document only the coordinate frame or invariant.

self._success_flags = torch.empty(self.num_envs, dtype=torch.bool, device=self.device)
self._goal_distance_buf = torch.empty(self.num_envs, dtype=torch.float32, device=self.device)
self._reward_buf = torch.empty(self.num_envs, dtype=torch.float32, device=self.device)
# cached Warp views of the buffers above; the hot loop launches kernels without conversions

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] This comment is factually incorrect: action views are still created with wp.from_torch(...) in _apply_hand_action and _hand_proprio_obs every step. After introducing persistent per-agent action buffers, rewrite this narrowly as # Cache Warp views of persistent Torch buffers. Until then, remove it rather than claiming a property the implementation does not have.

Comment on lines +135 to +149
# add hand, in-hand object, and goal object
self.right_hand = Articulation(self.cfg.right_robot_cfg)
self.left_hand = Articulation(self.cfg.left_robot_cfg)
self.object = RigidObject(self.cfg.object_cfg)
# add ground plane
spawn_ground_plane(prim_path="/World/ground", cfg=GroundPlaneCfg())
src, dest = "/World/envs/env_0", "/World/envs/env_{}"
pos = cloner.grid_transforms(self.scene.num_envs, self.scene.cfg.env_spacing, device=self.device)[0]
plan = cloner.ClonePlan.from_env_0(src, dest, self.scene.num_envs, self.device, pos)
cloner.replicate(plan, stage=self.scene.stage)
# add articulation to scene - we must register to scene to randomize with EventManager
self.scene.articulations["right_robot"] = self.right_hand
self.scene.articulations["left_robot"] = self.left_hand
self.scene.rigid_objects["object"] = self.object
# add lights

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Remove # add hand..., # add ground plane, and # add lights; they only narrate the next constructor/call. Keep the EventManager constraint on line 145, but tighten it to the functional reason: # Register assets with the scene for EventManager randomization.

Comment on lines +614 to +616
Launched over ``(num_envs, obs_dim)``: each thread walks a branch ladder over the
segment boundaries and writes one output column, so warps (32 consecutive columns)
stay branch-uniform except at segment boundaries.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Keep the launch shape, but remove the speculative warp-uniformity explanation. The branch behavior is an implementation/performance claim without a benchmark or enforced invariant and makes this already-long observation docstring harder to scan.

Comment on lines +55 to +57
Launched over ``(num_envs, obs_dim)``: each thread walks a branch ladder over the
segment boundaries and writes one output column, so warps (32 consecutive columns)
stay branch-uniform except at segment boundaries.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Keep the launch shape and output layout, but remove the warp-uniformity narrative. It is an implementation/performance claim rather than the kernel’s functional contract and duplicates the same prose in full_obs_kernel.

reward: wp.array(dtype=wp.float32),
):
i = wp.tid()
# Direct handover reward: exponential falloff with object-goal distance

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Remove this line; handover_reward_kernel, goal_distance, and the immediately following exponential expression already state exactly what it says.

device=device,
)
torch.testing.assert_close(dist, _rotation_distance_ref(q1, q2), atol=1e-4, rtol=1e-4)
# identical quaternions have zero distance

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Remove this comment. The test inputs (q1, q1.clone()), assertion, and test name make the zero-distance case self-explanatory.

buffers=buffers,
**params,
)
# torch reference

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Comment cleanup] Remove this generic label. The _ref variable names and subsequent assertions already distinguish the Torch reference computation from the Warp result.

@AntoineRichard AntoineRichard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] Three additional places where the review should name the exact missing coverage or ownership boundary, rather than leaving the fixer to infer it.

Added
^^^^^

* Added warp-first Direct variants of the Shadow cube reorientation and handover

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] Part 9 also changes source/isaaclab_tasks/.../shadow_hand_camera_env_cfg.py, but this is the only fragment added by the Part 9 commit range. The inherited source/isaaclab_tasks/changelog.d/task-cleanup-dex-part03.minor.rst belongs to Part 3 and does not mention the camera default; after the stack is rebased, Part 9 will touch isaaclab_tasks with no fragment. Either move commit 386272f2 to its owning stable-task PR or add a separate source/isaaclab_tasks/changelog.d/<slug>.rst Fixed entry for the camera backend default.

Comment on lines +8 to +10
Kit-free: imports only torch/warp and the kernel module. Every kernel is
checked against an independent torch reference implementation on randomized
inputs, on CPU and CUDA.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] Keep these kernel tests Kit-free, but add a separate registration smoke test because these 44 cases never load an env_cfg_entry_point or import either environment class. The current CI failure proves the gap: parameterize the four new Gym IDs, resolve each config entry point, and import its environment entry point. That test would fail on all five stale references currently present (shadow_hand_env_cfg ×3, reorient_task_base, and handover_task_base) while preserving this file’s focused kernel contract.

self.episode_length_buf_warp,
self._orientation_error.minimum_error,
self.time_out_flags,
self._orientation_error._has_sample,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AI Review][Pointed follow-up] This reaches into EpisodeErrorRecorder._has_sample, a private field owned by isaaclab_tasks.core.utils, and makes the experimental kernel depend on that class’s internal storage layout. EpisodeErrorRecorder.update() is the public boundary and also owns shape/finite-value semantics. Expose an explicit Warp-compatible recorder API/buffer contract, or keep Warp-owned minimum/sample buffers in this environment and pass summarized values to the recorder at reset; do not bind a kernel output directly to another class’s private attribute.

hujc7 added a commit that referenced this pull request Jul 29, 2026
… and enable handover Direct RSL-RL (#6414)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution. This PR (#6414) is now rebased directly onto
`develop`, so its own **Files changed** tab is its contribution.
- Links pin specific SHAs and can go stale after a branch update — the
table on #6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| #6411 Part 1/9: Newton cloner/cubric/visualizer fixes |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | merged |
| #6412 Part 2/9: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | merged |
| #6413 Part 3/9: Reorient Direct, torch |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — | merged |
| 📌 #6414 Part 4/9: MARL-to-single-agent fix + handover/camera Direct
(this PR) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| — (on develop) | Files changed tab |
| #6418 Part 5/9: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/d29afc75e71..707d37f8f99)
|
| #6421 Part 6/9: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| #6414, #6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/707d37f8f99..b50ac8906fc)
|
| #6410 Part 7/9: Environment overview docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d)
|
| #6415 Part 8/9: Benchmark success-rate utilities |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b)
|
| #6582 Part 9/9: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3)
|
| #6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

Converts the two-hand Shadow Hand **handover** task from multi-agent
(MARL) to **single-agent** (enabling RSL-RL training), fixes the
underlying MARL→single-agent observation bridge, and consolidates the
shared Shadow Hand definitions into the asset.

- **MARL → single-agent bridge (general, broader than this task).**
Single-agent RL libraries train `DirectMARLEnv` tasks via
`multi_agent_to_single_agent`; the bridge dropped the latest
observations from the public buffer. Fixed generally — RSL-RL
observations read from the env-owned `obs_buf`, stored by `reset` like
`step` on all env bases (`DirectRLEnv`, `DirectMARLEnv`, the
experimental warp base). Every MARL task + single-agent runner benefits;
handover is the first consumer.
- **Handover Direct → single-agent + RSL-RL.** Single-agent conversion,
RSL-RL runner config, shared identity in `handover_common`, success-rate
reward metrics, and a fix for its Newton construction failure (see
below).
- **Shadow Hand Newton robot → the asset.** Moved the Newton (MJWarp)
robot cfg into `isaaclab_assets` as `SHADOW_HAND_NEWTON_CFG` (beside
`SHADOW_HAND_CFG`); reorient and handover consume it as **siblings**
(neither imports the other). Reorient uses the default gains; handover
overrides only the finger stiffness/damping to `20/2` for its catch.
- **Shadow camera cleanup.** Renamed the camera Direct modules to
`shadow_hand_direct_camera_env[_cfg]`; moved cube-keypoint math to the
shared, unit-tested `reorient/mdp/observations.py` (replacing the
per-env `compute_keypoints` shim); and added OVPhysX physics presets to
the handover and camera Direct environments. The camera env config is
otherwise unchanged from develop.

### Behavior changes

**Reorient-on-Newton is unchanged.** The Newton hand definition moves
**verbatim** into `SHADOW_HAND_NEWTON_CFG` — same joint expressions,
effort limits, gains, friction and armature — so its config diff vs
`develop` is purely the move, and the Direct env config has no diff at
all.

Handover changes in three ways:

- Its **default physics backend moves from PhysX to Newton** (MJWarp),
matching the reorientation tasks. Pass `physics=physx` for the previous
backend.
- Its `distal_passive` actuator group is **removed**. It targeted
`robot0_(FF|MF|RF|LF)J0` — joints that **do not exist** on the Newton
asset (its fingers are numbered `J1`–`J4`/`J5`), so constructing the
environment raised `No joints found for actuator group`. The `fingers`
group already drives those joints, and the comment justifying the group
(USD-baked `stiffness=286/damping=57`) does not apply to this asset,
which authors no drive stiffness at all.
- Two orientation fixes: the goal orientation was initialized to a
180-degree rotation instead of identity, and the Newton root rotation
replaced the asset's baked rotation instead of composing with it,
leaving both palms rotated 90 degrees.

Two pre-existing discrepancies were found while verifying against the
asset and are left for a follow-up, since each is a behavior change
needing its own validation: the config sets `armature=2e-3` where the
asset authors `0.0002`, and the per-finger `J1`/`J2` pair is coupled by
a fixed tendon that the MJWarp solver currently skips — the actuator
gains are what hold that pair together today, which is why the `J4`
knuckle-abduction joints cannot simply be added to the driven set.

## Notes

- Rebased onto **latest develop**; clean 3-commit history: `Add
single-agent flattening for MARL Direct environments` / `Convert Shadow
Hand handover to single-agent Direct with RSL-RL` / `Clean up Shadow
reorient/camera tasks and consolidate the Newton hand`.

## Validation

- Kit-free suite green: handover, keypoint math, the MARL adapter, and
new checks pinning the RSL-RL wrapper observation contract (verified to
fail against the previous implementation).
- Camera Direct reaches training takeoff under `rsl_rl` (frame-verified
videos); its env config now matches develop's established vision env.
- **Reorient-on-Newton vs `develop`** (`rsl_rl`, 2048 envs, 1500
iterations, 4 runs per config): this branch spans 524–664 reward,
`develop` spans 654–822 — overlapping distributions whose per-config
spreads (140–168) exceed the gap between them. The move is additionally
verified at the config level: the Newton robot configuration is
character-for-character identical to `develop`'s.
- **Handover-on-Newton** trains end-to-end on this branch (reward 1314),
which the `develop` config cannot do at all — it fails during
construction. Full evidence: #6324.
matthewtrepte pushed a commit to matthewtrepte/IsaacLab that referenced this pull request Aug 4, 2026
…isualizer teardown (isaac-sim#6411)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution.
- Links pin specific SHAs and can go stale after a branch update — the
table on isaac-sim#6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| isaac-sim#6410 [Docs] Environment overview regen |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| — | — |
| 📌 isaac-sim#6411 Part 1/8: Newton cloner/cubric/visualizer fixes (this PR) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | — |
| isaac-sim#6412 Part 2/8: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | — |
| isaac-sim#6413 Part 3/8: Reorient Direct, torch |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — | — |
| isaac-sim#6414 Part 4/8: MARL-to-single-agent fix + handover/camera Direct |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6414/changes/6e8a63e4e028b2d43676ea30c446b9dc9068c7b5..5cb00e7cb5cc813b202521272e043007cd255194)
|
| isaac-sim#6418 Part 5/8: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/79f87501ac4c81de93a71dab00dc443da62113aa..e7c9a9a3fae3a7972b0c5165ae683abffb7d0e0f)
|
| isaac-sim#6421 Part 6/8: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| isaac-sim#6413, isaac-sim#6414, isaac-sim#6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/01c9f4d8c5c35a5688b2a5bb90209e16b8f81b99..835a5815ec49b11aada1d20a76c177054505e6e7)
|
| isaac-sim#6415 Part 7/8: Benchmark success-rate utilities + docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| isaac-sim#6413, isaac-sim#6414, isaac-sim#6418, isaac-sim#6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/e1abb6b1790ccc57af42551eebccf743633f1f13..d6348539aa8032d9668c20a8fea462c5d88d3af9)
|
| isaac-sim#6582 Part 8/8: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/21dbb1769c4e30c8e9e5b0f563c2dae24c230349..83e1587cadd9712a60615ed2a3cb2d177c2ac24d)
|
| isaac-sim#6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

- Fixes Newton cloner label rows, the cubric IAdapter version audit
(exact-match fallback to the CPU hierarchy path), and visualizer
teardown.
- Retains an in-tree `ignore_paths` workaround for custom-frequency USD
traversal; it becomes redundant once the Newton pin advance
(isaac-sim#6584) merges — this PR then
only needs a rebase.

## Stacking

- Independent; based on `develop`.

## Review history

- Approved. The Newton pin + MuJoCo overrides were split out to
isaac-sim#6584 via revert commits
(2026-07-17) so this PR's CI runs against develop's pins.
matthewtrepte pushed a commit to matthewtrepte/IsaacLab that referenced this pull request Aug 4, 2026
…eorientation Direct tasks (isaac-sim#6413)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution.
- Links pin specific SHAs and can go stale after a branch update — the
table on isaac-sim#6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| isaac-sim#6411 Part 1/9: Newton cloner/cubric/visualizer fixes |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | merged |
| isaac-sim#6412 Part 2/9: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | merged |
| 📌 isaac-sim#6413 Part 3/9: Reorient Direct, torch (this PR) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6413/changes/f4895f0f9ee..d29afc75e71)
|
| isaac-sim#6414 Part 4/9: MARL-to-single-agent fix + handover/camera Direct |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6414/changes/d29afc75e71..b10a84948f8)
|
| isaac-sim#6418 Part 5/9: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/d29afc75e71..707d37f8f99)
|
| isaac-sim#6421 Part 6/9: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| isaac-sim#6413, isaac-sim#6414, isaac-sim#6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/707d37f8f99..b50ac8906fc)
|
| isaac-sim#6410 Part 7/9: Environment overview docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| isaac-sim#6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d)
|
| isaac-sim#6415 Part 8/9: Benchmark success-rate utilities |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| isaac-sim#6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b)
|
| isaac-sim#6582 Part 9/9: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3)
|
| isaac-sim#6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

- Adds a behavioral `Metrics/success_rate` signal (goal-reach streaks
per episode) and threshold-independent episode orientation-error
diagnostics to the Direct reorientation environments; success gates task
health, reward stays diagnostic.
- Task logic is **torch-first** per the mainline convention (plain torch
buffers; `.torch` accessors only at the core-lib boundary). This
supersedes the earlier warp-first revision of this PR; the warp
implementation moved to `isaaclab_tasks_experimental`
(isaac-sim#6582).
- Lands shared helpers in `isaaclab_tasks.core.utils`
(`EpisodeErrorRecorder`, `sample_joint_positions_within_limits`) with
torch math tests; fixes hand resets below lower joint limits.

## Stacking

- First stack PR; based on `develop`.

## Validation

- Kit-free torch math + utils tests green; Direct state training on
Newton: success rate 0.85–1.00, reward ≈3600–3900 at 2000 iterations,
frame-verified policy video. Full integrated evidence: isaac-sim#6324.

## Review history

- The earlier warp-era review rounds on this PR are superseded by the
torch restack (2026-07-16); the warp implementation and its
review-polished kernels live on in
isaac-sim#6582.
matthewtrepte pushed a commit to matthewtrepte/IsaacLab that referenced this pull request Aug 4, 2026
… and enable handover Direct RSL-RL (isaac-sim#6414)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution. This PR (isaac-sim#6414) is now rebased directly onto
`develop`, so its own **Files changed** tab is its contribution.
- Links pin specific SHAs and can go stale after a branch update — the
table on isaac-sim#6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| isaac-sim#6411 Part 1/9: Newton cloner/cubric/visualizer fixes |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | merged |
| isaac-sim#6412 Part 2/9: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | merged |
| isaac-sim#6413 Part 3/9: Reorient Direct, torch |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — | merged |
| 📌 isaac-sim#6414 Part 4/9: MARL-to-single-agent fix + handover/camera Direct
(this PR) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| — (on develop) | Files changed tab |
| isaac-sim#6418 Part 5/9: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| isaac-sim#6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/d29afc75e71..707d37f8f99)
|
| isaac-sim#6421 Part 6/9: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| isaac-sim#6414, isaac-sim#6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/707d37f8f99..b50ac8906fc)
|
| isaac-sim#6410 Part 7/9: Environment overview docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| isaac-sim#6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d)
|
| isaac-sim#6415 Part 8/9: Benchmark success-rate utilities |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| isaac-sim#6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b)
|
| isaac-sim#6582 Part 9/9: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3)
|
| isaac-sim#6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

Converts the two-hand Shadow Hand **handover** task from multi-agent
(MARL) to **single-agent** (enabling RSL-RL training), fixes the
underlying MARL→single-agent observation bridge, and consolidates the
shared Shadow Hand definitions into the asset.

- **MARL → single-agent bridge (general, broader than this task).**
Single-agent RL libraries train `DirectMARLEnv` tasks via
`multi_agent_to_single_agent`; the bridge dropped the latest
observations from the public buffer. Fixed generally — RSL-RL
observations read from the env-owned `obs_buf`, stored by `reset` like
`step` on all env bases (`DirectRLEnv`, `DirectMARLEnv`, the
experimental warp base). Every MARL task + single-agent runner benefits;
handover is the first consumer.
- **Handover Direct → single-agent + RSL-RL.** Single-agent conversion,
RSL-RL runner config, shared identity in `handover_common`, success-rate
reward metrics, and a fix for its Newton construction failure (see
below).
- **Shadow Hand Newton robot → the asset.** Moved the Newton (MJWarp)
robot cfg into `isaaclab_assets` as `SHADOW_HAND_NEWTON_CFG` (beside
`SHADOW_HAND_CFG`); reorient and handover consume it as **siblings**
(neither imports the other). Reorient uses the default gains; handover
overrides only the finger stiffness/damping to `20/2` for its catch.
- **Shadow camera cleanup.** Renamed the camera Direct modules to
`shadow_hand_direct_camera_env[_cfg]`; moved cube-keypoint math to the
shared, unit-tested `reorient/mdp/observations.py` (replacing the
per-env `compute_keypoints` shim); and added OVPhysX physics presets to
the handover and camera Direct environments. The camera env config is
otherwise unchanged from develop.

### Behavior changes

**Reorient-on-Newton is unchanged.** The Newton hand definition moves
**verbatim** into `SHADOW_HAND_NEWTON_CFG` — same joint expressions,
effort limits, gains, friction and armature — so its config diff vs
`develop` is purely the move, and the Direct env config has no diff at
all.

Handover changes in three ways:

- Its **default physics backend moves from PhysX to Newton** (MJWarp),
matching the reorientation tasks. Pass `physics=physx` for the previous
backend.
- Its `distal_passive` actuator group is **removed**. It targeted
`robot0_(FF|MF|RF|LF)J0` — joints that **do not exist** on the Newton
asset (its fingers are numbered `J1`–`J4`/`J5`), so constructing the
environment raised `No joints found for actuator group`. The `fingers`
group already drives those joints, and the comment justifying the group
(USD-baked `stiffness=286/damping=57`) does not apply to this asset,
which authors no drive stiffness at all.
- Two orientation fixes: the goal orientation was initialized to a
180-degree rotation instead of identity, and the Newton root rotation
replaced the asset's baked rotation instead of composing with it,
leaving both palms rotated 90 degrees.

Two pre-existing discrepancies were found while verifying against the
asset and are left for a follow-up, since each is a behavior change
needing its own validation: the config sets `armature=2e-3` where the
asset authors `0.0002`, and the per-finger `J1`/`J2` pair is coupled by
a fixed tendon that the MJWarp solver currently skips — the actuator
gains are what hold that pair together today, which is why the `J4`
knuckle-abduction joints cannot simply be added to the driven set.

## Notes

- Rebased onto **latest develop**; clean 3-commit history: `Add
single-agent flattening for MARL Direct environments` / `Convert Shadow
Hand handover to single-agent Direct with RSL-RL` / `Clean up Shadow
reorient/camera tasks and consolidate the Newton hand`.

## Validation

- Kit-free suite green: handover, keypoint math, the MARL adapter, and
new checks pinning the RSL-RL wrapper observation contract (verified to
fail against the previous implementation).
- Camera Direct reaches training takeoff under `rsl_rl` (frame-verified
videos); its env config now matches develop's established vision env.
- **Reorient-on-Newton vs `develop`** (`rsl_rl`, 2048 envs, 1500
iterations, 4 runs per config): this branch spans 524–664 reward,
`develop` spans 654–822 — overlapping distributions whose per-config
spreads (140–168) exceed the gap between them. The move is additionally
verified at the config level: the Newton robot configuration is
character-for-character identical to `develop`'s.
- **Handover-on-Newton** trains end-to-end on this branch (reward 1314),
which the `develop` config cannot do at all — it fails during
construction. Full evidence: isaac-sim#6324.
@hujc7 hujc7 changed the title [Task Clean-up] Dexterous Part 9/9: Move the warp Direct task variants to isaaclab_tasks_experimental [Task Clean-up] Dexterous Part 10/10: Move the warp Direct task variants to isaaclab_tasks_experimental Aug 7, 2026
hujc7 added a commit that referenced this pull request Aug 11, 2026
…anager counterparts (#6418)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution.
- Links pin specific SHAs and can go stale after a branch update — this
table on #6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| #6411 Part 1/10: Newton cloner/cubric/visualizer fixes |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6411?label=)
| — | merged |
| #6412 Part 2/10: OVPhysX articulation + manager runtime |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6412?label=)
| — | merged |
| #6413 Part 3/10: Reorient Direct, torch |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6413?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6413/changes/f4895f0f9ee..d29afc75e71)
|
| #6414 Part 4/10: MARL-to-single-agent fix + handover/camera Direct |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6414?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6414/changes/d29afc75e71..b10a84948f8)
|
| 📌 #6418 Part 5/10: Reorient manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6418?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/3ea6f7bbf6c..0271783ea17)
|
| #6421 Part 6/10: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| #6413, #6414, #6418 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/b31b04eaf71..0cae3d87be4)
|
| #6410 Part 7/10: Environment overview docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d)
|
| #6954 Part 8/10: OpenAI Shadow variants → contrib (draft) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6954?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6954/changes/0cae3d87be4..b0d2d8448af)
|
| #6415 Part 9/10: Benchmark success-rate utilities |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b)
|
| #6582 Part 10/10: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| #6413 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3)
|
| #6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

Adds manager-based counterparts for the Shadow cube reorientation task
and aligns the existing
Allegro manager task with the Direct contracts.

- **3 manager tasks** mirror their Direct counterparts:
`Isaac-Reorient-Cube-Shadow`,
  `-Shadow-Camera` and `-Allegro`.
- The OpenAI variants move to the contributed tasks **unchanged**. They
encode a paper-specific
  training regime, so they get no manager counterpart.
- `Metrics/success_rate` now means the same thing in both workflows.
- The in-hand cube is one object per hand instead of one per physics
backend.

## 1. Manager tasks match the Direct contracts

Observations, actions, rewards, terminations, reset distributions and
timing were brought to the
Direct values. A value-parity test asserts the decimation / episode
length / simulation step
triple, the orientation success tolerance and the fall distance, so
drift on either side fails CI.

The Allegro observation space changes size, so existing manager
checkpoints must be retrained.
Domain randomization becomes opt-in through `presets=randomized`,
replacing a configuration-file
flag that the command line could not override.

## 2. OpenAI variants move to the contributed tasks

`Isaac-Reorient-Cube-Shadow-OpenAI-{FF,LSTM}-Direct` become
`IsaacContrib-Reorient-Cube-Shadow-OpenAI-{FF,LSTM}-Direct`. Both
identifiers are kept: they share
one environment configuration and differ only in their agent
configuration, so collapsing them
would leave the recurrent policy unreachable — the training entry point
selects an agent
configuration by workflow, not by name.

## 3. One success rate, defined once

`Metrics/success_rate` named two quantities. The manager tasks reported
goals reached over goals
presented; the Direct tasks reported a per-episode success bit drawn at
`success_count_threshold`.
The curves were not comparable despite sharing a name and measuring the
same task.

Both now report the per-attempt rate, and `success_count_threshold` is
removed as unused. The goal
accounting moves into a `SuccessTracker` beside `EpisodeErrorRecorder`,
which also suppresses
success detection for the single step after an automatic reset — where
the goal has been drawn but
no physics has run against it, so a reset pose inside the success
threshold would otherwise bank a
goal the policy never earned.

## 4. One in-hand cube per hand, not per backend

The cube was a `PresetCfg` with a variant per physics backend, so each
hand manipulated a different
object depending on the backend. On Shadow the branches disagreed on
size and spawn height: PhysX
spawned a 60 mm rigid body at `z=0.6`, Newton a 54 mm **articulation
with no joints** at `z=0.535`.
A policy trained on one backend was not solving the same task as one
trained on the other.

Each hand now declares a single `CUBE_CFG`. Shadow keeps the PhysX
values; Allegro keeps its 1.2
scale. The `mass_props` density overrides are dropped: the asset authors
an absolute `physics:mass`
of 0.216 kg, which takes precedence over density, so they never applied
on either backend.

## 5. Configuration hierarchy flattened, classes named by role

Every manager task overrode all seven of the shared base's
sub-configurations, so the base carried
pre-alignment defaults that each task then undid. The environment
configurations now derive from
`ManagerBasedRLEnvCfg` directly. Removed: `ReorientObjectEnvCfg`, the
shared sub-configurations no
task constructed, and `reorient_common`. `isaaclab_tasks.core.utils`
moves to
`isaaclab_tasks.core.reorient.utils`, which the hand-over task already
imports from.

One naming convention now applies throughout, since `SceneCfg`,
`EventCfg` and
`ObservationsCfg` are each defined in dozens of files and gave no clue
which base a task
was specializing. Classes shared across files carry the task prefix; the
`Base` suffix
marks only those a subclass must complete by supplying fields the parent
leaves unset, so
the observation halves are named as parts rather than templates. Classes
nested inside
another configuration drop the prefix. Registered and preset-selectable
configurations
always name their task and hold fields only, with their helpers declared
beside them.

## Validation

Eight arms, 1500 iterations, 8192 environments, `physics=newton_mjwarp`,
one L40 each. All exited
cleanly with no regression in reward.

| Arm | reward before | reward after |
|---|---|---|
| `Isaac-Reorient-Cube-Shadow` | 67.08 | 66.24 |
| `-Shadow` `presets=asymmetric` | 42.08 | 52.95 |
| `-Shadow-Direct` | 3532.95 | 3967.58 |
| `-Allegro` | 25.22 | 34.03 |
| `-Allegro` `presets=randomized` | 16.03 | 39.59 |
| `-Allegro-Direct` | 656.78 | 1003.11 |
| `IsaacContrib-…-OpenAI-FF-Direct` | 2757.56 | 4533.21 |
| `IsaacContrib-…-OpenAI-LSTM-Direct` | — | 2585.54 |

The LSTM arm resolves `ShadowHandAsymLSTMPPORunnerCfg`, confirming the
recurrent policy is reachable
through its own identifier.

### Known failure

`test_rendering_shadow_hand[newton-isaacsim_rtx-rgb]` fails; it passes
on `develop`. Only the `rgb`
modality is affected — depth, normals and all three segmentations pass
on the same backend, so the
cube move is not an obvious explanation. Root cause is not yet
established.
hujc7 added a commit that referenced this pull request Aug 17, 2026
…mera manager counterparts (#6421)

## Review Map

- **Exact changes**: a stacked PR's page shows the cumulative diff of
its dependency chain; the link pins the commit range that is the PR's
own contribution.
- Links pin specific SHAs and can go stale after a branch update — this
table on #6324 is refreshed first.

| PR | Status | Depends on | Exact changes |
|---|---|---|---|
| 📌 #6421 Part 6/10: Handover + camera manager counterparts |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6421?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/b31b04eaf71..0cae3d87be4)
|
| #6410 Part 7/10: Environment overview docs |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6410?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d)
|
| #6415 Part 9/10: Benchmark success-rate utilities |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6415?label=)
| #6421 |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b)
|
| #6582 Part 10/10: Warp variants → experimental (draft; merges last) |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6582?label=)
| — |
[changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3)
|
| #6324 [DO-NOT-MERGE] Lumped validation reference |
![](https://img.shields.io/github/pulls/detail/state/isaac-sim/IsaacLab/6324?label=)
| ALL | — |

## Summary

Completes manager coverage of the dexterous task families by adding
manager-based
counterparts for the Shadow handover and Shadow camera reorientation
tasks.

- **2 manager tasks** added: `Isaac-Shadow-Handover` and
`Isaac-Reorient-Cube-Shadow-Camera`.
- **The last 2 `-Play` registrations** in `isaaclab_tasks` are removed.

## 1. Handover manager counterpart

The fused handover reward became a plain reward term, with success and
goal-distance
bookkeeping moved to `HandoverCommand`, which owns the goal. It reports
`Metrics/success_rate` as a per-episode bit, matching the handover
Direct environment.

`HandoverCommand.command` builds its pose per call rather than returning
a persistent
buffer, so consumers that store it across steps are not aliased to live
data.

The task keeps no observation, reset or event code of its own. Every
observation is a
framework term or a reorientation one: fingertip pose is `body_pose_w`,
the object block
is the root pose, root velocities, the generated command and the
reorientation
goal-quaternion difference, and only the fingertip velocity stays
task-local because the
framework has no `body_vel_w`. Both hands reset through the
reorientation hand reset, one
term per hand. The object and goal block was previously observed once
per agent with
identical values, so a single copy now carries the same information.

`presets=randomized` adds the domain-randomization terms to the reset,
matching how the
reorientation manager tasks expose theirs.

The reset and action observations use the framework terms rather than
task-local ones,
following Part 5: the object resets through
`reset_root_state_with_random_orientation`
and both hands observe `last_action`, leaving only the two-hand joint
and PD-target
reset task-local. This samples the object's reset orientation uniformly
over SO(3)
where the Direct task composes X/Y rotations, and reports zero actions
on the reset
step where the Direct task reports the pre-reset action.

## 2. Camera manager counterpart

The camera task runs on PhysX by default: the RTX render modalities
require Fabric
cloning, which Newton does not support, so the inherited default could
not render.
Newton remains selectable with `physics=newton_mjwarp` for the
state-only observation
groups.

The feature-extractor observation term ignored its declared
`feature_extractor_cfg`
parameter and read the environment configuration instead; it now honours
the parameter.

## 3. Camera playback moves to `play_mode`

`Isaac-Reorient-Cube-Shadow-Camera-Play` and `-Camera-Direct-Play` were
the last `-Play`
registrations left in `isaaclab_tasks`; every other task moved to
`play_mode` in
#6676 — Remove the _PLAY
configs. Their
playback environment count and inference feature extractor now live in
`play_mode`
overrides on the manager and Direct camera configurations.

The override mutates the feature extractor rather than replacing it.
Replacing the
object resets every field the caller does not name, which silently
re-enabled the CNN
in `ShadowHandCameraBenchmarkEnvCfg` — a configuration whose entire
purpose is to
disable it.

## 4. Reorientation action configuration

The action term is named through a module path, so loading a task
configuration no
longer imports the USD bindings.

## Validation

Trained at 4096 environments, 1500 iterations, seed 42, on one L40
(`jichuanh-autorun-8gpu`). Success rate is logged per reset batch, so
the figures below
are the mean and range over the final eight batches rather than a single
value.

| Task | Backend | Success rate | Range |
|---|---|---|---|
| `Isaac-Shadow-Handover` (manager) | `newton_mjwarp` | 0.756 | 0.745 -
0.779 |
| `Isaac-Shadow-Handover-Direct` (reference) | `newton_mjwarp` | 0.697 |
0.563 - 0.875 |
| `Isaac-Shadow-Handover` (manager) | `isaacsim_physx` | 0.999 | 0.992 -
1.000 |

The manager task matches the Direct reference it replaces on the same
backend. The
spread between backends is a pre-existing property of the Newton Shadow
Hand actuation,
not something this pull request introduces; it is tracked separately.

`Isaac-Reorient-Cube-Shadow-Camera` was smoke-tested rather than trained
to convergence:
300 iterations at 256 environments through the Kit renderer completes
cleanly. Its
rendering matrix and golden images are covered separately.

`presets=randomized` converges more slowly than the default and does not
plateau within
1500 iterations. A longer run is in progress to set an appropriate
iteration budget.
A mask-only Articulation.reset called ActuatorCollection.reset(None), which
cleared delay buffers, network history, and Newton-native actuator state for
every environment. Newton rigid objects and collections dropped the mask
before resetting their wrench composers, clearing every environment's
persistent wrench.

ActuatorCollection.reset now takes env_mask. Isaac Lab actuator models still
reset by index, so the collection converts the mask to indices once for all
groups, and skips the conversion when no group carries reset state. Native
actuator state resets from the mask through a new
ActuatorControl.reset_native_actuators_mask hook; Newton and OVPhysX pass the
mask to the Newton actuator adapter, and the base default converts to indices
so backends that only implement the index hook stay correct.
InteractiveSceneWarp.reset passed env_ids=None to deformable objects, surface
grippers, and sensors on a masked reset, so every environment's sensor state
was cleared on each partial reset, and it never reset cable objects.

Forward the mask to every entity family in the stable scene's order. Surface
grippers use their reset_mask method. Cable objects take env_mask like the
other scene assets, so the scene does not convert the mask for a reset that
holds no state.
hujc7 added 10 commits October 20, 2026 09:55
…nup-dex-warp-exp

# Conflicts:
#	docs/source/_static/css/environment-browser.js
Revert 6ac6061 and 9328d98: the process-wide WarpRng state moves to its own pull request stacked on this one. The ray caster, Warp environments, MDP terms, managers, noise models and Warp tasks keep their own RNG arrays here, as on main.
Environments initialize WarpRng once at construction and configure_seed reseeds it in place. The ray caster, experimental managers, events, noise models and Warp tasks read WarpRng.state instead of keeping their own copies; rng_state_wp is removed.

Re-applies 6ac6061 and 9328d98, split out of the masked-reset pull request.
@hujc7 hujc7 changed the title [Warp] Part 4/5: Add a Shadow Hand reorientation Warp twin and fix the Allegro twin [Warp] Part 5/6: Add a Shadow Hand reorientation Warp twin and fix the Allegro twin Oct 22, 2026
hujc7 added 11 commits October 26, 2026 02:48
…pers

resolve_ids resolves ids or a boolean mask to ids on a device, as resolve_1d_mask does to a mask. resolve_1d_mask takes an optional scratch mask, copies a Warp mask on another device, and accepts a boolean torch mask on its device inside a graph capture. The experimental package now re-exports it instead of keeping a copy.
…red helpers

SensorBase, Camera and WrenchComposer resolve env_ids, env_mask and body_ids through resolve_ids and resolve_1d_mask instead of their own copies. The test doubles that build these objects without their initializer get the env masks a real sensor creates.
The nodal mask writers of BaseDeformableObject, which the OVPhysX deformable object inherits, and of the PhysX deformable object called wp.nonzero on a Warp array, which raised a RuntimeError. They now resolve the mask to ids with resolve_ids and call the index writers.
…sk writers through masks

The Newton assets resolve ids and masks through resolve_ids and resolve_1d_mask. The RigidObjectCollection mask writers and the fixed-tendon mask setters write through the masks instead of converting them to ids, which waited for the GPU on every call; the joint-coordinate writes reuse a scratch mask; one generic masked 2-D write kernel replaces two copies.
The OVPhysX assets resolve env, body, joint and tendon selections through resolve_ids and resolve_1d_mask instead of their own copies.
The PhysX assets resolve env, body, joint and tendon selections through resolve_ids and resolve_1d_mask instead of their own copies. The sensor test doubles get the env masks a real sensor creates.
…-native

isaac-sim#8821 owns the Newton mask writers: the collection write_body_*_to_sim_mask methods,
the fixed-tendon mask setters and their shared masked-copy kernel. This branch takes
its version of those and keeps only the reset-mask plumbing and the tendon-target
capture fix in the shared files.
…-shared

# Conflicts:
#	source/isaaclab/isaaclab/sensors/ray_caster/base_ray_caster.py
…leanup

# Conflicts:
#	source/isaaclab_experimental/isaaclab_experimental/managers/observation_manager.py
#	source/isaaclab_experimental/isaaclab_experimental/utils/__init__.pyi
#	source/isaaclab_experimental/isaaclab_experimental/utils/warp/utils.py
Writing the buffered targets every step cost 2-4% physics step time for every
articulation with tendon actuators. The only Warp caller, the Shadow Hand twin,
sets its targets outside the captured stage, so the host flag still sees them.
@hujc7 hujc7 changed the title [Warp] Part 5/6: Add a Shadow Hand reorientation Warp twin and fix the Allegro twin [Warp] Part 7/8: Add a Shadow Hand reorientation Warp twin and fix the Allegro twin Oct 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset New asset feature or request documentation Improvements or additions to documentation infrastructure isaac-lab Related to Isaac Lab team isaac-mimic Related to Isaac Mimic team isaac-sim Related to Isaac Sim team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants