Skip to content

Gazebo or MuJoCo ​

Both targets emit the same robot description, controllers, Nav2 settings, map, task and runtime. They differ in the simulator underneath.

sh
mobiledsl compile ... --target ros-gz-nav2 --output build
mobiledsl compile ... --target ros-mujoco-nav2 --output build_mujoco

What each runs ​

ros-gz-nav2ros-mujoco-nav2
SimulatorGazebo HarmonicMuJoCo 3.11 or later, run by the output's own node
The worldworld/world.sdf and world/bridge.yamlworld/mujoco.json
Robot to controllersgz_ros2_controltopic_based_ros2_control
A track's beltA TrackController on its link, told its speed and the base's centre of rotation by Gazebo's TrackedVehicleThe surface velocity of its box, set by the node
SensorsGazebo's sensor pluginsComputed from the physics state: rays for lasers and range finders, offscreen rendering for cameras
The lightA sun, an ambient light and a sky in world/world.sdfThe same light, set up by the node from world/mujoco.json
A windowheadless:=falseNone
Test imagerobotdsl/ros-gz-nav2:jazzy-harmonicrobotdsl/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.

Constructros-gz-nav2ros-mujoco-nav2
A mecanum or omni baseSimulatedRefused: 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 hullCollides through its visual meshRefused: MuJoCo cannot read the Collada mesh
A library object that only shows, by a mesh that is not glTFShownRefused: 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)RefusedRefused

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 mjcf target).
  • 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 Marker that 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.

sh
mobiledsl compile ... --target mjcf --output build_mjcf
python -m mujoco.viewer --mjcf build_mjcf/scene.xml

The 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.