Docs and Controllers Update
This commit is contained in:
171
docs/gazebo.md
171
docs/gazebo.md
@@ -1,13 +1,13 @@
|
||||
# Gazebo Simulation
|
||||
# Gazebo Simulation Guide
|
||||
|
||||
Running the GPS-denied drone simulation with Gazebo (Linux only).
|
||||
Running the GPS-denied drone simulation with Gazebo Ignition Fortress on Linux/WSL2.
|
||||
|
||||
## Quick Start (2 Terminals)
|
||||
## Quick Start (Two Terminals)
|
||||
|
||||
**Terminal 1 - Start Gazebo:**
|
||||
**Terminal 1 - Launch Gazebo + Bridge:**
|
||||
```bash
|
||||
source activate.sh
|
||||
gz sim gazebo/worlds/drone_landing.sdf
|
||||
ros2 launch gazebo/launch/drone_landing.launch.py
|
||||
```
|
||||
|
||||
**Terminal 2 - Run Controllers:**
|
||||
@@ -16,7 +16,9 @@ source activate.sh
|
||||
python run_gazebo.py --pattern circular --speed 0.3
|
||||
```
|
||||
|
||||
## Options
|
||||
Both the drone AND rover will move!
|
||||
|
||||
## Command Options
|
||||
|
||||
```bash
|
||||
python run_gazebo.py --help
|
||||
@@ -28,123 +30,130 @@ Options:
|
||||
--no-rover Disable rover controller
|
||||
```
|
||||
|
||||
## Spawning the Drone
|
||||
## How It Works
|
||||
|
||||
If the drone isn't in the world, spawn it:
|
||||
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`)
|
||||
|
||||
```bash
|
||||
gz service -s /world/drone_landing_world/create \
|
||||
--reqtype gz.msgs.EntityFactory \
|
||||
--reptype gz.msgs.Boolean \
|
||||
--req 'sdf_filename: "gazebo/models/drone/model.sdf", name: "drone"'
|
||||
```
|
||||
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 `run_gazebo.py` script provides the same sensor interface as PyBullet:
|
||||
The `GazeboBridge` provides the same sensor interface as PyBullet:
|
||||
|
||||
| Sensor | Source |
|
||||
|--------|--------|
|
||||
| IMU | Gazebo odometry |
|
||||
| IMU | Gazebo odometry orientation |
|
||||
| Altimeter | Gazebo Z position |
|
||||
| Velocity | Gazebo twist |
|
||||
| Camera | Gazebo camera sensor |
|
||||
| Camera | Gazebo camera sensor (if enabled) |
|
||||
| Landing Pad | Computed from relative position |
|
||||
|
||||
## Gazebo Topics
|
||||
## 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` | Velocity commands |
|
||||
| `/drone/cmd_vel` | `Twist` | Drone velocity commands |
|
||||
| `/rover/cmd_vel` | `Twist` | Rover velocity commands |
|
||||
| `/model/drone/odometry` | `Odometry` | Drone state |
|
||||
| `/drone/camera` | `Image` | Camera images |
|
||||
| `/drone/imu` | `IMU` | IMU sensor data |
|
||||
| `/clock` | `Clock` | Simulation time |
|
||||
|
||||
## Headless Mode
|
||||
## Headless Mode (WSL2 / No GPU)
|
||||
|
||||
Run without GUI:
|
||||
Run Gazebo without GUI:
|
||||
|
||||
```bash
|
||||
gz sim -s gazebo/worlds/drone_landing.sdf
|
||||
# Server mode only
|
||||
ign gazebo -s gazebo/worlds/drone_landing.sdf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ROS 2 Launch File (Advanced)
|
||||
|
||||
**Location:** `gazebo/launch/drone_landing.launch.py`
|
||||
|
||||
This launch file automates Gazebo startup for ROS 2 integration:
|
||||
1. Starts Gazebo with the world
|
||||
2. Spawns the drone automatically
|
||||
3. Starts `ros_gz_bridge` to connect topics
|
||||
|
||||
### Option 1: Direct Launch (Recommended)
|
||||
|
||||
Run the launch file directly with `ros2 launch`:
|
||||
|
||||
Then run the bridge manually:
|
||||
```bash
|
||||
source activate.sh
|
||||
ros2 launch gazebo/launch/drone_landing.launch.py
|
||||
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
|
||||
```
|
||||
|
||||
Then in another terminal, run just the controllers:
|
||||
```bash
|
||||
source activate.sh
|
||||
python controllers.py --pattern circular
|
||||
```
|
||||
## World File Details
|
||||
|
||||
### Option 2: Include in Your ROS 2 Package
|
||||
The world file `gazebo/worlds/drone_landing.sdf` includes:
|
||||
|
||||
If you have a ROS 2 package, copy the launch file and use:
|
||||
```bash
|
||||
ros2 launch my_drone_package drone_landing.launch.py
|
||||
```
|
||||
- **Drone** at (0, 0, 2) with:
|
||||
- `VelocityControl` plugin for movement
|
||||
- `OdometryPublisher` plugin for telemetry
|
||||
- IMU sensor
|
||||
|
||||
### Launch Arguments
|
||||
|
||||
| Argument | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `use_sim_time` | `true` | Use Gazebo clock |
|
||||
| `headless` | `false` | Run without GUI |
|
||||
|
||||
```bash
|
||||
ros2 launch gazebo/launch/drone_landing.launch.py headless:=true
|
||||
```
|
||||
|
||||
### Topics Bridged by Launch File
|
||||
|
||||
| ROS 2 Topic | Description |
|
||||
|-------------|-------------|
|
||||
| `/drone/cmd_vel` | Velocity commands |
|
||||
| `/model/drone/odometry` | Drone state |
|
||||
| `/drone/imu` | IMU sensor |
|
||||
| `/clock` | Simulation time |
|
||||
|
||||
---
|
||||
- **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
|
||||
```
|
||||
|
||||
### Drone falls immediately
|
||||
### "Cannot connect to display" (WSL2)
|
||||
|
||||
Enable the velocity controller:
|
||||
Use headless mode:
|
||||
```bash
|
||||
gz topic -t /drone/enable -m gz.msgs.Boolean -p 'data: true'
|
||||
ign gazebo -s gazebo/worlds/drone_landing.sdf
|
||||
```
|
||||
|
||||
### "Cannot connect to display"
|
||||
|
||||
Use headless mode or WSLg:
|
||||
Or ensure WSLg is working:
|
||||
```bash
|
||||
# Headless
|
||||
gz sim -s gazebo/worlds/drone_landing.sdf
|
||||
|
||||
# Or ensure DISPLAY is set
|
||||
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 |
|
||||
|
||||
Reference in New Issue
Block a user