[Task Clean-up][Manager] Dexterous Part 6/9: Add the handover and camera manager counterparts - #6421
[Task Clean-up][Manager] Dexterous Part 6/9: Add the handover and camera manager counterparts#6421hujc7 wants to merge 7 commits into
Conversation
Greptile SummaryThis PR adds the manager-based counterpart for the two-hand Shadow Hand handover task (
Confidence Score: 4/5The change adds new files only (plus a two-line extension to init.py); no existing behavior is modified. The new env config correctly delegates scene/physics to the Direct base, and the MDP terms are consistent in frame conventions. All newly added files follow the established lazy_export + PresetCfg pattern from the reorient task family. Frame conventions (local vs world) are consistent across commands, events, observations, and rewards. The single finding — storing two log values as zero-dim tensors while adjacent keys use .item() — is an inconsistency that could silently break a strict logging backend but does not affect training correctness. source/isaaclab_tasks/isaaclab_tasks/core/handover/mdp/rewards.py — the dist_reward/dist_goal logging inconsistency noted above. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[ManagerBasedRLEnv\nIsaac-Shadow-Handover] --> B[HandoverManagerEnvCfg]
B --> C[HandoverManagerSceneCfg\nPresetCfg: physx / newton_mjwarp / ovphysx]
C --> C1[_HandoverManagerSceneCfg\nright_hand / left_hand / object]
C1 --> C2[_DIRECT_CFG.right_robot_cfg\n_DIRECT_CFG.left_robot_cfg]
B --> D[ActionsCfg\nEMAJointPositionToLimitsActionCfg\nright_hand + left_hand]
B --> E[CommandsCfg\nHandoverCommand\nfixed pos + random X/Y orientation]
B --> F[ObservationsCfg\nPolicyCfg: right 157-dim + left 157-dim]
B --> G[EventCfg\nreset_handover_state]
B --> H[RewardsCfg\nHandoverReward\n2x exp reward / step_dt]
B --> I[TerminationsCfg\nobject_below_height + direct_timeout]
G -->|env._handover_reset_actions| J[hand_action obs term]
H -->|sticky success flag| K[Metrics/success_rate at reset]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[ManagerBasedRLEnv\nIsaac-Shadow-Handover] --> B[HandoverManagerEnvCfg]
B --> C[HandoverManagerSceneCfg\nPresetCfg: physx / newton_mjwarp / ovphysx]
C --> C1[_HandoverManagerSceneCfg\nright_hand / left_hand / object]
C1 --> C2[_DIRECT_CFG.right_robot_cfg\n_DIRECT_CFG.left_robot_cfg]
B --> D[ActionsCfg\nEMAJointPositionToLimitsActionCfg\nright_hand + left_hand]
B --> E[CommandsCfg\nHandoverCommand\nfixed pos + random X/Y orientation]
B --> F[ObservationsCfg\nPolicyCfg: right 157-dim + left 157-dim]
B --> G[EventCfg\nreset_handover_state]
B --> H[RewardsCfg\nHandoverReward\n2x exp reward / step_dt]
B --> I[TerminationsCfg\nobject_below_height + direct_timeout]
G -->|env._handover_reset_actions| J[hand_action obs term]
H -->|sticky success flag| K[Metrics/success_rate at reset]
Reviews (1): Last reviewed commit: "Add the Shadow handover manager counterp..." | Re-trigger Greptile |
| 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() |
There was a problem hiding this comment.
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.
| 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() |
8cbac98 to
b27cb24
Compare
…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
b27cb24 to
553cd1c
Compare
…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 |  | — | merged | | #6412 Part 2/9: OVPhysX articulation + manager runtime |  | — | merged | | 📌 #6413 Part 3/9: Reorient Direct, torch (this PR) |  | — | [changes](https://github.com/isaac-sim/IsaacLab/pull/6413/changes/f4895f0f9ee..d29afc75e71) | | #6414 Part 4/9: MARL-to-single-agent fix + handover/camera Direct |  | #6413 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6414/changes/d29afc75e71..b10a84948f8) | | #6418 Part 5/9: Reorient manager counterparts |  | #6413 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/d29afc75e71..707d37f8f99) | | #6421 Part 6/9: Handover + camera manager counterparts |  | #6413, #6414, #6418 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/707d37f8f99..b50ac8906fc) | | #6410 Part 7/9: Environment overview docs |  | #6421 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d) | | #6415 Part 8/9: Benchmark success-rate utilities |  | #6421 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b) | | #6582 Part 9/9: Warp variants → experimental (draft; merges last) |  | #6413 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3) | | #6324 [DO-NOT-MERGE] Lumped validation reference |  | 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.
| physx = _ShadowHandCameraManagerSceneCfg(clone_in_fabric=True) | ||
| newton_mjwarp = _ShadowHandCameraManagerSceneCfg(clone_in_fabric=False) | ||
| ovphysx = physx | ||
| default = newton_mjwarp |
There was a problem hiding this comment.
[AI Review][Important] The Manager camera task still defaults to an unsupported backend. Resolving ShadowHandCameraManagerEnvCfg() selects NewtonCfg with clone_in_fabric=False. The latest commit documents that the default RTX modalities require Fabric cloning, but its PhysX-default override was applied only to the Direct config. The new Manager and Play registrations therefore remain broken by default. Please default the Manager scene plus its sim-physics, robot, and object presets to PhysX, keep explicit newton_mjwarp selection available, and add the Manager task to the registered-camera rendering matrix so this configuration is exercised.
| func=mdp.root_height_below_minimum, | ||
| params={"minimum_height": 0.24, "asset_cfg": SceneEntityCfg("object")}, | ||
| ) | ||
| time_out = DoneTerm(func=mdp.time_out, time_out=True) |
There was a problem hiding this comment.
[AI Review][Important] This timeout is one control step later than the Direct task. The generic Manager time_out returns episode_length_buf >= max_episode_length, while HandoverEnv._get_dones() uses >= max_episode_length - 1. For max_episode_length == 450, buffer value 449 terminates Direct but not Manager, changing rollout boundaries and reset observations despite this config promising Direct parity. Please add a Direct-compatible handover timeout term (or share the boundary implementation) and cover 448/449/450 explicitly.
| gym.register( | ||
| id="Isaac-Reorient-Cube-Shadow-Camera-Direct", | ||
| entry_point=f"{__name__}.shadow_hand_camera_env:ShadowHandCameraEnv", | ||
| entry_point=f"{__name__}.shadow_hand_direct_camera_env:ShadowHandCameraEnv", |
There was a problem hiding this comment.
[AI Review][Important] The Direct camera module rename needs a deprecation shim. This PR changes the registered entry point to shadow_hand_direct_camera_env, but the previously documented shadow_hand_camera_env and shadow_hand_camera_env_cfg modules are deleted and no longer importable. That is a breaking public import-path change without the deprecation required by the repository guidelines; docs/source/overview/environments.rst also still links the old path. Please retain compatibility modules that warn and re-export the renamed symbols, and add migration guidance to the changelog before removing them in a later release.
| def __post_init__(self): | ||
| self.decimation = 2 | ||
| self.episode_length_s = 7.5 | ||
| # simulation — mirrors the Direct cfg (guarded by the value-parity test) |
There was a problem hiding this comment.
[AI Review][Moderate] This comment claims a safeguard that is not present on this branch. There is no checked-in Direct-vs-Manager value-parity test for handover; the available dexterous test covers math helpers only. The duplicated task values have already drifted at the timeout boundary. Please either centralize the shared task constants/configuration or land the claimed parity tests in this PR. The source comment itself should describe the functional setting, not the review/test process.
| # at module load (config modules import mdp; see the layering note above). | ||
| from isaaclab_tasks.core.reorient.config.shadow_hand.feature_extractor import FeatureExtractor | ||
|
|
||
| feature_extractor_cfg: FeatureExtractorCfg = env.cfg.feature_extractor |
There was a problem hiding this comment.
[AI Review][Moderate] The declared feature_extractor_cfg term parameter is silently ignored. CameraPolicyCfg supplies and rewires this parameter, but this constructor reads env.cfg.feature_extractor instead and __call__ deletes the declared argument. Consequently, configuring the observation term directly has no effect, and the later docstring claim that the term owns its copy is inaccurate. Please construct from cfg.params["feature_extractor_cfg"], or remove the parameter and all associated rewiring so there is only one explicit source of truth.
| init_rot: tuple[float, float, float, float], | ||
| ) -> PresetCfg: | ||
| """Per-hand Shadow Hand preset (PhysX and Newton MJWarp variants). | ||
| """Per-hand Shadow Hand preset (PhysX, Newton MJWarp, and OVPhysX variants). |
There was a problem hiding this comment.
[AI Review][Moderate] Please reduce this to durable functional documentation. This docstring is largely a tuning diary: comparisons with another backend, specific MAPPO rewards, the search history for gains, and historical asset names. Those details will age quickly and obscure the actual contract. Keep a concise description of what each actuator override controls, its units, and the backend constraint it addresses; move experiment results and rejected values to the PR or a design note. The same standard should be applied to the num_substeps benchmark anecdote below.
AntoineRichard
left a comment
There was a problem hiding this comment.
[AI Review] Review summary — changes requested before showroom-quality merge.
I left six inline findings: three Important correctness/compatibility issues and three Moderate duplication/configuration/comment-quality issues. The principal blockers are the unsupported Newton default on the new Manager camera task, the one-step Direct/Manager handover timeout mismatch, and removal of documented camera module paths without a deprecation shim.
Verification performed on head ba3e66c: ./isaaclab.sh -f passed all hooks; focused dexterous-math and MARL-adapter tests passed (24 tests). I also reproduced the Manager camera default as NewtonCfg with clone_in_fabric=False, the 449/450 timeout boundary mismatch, and failure to resolve both old camera module paths. Full Isaac Sim/GPU training was not run, and the PR currently has no substantive CI result beyond the labeler.
The existing Greptile suggestion to call .item() on per-step log tensors should not be applied: zero-dimensional device tensors follow the Manager logging convention, while .item() would force a host synchronization on every environment step.
… 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 |  | — | merged | | #6412 Part 2/9: OVPhysX articulation + manager runtime |  | — | merged | | #6413 Part 3/9: Reorient Direct, torch |  | — | merged | | 📌 #6414 Part 4/9: MARL-to-single-agent fix + handover/camera Direct (this PR) |  | — (on develop) | Files changed tab | | #6418 Part 5/9: Reorient manager counterparts |  | #6413 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6418/changes/d29afc75e71..707d37f8f99) | | #6421 Part 6/9: Handover + camera manager counterparts |  | #6414, #6418 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6421/changes/707d37f8f99..b50ac8906fc) | | #6410 Part 7/9: Environment overview docs |  | #6421 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6410/changes/b50ac8906fc..af259c0778d) | | #6415 Part 8/9: Benchmark success-rate utilities |  | #6421 | [changes](https://github.com/isaac-sim/IsaacLab/pull/6415/changes/b50ac8906fc..c7f2f019d8b) | | #6582 Part 9/9: Warp variants → experimental (draft; merges last) |  | — | [changes](https://github.com/isaac-sim/IsaacLab/pull/6582/changes/d29afc75e71..167c28578b3) | | #6324 [DO-NOT-MERGE] Lumped validation reference |  | 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.
b70115f to
8d4e54b
Compare
8d4e54b to
9ed1d70
Compare
Manager terms that run during the initial reset had no reset_buf to read: the attribute was only assigned in step(), which has not run yet at that point. Allocate it alongside episode_length_buf, before the managers load.
Provide the observation, action, event, command and termination terms the manager-based reorientation tasks need, alongside a parity test that pins their values against the Direct environment. Terminations evaluate success directly rather than reading the command's metrics, which the command manager only refreshes after the termination phase of step() has already run.
Register manager counterparts for the Allegro, Shadow and OpenAI Shadow reorientation tasks, each configured in its own per-robot module. Replace the single shared reorient_manager_env_cfg with those per-robot configurations: the shared base could only describe the Allegro task, so every Shadow variant overrode most of what it inherited.
The benchmark variant exists to measure rendering throughput rather than to train a policy, so it belongs alongside the other contributed tasks. Keep the released task ID working as a deprecated alias.
9ed1d70 to
b95c8b8
Compare
The handover configuration listed the Newton actuated joints itself, which duplicated knowledge that belongs to the robot asset and would drift the moment the asset gained or renamed a joint.
Register Isaac-Handover-Shadow as the manager counterpart of the Direct handover task. The fused Direct reward becomes a plain reward term, and the command term that owns the goal also owns the success and goal-distance bookkeeping, reporting the same per-episode success bit the Direct task does. A value-parity test pins the shared task values against the Direct configuration so drift on either side fails CI.
Register Isaac-Reorient-Cube-Shadow-Camera as the manager counterpart of the Direct camera task. It defaults to PhysX: the RTX render modalities need Fabric cloning, which Newton does not support, so the inherited default could not render. Newton stays selectable for the state-only observation groups. Move the camera playback settings into play_mode, removing the last two -Play registrations in isaaclab_tasks. The override mutates the feature extractor rather than replacing it, since replacing resets every field the caller does not name -- which had silently re-enabled the CNN in the benchmark configuration whose purpose is to disable it.
b95c8b8 to
e8c626d
Compare
Review Map
Summary
Completes manager coverage of the dexterous task families by adding manager-based counterparts
for the Shadow handover and Shadow camera reorientation tasks. Stacks on
#6418 — [Task Clean-up][Manager] Dexterous Part 5/9: Add the reorientation manager counterparts
Isaac-Handover-ShadowandIsaac-Reorient-Cube-Shadow-Camera.-Playregistrations inisaaclab_tasksare 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 reportsMetrics/success_rateasa per-episode bit, matching the handover Direct environment. A value-parity test covers the
handover pair alongside the reorientation ones.
HandoverCommand.commandbuilds its pose per call rather than returning a persistent buffer, soconsumers that store it across steps are not aliased to live data.
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_mjwarpfor the state-only observation groups.The feature-extractor observation term ignored its declared
feature_extractor_cfgparameterand read the environment configuration instead; it now honours the parameter.
3. Camera playback moves to
play_modeIsaac-Reorient-Cube-Shadow-Camera-Playand-Camera-Direct-Playwere the last-Playregistrations left in
isaaclab_tasks; every other task moved toplay_modein#6676 — Remove the _PLAY configs. Their playback
environment count and inference feature extractor now live in
play_modeoverrides on themanager 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
Handover manager reaches a success rate of 0.859 against the Direct task's 0.667 over 1500
iterations at seed 42. The camera task's registered-rendering matrix and golden images are
tracked separately.