Skip to content

fix(g4): emit measured floor-arena rest-z so libero_object pose_tolerance passes (RCA Regime A)#37

Merged
KE7 merged 1 commit into
mainfrom
rca/g4-task-pose-drift
Jun 24, 2026
Merged

fix(g4): emit measured floor-arena rest-z so libero_object pose_tolerance passes (RCA Regime A)#37
KE7 merged 1 commit into
mainfrom
rca/g4-task-pose-drift

Conversation

@KE7

@KE7 KE7 commented Jun 23, 2026

Copy link
Copy Markdown
Owner

g4 task-object pose_tolerance drift — RCA + Regime A (floor arena) fix

RCA of the 66k publication run (run3) g4 task-object consistency drop
(41,515/66,430 = 62.49%). Full RCA: validation_run3/rca/g4_task_pose_drift.md.

Root cause (diagnosed, not band-aided)

The g4 pose_tolerance failures are NOT physical pose drift. xy is realized to
sub-millimetre and objects settle stably; 100% of the error is in z. The failing
quantity is the renderer's analytic, pre-physics spawn-z reference (obj.position[2]),
which diverges from the deterministic post-settle MuJoCo z.

This PR fixes Regime A — the libero_object (floor) arena, the largest single
deterministic regime (BEFORE: 0/420 = 0.00% pass on these tasks; max xy only 0.66mm,
all error in z up to 144mm). The libero_object suite maps to workspace class floor
(arena_surface_z(floor) = -0.115), and the kitchen per-class clearance does not
transfer — the suite authors several classes (ketchup, salad_dressing, milk,
orange_juice) in a different rest orientation, so the same class settles at a different
body-origin clearance. The clearances were also partly n=1 / missing.

Fix (Option 2: make renderer_z == settled_z, gate unchanged at 5mm)

floor is exactly the situation PER_ARENA_TABLE_CLASSES + measured |
clearances already handle for living_room/coffee — there were simply no *|floor rows and
floor was not threaded.

  1. asset_metadata.PER_ARENA_TABLE_CLASSES: add floor so the renderer threads
    surface_class='floor' for floor-arena table-resters and object-axis variants.
  2. scripts/measure_spawn_clearances.py: register the floor arena (10 basket tasks)
    with a position+object sweep (12 seeds), per-arena seed/subset configs (living-room/
    kitchen stay byte-identical), a determinism (spread) report, and an --arena= filter.
    Corrective-merge (>5mm only).
  3. data/spawn_clearances_variants.json: +15 measured |floor rows (canonical +
    variants). All measured at 0.00mm rest-z spread (fully deterministic); merge is purely
    additive — zero existing rows removed or changed.
  4. tests/test_spawn_z_consistency.py: 3 tests pin floor threading, presence of the
    measured |floor rows, and that resolved floor z lands in the suite band.

Determinism de-risk (STEP 0)

Settling each class via the production path across 8 seeds gives 0.00mm rest-z spread —
the 67mm cross-class "implied surface" spread in the RCA was a data-quality artifact of
the borrowed kitchen clearances, not physics wobble. No metastable residual on floor.

Verification

  • Codegen: renderer now emits floor z matching the measured settle to <0.05mm
    (ketchup 0.1285 vs 0.1285 — was off 91mm; salad_dressing was off 144mm).
  • Env before/after (scripts/verify_g4_floor.py, 10 floor tasks × position/object subsets):
    BEFORE 0/420 = 0.00% pass (max |dz| 144mm) → AFTER 560/560 = 100.00% pass
    (max |dz| 0.05mm, max xy 0.66mm unchanged, 0 g3/build fails).
  • No regression: data merge is additive |floor-only; the code change only affects
    floor-workspace scenes, so the 191,285 currently-passing (non-floor) keys are
    untouched by construction. xy stays <1mm. Fixtures untouched.
  • tests/test_spawn_z_consistency.py 96 passed; ruff + black clean on src/+tests/.

Scope note (refined taxonomy)

Re-analysis shows the original RCA "stacked (~10,439)" bucket is predominantly
table-resters in other arenas (table, kitchen_table, living_room_table, study_table) with
the same per-arena-clearance mechanism — NOT object-on-object stacking. True stacks are a
small tail (akita_black_bowl stacked_on {cookies, ramekin}). Those other-arena corrections
(incl. reference-arena canonical fixes and a few living_room_table metastable residuals to
flag) and the true-stack renderer offset are the same template applied per arena,
recommended as focused follow-ups to keep each change deterministic-gated and low-risk.
This PR lands the fully de-risked floor regime.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

…ance passes (RCA Regime A)

RCA of the run3 g4 task-object pose_tolerance drop (62.49%) found the failures are
NOT physical drift: xy is realized to <1mm and objects settle stably; 100% of the
error is in z. The renderer's analytic pre-physics spawn-z reference diverges from the
deterministic post-settle MuJoCo z.

This fixes Regime A — the libero_object (floor) arena (BEFORE: 0/420 pass; all error in
z up to 144mm). libero_object maps to workspace class `floor` (arena_surface_z=-0.115);
the kitchen per-class clearance does not transfer because the suite authors several
classes (ketchup, salad_dressing, milk, orange_juice) in a different rest orientation.
This is exactly the PER_ARENA_TABLE_CLASSES + measured <class>|<arena> pattern already
used for living_room/coffee — floor was simply not threaded and had no |floor rows.

- asset_metadata.PER_ARENA_TABLE_CLASSES: add `floor` (thread surface_class='floor').
- scripts/measure_spawn_clearances.py: register the floor arena (10 basket tasks) with a
  position+object sweep, per-arena seed/subset config (living-room/kitchen byte-identical),
  determinism spread report, and --arena= filter. Corrective-merge (>5mm only).
- data/spawn_clearances_variants.json: +15 measured <class>|floor rows (all 0.00mm
  rest-z spread; deterministic). Purely additive — 0 existing rows changed/removed.
- tests/test_spawn_z_consistency.py: pin floor threading + measured |floor rows + band.
- scripts/{repro_g4_pose_drift,verify_g4_floor}.py: RCA repro + before/after harness.

Verified: codegen renderer_z == settle to <0.05mm for every floor class; data merge
additive; 96 spawn-z tests pass; ruff+black clean on src/+tests/. No regression: the
code change only affects floor-workspace scenes (the 10 libero_object tasks); the 191,285
currently-passing non-floor keys are untouched by construction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@KE7
KE7 merged commit dd8a0cd into main Jun 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant