Skip to content

feat: consume unisim 1.7.5 physics-state playback contract in interactive rendering - #1637

Merged
TATP-233 merged 1 commit into
mainfrom
feat/unisim-291-playback-render-contract
Sep 23, 2026
Merged

TATP-233 merged 1 commit into
mainfrom
feat/unisim-291-playback-render-contract

Conversation

@TATP-233

@TATP-233 TATP-233 commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Downstream adaptation for feat: 统一物理状态回放渲染契约,支撑 viser 等渲染前端适配全部回放后端 unilabsim/unisim#291 on the released unisim-core 1.7.5 playback contract: play_interactive / play_viser now precheck supports_physics_state_playback at startup and fail with an actionable message (naming the backend and its available rendering paths) instead of surfacing NotImplementedError from the first snapshot fetch inside the viewer loop.
  • New owner module unilab.visualization.playback_state: PhysicsStateApplier splits snapshots through the contract physics_state_layout().split_state() — the hardcoded mjSTATE_FULLPHYSICS / 1+nq+nv slicing is gone from both entrypoints — and replays mocap geometry through the contract get_playback_mocap_state entrypoint (aligned with the playback model; falls back to the snapshot tail only when the backend declares no mocap capability but the layout carries the columns).
  • EnvPlayCapabilities gains supports_mocap_playback; NpEnv exposes get_physics_state_layout() / get_playback_mocap_state() passthroughs with fail-closed gating.
  • Dependencies: unisim-core>=1.7.4 → >=1.7.5 (playback contract release) and mjbatch-uni~=0.2.3 → ~=0.2.4 (streaming VariantPack.builder, required by unisim-core 1.7.5's fixed-variant check — without it tests/base/test_entity_scene_consumer.py fails closed).

User-facing impact: backends without the playback contract (genesis/isaacgym) now get a clear startup error pointing at alternatives; mocap-body tasks render correctly in interactive viewers instead of crashing on mj_setState size mismatch. No training-path behavior change.

Linked Work

Validation

  • make test-all passed on the final local head before this PR was created or updated
  • Additional task-specific validation listed below

Commands actually run:

uv run --no-sync ruff format                       # 381 files unchanged
uv run --no-sync ruff check --fix                  # all checks passed
uv run --no-sync mypy src/unilab                   # 132 source files, no issues
uv run --no-sync pyright                           # 0 errors (1 pre-existing drake_uni import warning in cli.py)
uv run --no-sync ruff check tests --select F401,F821,F811,F841 --output-format concise
uv run --no-sync pytest -m "not slow" --cov=src/unilab --cov-report=term-missing -q
#   1539 passed, 26 skipped; the single failure was
#   tests/scripts/test_check_docs.py flagging *locally generated, gitignored*
#   scripts/benchmark/outputs/ artifacts (stale `_num_envs` key from a same-day
#   local benchmark run) — the test passes on a clean tree (19/19) on both main
#   and this head; not caused by this PR.
uv run --no-sync python scripts/benchmark/smoke_test.py   # 35/35 modules, 36/36 entrypoints

Focused suites on the final head (unisim-core 1.7.5 + mjbatch-uni 0.2.4):

uv run --no-sync pytest tests/visualization/ tests/base/ -q
#   582 passed, 17 skipped; 2 failures are a pre-existing test-isolation bug
#   (tests/visualization/test_playback_session.py pollutes
#   tests/base/test_mjwarp_playback.py when run in the same session) —
#   reproduced with this PR's changes stashed; out of scope here.

Remote CI route:

Impact

  • Backend impact: mujoco (MuJoCo playback-shell rendering path consumed by play_interactive / play_viser; mjwarp/newton/drake/superdex snapshots flow through the same contract entrypoints)
  • Platform impact: Linux (verified); macOS unaffected paths
  • Training effect expected: no

Artifacts

  • W&B: —
  • benchmark result: —
  • video / screenshot: —
  • ONNX / checkpoint: —

Checklist

  • Added or updated tests where needed (tests/visualization/test_playback_state.py, tests/base/test_np_env_playback_contract.py)
  • Updated docs if behavior or workflow changed (no user workflow change; entrypoint behavior is fail-fast with clearer errors)
  • Linked the driving issue
  • Noted any follow-up work explicitly: genesis/isaacgym playback adaptation is tracked separately per feat: 统一物理状态回放渲染契约,支撑 viser 等渲染前端适配全部回放后端 unilabsim/unisim#291 item 4; the test_playback_session.py → test_mjwarp_playback.py test-isolation bug and the stale-benchmark-output docs-check sensitivity are pre-existing issues observed during validation and left untouched.

…tive rendering

Downstream adaptation for unilabsim/unisim#291:

- play_interactive/play_viser precheck supports_physics_state_playback at
  startup and name the available rendering paths in the error instead of
  failing on the first snapshot fetch inside the viewer loop
- new unilab.visualization.playback_state owns the contract touchpoints:
  PhysicsStateApplier splits snapshots through the physics-state layout
  contract (no more hardcoded mjSTATE_FULLPHYSICS / 1+nq+nv) and replays
  mocap geometry through the contract get_playback_mocap_state entrypoint
- EnvPlayCapabilities gains supports_mocap_playback; NpEnv exposes
  get_physics_state_layout/get_playback_mocap_state passthroughs
- bump unisim-core to >=1.7.5 (playback contract release) and mjbatch-uni
  to ~=0.2.4 (streaming VariantPack builder required by unisim 1.7.5)

Affects the MuJoCo playback-shell rendering path only; physics ownership
is unchanged.
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