TL;DR
- Install Gazebo Sim Fortress (v7.0.0) for ROS 2 and modern features:
sudo apt-get install ignition-fortress - Create worlds with SDF (e.g.,
world.sdf):<sdf version="1.9"> <world name="default"> <include file="plane.sdf"/> <include file="robot.urdf"/> </world> </sdf> - Spawn robots via CLI:
gz sim -v 4 -r empty.sdf robot.urdf - Bridge ROS 2 and Gazebo with:
ros2 launch ros_gz_bridge server_bridge.xml - Add sensor noise in SDF:
<sensor name="noisy_lidar" type="gpu_lidar"> <noise type="gaussian" mean="0.0" stddev="0.01"/> </sensor> - Run headless for CI:
gz sim -v 4 -r world.sdf --headless
1. Install Gazebo Sim (Modern Version)
Gazebo Sim (formerly Ignition Gazebo) is the active development branch with ROS 2 support. Use Gazebo Classic only for legacy ROS 1 projects.
Ubuntu 22.04/24.04 (Recommended)
# Add Gazebo Sim repository
sudo apt-get install software-properties-common
sudo sh -c 'echo "deb [arch=amd64] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" > /etc/apt/sources.list.d/gazebo-stable.list'
# Add GPG key
wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
# Install Gazebo Sim Fortress (LTS)
sudo apt-get update
sudo apt-get install ignition-fortress
Verify Installation
gz sim --version
Expected Output:
Gazebo Sim Fortress 7.0.0
Windows/macOS
| Platform | Command/Download Link |
|---|---|
| Windows | Download Installer (Requires VS 2022) |
| macOS | brew install gz-sim7 (Homebrew) |
From Source (Advanced)
# Clone and build (Linux/macOS)
git clone --recursive https://github.com/gazebosim/gz-sim.git
mkdir gz-sim/build && cd gz-sim/build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
sudo make install
Gotchas:
- Ubuntu 24.04: Ensure
libignition-math6andlibignition-transport11are installed. - GPU Rendering: Requires NVIDIA drivers for Omniverse integration (experimental).
- ROS 2: Install
ros-foxy-ros-gz-bridgeorros-humble-ros-gz-bridgefor your ROS 2 distro.
2. Building Worlds with SDF
SDF (Simulation Description Format) replaces URDF for Gazebo Sim. Start with a plane and add models.
Create a Basic World (world.sdf)
<?xml version="1.0"?>
<sdf version="1.9">
<world name="default">
<!-- Ground plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!-- Light -->
<light name="sun" type="directional">
<pose>0 0 10 0 0 0</pose>
<cast_shadows>true</cast_shadows>
</light>
<!-- Spawn a robot later via CLI -->
</world>
</sdf>
Load the World
gz sim -v 4 -r world.sdf
Flags:
-v 4: Verbose logging (debug level).-r: Load world file.
Add a Robot Model
- Download a robot model (e.g., TurtleBot3):
gz model --download turtlebot3_burger - Include it in
world.sdf:<include> <uri>model://turtlebot3_burger</uri> <pose>1 1 0 0 0 0</pose> </include>
Gotchas:
- Model Paths: Use
model://for built-in models or absolute paths for custom models. - SDF Version: Always specify
<sdf version="1.9">for Gazebo Sim Fortress.
3. Spawning Robots and Sensors
Spawn a Robot via CLI
gz sim -v 4 -r empty.sdf -m robot.urdf
Flags:
-m: Spawn a model from a URDF/SDF file.
Add Sensors Dynamically
gz model --spawn-file robot_sensor.sdf
Example robot_sensor.sdf:
<model name="lidar">
<include>
<uri>model://hokuyo</uri>
<pose>0.2 0 0.1 0 0 0</pose>
</include>
</model>
Sensor Noise Configuration
Add noise to sensors in SDF:
<sensor name="noisy_lidar" type="gpu_lidar">
<pose>0.2 0 0.1 0 0 0</pose>
<visualize>true</visualize>
<update_rate>30.0</update_rate>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev> <!-- 1cm noise -->
</noise>
</sensor>
Realism Tips:
- Lidar: Use
stddev="0.01"for 1cm noise. - Camera: Add lens distortion:
<camera name="noisy_camera"> <distortion> <k1>0.001</k1> <!-- Radial distortion --> <k2>0.0001</k2> </distortion> </camera>
4. ROS 2 Integration with ros_gz_bridge
Gazebo Sim replaces gazebo_ros_pkgs with ros_gz_bridge.
Install the Bridge
sudo apt-get install ros-<distro>-ros-gz-bridge
Replace <distro> with your ROS 2 version (e.g., humble, foxy).
Launch the Bridge
ros2 launch ros_gz_bridge server_bridge.xml
Example server_bridge.xml:
<launch>
<node pkg="ros_gz_bridge" exec="parameter_bridge" name="parameter_bridge">
<remap from="/clock" to="/clock"/>
<param name="qos_overrides" value="/tf"/>
</node>
<node pkg="ros_gz_bridge" exec="create" name="create">
<remap from="/cmd_vel" to="/diff_drive_controller/cmd_vel_unstamped"/>
</node>
</launch>
Publish a Topic from Gazebo
ros2 topic echo /model/turtlebot3_burger/odom
Gotchas:
- Topic Names: Gazebo Sim uses
/model/<model_name>/<topic>(e.g.,/model/turtlebot3_burger/odom). - Latency: Add
qos_overridesfor/tfto reduce lag. - Legacy ROS 1: Use
ros1_bridgeif mixing ROS 1/2.
5. Writing System Plugins
Plugins extend Gazebo Sim’s functionality (e.g., custom controllers, sensors).
Plugin Structure
my_plugin/
├── CMakeLists.txt
├── plugin.cc
└── package.xml
Example: Custom Controller Plugin
plugin.cc:
#include <gz/sim/System.hh>
#include <gz/transport/Node.hh>
class MyController : public gz::sim::System
{
public:
MyController() : System() {}
~MyController() override {}
void Init() override {
this->node = std::make_unique<gz::transport::Node>();
this->pub = this->node->Advertise<gz::msgs::Boolean>("~/cmd", 10);
}
void Reset() override {}
void PreUpdate(const gz::sim::UpdateInfo &_info, const gz::sim::Entity &_entity) override {
auto msg = std::make_shared<gz::msgs::Boolean>();
msg->set_data(true);
this->pub->Publish(msg);
}
private:
std::unique_ptr<gz::transport::Node> node;
gz::transport::Publisher pub;
};
GZ_REGISTER_SYSTEM(MyController)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(my_plugin)
find_package(gz-sim REQUIRED)
find_package(gz-transport REQUIRED)
add_library(my_plugin SHARED plugin.cc)
target_link_libraries(my_plugin PRIVATE gz-sim gz-transport)
Build and Load the Plugin
mkdir build && cd build
cmake .. && make
gz sim -v 4 -r world.sdf --plugin libmy_plugin.so
Gotchas:
- Plugin Path: Use
--pluginor setGAZEBO_PLUGIN_PATH. - Dependencies: Link against
gz-simandgz-transport. - Debugging: Use
-v 4for verbose plugin logs.
6. Sensor Noise and Realism
Gazebo Sim supports physics-based noise and environmental effects.
Add Wind to a World
<world name="default">
<physics name="default_physics">
<max_step_size>0.001</max_step_size>
<real_time_factor>1</real_time_factor>
<real_time_update_rate>1000</real_time_update_rate>
</physics>
<environment>
<wind>
<speed>2.0</speed> <!-- m/s -->
<direction>0 0 1</direction> <!-- X Y Z -->
</wind>
</environment>
</world>
Simulate Slippery Surfaces
<model name="floor">
<static>true</static>
<link name="link">
<collision name="collision">
<surface>
<friction>
<ode>
<mu>0.1</mu> <!-- Coefficient of friction -->
<mu2>0.01</mu2>
</ode>
</friction>
</surface>
</collision>
</link>
</model>
Realism Checklist:
- Add Gaussian noise to sensors (
<noise>tag). - Use ODE physics for realistic collisions (
<physics type="ode">). - Simulate lighting conditions with
<light>tags. - Enable contact forces for dynamic interactions.
7. Headless Simulation for CI
Run Gazebo Sim without a GUI for continuous integration.
Headless Mode
gz sim -v 4 -r world.sdf --headless
Flags:
--headless: Disable GUI.--api-key <key>: Required for cloud/remote control.
CI Example (GitHub Actions)
jobs:
test:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Install Gazebo Sim
run: |
sudo apt-get update
sudo apt-get install ignition-fortress
- name: Run Simulation
run: |
gz sim -v 4 -r world.sdf --headless --api-key dummy_key
# Run ROS 2 tests here
Gotchas:
- API Key: Required for remote control (use
dummy_keyfor local CI). - Performance: Headless mode is faster but lacks GUI debugging.
- Logs: Redirect output to a file:
gz sim -v 4 -r world.sdf --headless > sim.log 2>&1
What’s Next?
- Test a Full Robot Stack:
- Simulate a TurtleBot3 with ROS 2 and
ros_gz_bridge. - Run:
gz sim -v 4 -r turtlebot3_world.sdf ros2 launch ros_gz_bridge server_bridge.xml ros2 launch turtlebot3_gazebo turtlebot3_empty_world.launch.py
- Simulate a TurtleBot3 with ROS 2 and
- Add Custom Plugins:
- Write a **
