Skip to content
Open
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
2 changes: 1 addition & 1 deletion source/isaaclab/config/extension.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

# Note: Semantic Versioning is used: https://semver.org/
version = "4.6.10"
version = "4.6.11"

# Description
title = "Isaac Lab framework for Robot Learning"
Expand Down
46 changes: 46 additions & 0 deletions source/isaaclab/docs/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,52 @@
Changelog
---------

4.6.11 (2026-04-24)
~~~~~~~~~~~~~~~~~~~

Changed
^^^^^^^

* Refactored :class:`~isaaclab.sim.converters.UrdfConverter` to delegate the full conversion
pipeline to :class:`isaacsim.asset.importer.urdf.URDFImporter` /
:class:`isaacsim.asset.importer.urdf.URDFImporterConfig`. The duplicated IsaacLab
implementations of ``_apply_fix_base``, ``_apply_link_density``, ``_apply_joint_drives``,
``_set_drive_type_on_joints``, ``_set_target_type_on_joints``, ``_set_drive_gains_on_joints``,
and ``_fix_articulation_root_for_fixed_base`` have been removed and replaced with a thin
translation layer that maps :class:`~isaaclab.sim.converters.UrdfConverterCfg` onto the
Isaac Sim importer config. All behaviour is preserved.
* Replaced :mod:`isaaclab.sim.converters.urdf_utils` with a thin re-export shim that
forwards :func:`~isaaclab.sim.converters.urdf_utils.merge_fixed_joints` to the canonical
implementation in :mod:`isaacsim.asset.importer.urdf.impl.urdf_utils`. The public import
path is preserved.
* Updated :class:`~isaaclab.sim.converters.MjcfConverter` to forward the full set of
:class:`isaacsim.asset.importer.mjcf.MJCFImporterConfig` options to the Isaac Sim importer.

Added
^^^^^

* Added :attr:`~isaaclab.sim.converters.UrdfConverterCfg.ros_package_paths`,
:attr:`~isaaclab.sim.converters.UrdfConverterCfg.robot_type`,
:attr:`~isaaclab.sim.converters.UrdfConverterCfg.run_asset_transformer`,
:attr:`~isaaclab.sim.converters.UrdfConverterCfg.run_multi_physics_conversion`, and
:attr:`~isaaclab.sim.converters.UrdfConverterCfg.debug_mode` config fields that mirror the
new :class:`isaacsim.asset.importer.urdf.URDFImporterConfig` options.
* Extended :attr:`~isaaclab.sim.converters.UrdfConverterCfg.collision_type` to accept
``"Bounding Sphere"`` and ``"Bounding Cube"`` in addition to the existing ``"Convex Hull"``
and ``"Convex Decomposition"`` values.
* Added :attr:`~isaaclab.sim.converters.MjcfConverterCfg.fix_base`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.link_density`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.robot_type`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.override_gain_type`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.override_bias_type`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.override_gain_prm`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.override_bias_prm`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.run_asset_transformer`,
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.run_multi_physics_conversion`, and
:attr:`~isaaclab.sim.converters.MjcfConverterCfg.debug_mode` config fields that mirror the
new :class:`isaacsim.asset.importer.mjcf.MJCFImporterConfig` options.


4.6.10 (2026-04-22)
~~~~~~~~~~~~~~~~~~~

Expand Down
39 changes: 25 additions & 14 deletions source/isaaclab/isaaclab/sim/converters/mjcf_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from __future__ import annotations

import os
import shutil

