Skip to content

Commit dae8dc6

Browse files
committed
Refine stack metal seams and ROS batch publishing
1 parent ad691bf commit dae8dc6

20 files changed

Lines changed: 1526 additions & 117 deletions

PORT_TO_MLX_TODO.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ without pausing for replanning after every small success.
7979
- `DONE` Synthetic cartpole RGB/depth camera slices landed as eval-only mac-native tasks with deterministic analytic `100x100` observations, public MLX wrapper exposure, sensor benchmark coverage, and CI smoke coverage
8080
- `DONE` Locomotion hotpaths now combine a true Metal-backed root-step kernel with compiled MLX contact/support helpers, and benchmark/semantic reports surface `hotpath: "mlx-metal-root-step"` for the ANYmal-C and H1 slices while Franka keeps its own family-specific hotpath label
8181
- `DONE` Benchmark coverage for the current mac-native task set now lives behind a stable `current-mac-native` benchmark group enforced by tests and CI
82-
- `IN PROGRESS` UR10 long-suction and short-suction stack slices are threaded through the public manifest, benchmark runner, direct CLI scripts, README table, and semantic-drift expectations; validation is currently blocked by an import-time `NameError` in `source/isaaclab/isaaclab/backends/mac_sim/manipulation.py` because `MacUR10StackRgbEnv` is defined before its `MacFrankaStackRgbEnv` base class
82+
- `DONE` UR10 long-suction and short-suction stack slices are threaded through the public manifest, benchmark runner, direct CLI scripts, README table, semantic-drift expectations, and direct train/eval smokes with an honest reduced `7`-action / `40`-observation contract
8383
- `DONE` Checkpoint/resume and replay contracts are now explicitly covered across the current mac-native task slices
8484
- `DONE` Maintained kernel inventory now maps the next real Warp/CUDA families to source files, target task classes, and replacement strategies
8585
- `DONE` Shared MLX task CLIs now cover train and replay/eval flows across the current mac-native slices
@@ -108,6 +108,9 @@ without pausing for replanning after every small success.
108108
- `DONE` Two more trainable reduced deployment/manipulation slices landed for `Isaac-Deploy-GearAssembly-UR10e-2F140-v0` and `Isaac-Deploy-GearAssembly-UR10e-2F85-v0`, with insertion-aware 19D policy observations, honest `semantic_contract="reduced-analytic-assembly"` metadata, public MLX wrapper/CLI support, benchmark coverage, semantic baseline refresh to `task_count=28`, and a broad backend regression ring at `285 passed, 21 warnings`
109109
- `DONE` Five more upstream-compatible manipulation aliases now resolve to existing reduced canonical slices without changing the public counts or benchmark groups: `Isaac-Deploy-Reach-UR10e-ROS-Inference-v0` maps to `ur10e-deploy-reach`; `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0` / `Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0` map to `franka-stack`; and `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-v0` / `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-Cosmos-v0` map to `franka-stack-rgb` with explicit reduced-contract metadata across the lazy registry, parsed configs, public wrapper, and installed CLI
110110
- `DONE` Two new reduced analytic UR10 suction-stack slices landed for `Isaac-Stack-Cube-UR10-Long-Suction-IK-Rel-v0` and `Isaac-Stack-Cube-UR10-Short-Suction-IK-Rel-v0`, with honest 7D action / 40D observation contracts, explicit `semantic_contract="reduced-analytic-suction-stack"` metadata across the lazy registry and public MLX wrapper, corrected three-cube terminal benchmark signatures, a refreshed semantic baseline at `task_count=30`, and a focused UR10 public-surface ring at `139 passed, 21 warnings`
111+
- `DONE` The reduced pick-place surrogate family now includes `Isaac-PickPlace-GR1T2-Abs-v0` alongside the waist-enabled, G1, nut-pour, and exhaust-pipe aliases, all mapped honestly onto the existing `franka-bin-stack` substrate through the lazy registry, parsed env configs, public MLX wrapper, and installed CLI without inflating the canonical public task counts
112+
- `DONE` Franka stack family hotpaths now carry dedicated family-specific Metal labels across backend diagnostics, benchmarks, and semantic drift: `franka-stack` reports `mlx-metal-franka-stack`, while `franka-stack-rgb` and `franka-bin-stack` report `mlx-metal-franka-stack-rgb` instead of reusing the generic Franka end-effector label
113+
- `DONE` Planner/ROS batch helpers now explicitly reject mixed topic-root batches in tests, keeping `batch_index` ordering semantics honest for both planner world-state and joint-trajectory envelopes
111114

