docs: Improve quick start, ArduPilot setup, and troubleshooting, and add GPS mode option.

This commit is contained in:
2026-01-07 21:27:34 +00:00
parent 202465af99
commit 3251fc7b27
6 changed files with 350 additions and 294 deletions

View File

@@ -1,6 +1,6 @@
# RDC Simulation # RDC Simulation
GPS-denied drone landing simulation using ArduPilot and Gazebo. **GPS-Denied Drone Landing Simulation** using ArduPilot and Gazebo.
## Quick Start ## Quick Start
@@ -23,25 +23,23 @@ cd RDC_Simulation
source ~/.bashrc source ~/.bashrc
``` ```
### Run the Simulation ### Run the Simulation (3 Terminals)
You need **3 terminals**: **Terminal 1 - Start Gazebo FIRST:**
**Terminal 1 - Gazebo:**
```bash ```bash
cd ~/RDC_Simulation cd ~/RDC_Simulation
./scripts/run_ardupilot_sim.sh runway ./scripts/run_ardupilot_sim.sh runway
# Wait until the drone appears in Gazebo # WAIT until you see the drone in Gazebo!
``` ```
**Terminal 2 - SITL:** **Terminal 2 - Start ArduCopter SITL:**
```bash ```bash
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console
# Wait for "Waiting for connection" then telemetry # Wait for "JSON received:" messages (shows Gazebo is connected)
``` ```
**Terminal 3 - Controller:** **Terminal 3 - Run Controller:**
```bash ```bash
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
cd ~/RDC_Simulation cd ~/RDC_Simulation
@@ -62,6 +60,9 @@ python scripts/run_ardupilot.py --pattern hover
# Custom altitude # Custom altitude
python scripts/run_ardupilot.py --pattern square --altitude 10 python scripts/run_ardupilot.py --pattern square --altitude 10
# Use GPS mode instead of GPS-denied
python scripts/run_ardupilot.py --pattern square --gps
``` ```
## Project Structure ## Project Structure
@@ -71,13 +72,13 @@ RDC_Simulation/
├── scripts/ ├── scripts/
│ ├── run_ardupilot_sim.sh # Launch Gazebo │ ├── run_ardupilot_sim.sh # Launch Gazebo
│ ├── run_ardupilot_controller.sh # Launch SITL + Controller │ ├── run_ardupilot_controller.sh # Launch SITL + Controller
│ └── run_ardupilot.py # Flight controller │ └── run_ardupilot.py # Flight controller entry point
├── src/ ├── src/
│ ├── drone_controller.py # Simple drone controller │ ├── drone_controller.py # Main drone controller class
│ ├── rover_controller.py # Moving landing pad (ROS 2) │ ├── rover_controller.py # Moving landing pad (ROS 2)
│ └── camera_viewer.py # Camera viewer (ROS 2) │ └── camera_viewer.py # Camera viewer (ROS 2)
├── setup/ ├── setup/
│ ├── install_ubuntu.sh # Ubuntu installer │ ├── install_ubuntu.sh # Ubuntu/WSL installer
│ ├── install_ardupilot.sh # ArduPilot installer │ ├── install_ardupilot.sh # ArduPilot installer
│ └── install_arch.sh # Arch Linux installer │ └── install_arch.sh # Arch Linux installer
├── gazebo/ ├── gazebo/
@@ -92,29 +93,40 @@ RDC_Simulation/
Gazebo isn't sending data to SITL. Gazebo isn't sending data to SITL.
- **Fix**: Start Gazebo FIRST, wait for it to fully load, THEN start SITL. - **Fix**: Start Gazebo FIRST, wait for it to fully load, THEN start SITL.
### "empy not found" ### "empy not found" or wrong Python
Wrong Python environment. Wrong virtual environment.
- **Fix**: `source ~/venv-ardupilot/bin/activate` ```bash
source ~/venv-ardupilot/bin/activate
pip install empy==3.3.4
```
### "sim_vehicle.py not found" ### "sim_vehicle.py not found"
ArduPilot tools not in PATH. ArduPilot tools not in PATH.
- **Fix**: `source ~/.ardupilot_env` ```bash
source ~/.ardupilot_env
```
### Can't arm ### Drone won't arm
The drone won't arm or takeoff. - Make sure SITL is in STABILIZE or GUIDED mode
- **Fix**: Make sure you're in GUIDED mode and Gazebo is running. - Check for pre-arm errors in MAVProxy console
- Check console for pre-arm errors. - Try in MAVProxy: `arm throttle force`
### Gazebo is slow ### Wrong vehicle type (ArduPlane instead of ArduCopter)
- Try a lighter world: `./scripts/run_ardupilot_sim.sh runway` You see modes like FBWA, FBWB, QSTABILIZE.
- Check GPU: `glxinfo | grep "OpenGL renderer"` ```bash
# Kill old processes
pkill -9 -f sim_vehicle
# Start with explicit ArduCopter
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --wipe-eeprom
```
## Documentation ## Documentation
- [Installation Guide](docs/installation.md) - [Installation Guide](docs/installation.md)
- [ArduPilot Guide](docs/ardupilot.md) - [ArduPilot Guide](docs/ardupilot.md)
- [Drone Controller Guide](docs/drone_guide.md)
- [Architecture](docs/architecture.md) - [Architecture](docs/architecture.md)
- [Gazebo Worlds](docs/gazebo_worlds.md)
## License ## License

