Documentation
Exporting URDF, MJCF and SDF
Robot export writes a robot description from an assembly. Components become links, joints become joints, and each link’s mass, centre of mass and inertia come from its exact solids and materials. Click URDF in the header, or right-click a component and choose Export Robot (URDF / MJCF / SDF)…: the model is checked first, you can drag the joints to see that it moves as it should, and the result is one zip with the formats you tick: URDF, MJCF, SDF and a ROS 2 package with a launch file and an RViz configuration.
How should I build the model?
- Make one component per rigid link. Everything inside a component moves together, so a link can be several bodies.
- A .sldasm assembly comes in with a component per part. A STEP file comes in as one component, so split it first: select the bodies of the links that move and choose New component with From the selected bodies ticked, which gives each selected body a component of its own.
- Connect the components with joints (J), the way the real robot moves. See Assemblies and joints.
- Pin the base (right-click it, Pin): the pinned component is the root link, and MJCF and SDF fix it to the world where it stands. Other pinned components that no joint connects to the root are fixed to it where they stand.
- Give revolute and slider joints their limits, a minimum and a maximum. A revolute joint without limits turns all the way round; a slider needs limits for URDF and the ROS 2 package.
- Give every component a Physical material, or the default density of 1000 kg/m³ is used and the inertia will be wrong.
- Put the joint origins and axes where the real axes are; the export writes each joint’s frame from them.
What does each part of the model become?
| In ProtoJoint | URDF | MJCF | SDF |
|---|---|---|---|
| Component | link | body | link |
| Rigid joint | fixed | child body with no joint | fixed |
| Revolute joint with limits | revolute | hinge with a range | revolute |
| Revolute joint without limits | continuous | hinge | continuous |
| Slider joint | prismatic | slide | prismatic |
| Ball joint | fixed, with a warning | ball | ball |
| Cylindrical or pin-slot joint | fixed, with a warning | slide and hinge | fixed, with a warning |
| Planar joint | fixed, with a warning | two slide joints and a hinge | fixed, with a warning |
| Motion link | mimic | equality joint | none: SDF 1.9 has no mimic (a warning) |
A joint a format cannot express is not refused: it is fixed where it stands, and the warning says what to use instead, such as a slider and a revolute joint through an intermediate component, three revolute joints for a ball, or MJCF, which keeps them all.
A component nested in another and moved by no joint of its own is part of its parent’s link. A joint between two components of the same link moves nothing and is left out, with a warning. Hidden bodies are left out of the geometry and the mass, with a warning too.
Where does the inertia come from?
From the solids themselves. Each link’s volume, centre of mass and inertia are computed from its exact shape, not from the triangles on screen or a box around it, and weighted by its component’s material density. The values are written in the link’s own frame.
What does the check before export look for?
- A tree. One root link, one parent for every other link, no loops. A closed linkage such as a four-bar can be modeled and moved in ProtoJoint, but URDF, MJCF and SDF all describe a tree, so a loop is refused in every format: suppress one of its joints to export, and close the loop in the simulator, with an equality constraint in MuJoCo for instance.
- Mass and inertia. Every link with a solid needs a positive mass and an inertia that is positive about every axis. A component without a material is weighed at 1000 kg/m³, with a warning. A component with no solid and no joint is left out; one with no solid but a joint becomes a massless frame, which MJCF and SDF refuse when a moving joint drives it.
- An inertia a real object could have. No moment of inertia may be larger than the other two added together. Every real body passes; an inertia that fails makes simulators misbehave.
- Limits. A joint’s minimum and maximum are both set or both empty, and the minimum is not above the maximum. A slider without limits cannot be written as URDF or a ROS 2 package. With MJCF ticked, a minimum equal to the maximum is refused as well, since MuJoCo does not accept a range of no width.
Errors stop the export until they are fixed; warnings say what the files will do differently. Click either to select the component or joint it is about.
How do I check the motion before exporting?
Select a joint and drag its handle, or type a value, and watch the links follow. Limits stop the joint where the real one stops, motion links move geared joints together, and Animate runs a joint through its range. Interference check shows links that run into each other.
Which format should I choose?
- URDF for ROS 2, RViz and MoveIt.
- MJCF for MuJoCo, which LeRobot’s simulations use. It comes with a
scene.xmlthat adds a floor and lights, and a position actuator for each driven hinge and slide. - SDF for Gazebo, with
model.configand aworld.sdfto open withgz sim. - A ROS 2 package when you want to see the robot in RViz without writing the launch and configuration files yourself.
Tick as many as you need: they go into one zip named after the package, with each link’s meshes and a README that says how to open each format.
How do I use the ROS 2 package?
The package holds the robot description, its meshes, a launch file and an RViz configuration. Unpack it into the src folder of a ROS 2 workspace, build the workspace with colcon build, source it, and start the launch file with ros2 launch to see the robot in RViz. When you change the model, export again and rebuild.