Skip to content

Enable viser rendering for the motrix backend - #1639

Merged
TATP-233 merged 4 commits into
mainfrom
feat/motrix-viser-playback
Sep 24, 2026
Merged

TATP-233 merged 4 commits into
mainfrom
feat/motrix-viser-playback

Conversation

@TATP-233

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #1638: unisim-core 1.7.6 (unilabsim/unisim#302) implements the physics-state playback contract on the Motrix adapter — for both portable entity scenes and whole-MJCF scenes guarded by a construction-time MJCF joint-order validation — so the browser-based viser viewer no longer fail-closes on --sim motrix.

  • src/unilab/cli.py: motrix leaves VISER_UNSUPPORTED_SIMS (genesis/isaacgym/isaacsim keep their fail-closed rejection); viser is browser-based, so macOS motrix playback no longer requires mxpython for this mode.
  • Dependency pins move to unisim-core>=1.7.6 (pyproject.toml, pyproject.rocm.toml, uv.lock): the motrix playback contract only exists since 1.7.6.
  • Tests: the two former motrix rejection cases become positive routing cases (eval → play_viser.py, train → training.play_render_mode=viser forwarded to the train script); new genesis eval/train rejection cases keep the fail-closed branch covered.
  • Docs: en/zh support matrix playback sections record motrix viser routing.

Validation

  • uv run pytest tests/test_cli.py tests/visualization -q — 119 passed
  • make check — green (ruff, mypy, pyright)
  • tests/scripts/test_check_docs.py — only the 3 pre-existing scripts/benchmark/outputs failures already present on clean main
  • End-to-end on real checkpoint (logs/rsl_rl_ppo/Go2JoystickFlat/2026-09-22_13-24-20_motrix):
    uv run eval --algo ppo --task go2_joystick_flat --sim motrix --render-mode viser viser.max_envs=2 viser.port=18099 training.play_steps=100
    — viser server comes up, 2 env slots render from motrix physics-state snapshots, ran 150s clean (server loop stopped by timeout).

Known scope boundary (upstream): kinematic mocap mirroring in playback is phase 2, so tasks whose playback MJCF carries mocap bodies (e.g. g1_motion_tracking) still fail closed at the PhysicsStateApplier with an actionable error.

unisim-core 1.7.6 (unilabsim/unisim#302) implements the physics-state
playback contract on the Motrix adapter for both portable entity scenes
and audited whole-MJCF scenes, so the viser viewer no longer fail-closes
on --sim motrix: eval routes to play_viser.py and train forwards
training.play_render_mode=viser, and the browser-based viewer no longer
requires mxpython on macOS. genesis/isaacgym/isaacsim keep their
fail-closed rejection, now covered by dedicated tests.
The whole-MJCF joint-order validation added in unilabsim/unisim#302 runs
at MotrixBackend construction: fake-model tests stub it out (its own
coverage lives upstream), the pre-step-control fake gains the new
_time_view/_sim_dt playback-clock fields, and the stewart scene names its
twelve passive leg hinges (physics unchanged) because the validation
requires named MJCF joints.
@TATP-233

Copy link
Copy Markdown
Collaborator Author

CI 暴露了两类问题,均已定位:

  1. 上游 1.7.6 缺陷(阻塞本 PR):extract_mjcf_joint_layout 只读取第一个 <worldbody>,include 合并场景丢关节 → allegro in-hand 场景构造失败。已提上游修复 fix(motrix): merge every worldbody in extract_mjcf_joint_layout unilabsim/unisim#306(CI 绿),等 1.7.7 发版后本 PR 升 pin 到 >=1.7.7。
  2. UniLab 测试 fixture 不适配新构造校验:已修复并推送(5e31688e)——stewart 场景 12 个被动铰链命名、fake-model 测试补齐/屏蔽新校验。

本地用修复版 unisim 全量复验:1544 passed,唯一失败是 main 上既有的 docs 检查项。

unisim-core 1.7.8 merges every <worldbody> section (including the ones
inlined by <include>) in extract_mjcf_joint_layout, matching MuJoCo.
Without it, scenes composed from includes that each carry a worldbody
(for example the Allegro in-hand scene) fail motrix playback validation
at construction with a generalized-state dimension mismatch.
The test job restores a long-lived actions/cache snapshot of
src/unilab/assets/robots to reuse HF-downloaded meshes, but the snapshot
also contains git-tracked scene XMLs and silently rolls them back to the
cached revision. The stewart scene rename in this branch (named passive
hinges, required by the unisim-core 1.7.6+ motrix joint-order validation)
never reached the parser: CI kept reading the cached old XML and failed
with 'a hinge joint on body leg00 is unnamed' while the checked-out
commit carried the fix. Restore tracked files from the index after the
cache extraction; untracked mesh downloads are unaffected.
@TATP-233

Copy link
Copy Markdown
Collaborator Author

更新:unisim-core 1.7.8 已发布(含 unilabsim/unisim#306 的多 worldbody 合并修复),本 PR 三处 pin 已升到 >=1.7.8 并复锁 uv.lock,CI 全绿。

排查记录:升 pin 后 CI 曾持续报 stewart unnamed hinge on leg00,但 merge ref、PyPI sdist、本地 py3.11 全量复现均正常。根因是测试 job 的 actions/cache(key 只随 hub.py 变化)会把整个 src/unilab/assets/robots 旧快照盖回 checkout,git 跟踪的 scene XML 被悄悄回滚到缓存版本;main 锁 1.7.5 无 joint 校验所以从未暴露。已加 git restore 步骤固定跟踪文件到当前 commit(b6af915f),缓存的 HF 网格文件不受影响。

@TATP-233
TATP-233 merged commit d92772f into main Sep 24, 2026
8 checks passed
@TATP-233
TATP-233 deleted the feat/motrix-viser-playback branch September 24, 2026 10:50
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