Skip to content

[Task Clean-up][Manager] Dexterous Part 6/10: Add the handover and camera manager counterparts - #6421

Merged
hujc7 merged 13 commits into
isaac-sim:developfrom
hujc7:jichuanh/task-cleanup-dex-part11
Aug 17, 2026
Merged

hujc7 merged 13 commits into
isaac-sim:developfrom
hujc7:jichuanh/task-cleanup-dex-part11

Conversation

@hujc7

@hujc7 hujc7 commented Jul 8, 2026 •

Copy link
Copy Markdown
Collaborator

Review Map

PR Status Depends on Exact changes
📌 #6421 Part 6/10: Handover + camera manager counterparts — changes
#6410 Part 7/10: Environment overview docs #6421 changes
#6415 Part 9/10: Benchmark success-rate utilities #6421 changes
#6582 Part 10/10: Warp variants → experimental (draft; merges last) — changes
#6324 [DO-NOT-MERGE] Lumped validation reference 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.

@greptile-apps

greptile-apps Bot commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR completes manager coverage of the dexterous task families by adding Isaac-Shadow-Handover (manager-based counterpart to the Direct MARL handover env) and Isaac-Reorient-Cube-Shadow-Camera (manager-based camera reorientation task), and removes the last two -Play registrations in isaaclab_tasks, replacing them with play_mode overrides.

  • HandoverCommand owns success bookkeeping and goal-distance metrics, routing Metrics/success_rate to the unified TensorBoard path; the goal pose is constructed fresh each call via torch.cat to avoid consumer aliasing.
  • BALL_CFG consolidates the old ObjectCfg(PresetCfg) into a single RigidObjectCfg for both the Direct and manager envs, removing the Newton-specific variant that previously excluded PhysX-only rigid-body properties (solver_position_iteration_count, sleep_threshold, physics_material). Newton backend will now receive these settings.
  • HandoverEventPresetCfg neatly separates the state reset (ResetEventCfg) from domain randomisation (RandomizationEventCfg) via multiple inheritance, with presets=randomized as the opt-in path.

Confidence Score: 5/5

  • Safe to merge; the changes are well-scoped manager env additions with a straightforward reward term and command term, backed by reported validation results.
  • The new HandoverCommand, handover_goal_distance_reward, and HandoverManagerEnvCfg are clean and follow established patterns from the reorient counterparts. The consolidation of BALL_CFG removes an explicit Newton-specific variant, but this is a physics-property question rather than a control-flow defect. No crashes, incorrect state transitions, or broken contracts were found. The two observations noted are quality concerns for future maintainers, not blockers.
  • The handover_env_cfg.py and handover_manager_env_cfg.py files share the unified BALL_CFG; if Newton physics turns out to reject or warn on the PhysX-specific properties, both files need a backend-specific ball config restored.

Important Files Changed

