Skip to main content

Gazebo Simulation Environment Setup

Welcome to Module 2: The Digital Twin! This chapter introduces you to Gazebo, the premier simulation environment for robotics. Gazebo provides a physics-based environment where you can test and validate your humanoid robot designs before deploying them on real hardware.

Learning Objectives

By the end of this chapter, you will be able to:

  • Install and configure Gazebo for humanoid robotics simulation
  • Understand Gazebo's architecture and physics engine
  • Create basic simulation worlds and environments
  • Integrate Gazebo with ROS 2 using Gazebo ROS packages
  • Launch and control simulated robots in Gazebo
  • Configure simulation parameters for realistic behavior

Introduction to Gazebo

Gazebo is a 3D simulation environment that provides realistic physics simulation, high-quality graphics, and convenient programmatic interfaces. For humanoid robotics, Gazebo serves as a crucial "digital twin" where complex behaviors can be tested safely and efficiently.

Key Features of Gazebo

  • Physics Simulation: Realistic multi-body dynamics with ODE, Bullet, or DART engines
  • Sensor Simulation: Cameras, LIDAR, IMU, force/torque sensors, and more
  • Graphics: High-quality rendering with OGRE graphics engine
  • Plugins: Extensible architecture for custom behaviors
  • ROS Integration: Seamless integration with ROS 2 through Gazebo ROS packages

Why Simulation for Humanoid Robotics?

Simulation is particularly important for humanoid robots because:

  • Safety: Test complex behaviors without risk of hardware damage
  • Cost: Develop and test without expensive hardware
  • Speed: Run simulations faster than real-time
  • Repeatability: Test scenarios multiple times with identical conditions
  • Scenarios: Test dangerous or hard-to-replicate situations

Gazebo Architecture

Core Components

  • Gazebo Server (gzserver): Handles physics simulation and sensor updates
  • Gazebo Client (gzclient): Provides GUI for visualization and interaction
  • Gazebo Libraries: C++ libraries for custom plugins and applications
  • Message System: Communication between components using Protobuf

Physics Engine Integration

Gazebo supports multiple physics engines:

  • ODE (Open Dynamics Engine): Default, good for most applications
  • Bullet: Good for complex contact scenarios
  • DART: Advanced for articulated bodies and humanoid robots

Installation and Setup

Prerequisites

  • Ubuntu 22.04 LTS with ROS 2 Humble
  • Graphics card with OpenGL 2.1+ support
  • At least 8GB RAM recommended
  • Multi-core processor

Installation Methods

# Install Gazebo with ROS 2 packages
sudo apt update
sudo apt install ros-humble-gazebo-ros-pkgs ros-humble-gazebo-ros2-control

Method 2: Separate Gazebo Installation

# Install Gazebo Fortress (recommended version)
sudo apt install gazebo11 gz-tools1

Verification

# Check Gazebo installation
gazebo --version

# Launch Gazebo GUI
gazebo

# Launch Gazebo server only
gzserver

Gazebo World Files

World files define the simulation environment using SDF (Simulation Description Format):

Basic World Structure

<?xml version="1.0" ?>
<sdf version="1.7">
<world name="default">
<!-- Physics engine configuration -->
<physics type="ode">
<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>

<!-- Include models from Gazebo database -->
<include>
<uri>model://ground_plane</uri>
</include>

<include>
<uri>model://sun</uri>
</include>

<!-- Custom models can be placed here -->
<model name="my_robot">
<!-- Model definition -->
</model>
</world>
</sdf>

Creating a Simple World

<?xml version="1.0" ?>
<sdf version="1.7">
<world name="humanoid_lab">
<!-- Physics configuration -->
<physics type="ode">
<max_step_size>0.001</max_step_size>
<real_time_factor>1</real_time_factor>
<real_time_update_rate>1000</real_time_update_rate>
<gravity>0 0 -9.8</gravity>
</physics>

<!-- Environment -->
<include>
<uri>model://ground_plane</uri>
</include>

<include>
<uri>model://sun</uri>
</include>

<!-- Simple obstacles -->
<model name="table">
<pose>2 0 0.5 0 0 0</pose>
<link name="link">
<collision name="collision">
<geometry>
<box>
<size>1 0.8 1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>1 0.8 1</size>
</box>
</geometry>
<material>
<ambient>0.8 0.6 0.2 1</ambient>
<diffuse>0.8 0.6 0.2 1</diffuse>
</material>
</visual>
<inertial>
<mass>10</mass>
<inertia>
<ixx>1</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>1</iyy>
<iyz>0</iyz>
<izz>1</izz>
</inertia>
</inertial>
</link>
</model>

