feat: Simplify drone controller to basic flight pattern, overhaul installation guide, and update related scripts.

This commit is contained in:
2026-01-07 21:02:31 +00:00
parent 760293d896
commit e266f75fca
9 changed files with 919 additions and 1407 deletions

View File

@@ -1,202 +1,184 @@
# ArduPilot + Gazebo Simulation
# ArduPilot + Gazebo Guide
## Prerequisites
## Overview
Before running, ensure your environment is set up:
```bash
source activate.sh
# or
source ~/.ardupilot_env && source ~/venv-ardupilot/bin/activate
```
## Quick Start (2 Terminals)
**Terminal 1 - Start Gazebo:**
```bash
./scripts/run_ardupilot_sim.sh runway
```
**Terminal 2 - Start Controller:**
```bash
./scripts/run_ardupilot_controller.sh
```
This project uses:
- **ArduPilot SITL**: Software-in-the-loop flight controller
- **Gazebo**: 3D physics simulation
- **MAVLink**: Communication protocol
## Architecture
```
┌─────────────────┐ ┌────────────────┐ ┌─────────────────┐
│ Gazebo │◄───►│ ArduPilot SITL │◄───►│ run_ardupilot.py
│ (Physics) │JSON │ (Flight Ctrl) │MAV │ (Your Logic)
└─────────────────┘ └────────────────┘ └─────────────────┘
┌─────────────┐ JSON (UDP 9002) ┌─────────────┐ MAVLink (TCP 5760) ┌─────────────┐
Gazebo │◄──────────────────────►│ ArduPilot │◄────────────────────────►│ Your
(Physics) sensor data │ SITL │ commands/telemetry │ Controller
└─────────────┘ └─────────────┘ └─────────────┘
```
**Communication:**
- Gazebo ↔ SITL: JSON sensor data over UDP (port 9002)
- SITL ↔ Your Code: MAVLink over TCP (port 5760)
## Quick Start
## World Options
### Step 1: Start Gazebo
```bash
./scripts/run_ardupilot_sim.sh runway # Default (outdoor runway)
./scripts/run_ardupilot_sim.sh warehouse # Indoor warehouse
./scripts/run_ardupilot_sim.sh gimbal # With camera gimbal
./scripts/run_ardupilot_sim.sh zephyr # Fixed-wing aircraft
./scripts/run_ardupilot_sim.sh custom # Your custom world
./scripts/run_ardupilot_sim.sh my_world # gazebo/worlds/my_world.sdf
cd ~/RDC_Simulation
./scripts/run_ardupilot_sim.sh runway
```
## GPS-Denied Mode
Wait until the drone appears in the 3D view.
The simulation runs in GPS-denied mode by default. The controller disables GPS checks and uses visual navigation.
For manual debugging with MAVProxy:
```bash
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console
# In MAVProxy console:
param set ARMING_CHECK 0
mode stabilize
arm throttle force
rc 3 1500 # Throttle up
```
## Controller Options
### Step 2: Start SITL
```bash
./scripts/run_ardupilot_controller.sh # Auto takeoff
./scripts/run_ardupilot_controller.sh --no-takeoff # Manual control
./scripts/run_ardupilot_controller.sh -a 10 # 10m altitude
```
## Files
| File | Purpose |
|------|---------|
| `scripts/run_ardupilot_sim.sh` | Gazebo launcher with GPU detection |
| `scripts/run_ardupilot_controller.sh` | SITL + Controller launcher |
| `scripts/run_ardupilot.py` | MAVLink interface script |
| `src/drone_controller.py` | Your landing algorithm |
## Environment Variables
The scripts automatically set these, but for manual runs:
```bash
# ArduPilot tools
export PATH=$PATH:~/ardupilot/Tools/autotest
# ArduPilot venv (has empy, pymavlink, etc.)
source ~/venv-ardupilot/bin/activate
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console
```
# Gazebo plugin paths
export GZ_SIM_SYSTEM_PLUGIN_PATH=~/ardupilot_gazebo/build:$GZ_SIM_SYSTEM_PLUGIN_PATH
export GZ_SIM_RESOURCE_PATH=~/ardupilot_gazebo/models:~/ardupilot_gazebo/worlds:$GZ_SIM_RESOURCE_PATH
You should see telemetry scrolling (NOT "No JSON sensor message").
### Step 3: Run Controller
```bash
source ~/venv-ardupilot/bin/activate
cd ~/RDC_Simulation
python scripts/run_ardupilot.py --pattern square
```
## Flight Patterns
```bash
# Square pattern (5m sides, 5m altitude)
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
python scripts/run_ardupilot.py --pattern hover
# Larger pattern at higher altitude
python scripts/run_ardupilot.py --pattern square --size 10 --altitude 15
```
## Controller Code
The flight controller is in `src/drone_controller.py`:
```python
from src.drone_controller import SimpleDroneController
drone = SimpleDroneController()
drone.connect()
drone.set_mode("GUIDED")
drone.arm()
drone.takeoff(5.0)
drone.fly_square(size=5, altitude=5)
drone.land()
```
### Key Methods
| 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 |
## Available Worlds
```bash
# Outdoor runway (default)
./scripts/run_ardupilot_sim.sh runway
# Indoor warehouse
./scripts/run_ardupilot_sim.sh warehouse
```
## MAVLink Connection
The controller connects via TCP port 5760:
```python
# config.py
MAVLINK = {
"connection_string": "tcp:127.0.0.1:5760",
}
```
## Troubleshooting
### "No JSON sensor message" or "No heartbeat"
### "No JSON sensor message received"
**Cause:** Gazebo isn't running or ArduPilot plugin isn't loaded.
SITL isn't receiving data from Gazebo.
**Fix:**
1. Start Gazebo first (Terminal 1)
2. Wait for world to fully load
3. Then start controller (Terminal 2)
1. Make sure Gazebo is running FIRST
2. Wait for the world to fully load
3. Then start SITL
### "sim_vehicle.py not found"
**Cause:** ArduPilot tools not in PATH.
### Drone won't arm
**Fix:**
```bash
source ~/.ardupilot_env
# or
export PATH=$PATH:~/ardupilot/Tools/autotest
# Check pre-arm status in MAVProxy
arm status
# Force arm
arm throttle force
```
### "empy not found" during waf build
**Cause:** Wrong Python environment.
### Wrong Python environment
**Fix:**
```bash
source ~/venv-ardupilot/bin/activate
pip install empy==3.3.4
cd ~/ardupilot
./waf configure --board sitl
./waf copter
which python3 # Should be ~/venv-ardupilot/bin/python3
```
### Drone doesn't respond to commands
**Possible causes:**
1. Not in GUIDED mode - check MAVProxy: `mode`
2. Not armed - run: `arm throttle force`
3. Pre-arm checks failing - run: `param set ARMING_CHECK 0`
### Drone immediately crashes in Gazebo
**Cause:** Usually a physics/plugin issue.
### Gazebo plugin not loading
**Fix:**
```bash
# Rebuild the ArduPilot Gazebo plugin
cd ~/ardupilot_gazebo/build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j4
# Check plugin exists
ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so
# Check paths
echo $GZ_SIM_SYSTEM_PLUGIN_PATH
# Should include: ~/ardupilot_gazebo/build
```
### Simulation is laggy
## Manual SITL Control
**Cause:** Software rendering or GPU not detected.
Use MAVProxy commands:
**Check:**
```bash
glxinfo | grep "OpenGL renderer"
# In SITL console
mode GUIDED
arm throttle force
takeoff 5
# Move to position
guided 10 0 -5
# Land
mode LAND
```
Should show your GPU name, not "llvmpipe" or "software".
## Useful Commands
**Fix for WSL:**
- Install NVIDIA drivers for WSL: https://developer.nvidia.com/cuda/wsl
- Ensure WSLg is enabled (Windows 11)
### MAVProxy console not opening
**Cause:** Missing `--console` flag or display issues.
**Fix:**
```bash
# Run directly
# List Gazebo topics
gz topic -l
# Check SITL status
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --map
# If display errors:
export DISPLAY=:0 # Linux/WSL with X server
```
## Advanced: Custom Takeoff
To customize the takeoff behavior, edit `scripts/run_ardupilot.py`:
```python
# Change altitude
TAKEOFF_ALTITUDE = 15 # meters
# Change timeout
CONNECTION_TIMEOUT = 60 # seconds
```
## Logs
ArduPilot logs are saved to:
```
~/ardupilot/logs/
~/ardupilot/build/sitl/logs/
```
View with:
```bash
mavlogdump.py --types GPS,ATT ~/ardupilot/logs/LASTLOG.BIN
# View camera (if available)
gz topic -e -t /camera
```

