ROS 2 Humble is the eighth release of ROS 2, which is a set of software libraries and tools for building robot applications. ROS, in its various iterations or “distributions,” is regularly released, with multiple “distros” supported at the same time, although they do not all have the same lifetimes. Fun fact, those new distributions are generally released on World Turtle Day, since their symbols are always turtles or tortoises.

As for Gazebo, it is a 3D simulator that can be used to simulate robots and their environments. It is a powerful tool that can be used to test and debug robot software, as well as to train robots. It has been developed with the desire to support ROS instructions, in order to properly test features before using expensive material.

In this tutorial, I’ll explain the basics needed to be able to discuss back and forth between Gazebo and ROS node.

At the time of the creation of this article, the only 2 non-deprecated versions of ROS2 are Humble, which comes with long term support (LTS) and will be supported up to May 2027, and Iron, set to be deprecated in November 2024. To keep this article relevant for as long as possible, this article will only be focusing on ROS2 Humble.


The target audience of this article is curious beginners at ROS that would like a simple introduction to the workings of Gazebo !

The only basis needed in order to understand this tutorial is to have a basic understanding of ROS nodes and topic/subscribers, as well as basic coding vocabulary. I’ll explain as much as I deem necessary, however if anything still seems too abstract, I recommend turning towards the documentation.

No previous experience with Gazebo is needed.

This tutorial was tested on Ubuntu 22.04, since this is one of the OS supported by Humble. Please check the following link to verify which installation method matches your OS. Here are the links towards the download of both Ros2 Humble and Gazebo Fortress used in this tutorial.


Installing ROS Humble on an OS that precedes 22.04 could take several hours, so please plan accordingly if you don’t already have it installed.

Main tutorial

First steps

Gazebo uses the SDFormat to describe what scenes and robots are supposed to look like. Since this tutorial focuses on the use of ROS to discuss with the simulation, we will not be discussing how to create a new project from scratch. Instead, we will use a preexisting one, included with the installation of ign_gazebo:

ign gazebo visualize_lidar.sdf

In another terminal, you can now check which topics have been provided with the command

ign topic -l

You should have something along the lines of :


Now, let’s try and create a bridge between Gazebo and ROS !

Open a discussion

The first we’ll do is to establish a discussion between Gazebo and ROS, by checking if you can catch events happening in the simulation. To do that, we’ll need ros_ign_bridge, which is a bridge that enables messages to go between the two. Here is the pattern :

ros2 run ros_ign_bridge parameter_bridge /TOPIC@ROS_MSG@IGN_MSG

The “ros2 run ros_ign_bridge parameter_bridge” command is used to execute the parameter_bridge code provided by the ros_ign_bridge package.

When using this command, the /TOPIC parameter specifies the target topic for message exchange. The “@” symbol is employed to separate the topic name from the message types. After the first “@” symbol, you’ll find the ROS message type.

The ROS message type is then followed by either

  • “@” (indicating a bidirectional bridge),
  • “[” (indicating a bridge from Ignition to ROS),
  • “]” (indicating a bridge from ROS to Ignition).

These symbols denote the direction of message transfer between ROS and Ignition.

%%{init: {'theme':'dark'}}%%
graph TB

    subgraph Gazebo
    A[[IGN Gazebo]] --> B([Ign topics])
    subgraph Bridge
    C[[ros_ign_bridge]] -.- D{{parameter_bridge}}
    subgraph ROS2
    F[[Humble]] --> G([ROS2 topics])
    B <-- gazebo_type --> D
    G <-- ros_type --> D
    A ~~~ C
    F ~~~ C


You’ll have to open different terminals to be able to run commands simultaneously, so if you aren’t already doing it, don’t forget to source ROS !

I made myself an alias in my .bashrc file in order to make this cleaner (if you want to use it as well, change the path beforehand as it may differ on your machine):

alias ros_setup=‘source /opt/ros/humble/setup.bash’

Now let’s try to catch the camera movements ! This should do the trick :

ros2 run ros_gz_bridge parameter_bridge /gui/camera/pose@geometry_msgs/msg/Pose[ignition.msgs.Pose

To dissect it a little bit, you can see that we’ll publish on the topic /gui/camera/pose. The ‘Position’ type is referred to as geometry_msgs/msg/Pose for ROS, and ignition.msgs.Pose for Gazebo.

Just to make sure that everything went well, we should check that the topic exists ! In a new terminal, write the following to see all current topics (don’t forget to source :p):

> ros2 topic list


There it is !

Now, in order to catch those messages, lets open up the topic :

ros2 topic echo /gui/camera/pose

Move around a bit, and congrats ! You can see the messages about what you are doing :) You will receive a lot of them, so you can just CTRL-C both terminals, since you’ll be running more commands in the following paragraph.

