docs: Improve quick start, ArduPilot setup, and troubleshooting, and add GPS mode option.
This commit is contained in:
@@ -1,42 +1,39 @@
|
||||
# ArduPilot + Gazebo Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This project uses:
|
||||
- **ArduPilot SITL**: Software-in-the-loop flight controller
|
||||
- **Gazebo**: 3D physics simulation
|
||||
- **MAVLink**: Communication protocol
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────┐ JSON (UDP 9002) ┌─────────────┐ MAVLink (TCP 5760) ┌─────────────┐
|
||||
│ Gazebo │◄──────────────────────►│ ArduPilot │◄────────────────────────►│ Your │
|
||||
│ (Physics) │ sensor data │ SITL │ commands/telemetry │ Controller │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
┌─────────────────┐ UDP 9002 ┌─────────────────┐ TCP 5760 ┌─────────────────┐
|
||||
│ │ JSON sensor data │ │ MAVLink cmds │ │
|
||||
│ Gazebo │◄─────────────────────►│ ArduPilot SITL │◄───────────────────►│ Controller │
|
||||
│ (Physics) │ motor commands │ (ArduCopter) │ telemetry │ (run_ardupilot) │
|
||||
│ │ │ │ │ │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
## Quick Start (3 Terminals)
|
||||
|
||||
### Step 1: Start Gazebo
|
||||
### Terminal 1: Start Gazebo FIRST
|
||||
|
||||
```bash
|
||||
cd ~/RDC_Simulation
|
||||
./scripts/run_ardupilot_sim.sh runway
|
||||
```
|
||||
|
||||
Wait until the drone appears in the 3D view.
|
||||
Wait until the drone appears in the 3D view!
|
||||
|
||||
### Step 2: Start SITL
|
||||
### Terminal 2: Start ArduCopter SITL
|
||||
|
||||
```bash
|
||||
source ~/venv-ardupilot/bin/activate
|
||||
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console
|
||||
```
|
||||
|
||||
You should see telemetry scrolling (NOT "No JSON sensor message").
|
||||
You should see:
|
||||
- "JSON received: timestamp, imu, position..." ✅
|
||||
- NOT "No JSON sensor message received" ❌
|
||||
|
||||
### Step 3: Run Controller
|
||||
### Terminal 3: Run Controller
|
||||
|
||||
```bash
|
||||
source ~/venv-ardupilot/bin/activate
|
||||
@@ -53,44 +50,72 @@ python scripts/run_ardupilot.py --pattern square --size 5 --altitude 5
|
||||
# Circle pattern (5m radius)
|
||||
python scripts/run_ardupilot.py --pattern circle --size 5
|
||||
|
||||
# Hover in place for testing
|
||||
# Hover in place
|
||||
python scripts/run_ardupilot.py --pattern hover
|
||||
|
||||
# Larger pattern at higher altitude
|
||||
python scripts/run_ardupilot.py --pattern square --size 10 --altitude 15
|
||||
# GPS mode (instead of GPS-denied)
|
||||
python scripts/run_ardupilot.py --pattern square --gps
|
||||
```
|
||||
|
||||
## Controller Code
|
||||
|
||||
The flight controller is in `src/drone_controller.py`:
|
||||
|
||||
```python
|
||||
from src.drone_controller import DroneController
|
||||
|
||||
drone = DroneController()
|
||||
drone.connect()
|
||||
drone.set_mode("GUIDED")
|
||||
|
||||
# GPS-denied setup
|
||||
drone.setup_gps_denied()
|
||||
drone.set_mode("GUIDED_NOGPS")
|
||||
|
||||
# Or GPS mode
|
||||
# drone.set_mode("GUIDED")
|
||||
|
||||
drone.arm()
|
||||
drone.takeoff(5.0)
|
||||
drone.fly_square(size=5, altitude=5)
|
||||
drone.land()
|
||||
```
|
||||
|
||||
### Key Methods
|
||||
## ArduCopter Flight Modes
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `connect()` | Connect to SITL via MAVLink |
|
||||
| `set_mode(mode)` | Set flight mode (GUIDED, LAND, etc.) |
|
||||
| `arm()` | Arm motors (force arm) |
|
||||
| `takeoff(alt)` | Take off to altitude |
|
||||
| `goto(x, y, z)` | Go to position (NED frame) |
|
||||
| `fly_to_and_wait(x, y, alt)` | Go to position and wait |
|
||||
| `fly_square(size, alt)` | Fly square pattern |
|
||||
| `fly_circle(radius, alt)` | Fly circle pattern |
|
||||
| `land()` | Land the drone |
|
||||
| Mode | ID | Description |
|
||||
|------|-----|-------------|
|
||||
| STABILIZE | 0 | Manual, self-leveling |
|
||||
| ALT_HOLD | 2 | Hold altitude |
|
||||
| GUIDED | 4 | Waypoint commands (GPS required) |
|
||||
| LOITER | 5 | Hold position (GPS required) |
|
||||
| RTL | 6 | Return to launch |
|
||||
| LAND | 9 | Automatic landing |
|
||||
| **GUIDED_NOGPS** | 20 | Commands without GPS |
|
||||
|
||||
## Available Worlds
|
||||
## MAVProxy Commands
|
||||
|
||||
In the SITL console, you can type:
|
||||
|
||||
```bash
|
||||
# Check status
|
||||
status
|
||||
|
||||
# Change mode
|
||||
mode GUIDED
|
||||
mode GUIDED_NOGPS
|
||||
|
||||
# Arm
|
||||
arm throttle force
|
||||
|
||||
# Takeoff (in GUIDED mode)
|
||||
takeoff 5
|
||||
|
||||
# Land
|
||||
mode LAND
|
||||
|
||||
# Set parameter
|
||||
param set ARMING_CHECK 0
|
||||
```
|
||||
|
||||
## Gazebo Worlds
|
||||
|
||||
```bash
|
||||
# Outdoor runway (default)
|
||||
@@ -102,83 +127,73 @@ drone.land()
|
||||
|
||||
## MAVLink Connection
|
||||
|
||||
The controller connects via TCP port 5760:
|
||||
Default: `tcp:127.0.0.1:5760`
|
||||
|
||||
```python
|
||||
# config.py
|
||||
MAVLINK = {
|
||||
"connection_string": "tcp:127.0.0.1:5760",
|
||||
}
|
||||
```
|
||||
Port map:
|
||||
- **5760**: Primary MAVLink (SERIAL0)
|
||||
- **5762**: Secondary (SERIAL1)
|
||||
- **5763**: Tertiary (SERIAL2)
|
||||
- **14550**: MAVProxy GCS output (UDP)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No JSON sensor message received"
|
||||
|
||||
SITL isn't receiving data from Gazebo.
|
||||
Gazebo isn't sending data.
|
||||
|
||||
**Fix:**
|
||||
1. Make sure Gazebo is running FIRST
|
||||
2. Wait for the world to fully load
|
||||
2. Wait for world to fully load
|
||||
3. Then start SITL
|
||||
|
||||
### Drone won't arm
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check pre-arm status in MAVProxy
|
||||
arm status
|
||||
|
||||
# Force arm
|
||||
# In MAVProxy console
|
||||
arm throttle force
|
||||
|
||||
# Or set in your code
|
||||
drone.set_param("ARMING_CHECK", 0)
|
||||
```
|
||||
|
||||
### Wrong Python environment
|
||||
### Wrong vehicle type (ArduPlane)
|
||||
|
||||
Mode list shows FBWA, FBWB, QSTABILIZE instead of GUIDED_NOGPS, ALT_HOLD.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
source ~/venv-ardupilot/bin/activate
|
||||
which python3 # Should be ~/venv-ardupilot/bin/python3
|
||||
pkill -9 -f sim_vehicle
|
||||
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --wipe-eeprom
|
||||
```
|
||||
|
||||
### Mode not changing
|
||||
|
||||
The controller hardcodes mode IDs for ArduCopter. If using ArduPlane, modes will differ.
|
||||
|
||||
### Gazebo plugin not loading
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Check plugin exists
|
||||
ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so
|
||||
|
||||
# Check paths
|
||||
# Check environment
|
||||
echo $GZ_SIM_SYSTEM_PLUGIN_PATH
|
||||
# Should include: ~/ardupilot_gazebo/build
|
||||
```
|
||||
|
||||
## Manual SITL Control
|
||||
|
||||
Use MAVProxy commands:
|
||||
|
||||
```bash
|
||||
# In SITL console
|
||||
mode GUIDED
|
||||
arm throttle force
|
||||
takeoff 5
|
||||
|
||||
# Move to position
|
||||
guided 10 0 -5
|
||||
|
||||
# Land
|
||||
mode LAND
|
||||
```
|
||||
|
||||
## Useful Commands
|
||||
## Useful Debug Commands
|
||||
|
||||
```bash
|
||||
# List Gazebo topics
|
||||
gz topic -l
|
||||
|
||||
# Check SITL status
|
||||
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --map
|
||||
# Echo a topic
|
||||
gz topic -e -t /model/iris_with_gimbal/pose
|
||||
|
||||
# View camera (if available)
|
||||
gz topic -e -t /camera
|
||||
# Check SITL processes
|
||||
ps aux | grep ardupilot
|
||||
|
||||
# Check port usage
|
||||
lsof -i :5760
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user