Gazebo Simulation Launcher
This notebook demonstrates the pykal.gazebo module, which provides simple wrappers for launching and managing Gazebo simulations directly from Jupyter notebooks.
Overview
The pykal.gazebo module provides two main functions:
start_gazebo(): Launch a Gazebo simulation with a robotstop_gazebo(): Cleanly shut down the simulation
These wrappers handle all the complexity of:
Process management
ROS2 environment setup
Robot spawning at specified positions
Cleanup and shutdown
This allows you to focus on control algorithms rather than infrastructure.
Learning Objectives
By the end of this notebook, you will understand:
Basic API: How to start and stop Gazebo simulations
Configuration Options: Robots, worlds, spawn positions, headless mode
Lifecycle Management: Process status checking and cleanup
Use Cases: When to use GUI vs headless mode
Integration: How this fits into the pykal workflow
Let’s begin!
from pykal.gazebo import start_gazebo, stop_gazebo
import time
print("✓ Imports complete")
Part 1: Basic Usage
The simplest use case: launch Gazebo with default settings.
1.1 Start Gazebo with TurtleBot3
The start_gazebo() function launches a Gazebo simulation and spawns a robot. It returns a GazeboProcess object for lifecycle management.
# Launch Gazebo with TurtleBot3 Burger
gz = start_gazebo(
robot='turtlebot3', # Robot type
world='turtlebot3_world', # World/environment
headless=False, # Show GUI (set True for faster simulation)
x_pose=0.0, # Spawn at origin
y_pose=0.0,
z_pose=0.0,
yaw=0.0, # Facing forward (radians)
model='burger' # TurtleBot variant
)
print(f"\n{'='*60}")
print(f"Gazebo Process: {gz}")
print(f"{'='*60}")
print("\n✓ Gazebo launched successfully!")
print(" Check the Gazebo window to see your TurtleBot3.")
print("\n The robot is ready to receive ROS2 commands.")
What just happened?
The start_gazebo() function:
Launched the Gazebo simulator
Loaded the
turtlebot3_worldenvironmentSpawned a TurtleBot3 Burger at position (0, 0, 0)
Set up all ROS2 topics for communication
You should now see a Gazebo window with a small robot in an environment with obstacles.
1.2 Let Simulation Run
The robot is now active in Gazebo. Let’s let it run for a few seconds so you can observe it.
print("Simulation running...")
print("(The robot is idle, waiting for velocity commands on /cmd_vel)")
time.sleep(5)
print("✓ Observation complete")
Simulation running...
(The robot is idle, waiting for velocity commands on /cmd_vel)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[1], line 3
1 print("Simulation running...")
2 print("(The robot is idle, waiting for velocity commands on /cmd_vel)")
----> 3 time.sleep(5)
4 print("✓ Observation complete")
NameError: name 'time' is not defined
1.3 Stop Gazebo
Always cleanly shut down Gazebo when you’re done. This prevents zombie processes.
stop_gazebo(gz)
print("✓ Gazebo shut down successfully")
print(" The Gazebo window should now be closed.")
Part 2: Configuration Options
The start_gazebo() function accepts several parameters to customize the simulation.
2.1 Supported Robots
PyKal currently supports two robot platforms:
turtlebot3: Ground robot with differential driveModels:
burger(default),waffle,waffle_piGood for: Navigation, SLAM, ground-based control
crazyflie: Quadrotor UAVModels: Standard Crazyflie 2.0
Good for: 3D control, aerial robotics
Let’s try launching a Crazyflie:
# Launch Crazyflie quadrotor
gz_cf = start_gazebo(
robot='crazyflie',
world='empty_world', # Simple empty environment
headless=False,
x_pose=0.0,
y_pose=0.0,
z_pose=0.5, # Spawn 0.5m above ground
yaw=0.0
)
print("\n✓ Crazyflie spawned at z=0.5m")
print(" Look for a small quadrotor hovering in the Gazebo window.")
time.sleep(3)
# Clean shutdown
stop_gazebo(gz_cf)
print("\n✓ Crazyflie simulation stopped")
2.2 Spawn Position and Orientation
You can spawn robots at any position and orientation using the x_pose, y_pose, z_pose, and yaw parameters.
Coordinate System:
x: Forward/backward (meters)
y: Left/right (meters)
z: Up/down (meters)
yaw: Rotation around z-axis (radians, 0 = facing +x)
Let’s spawn a TurtleBot at position (2, 1, 0) facing 45 degrees:
import numpy as np
# Spawn at custom position
gz_custom = start_gazebo(
robot='turtlebot3',
world='turtlebot3_world',
headless=False,
x_pose=2.0, # 2 meters forward
y_pose=1.0, # 1 meter to the left
z_pose=0.0, # On the ground
yaw=np.pi/4, # 45 degrees (π/4 radians)
model='burger'
)
print(f"\n✓ TurtleBot spawned at position (2, 1, 0)")
print(f" Orientation: 45° (π/4 rad)")
print(f"\n In the Gazebo window, the robot should be:")
print(f" - 2 meters forward from origin")
print(f" - 1 meter to the left")
print(f" - Rotated 45 degrees counterclockwise")
time.sleep(5)
stop_gazebo(gz_custom)
print("\n✓ Custom position simulation stopped")
2.3 Headless Mode (Faster Simulation)
When you don’t need visualization, use headless=True for significantly faster simulation. This is ideal for:
Automated testing
Parameter tuning
Large-scale experiments
CI/CD pipelines
Performance comparison:
GUI mode: ~1x real-time (limited by rendering)
Headless mode: 5-10x real-time (CPU-limited only)
# Launch in headless mode
gz_headless = start_gazebo(
robot='turtlebot3',
world='empty_world',
headless=True, # No GUI!
x_pose=0.0,
y_pose=0.0,
z_pose=0.0,
yaw=0.0,
model='burger'
)
print("\n✓ Headless simulation started")
print(" No Gazebo window - simulation runs in background.")
print(" This is much faster for automated testing!")
# Simulate some work
print("\nRunning headless simulation for 3 seconds...")
time.sleep(3)
stop_gazebo(gz_headless)
print("\n✓ Headless simulation stopped")
2.4 Different Worlds
Gazebo supports different simulation environments (“worlds”). Common options:
For TurtleBot3:
turtlebot3_world: Environment with obstacles and landmarksturtlebot3_house: Indoor house environmentempty_world: Minimal empty environment
For Crazyflie:
empty_world: Open space for flight testingCustom worlds with obstacles for navigation
The world parameter affects available features (obstacles, lighting, etc.) but not the robot’s ROS2 interface.
# Launch in empty world (minimal)
gz_empty = start_gazebo(
robot='turtlebot3',
world='empty_world', # Just a ground plane
headless=False,
x_pose=0.0,
y_pose=0.0,
z_pose=0.0,
yaw=0.0,
model='burger'
)
print("\n✓ Launched in empty_world")
print(" You should see just a ground plane - no obstacles.")
print(" This is useful for basic motion testing.")
time.sleep(3)
stop_gazebo(gz_empty)
print("\n✓ Empty world simulation stopped")
Part 3: Lifecycle Management
Understanding the GazeboProcess object and proper cleanup.
3.1 The GazeboProcess Object
The start_gazebo() function returns a GazeboProcess object that tracks the simulation process. This object is used for cleanup.
# Start simulation
gz_demo = start_gazebo(
robot='turtlebot3',
world='empty_world',
headless=True,
x_pose=0.0,
y_pose=0.0,
z_pose=0.0,
yaw=0.0,
model='burger'
)
# Inspect the GazeboProcess object
print(f"GazeboProcess object: {gz_demo}")
print(f"Type: {type(gz_demo)}")
print(f"\nThis object keeps track of:")
print(f" - Process IDs")
print(f" - Environment variables")
print(f" - Cleanup requirements")
# Clean shutdown using the object
stop_gazebo(gz_demo)
print("\n✓ Simulation stopped using GazeboProcess object")
3.2 Always Use stop_gazebo()
Important: Always call stop_gazebo() to cleanly shut down the simulation. Not doing so can leave:
Zombie processes consuming CPU
ROS2 nodes still running
Port conflicts for future simulations
Best Practice Pattern:
try:
gz = start_gazebo(...)
# Your simulation code here
finally:
stop_gazebo(gz)
3.3 Error Handling
Proper error handling ensures cleanup even if your simulation code fails.
# Example: Safe simulation with error handling
gz_safe = None
try:
print("Starting simulation with error handling...")
gz_safe = start_gazebo(
robot='turtlebot3',
world='empty_world',
headless=True,
x_pose=0.0,
y_pose=0.0,
z_pose=0.0,
yaw=0.0,
model='burger'
)
print("✓ Simulation started")
# Simulate some work
time.sleep(2)
# If an error occurred here, cleanup would still happen
print("✓ Work completed successfully")
finally:
if gz_safe is not None:
print("\nCleaning up...")
stop_gazebo(gz_safe)
print("✓ Cleanup complete (even if errors occurred)")
Part 4: Integration with ROS2
Once Gazebo is running, the robot automatically publishes sensor data and listens for commands on ROS2 topics.
4.1 Available ROS2 Topics
When you launch a robot in Gazebo, it automatically sets up ROS2 topics:
TurtleBot3 Topics:
/cmd_vel(Twist): Velocity commands (linear and angular)/odom(Odometry): Position, velocity, and pose estimates/scan(LaserScan): LIDAR data (if equipped)/imu(Imu): IMU sensor data/joint_states: Joint positions and velocities
Crazyflie Topics:
/cmd_vel(Twist): Velocity commands/odom(Odometry): Position and velocity/imu(Imu): IMU data
These topics are ready for use with ROSNode wrappers (covered in later tutorials).
4.2 Quick Topic Check
You can verify the topics are active by inspecting ROS2 while Gazebo is running.
Note: This requires ROS2 command-line tools. If not available, skip this cell.
# Optional: Check available ROS2 topics
# This requires ros2 CLI tools installed
try:
import subprocess
gz_check = start_gazebo(
robot='turtlebot3',
world='empty_world',
headless=True,
x_pose=0.0,
y_pose=0.0,
z_pose=0.0,
yaw=0.0,
model='burger'
)
print("Checking ROS2 topics...\n")
time.sleep(3) # Wait for topics to initialize
result = subprocess.run(
['ros2', 'topic', 'list'],
capture_output=True,
text=True,
timeout=5
)
topics = [t for t in result.stdout.split('\n') if t.strip()]
print("Active ROS2 topics:")
for topic in topics:
if any(key in topic for key in ['cmd_vel', 'odom', 'scan', 'imu']):
print(f" ✓ {topic}")
stop_gazebo(gz_check)
except Exception as e:
print(f"Topic check skipped: {e}")
print("(This is optional - ROS2 CLI tools may not be available)")
try:
stop_gazebo(gz_check)
except:
pass
Part 5: Common Use Cases
Practical examples for different scenarios.
5.1 Use Case: Interactive Development
Scenario: You’re developing a controller and want to see the robot’s behavior.
Configuration:
headless=False- Show GUI for visual feedbackworld='turtlebot3_world'- Rich environment with obstaclesDefault spawn position
print("Use Case: Interactive Development\n")
gz_dev = start_gazebo(
robot='turtlebot3',
world='turtlebot3_world',
headless=False, # Show GUI
x_pose=0.0,
y_pose=0.0,
z_pose=0.0,
yaw=0.0,
model='burger'
)
print("✓ Interactive simulation ready")
print(" - GUI visible for debugging")
print(" - Rich environment with obstacles")
print(" - Ready for ROSNode control commands")
# In a real workflow, you'd connect ROSNode controllers here
time.sleep(3)
stop_gazebo(gz_dev)
print("\n✓ Development session complete")
5.2 Use Case: Automated Testing
Scenario: Running regression tests in CI/CD pipeline.
Configuration:
headless=True- Maximum speed, no GUIworld='empty_world'- Minimal complexityProgrammatic position setup for repeatable tests
print("Use Case: Automated Testing\n")
# Test configuration
test_positions = [
(0.0, 0.0, 0.0),
(1.0, 0.0, np.pi/2),
(-1.0, 1.0, np.pi),
]
for i, (x, y, yaw) in enumerate(test_positions):
print(f"Test {i+1}/3: Position ({x}, {y}), yaw={yaw:.2f} rad")
gz_test = start_gazebo(
robot='turtlebot3',
world='empty_world',
headless=True, # Fast!
x_pose=x,
y_pose=y,
z_pose=0.0,
yaw=yaw,
model='burger'
)
# Run test (placeholder)
time.sleep(1)
stop_gazebo(gz_test)
print(f" ✓ Test {i+1} passed\n")
print("✓ All automated tests complete")
5.3 Use Case: Multi-Robot Experiments
Scenario: Testing multi-agent coordination.
Note: This requires advanced Gazebo configuration. The basic pattern is:
Launch one simulation
Spawn additional robots using ROS2 spawn service
For simplicity, the start_gazebo() wrapper currently supports single-robot scenarios. Multi-robot setups require manual ROS2 service calls (covered in advanced tutorials).
Part 6: Best Practices
Guidelines for effective Gazebo usage in pykal workflows.
6.1 Development Workflow
Recommended progression:
Pure Python (no Gazebo)
Develop DynamicalSystem components
Test with synthetic data
Validate algorithms
Gazebo Simulation (this notebook)
Wrap components in ROSNode callbacks
Deploy to Gazebo for physics validation
Test with realistic sensor noise
Hardware Deployment
Transfer validated code to robot
Minimal changes required
Why this order?
Faster iteration in early stages
Physics validation before hardware
Risk reduction (no robot damage during algorithm development)
6.2 Performance Considerations
When to use headless mode:
✓ Automated testing
✓ Parameter tuning loops
✓ Long simulation runs
✓ CI/CD pipelines
When to use GUI mode:
✓ Algorithm debugging
✓ Behavior verification
✓ Demos and presentations
✓ Initial development
Resource usage:
GUI mode: ~2-4 GB RAM, 50-100% CPU (one core)
Headless mode: ~1-2 GB RAM, 30-60% CPU (one core)
6.3 Troubleshooting
Common issues:
“Gazebo won’t start”
Check ROS2 installation
Verify robot packages installed (e.g.,
ros-humble-turtlebot3-*)Try
headless=Trueto rule out graphics issues
“Simulation is very slow”
Use
headless=TrueClose other applications
Use
empty_worldinstead of complex environments
“Topics not appearing”
Wait 2-3 seconds after
start_gazebo()for initializationCheck robot model is correct
Verify ROS2 environment (
echo $ROS_DOMAIN_ID)
“Process won’t stop”
Always call
stop_gazebo(gz)If stuck, manually kill:
pkill -9 gzserverRestart notebook kernel if necessary
Summary
This notebook covered the pykal.gazebo module:
Key Functions
start_gazebo(): Launch simulation with configurable robots, worlds, and positionsstop_gazebo(): Clean shutdown
Configuration Options
Robots:
turtlebot3,crazyflieWorlds:
turtlebot3_world,empty_world, etc.Position:
x_pose,y_pose,z_pose,yawMode:
headless=True/FalseVariants:
model='burger'/'waffle'for TurtleBot3
Best Practices
Always use
stop_gazebo()for cleanupUse error handling (
try/finally) for robust cleanupChoose headless vs GUI based on use case
Follow development workflow: Python → Gazebo → Hardware
Next Steps
Now that you understand the Gazebo launcher, proceed to:
ROS Deployment with Gazebo: Full integration with ROSNode, controllers, and state estimators
TurtleBot Gazebo Integration: Robot-specific examples
Crazyflie Gazebo Integration: Aerial robotics examples
Tip
The Gazebo launcher is designed for Jupyter notebook workflows. For production deployments, you may want to use native ROS2 launch files. However, for rapid prototyping and algorithm development, pykal.gazebo provides the fastest path from theory to simulation.