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
Upstream: https://github.com/michaelgillett/mjlab Upstream-Commit: c19f713c415a699a79d71cd96aa13c3104a05047 Upstream-Branch: main
286 lines
8.4 KiB
ReStructuredText
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.
|