mjlab/docs/source/migration_isaac_lab.rst
Upstream Snapshot 32a241c28f
Some checks failed
nightly / Test against latest dependencies (py3.10) (push) Has been cancelled
nightly / Test against latest dependencies (py3.13) (push) Has been cancelled
tests / tests (3.13, locked) (push) Has been cancelled
tests / tests (3.13, unlocked) (push) Has been cancelled
tests / pyright (3.10) (push) Has been cancelled
tests / lint-format (push) Has been cancelled
tests / tests (3.10, locked) (push) Has been cancelled
tests / tests (3.11, locked) (push) Has been cancelled
tests / tests (3.12, locked) (push) Has been cancelled
tests / pyright (3.11) (push) Has been cancelled
tests / pyright (3.12) (push) Has been cancelled
tests / pyright (3.13) (push) Has been cancelled
tests / ty-check (3.10) (push) Has been cancelled
tests / ty-check (3.11) (push) Has been cancelled
tests / ty-check (3.12) (push) Has been cancelled
tests / ty-check (3.13) (push) Has been cancelled
tests / stubs (push) Has been cancelled
tests / smoke-test (push) Has been cancelled
Docker / check_paths (push) Has been cancelled
docs / build (push) Has been cancelled
Docker / build (push) Has been cancelled
Import upstream snapshot c19f713c415a699a79d71cd96aa13c3104a05047
Upstream: https://github.com/michaelgillett/mjlab
Upstream-Commit: c19f713c415a699a79d71cd96aa13c3104a05047
Upstream-Branch: main
2026-08-28 15:42:17 +08:00

286 lines
8.4 KiB
ReStructuredText

