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
41 changes: 0 additions & 41 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,11 @@
sync:
uv sync --extra mujoco --extra motrix

# Switch the MuJoCo solver version (support window: >=3.5,<3.12), e.g.
# make mujoco MJ=3.10.0
# This is the explicit sdist fallback path: the prebuilt mujoco-uni-runtime
# wheels only bind the default mujoco==3.11.0, so any other version requires
# recompiling the native extension from source against the requested mujoco.
# The mujoco extra declares `mujoco~=3.11.0`, which a lock upgrade can never
# leave, so the override operates on the environment directly (uv pip, no
# re-lock): install the requested mujoco plus the runtime's build
# requirements, then force an in-env sdist rebuild of the runtime. The
# override is environment-local — uv.lock is untouched, and
# `uv sync --extra mujoco --reinstall-package mujoco-uni-runtime` reverts to
# the locked default (mujoco 3.11.0 + prebuilt wheel), which is the
# switch-back path. The reinstall flag is required there: plain `uv sync`
# restores mujoco but keeps the locally rebuilt extension, which then fails
# to load against the reverted mujoco. The default `make setup` path installs
# the prebuilt wheel and needs no compiler.
.PHONY: check-cxx-toolchain
check-cxx-toolchain:
@command -v c++ >/dev/null 2>&1 || { \
echo "error: building mujoco-uni-runtime from source requires a C++ toolchain, but 'c++' was not found."; \
echo " Debian/Ubuntu: sudo apt-get install build-essential"; \
echo " macOS: xcode-select --install"; \
echo " Fedora/RHEL: sudo dnf install gcc-c++ make"; \
exit 1; \
}

.PHONY: mujoco
mujoco:
@test -n "$(MJ)" || (echo "usage: make mujoco MJ=3.10.0" && exit 1)
@$(MAKE) --no-print-directory check-cxx-toolchain
uv pip install "mujoco==$(MJ)" pybind11 wheel setuptools
uv cache clean mujoco-uni-runtime
ver=$$(uv pip show mujoco-uni-runtime | sed -n 's/^Version: //p') && \
uv pip install --force-reinstall --no-deps --no-build-isolation \
--no-binary mujoco-uni-runtime "mujoco-uni-runtime==$$ver"

.PHONY: setup
setup:
uv sync --extra mujoco --extra motrix
uv run --no-sync unilab-complete install

.PHONY: setup-mujoco
setup-mujoco:
uv sync --extra mujoco
uv run --no-sync unilab-complete install

# Installs the Python extra and builds DrakeUni's native extension. By default
# the host-compatible official tarball is downloaded; use DRAKE_HOME=<prefix>
# to build against an existing installation.
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/source/api_reference/backend/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ only assembles task-owned scenes through `unilab.base.backend_factory`.

| Backend | Strengths | Notes |
|---|---|---|
| **MuJoCo** (`mujoco` + `mujoco-uni-runtime`) | Mature, broad asset support, deterministic | Default for research |
| **MuJoCo** (`mujoco` + `mjbatch`) | Mature, broad asset support, deterministic | Default for research |
| **Motrix** (`motrixsim-core`) | High-throughput, multithread step, snapshot/playback | Cross-platform; required for video export on macOS |

Pick a backend per task via the top-level `--sim <backend>` CLI flag — see
Expand Down
48 changes: 48 additions & 0 deletions docs/sphinx/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,54 @@ UniLab 遵循[语义化版本](https://semver.org/)。本共享页面以中英

## Unreleased / 未发布

- Replace the `mujoco-uni-runtime` dependency (`mujoco_uni` import) with the
`mjbatch` native batch engine across the repository (roadmap
[#1552](https://github.com/unilabsim/UniLab/issues/1552),
[#1553](https://github.com/unilabsim/UniLab/issues/1553)). The `mujoco`
extra now installs `mujoco~=3.11.0` plus `mjbatch` pinned to the
[integration fork](https://github.com/unilabsim/mjbatch); the fork's final
distribution identity (PyPI package vs git pin, and prebuilt wheels) is the
roadmap's open maintainer item. The `sim=mujoco` CLI runtime check now gates
on the `mjbatch` module. A post-swap ablation slimmed the pinned fork's
API ([#1557](https://github.com/unilabsim/UniLab/issues/1557)): the
per-substep callback is `fn(k, state, ctrl)` (no `callback_sensordata`
argument), `steps_done` / `stop_on_warning` are gone, and the hfield
scanner is height-only with its own validation. Numerical equivalence
before and after the swap is **not** guaranteed; the accepted drift is
characterized by the #1554 drift baseline.
全仓库将 `mujoco-uni-runtime` 依赖(`mujoco_uni` 导入)替换为 `mjbatch`
原生 batch 引擎(roadmap #1552、#1553)。`mujoco` extra 现安装
`mujoco~=3.11.0` 加钉住的 [集成 fork](https://github.com/unilabsim/mjbatch)
`mjbatch`;fork 的最终分发身份(PyPI package 还是 git 钉版、是否提供预编译
wheel)是 roadmap 上的待定维护事项。`sim=mujoco` 的 CLI 运行时检查改为检查
`mjbatch` 模块。替换后的消融精简了钉住 fork 的 API(#1557):per-substep
回调为 `fn(k, state, ctrl)`(不再有 `callback_sensordata` 参数),
`steps_done` / `stop_on_warning` 已移除,hfield 扫描器只输出高度并自带
校验。替换前后数值不保证一致;接受的漂移由 #1554 漂移基线表征。

- Deprecate and remove the MuJoCo chunk/forward knobs: `EnvCfg` fields
`post_step_forward_sensor`, `adaptive_chunk_size`, and `chunk_size`, the
`bench_nsteps` backend kwarg, the matching Hydra owner keys, and the
`make mujoco MJ=<version>` / `check-cxx-toolchain` / `setup-mujoco` Makefile
targets are gone. `mjbatch` schedules per-simulation work without a chunk
knob, and step ends one substep behind the state by default, matching the
previous `post_step_forward_sensor=False` semantics; the per-env model
variant machinery (`ModelVariantSpec` materialization on the MuJoCo backend)
is no longer supported there — init-lifecycle geometry overrides move to the
remaining variant-capable backends. Windows support is unchanged: the
MuJoCo physics backend stays Linux/macOS-only because `mjbatch` ships no
Windows wheels.
弃用并移除 MuJoCo chunk/forward 旋钮:`EnvCfg` 字段
`post_step_forward_sensor`、`adaptive_chunk_size`、`chunk_size`、`bench_nsteps`
后端 kwarg、对应的 Hydra owner 键,以及 Makefile 目标
`make mujoco MJ=<version>` / `check-cxx-toolchain` / `setup-mujoco` 均已删除。
`mjbatch` 在没有 chunk 旋钮的情况下调度 per-simulation 工作,且 sensordata
默认落后一个子步,与之前的 `post_step_forward_sensor=False` 语义一致;
MuJoCo 后端不再支持 per-env 模型 variants(`ModelVariantSpec`
materialization)——init-lifecycle 几何覆盖改由仍支持 variants 的后端提供。
Windows 支持不变:由于 `mjbatch` 不提供 Windows wheel,MuJoCo 物理后端
仍然只支持 Linux/macOS。

## 1.2.0 (2026-09-10)

- Update the required `unisim-core` release to `>=1.2.0` and the pinned
Expand Down
122 changes: 46 additions & 76 deletions docs/sphinx/source/en/1-getting_started/2-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ live in the getting-started and algorithm pages.
- Git and `curl`, used to clone the repository and fetch runtime assets.
- `cmake`, required when building the Drake native batch extension. The Drake
setup script uses CMake and a C++ toolchain.
- For the `mujoco` extra: the default install path uses the prebuilt
`mujoco-uni-runtime` wheel (bound to `mujoco==3.11.0`), so
`make setup` / `uv sync --extra mujoco` needs no compiler. A C++17 toolchain
and Python development headers are only required on the explicit
source-rebuild path (switching the MuJoCo version; see "Switching The Local
MuJoCo Version"); without them the build fails with errors such as
`fatal error: Python.h: No such file or directory` (see "Install Error
Signatures" for the full lookup table).
- For the `mujoco` extra: the MuJoCo physics backend executes on the
`mjbatch` native batch engine, currently consumed from the pinned
integration fork (`unilabsim/mjbatch`). uv builds it from the pinned git
source with an isolated build (scikit-build-core + nanobind), which requires
a C++17 toolchain and Python development headers; the build binds
`mujoco==3.11.0` and the engine refuses to import against any other mujoco
version. A no-compiler install path depends on the fork's final distribution
channel (prebuilt wheels vs the git pin), which is the roadmap's open item
(see "Switching The Local MuJoCo Version" and "Install Error Signatures").
- macOS: `xcode-select --install`
- Ubuntu / Debian: `sudo apt-get install build-essential python3-dev`
- Fedora / RHEL: `sudo dnf install gcc-c++ make python3-devel`
Expand Down Expand Up @@ -61,16 +62,12 @@ make setup

# Fastest path for the first Motrix demo.
# make setup-motrix

# MuJoCo only.
# make setup-mujoco
```

`make setup` runs `uv sync --extra mujoco --extra motrix` and installs shell
completion. `make setup-motrix` runs `uv sync --extra motrix` and installs the
same completion entry. `make setup-mujoco` runs `uv sync --extra mujoco` and
installs completion. Run only one of these paths. If `make` is unavailable, run
the matching commands directly:
same completion entry. Run only one of these paths. If `make` is unavailable,
run the matching commands directly:

```bash
# Full default setup:
Expand All @@ -79,16 +76,13 @@ uv run --no-sync unilab-complete install

# Motrix only:
# uv sync --extra motrix && uv run --no-sync unilab-complete install

# MuJoCo only:
# uv sync --extra mujoco && uv run --no-sync unilab-complete install
```

## Conda And Pip

The recommended path is still the in-repo `make setup` / `make setup-motrix` (or
`uv`) workflow. Use `make setup-mujoco` when Motrix is not needed. Conda can
serve as an outer environment for Python, CUDA, or system-library isolation,
`uv`) workflow. Use `uv sync --extra mujoco` when Motrix is not needed. Conda
can serve as an outer environment for Python, CUDA, or system-library isolation,
but once the environment is active keep using the repository's `make` / `uv`
commands inside it:

Expand All @@ -101,8 +95,8 @@ cd UniLab
make setup-motrix
```

Use `make setup-mujoco` if you do not need Motrix. ROCm and XPU still go through
the platform-specific `make` targets below.
Use `uv sync --extra mujoco` if you do not need Motrix. ROCm and XPU still go
through the platform-specific `make` targets below.

From a source checkout, pip is a fallback path. Install the package first, then
add optional runtimes explicitly:
Expand All @@ -117,19 +111,17 @@ pip install -e .
# Motrix, when needed:
pip install motrixsim-core==0.8.2

# MuJoCo, when needed (the default install resolves the prebuilt wheel bound
# to mujoco==3.11.0):
pip install "mujoco~=3.11.0" "mujoco-uni-runtime==0.5.0"
# MuJoCo, when needed (resolves the pinned mjbatch integration fork, built
# against mujoco==3.11.0):
pip install "mujoco~=3.11.0" "mjbatch @ git+https://github.com/unilabsim/mjbatch.git@cf4a83d"
```

The editable install points at the checkout; the regular install copies the
package and its task configs (`unilab/conf/`) into the environment. In both
cases, `train`, `eval`, and `demo` work from any directory, while logs and
checkpoints are written under the current working directory. The prebuilt
`mujoco-uni-runtime` wheel installs directly through pip with no build step;
`pybind11` / `wheel` and `--no-build-isolation` are only needed when forcing an
sdist rebuild against a non-default mujoco version (see "Switching The Local
MuJoCo Version"). For MJWarp, Genesis, platform-specific torch indexes, and
checkpoints are written under the current working directory. The `mjbatch`
engine builds against the pinned `mujoco==3.11.0`; for MJWarp, Genesis,
platform-specific torch indexes, and
ROCm/XPU profiles, prefer the uv paths above. Robot meshes and
textures are intentionally excluded from the wheel and downloaded on the cold
path from the `unilabsim/unilab-robots` dataset. Ensure the installed package
Expand Down Expand Up @@ -178,7 +170,7 @@ uv sync --extra mujoco --extra mjwarp --extra newton

| Backend | Install path | Important prerequisites |
| --- | --- | --- |
| MuJoCo | `make setup-mujoco` or `uv sync --extra mujoco` | Prebuilt wheel (bound to `mujoco==3.11.0`), no compiler needed; a C++17 toolchain and Python development headers are only required when switching versions (`make mujoco MJ=<version>`) |
| MuJoCo | `make setup` or `uv sync --extra mujoco` | Builds the pinned `mjbatch` fork (bound to `mujoco==3.11.0`) from source; a C++17 toolchain and Python development headers are required until prebuilt wheels exist (roadmap open item) |
| Motrix | `make setup-motrix` or `uv sync --extra motrix` | Motrix runtime is installed from the pinned Python package |
| MJWarp | `uv sync --extra mujoco --extra mjwarp` | NVIDIA CUDA and an explicit CUDA process device |
| Genesis | `uv sync --extra genesis` | The validated path uses Linux x86_64, an NVIDIA GPU, and the pinned torch/Genesis versions |
Expand All @@ -205,57 +197,33 @@ runtime variables, renderer requirements, and verification commands:

## Switching The Local MuJoCo Version

The default install path of the `mujoco` extra uses the prebuilt
`mujoco-uni-runtime==0.5.0` wheel. Each runtime release carries exactly one
prebuilt MuJoCo binding: the 0.5.0 wheels are compiled against
`mujoco==3.11.0`, and the native extension records its build-time mujoco
version and refuses to load on a mismatch (see the watchdog row in "Install
Error Signatures"). A bump of the default MuJoCo version therefore always
ships with a new runtime release; the coordination details live in the
mujoco-uni-runtime repository's `docs/release-coordination.md`.

Switching the MuJoCo version inside the support window `>=3.5,<3.12` always
takes the source-rebuild path:
The `mujoco` extra declares `mujoco~=3.11.0`, and the `mjbatch` batch engine
is built against `mujoco==3.11.0`: it records its build-time mujoco version
and refuses to import against a different one (see the watchdog row in
"Install Error Signatures"). Switching the local MuJoCo version therefore
requires an `mjbatch` build against that version — it is not a UniLab config
change:

```bash
make mujoco MJ=3.10.0
```
1. bump the `mujoco` bound and the `mjbatch` source pin in `pyproject.toml`
(and mirror `pyproject.rocm.toml`),
2. re-lock (`uv lock`, plus the ROCm lockfile via `make sync-rocm`) and
re-sync (`uv sync --extra mujoco`).

The `mujoco` extra declares `mujoco~=3.11.0`, which a re-lock can never leave,
so the target operates on the environment directly (`uv pip`, without touching
`uv.lock`). It runs, in order:

1. the `check-cxx-toolchain` preflight: fails fast when no C++ compiler is
found and prints per-platform install commands;
2. `uv pip install "mujoco==3.10.0" pybind11 wheel setuptools`: installs the
requested mujoco plus the runtime's build requirements into the current
environment;
3. `uv cache clean mujoco-uni-runtime`: drops the build cache (uv's cache
cannot see that the extension depends on the mujoco version);
4. `uv pip install --force-reinstall --no-deps --no-build-isolation
--no-binary mujoco-uni-runtime "mujoco-uni-runtime==<installed version>"`:
recompiles the native extension from the sdist against the new mujoco.

The override is **environment-local**: `uv.lock` stays unchanged. The
switch-back path is `uv sync --extra mujoco --reinstall-package
mujoco-uni-runtime`, which restores the locked default (mujoco 3.11.0 +
prebuilt wheel); the `--reinstall-package` flag is required because a plain
`uv sync` restores mujoco but keeps the locally rebuilt extension, which then
fails to load. The source rebuild requires a C++17 toolchain and Python
development headers (see "Requirements").
The fork's build pins `mujoco==3.11.0` at build time, so the isolated build
always compiles against the matching mujoco. Until the fork's distribution
identity is decided (PyPI package vs git pin — the roadmap's open item),
coordinate version bumps with the
[fork](https://github.com/unilabsim/mjbatch).

## Install Error Signatures

Reverse-lookup from error text to cause and fix.

| Error signature | Where it comes from | Fix |
| --- | --- | --- |
| `error: building mujoco-uni-runtime from source requires a C++ toolchain, but 'c++' was not found.` | The `check-cxx-toolchain` preflight of `make mujoco MJ=<version>` | Install a C++ toolchain and retry: Debian/Ubuntu `sudo apt-get install build-essential`; macOS `xcode-select --install`; Fedora/RHEL `sudo dnf install gcc-c++ make` |
| `error: [Errno 2] No such file or directory: 'c++'` (or `c++: No such file or directory`) | Building `mujoco-uni-runtime` from the sdist without a compiler; only occurs on the source-rebuild path — the default wheel path never compiles | Same toolchain install as above; or do not switch versions and use the default wheel path `uv sync --extra mujoco` |
| `fatal error: Python.h: No such file or directory` | Missing Python development headers during a source rebuild | A uv-managed Python (`uv python install`) bundles the headers; system Pythons need `python3-dev` (Debian/Ubuntu) or `python3-devel` (Fedora/RHEL) |
| `MuJoCoUni native batch extension was built against mujoco '3.11.0', but loaded mujoco is '...'` | Version watchdog: the extension's recorded build-time mujoco version does not match the loaded mujoco | Install the mujoco version the extension binds (the prebuilt wheel binds `3.11.0`: `uv sync --extra mujoco --reinstall-package mujoco-uni-runtime`); or rebuild from source against the active mujoco: `make mujoco MJ=<version>` |
| `mujoco_uni 0.5.0 supports official mujoco>=3.5,<3.12; found mujoco '...'` | The installed mujoco is outside the runtime's support window | Install a mujoco version inside `>=3.5,<3.12` (`make mujoco MJ=<version>`) |
| `MuJoCoUni native batch extension has not been built` | The native extension failed to import (`mujoco_uni.batch_available()` returns `False`); a common cause is a plain `uv sync` after a version switch, which restores mujoco but keeps the locally rebuilt extension linked to the old `libmujoco.so` | Run `uv run python -c "import mujoco_uni; print(mujoco_uni.batch_import_error())"` for the underlying cause; after a version switch, restore the prebuilt wheel with `uv sync --extra mujoco --reinstall-package mujoco-uni-runtime` |
| `fatal error: Python.h: No such file or directory` | Missing Python development headers while uv builds the `mjbatch` fork from source | A uv-managed Python (`uv python install`) bundles the headers; system Pythons need `python3-dev` (Debian/Ubuntu) or `python3-devel` (Fedora/RHEL) |
| `error: [Errno 2] No such file or directory: 'c++'` (or `c++: No such file or directory`) | Building `mjbatch` from the pinned git source without a compiler | Install a C++ toolchain (see "Requirements") and retry `uv sync --extra mujoco` |
| `mjbatch was built against MuJoCo <version> but <other> is installed` | Version watchdog: the engine's build-time mujoco pin does not match the installed mujoco | Restore the locked pair with `uv sync --extra mujoco`; a different mujoco version requires an `mjbatch` rebuild (see "Switching The Local MuJoCo Version") |

## Platform Profiles

Expand All @@ -269,10 +237,12 @@ uses the `mjpython` application bundled by the official MuJoCo wheel. Torch's
`cuda` alias resolves to MPS when CUDA is absent.

On Windows, use the direct `uv sync` commands from above unless GNU `make` and
Bash are available. The default install uses the prebuilt wheel; MSVC Build
Tools and Python development headers are only needed when rebuilding the MuJoCo
native extension from source (version switch). If you want to use the Makefile,
install GNU Make and Bash separately (for example through Chocolatey or WSL).
Bash are available. The `mjbatch` engine does not ship Windows wheels (the
official `mujoco.dll` provides no import library), so the MuJoCo physics
backend stays Linux/macOS-only there; plain `mujoco` (MJCF conversion,
playback rendering via other backends) still installs. If you want to use the
Makefile, install GNU Make and Bash separately (for example through Chocolatey
or WSL).

ROCm and Intel XPU have explicit Makefile targets:

Expand Down
Loading
Loading