Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Render modes:

- `interactive` — open viewer window (default on macOS Motrix).
- `record` — write MP4 to `runs/<run>/playback/`.
- `viser` — serve the rollout in a browser-based viser viewer
(`--sim mujoco` / `--sim mjwarp` only; requires the viser extra).
- `viser` — serve the rollout in a browser-based viser viewer (any backend
with physics-state playback: `mujoco`, `mjwarp`, `newton`, `drake`,
`superdex`).
- `none` — skip rendering, just compute metrics.

For `--sim mujoco --render-mode interactive`, `uv run eval` launches the dedicated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ Supported render modes are `auto`, `interactive`, `record`, `viser`, and
The MuJoCo interactive mode (`--sim mujoco --render-mode interactive`) routes
directly to `play_interactive.py` and always rolls out one environment.

For `--sim mujoco` and `--sim mjwarp`, `--render-mode viser` routes to the
browser-based viser viewer (`play_viser.py`): no local display is required,
and macOS runs it without `mjpython`. It needs the viser extra (`uv sync
--extra viser`); the `viser.*` config group (`viser.port`, `viser.max_envs`,
For backends with physics-state playback (`mujoco`, `mjwarp`, `newton`,
`drake`, `superdex`), `--render-mode viser` serves the rollout through the
browser-based viser viewer: no local display is required, and macOS runs it
without `mjpython`. Eval routes to the standalone `play_viser.py` viewer;
train runs the same viewer as its post-training playback. viser is a required
dependency; the `viser.*` config group (`viser.port`, `viser.max_envs`,
`viser.display_mode`, `viser.env_idx`) tunes the server and the scene.

## Demo
Expand Down
3 changes: 2 additions & 1 deletion docs/sphinx/source/en/2-user_guide/3-backends/0-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ The selected owner YAML sets `training.sim_backend` as an identity field.
paths.
- `--render-mode record` records without opening an interactive window.
- `--render-mode viser` serves the rollout in a browser-based viser viewer on
MuJoCo and mjwarp paths (requires the viser extra).
backends with physics-state playback (MuJoCo, mjwarp, newton, drake,
superdex).
- `--render-mode none` disables playback.

```bash
Expand Down
3 changes: 1 addition & 2 deletions docs/sphinx/source/en/5-reference/5-support_matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ in English. Do not infer support beyond the evidence grade shown below.
## Playback Differences

- `mujoco`: `--render-mode auto` exports `play_video.mp4`; `--render-mode
viser` serves the rollout in a browser-based viser viewer (requires the
viser extra).
viser` serves the rollout in a browser-based viser viewer.
- `motrix`: `--render-mode auto` opens an interactive renderer window; it does
not record a video and is not bound by `play_steps`.
- `mjwarp`: supports explicit, finite-step `record` by default, rendered offline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ uv run demo dance
- `interactive` — 打开查看器窗口(macOS Motrix 上的默认值)。
- `record` — 将 MP4 写入 `runs/<run>/playback/`。
- `viser` — 在基于浏览器的 viser viewer 中展示回放
(仅 `--sim mujoco` / `--sim mjwarp`;需要 viser extra)。
(支持所有具备 physics-state playback 的后端:`mujoco`、`mjwarp`、`newton`、`drake`、`superdex`)。
- `none` — 跳过渲染,仅计算指标。

当使用 `--sim mujoco --render-mode interactive` 时,`uv run eval` 会直接启动
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ uv run eval --algo ppo --task go2_joystick_flat --sim motrix --load-run -1 \
(`--sim mujoco --render-mode interactive`)直接路由到 `play_interactive.py`,并始终只
rollout 一个环境。

`--sim mujoco` 和 `--sim mjwarp` 还支持 `--render-mode viser`:路由到基于浏览器的
viser viewer(`play_viser.py`),不需要本地显示,在 macOS 上也不需要 `mjpython`。
该模式需要 viser extra(`uv sync --extra viser`);`viser.*` 配置组
具备 physics-state playback 的后端(`mujoco`、`mjwarp`、`newton`、`drake`、`superdex`)
还支持 `--render-mode viser`:通过基于浏览器的 viser viewer 展示回放,不需要本地显示,
在 macOS 上也不需要 `mjpython`。eval 会路由到独立的 `play_viser.py` viewer;train 则在
训练后回放阶段运行同一 viewer。viser 是必选依赖;`viser.*` 配置组
(`viser.port`、`viser.max_envs`、`viser.display_mode`、`viser.env_idx`)用于调整服务器与场景。

## 演示
Expand Down
4 changes: 2 additions & 2 deletions docs/sphinx/source/zh_CN/2-user_guide/3-backends/0-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ Owner YAML 位置:
- `--render-mode auto` 在 MuJoCo 路径上导出 `play_video.mp4`。
- `--render-mode auto` 在 Motrix 路径上打开 Motrix 原生交互式渲染。
- `--render-mode record` 在不打开交互式窗口的情况下录制。
- `--render-mode viser` 在 MuJoCo 和 mjwarp 路径上通过基于浏览器的 viser
viewer 展示回放(需要 viser extra)。
- `--render-mode viser` 在具备 physics-state playback 的后端(MuJoCo、mjwarp、
newton、drake、superdex)上通过基于浏览器的 viser viewer 展示回放。
- `--render-mode none` 禁用回放。

```bash
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
## Playback Differences

- `mujoco`: `--render-mode auto` 会导出 `play_video.mp4`;`--render-mode viser`
通过基于浏览器的 viser viewer 展示回放(需要 viser extra)
通过基于浏览器的 viser viewer 展示回放
- `motrix`: `--render-mode auto` 会打开交互式 renderer 窗口,不录制视频,不受 `play_steps` 限制
- `mjwarp`: 默认仅支持显式、有限步数的 `record`,通过 task owner 的 MuJoCo visual model 离线录制;`--render-mode interactive` 路由到 MuJoCo 交互 viewer(mjwarp 跑物理、MuJoCo 渲染 env[0],强制单 env);`--render-mode viser` 路由到浏览器 viser viewer(按 env 使用 MuJoCo playback model);不支持 `auto` 或 native renderer
- `isaacsim`: `auto` 在有 display 时选择 Kit viewer,否则选择 headless RGB camera;当前真实主机仍有 RTX renderer 初始化 blocker,支持等级保持 `Configured`
Expand Down
39 changes: 7 additions & 32 deletions pyproject.rocm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,7 @@ classifiers = [
requires-python = ">=3.10,<3.14"
dependencies = [
"numpy",
# Physics implementations are provided by the independently released
# unisim-core package. Version 1.5.0 provides the M2 physical entity,
# immutable variant, layout and selected-reset contracts; 1.6.0 adds
# Newton CUDA graph execution; 1.7.2 adds SuperDex physical
# kinematic roots to the portable MJCF profile; and 1.7.3 adds IsaacSim
# mapped-scene contact sensors, bounded PhysX solver configuration and
# mapped reset domain randomization.
"unisim-core>=1.7.3",
# RL algorithms and async runtimes live in the independently released
# uni-rl package (distribution name ``unilab-rl``); see pyproject.toml.
# Optional: only APPO, off-policy algorithms, and multi-GPU PPO need it
# (extra ``uni_rl``); the dev group below keeps it installed for CI.
"torch==2.11.0",
"triton-rocm==3.6.0 ; sys_platform == 'linux' and platform_machine == 'x86_64'",
"gymnasium",
Expand All @@ -57,6 +46,8 @@ dependencies = [
"huggingface_hub>=0.25",
"ninja ; sys_platform == 'linux'",
"imageio-ffmpeg>=0.6.0",
"viser>=1.0.26",
"trimesh>=3.21.7",
]

[project.scripts]
Expand All @@ -72,36 +63,20 @@ unilab-pull-assets = "unilab.assets.pull:main"
drake = [
"drake-uni==0.1.0",
]
# mjbatch is built and version-checked against mujoco==3.11.0; switching
# MuJoCo versions requires an mjbatch rebuild.
mujoco = [
# MuJoCo 3.11 alignment (unilabsim/UniLab#1515): the bound is a
# compatible-release specifier; uv.rocm.lock pins the exact MuJoCo
# version. The MuJoCo physics backend (unisim.backend.mujoco.backend)
# executes on the mjbatch native batch engine, which is built and
# version-checked against mujoco==3.11.0 — switching MuJoCo versions
# requires an mjbatch rebuild, not a UniLab config change. The batch
# engine is the unilabsim mjbatch fork, published on PyPI as
# mjbatch-uni (#1552); its build backend pins mujoco==3.11.0 at build
# time, so isolated builds are correct and no compiler preflight is
# needed.
"mujoco~=3.11.0",
"mjbatch-uni~=0.2.1",
]
# The Motrix runtime pin lives in the unisim-core ``motrix`` extra, so
# the consumed runtime always matches the version the
# unisim.backend.motrix adapter is tested against.
motrix = ["unisim-core[motrix]>=1.7.3"]
viser = ["viser>=1.0.26", "trimesh>=3.21.7"]
# APPO / off-policy (SAC) runners, collectors, IPC, and multi-GPU
# data-parallel PPO launches require the optional uni-rl runtime. PPO
# single-process training and playback run directly on rsl-rl-lib.
uni_rl = ["unilab-rl==1.3.2"]

[dependency-groups]
# Repo development and CI exercise the APPO/off-policy/multi-GPU paths, so
# the dev environment keeps the optional unilab-rl runtime installed.
# Dev/CI exercises the APPO/off-policy/multi-GPU paths, so the optional
# unilab-rl runtime stays installed in the dev environment.
dev = ["pytest", "pytest-cov", "ruff", "mypy", "pyright>=1.1.408", "unilab-rl==1.3.2"]

# ========== ROCm 索引配置 ==========
[[tool.uv.index]]
name = "pytorch-rocm72"
url = "https://download.pytorch.org/whl/rocm7.2"
Expand Down Expand Up @@ -175,7 +150,7 @@ venv = ".venv"
include = ["src/unilab"]
exclude = [
"src/unilab/envs/", # lazy optional `mujoco` import; not installed in the pyright env
"src/unilab/visualization/", # direct mujoco C bindings + optional viser deps
"src/unilab/visualization/", # direct mujoco C bindings; not installed in the pyright env
]
reportMissingImports = "warning"
reportMissingModuleSource = "none"
110 changes: 18 additions & 92 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ requires = ["uv_build>=0.12.1,<0.13"]
build-backend = "uv_build"

[tool.uv.build-backend]
# Robot meshes/textures are hosted on Hugging Face (unilabsim/unilab-robots)
# and downloaded into these paths on first use; keep them out of the
# wheel/sdist even when they exist in the source tree. XML and small metadata
# stay packaged. Directories must stay in sync with ROBOT_ASSET_SPECS and
# SUPERDEX_ROBOT_ASSET_SPECS in src/unilab/assets/hub.py.
# Downloaded robot meshes stay out of the wheel; keep in sync with
# ROBOT_ASSET_SPECS in src/unilab/assets/hub.py.
source-exclude = [
"/src/unilab/assets/bots",
"/src/unilab/assets/robots/allegro_hand/assets",
Expand Down Expand Up @@ -38,33 +35,11 @@ classifiers = [
requires-python = ">=3.10,<3.14"
dependencies = [
"numpy",
# Physics implementations are provided by the independently released
# unisim-core package. Version 1.5.0 provides the M2 physical entity,
# immutable variant, layout and selected-reset contracts; 1.5.1 adds
# get_motion_body_ids on the newton/genesis adapters; 1.6.0 adds Newton
# CUDA graph execution; 1.7.0 adds the portable MJCF scene profile;
# 1.7.1 isolates the IsaacSim worker from host compiled dependencies;
# 1.7.2 adds SuperDex physical kinematic roots to the portable profile;
# and 1.7.3 adds IsaacSim mapped-scene contact sensors, bounded PhysX
# solver configuration, per-entity self-collision and mapped reset
# domain randomization, plus IsaacGym mapped-scene reset randomization.
# 1.7.5 formalizes the physics-state playback rendering contract (layout
# split, mocap playback, conformance coverage; unilabsim/unisim#291).
"unisim-core>=1.7.5",
# RL algorithms and async runtimes (APPO/SAC runners, collectors,
# IPC, logging) live in the independently released uni-rl package
# (distribution name ``unilab-rl``), consumed via the injected env
# contract (uni_rl.env_contract.EnvFactory). It is an optional dependency:
# PPO training and playback run directly on rsl-rl-lib; only APPO,
# off-policy algorithms, and multi-GPU data-parallel PPO need it
# (extra ``uni_rl``). Published on PyPI.
"numba>=0.67",
"prettytable>=3.10",
# torch is a range (not an exact pin) so that published PyPI metadata lets
# ROCm users substitute a rocm build installed from the PyTorch ROCm index
# (install torch there first, then unilab; pip keeps the installed build).
# Repo development and CI stay reproducible: uv.lock pins the tested
# cu128/cu130 builds below via tool.uv.sources.
# A range (not an exact pin) lets ROCm users substitute a ROCm torch
# build; uv.lock pins the tested CUDA builds via tool.uv.sources.
"torch>=2.9,<2.12 ; sys_platform == 'linux' and platform_machine == 'aarch64'",
"torch>=2.8,<2.12 ; sys_platform != 'linux' or platform_machine != 'aarch64'",
"gymnasium",
Expand All @@ -75,11 +50,7 @@ dependencies = [
"rsl-rl-lib>=5.0.0",
"packaging",
"mediapy",
# >=2.21 drops the pkg_resources import removed in setuptools>=82,
# which otherwise breaks `uv run tensorboard` at startup.
"tensorboard>=2.21.0",
# Unpinned: quadrants (genesis-world 1.3.3 pin) requires setuptools>=77,
# and nothing in this repo imports setuptools/pkg_resources at runtime.
"setuptools",
"rich",
"tqdm",
Expand All @@ -91,6 +62,8 @@ dependencies = [
"huggingface_hub>=0.25",
"ninja ; sys_platform == 'linux'",
"imageio-ffmpeg>=0.6.0",
"viser>=1.0.26",
"trimesh>=3.21.7",
]

[project.scripts]
Expand All @@ -109,91 +82,44 @@ Repository = "https://github.com/unilabsim/UniLab"
Issues = "https://github.com/unilabsim/UniLab/issues"

[project.optional-dependencies]
# Drake C++ is an external toolchain; the native extension is built against
# the local DRAKE_HOME after sync. mujoco provides the playback renderer.
drake = [
# Python runtime for the Drake batch adapter. Drake C++ remains an external
# toolchain and the native extension must be built against the local
# DRAKE_HOME after this extra is synced.
"drake-uni==0.1.0",
# Drake playback always uses MuJoCo's native renderer (MuJoCo is never
# stepped). Keep the renderer available from the single Drake install
# path; the MuJoCo physics extension remains in the separate mujoco extra.
"mujoco>=3.5",
]
# mjbatch is built and version-checked against mujoco==3.11.0; switching
# MuJoCo versions requires an mjbatch rebuild.
mujoco = [
# MuJoCo 3.11 alignment (unilabsim/UniLab#1515): the mujoco, mjwarp, and
# newton extras share one MuJoCo 3.11 / MuJoCo-Warp 3.11 / warp-lang 1.16.0
# line and are jointly installable. The `mujoco` bound is a compatible-
# release specifier; `uv.lock` pins the exact MuJoCo version. The MuJoCo
# physics backend (unisim.backend.mujoco.backend) executes on the mjbatch
# native batch engine, which is built and version-checked against
# mujoco==3.11.0 — switching MuJoCo versions requires an mjbatch rebuild,
# not a UniLab config change.
"mujoco~=3.11.0",
# The batch engine is the published unilabsim mjbatch fork. 0.2.4 adds the
# streaming VariantPack builder required by unisim-core 1.7.5.
"mjbatch-uni~=0.2.4",
]
# Shares the MuJoCo 3.11 / warp-lang 1.16 line with the mujoco/newton extras.
mjwarp = [
# Keep the Warp backend on the same MuJoCo minor line as the host backend.
# ``mujoco-warp`` imports as ``mujoco_warp`` and owns the GPU physics
# implementation; it is deliberately a separate optional extra rather
# than a mode of the ``mujoco`` backend. warp-lang stays an exact pin on
# the 1.16.0 line shared with the newton extra.
"mujoco-warp~=3.11.0",
"warp-lang==1.16.0",
]
newton = [
# Newton 1.5.1 is coupled to the MuJoCo-Warp 3.11 / Warp 1.16 line, so
# these stay exact pins. They sit on the same 3.11 line as the mujoco and
# mjwarp extras: newton 1.5.1 requires warp-lang>=1.16.0, and mujoco-warp
# 3.11.0 accepts warp-lang>=1.14 and mujoco>=3.9.0, so warp-lang==1.16.0
# satisfies all three extras in one joint environment.
"newton==1.5.1",
"mujoco-warp==3.11.0",
"mujoco==3.11.0",
"warp-lang==1.16.0",
# Newton's MJCF importer loads mesh assets through trimesh on the
# materialization cold path; newton does not declare it as a hard
# dependency, so the extra carries it explicitly.
"trimesh>=3.21.7",
# Native ViewerGL is Newton's default playback renderer (offline record
# and interactive), so keep its GUI stack in the same backend extra.
# ViewerGL playback renderer GUI stack.
"pyglet>=2.1.6,<3",
"imgui-bundle>=1.92.0",
]
# The Motrix runtime pin lives in the unisim-core ``motrix`` extra, so
# the consumed runtime always matches the version the
# unisim.backend.motrix adapter is tested against.
motrix = ["unisim-core[motrix]>=1.7.5"]
genesis = [
# Genesis imports as ``genesis`` and owns the GPU physics implementation;
# it is a separate optional extra pinned exactly to the probed release
# (scripts/tools/genesis_feasibility/REPORT.md, #1372).
"genesis-world==1.3.3",
]
viser = ["viser>=1.0.26", "trimesh>=3.21.7"]
# APPO / off-policy (SAC) runners, collectors, IPC, and multi-GPU
# data-parallel PPO launches require the optional uni-rl runtime. PPO
# single-process training and playback run directly on rsl-rl-lib.
genesis = ["genesis-world==1.3.3"]
uni_rl = ["unilab-rl==1.3.2"]
# SuperDex Physics/Robotics 1.1.0 ships as published wheels; the exact pins and
# the temporary superdex-uni build names are owned by unisim-core's superdex
# extra (they revert to superdex-physics/-robotics once the upstream
# project_superdex release lands). That extra already carries plain `mujoco`
# for MJCF conversion and the offline playback renderer; mjbatch is
# deliberately NOT bound here, since only the MuJoCo physics backend
# (unisim.backend.mujoco.backend) needs it and UniLab guards that backend on
# the `mjbatch` module. The wheels are CPython 3.12/3.13 Linux x86_64 only,
# so the marker keeps `uv lock` resolvable for the other
# required-environments; elsewhere the extra is empty and the CLI reports a
# targeted runtime diagnostic.
# Wheels are CPython 3.12/3.13 Linux x86_64 only; the marker keeps uv lock
# resolvable for the other required-environments.
superdex = [
"unisim-core[superdex]>=1.7.5 ; python_version >= '3.12' and sys_platform == 'linux' and platform_machine == 'x86_64'",
]

[dependency-groups]
# Repo development and CI exercise the APPO/off-policy/multi-GPU paths, so
# the dev environment keeps the optional unilab-rl runtime installed.
# Dev/CI exercises the APPO/off-policy/multi-GPU paths, so the optional
# unilab-rl runtime stays installed in the dev environment.
dev = ["pytest", "pytest-cov", "ruff", "mypy", "pyright>=1.1.408", "unilab-rl==1.3.2"]

[[tool.uv.index]]
Expand Down Expand Up @@ -269,7 +195,7 @@ venv = ".venv"
include = ["src/unilab"]
exclude = [
"src/unilab/envs/", # lazy optional `mujoco` import; not installed in the pyright env
"src/unilab/visualization/", # direct mujoco C bindings + optional viser deps
"src/unilab/visualization/", # direct mujoco C bindings; not installed in the pyright env
]
reportMissingImports = "warning"
reportMissingModuleSource = "none"
6 changes: 1 addition & 5 deletions scripts/play_viser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

Thin wrapper around the packaged viewer ``unilab.scripts.play_viser``; the
playback loop, session dispatch, and scene code live there. This script keeps
the direct Hydra entry for source checkouts.

Prerequisites::

uv sync --extra viser
the direct Hydra entry for source checkouts. viser is a required dependency.

Usage::

Expand Down
Loading
Loading