Filename Overview
source/isaaclab_tasks/isaaclab_tasks/core/handover/mdp/commands.py New HandoverCommand class implementing the goal-pose command term. The reset() method has a subtle ordering consideration when converting env_ids to slice(None), and the _resample_command uses only X/Y axis rotations (intentionally, to match the Direct task's goal sampling). Overall logic is sound.
source/isaaclab_tasks/isaaclab_tasks/core/handover/mdp/rewards.py Adds handover_goal_distance_reward for the manager env. The 2× multiplier on handover_reward (which itself returns 2×) yields a 4× total; the docstring explains this mirrors the Direct env's per-hand sum. Clean addition, no issues found.
source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_manager_env_cfg.py New manager env cfg mirroring the Direct MARL single-agent adapter. Uses BALL_CFG (plain RigidObjectCfg, not a PresetCfg) which includes PhysX-only rigid_props and physics_material settings that the old ObjectCfg Newton variant explicitly excluded. The preset split for events (ResetEventCfg vs HandoverEventCfg) is well structured.
source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_env_cfg.py Simplified to introduce BALL_CFG as a shared singleton replacing the old ObjectCfg(PresetCfg). The EventCfg class was removed (it was already noted as unwired). Changes are clean doc/cleanup, but the BALL_CFG consolidation carries the same Newton-backend concern as the manager file.
source/isaaclab_tasks/isaaclab_tasks/core/handover/init.py Adds the Isaac-Shadow-Handover manager env registration before the Direct registration. Correctly wires env_cfg_entry_point and rsl_rl_cfg_entry_point. No issues.
source/isaaclab_tasks/isaaclab_tasks/core/handover/mdp/init.pyi Stub file updated to export HandoverCommand, HandoverCommandCfg, and handover_goal_distance_reward. Correct additions, consistent with the new modules.

Sequence Diagram

sequenceDiagram
    participant CM as CommandManager
    participant HC as HandoverCommand
    participant CT as CommandTerm (base)
    participant EER as EpisodeErrorRecorder

    Note over CM,EER: Per-step flow
    CM->>HC: compute(dt)
    HC->>CT: (base) _update_metrics()
    HC->>CT: (base) _update_command() [no-op]

    Note over CM,EER: Episode reset flow
    CM->>HC: reset(env_ids)
    HC->>HC: "metrics["success_rate"][env_ids] = _succeeded.float()"
    HC->>CT: super().reset(env_ids)
    CT->>CT: mean metrics → extras dict
    CT->>CT: zero metrics
    CT->>HC: _resample_command(env_ids)
    HC->>HC: sample random X/Y-axis goal quat
    CT-->>HC: return extras
    HC->>HC: "_succeeded[env_ids] = False"
    HC->>EER: _minimum_goal_distance.reset(env_ids)
    EER-->>HC: "{mean, min, max} statistics"
    HC->>HC: route Metrics/success_rate → env.extras["log"]
    HC-->>CM: return remaining extras
Loading

Reviews (2): Last reviewed commit: "Use the shared actuated-joint list in th..." | Re-trigger Greptile

Comment on lines +80 to +82
env.extras.setdefault("log", {})["dist_reward"] = per_agent_reward.mean()
env.extras["log"]["dist_goal"] = goal_distance.mean()
env.extras["log"]["Metrics/goal_distance"] = goal_distance.mean().item()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Mixed tensor/scalar types in extras log dict. dist_reward and dist_goal are stored as zero-dim PyTorch tensors (.mean() without .item()), while the Metrics/* keys on the very next lines use .item() to produce Python floats. A logging backend that serializes extras["log"] to JSON or passes values to a scalar summarizer will silently fail or produce unexpected output for those two keys.

Suggested change
env.extras.setdefault("log", {})["dist_reward"] = per_agent_reward.mean()
env.extras["log"]["dist_goal"] = goal_distance.mean()
env.extras["log"]["Metrics/goal_distance"] = goal_distance.mean().item()
env.extras.setdefault("log", {})["dist_reward"] = per_agent_reward.mean().item()
env.extras["log"]["dist_goal"] = goal_distance.mean().item()
env.extras["log"]["Metrics/goal_distance"] = goal_distance.mean().item()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Resolved. The reward term no longer writes to the extras log dict at all; the success metric is routed through the command term's metrics and namespaced as Metrics/success_rate by CommandManager.reset(). No mixed tensor/scalar values remain.

@hujc7
hujc7 force-pushed the jichuanh/task-cleanup-dex-part11 branch from 8cbac98 to b27cb24 Compare July 17, 2026 00:59
@hujc7 hujc7 changed the title [Task Clean-up][Manager] Dexterous Part 11/11: Add the Shadow handover manager counterpart [Task Clean-up][Manager] Dexterous Part 11: Add the handover and camera manager counterparts Jul 17, 2026
@hujc7 hujc7 changed the title [Task Clean-up][Manager] Dexterous Part 11: Add the handover and camera manager counterparts [Task Clean-up][Manager] Dexterous Part 11/11: Add the Shadow handover manager counterpart Jul 17, 2026
hujc7 added a commit that referenced this pull request Jul 17, 2026
…nager runtime (#6412)

## Summary

- Fixes OVPhysX actuator joint indices to follow the common actuator
indexing contract.
- Fixes OVPhysX initialization alongside Kit by reusing Kit's registered
PhysX schema provider.
- Fixes the OVPhysX manager to support both the declared public runtime
API and the current runtime API.
- Regression tests included. Validated by full dexterous training runs
on the OVPhysX backend; split out of the lumped validation branch #6324
(Part 2 of 11).

## Dependencies

- None.

## Series review map

Full integrated diff + training/validation evidence: the lumped
validation PR #6324
(DO-NOT-MERGE).

| Part | PR |
|---|---|
| Docs: regenerate the environment overview table |
#6410 |
| Part 1/11: Newton runtime fixes (cloner rows, cubric fallback, viz
teardown) | #6411 |
| **Part 2/11: OVPhysX runtime fixes (this PR)** |
#6412 |
| Part 3/11: success-rate metrics for the Direct reorientation tasks |
#6413 |
| Part 4/11: RSL-RL training for the handover Direct task |
#6414 |
| Part 5/11: success-rate support in the benchmark utilities |
#6415 |
| Part 6/11: renderer presets for the Direct camera task |
#6416 |
| Part 7/11: OVPhysX presets for the dexterous tasks |
#6417 |
| Part 8/11: Allegro manager counterpart |
#6418 |
| Part 9/11: Shadow + OpenAI manager counterparts |
#6419 |
| Part 10/11: Shadow camera manager counterpart |
#6420 |
| Part 11/11: Shadow handover manager counterpart |
#6421 |


---
### Exact changes in this PR

- OVPhysX backend changes + tests:
1f7a433
@hujc7 hujc7 changed the title [Task Clean-up][Manager] Dexterous Part 11/11: Add the Shadow handover manager counterpart [Task Clean-up][Manager] Dexterous Part 6/8: Add the handover and camera manager counterparts Jul 17, 2026
@hujc7
hujc7 force-pushed the jichuanh/task-cleanup-dex-part11 branch from b27cb24 to 553cd1c Compare July 18, 2026 11:10
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 force-pushed the jichuanh/task-cleanup-dex-part11 branch 2 times, most recently from 71c3240 to ce96045 Compare August 5, 2026 19:53
@hujc7 hujc7 changed the title [Task Clean-up][Manager] Dexterous Part 6/9: Add the handover and camera manager counterparts [Task Clean-up][Manager] Dexterous Part 6/10: Add the handover and camera manager counterparts Aug 7, 2026
hujc7 added 2 commits August 7, 2026 03:04
Adds manager-based Allegro and Shadow cube reorientation environments that
mirror their Direct counterparts, sharing the reward, termination, command and
event definitions so the two workflows stay numerically in step. A value-parity
test pins the shared task-defining values.

Moves the shared task helpers into the reorientation task package and renames
the manager Allegro configurations after the robot rather than the object.
Adds the manager-based handover task and the Shadow camera reorientation task,
each mirroring its Direct counterpart's observation, reward and termination
contracts. Extends the value-parity test to the handover pair.

Retargets the handover recorder import to the reorientation helpers, which the
previous part moved out of core/utils.py.
@hujc7
hujc7 force-pushed the jichuanh/task-cleanup-dex-part11 branch from 097ab95 to 0cae3d8 Compare August 7, 2026 10:05
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 10 commits August 11, 2026 17:11
Part 5 merged, so the reorientation half of this branch is now upstream.
Resolved every file it owns to develop, keeping this part's own handover,
camera and action-term work.

Follow the merged part-5 setup in the handover manager counterpart:

- reset the object with the general reset_root_state_with_random_orientation
  term instead of a task-local random X/Y rotation, leaving only the two-hand
  joint and PD-target reset task-local;
- observe both hands' actions with the general last_action term, dropping the
  hand_action term and the reset-action side-channel it read;
- keep the shared helpers in isaaclab_tasks.core.utils, and drop the
  Direct-versus-manager value-parity test.

Restore fingertip_quat to the reorientation observations, which handover
consumes and part 5 does not define.
Run tools/update_environments_rst.py so the comprehensive table and the
environment browser list this part's registered tasks. 130 training
environments.
The OpenAI manager configuration is registered nowhere, and part 5 moved the
OpenAI Shadow variants to the contributed package, so the core copy is dead.
Its action term was that configuration's only consumer.
Reuse the shared terms rather than task-local copies: both hands reset
through the reorientation hand reset, one per hand, so the task keeps no
reset code of its own.

Collapse the object preset into a single ball configuration named after the
object. The Newton variant existed to drop PhysX-only knobs, but Newton
ignores them: a random agent builds and steps the scene on newton_mjwarp
with the consolidated configuration.

Lift the policy observation group to module scope, and add the
domain-randomization terms behind presets=randomized, matching how the
reorientation manager tasks expose theirs.
The command wrote the success rate straight into the environment's log as a
zero-dimensional tensor, having taken the mean itself and skipped the host
conversion, so a backend expecting scalars received a device tensor.

Register it as a command metric instead. The base class means it over the
resetting environments, converts it and clears it, and the value is then
routed to the shared Metrics/success_rate path exactly as the reorientation
command does.
The task carried three observation terms that the framework already
provides. Fingertip position and orientation are body_pose_w, and the
object block is the root pose, root velocities, the generated command and
the reorientation goal-quaternion difference. Only the fingertip velocity
has no framework equivalent, so it stays and is imported from the
reorientation terms alongside the hand reset.

The object and goal block was also observed once per agent. Both copies
carried identical values, so a single copy carries the same information.

With the observation module gone the task keeps no observation code of its
own, and the reorientation package is untouched by this part again.
The two helpers wrapped a single SceneEntityCfg construction each, so the
call sites now name the entity and its joints or bodies directly.
The task addressed its action joints through a per-backend preset built on a
new Newton-specific name list. Both Shadow Hand assets actuate the joints the
shared actuator regex selects, and the reorientation tasks address them with
the one shared list, so the handover task now does the same.

This drops the Newton name list and the preset that selected it, leaving the
asset package untouched by this part.
@hujc7
hujc7 marked this pull request as ready for review August 12, 2026 08:50
@hujc7
hujc7 requested a review from AntoineRichard August 14, 2026 08:13
…eanup-dex-part11

# Conflicts:
#	source/isaaclab_tasks/isaaclab_tasks/core/handover/handover_env_cfg.py


@configclass
class HandoverCommandCfg(CommandTermCfg):

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.

Do not put cfg together in implementation

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Will be addressed in a followup PR for asset consolidation.

)


def _shadow_hand_cfg(

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.

something is wrong in this cfg, we shouldn't work around the asset and behavior different like this.....


def _resample_command(self, env_ids: Sequence[int]) -> None:
random_values = 2.0 * torch.rand((len(env_ids), 2), device=self.device) - 1.0
self.quat_command_w[env_ids] = math_utils.quat_mul(

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.

this looks like a very inefficient way to sample in quaternion space, you can just randomly sample r p y, then convert to quaternion instead...

# Newton's importer bakes the asset's root orientation into the root joint (see the note on
# SHADOW_HAND_NEWTON_CFG.init_state), so the task rotation must compose with it rather than
# replace it — replacing leaves both palms rotated 90 degrees.
newton_rot = tuple(

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.

.............. can we fix the issue from root not patch like that

@hujc7
hujc7 merged commit 2227ce7 into isaac-sim:develop Aug 17, 2026
72 of 74 checks passed
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 isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants