- This guide applies to everything under
src/mjlab/**. - Default to editing only
src/mjlab/**unless the user explicitly asks otherwise. - Prefer reusing existing runnable entrypoints under
src/mjlab/scripts/instead of writing new glue code.
mjlab/envs/: MuJoCo RL env core (ManagerBasedRlEnv,ManagerBasedRlEnvCfg) and shared MDP utilities.mjlab/tasks/: Task registry + task-specific configs/MDP terms.mjlab/rl/: RSL-RL wrappers, runner configs, exporters.mjlab/scripts/: CLI entrypoints (train.py,play.py,list_envs.py,demo.py).mjlab/viewer/: Viewer backends (NativeMujocoViewer,ViserPlayViewer).
- Tasks are registered via
mjlab.tasks.registry.register_mjlab_task(...). - Registration happens at import-time, typically from
mjlab/tasks/**/config/**/__init__.py. import mjlab.tasksrecursively imports task packages viamjlab.utils.lab_api.tasks.importer.import_packages, with a blacklist of package-name substrings:["utils", ".mdp"].- Put registration code in
config/packages (not inmdp/). - Keep import-time side effects limited to registration (avoid starting sims, allocating GPU memory, etc.).
- Put registration code in
Mjlab-Homie-Unitree-H1Mjlab-Homie-Unitree-H1-with_hands
- Base env config factory:
mjlab/tasks/homie/homie_env_cfg.py - Robot-specific overrides:
mjlab/tasks/homie/config/h1/env_cfgs.py - PPO runner config:
mjlab/tasks/homie/config/h1/rl_cfg.py - MDP terms (obs/reward/termination/curriculum):
mjlab/tasks/homie/mdp/ - Custom runner:
mjlab/tasks/homie/rl/runner.py- When logging to W&B, it exports an ONNX policy and attaches metadata on each save.
- If you change HOMIE observation/action shapes, also update any dependent utilities.
- Example:
mjlab/scripts/infer_h1_with_hands_lowerbody_policy.pycurrently expectsobs_dim=97,act_dim=10for the shippedhomie_rl.pt.
- Example:
- Use
uv runfrom repo root for all CLI workflows. - If
uv runfails due to cache permissions, setUV_CACHE_DIR=.uv-cache(repo-local) or pass--cache-dir .uv-cache. - List registered tasks:
uv run python -m mjlab.scripts.list_envs- Filter:
uv run python -m mjlab.scripts.list_envs --keyword homie
- Filter:
- Train (RSL-RL):
uv run python -m mjlab.scripts.train <TaskID> [flags...]- Multi-GPU is handled internally via
torchrunxwhenCUDA_VISIBLE_DEVICESexposes >1 GPU.
- Multi-GPU is handled internally via
- Play:
uv run python -m mjlab.scripts.play <TaskID> [flags...]- Trained policy: use
--wandb-run-path ...or--checkpoint-file ... - Debug policies:
--agent zeroor--agent random
- Trained policy: use
- Tracking demo (downloads a checkpoint + motion):
uv run python -m mjlab.scripts.demo
- Some tracking tasks require a motion file.
- Train: either set
--registry-name ...(download artifact) or override--env.commands.motion.motion-file .... - Play: use
--motion-file ...for local, or--wandb-run-path ...so the motion artifact can be resolved.
- Train: either set
train.pysetsMUJOCO_GL=egland (multi-GPU) setsMUJOCO_EGL_DEVICE_IDfromLOCAL_RANK.play.pyusesviewer="auto":- picks
nativewhen a display is available (DISPLAY/WAYLAND_DISPLAY) - otherwise defaults to
viser(headless-friendly)
- picks
- For offscreen video,
--videousesrender_mode="rgb_array"internally.
- Keep formatting consistent with this tree: 2-space indentation, explicit type hints, dataclasses for configs.
- Prefer small, local changes; don’t refactor unrelated modules.
- When adding a new task:
- Add
mjlab/tasks/<task>/config/<robot>/__init__.pythat callsregister_mjlab_task. - Provide
env_cfg(...),play_env_cfg(...), andrl_cfg(...)factories. - Verify it shows up in
mjlab.scripts.list_envs.
- Add