112115
## Phase A: Import And Packaging Safety
113116

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ What works today:
4242
- a runnable `MLX + mac-sim` H1 rough locomotion slice with procedural wave terrain, analytic height scans, deterministic replay coverage, and corrected rough observation sizing for the shared H1 policy path
4343
- trainable rough locomotion slices for ANYmal-C and H1 with shared PPO/checkpoint contracts, replay support, and CI smoke coverage
4444
- a Metal-backed locomotion root-step helper for the ANYmal-C and H1 slices, with benchmark and semantic-drift diagnostics that report `hotpath: "mlx-metal-root-step"` when that narrow kernel is active
45-
- trainable `MLX + mac-sim` Franka reach, cube-lift, teddy-bear lift, instance-randomized two-cube stack, two-cube stack, three-cube stack, bin-anchored three-cube stack, cabinet-drawer, and open-drawer slices with deterministic analytic kinematics, lightweight grasp/open/stack logic, and benchmark diagnostics that now report `hotpath: "mlx-metal-ee"` for the shared Franka end-effector path when the Metal kernel is available
45+
- trainable `MLX + mac-sim` Franka reach, cube-lift, teddy-bear lift, instance-randomized two-cube stack, two-cube stack, three-cube stack, bin-anchored three-cube stack, cabinet-drawer, and open-drawer slices with deterministic analytic kinematics, lightweight grasp/open/stack logic, and family-specific benchmark diagnostics that now distinguish `hotpath: "mlx-metal-ee"` for the shared Franka end-effector path, `hotpath: "mlx-metal-franka-stack"` for the two-cube stack seam, and `hotpath: "mlx-metal-franka-stack-rgb"` for the three-cube/bin-stack seam when those narrow Metal helpers are available
4646
- trainable `MLX + mac-sim` OpenArm reach, bimanual reach, cube-lift, and open-drawer slices with explicit reduced-contract metadata, deterministic analytic surrogate kinematics, and replay/checkpoint support through the same public MLX wrapper and installed CLI surface
4747
- trainable `MLX + mac-sim` UR10 reach and UR10e deploy-reach slices with deterministic analytic pose tracking, reduced-contract metadata (`semantic_contract="reduced-analytic-pose"`), benchmark coverage, and replay/checkpoint support through the same public MLX wrapper and installed CLI surface
4848
- trainable `MLX + mac-sim` UR10e gear-assembly slices for the Robotiq 2F-140 and 2F-85 grippers with explicit reduced-contract metadata (`semantic_contract="reduced-analytic-assembly"`), insertion-aware policy observations, benchmark coverage, and replay/checkpoint support through the same public MLX wrapper and installed CLI surface
4949
- upstream-compatible Franka reach/lift/stack/open-drawer controller variants now resolve through the lazy task registry, public `isaaclab_rl.mlx` wrapper, and installed MLX CLI onto the existing reduced mac-native slices instead of failing on macOS import/runtime seams
5050
- upstream-compatible `Isaac-Deploy-Reach-UR10e-v0`, `Isaac-Deploy-Reach-UR10e-Play-v0`, and `Isaac-Deploy-Reach-UR10e-ROS-Inference-v0` identifiers now resolve through the same lazy registry, public wrapper, and installed CLI onto the canonical `ur10e-deploy-reach` slice while keeping the reduced-contract metadata explicit
5151
- upstream-compatible `Isaac-Deploy-GearAssembly-UR10e-2F140-v0`, `Isaac-Deploy-GearAssembly-UR10e-2F140-Play-v0`, `Isaac-Deploy-GearAssembly-UR10e-2F85-v0`, and `Isaac-Deploy-GearAssembly-UR10e-2F85-Play-v0` identifiers now resolve through the same lazy registry, public wrapper, and installed CLI onto the canonical `ur10e-gear-assembly-2f140` and `ur10e-gear-assembly-2f85` slices while keeping the reduced-contract metadata explicit
52-
- upstream-compatible `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-v0`, and `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-Cosmos-v0` now resolve through the same lazy registry, public wrapper, and installed CLI onto the canonical `franka-stack` or `franka-stack-rgb` slices with explicit reduced-contract metadata instead of pretending blueprint / skillgen / visuomotor / Cosmos subsystem parity; the upstream `Isaac-Stack-Cube-Bin-Franka-IK-Rel-Mimic-v0` alias remains the reduced public `franka-bin-stack` exception with explicit `semantic_contract="reduced-no-mimic"` metadata
52+
- upstream-compatible `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-v0`, and `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-Cosmos-v0` now resolve through the same lazy registry, public wrapper, and installed CLI onto the canonical `franka-stack` or `franka-stack-rgb` slices with explicit reduced-contract metadata instead of pretending blueprint / skillgen / visuomotor / Cosmos subsystem parity; the upstream `Isaac-Stack-Cube-Bin-Franka-IK-Rel-Mimic-v0` alias and the reduced pick-place surrogates `Isaac-PickPlace-GR1T2-Abs-v0`, `Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0`, `Isaac-PickPlace-G1-InspireFTP-Abs-v0`, `Isaac-NutPour-GR1T2-Pink-IK-Abs-v0`, and `Isaac-ExhaustPipe-GR1T2-Pink-IK-Abs-v0` remain explicit reduced-contract exceptions instead of pretending scene parity
5353
- a first mac-native analytic terrain raycast / height-scan sensor substrate for locomotion tasks
5454
- eval-only synthetic cartpole RGB/depth camera slices with deterministic analytic `100x100` observations, upstream-aligned reset ranges, and sensor benchmark coverage
5555
- a backend-local macOS external stereo camera discovery/capture path for UVC devices such as ZED 2i, including a live Terminal-hosted `zed-sdk-mlx` validation path for macOS TCC-safe raw capture
@@ -121,7 +121,7 @@ The kernel backend isolates Warp and future Metal custom-kernel paths:
121121