from .asset_converter_base import AssetConverterBase
from .mjcf_converter_cfg import MjcfConverterCfg
Expand All @@ -14,9 +15,12 @@
class MjcfConverter(AssetConverterBase):
"""Converter for a MJCF description file to a USD file.

This class wraps around the `isaacsim.asset.importer.mjcf`_ extension to provide a lazy implementation
for MJCF to USD conversion. It uses the :class:`MJCFImporter` class and :class:`MJCFImporterConfig`
dataclass from Isaac Sim to perform the conversion.
This class wraps around the `isaacsim.asset.importer.mjcf`_ extension to provide a lazy
implementation for MJCF to USD conversion. All conversion logic (USD schema application,
fix-base, density, actuator gains, self-collision, mesh merging, asset transformer
profile) is performed by :class:`~isaacsim.asset.importer.mjcf.MJCFImporter` — this class
only translates :class:`MjcfConverterCfg` into a flat
:class:`~isaacsim.asset.importer.mjcf.MJCFImporterConfig`.

.. caution::
The current lazy conversion implementation does not automatically trigger USD generation if
Expand Down Expand Up @@ -44,8 +48,8 @@ def __init__(self, cfg: MjcfConverterCfg):
Args:
cfg: The configuration instance for MJCF to USD conversion.
"""
# The new MJCF importer outputs to: {usd_path}/{robot_name}/{robot_name}.usda
# Pre-adjust usd_file_name to match this output structure so that lazy conversion works correctly.
# The MJCF importer outputs to: {usd_path}/{robot_name}/{robot_name}.usda
# Pre-adjust `usd_file_name` to match this output structure so that lazy conversion works correctly.
file_basename = os.path.splitext(os.path.basename(cfg.asset_path))[0]
cfg.usd_file_name = os.path.join(file_basename, f"{file_basename}.usda")
super().__init__(cfg=cfg)
Expand All @@ -55,18 +59,16 @@ def __init__(self, cfg: MjcfConverterCfg):
"""

def _convert_asset(self, cfg: MjcfConverterCfg):
"""Calls underlying Isaac Sim MJCFImporter to convert MJCF to USD.
"""Run the Isaac Sim MJCF importer pipeline.

Args:
cfg: The configuration instance for MJCF to USD conversion.
"""
import shutil

from isaacsim.asset.importer.mjcf import MJCFImporter, MJCFImporterConfig

# Clean up existing output subdirectory so the importer writes fresh files.
# The MJCFImporter outputs to {usd_dir}/{robot_name}/{robot_name}.usda and may
# skip writing if the output already exists from a previous conversion.
# Clean up any existing output subdirectory so the importer writes fresh files.
# MJCFImporter outputs to `{usd_dir}/{robot_name}/{robot_name}.usda` and may skip
# writing if the output already exists from a previous conversion.
file_basename = os.path.splitext(os.path.basename(cfg.asset_path))[0]
output_subdir = os.path.join(self.usd_dir, file_basename)
if os.path.exists(output_subdir):
Expand All @@ -75,12 +77,21 @@ def _convert_asset(self, cfg: MjcfConverterCfg):
import_config = MJCFImporterConfig(
mjcf_path=cfg.asset_path,
usd_path=self.usd_dir,
import_scene=cfg.import_physics_scene,
merge_mesh=cfg.merge_mesh,
collision_from_visuals=cfg.collision_from_visuals,
collision_type=cfg.collision_type,
allow_self_collision=cfg.self_collision,
import_scene=cfg.import_physics_scene,
robot_type=cfg.robot_type,
fix_base=cfg.fix_base,
link_density=cfg.link_density if cfg.link_density > 0.0 else None,
override_gain_type=cfg.override_gain_type,
override_bias_type=cfg.override_bias_type,
override_gain_prm=cfg.override_gain_prm,
override_bias_prm=cfg.override_bias_prm,
run_asset_transformer=cfg.run_asset_transformer,
run_multi_physics_conversion=cfg.run_multi_physics_conversion,
debug_mode=cfg.debug_mode,
)

importer = MJCFImporter(import_config)
importer.import_mjcf()
MJCFImporter(import_config).import_mjcf()
105 changes: 96 additions & 9 deletions source/isaaclab/isaaclab/sim/converters/mjcf_converter_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#
# SPDX-License-Identifier: BSD-3-Clause

from __future__ import annotations

from typing import Literal

from isaaclab.sim.converters.asset_converter_base_cfg import AssetConverterBaseCfg
from isaaclab.utils import configclass

Expand All @@ -11,31 +15,114 @@
class MjcfConverterCfg(AssetConverterBaseCfg):
"""The configuration class for MjcfConverter.

.. note::
From Isaac Sim 5.0 onwards, the MJCF importer was rewritten to use the ``mujoco-usd-converter``
library. Several settings from the old importer (``fix_base``, ``link_density``,
``import_inertia_tensor``, ``import_sites``) are no longer available as they are handled
automatically by the converter based on the MJCF file content.
Maps to :class:`~isaacsim.asset.importer.mjcf.MJCFImporterConfig` from the Isaac Sim
MJCF importer. All post-import USD edits (fix-base, density override, actuator gain
overrides, self-collision, mesh merging, asset transformer profile) are performed by
the Isaac Sim importer — this config just forwards the user's choices.

.. note::
The :attr:`~AssetConverterBaseCfg.make_instanceable` setting from the base class is not
supported by the new MJCF importer and will be ignored.
From Isaac Sim 5.0 onwards, the MJCF importer was rewritten to use the
``mujoco-usd-converter`` library. The :attr:`AssetConverterBaseCfg.make_instanceable`
setting from the base class is not supported by the new MJCF importer and is ignored.
"""

