Gazebo or MuJoCo
Both targets emit the same robot description, controllers, Nav2 settings, map, task and runtime. They differ in the simulator underneath.
mobiledsl compile ... --target ros-gz-nav2 --output build
mobiledsl compile ... --target ros-mujoco-nav2 --output build_mujocoWhat each runs
ros-gz-nav2 | ros-mujoco-nav2 | |
|---|---|---|
| Simulator | Gazebo Harmonic | MuJoCo 3.11 or later, run by the output's own node |
| The world | world/world.sdf and world/bridge.yaml | world/mujoco.json |
| Robot to controllers | gz_ros2_control | topic_based_ros2_control |
| A track's belt | A TrackController on its link, told its speed and the base's centre of rotation by Gazebo's TrackedVehicle | The surface velocity of its box, set by the node |
| Sensors | Gazebo's sensor plugins | Computed from the physics state: rays for lasers and range finders, offscreen rendering for cameras |
| The light | A sun, an ambient light and a sky in world/world.sdf | The same light, set up by the node from world/mujoco.json |
| A window | headless:=false | None |
| Test image | robotdsl/ros-gz-nav2:jazzy-harmonic | robotdsl/ros-mujoco-nav2:jazzy |
Both publish the same topics, including the robot's ground-truth pose on /model/<robot>/pose, so the same task runner judges both.
What each refuses
A target refuses what it cannot simulate, at compile time, instead of writing something that runs wrong.
| Construct | ros-gz-nav2 | ros-mujoco-nav2 |
|---|---|---|
| A mecanum or omni base | Simulated | Refused: MuJoCo's contact friction is the same in every direction, so a wheel cannot slide freely along its rollers |
| A part, other than a wheel or a track, that declares neither a collision box nor a hull | Collides through its visual mesh | Refused: MuJoCo cannot read the Collada mesh |
| A library object that only shows, by a mesh that is not glTF | Shown | Refused: the node reads glTF and nothing else of a world's objects, so nothing of this one would be in the scene |
A movable entity (is_static = false) | Refused | Refused |
Where they differ in behaviour
- Skid-steer turns. In MuJoCo a skid-steer base turns slower than commanded, while the odometry reports the full turn. The demo skid-steer base turned in place at about a third of the commanded rate in the image. How much slower depends on the base: in the model both MuJoCo targets build, the component library's skid-steer examples, told to turn at 0.5 rad/s while driving at 0.2 m/s, turned at a seventh to seven tenths of it, the two heaviest, of 39 and 55 kg, least (see the
mjcftarget). - Tracked turns. Both move a belt's contacts about the centre the base is commanded to turn about, and the test base, with runs of 0.10 m that lie 0.16 m apart, turned the 3 rad it was commanded in both (3.05 rad in Gazebo, 3.00 in MuJoCo). Gazebo moves every contact of a belt at the belt's one speed, so a contact further from the centre than its belt's middle drags: with runs of 0.15 m the same base turned 2.48 rad there and 3.00 in MuJoCo.
- Library objects. Both collide an object by the shapes its entry declares and show its mesh to their cameras. Gazebo decodes the mesh, and its lasers and range finders see it. MuJoCo decodes no glTF: the output's node reads the mesh and shows it in its materials' base colours with the pictures laid on them, which must be PNG, and without a material's other maps or the light it states it gives off (
emissiveFactor), which Gazebo adds to every pixel of the object; its lasers and range finders see the shapes the object collides by. Of an object whose mesh is not glTF, MuJoCo shows those shapes in the mesh's place. - Marks. A
Markerthat does not collide is in both simulators' camera pictures. Gazebo's lasers and range finders see it as well, since they see what is shown; MuJoCo's return only from what collides. A post that only shows, a metre ahead of a robot with a laser, marked the local costmap in Gazebo and not in MuJoCo. - Contacts. Gazebo gives each kind of wheel its own friction model, anisotropic where the wheel slides one way. MuJoCo gives a rolling wheel a grip of 1 and a caster or skid 0.01, in every direction.
- The drive. MuJoCo drives each wheel through a velocity actuator whose gain the target chooses, since a part states its motor's ratings and not the driver's loop gain; the actuator's force is clamped to the motor's stall torque and its command to the motor's no-load speed.
Each of these is declared in compile.json.
Which to use
Use ros-gz-nav2 for any base on wheels or tracks, and for parts that declare no collision box; a legged base, or any part with links, only mjcf writes. Use ros-mujoco-nav2 for a base on standard wheels or on tracks when you want a second simulator's opinion of the same program: a run that passes in one and fails in the other points at something the program leaves to a simulator's defaults.
The robot alone in MuJoCo
A third target writes the robot by itself, for MuJoCo without ROS: the robot on its floor as one MJCF, scene.xml, and drive.json, which says how a base motion becomes each wheel's and kingpin's command, or each belt's surface motion.
mobiledsl compile ... --target mjcf --output build_mjcf
python -m mujoco.viewer --mjcf build_mjcf/scene.xmlThe robot is the one ros-mujoco-nav2 gives MuJoCo, with the same contacts and actuators (see the output reference); the world is its floor and its gravity, without its entities, and a sensor keeps its body, mass and collision but senses nothing. It is the robot to drive by hand, made for the Studio, which is to drop it onto a floor in the browser and drive it from the keys. A base on tracks drives by its belts' surfaces, as ros-mujoco-nav2's node moves them. A mecanum base drives on its wheels' rollers, which ros-mujoco-nav2 does not have: each wheel is written as barrel-shaped rollers on free hinges round its hub, at 45 degrees to the axle, and drives ahead, aside and round as ros-gz-nav2's mecanum controller would turn its wheels. A legged base, which neither ROS target writes yet, walks by the walking controller its part states, its feet alone meeting the floor: by a policy, which goes beside the model, the model stepping as the policy was trained; or by a gait, which needs no training and is worked out from the model itself as the robot walks. It refuses the other bases and parts ros-mujoco-nav2 refuses, and a world without a floor.
The output contract specifies the targets' files in full.