View File

@@ -1,79 +1,176 @@
# DroneController Guide
# Drone Controller Guide
## 3-Phase Mission
## Overview
```
SEARCH ──► COMMAND ──► LAND ──► COMPLETE
```
The drone controller (`src/drone_controller.py`) provides a simple interface for flying the drone in simulation.
| Phase | Action |
|-------|--------|
| SEARCH | Find QR code on rover |
| COMMAND | Send commands to rover |
| LAND | Land on rover |
## Usage
## Your Code
Edit `src/drone_controller.py`:
### Search Phase
```python
def calculate_search_maneuver(self, telemetry):
return (thrust, pitch, roll, yaw)
def detect_qr_code(self):
return {'data': 'qr_content', 'position': {...}} or None
```
### Command Phase
```python
def generate_rover_command(self, qr_data):
return {'type': 'move', 'x': 0, 'y': 0}
```
### Land Phase
```python
def calculate_landing_maneuver(self, telemetry, rover_telemetry):
return (thrust, pitch, roll, yaw)
```
## Telemetry
```python
telemetry = {
"altimeter": {"altitude": 5.0, "vertical_velocity": -0.1},
"velocity": {"x": 0, "y": 0, "z": 0},
"imu": {"orientation": {"roll": 0, "pitch": 0, "yaw": 0}},
"landing_pad": {"relative_x": 0.5, "relative_y": -0.2, "distance": 5.0}
}
```
## Control Output
| Value | Range | Effect |
|-------|-------|--------|
| thrust | ±1.0 | Vertical velocity |
| pitch | ±0.5 | Forward/back |
| roll | ±0.5 | Left/right |
| yaw | ±0.5 | Rotation |
## Configuration
Edit `config.py`:
```python
CONTROLLER = {
"Kp_z": 0.5,
"Kd_z": 0.3,
"Kp_xy": 0.3,
"Kd_xy": 0.2,
"rate": 50,
}
```
## Testing
### Command Line
```bash
./scripts/run_ardupilot_sim.sh runway
./scripts/run_ardupilot_controller.sh
source ~/venv-ardupilot/bin/activate
cd ~/RDC_Simulation
# Fly a square pattern
python scripts/run_ardupilot.py --pattern square
# Options
python scripts/run_ardupilot.py --help
```
### 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 |
### Examples
```bash
# Fly a 10m square at 8m altitude
python scripts/run_ardupilot.py --pattern square --size 10 --altitude 8
# Fly a circle with 5m radius
python scripts/run_ardupilot.py --pattern circle --size 5
# Just hover (useful for testing)
python scripts/run_ardupilot.py --pattern hover
```
## Python API
### Basic Usage
```python
from src.drone_controller import SimpleDroneController
# Create and connect
drone = SimpleDroneController()
if not drone.connect():
print("Connection failed")
exit(1)
# Takeoff
drone.set_mode("GUIDED")
drone.arm()
drone.takeoff(5.0)
# Fly
drone.fly_square(size=5, altitude=5)
# Land
drone.land()
```
### Class: SimpleDroneController
#### Connection
```python
drone = SimpleDroneController(connection_string="tcp:127.0.0.1:5760")
drone.connect(timeout=30) # Returns True/False
```
#### State
```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}
```
#### Commands
```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
```
#### Patterns
```python
drone.fly_square(size=5, altitude=5) # Square pattern
drone.fly_circle(radius=5, altitude=5) # Circle pattern
```
## Coordinate System
ArduPilot uses NED (North-East-Down):
- **X**: North (positive forward)
- **Y**: East (positive right)
- **Z**: Down (negative is up!)
```python
# Go 5m north, 3m east, at 10m altitude
drone.goto(5, 3, -10) # Z is negative for altitude
```
## Flight Modes
| Mode | Description |
|------|-------------|
| GUIDED | Accept external commands |
| LAND | Automatic landing |
| LOITER | Hold position |
| RTL | Return to launch |
| STABILIZE | Manual control |
## Sequence Diagram
```
┌─────────┐ ┌──────────┐ ┌─────────┐
│ Gazebo │ │ SITL │ │ Script │
└────┬────┘ └────┬─────┘ └────┬────┘
│ │ │
│ Physics data │ │
│ ◄──────────────│ │
│ │ │
│ Sensor JSON │ │
│ ───────────────► │
│ │ Connect │
│ │ ◄────────────────│
│ │ │
│ │ Set GUIDED │
│ │ ◄────────────────│
│ │ │
│ │ Arm │
│ │ ◄────────────────│
│ │ │
│ │ Takeoff │
│ │ ◄────────────────│
│ │ │
│ Motor commands │ │
│ ◄──────────────│ │
│ │ │
│ Drone moves │ │
│ │ │
```
## Troubleshooting
### Drone doesn't move
1. Check Gazebo is running
2. Check SITL shows telemetry (not "No JSON sensor message")
3. Check drone is armed
### Timeout waiting for altitude
- 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"
```

View File

@@ -1,230 +1,174 @@
# Installation
# Installation Guide
## Quick Install (Ubuntu/WSL)
## System Requirements
- **OS**: Ubuntu 22.04 or 24.04 (Windows users: use WSL2)
- **RAM**: 8GB minimum, 16GB recommended
- **Disk**: 10GB free space
- **GPU**: Any GPU with OpenGL 3.3+ support
## Quick Install (Ubuntu)
```bash
./setup/install_ubuntu.sh
./setup/install_ardupilot.sh
# Clone repository
git clone <repo-url> RDC_Simulation
cd RDC_Simulation
# Run installer (includes ArduPilot)
./setup/install_ubuntu.sh --with-ardupilot
# Reload shell
source ~/.bashrc
```
## What Gets Installed
This installs:
- Python 3 + virtual environment
- Gazebo Harmonic
- ArduPilot SITL
- ArduPilot Gazebo plugin
- MAVProxy
| Component | Location |
|-----------|----------|
| ArduPilot SITL | `~/ardupilot` |
| ArduPilot venv | `~/venv-ardupilot` |
| ardupilot_gazebo | `~/ardupilot_gazebo` |
| Gazebo Harmonic | System |
| ROS 2 | System |
| MAVProxy | `~/.local/bin` |
## Windows (WSL2)
## Platform-Specific Installation
### Ubuntu (Native)
```bash
./setup/install_ubuntu.sh --with-ardupilot
```
### Windows (via WSL2)
WSL2 (Windows Subsystem for Linux) is the recommended way to run this simulation on Windows.
#### Step 1: Install WSL2
### Step 1: Install WSL2
Open PowerShell as Administrator:
```powershell
wsl --install -d Ubuntu-24.04
```
Restart computer, then open Ubuntu from Start menu.
Restart your computer when prompted.
### Step 2: Install in WSL
#### Step 2: Configure WSL2 for GUI Apps
WSL2 on Windows 11 has built-in GUI support (WSLg). For Windows 10, you may need an X server:
```powershell
# Windows 11 - WSLg is automatic, no extra setup needed
# Windows 10 - Install VcXsrv or X410 from Microsoft Store
```
#### Step 3: Install in WSL
Open Ubuntu from Start menu:
```bash
# Clone the project (or copy from Windows)
git clone https://github.com/your-repo/RDC_Simulation.git
cd RDC_Simulation
# Update system
sudo apt update && sudo apt upgrade -y
# Run installation
./setup/install_ubuntu.sh
./setup/install_ardupilot.sh
# Clone and install
git clone <repo-url> ~/RDC_Simulation
cd ~/RDC_Simulation
./setup/install_ubuntu.sh --with-ardupilot
# Reload
source ~/.bashrc
```
#### Step 4: GPU Acceleration in WSL
### WSL2 Tips
For best performance with Gazebo:
```bash
# Check GPU availability
glxinfo | grep "OpenGL renderer"
# Should show your GPU, not "llvmpipe"
# If using NVIDIA, install NVIDIA GPU driver for WSL:
# https://developer.nvidia.com/cuda/wsl
```
#### WSL Tips
- **Access Windows files:** `/mnt/c/Users/YourName/`
- **Open file explorer:** `explorer.exe .`
- **Copy to clipboard:** `cat file | clip.exe`
- **Memory limit:** Create `%UserProfile%\.wslconfig`:
```ini
[wsl2]
memory=8GB
processors=4
```
### macOS
Gazebo is not officially supported on macOS. Use standalone mode:
- **GUI Apps**: Windows 11 has WSLg built-in. Gazebo should work automatically.
- **GPU**: Install NVIDIA WSL driver from [nvidia.com/wsl](https://developer.nvidia.com/cuda/wsl)
- **Access Windows files**: `/mnt/c/Users/YourName/`
- **Performance**: Clone repo to Linux filesystem (not `/mnt/c/`)
## macOS
macOS doesn't support Gazebo Harmonic natively. Options:
1. **Docker** (recommended): Use Linux container
2. **VM**: Use UTM or Parallels with Ubuntu
3. **Standalone**: Run PyBullet-only simulation
```bash
# Install basic dependencies
./setup/install_macos.sh
# Use standalone simulation
python standalone_simulation.py
```
For full simulation, use a Linux VM (UTM for Apple Silicon) or Docker.
### Arch Linux
## Arch Linux
```bash
./setup/install_arch.sh
./setup/install_arch.sh --with-ardupilot
source ~/.bashrc
```
ROS 2 and Gazebo are available via AUR - see script output for details.
## Dependencies
```bash
pip install -r requirements.txt
```
- pybullet
- numpy
- pillow
- opencv-python
- pymavlink
- pexpect
## Verify Installation
```bash
# Source the environment
source activate.sh
# Check ArduPilot tools
# Check ArduPilot
source ~/venv-ardupilot/bin/activate
python -c "import em; print('empy OK')"
sim_vehicle.py --help
which mavproxy.py
# Check Gazebo
gz sim --help
gz sim --version
ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so
```
## Environment Setup
## Post-Installation
After installation, always source the environment before running:
### Environment Setup
The installer creates `activate.sh` in the project root:
```bash
cd ~/RDC_Simulation
source activate.sh
# or
source ~/.bashrc # if ArduPilot was installed
```
The activation script sets up:
- ROS 2 environment
- ArduPilot Python venv (with empy, pymavlink, etc.)
- Gazebo resource paths
- ArduPilot tools path
This sources:
- ROS 2 (if installed)
- ArduPilot virtual environment
- Gazebo paths
### First Run
```bash
# Terminal 1: Start Gazebo
./scripts/run_ardupilot_sim.sh runway
# Terminal 2: Start SITL (after Gazebo loads)
source ~/venv-ardupilot/bin/activate
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console
# Terminal 3: Run controller
source ~/venv-ardupilot/bin/activate
cd ~/RDC_Simulation
python scripts/run_ardupilot.py --pattern square
```
## Troubleshooting
### "empy not found" or waf configure fails
### "empy not found"
The ArduPilot venv isn't activated. Run:
```bash
source ~/venv-ardupilot/bin/activate
pip install empy==3.3.4
```
### sim_vehicle.py not found
### "No JSON sensor message"
SITL isn't receiving data from Gazebo.
- Start Gazebo FIRST
- Wait for it to fully load
- Then start SITL
### "sim_vehicle.py not found"
```bash
source ~/.ardupilot_env
# or
# OR
export PATH=$PATH:~/ardupilot/Tools/autotest
```
### mavproxy.py not found
```bash
export PATH=$PATH:~/.local/bin
```
### pexpect error
```bash
pip install pexpect
```
### Gazebo slow / Software rendering
### Gazebo crashes / slow
```bash
# Check GPU
glxinfo | grep "OpenGL renderer"
```
Should show your GPU, not "llvmpipe". Install proper GPU drivers:
- **NVIDIA:** `sudo apt install nvidia-driver-XXX`
- **AMD:** `sudo apt install mesa-vulkan-drivers`
- **Intel:** Usually works out of box
- **WSL:** Install NVIDIA WSL driver from nvidia.com
### Wrong Python environment
If you see errors about missing packages that should be installed:
```bash
# Check which Python is being used
which python3
# Should be: ~/venv-ardupilot/bin/python3
# If not, activate the correct venv:
source ~/venv-ardupilot/bin/activate
# Try software rendering (slow but works)
export LIBGL_ALWAYS_SOFTWARE=1
gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf
```
### WSL: Display not working
```bash
# Check DISPLAY variable
echo $DISPLAY
# Check WSLg
ls /mnt/wslg
# For WSLg (Windows 11), should be auto-set
# For Windows 10 with X server:
export DISPLAY=:0
# If missing, update WSL
wsl --update
```
### WSL: Out of memory
Create `%UserProfile%\.wslconfig`:
```ini
[wsl2]
memory=8GB
swap=4GB
```
Then restart WSL: `wsl --shutdown`