Chapter 1: Physics Simulation with Gazebo
Learning Objectives
- Understand why simulation is essential for robotics development
- Install and configure Gazebo Fortress
- Create robot models using URDF and SDF
- Spawn and control robots in simulated environments
- Add physics properties and constraints
1.1 Why Simulation?
The Reality of Robot Development
Problem: Physical robots are:
- Expensive: $50,000 - $1,000,000+ for humanoids
- Dangerous: A malfunctioning humanoid can cause serious injury
- Slow: Each test requires setup, deployment, and reset
- Limited: Can't test extreme scenarios (falling, collisions
)
Solution: Validate algorithms in simulation first, then deploy to hardware.
Simulation Benefits
| Aspect | Simulation | Physical Robot |
|---|---|---|
| Cost | Free | $$$$ |
| Safety | Perfectly safe | Can damage robot/environment |
| Iteration Speed | Seconds | Minutes to hours |
| Parallelization | Run 1000 instances | Limited by hardware |
| Scenarios | Any imaginable | Limited by lab |
| Debugging | Full state access | Limited sensors |
The Sim-to-Real Gap
Simulation is not perfect:
- Physics: Simplified contact models
- Sensors: Noise models are approximations
- Actuators: Ideal vs. real motor dynamics
Solution: Domain randomization and careful calibration minimize the gap.
1.2 Gazebo Architecture
Gazebo Classic vs. Gazebo (Ignition/Fortress)
We use Gazebo Fortress (also called Ignition Gazebo):
- Modern architecture
- Better performance
- Improved rendering (Ogre 2)
- Plugins for ROS 2 integration
Installation
# Install Gazebo Fortress
sudo apt-get update
sudo apt-get install ros-humble-ros-gz
# Verify installation
gz sim --version
Architecture
┌──────────────┐
│ Gazebo GUI │ ← Visualization
└──────┬───────┘
│
┌──────▼───────┐
│ Gazebo Server│ ← Physics engine
│ (gz sim) │
└──────┬───────┘
│
┌───▼───┐
│ PhysX │ ← Contact dynamics
└───────┘
1.3 Creating World Files
SDF (Simulation Description Format)
Gazebo uses SDF to describe worlds and models.
worlds/empty.sdf
<?xml version="1.0" ?>
<sdf version="1.8">
<world name="empty_world">
<!-- Physics engine settings -->
<physics name="1ms" type="dart">
<max_step_size>0.001</max_step_size>
<real_time_factor>1.0</real_time_factor>
</physics>
<!-- Lighting -->
<light type="directional" name="sun">
<cast_shadows>true</cast_shadows>
<pose>0 0 10 0 0 0</pose>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.2 0.2 0.2 1</specular>
<attenuation>
<range>1000</range>
</attenuation>
<direction>-0.5 0.1 -0.9</direction>
</light>
<!-- Ground plane -->
<model name="ground_plane">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
</collision>
<visual name="visual">
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
<material>
<ambient>0.8 0.8 0.8 1</ambient>
<diffuse>0.8 0.8 0.8 1</diffuse>
</material>
</visual>
</link>
</model>
</world>
</sdf>
Launching a World
gz sim worlds/empty.sdf
1.4 URDF to SDF Conversion
Why Two Formats?
- URDF: ROS-specific, simpler, good for robot description
- SDF: Gazebo-specific, more features, good for world description
Gazebo can import URDF but converts it to SDF internally.
Enhanced URDF with Gazebo Tags
urdf/humanoid_gazebo.urdf
<?xml version="1.0"?>
<robot name="humanoid_gazebo">
<link name="base_link">
<visual>
<geometry>
<box size="0.3 0.2 0.5"/>
</geometry>
<material name="blue">
<color rgba="0.2 0.4 0.8 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="0.3 0.2 0.5"/>
</geometry>
</collision>
<inertial>
<mass value="10.0"/>
<inertia ixx="0.2" ixy="0" ixz="0"
iyy="0.3" iyz="0" izz="0.2"/>
</inertial>
</link>
<!-- Gazebo-specific material -->
<gazebo reference="base_link">
<material>Gazebo/Blue</material>
<mu1>0.8</mu1> <!-- Friction coefficient -->
<mu2>0.8</mu2>
</gazebo>
<link name="right_foot">
<visual>
<geometry>
<box size="0.2 0.1 0.05"/>
</geometry>
</visual>
<collision>
<geometry>
<box size="0.2 0.1 0.05"/>
</geometry>
</collision>
<inertial>
<mass value="1.0"/>
<inertia ixx="0.01" ixy="0" ixz="0"
iyy="0.01" iyz="0" izz="0.01"/>
</inertial>
</link>
<joint name="right_ankle" type="revolute">
<parent link="base_link"/>
<child link="right_foot"/>
<origin xyz="0.1 -0.15 -0.4" rpy="0 0 0"/>
<axis xyz="1 0 0"/>
<limit lower="-0.5" upper="0.5" effort="100" velocity="2"/>
</joint>
<!-- Gazebo plugin for joint control -->
<gazebo>
<plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control">
<robot_param>robot_description</robot_param>
<parameters>config/controllers.yaml</parameters>
</plugin>
</gazebo>
</robot>
1.5 Spawning Robots
Using ros2 launch
launch/spawn_humanoid.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
pkg_path = get_package_share_directory('humanoid_gazebo')
urdf_file = os.path.join(pkg_path, 'urdf', 'humanoid_gazebo.urdf')
with open(urdf_file, 'r') as f:
robot_description = f.read()
spawn_entity = Node(
package='ros_gz_sim',
executable='create',
arguments=[
'-name', 'humanoid',
'-topic', 'robot_description',
'-x', '0',
'-y', '0',
'-z', '1.0'
],
output='screen'
)
robot_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'robot_description': robot_description}]
)
return LaunchDescription([
robot_state_publisher,
spawn_entity
])
Testing Basic Motion
# Start Gazebo
gz sim worlds/empty.sdf
# Spawn robot
ros2 launch humanoid_gazebo spawn_humanoid.launch.py
# Command a joint
gz topic -t /model/humanoid/joint/right_ankle/cmd_pos -m gz.msgs.Double -p "data: 0.3"
1.6 Physics Properties
Contact Parameters
Critical for walking:
<gazebo reference="right_foot">
<mu1>1.0</mu1> <!-- Friction in primary direction -->
<mu2>1.0</mu2> <!-- Friction in secondary direction -->
<kp>1000000.0</kp> <!-- Contact stiffness -->
<kd>1.0</kd> <!-- Contact damping -->
<minDepth>0.001</minDepth> <!-- Minimum penetration for contact -->
</gazebo>
Self-Collision
<gazebo>
<self_collide>true</self_collide>
</gazebo>
Summary
✅ Understand simulation advantages and limitations
✅ Install and use Gazebo Fortress
✅ Create world and robot descriptions
✅ Spawn robots and apply physics