Simple movement

Now that you have an example of a Gazebo -> ROS discussion, let’s do it the other way around !

In the simulation you launched, there is a little blue car (it might look a bit grey on certain computers). Let’s try and make it move a bit. You can use the same terminals as the previous part :

ros2 run ros_gz_bridge parameter_bridge /model/vehicle_blue/cmd_vel@geometry_msgs/msg/Twist]ignition.msgs.Twist

To dissect it again, here is what is happening. The topic is now /model/vehicle_blue/cmd_vel, with the message type being Twist for both ROS and Gazebo. A Twist is a geometry message that represents a movement in a 3D free space. It has two components :

  • Linear velocity: a 3D vector that represents the velocity of the object in the x, y, and z directions.
  • Angular velocity: a 3D vector that represents the angular velocity of the object around the x, y, and z axes

And now, let’s make that little car move ! In your ROS terminal, write :

ros2 topic pub /model/vehicle_blue/cmd_vel geometry_msgs/Twist "linear: { x: 0.1 }"

Instead of echoing the messages on the topic, what we’ll do here is publish (pub) a message. We just want it to go forward, so increasing the x value of the linear velocity is perfect !

This should send it forward !


The provided robot is restrained in it’s movements, and is not able to move up and down or left to right, however it is able to rotate sideways ;)

“angular: { x: 0, y: 0, z: 0.1 }” you spin me right round baby right round

Debug examples

Let’s end this article with a few tips on how to debug (or simply understand a little bit more) what is going on in your simulation !

The main advice I would give you would be to launch your work with the -v flag:

ign gazebo -v 4 -r visualize_lidar.sdf


The -v option is used to set the verbosity level of the Gazebo simulator. The verbosity level determines how much information is printed to the console. The possible verbosity levels are:

  • 0: Fatal errors only
  • 1: Errors and warnings (default verbosity)
  • 2: Information messages
  • 3: Debug messages
  • 4: Trace messages

Each verbosity level includes the messages of all its predecessors.

The -r option is used to specify the world file to load.

Although if you want to get really into the inner workings of your work, there is another way of doing it : ign Gazebo uses command line tools based on Ruby. The easiest way to debug them would be to use GDB, which means running it against the Ruby executable.

There are two different types of debugging that you could do with Gazebo: either Server or GUI.

Server debugging is the most useful of the two for your current level, as it is can be used to understand why your robot is not behaving the way you expected it, or where do the errors you see come from.

GUI debugging is a bit more “complicated”, as it can help understand why it is not responding to your input (for example, buttons may not be working or the viewport may not be updating).

I’ll explain below how to do both of them. In both cases, the first step would be to find the ign executable:

which ign

This resulted in usr/bin/ign for me, don’t forget to change it if this differs on your machine.

Server debugging

The first step is to run gdb with ruby :

gdb ruby

Then, you can just run the Gazebo server as normal. Just don’t forget to use the -s argument.

(gdb) r /usr/bin/ign gazebo -s visualize_lidar.sdf 


The -s argument specifies the simulation mode, it can be used 3 ways :

  • -s headless, which runs the simulation without the GUI
  • -s gui, the default mode
  • -s none, allowing you to load and inspect a world without running the simulation (our current situation)

You’ll be able to use GDB as usual right after !

GUI debugging

Similarly, the first step is to run gdb with ruby :

gdb ruby

Then run the GUI :

(gdb) r /usr/bin/ign gazebo


You may want to add the -g option to set the default gravity

In another terminal, you can just launch the server like before :

ign gazebo -s -v 4 -r visualize_lidar.sdf

And you can just use GDB as usual !

To go further

Since this was simply an entry point to the world Gazebo ignition and ROS Humble have to offer, there are a lot more things that can be done to improve your understanding !

For instance, no examples of ROS nodes were made in this tutorial, we simply listened on the topic or published directly to it. Try and make your own node to listen on the cameras position, or publish a command to the car !

As for gazebo, working in a premade world would be very limiting, especially if you want to try and make your own project. If you wish to deepen your understanding of Gazebo, you can try following this tutorial on how to create your own server and robot !


I hope to have explained enough of the interactions between ROS and Gazebo for you to have a base to hold onto when you try your own project! These tools can prove to be very frustrating to work with, however they most definitely are very satisfying when you finally understand them!

Thank you for your time and good luck in your future endeavors ;)

Useful resources