4.0 KiB
Gazebo Simulation Guide
Running the GPS-denied drone simulation with Gazebo Ignition Fortress on Linux/WSL2.
Quick Start (Two Terminals)
Terminal 1 - Launch Gazebo + Bridge:
source activate.sh
ros2 launch gazebo/launch/drone_landing.launch.py
Terminal 2 - Run Controllers:
source activate.sh
python run_gazebo.py --pattern circular --speed 0.3
Both the drone AND rover will move!
Command Options
python run_gazebo.py --help
Options:
--pattern stationary, linear, circular, square, random
--speed, -s Rover speed in m/s (default: 0.5)
--amplitude, -a Movement amplitude (default: 2.0)
--no-rover Disable rover controller
How It Works
-
Gazebo runs the physics simulation with:
- Drone with
VelocityControlplugin (responds to/drone/cmd_vel) - Rover with
VelocityControlplugin (responds to/rover/cmd_vel)
- Drone with
-
ros_gz_bridge connects Gazebo topics to ROS 2
-
run_gazebo.py starts:
GazeboBridge- converts ROS topics to telemetry formatDroneController- your landing algorithmRoverController- moves the landing pad
GPS-Denied Sensors
The GazeboBridge provides the same sensor interface as PyBullet:
| Sensor | Source |
|---|---|
| IMU | Gazebo odometry orientation |
| Altimeter | Gazebo Z position |
| Velocity | Gazebo twist |
| Camera | Gazebo camera sensor (if enabled) |
| Landing Pad | Computed from relative position |
Topics
ROS 2 Topics (your code uses these)
| Topic | Type | Direction |
|---|---|---|
/cmd_vel |
Twist |
Input (from DroneController) |
/drone/telemetry |
String |
Output (to DroneController) |
/rover/telemetry |
String |
Output (rover position) |
Gazebo Topics (bridged automatically)
| Topic | Type | Description |
|---|---|---|
/drone/cmd_vel |
Twist |
Drone velocity commands |
/rover/cmd_vel |
Twist |
Rover velocity commands |
/model/drone/odometry |
Odometry |
Drone state |
/drone/imu |
IMU |
IMU sensor data |
/clock |
Clock |
Simulation time |
Headless Mode (WSL2 / No GPU)
Run Gazebo without GUI:
# Server mode only
ign gazebo -s gazebo/worlds/drone_landing.sdf
Then run the bridge manually:
ros2 run ros_gz_bridge parameter_bridge \
/drone/cmd_vel@geometry_msgs/msg/Twist]ignition.msgs.Twist \
/rover/cmd_vel@geometry_msgs/msg/Twist]ignition.msgs.Twist \
/model/drone/odometry@nav_msgs/msg/Odometry[ignition.msgs.Odometry
World File Details
The world file gazebo/worlds/drone_landing.sdf includes:
-
Drone at (0, 0, 2) with:
VelocityControlplugin for movementOdometryPublisherplugin for telemetry- IMU sensor
-
Landing Pad (Rover) at (0, 0, 0.15) with:
VelocityControlplugin for movement- Visual H marker
Troubleshooting
Drone falls immediately
The drone should hover with the controller running. If it falls:
- Check that
run_gazebo.pyis running - Verify the bridge shows "Passing message from ROS"
- Check
/drone/cmd_veltopic:ros2 topic echo /drone/cmd_vel
Rover doesn't move
- Check that
/rover/cmd_velis bridged - Verify RoverController is publishing:
ros2 topic echo /rover/cmd_vel
Model not found
Set the model path:
export GZ_SIM_RESOURCE_PATH=$PWD/gazebo/models:$GZ_SIM_RESOURCE_PATH
export IGN_GAZEBO_RESOURCE_PATH=$PWD/gazebo/models:$IGN_GAZEBO_RESOURCE_PATH
"Cannot connect to display" (WSL2)
Use headless mode:
ign gazebo -s gazebo/worlds/drone_landing.sdf
Or ensure WSLg is working:
export DISPLAY=:0
Plugin not found
For Ignition Fortress, plugins use libignition-gazebo-*-system.so naming.
Check available plugins:
ls /usr/lib/x86_64-linux-gnu/ign-gazebo-6/plugins/
Launch File Options
ros2 launch gazebo/launch/drone_landing.launch.py use_sim_time:=true
| Argument | Default | Description |
|---|---|---|
use_sim_time |
true |
Use Gazebo clock |