docs: Improve quick start, ArduPilot setup, and troubleshooting, and add GPS mode option.
This commit is contained in:
@@ -2,43 +2,45 @@
|
||||
|
||||
## Overview
|
||||
|
||||
The drone controller (`src/drone_controller.py`) provides a simple interface for flying the drone in simulation.
|
||||
The `DroneController` class (`src/drone_controller.py`) provides a simple interface for controlling the drone in ArduPilot SITL simulation.
|
||||
|
||||
## Usage
|
||||
|
||||
### Command Line
|
||||
## Command Line Usage
|
||||
|
||||
```bash
|
||||
# Activate environment first
|
||||
source ~/venv-ardupilot/bin/activate
|
||||
cd ~/RDC_Simulation
|
||||
|
||||
# Fly a square pattern
|
||||
# Run flight patterns
|
||||
python scripts/run_ardupilot.py --pattern square
|
||||
|
||||
# Options
|
||||
python scripts/run_ardupilot.py --help
|
||||
python scripts/run_ardupilot.py --pattern circle
|
||||
python scripts/run_ardupilot.py --pattern hover
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `--pattern` | square | Flight pattern: square, circle, hover |
|
||||
| `--altitude` | 5 | Flight altitude in meters |
|
||||
| `--size` | 5 | Pattern size (side length or radius) |
|
||||
| `--connection` | tcp:127.0.0.1:5760 | MAVLink connection string |
|
||||
| `--pattern, -p` | square | Flight pattern: square, circle, hover |
|
||||
| `--altitude, -a` | 5.0 | Flight altitude in meters |
|
||||
| `--size, -s` | 5.0 | Pattern size (side length or radius) |
|
||||
| `--connection, -c` | tcp:127.0.0.1:5760 | MAVLink connection string |
|
||||
| `--gps` | false | Use GPS mode (default is GPS-denied) |
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Fly a 10m square at 8m altitude
|
||||
python scripts/run_ardupilot.py --pattern square --size 10 --altitude 8
|
||||
# Large square at high altitude
|
||||
python scripts/run_ardupilot.py --pattern square --size 10 --altitude 15
|
||||
|
||||
# Fly a circle with 5m radius
|
||||
python scripts/run_ardupilot.py --pattern circle --size 5
|
||||
# Small circle
|
||||
python scripts/run_ardupilot.py --pattern circle --size 3 --altitude 5
|
||||
|
||||
# Just hover (useful for testing)
|
||||
# Hover for testing
|
||||
python scripts/run_ardupilot.py --pattern hover
|
||||
|
||||
# GPS mode (instead of GPS-denied)
|
||||
python scripts/run_ardupilot.py --pattern square --gps
|
||||
```
|
||||
|
||||
## Python API
|
||||
@@ -54,123 +56,119 @@ if not drone.connect():
|
||||
print("Connection failed")
|
||||
exit(1)
|
||||
|
||||
# Takeoff
|
||||
drone.set_mode("GUIDED")
|
||||
# Setup for GPS-denied (disables arming checks)
|
||||
drone.setup_gps_denied()
|
||||
|
||||
# Set mode and arm
|
||||
drone.set_mode("GUIDED_NOGPS") # or "GUIDED" for GPS mode
|
||||
drone.arm()
|
||||
|
||||
# Takeoff
|
||||
drone.takeoff(5.0)
|
||||
|
||||
# Fly
|
||||
# Fly a pattern
|
||||
drone.fly_square(size=5, altitude=5)
|
||||
|
||||
# Land
|
||||
drone.land()
|
||||
```
|
||||
|
||||
### Class: DroneController
|
||||
### DroneController Class
|
||||
|
||||
#### Connection
|
||||
#### Constructor
|
||||
|
||||
```python
|
||||
drone = DroneController(connection_string="tcp:127.0.0.1:5760")
|
||||
drone.connect(timeout=30) # Returns True/False
|
||||
```
|
||||
|
||||
#### State
|
||||
#### Properties
|
||||
|
||||
```python
|
||||
drone.armed # bool: Is the drone armed?
|
||||
drone.mode # str: Current flight mode
|
||||
drone.altitude # float: Current altitude (m)
|
||||
drone.position # dict: {"x": float, "y": float, "z": float}
|
||||
```
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `armed` | bool | Is the drone armed? |
|
||||
| `mode` | str | Current flight mode |
|
||||
| `altitude` | float | Current altitude (meters) |
|
||||
| `position` | dict | Current position {"x", "y", "z"} |
|
||||
| `vehicle_type` | str | "copter" or "plane" |
|
||||
|
||||
#### Commands
|
||||
#### Methods
|
||||
|
||||
```python
|
||||
drone.set_mode("GUIDED") # Set flight mode
|
||||
drone.arm() # Arm motors (force arm)
|
||||
drone.takeoff(5.0) # Takeoff to altitude
|
||||
drone.goto(x, y, z) # Go to position (NED frame)
|
||||
drone.fly_to_and_wait(x, y, alt) # Go and wait until reached
|
||||
drone.land() # Land
|
||||
```
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `connect(timeout=30)` | Connect to SITL, returns True/False |
|
||||
| `set_mode(mode)` | Set flight mode (GUIDED, GUIDED_NOGPS, LAND, etc.) |
|
||||
| `setup_gps_denied()` | Configure for GPS-denied operation |
|
||||
| `arm()` | Arm motors (force arm) |
|
||||
| `takeoff(altitude)` | 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 until reached |
|
||||
| `fly_square(size, alt)` | Fly square pattern |
|
||||
| `fly_circle(radius, alt)` | Fly circle pattern |
|
||||
| `land()` | Land the drone |
|
||||
| `set_param(name, value)` | Set an ArduPilot parameter |
|
||||
|
||||
#### Patterns
|
||||
### Flight Modes (ArduCopter)
|
||||
|
||||
```python
|
||||
drone.fly_square(size=5, altitude=5) # Square pattern
|
||||
drone.fly_circle(radius=5, altitude=5) # Circle pattern
|
||||
```
|
||||
| Mode | ID | Description |
|
||||
|------|-----|-------------|
|
||||
| STABILIZE | 0 | Manual control, self-leveling |
|
||||
| ALT_HOLD | 2 | Hold altitude, manual position |
|
||||
| GUIDED | 4 | Accept waypoint commands (needs GPS) |
|
||||
| LOITER | 5 | Hold position |
|
||||
| RTL | 6 | Return to launch |
|
||||
| LAND | 9 | Automatic landing |
|
||||
| GUIDED_NOGPS | 20 | Accept commands without GPS |
|
||||
|
||||
## Coordinate System
|
||||
|
||||
ArduPilot uses NED (North-East-Down):
|
||||
- **X**: North (positive forward)
|
||||
- **Y**: East (positive right)
|
||||
- **Z**: Down (negative is up!)
|
||||
- **X (North)**: Positive = forward
|
||||
- **Y (East)**: Positive = right
|
||||
- **Z (Down)**: Positive = down, **negative = up!**
|
||||
|
||||
```python
|
||||
# Go 5m north, 3m east, at 10m altitude
|
||||
drone.goto(5, 3, -10) # Z is negative for altitude
|
||||
# Go 5m forward, 3m right, at 10m altitude
|
||||
drone.goto(5, 3, -10) # Z is negative for altitude!
|
||||
```
|
||||
|
||||
## Flight Modes
|
||||
## GPS-Denied Mode
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| GUIDED | Accept external commands |
|
||||
| LAND | Automatic landing |
|
||||
| LOITER | Hold position |
|
||||
| RTL | Return to launch |
|
||||
| STABILIZE | Manual control |
|
||||
The controller defaults to GPS-denied mode, which:
|
||||
|
||||
## Sequence Diagram
|
||||
1. Disables arming checks (`ARMING_CHECK=0`)
|
||||
2. Uses `GUIDED_NOGPS` mode (ID 20)
|
||||
3. Relies on barometer for altitude
|
||||
|
||||
```
|
||||
┌─────────┐ ┌──────────┐ ┌─────────┐
|
||||
│ Gazebo │ │ SITL │ │ Script │
|
||||
└────┬────┘ └────┬─────┘ └────┬────┘
|
||||
│ │ │
|
||||
│ Physics data │ │
|
||||
│ ◄──────────────│ │
|
||||
│ │ │
|
||||
│ Sensor JSON │ │
|
||||
│ ───────────────► │
|
||||
│ │ Connect │
|
||||
│ │ ◄────────────────│
|
||||
│ │ │
|
||||
│ │ Set GUIDED │
|
||||
│ │ ◄────────────────│
|
||||
│ │ │
|
||||
│ │ Arm │
|
||||
│ │ ◄────────────────│
|
||||
│ │ │
|
||||
│ │ Takeoff │
|
||||
│ │ ◄────────────────│
|
||||
│ │ │
|
||||
│ Motor commands │ │
|
||||
│ ◄──────────────│ │
|
||||
│ │ │
|
||||
│ Drone moves │ │
|
||||
│ │ │
|
||||
To use GPS mode instead:
|
||||
```bash
|
||||
python scripts/run_ardupilot.py --pattern square --gps
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Drone doesn't move
|
||||
### Drone won't arm
|
||||
|
||||
1. Check Gazebo is running
|
||||
2. Check SITL shows telemetry (not "No JSON sensor message")
|
||||
3. Check drone is armed
|
||||
1. Check MAVProxy console for pre-arm errors
|
||||
2. Try force arming in MAVProxy: `arm throttle force`
|
||||
3. Make sure SITL is connected to Gazebo (shows "JSON received:")
|
||||
|
||||
### Timeout waiting for altitude
|
||||
### Mode not changing
|
||||
|
||||
- Increase takeoff timeout
|
||||
- Check for pre-arm failures in SITL console
|
||||
|
||||
### Connection refused
|
||||
|
||||
```bash
|
||||
# Check SITL is running
|
||||
nc -z 127.0.0.1 5760 && echo "SITL is ready" || echo "SITL not running"
|
||||
Check the current mode in MAVProxy console. If stuck, try:
|
||||
```
|
||||
mode GUIDED
|
||||
```
|
||||
|
||||
### Drone not moving
|
||||
|
||||
1. Make sure you're in GUIDED or GUIDED_NOGPS mode
|
||||
2. Check altitude - drone needs to be off ground
|
||||
3. Verify Gazebo is running and responsive
|
||||
|
||||
### Wrong vehicle type detected
|
||||
|
||||
If you see ArduPlane modes (FBWA, FBWB), restart SITL:
|
||||
```bash
|
||||
pkill -9 -f sim_vehicle
|
||||
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --wipe-eeprom
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user