122122
Today the public MLX tasks mostly use pure MLX ops plus compiled MLX helpers. The explicit kernel selection seam now has narrow Metal-backed helpers on both the Franka end-effector path and the shared locomotion root-step path, so future kernels can keep landing without rewriting task-facing APIs again.
123123

124-
For the current locomotion slices, the shared root-step integrator now runs through a Metal-backed MLX kernel and benchmark diagnostics surface that as `hotpath: "mlx-metal-root-step"` when that narrow helper is active, while the remaining locomotion contact/support helpers stay on compiled MLX. For the Franka manipulation slices, the shared analytic end-effector kinematics helper continues to surface `hotpath: "mlx-metal-ee"` when that narrow helper is active, otherwise each family falls back to its compiled MLX helper path.
124+
For the current locomotion slices, the shared root-step integrator now runs through a Metal-backed MLX kernel and benchmark diagnostics surface that reports `hotpath: "mlx-metal-root-step"` when that narrow helper is active, while the remaining locomotion contact/support helpers stay on compiled MLX. For the Franka manipulation slices, the shared analytic end-effector helper still reports `hotpath: "mlx-metal-ee"` for reach/lift/cabinet/open-drawer tasks, while the two-cube stack seam reports `hotpath: "mlx-metal-franka-stack"` and the three-cube/bin-stack seam reports `hotpath: "mlx-metal-franka-stack-rgb"` when those dedicated Metal helpers are active.
125125

126126
## MLX Quick Start
127127

