Import upstream snapshot c19f713c415a699a79d71cd96aa13c3104a05047
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
Docker / build (push) Has been cancelled
docs / build (push) Has been cancelled
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
Docker / build (push) Has been cancelled
docs / build (push) Has been cancelled
Upstream: https://github.com/michaelgillett/mjlab Upstream-Commit: c19f713c415a699a79d71cd96aa13c3104a05047 Upstream-Branch: main
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
.. _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.
|
||||
Reference in New Issue
Block a user