RobotForge
Published·~12 min

URDF, MJCF, USD: robot description formats

The three dialects of 'what is this robot' — what each captures, what each loses, and how to convert between them without losing your mind.

by RobotForge
#simulators#urdf#mjcf#usd

A robot description format encodes a robot's geometry, kinematics, dynamics, and (sometimes) actuators and sensors. Three formats dominate in 2026: URDF (ROS), MJCF (MuJoCo), USD (Isaac / Omniverse). Each captures slightly different things; conversion between them is doable but lossy. Understanding the differences saves you from "my robot looks fine in URDF but spins crazily in MuJoCo" debugging sessions.

URDF (Unified Robot Description Format)

The ROS standard. XML-based; covered in detail in the ROS 2 track. Captures:

  • Tree of links connected by joints (revolute, prismatic, fixed, continuous, etc.).
  • Visual geometry per link (mesh files, primitives).
  • Collision geometry (separate from visual; usually simplified).
  • Inertial properties (mass, center of mass, inertia tensor).
  • Joint limits, dynamics (damping, friction).

Strengths: simple, widely supported, ROS-standard. Every ROS-compatible simulator imports URDF.

Weaknesses:

  • Strictly tree (no kinematic loops — a four-bar linkage needs custom plugins).
  • Limited actuator model (no PMSM/BLDC realism, no harmonic drive, no series-elastic).
  • No native sensor descriptions (you add Gazebo plugin tags as workarounds).
  • Verbose for parametric robots (Xacro adds macros but it's a separate preprocessor).

MJCF (MuJoCo XML)

MuJoCo's native format. Captures:

  • Everything URDF captures.
  • Plus: contacts (which links touch which), tendons, equality constraints (closed loops!), actuators with realistic dynamics, sensors built into the description.
  • Detailed contact parameters (friction, solref, solimp).
  • Inline material specifications.

Strengths: more expressive than URDF; closer to a complete simulation specification.

Weaknesses: MuJoCo-specific. Other simulators don't read MJCF natively.

USD (Universal Scene Description)

Pixar's format, adopted by NVIDIA Isaac. Captures:

  • Everything URDF and MJCF capture.
  • Plus: scene composition (one robot, multiple variants), layered editing, materials, lighting, animation, full RTX rendering.
  • Hierarchical references (one base file, multiple overlays).
  • Time-sampled data (animations, sensor recordings).

Strengths: by far the most expressive. Built for complex scenes, not just robots.

Weaknesses:

  • Verbose (USD files for a simple robot are 5–10× the size of URDF).
  • Tooling is heavy (Pixar's USDPython, NVIDIA's USDView).
  • Not natively supported outside Omniverse / Isaac.

The conversion matrix

From → To Tool Quality
URDF → MJCFmujoco from_urdf, dm_control~80%; manual contact/actuator tuning
URDF → USDIsaac Sim's URDF importer~80%; manual material refinement
MJCF → URDFNo standard; manualLossy; loses tendons, constraints
USD → URDFCustom scripts; community toolsLossy; loses materials, layers
USD ↔ MJCFThrough URDF as middlewareDouble-lossy

Practical rule: maintain URDF (or Xacro) as your canonical source. Convert to MJCF / USD per simulator. Tweak the targeted format as needed; never edit two simultaneously.

What gets lost in URDF → MJCF

  • Mesh inertia: URDF's inertia is per-link; MJCF can compute from mesh density. Re-derive in MJCF.
  • Contact parameters: URDF doesn't specify contact stiffness/damping. MJCF has detailed contact params. Defaults often work; tune for stiff contact tasks.
  • Actuator dynamics: URDF says "this is a position-controlled joint with these limits." MJCF can specify a full motor model with stator inductance, gear ratio, etc.
  • Closed kinematic chains: URDF can't represent these; MJCF can. If your robot has a four-bar linkage, you'll need MJCF-specific edits.

What gets lost in URDF → USD

  • Visual material quality: URDF mesh + color → USD with full PBR materials? Mostly automatic; sometimes the auto-generated materials look bad. Replace with hand-tuned in USD.
  • Sensor specifications: URDF + Gazebo plugins don't translate cleanly to Isaac sensors. Re-specify in USD.
  • Articulation root: USD has explicit articulation roots; URDF assumes the first link is root. Sometimes wrong for floating-base robots.

The robot-modeling workflow

For a new robot project in 2026:

  1. Model the robot in CAD (FreeCAD, OnShape, Fusion 360).
  2. Export meshes (STL / OBJ / GLTF).
  3. Hand-write the URDF (or use a CAD-to-URDF plugin) referencing meshes + measured inertias.
  4. For each target simulator:
    • Convert to that format (MJCF / USD).
    • Validate visually + dynamically.
    • Tune sim-specific parameters (contact stiffness, actuator gains, sensor noise).
  5. Maintain only the URDF as canonical; regenerate other formats periodically.

For our /cad page on RobotForge, we export URDF directly — covered in the URDF lesson and the CAD module.

The other formats you might meet

  • SDF (Simulation Description Format): Gazebo's preferred format. Richer than URDF; supports world-level objects (lights, plugins). Often auto-converted from URDF.
  • COLLADA (.dae): an old XML format for 3D models. Still used by some legacy robotics tools. Rare.
  • OBJ / STL: mesh-only formats. Used for visual meshes; not robot description per se.
  • FBX, GLTF: game-industry formats. Used for animations and rendering; rarely for robotics descriptions directly.

Common gotchas

  • Mesh paths: URDF uses package:// URIs. MJCF and USD use plain paths. Conversion has to handle the rewrite.
  • Coordinate frames: URDF assumes z-up, right-handed. Some CAD exports (especially game-engine-targeted) are y-up. Always check.
  • Inertia tensor units: URDF expects kg·m². CAD tools often export in g·mm² or kg·mm². Mistake → robot wobbles.
  • Joint limits as soft vs hard: URDF specifies hard mechanical limits. Some simulators treat them as soft springs; tune.

Exercise

Take a URDF (the Franka Panda is publicly available). Convert to MJCF using mujoco from_urdf. Drive both versions in their respective simulators with the same joint commands. Compare end-effector trajectories. The differences (and the iterations to make them match) teach you what each format captures and what each requires you to manually tune.

Next

The Gymnasium API — the interface every modern RL trainer expects, regardless of which simulator backs it.

Comments

    Sign in to post a comment.