@@ -833,10 +833,10 @@ The cartpole path preserves the important upstream task semantics:
833833
- Franka open-drawer preserves the reduced analytic drawer substrate while exposing the manager-style public task ID, deterministic handle-distance/open-distance terminal metrics, and the same train/replay/checkpoint contract as the other Franka slices
834834
- OpenArm open-drawer preserves the reduced analytic drawer workflow with OpenArm-surrogate reduced-contract metadata, deterministic handle-distance/open-distance terminal metrics, and the same train/replay/checkpoint contract as the other manipulation slices
835835
- upstream-compatible reach/lift/stack/open-drawer controller variants plus the `Isaac-Deploy-Reach-UR10e-v0` / `Isaac-Deploy-Reach-UR10e-Play-v0` / `Isaac-Deploy-Reach-UR10e-ROS-Inference-v0` deploy aliases now normalize to canonical MLX task keys in the public wrapper and installed CLI, so the mac-native surface stays recognizable without pretending separate controller-physics or deployment-runtime parity
836-
- upstream task IDs that name heavier policy, model, or process layers now either normalize to explicit reduced-contract aliases or stay isaacsim-only. The supported reduced aliases here are `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-Cosmos-v0`, `Isaac-Deploy-Reach-UR10e-ROS-Inference-v0`, and `Isaac-Stack-Cube-Bin-Franka-IK-Rel-Mimic-v0`; all keep explicit reduced-contract metadata instead of pretending blueprint / skillgen / visuomotor / Cosmos / ROS-inference parity
836+
- upstream task IDs that name heavier policy, model, or process layers now either normalize to explicit reduced-contract aliases or stay isaacsim-only. The supported reduced aliases here are `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-v0`, `Isaac-Stack-Cube-Franka-IK-Rel-Visuomotor-Cosmos-v0`, `Isaac-Deploy-Reach-UR10e-ROS-Inference-v0`, `Isaac-Stack-Cube-Bin-Franka-IK-Rel-Mimic-v0`, `Isaac-PickPlace-GR1T2-Abs-v0`, `Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0`, `Isaac-PickPlace-G1-InspireFTP-Abs-v0`, `Isaac-NutPour-GR1T2-Pink-IK-Abs-v0`, and `Isaac-ExhaustPipe-GR1T2-Pink-IK-Abs-v0`; all keep explicit reduced-contract metadata instead of pretending blueprint / skillgen / visuomotor / Cosmos / ROS-inference / pick-place scene parity
837837
- the first mac-native sensor slice is an analytic terrain raycast / height-scan path for locomotion benchmarks
838838
- the `sensor-mac-native` benchmark rows now cover the synthetic cartpole RGB/depth camera tasks plus `height_scan_enabled=True` variants of the ANYmal-C and H1 flat locomotion tasks
839-
- benchmark and semantic drift reports now surface `hotpath: "mlx-metal-root-step"` for the locomotion root-step seam when active, `hotpath: "mlx-metal-ee"` for the Franka reach/lift/stack/stack-RGB/cabinet slices when the Metal end-effector helper is active, and keep the remaining helpers explicit when they stay on compiled MLX
839+
- benchmark and semantic drift reports now surface `hotpath: "mlx-metal-root-step"` for the locomotion root-step seam when active, `hotpath: "mlx-metal-ee"` for the Franka reach/lift/cabinet/open-drawer seam, `hotpath: "mlx-metal-franka-stack"` for the two-cube stack seam, and `hotpath: "mlx-metal-franka-stack-rgb"` for the three-cube/bin-stack seam when those dedicated helpers are active, while keeping the remaining helpers explicit when they stay on compiled MLX
840840
- the first backend-local mac camera slice is a UVC/AVFoundation discovery path plus raw stereo YUYV depth smoke, with live hardware validation kept host-specific
841841

842842
## Bootstrapping Upstream Sources