.. _migration_isaac_lab:
Migrating from Isaac Lab
========================
.. warning::
This guide is a work in progress. As more users migrate, we will update this
page with additional patterns and edge cases. If something is not covered,
please open an issue on GitHub or start a discussion:
- Issues: https://github.com/mujocolab/mjlab/issues
- Discussions: https://github.com/mujocolab/mjlab/discussions
TL;DR
-----
Most Isaac Lab *manager-based* task configs can be ported to ``mjlab`` with
only small changes:
- The overall **MDP structure is the same** (managers for rewards, observations,
actions, commands, terminations, events, curriculum).
- The **environment base classes are similar**, but naming is slightly
different.
- The biggest change is **configuration style**: Isaac Lab uses nested
``@configclass`` definitions; ``mjlab`` uses dictionaries of config objects.
If you are familiar with Isaac Lab's manager-based API, migration is mostly
mechanical.
Key Differences
---------------
1. Import Paths
~~~~~~~~~~~~~~~
Isaac Lab:
.. code-block:: python
from isaaclab.envs import ManagerBasedRLEnv
mjlab:
.. code-block:: python
from mjlab.envs import ManagerBasedRlEnvCfg
.. note::
``mjlab`` uses a consistent ``CamelCase`` naming convention (for example,
``RlEnv`` instead of ``RLEnv``).
2. Configuration Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~
Isaac Lab uses nested ``@configclass`` blocks for manager terms. ``mjlab``
instead uses **plain dictionaries** mapping names to config objects, which makes
it easy to construct variants, merge configs, or generate them programmatically.
For the full context behind this design decision, see
`PR #292 <https://github.com/mujocolab/mjlab/pull/292>`_.
**Isaac Lab:**
.. code-block:: python
@configclass
class RewardsCfg:
"""Reward terms for the MDP."""
motion_global_anchor_pos = RewTerm(
func=mdp.motion_global_anchor_position_error_exp,
weight=0.5,
params={"command_name": "motion", "std": 0.3},
)
motion_global_anchor_ori = RewTerm(
func=mdp.motion_global_anchor_orientation_error_exp,
weight=0.5,
params={"command_name": "motion", "std": 0.4},
)
**mjlab:**
.. code-block:: python
rewards = {
"motion_global_anchor_pos": RewardTermCfg(
func=mdp.motion_global_anchor_position_error_exp,
weight=0.5,
params={"command_name": "motion", "std": 0.3},
),
"motion_global_anchor_ori": RewardTermCfg(
func=mdp.motion_global_anchor_orientation_error_exp,
weight=0.5,
params={"command_name": "motion", "std": 0.4},
),
}
cfg = ManagerBasedRlEnvCfg(
scene=scene,
rewards=rewards,
# ... other manager dictionaries:
# observations=..., actions=..., commands=..., terminations=...,
# events=..., curriculum=...
)
This pattern applies to all managers:
- ``rewards``
- ``observations``
- ``actions``
- ``commands``
- ``terminations``
- ``events``
- ``curriculum``
3. Scene Configuration
~~~~~~~~~~~~~~~~~~~~~~
Scene setup is **simpler** in ``mjlab``:
- No Omniverse / USD scene graph, no ``prim_path`` management.
- Assets are pure MuJoCo (MJCF) with modifier dataclasses applied to
``mujoco.MjSpec``.
- Lights, materials, textures, and sensors are configured as part of
``SceneCfg`` and robot configs.
**Isaac Lab:**
.. code-block:: python
from whole_body_tracking.robots.g1 import G1_ACTION_SCALE, G1_CYLINDER_CFG
from isaaclab.scene import InteractiveSceneCfg
from isaaclab.sensors import ContactSensorCfg
from isaaclab.terrains import TerrainImporterCfg
import isaaclab.sim as sim_utils
from isaaclab.assets import ArticulationCfg, AssetBaseCfg
@configclass
class MySceneCfg(InteractiveSceneCfg):
"""Configuration for the terrain scene with a legged robot."""
# ground terrain
terrain = TerrainEntityCfg(
prim_path="/World/ground",
terrain_type="plane",
collision_group=-1,
physics_material=sim_utils.RigidBodyMaterialCfg(
friction_combine_mode="multiply",
restitution_combine_mode="multiply",
static_friction=1.0,
dynamic_friction=1.0,
),
visual_material=sim_utils.MdlFileCfg(
mdl_path="{NVIDIA_NUCLEUS_DIR}/Materials/Base/Architecture/Shingles_01.mdl",
project_uvw=True,
),
)
# lights
light = AssetBaseCfg(
prim_path="/World/light",
spawn=sim_utils.DistantLightCfg(
color=(0.75, 0.75, 0.75), intensity=3000.0
),
)
sky_light = AssetBaseCfg(
prim_path="/World/skyLight",
spawn=sim_utils.DomeLightCfg(
color=(0.13, 0.13, 0.13), intensity=1000.0
),
)
robot = G1_CYLINDER_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
**mjlab:**
.. code-block:: python
from dataclasses import replace
from mjlab.scene import SceneCfg
from mjlab.asset_zoo.robots.unitree_g1.g1_constants import get_g1_robot_cfg
from mjlab.utils.spec_config import ContactSensorCfg
from mjlab.terrains import TerrainEntityCfg
# Configure contact sensor
self_collision_sensor = ContactSensorCfg(
name="self_collision",
subtree1="pelvis",
subtree2="pelvis",
data=("found",),
reduce="netforce",
num=10, # report up to 10 contacts
)
# Add sensor to robot config
g1_cfg = replace(get_g1_robot_cfg(), sensors=(self_collision_sensor,))
# Create scene
SCENE_CFG = SceneCfg(
terrain=TerrainEntityCfg(terrain_type="plane"),
entities={"robot": g1_cfg},
)
Key changes:
- No USD ``prim_path`` or cloning; the scene is described directly in MuJoCo.
- Materials, lights, and visual properties are applied via
``MjSpec``-modifier dataclasses.
- See ``mjlab.utils.spec_config`` in the repository for helpers that apply
these changes for you.
- ``asset_name`` has been unified to ``entity_name`` across all configurations.
Complete Example Comparison
---------------------------
A good way to learn the pattern is to compare concrete tasks that have already
been ported:
- Isaac Lab implementation (Beyond Mimic):
- https://github.com/HybridRobotics/whole_body_tracking/blob/main/source/whole_body_tracking/whole_body_tracking/tasks/tracking/tracking_env_cfg.py
- mjlab implementation:
- https://github.com/mujocolab/mjlab/blob/main/src/mjlab/tasks/tracking/tracking_env_cfg.py
You will see that:
- Manager dictionaries in ``mjlab`` mirror Isaac Lab's config classes,
- Reward, observation, command, and termination logic is almost identical,
- Scene and asset setup are simplified to pure MuJoCo.
Migration Checklist
-------------------
Use this as a quick checklist when porting a task:
1. **Base class and imports**
- Replace Isaac Lab imports (for example,
``from isaaclab.envs import ManagerBasedRLEnv``) with the corresponding
``mjlab`` imports (for example,
``from mjlab.envs import ManagerBasedRlEnvCfg``).
2. **Manager configuration**
- Convert each Isaac Lab ``@configclass`` manager (``RewardsCfg``,
``ObservationsCfg``, etc.) into a dictionary of config objects.
- Pass these dictionaries into ``ManagerBasedRlEnvCfg``.
3. **Scene and assets**
- Replace ``InteractiveSceneCfg`` with a ``SceneCfg`` instance.
- Replace USD / ``prim_path`` logic with MuJoCo asset configs and scene
entities (for example, a robot from ``asset_zoo``).
4. **Sensors and contact handling**
- Convert Isaac Lab ``ContactSensorCfg`` to
``mjlab.utils.spec_config.ContactSensorCfg`` and attach it to the robot
config.
5. **RL entry points**
- Make sure your training script or entry point uses the correct task id and
environment config (for example, via Gymnasium registration or direct
construction, depending on how your project is structured).
Tips and Support
----------------
1. Check the examples in the repository under:
- ``src/mjlab/tasks/``
2. If you get stuck:
- Open an issue: https://github.com/mujocolab/mjlab/issues
- Start a discussion: https://github.com/mujocolab/mjlab/discussions
3. Keep in mind MuJoCo vs Isaac Sim differences:
- Some Omniverse / USD rendering features do not have direct equivalents.
- Focus first on matching the **physics and observations**, then polish
visuals if needed.