<!-- Lighting -->
<light name="light1" type="point">
<pose>0 0 5 0 0 0</pose>
<diffuse>1 1 1 1</diffuse>
<specular>0.5 0.5 0.5 1</specular>
<attenuation>
<range>10</range>
</attenuation>
</light>
</world>
</sdf>

Gazebo ROS Integration

Gazebo ROS Packages

The Gazebo ROS packages provide the bridge between Gazebo and ROS 2:

  • gazebo_ros: Core ROS integration
  • gazebo_plugins: Standard robot plugins
  • gazebo_ros_control: Integration with ros_control
  • gazebo_dev: Development headers and libraries

Launching Gazebo with ROS 2

# Launch Gazebo server with ROS 2 interface
ros2 launch gazebo_ros empty_world.launch.py

# Launch with a specific world
ros2 launch gazebo_ros empty_world.launch.py world_name:=path/to/world.sdf

# Launch with GUI
ros2 launch gazebo_ros gzserver.launch.py gui:=true

Gazebo ROS Parameters

Common launch parameters:

  • world_name: Path to world file
  • gui: Whether to launch GUI (true/false)
  • verbose: Verbose output (true/false)
  • physics: Physics engine to use

Basic Robot Simulation

Spawning a Robot in Gazebo

# Spawn a model from the Gazebo model database
ros2 run gazebo_ros spawn_entity.py -database unit_box -entity my_box

# Spawn a model from a file
ros2 run gazebo_ros spawn_entity.py -file path/to/robot.urdf -entity my_robot

# Spawn with custom pose
ros2 run gazebo_ros spawn_entity.py -file path/to/robot.urdf -entity my_robot -x 1 -y 2 -z 0

Robot State Publisher Integration

<!-- In your launch file -->
<node name="robot_state_publisher" pkg="robot_state_publisher" exec="robot_state_publisher">
<param name="robot_description" value="$(var robot_description)"/>
</node>

<node name="gazebo" pkg="gazebo_ros" exec="spawn_entity.py">
<param name="robot_name" value="my_robot"/>
<param name="robot_namespace" value=""/>
<param name="urdf" value="$(var robot_description)"/>
</node>

Gazebo Plugins for Humanoid Robots

Essential Plugins

1. Joint State Publisher

Publishes joint states from Gazebo to ROS 2:

<gazebo>
<plugin name="joint_state_publisher" filename="libgazebo_ros_joint_state_publisher.so">
<joint_name>joint1</joint_name>
<joint_name>joint2</joint_name>
<update_rate>30</update_rate>
</plugin>
</gazebo>

2. Diff Drive Controller

For wheeled robots (not typically for humanoid):

<gazebo>
<plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
<left_joint>left_wheel_joint</left_joint>
<right_joint>right_wheel_joint</right_joint>
<wheel_separation>0.3</wheel_separation>
<wheel_diameter>0.15</wheel_diameter>
</plugin>
</gazebo>

3. Joint Position/Velocity/Effort Controllers

For humanoid joint control:

<gazebo>
<plugin name="ros_control" filename="libgazebo_ros_control.so">
<robot_namespace>/my_robot</robot_namespace>
</plugin>
</gazebo>

Simulation Parameters for Humanoid Robots

Physics Configuration

For humanoid robots, consider these physics settings:

<physics type="ode">
<max_step_size>0.001</max_step_size> <!-- Small for stability -->
<real_time_factor>1</real_time_factor> <!-- Real-time simulation -->
<real_time_update_rate>1000</real_time_update_rate> <!-- High update rate -->
<gravity>0 0 -9.8</gravity>
<ode>
<solver>
<type>quick</type>
<iters>1000</iters> <!-- More iterations for stability -->
<sor>1.3</sor>
</solver>
<constraints>
<cfm>0.0</cfm>
<erp>0.2</erp> <!-- Error reduction parameter -->
<contact_max_correcting_vel>100.0</contact_max_correcting_vel>
<contact_surface_layer>0.001</contact_surface_layer>
</constraints>
</ode>
</physics>

Contact Parameters for Humanoid Feet