View File

@@ -1,42 +1,39 @@
# ArduPilot + Gazebo Guide # ArduPilot + Gazebo Guide
## Overview
This project uses:
- **ArduPilot SITL**: Software-in-the-loop flight controller
- **Gazebo**: 3D physics simulation
- **MAVLink**: Communication protocol
## Architecture ## Architecture
``` ```
┌─────────────┐ JSON (UDP 9002) ┌─────────────┐ MAVLink (TCP 5760) ┌─────────────┐ ┌───────────────── UDP 9002 ┌──────────────── TCP 5760 ┌─────────────────
Gazebo │◄──────────────────────►│ ArduPilot │◄────────────────────────►│ Your │ JSON sensor data │ │ MAVLink cmds │
(Physics) │ sensor data │ SITL │ commands/telemetry Controller │ 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 ```bash
cd ~/RDC_Simulation cd ~/RDC_Simulation
./scripts/run_ardupilot_sim.sh runway ./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 ```bash
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console 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 ```bash
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
@@ -53,44 +50,72 @@ python scripts/run_ardupilot.py --pattern square --size 5 --altitude 5
# Circle pattern (5m radius) # Circle pattern (5m radius)
python scripts/run_ardupilot.py --pattern circle --size 5 python scripts/run_ardupilot.py --pattern circle --size 5
# Hover in place for testing # Hover in place
python scripts/run_ardupilot.py --pattern hover python scripts/run_ardupilot.py --pattern hover
# Larger pattern at higher altitude # GPS mode (instead of GPS-denied)
python scripts/run_ardupilot.py --pattern square --size 10 --altitude 15 python scripts/run_ardupilot.py --pattern square --gps
``` ```
## Controller Code ## Controller Code
The flight controller is in `src/drone_controller.py`:
```python ```python
from src.drone_controller import DroneController from src.drone_controller import DroneController
drone = DroneController() drone = DroneController()
drone.connect() 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.arm()
drone.takeoff(5.0) drone.takeoff(5.0)
drone.fly_square(size=5, altitude=5) drone.fly_square(size=5, altitude=5)
drone.land() drone.land()
``` ```
### Key Methods ## ArduCopter Flight Modes
| Method | Description | | Mode | ID | Description |
|--------|-------------| |------|-----|-------------|
| `connect()` | Connect to SITL via MAVLink | | STABILIZE | 0 | Manual, self-leveling |
| `set_mode(mode)` | Set flight mode (GUIDED, LAND, etc.) | | ALT_HOLD | 2 | Hold altitude |
| `arm()` | Arm motors (force arm) | | GUIDED | 4 | Waypoint commands (GPS required) |
| `takeoff(alt)` | Take off to altitude | | LOITER | 5 | Hold position (GPS required) |
| `goto(x, y, z)` | Go to position (NED frame) | | RTL | 6 | Return to launch |
| `fly_to_and_wait(x, y, alt)` | Go to position and wait | | LAND | 9 | Automatic landing |
| `fly_square(size, alt)` | Fly square pattern | | **GUIDED_NOGPS** | 20 | Commands without GPS |
| `fly_circle(radius, alt)` | Fly circle pattern |
| `land()` | Land the drone |
## 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 ```bash
# Outdoor runway (default) # Outdoor runway (default)
@@ -102,83 +127,73 @@ drone.land()
## MAVLink Connection ## MAVLink Connection
The controller connects via TCP port 5760: Default: `tcp:127.0.0.1:5760`
```python Port map:
# config.py - **5760**: Primary MAVLink (SERIAL0)
MAVLINK = { - **5762**: Secondary (SERIAL1)
"connection_string": "tcp:127.0.0.1:5760", - **5763**: Tertiary (SERIAL2)
} - **14550**: MAVProxy GCS output (UDP)
```
## Troubleshooting ## Troubleshooting
### "No JSON sensor message received" ### "No JSON sensor message received"
SITL isn't receiving data from Gazebo. Gazebo isn't sending data.
**Fix:** **Fix:**
1. Make sure Gazebo is running FIRST 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 3. Then start SITL
### Drone won't arm ### Drone won't arm
**Fix:** **Fix:**
```bash ```bash
# Check pre-arm status in MAVProxy # In MAVProxy console
arm status
# Force arm
arm throttle force 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:** **Fix:**
```bash ```bash
source ~/venv-ardupilot/bin/activate pkill -9 -f sim_vehicle
which python3 # Should be ~/venv-ardupilot/bin/python3 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 ### Gazebo plugin not loading
**Fix:**
```bash ```bash
# Check plugin exists # Check plugin exists
ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so
# Check paths # Check environment
echo $GZ_SIM_SYSTEM_PLUGIN_PATH echo $GZ_SIM_SYSTEM_PLUGIN_PATH
# Should include: ~/ardupilot_gazebo/build # Should include: ~/ardupilot_gazebo/build
``` ```
## Manual SITL Control ## Useful Debug Commands
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
```bash ```bash
# List Gazebo topics # List Gazebo topics
gz topic -l gz topic -l
# Check SITL status # Echo a topic
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --map gz topic -e -t /model/iris_with_gimbal/pose
# View camera (if available) # Check SITL processes
gz topic -e -t /camera ps aux | grep ardupilot
# Check port usage
lsof -i :5760
``` ```

