# 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:** ```bash source activate.sh ros2 launch gazebo/launch/drone_landing.launch.py ``` **Terminal 2 - Run Controllers:** ```bash source activate.sh python run_gazebo.py --pattern circular --speed 0.3 ``` Both the drone AND rover will move! ## Command Options ```bash 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 1. **Gazebo** runs the physics simulation with: - Drone with `VelocityControl` plugin (responds to `/drone/cmd_vel`) - Rover with `VelocityControl` plugin (responds to `/rover/cmd_vel`) 2. **ros_gz_bridge** connects Gazebo topics to ROS 2 3. **run_gazebo.py** starts: - `GazeboBridge` - converts ROS topics to telemetry format - `DroneController` - your landing algorithm - `RoverController` - 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: ```bash # Server mode only ign gazebo -s gazebo/worlds/drone_landing.sdf ``` Then run the bridge manually: ```bash 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: - `VelocityControl` plugin for movement - `OdometryPublisher` plugin for telemetry - IMU sensor - **Landing Pad (Rover)** at (0, 0, 0.15) with: - `VelocityControl` plugin for movement - Visual H marker ## Troubleshooting ### Drone falls immediately The drone should hover with the controller running. If it falls: 1. Check that `run_gazebo.py` is running 2. Verify the bridge shows "Passing message from ROS" 3. Check `/drone/cmd_vel` topic: `ros2 topic echo /drone/cmd_vel` ### Rover doesn't move 1. Check that `/rover/cmd_vel` is bridged 2. Verify RoverController is publishing: `ros2 topic echo /rover/cmd_vel` ### Model not found Set the model path: ```bash 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: ```bash ign gazebo -s gazebo/worlds/drone_landing.sdf ``` Or ensure WSLg is working: ```bash export DISPLAY=:0 ``` ### Plugin not found For Ignition Fortress, plugins use `libignition-gazebo-*-system.so` naming. Check available plugins: ```bash ls /usr/lib/x86_64-linux-gnu/ign-gazebo-6/plugins/ ``` ## Launch File Options ```bash ros2 launch gazebo/launch/drone_landing.launch.py use_sim_time:=true ``` | Argument | Default | Description | |----------|---------|-------------| | `use_sim_time` | `true` | Use Gazebo clock |