Files
walkersim/sim/isaac/convert_mjcf_to_usd.py
5shekel fb8ae4c5ef feat(isaac): add URDF conversion and standalone visual debug demo
Add an MJCF->URDF conversion workflow and a uv-served urdf-loader demo so the walker can be inspected outside MuJoCo. Include playback kinematics, anchor diagnostics, and docs to speed up linkage debugging in Isaac-oriented workflows.
2026-02-21 11:22:47 +02:00

79 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Convert MuJoCo MJCF assets to Isaac Sim USD assets.
Run this with Isaac Sim's Python launcher, for example:
./python.sh sim/isaac/convert_mjcf_to_usd.py \
--input sim/mujoco/model/walker.xml \
--output sim/isaac/model/walker.usd
"""
from __future__ import annotations
import argparse
import pathlib
def parse_args() -> argparse.Namespace:
repo_root = pathlib.Path(__file__).resolve().parents[2]
default_input = repo_root / "sim" / "mujoco" / "model" / "walker.xml"
default_output = repo_root / "sim" / "isaac" / "model" / "walker.usd"
parser = argparse.ArgumentParser(description="Convert MJCF to USD using Isaac Sim")
parser.add_argument("--input", type=pathlib.Path, default=default_input, help="Path to MJCF file")
parser.add_argument("--output", type=pathlib.Path, default=default_output, help="Path to USD output")
parser.add_argument("--prim-path", default="/World/walker", help="Root prim path for imported robot")
parser.add_argument("--fix-base", action="store_true", help="Import articulation with fixed base")
parser.add_argument("--headless", action="store_true", help="Run Isaac Sim headless")
return parser.parse_args()
def main() -> None:
args = parse_args()
input_path = args.input.resolve()
output_path = args.output.resolve()
output_path.parent.mkdir(parents=True, exist_ok=True)
if not input_path.exists():
raise FileNotFoundError(f"MJCF file not found: {input_path}")
from isaacsim import SimulationApp
app = SimulationApp({"headless": args.headless})
try:
import omni.kit.commands
import omni.usd
from omni.isaac.core.utils.extensions import enable_extension
enable_extension("omni.importer.mjcf")
ok, import_config = omni.kit.commands.execute("MJCFCreateImportConfig")
if not ok:
raise RuntimeError("Failed to create MJCF import config")
import_config.fix_base = args.fix_base
import_config.make_default_prim = True
import_config.self_collision = True
import_config.create_physics_scene = True
ok, _ = omni.kit.commands.execute(
"MJCFCreateAsset",
mjcf_path=str(input_path),
import_config=import_config,
prim_path=args.prim_path,
)
if not ok:
raise RuntimeError("MJCF import failed")
usd_context = omni.usd.get_context()
if not usd_context.save_as_stage(str(output_path)):
raise RuntimeError(f"Failed to save USD: {output_path}")
print(f"Converted MJCF -> USD: {input_path} -> {output_path}")
finally:
app.close()
if __name__ == "__main__":
main()