View File

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

View File

@@ -2,19 +2,23 @@
## System Requirements ## System Requirements
- **OS**: Ubuntu 22.04 or 24.04 (Windows users: use WSL2) | Requirement | Minimum | Recommended |
- **RAM**: 8GB minimum, 16GB recommended |-------------|---------|-------------|
- **Disk**: 10GB free space | **OS** | Ubuntu 22.04 | Ubuntu 24.04 |
- **GPU**: Any GPU with OpenGL 3.3+ support | **RAM** | 8 GB | 16 GB |
| **Disk** | 10 GB | 20 GB |
| **GPU** | OpenGL 3.3 | NVIDIA/AMD dedicated |
## Quick Install (Ubuntu) > **Windows users**: Use WSL2 with Ubuntu (see below)
## Quick Install (Ubuntu/WSL2)
```bash ```bash
# Clone repository # Clone repository
git clone <repo-url> RDC_Simulation git clone <repo-url> ~/RDC_Simulation
cd RDC_Simulation cd ~/RDC_Simulation
# Run installer (includes ArduPilot) # Run full installer (includes ArduPilot)
./setup/install_ubuntu.sh --with-ardupilot ./setup/install_ubuntu.sh --with-ardupilot
# Reload shell # Reload shell
@@ -22,11 +26,11 @@ source ~/.bashrc
``` ```
This installs: This installs:
- Python 3 + virtual environment - Python 3 + virtual environment
- Gazebo Harmonic - Gazebo Harmonic
- ArduPilot SITL - ArduPilot SITL
- ArduPilot Gazebo plugin - ArduPilot Gazebo plugin
- MAVProxy - MAVProxy
## Windows (WSL2) ## Windows (WSL2)
@@ -36,7 +40,8 @@ Open PowerShell as Administrator:
```powershell ```powershell
wsl --install -d Ubuntu-24.04 wsl --install -d Ubuntu-24.04
``` ```
Restart computer, then open Ubuntu from Start menu.
Restart your computer, then open "Ubuntu" from the Start menu.
### Step 2: Install in WSL ### Step 2: Install in WSL
@@ -49,32 +54,20 @@ git clone <repo-url> ~/RDC_Simulation
cd ~/RDC_Simulation cd ~/RDC_Simulation
./setup/install_ubuntu.sh --with-ardupilot ./setup/install_ubuntu.sh --with-ardupilot
# Reload # Reload shell
source ~/.bashrc source ~/.bashrc
``` ```
### WSL2 Tips ### WSL2 Tips
- **GUI Apps**: Windows 11 has WSLg built-in. Gazebo should work automatically. - **GUI**: 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) - **GPU**: Install [NVIDIA WSL driver](https://developer.nvidia.com/cuda/wsl) for GPU acceleration
- **Access Windows files**: `/mnt/c/Users/YourName/` - **Performance**: Keep files in Linux filesystem (`~/`), not Windows (`/mnt/c/`)
- **Performance**: Clone repo to Linux filesystem (not `/mnt/c/`) - **Memory**: WSL may need more RAM. Create `~/.wslconfig` in Windows:
```ini
## macOS [wsl2]
memory=8GB
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
```
## Arch Linux ## Arch Linux
@@ -83,46 +76,51 @@ python standalone_simulation.py
source ~/.bashrc source ~/.bashrc
``` ```
## macOS
macOS doesn't support Gazebo Harmonic. Options:
1. **Docker**: Run Linux in container
2. **VM**: Use UTM/Parallels with Ubuntu
3. **Basic**: PyBullet-only simulation
```bash
./setup/install_macos.sh
```
## Verify Installation ## Verify Installation
```bash ```bash
# Check ArduPilot # Check ArduPilot virtual environment
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
python -c "import em; print('empy OK')" python -c "import em; print('empy: OK')"
sim_vehicle.py --help which sim_vehicle.py
# Check Gazebo # Check Gazebo
gz sim --version gz sim --version
# Check ArduPilot plugin
ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so
``` ```
## Post-Installation ## First Run
### Environment Setup
The installer creates `activate.sh` in the project root:
### Terminal 1 - Gazebo
```bash ```bash
cd ~/RDC_Simulation cd ~/RDC_Simulation
source activate.sh
```
This sources:
- ROS 2 (if installed)
- ArduPilot virtual environment
- Gazebo paths
### First Run
```bash
# Terminal 1: Start Gazebo
./scripts/run_ardupilot_sim.sh runway ./scripts/run_ardupilot_sim.sh runway
```
Wait for the drone to appear!
# Terminal 2: Start SITL (after Gazebo loads) ### Terminal 2 - SITL
```bash
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console
```
Wait for "JSON received:" messages.
# Terminal 3: Run controller ### Terminal 3 - Controller
```bash
source ~/venv-ardupilot/bin/activate source ~/venv-ardupilot/bin/activate
cd ~/RDC_Simulation cd ~/RDC_Simulation
python scripts/run_ardupilot.py --pattern square python scripts/run_ardupilot.py --pattern square
@@ -137,30 +135,29 @@ source ~/venv-ardupilot/bin/activate
pip install empy==3.3.4 pip install empy==3.3.4
``` ```
### "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" ### "sim_vehicle.py not found"
```bash ```bash
source ~/.ardupilot_env source ~/.ardupilot_env
# OR # Or add to PATH manually:
export PATH=$PATH:~/ardupilot/Tools/autotest export PATH=$PATH:~/ardupilot/Tools/autotest
``` ```
### Gazebo crashes / slow ### "No JSON sensor message"
SITL isn't receiving data from Gazebo.
- Start Gazebo FIRST
- Wait for world to fully load
- Then start SITL
### Gazebo crashes or slow
```bash ```bash
# Check GPU # Check GPU
glxinfo | grep "OpenGL renderer" glxinfo | grep "OpenGL renderer"
# Try software rendering (slow but works) # Force software rendering (slow but works)
export LIBGL_ALWAYS_SOFTWARE=1 export LIBGL_ALWAYS_SOFTWARE=1
gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf
``` ```
### WSL: Display not working ### WSL: Display not working
@@ -169,6 +166,14 @@ gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf
# Check WSLg # Check WSLg
ls /mnt/wslg ls /mnt/wslg
# If missing, update WSL # Update WSL if missing
wsl --update wsl --update
``` ```
### ArduPlane instead of ArduCopter
If mode list shows FBWA, FBWB (plane modes):
```bash
pkill -9 -f sim_vehicle
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --wipe-eeprom
```

View File

@@ -6,7 +6,7 @@
# Run Gazebo FIRST in another terminal! # Run Gazebo FIRST in another terminal!
# #
# Usage: # Usage:
# Terminal 1: ./scripts/run_ardupilot_sim.sh # Terminal 1: ./scripts/run_ardupilot_sim.sh runway
# Terminal 2: ./scripts/run_ardupilot_controller.sh --pattern square # Terminal 2: ./scripts/run_ardupilot_controller.sh --pattern square
# ============================================================================= # =============================================================================
@@ -15,6 +15,10 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")" PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
# =============================================================================
# ENVIRONMENT SETUP
# =============================================================================
# Deactivate any existing venv # Deactivate any existing venv
if [ -n "$VIRTUAL_ENV" ]; then if [ -n "$VIRTUAL_ENV" ]; then
deactivate 2>/dev/null || true deactivate 2>/dev/null || true
@@ -34,7 +38,10 @@ echo " ArduPilot SITL + Controller"
echo "==============================================" echo "=============================================="
echo "" echo ""
# Check sim_vehicle.py # =============================================================================
# CHECKS
# =============================================================================
if ! command -v sim_vehicle.py &> /dev/null; then if ! command -v sim_vehicle.py &> /dev/null; then
echo "[ERROR] sim_vehicle.py not found" echo "[ERROR] sim_vehicle.py not found"
echo "" echo ""
@@ -43,7 +50,6 @@ if ! command -v sim_vehicle.py &> /dev/null; then
exit 1 exit 1
fi fi
# Check empy
if ! python3 -c "import em" 2>/dev/null; then if ! python3 -c "import em" 2>/dev/null; then
echo "[ERROR] empy not found" echo "[ERROR] empy not found"
echo "" echo ""
@@ -52,13 +58,18 @@ if ! python3 -c "import em" 2>/dev/null; then
fi fi
echo "[OK] Environment ready" echo "[OK] Environment ready"
echo "[INFO] Python: $(which python3)"
echo "" echo ""
# Start SITL with console # =============================================================================
echo "[INFO] Starting SITL..." # START SITL
# =============================================================================
echo "[INFO] Starting ArduCopter SITL..."
echo "[INFO] Make sure Gazebo is running first!" echo "[INFO] Make sure Gazebo is running first!"
echo "" echo ""
cd ~/ardupilot
sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console & sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console &
SITL_PID=$! SITL_PID=$!
@@ -68,32 +79,42 @@ TRIES=0
while ! nc -z 127.0.0.1 5760 2>/dev/null; do while ! nc -z 127.0.0.1 5760 2>/dev/null; do
sleep 1 sleep 1
TRIES=$((TRIES + 1)) TRIES=$((TRIES + 1))
if [ $TRIES -ge 60 ]; then if [ $TRIES -ge 90 ]; then
echo "[ERROR] SITL timeout" echo ""
echo "[ERROR] SITL timeout (90s)"
kill $SITL_PID 2>/dev/null || true kill $SITL_PID 2>/dev/null || true
exit 1 exit 1
fi fi
if ! kill -0 $SITL_PID 2>/dev/null; then if ! kill -0 $SITL_PID 2>/dev/null; then
echo "[ERROR] SITL died - is Gazebo running?" echo ""
echo "[ERROR] SITL process died"
echo "[TIP] Is Gazebo running? Start it first with:"
echo " ./scripts/run_ardupilot_sim.sh runway"
exit 1 exit 1
fi fi
echo -n "." echo -n "."
done done
echo "" echo ""
echo "[OK] SITL ready" echo "[OK] SITL ready on port 5760"
echo "" echo ""
# Cleanup on exit # =============================================================================
trap "echo ''; echo '[INFO] Stopping...'; kill $SITL_PID 2>/dev/null; exit 0" INT TERM # CLEANUP
# =============================================================================
# Wait a moment for SITL to stabilize trap "echo ''; echo '[INFO] Stopping SITL...'; kill $SITL_PID 2>/dev/null; exit 0" INT TERM
sleep 2
# Run the controller # Wait for SITL to stabilize
echo "[INFO] Starting flight controller..." sleep 3
# =============================================================================
# RUN CONTROLLER
# =============================================================================
echo "[INFO] Starting drone controller..."
echo "" echo ""
cd "$PROJECT_DIR" cd "$PROJECT_DIR"
python scripts/run_ardupilot.py "$@" python scripts/run_ardupilot.py "$@"
# Cleanup # Cleanup
kill $SITL_PID 2>/dev/null kill $SITL_PID 2>/dev/null || true

View File

@@ -2,8 +2,8 @@
# ============================================================================= # =============================================================================
# ArduPilot Gazebo Simulation Launcher # ArduPilot Gazebo Simulation Launcher
# ============================================================================= # =============================================================================
# Launches Gazebo with the ArduPilot iris drone model. # Launches Gazebo with the ArduPilot iris drone.
# Start this FIRST, then run SITL in another terminal. # START THIS FIRST, then run SITL in another terminal.
# #
# Usage: # Usage:
# ./scripts/run_ardupilot_sim.sh # Default runway # ./scripts/run_ardupilot_sim.sh # Default runway
@@ -17,7 +17,6 @@ echo " Gazebo + ArduPilot Simulation"
echo "==============================================" echo "=============================================="
echo "" echo ""
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")" PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
@@ -53,14 +52,19 @@ export GZ_SIM_RESOURCE_PATH="${PROJECT_DIR}/gazebo/models:${GZ_SIM_RESOURCE_PATH
# CHECK INSTALLATION # CHECK INSTALLATION
# ============================================================================= # =============================================================================
if [ ! -d "${HOME}/ardupilot_gazebo" ]; then if [ ! -d "${HOME}/ardupilot_gazebo" ]; then
echo "[ERROR] ardupilot_gazebo not found!" echo "[ERROR] ardupilot_gazebo directory not found!"
echo "Run: ./setup/install_ardupilot.sh" echo ""
echo "Install with: ./setup/install_ardupilot.sh"
exit 1 exit 1
fi fi
if [ ! -f "${HOME}/ardupilot_gazebo/build/libArduPilotPlugin.so" ]; then if [ ! -f "${HOME}/ardupilot_gazebo/build/libArduPilotPlugin.so" ]; then
echo "[ERROR] ArduPilot plugin not built!" echo "[ERROR] ArduPilot Gazebo plugin not built!"
echo "Run: cd ~/ardupilot_gazebo && mkdir -p build && cd build && cmake .. && make -j4" echo ""
echo "Build it:"
echo " cd ~/ardupilot_gazebo"
echo " mkdir -p build && cd build"
echo " cmake .. && make -j4"
exit 1 exit 1
fi fi
@@ -92,22 +96,22 @@ case "$WORLD_ARG" in
;; ;;
esac esac
echo "[INFO] World: $(basename "$WORLD")" echo "[OK] World: $(basename "$WORLD")"
echo "" echo ""
# ============================================================================= # =============================================================================
# INSTRUCTIONS # INSTRUCTIONS
# ============================================================================= # =============================================================================
echo "==============================================" echo "=============================================="
echo " STEP 1: Gazebo Starting..." echo " NEXT STEPS"
echo "==============================================" echo "=============================================="
echo "" echo ""
echo "After Gazebo loads, run SITL in another terminal:" echo "After Gazebo loads, open a NEW terminal and run:"
echo "" echo ""
echo " source ~/venv-ardupilot/bin/activate" echo " source ~/venv-ardupilot/bin/activate"
echo " sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console" echo " sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console"
echo "" echo ""
echo "Then run the flight controller:" echo "Then open ANOTHER terminal to run the controller:"
echo "" echo ""
echo " source ~/venv-ardupilot/bin/activate" echo " source ~/venv-ardupilot/bin/activate"
echo " cd ~/RDC_Simulation" echo " cd ~/RDC_Simulation"
@@ -115,6 +119,7 @@ echo " python scripts/run_ardupilot.py --pattern square"
echo "" echo ""
echo "==============================================" echo "=============================================="
echo "" echo ""
echo "[INFO] Starting Gazebo..."
# ============================================================================= # =============================================================================
# RUN GAZEBO # RUN GAZEBO