<link name="left_foot">
<collision name="foot_collision">
<geometry>
<box size="0.2 0.1 0.05"/>
</geometry>
<surface>
<friction>
<ode>
<mu>1.0</mu> <!-- High friction for stable walking -->
<mu2>1.0</mu2>
</ode>
</friction>
<contact>
<ode>
<kp>1e6</kp> <!-- High stiffness for feet -->
<kd>100</kd> <!-- Damping for stability -->
<max_vel>100.0</max_vel>
<min_depth>0.001</min_depth>
</ode>
</contact>
</surface>
</collision>
</link>

Launch Files for Gazebo Simulation

Basic Gazebo Launch File

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare

def generate_launch_description():
# Declare launch arguments
use_sim_time_arg = DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation time'
)

world_arg = DeclareLaunchArgument(
'world',
default_value='empty',
description='Choose one of the world files from Gazebo models'
)

# Launch Gazebo
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource([
PathJoinSubstitution([
FindPackageShare('gazebo_ros'),
'launch',
'gazebo.launch.py'
])
]),
launch_arguments={
'world': LaunchConfiguration('world'),
'verbose': 'false',
}.items()
)

# Robot state publisher
robot_state_publisher_node = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'use_sim_time': LaunchConfiguration('use_sim_time')}]
)

return LaunchDescription([
use_sim_time_arg,
world_arg,
gazebo,
robot_state_publisher_node
])

Spawning Robot Launch File

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, RegisterEventHandler
from launch.event_handlers import OnProcessExit
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare

def generate_launch_description():
# Declare arguments
use_sim_time = LaunchConfiguration('use_sim_time')

# Get URDF via xacro
robot_description_content = Command(
[
PathJoinSubstitution([FindExecutable(name="xacro")]),
" ",
PathJoinSubstitution([
FindPackageShare("my_robot_description"),
"urdf",
"humanoid_robot.urdf.xacro",
]),
]
)
robot_description = {"robot_description": robot_description_content}

# Robot state publisher
node_robot_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
output='screen',
parameters=[robot_description, {'use_sim_time': use_sim_time}],
)

# Spawn robot in Gazebo
spawn_entity = Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-topic', 'robot_description', '-entity', 'humanoid_robot'],
output='screen'
)

# Create launch description
return LaunchDescription([
# Launch Arguments
DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use simulation (Gazebo) clock if true'
),

# Nodes
node_robot_state_publisher,
spawn_entity,
])

Debugging Gazebo Simulations

Common Issues and Solutions

Issue: Robot Falls Through Ground

Solution: Check mass, inertia, and collision properties in URDF

Issue: Unstable Simulation

Solution: Reduce step size, increase iterations, check joint limits

Issue: No Communication with ROS

Solution: Verify robot state publisher and joint state publisher plugins

Issue: Slow Performance

Solution: Simplify collision geometries, reduce update rates

Debugging Commands

# Check Gazebo topics
ros2 topic list | grep gazebo

# Monitor joint states
ros2 topic echo /joint_states

# Check TF tree
ros2 run tf2_tools view_frames

Best Practices for Humanoid Simulation

1. Physics Tuning

  • Start with conservative parameters and increase gradually
  • Use appropriate friction coefficients for feet
  • Tune contact parameters for stable walking

2. Model Simplification

  • Use simpler collision geometries for better performance
  • Balance visual detail with simulation speed
  • Consider different models for different purposes

3. Realistic Sensors

  • Configure sensors with realistic noise parameters
  • Match simulation sensors to real hardware specifications
  • Test sensor fusion algorithms in simulation first

4. Scenario Testing

  • Create diverse environments for robustness testing
  • Test edge cases that would be dangerous in real life
  • Validate behaviors across different conditions

Integration with ROS 2 Ecosystem

Robot Description Parameter

# In your nodes, use robot description from parameter server
robot_description = self.get_parameter('robot_description').value

TF Integration

Gazebo automatically publishes transforms for all joints, making it easy to visualize in RViz.

Sensor Integration

Gazebo plugins publish sensor data in standard ROS 2 message formats.

Summary

Gazebo provides a powerful simulation environment for humanoid robotics development. Proper setup and configuration are essential for realistic simulation that bridges the gap between virtual and real robot behavior. The integration with ROS 2 through Gazebo ROS packages enables seamless development workflows.

Next Steps

In the next chapter, we'll explore robot description formats beyond URDF, specifically SDF, and learn how to create more complex simulation scenarios.


Estimated Reading Time: 26 minutes