# ---------------------------------------------------------------
# Geometry / mesh options
# ---------------------------------------------------------------

merge_mesh: bool = False
"""Merge meshes where possible to optimize the model. Defaults to False."""

collision_from_visuals: bool = False
"""Generate collision geometry from visual geometries. Defaults to False."""

collision_type: str = "Convex Hull"
collision_type: Literal["Convex Hull", "Convex Decomposition", "Bounding Sphere", "Bounding Cube"] = "Convex Hull"
"""Type of collision geometry to use. Defaults to ``"Convex Hull"``.

Supported values are ``"Convex Hull"``, and ``"Convex Decomposition"``.
Supported values match the ``collision_type`` field of
:class:`~isaacsim.asset.importer.mjcf.MJCFImporterConfig`.
"""

self_collision: bool = False
"""Activate self-collisions between links of the articulation. Defaults to False."""

# ---------------------------------------------------------------
# Physics / articulation options
# ---------------------------------------------------------------

import_physics_scene: bool = False
"""Import the physics scene (time step per second, gravity, etc.) from the MJCF file. Defaults to False."""

fix_base: bool = False
"""Add a fixed joint from the world to the root rigid-body link. Defaults to False.

When enabled, :class:`~isaacsim.asset.importer.mjcf.MJCFImporter` inserts a ``FixedJoint``
between the world and the articulation root and relocates ``ArticulationRootAPI`` onto the
appropriate ancestor prim so PhysX treats the articulation as fixed-base.
"""

link_density: float = 0.0
"""Default density in ``kg/m^3`` for links whose ``"inertial"`` properties are missing.
Defaults to 0.0.

A value of ``0.0`` leaves density unchanged.
"""

robot_type: str = "Default"
"""Robot type applied by the USD robot schema. Defaults to ``"Default"``.

Forwarded to :class:`~isaacsim.asset.importer.mjcf.MJCFImporterConfig`.
"""

# ---------------------------------------------------------------
# Actuator gain overrides
# ---------------------------------------------------------------

override_gain_type: str | None = None
"""MuJoCo actuator gain type override (e.g. ``"fixed"``). Defaults to ``None``.

``None`` leaves the value parsed from the MJCF file unchanged. See
:func:`isaacsim.asset.importer.utils.impl.asset_utils.apply_mjc_actuator_gains` for
the supported encodings.
"""

override_bias_type: str | None = None
"""MuJoCo actuator bias type override (e.g. ``"affine"``). Defaults to ``None``.

``None`` leaves the value parsed from the MJCF file unchanged.
"""

override_gain_prm: list[float] | None = None
"""MuJoCo actuator gain parameter array (10 floats) override. Defaults to ``None``.

``None`` leaves the value parsed from the MJCF file unchanged. Example for position
control: ``[kp, 0, 0, 0, 0, 0, 0, 0, 0, 0]``.
"""

override_bias_prm: list[float] | None = None
"""MuJoCo actuator bias parameter array (10 floats) override. Defaults to ``None``.

``None`` leaves the value parsed from the MJCF file unchanged. Example for position
control: ``[0, -kp, -kd, 0, 0, 0, 0, 0, 0, 0]``.
"""

# ---------------------------------------------------------------
# Importer pipeline options
# ---------------------------------------------------------------

run_asset_transformer: bool = True
"""Whether to run the asset transformer profile after conversion. Defaults to True.

When enabled, the importer restructures the intermediate USD into a layered,
payload-based package. Disable for a single flat USD output.
"""

run_multi_physics_conversion: bool = True
"""Whether to run the MJCF-to-PhysX physics conversion pass. Defaults to True."""
Comment on lines +113 to +121
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 run_asset_transformer and run_multi_physics_conversion default to True — worth documenting the behavioral implications

Defaulting them to True preserves existing behaviour, which is correct. However, if a user accidentally sets run_multi_physics_conversion=False, the resulting USD will lack PhysX joint attributes and the articulation will be unusable in simulation. Consider adding a .. warning:: block to both docstrings noting that disabling these flags produces a non-simulated asset intended only for inspection/debugging.


debug_mode: bool = False
"""Enable debug mode in the underlying MJCF importer. Defaults to False.

When enabled, the importer writes intermediate conversion artifacts next to the output
USD for inspection instead of using a temporary scratch directory.
"""
Loading