> Historical bottle-lift-v2 report. The current task uses upstream MJLab lift-cube rewards; see [reward update](reward-report.md) and [current task specification](task.md). Measurements below retain their original reward/critic configuration.

# Domain randomization, curriculum and RL task setup

The standalone `~/mjlab_gs` registered task now contains the reset distribution,
step-based curriculum, lift-and-hold objective and evaluation metrics. **No RL
training was run in this update.** Reward weights and learning performance remain
to be qualified by training experiments.

## Implemented

- Object/table/robot/pedestal poses, initial arm/gripper configuration, camera
  mount/intrinsics, friction, bottle mass/inertia, damping, native light/material
  appearance, exposure, white balance and image noise.
- MJLab curriculum scales 0.05 → 0.15 → 0.35 → 0.65 → 1 at vector steps
  0 / 20,000 / 50,000 / 100,000 / 200,000, affecting each world's next reset.
  Ten percent of training episodes remain nominal.
- No IK/visibility/feasibility rejection. Far-table and poor starts remain in the
  denominator. A conservative static-layout footprint diagnostic is separate
  from physical contact validity.
- The 16-value actor state, wrist RGB and seven action units are preserved;
  the privileged critic has 59 values. Native MJLab managers, task registration,
  viewer, recording and evaluation use the same task.
- Success: stable bilateral-pad grasp, bottle bottom ≥10 cm above the table,
  continuously held for 2 s, with contact/motion validity guards. Also logs 15-cm
  holds, peak lift, drops, contact fraction, collisions, penetration and motion.
- Dense reach/grasp/lift/hold shaping, motion/contact costs, and a one-time 200
  success bonus. Fixed per-world episode quotas and scale × table-location
  success/lift tables; incomplete evaluations cannot claim a final success rate.

Complete distributions, observation ordering, reward definitions, commands and
limitations: [task specification](task.md). Configurable presets are
in `configs/curriculum.json`, `eval_full.json` and `nominal.json`.

## Bugs found and corrected while validating

MuJoCo Warp caches world-welded geom transforms at startup. Randomizing body poses
alone left the table and pedestal collision/native visual geoms at old positions.
The reset now refreshes these geoms after GPU kinematics, before forward physics
and renderer BVH refit. No collision geometry is moved independently of its body.

The prior GPU controller omitted the legacy servo's joint-bias compensation.
A zero Cartesian action slowly sagged into a table contact after ~2.85 s. The
arm servo now adds qfrc_bias / actuator gain to its position targets, preserving
actuator force limits. A 15-second neutral-action regression passes with maximum
reported TCP drift 0 m (float32 state precision),
no robot-room contact, peak penetration 0.514 mm,
and peak arm speed 2.27e-05 rad/s.

This controller correction is explicitly recorded in simulator contract
**mjlab-gs-cartesian-v2**. Existing v1 checkpoints require deliberate migration.
The GPU differential IK still differs from the old CPU iterative solver.

## Validation

- Six unit tests pass: curriculum bounds, configuration validation, exact 2-second
  hold boundary, one-pad rejection, high lift, drop/penetration/speed/collision
  guards, single success payment, partial tracker reset and episode denominators.
- Four-world GPU integration: actor `[4,16]`, critic `[4,59]`, RGB
  `[4,3,100,160]`, finite CUDA observations; seeded resets reproduce state/model
  values within 2e-7; partial reset isolation and reset-only curriculum transitions.
- 48 full-table samples cover both axes within the configured edge margins,
  without IK rejection. Static geom poses persist while stepping.
- Captured/uncaptured metric trajectory maximum discrepancy:
  4.29e-06; terminal metrics survive autoreset.
- Four randomized CPU/OpenGL reference comparisons have composite RGB mean
  absolute error 1.823–2.559/255.
  Matched non-background geom positions differ by at most
  3.4e-07 m. These visual cases
  deliberately use near-nominal arm joints and moderate table/base displacement
  to keep useful foreground in view; camera/light/material variation is enabled.
- Browser play/pause/step/reset and camera feed are checked using the actual
  Viser client. `reports/browser/result.json` records the check.

The tests validate mechanics and accounting, not a successful learned grasp.

## Throughput with this task

| Configuration | Worlds | RGB | Environment steps/s | Process GPU GiB |
|---|---:|---|---:|---:|
| Nominal | 64 | 128×128 | 730.4 | 1.95 |
| Full DR | 64 | 128×128 | 540.6 | 1.72 |

RTX A6000; 40 measured vector steps after five warmup steps. Includes Cartesian
IK with bias compensation, 50 physics substeps, contact/reward/metric managers,
Gaussian/native rendering and observation conversion. Excludes PPO updates,
browser output and recording. Memory is sampled process NVML memory. Randomized
camera occupancy and reset frequency differ, so these are workload measurements,
not a controlled estimate of renderer overhead or maximum-capacity scaling.

## Fixed-quota evaluation smoke

| DR scale | Completed / requested | Success | Invalid episode fraction |
|---:|---:|---:|---:|
| 0.00 | 8/8 | 0% | 0% |
| 0.35 | 8/8 | 0% | 0% |
| 1.00 | 8/8 | 0% | 0% |

Zero Cartesian action and open gripper; eight episodes per scale. No trained
checkpoint. Zero success is expected. Invalid means the task's episode contact,
penetration, speed, force or finite-state guard failed; it is not an IK
reachability label. All completed trials remain in the denominator. Matrix JSON
contains each episode and its bottle-location bin. Evaluation does not terminate
early on success, allowing high-lift and later-drop diagnostics.

## GPU and scope

Physics, reset sampling, image/calibration transforms, bounded Gaussian batches,
IK, rewards and contact tracking operate on CUDA. Python orchestration, packed
rasterizer allocation synchronization, resets, disk/browser output and report
aggregation still involve the CPU. This is not a fully host-free pipeline.

The room Gaussian lighting is baked. Native lighting/material variation and
composite image effects do not physically relight it. Full-scene relighting,
multi-camera input, latency/delay/push randomization and production RL memory
scaling are future work. Broad randomization endpoints are proposal ranges from
the older study, not a promise that every sample can be completed.