scripts/benchmarks/mlx/baselines/semantic-baseline.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"generated_at": "2026-03-20T02:04:47Z",
2+
"generated_at": "2026-03-20T02:44:39Z",
33
"git_sha": null,
44
"hardware_label": "darwin-arm64",
55
"parameters": {
@@ -204,7 +204,7 @@
204204
"franka-bin-stack": {
205205
"contract": {
206206
"action_dim": 8,
207-
"hotpath": "mlx-metal-ee",
207+
"hotpath": "mlx-metal-franka-stack-rgb",
208208
"observation_dim": 45,
209209
"output_signature": {
210210
"final_active_is_top_ratio": 0.0,
@@ -331,7 +331,7 @@
331331
"franka-stack": {
332332
"contract": {
333333
"action_dim": 8,
334-
"hotpath": "mlx-metal-ee",
334+
"hotpath": "mlx-metal-franka-stack",
335335
"observation_dim": 33,
336336
"output_signature": {
337337
"final_cube_distance_mean": 0.4998617172241211,
@@ -360,7 +360,7 @@
360360
"franka-stack-instance-randomize": {
361361
"contract": {
362362
"action_dim": 8,
363-
"hotpath": "mlx-metal-ee",
363+
"hotpath": "mlx-metal-franka-stack",
364364
"observation_dim": 35,
365365
"output_signature": {
366366
"final_cube_distance_mean": 0.4969131052494049,
@@ -391,7 +391,7 @@
391391
"franka-stack-rgb": {
392392
"contract": {
393393
"action_dim": 8,
394-
"hotpath": "mlx-metal-ee",
394+
"hotpath": "mlx-metal-franka-stack-rgb",
395395
"observation_dim": 42,
396396
"output_signature": {
397397
"final_active_is_top_ratio": 0.0,

scripts/benchmarks/mlx/benchmark_mac_tasks.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
detect_cpu_fallback,
2626
get_runtime_state,
2727
)
28+
from isaaclab.backends.mac_sim.hotpath import get_franka_stack_hotpath_backend
2829
from isaaclab.backends.mac_sim import (
2930
DEFAULT_HEIGHT_SCAN_OFFSETS,
3031
MacAnymalCFlatEnv,
@@ -378,6 +379,14 @@ def _franka_output_signature(env: Any, trace: Any) -> dict[str, float]:
378379
return payload
379380

380381

382+
def _franka_stack_diagnostics(env: Any, trace: Any) -> dict[str, Any]:
383+
"""Capture diagnostics for stack tasks with the stack-specific hotpath label."""
384+
385+
diagnostics = mac_env_diagnostics(env, rollout_summary=trace.summary())
386+
diagnostics["sim_backend"]["subsystems"]["hotpath"] = get_franka_stack_hotpath_backend()
387+
return diagnostics
388+
389+
381390
def _openarm_bi_output_signature(env: Any, trace: Any) -> dict[str, float]:
382391
"""Capture compact semantic signatures for the reduced bimanual OpenArm reach slice."""
383392

@@ -994,7 +1003,7 @@ def benchmark_franka_stack(num_envs: int, steps: int, seed: int) -> dict[str, An
9941003
"observation_dim": env.cfg.observation_space,
9951004
"action_dim": env.cfg.action_space,
9961005
"output_signature": _franka_output_signature(env, trace),
997-
"diagnostics": mac_env_diagnostics(env, rollout_summary=trace.summary()),
1006+
"diagnostics": _franka_stack_diagnostics(env, trace),
9981007
},
9991008
)
10001009

@@ -1021,7 +1030,7 @@ def benchmark_franka_stack_instance_randomize(num_envs: int, steps: int, seed: i
10211030
"observation_dim": env.cfg.observation_space,
10221031
"action_dim": env.cfg.action_space,
10231032
"output_signature": _franka_output_signature(env, trace),
1024-
"diagnostics": mac_env_diagnostics(env, rollout_summary=trace.summary()),
1033+
"diagnostics": _franka_stack_diagnostics(env, trace),
10251034
},
10261035
)
10271036

0 commit comments

Comments
 (0)