diff --git a/README.md b/README.md index a744d6e..2b59963 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RDC Simulation -GPS-denied drone landing simulation using ArduPilot and Gazebo. +**GPS-Denied Drone Landing Simulation** using ArduPilot and Gazebo. ## Quick Start @@ -23,25 +23,23 @@ cd RDC_Simulation source ~/.bashrc ``` -### Run the Simulation +### Run the Simulation (3 Terminals) -You need **3 terminals**: - -**Terminal 1 - Gazebo:** +**Terminal 1 - Start Gazebo FIRST:** ```bash cd ~/RDC_Simulation ./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 source ~/venv-ardupilot/bin/activate 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 source ~/venv-ardupilot/bin/activate cd ~/RDC_Simulation @@ -62,6 +60,9 @@ python scripts/run_ardupilot.py --pattern hover # Custom altitude 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 @@ -71,13 +72,13 @@ RDC_Simulation/ ├── scripts/ │ ├── run_ardupilot_sim.sh # Launch Gazebo │ ├── run_ardupilot_controller.sh # Launch SITL + Controller -│ └── run_ardupilot.py # Flight controller +│ └── run_ardupilot.py # Flight controller entry point ├── src/ -│ ├── drone_controller.py # Simple drone controller +│ ├── drone_controller.py # Main drone controller class │ ├── rover_controller.py # Moving landing pad (ROS 2) │ └── camera_viewer.py # Camera viewer (ROS 2) ├── setup/ -│ ├── install_ubuntu.sh # Ubuntu installer +│ ├── install_ubuntu.sh # Ubuntu/WSL installer │ ├── install_ardupilot.sh # ArduPilot installer │ └── install_arch.sh # Arch Linux installer ├── gazebo/ @@ -92,29 +93,40 @@ RDC_Simulation/ Gazebo isn't sending data to SITL. - **Fix**: Start Gazebo FIRST, wait for it to fully load, THEN start SITL. -### "empy not found" -Wrong Python environment. -- **Fix**: `source ~/venv-ardupilot/bin/activate` +### "empy not found" or wrong Python +Wrong virtual environment. +```bash +source ~/venv-ardupilot/bin/activate +pip install empy==3.3.4 +``` ### "sim_vehicle.py not found" ArduPilot tools not in PATH. -- **Fix**: `source ~/.ardupilot_env` +```bash +source ~/.ardupilot_env +``` -### Can't arm -The drone won't arm or takeoff. -- **Fix**: Make sure you're in GUIDED mode and Gazebo is running. -- Check console for pre-arm errors. +### Drone won't arm +- Make sure SITL is in STABILIZE or GUIDED mode +- Check for pre-arm errors in MAVProxy console +- Try in MAVProxy: `arm throttle force` -### Gazebo is slow -- Try a lighter world: `./scripts/run_ardupilot_sim.sh runway` -- Check GPU: `glxinfo | grep "OpenGL renderer"` +### Wrong vehicle type (ArduPlane instead of ArduCopter) +You see modes like FBWA, FBWB, QSTABILIZE. +```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 - [Installation Guide](docs/installation.md) - [ArduPilot Guide](docs/ardupilot.md) +- [Drone Controller Guide](docs/drone_guide.md) - [Architecture](docs/architecture.md) -- [Gazebo Worlds](docs/gazebo_worlds.md) ## License diff --git a/docs/ardupilot.md b/docs/ardupilot.md index feb491f..b201dda 100644 --- a/docs/ardupilot.md +++ b/docs/ardupilot.md @@ -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 ``` diff --git a/docs/drone_guide.md b/docs/drone_guide.md index 4b89cc4..35d44bc 100644 --- a/docs/drone_guide.md +++ b/docs/drone_guide.md @@ -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 ``` diff --git a/docs/installation.md b/docs/installation.md index 6c36b34..2a1e591 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,19 +2,23 @@ ## 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 +| Requirement | Minimum | Recommended | +|-------------|---------|-------------| +| **OS** | Ubuntu 22.04 | Ubuntu 24.04 | +| **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 # Clone repository -git clone RDC_Simulation -cd RDC_Simulation +git clone ~/RDC_Simulation +cd ~/RDC_Simulation -# Run installer (includes ArduPilot) +# Run full installer (includes ArduPilot) ./setup/install_ubuntu.sh --with-ardupilot # Reload shell @@ -22,11 +26,11 @@ source ~/.bashrc ``` This installs: -- Python 3 + virtual environment -- Gazebo Harmonic -- ArduPilot SITL -- ArduPilot Gazebo plugin -- MAVProxy +- ✅ Python 3 + virtual environment +- ✅ Gazebo Harmonic +- ✅ ArduPilot SITL +- ✅ ArduPilot Gazebo plugin +- ✅ MAVProxy ## Windows (WSL2) @@ -36,7 +40,8 @@ Open PowerShell as Administrator: ```powershell 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 @@ -49,32 +54,20 @@ git clone ~/RDC_Simulation cd ~/RDC_Simulation ./setup/install_ubuntu.sh --with-ardupilot -# Reload +# Reload shell source ~/.bashrc ``` ### WSL2 Tips -- **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 -``` +- **GUI**: Windows 11 has WSLg built-in. Gazebo should work automatically. +- **GPU**: Install [NVIDIA WSL driver](https://developer.nvidia.com/cuda/wsl) for GPU acceleration +- **Performance**: Keep files in Linux filesystem (`~/`), not Windows (`/mnt/c/`) +- **Memory**: WSL may need more RAM. Create `~/.wslconfig` in Windows: + ```ini + [wsl2] + memory=8GB + ``` ## Arch Linux @@ -83,46 +76,51 @@ python standalone_simulation.py 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 ```bash -# Check ArduPilot +# Check ArduPilot virtual environment source ~/venv-ardupilot/bin/activate -python -c "import em; print('empy OK')" -sim_vehicle.py --help +python -c "import em; print('empy: OK')" +which sim_vehicle.py # Check Gazebo gz sim --version + +# Check ArduPilot plugin ls ~/ardupilot_gazebo/build/libArduPilotPlugin.so ``` -## Post-Installation - -### Environment Setup - -The installer creates `activate.sh` in the project root: +## First Run +### Terminal 1 - Gazebo ```bash 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 +``` +Wait for the drone to appear! -# Terminal 2: Start SITL (after Gazebo loads) +### Terminal 2 - SITL +```bash source ~/venv-ardupilot/bin/activate 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 cd ~/RDC_Simulation python scripts/run_ardupilot.py --pattern square @@ -137,30 +135,29 @@ source ~/venv-ardupilot/bin/activate 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" ```bash source ~/.ardupilot_env -# OR +# Or add to PATH manually: 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 # Check GPU glxinfo | grep "OpenGL renderer" -# Try software rendering (slow but works) +# Force software rendering (slow but works) export LIBGL_ALWAYS_SOFTWARE=1 -gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf ``` ### WSL: Display not working @@ -169,6 +166,14 @@ gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf # Check WSLg ls /mnt/wslg -# If missing, update WSL +# Update WSL if missing 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 +``` diff --git a/scripts/run_ardupilot_controller.sh b/scripts/run_ardupilot_controller.sh index 5caac5b..436947f 100755 --- a/scripts/run_ardupilot_controller.sh +++ b/scripts/run_ardupilot_controller.sh @@ -6,7 +6,7 @@ # Run Gazebo FIRST in another terminal! # # 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 # ============================================================================= @@ -15,6 +15,10 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +# ============================================================================= +# ENVIRONMENT SETUP +# ============================================================================= + # Deactivate any existing venv if [ -n "$VIRTUAL_ENV" ]; then deactivate 2>/dev/null || true @@ -34,7 +38,10 @@ echo " ArduPilot SITL + Controller" echo "==============================================" echo "" -# Check sim_vehicle.py +# ============================================================================= +# CHECKS +# ============================================================================= + if ! command -v sim_vehicle.py &> /dev/null; then echo "[ERROR] sim_vehicle.py not found" echo "" @@ -43,7 +50,6 @@ if ! command -v sim_vehicle.py &> /dev/null; then exit 1 fi -# Check empy if ! python3 -c "import em" 2>/dev/null; then echo "[ERROR] empy not found" echo "" @@ -52,13 +58,18 @@ if ! python3 -c "import em" 2>/dev/null; then fi echo "[OK] Environment ready" +echo "[INFO] Python: $(which python3)" 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 "" +cd ~/ardupilot sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console & SITL_PID=$! @@ -68,32 +79,42 @@ TRIES=0 while ! nc -z 127.0.0.1 5760 2>/dev/null; do sleep 1 TRIES=$((TRIES + 1)) - if [ $TRIES -ge 60 ]; then - echo "[ERROR] SITL timeout" + if [ $TRIES -ge 90 ]; then + echo "" + echo "[ERROR] SITL timeout (90s)" kill $SITL_PID 2>/dev/null || true exit 1 fi 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 fi echo -n "." done echo "" -echo "[OK] SITL ready" +echo "[OK] SITL ready on port 5760" 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 -sleep 2 +trap "echo ''; echo '[INFO] Stopping SITL...'; kill $SITL_PID 2>/dev/null; exit 0" INT TERM -# Run the controller -echo "[INFO] Starting flight controller..." +# Wait for SITL to stabilize +sleep 3 + +# ============================================================================= +# RUN CONTROLLER +# ============================================================================= + +echo "[INFO] Starting drone controller..." echo "" cd "$PROJECT_DIR" python scripts/run_ardupilot.py "$@" # Cleanup -kill $SITL_PID 2>/dev/null +kill $SITL_PID 2>/dev/null || true diff --git a/scripts/run_ardupilot_sim.sh b/scripts/run_ardupilot_sim.sh index f446f48..96b9279 100755 --- a/scripts/run_ardupilot_sim.sh +++ b/scripts/run_ardupilot_sim.sh @@ -2,8 +2,8 @@ # ============================================================================= # ArduPilot Gazebo Simulation Launcher # ============================================================================= -# Launches Gazebo with the ArduPilot iris drone model. -# Start this FIRST, then run SITL in another terminal. +# Launches Gazebo with the ArduPilot iris drone. +# START THIS FIRST, then run SITL in another terminal. # # Usage: # ./scripts/run_ardupilot_sim.sh # Default runway @@ -17,7 +17,6 @@ echo " Gazebo + ArduPilot Simulation" echo "==============================================" echo "" -# Get script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" @@ -53,14 +52,19 @@ export GZ_SIM_RESOURCE_PATH="${PROJECT_DIR}/gazebo/models:${GZ_SIM_RESOURCE_PATH # CHECK INSTALLATION # ============================================================================= if [ ! -d "${HOME}/ardupilot_gazebo" ]; then - echo "[ERROR] ardupilot_gazebo not found!" - echo "Run: ./setup/install_ardupilot.sh" + echo "[ERROR] ardupilot_gazebo directory not found!" + echo "" + echo "Install with: ./setup/install_ardupilot.sh" exit 1 fi if [ ! -f "${HOME}/ardupilot_gazebo/build/libArduPilotPlugin.so" ]; then - echo "[ERROR] ArduPilot plugin not built!" - echo "Run: cd ~/ardupilot_gazebo && mkdir -p build && cd build && cmake .. && make -j4" + echo "[ERROR] ArduPilot Gazebo plugin not built!" + echo "" + echo "Build it:" + echo " cd ~/ardupilot_gazebo" + echo " mkdir -p build && cd build" + echo " cmake .. && make -j4" exit 1 fi @@ -92,22 +96,22 @@ case "$WORLD_ARG" in ;; esac -echo "[INFO] World: $(basename "$WORLD")" +echo "[OK] World: $(basename "$WORLD")" echo "" # ============================================================================= # INSTRUCTIONS # ============================================================================= echo "==============================================" -echo " STEP 1: Gazebo Starting..." +echo " NEXT STEPS" echo "==============================================" echo "" -echo "After Gazebo loads, run SITL in another terminal:" +echo "After Gazebo loads, open a NEW terminal and run:" echo "" echo " source ~/venv-ardupilot/bin/activate" echo " sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console" echo "" -echo "Then run the flight controller:" +echo "Then open ANOTHER terminal to run the controller:" echo "" echo " source ~/venv-ardupilot/bin/activate" echo " cd ~/RDC_Simulation" @@ -115,6 +119,7 @@ echo " python scripts/run_ardupilot.py --pattern square" echo "" echo "==============================================" echo "" +echo "[INFO] Starting Gazebo..." # ============================================================================= # RUN GAZEBO