From edfed30fb1d620e9c5f95029985a96a589aa13e7 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 4 Jan 2026 01:42:01 +0000 Subject: [PATCH] Docs Update --- .gitignore | 1 - README.md | 44 +++---- docs/architecture.md | 93 +++++++------- docs/ardupilot.md | 137 ++++++++++----------- docs/drone_guide.md | 70 ++++------- docs/gazebo.md | 50 ++++---- docs/installation.md | 113 +++++------------ gazebo/worlds/iris_camera.sdf | 225 ++++++++++++++++++++++++++++++++++ scripts/run_ardupilot_sim.sh | 163 ++++++++++++++++++++++++ 9 files changed, 591 insertions(+), 305 deletions(-) create mode 100644 gazebo/worlds/iris_camera.sdf create mode 100755 scripts/run_ardupilot_sim.sh diff --git a/.gitignore b/.gitignore index 843cfaf..5140b0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ - venv/ __pycache__/ notes/ diff --git a/README.md b/README.md index 4e9d7c7..62bcda2 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Drone Landing Simulation (GPS-Denied) -Land a drone on a moving platform using only relative sensors (IMU, altimeter, camera). +Land a drone on a moving platform using only relative sensors. ## Quick Start -### Standalone (1 Terminal - Any Platform) +### Standalone (1 Terminal) ```bash source activate.sh @@ -22,30 +22,31 @@ ros2 launch gazebo/launch/drone_landing.launch.py ```bash source activate.sh python run_gazebo.py --pattern circular +python camera_viewer.py # View camera ``` -### ArduPilot SITL (2 Terminals) +### ArduPilot GPS-Denied (2 Terminals) **Terminal 1:** ```bash -gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf +./scripts/run_ardupilot_sim.sh camera ``` **Terminal 2:** ```bash sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console + +# GPS-denied mode: +param set ARMING_CHECK 0 +mode stabilize +arm throttle force ``` ## Installation ```bash -# Ubuntu/Debian ./setup/install_ubuntu.sh - -# ArduPilot SITL (optional) -./setup/install_ardupilot.sh - -# Activate environment +./setup/install_ardupilot.sh # Optional source activate.sh ``` @@ -55,31 +56,30 @@ source activate.sh |------|-------------| | `standalone_simulation.py` | All-in-one simulation | | `run_gazebo.py` | Gazebo controllers | +| `scripts/run_ardupilot_sim.sh` | ArduPilot launcher (auto GPU) | +| `camera_viewer.py` | Camera feed window | | `drone_controller.py` | **Your landing algorithm** | -| `camera_viewer.py` | Drone camera window | | `config.py` | Configuration | -## Sensors +## Sensors (GPS-Denied) | Sensor | Data | |--------|------| | IMU | Orientation, angular velocity | | Altimeter | Altitude, vertical velocity | -| Camera | 320x240 downward image | +| Camera | Downward image | | Landing Pad | Relative position (when visible) | ## Options ```bash ---pattern, -p stationary, linear, circular, square, random ---speed, -s Speed in m/s (default: 0.5) +--pattern stationary, linear, circular, square, random +--speed Speed in m/s (default: 0.5) ``` -## Documentation +## Docs -| Document | Description | -|----------|-------------| -| [Installation](docs/installation.md) | Setup guide | -| [Architecture](docs/architecture.md) | System overview | -| [ArduPilot](docs/ardupilot.md) | ArduPilot SITL | -| [Drone Guide](docs/drone_guide.md) | Algorithm guide | \ No newline at end of file +- [Installation](docs/installation.md) +- [Architecture](docs/architecture.md) +- [ArduPilot](docs/ardupilot.md) +- [Gazebo](docs/gazebo.md) \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 52ddfdd..62019b8 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,8 +1,8 @@ # Architecture Overview -## Operation Modes +## Modes -### 1. Standalone (Any Platform, 1 Terminal) +### 1. Standalone (1 Terminal) ```bash python standalone_simulation.py --pattern circular @@ -11,79 +11,68 @@ python standalone_simulation.py --pattern circular ``` ┌────────────────────────────────────────┐ │ standalone_simulation.py │ -│ PyBullet Physics + Camera + Controllers│ +│ PyBullet + Controllers + Camera │ └────────────────────────────────────────┘ ``` ### 2. Gazebo + ROS 2 (2 Terminals) -**Terminal 1:** -```bash -ros2 launch gazebo/launch/drone_landing.launch.py -``` - -**Terminal 2:** -```bash -python run_gazebo.py --pattern circular -``` - ``` Terminal 1 Terminal 2 ┌───────────────────┐ ┌───────────────────┐ │ Gazebo + Bridge │◄──────►│ run_gazebo.py │ -│ (Physics) │ ROS │ + Controllers │ -└───────────────────┘ └───────────────────┘ +└───────────────────┘ ROS └───────────────────┘ ``` -### 3. ArduPilot SITL + Gazebo (2 Terminals) - -**Terminal 1:** -```bash -gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf -``` - -**Terminal 2:** -```bash -sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console -``` +### 3. ArduPilot GPS-Denied (2 Terminals) ``` Terminal 1 Terminal 2 ┌───────────────────┐ ┌───────────────────┐ │ Gazebo + │◄──────►│ ArduPilot SITL │ │ ArduPilot Plugin │ JSON │ + MAVProxy │ -└───────────────────┘ UDP └───────────────────┘ +└───────────────────┘ └───────────────────┘ ``` -**Key features:** -- Full ArduPilot flight controller -- EKF, stabilization, failsafes -- MAVLink protocol -- Compatible with QGroundControl, Mission Planner +## Data Flow -## Key Components +### Standalone +``` +Controller → PyBullet → Telemetry → Controller +``` -| Component | Description | -|-----------|-------------| -| `standalone_simulation.py` | All-in-one PyBullet simulation | -| `run_gazebo.py` | Gazebo bridge + controllers | +### Gazebo +``` +Controller → /cmd_vel → Gazebo → /odometry → Controller +``` + +### ArduPilot +``` +Gazebo ◄─── JSON/UDP ───► SITL ◄─── MAVLink ───► MAVProxy +``` + +## Key Files + +| File | Purpose | +|------|---------| | `drone_controller.py` | Your landing algorithm | -| `camera_viewer.py` | Camera display window | +| `gazebo_bridge.py` | Gazebo ↔ ROS bridge | +| `camera_viewer.py` | Camera display | +| `config.py` | Configuration | -## ROS 2 Topics (Gazebo Mode) - -| Topic | Direction | Description | -|-------|-----------|-------------| -| `/drone/telemetry` | ← | Sensor data (JSON) | -| `/cmd_vel` | → | Velocity commands | -| `/drone/camera` | ← | Camera images | - -## Sensors +## GPS-Denied Sensors | Sensor | Data | |--------|------| -| IMU | orientation, angular_velocity | -| Altimeter | altitude, vertical_velocity | -| Velocity | x, y, z (m/s) | -| Camera | 320x240 image | -| Landing Pad | relative_x, relative_y (when visible) | +| IMU | Orientation, angular velocity | +| Altimeter | Altitude, vertical velocity | +| Camera | Downward image | +| Landing Pad | Relative position | + +## Topics + +| Topic | Direction | +|-------|-----------| +| `/cmd_vel` | → Drone commands | +| `/drone/telemetry` | ← Sensor data | +| `/drone/camera` | ← Camera images | diff --git a/docs/ardupilot.md b/docs/ardupilot.md index 4cf3723..671ddce 100644 --- a/docs/ardupilot.md +++ b/docs/ardupilot.md @@ -1,17 +1,22 @@ -# ArduPilot SITL Integration +# ArduPilot GPS-Denied Simulation -Run the simulation with a realistic ArduPilot flight controller. +Realistic flight controller simulation without GPS. ## Quick Start (2 Terminals) -**Terminal 1 - Gazebo:** +**Terminal 1:** ```bash -gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf +./scripts/run_ardupilot_sim.sh camera ``` -**Terminal 2 - SITL + MAVProxy:** +**Terminal 2:** ```bash sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console + +# GPS-denied mode: +param set ARMING_CHECK 0 +mode stabilize +arm throttle force ``` ## Installation @@ -21,82 +26,74 @@ sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console source ~/.bashrc ``` -This installs: -- ArduPilot SITL -- Gazebo Harmonic -- ardupilot_gazebo plugin -- MAVProxy +Installs: ArduPilot SITL, Gazebo, ardupilot_gazebo plugin, MAVProxy + +## GPS-Denied Configuration + +In MAVProxy console: + +```bash +# Disable all pre-arm checks +param set ARMING_CHECK 0 + +# GPS-free flight modes +mode stabilize # Manual with stabilization +mode alt_hold # Altitude hold +mode guided_nogps # Guided without GPS +``` + +## GPU Support + +The launcher auto-detects your GPU: + +| GPU | Status | +|-----|--------| +| NVIDIA | Best performance | +| Intel integrated | Good for laptops | +| AMD | Good performance | +| Software | Works but slow | + +## Camera Feed + +### In Gazebo GUI +Click camera icon → Select drone camera + +### Using camera_viewer +```bash +ros2 run ros_gz_bridge parameter_bridge /drone/camera@sensor_msgs/msg/Image[gz.msgs.Image +python camera_viewer.py --topic /drone/camera +``` + +## World Options + +```bash +./scripts/run_ardupilot_sim.sh runway # Default +./scripts/run_ardupilot_sim.sh camera # With camera +``` ## MAVProxy Commands -Once `sim_vehicle.py` is running: - ```bash -# Set GUIDED mode -mode guided - -# Arm -arm throttle - -# Takeoff to 5m -takeoff 5 - -# Land -mode land - -# Disarm -disarm +mode stabilize # Manual mode +mode guided_nogps # Autonomous (no GPS) +arm throttle force # Arm motors +takeoff 5 # Takeoff 5m +mode land # Land ``` -## Available Worlds - -```bash -# Iris on runway -gz sim -v4 -r ~/ardupilot_gazebo/worlds/iris_runway.sdf - -# Zephyr plane -gz sim -v4 -r ~/ardupilot_gazebo/worlds/zephyr_runway.sdf -``` - -## Standalone SITL (No Gazebo) - -```bash -sim_vehicle.py -v ArduCopter --console --map -``` - -This opens a 2D map view for testing without Gazebo. - -## How It Works - -``` -Gazebo ArduPilot SITL -┌─────────────────┐ ┌─────────────────┐ -│ iris_runway.sdf │◄────►│ sim_vehicle.py │ -│ + ArduPilot │ JSON │ + MAVProxy │ -│ Plugin │ UDP │ │ -└─────────────────┘ └─────────────────┘ - │ - ▼ MAVLink - Your Controller -``` - -The ArduPilot Gazebo plugin communicates with SITL via JSON over UDP. - ## Troubleshooting -**sim_vehicle.py not found:** +### Simulation laggy ```bash -export PATH=$PATH:~/ardupilot/Tools/autotest +glxinfo | grep "OpenGL renderer" +# Should show GPU, not "llvmpipe" ``` -**Plugin not loading:** +### Can't arm ```bash -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 -``` - -**Can't arm:** -```bash -# In MAVProxy, disable pre-arm checks param set ARMING_CHECK 0 +arm throttle force ``` + +### No camera +Use `./scripts/run_ardupilot_sim.sh camera` for camera world. diff --git a/docs/drone_guide.md b/docs/drone_guide.md index 375b66d..3efd8f9 100644 --- a/docs/drone_guide.md +++ b/docs/drone_guide.md @@ -1,6 +1,6 @@ # DroneController Guide -Implement your GPS-denied landing algorithm in `drone_controller.py`. +Implement your GPS-denied landing algorithm. ## Quick Start @@ -9,25 +9,14 @@ Implement your GPS-denied landing algorithm in `drone_controller.py`. 3. Implement your algorithm 4. Test: `python standalone_simulation.py` -## Sensors Available - -| Sensor | Description | -|--------|-------------| -| IMU | Orientation, angular velocity | -| Altimeter | Altitude, vertical velocity | -| Velocity | Estimated velocity (x, y, z) | -| Camera | 320x240 downward image | -| Landing Pad | Relative position (may be null!) | - ## Function to Implement ```python def calculate_landing_maneuver(self, telemetry, rover_telemetry): - # Your code here return (thrust, pitch, roll, yaw) ``` -## Sensor Data +## Sensors (GPS-Denied) ```python # Altitude @@ -58,23 +47,23 @@ if landing_pad: ```python def calculate_landing_maneuver(self, telemetry, rover_telemetry): - altimeter = telemetry.get('altimeter', {}) - altitude = altimeter.get('altitude', 5.0) - vertical_vel = altimeter.get('vertical_velocity', 0.0) + alt = telemetry.get('altimeter', {}) + altitude = alt.get('altitude', 5.0) + vert_vel = alt.get('vertical_velocity', 0.0) - velocity = telemetry.get('velocity', {}) - vel_x = velocity.get('x', 0.0) - vel_y = velocity.get('y', 0.0) + vel = telemetry.get('velocity', {}) + vel_x = vel.get('x', 0.0) + vel_y = vel.get('y', 0.0) - landing_pad = telemetry.get('landing_pad') + pad = telemetry.get('landing_pad') - # Altitude control - thrust = 0.5 * (0 - altitude) - 0.3 * vertical_vel + # Altitude PD control + thrust = 0.5 * (0 - altitude) - 0.3 * vert_vel # Horizontal control - if landing_pad: - pitch = 0.3 * landing_pad['relative_x'] - 0.2 * vel_x - roll = 0.3 * landing_pad['relative_y'] - 0.2 * vel_y + if pad: + pitch = 0.3 * pad['relative_x'] - 0.2 * vel_x + roll = 0.3 * pad['relative_y'] - 0.2 * vel_y else: pitch = -0.2 * vel_x roll = -0.2 * vel_y @@ -82,33 +71,16 @@ def calculate_landing_maneuver(self, telemetry, rover_telemetry): return (thrust, pitch, roll, 0.0) ``` -## Using the Camera - -```python -import cv2 -import numpy as np -import base64 - -camera = telemetry.get('camera', {}) -image_b64 = camera.get('image') - -if image_b64: - image_bytes = base64.b64decode(image_b64) - nparr = np.frombuffer(image_bytes, np.uint8) - image = cv2.imdecode(nparr, cv2.IMREAD_COLOR) - # Process image... -``` - ## Testing ```bash -# Easy - stationary +# Easy python standalone_simulation.py --pattern stationary -# Medium - circular +# Medium python standalone_simulation.py --pattern circular --speed 0.3 -# Hard - random +# Hard python standalone_simulation.py --pattern random --speed 0.5 ``` @@ -118,9 +90,9 @@ Edit `config.py`: ```python CONTROLLER = { - "Kp_z": 0.5, # Altitude proportional - "Kd_z": 0.3, # Altitude derivative - "Kp_xy": 0.3, # Horizontal proportional - "Kd_xy": 0.2, # Horizontal derivative + "Kp_z": 0.5, + "Kd_z": 0.3, + "Kp_xy": 0.3, + "Kd_xy": 0.2, } ``` diff --git a/docs/gazebo.md b/docs/gazebo.md index 64d82f9..4f94b6e 100644 --- a/docs/gazebo.md +++ b/docs/gazebo.md @@ -2,43 +2,38 @@ ## Quick Start (2 Terminals) -**Terminal 1 - Gazebo:** +**Terminal 1:** ```bash ros2 launch gazebo/launch/drone_landing.launch.py ``` -**Terminal 2 - Controllers:** +**Terminal 2:** ```bash source activate.sh python run_gazebo.py --pattern circular ``` -## Command Options - -```bash -python run_gazebo.py --pattern circular --speed 0.5 - -Options: - --pattern, -p stationary, linear, circular, square, random - --speed, -s Rover speed in m/s (default: 0.5) - --amplitude, -a Movement radius (default: 2.0) - --no-rover Disable rover controller -``` - -## View Camera +## Camera Feed ```bash python camera_viewer.py --topic /drone/camera ``` +## Options + +```bash +--pattern stationary, linear, circular, square, random +--speed Rover speed in m/s (default: 0.5) +--no-rover Disable rover movement +``` + ## Sensors -| Sensor | Description | -|--------|-------------| -| IMU | Orientation, angular velocity | -| Altimeter | Altitude, vertical velocity | -| Velocity | Estimated velocity (x, y, z) | -| Camera | Downward-facing image | +| Sensor | Source | +|--------|--------| +| IMU | Gazebo odometry | +| Altimeter | Z position | +| Camera | Camera sensor | | Landing Pad | Relative position | ## ROS 2 Topics @@ -47,24 +42,23 @@ python camera_viewer.py --topic /drone/camera |-------|-----------| | `/cmd_vel` | Your commands → Drone | | `/drone/telemetry` | Sensors → You | -| `/drone/camera` | Camera → You | -| `/rover/telemetry` | Rover position | +| `/drone/camera` | Camera images | ## Headless Mode (WSL2) ```bash -# Server only (no GUI) ign gazebo -s gazebo/worlds/drone_landing.sdf ``` ## Troubleshooting **Drone falls:** -- Check `run_gazebo.py` is running -- Check topic: `ros2 topic echo /drone/cmd_vel` +Check `run_gazebo.py` is running -**Rover doesn't move:** -- Check topic: `ros2 topic echo /rover/cmd_vel` +**No camera:** +```bash +python camera_viewer.py --list # Find topics +``` **Model not found:** ```bash diff --git a/docs/installation.md b/docs/installation.md index a77cf22..eed61b5 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -3,21 +3,17 @@ ## Quick Install ```bash -# Ubuntu/Debian ./setup/install_ubuntu.sh source activate.sh - -# Test python standalone_simulation.py ``` -## Install Scripts +## Scripts | Platform | Command | |----------|---------| | Ubuntu/Debian | `./setup/install_ubuntu.sh` | | ArduPilot SITL | `./setup/install_ardupilot.sh` | -| Arch Linux | `./setup/install_arch.sh` | | macOS | `./setup/install_macos.sh` | | Windows | `.\setup\install_windows.ps1` | @@ -26,8 +22,8 @@ python standalone_simulation.py | Mode | Ubuntu | macOS | Windows | |------|--------|-------|---------| | Standalone | ✅ | ✅ | ✅ | -| Gazebo + ROS 2 | ✅ | ❌ | WSL2 | -| ArduPilot SITL | ✅ | ❌ | WSL2 | +| Gazebo | ✅ | ❌ | WSL2 | +| ArduPilot | ✅ | ❌ | WSL2 | --- @@ -36,74 +32,46 @@ python standalone_simulation.py ```bash ./setup/install_ubuntu.sh source activate.sh -python standalone_simulation.py ``` -**Installs:** -- ROS 2 Humble/Jazzy -- Gazebo -- Python packages (pybullet, numpy, opencv, pymavlink) +Installs: ROS 2, Gazebo, PyBullet, OpenCV, pymavlink --- ## ArduPilot SITL -For realistic flight controller simulation: - ```bash ./setup/install_ardupilot.sh source ~/.bashrc ``` -**Installs:** -- Micro-XRCE-DDS-Gen (required for DDS) -- ArduPilot SITL -- ardupilot_gz (Gazebo integration) -- MAVProxy (`~/.local/bin/mavproxy.py`) +Installs: ArduPilot SITL, ardupilot_gazebo, MAVProxy -**Run (2 terminals):** - -Terminal 1: +**Run:** ```bash -source ~/ardu_ws/install/setup.bash -ros2 launch ardupilot_gz_bringup iris_runway.launch.py -``` - -Terminal 2: -```bash -mavproxy.py --console --map --master=:14550 +./scripts/run_ardupilot_sim.sh camera ``` --- -## Windows (WSL2) +## GPU Support -1. Install WSL2: -```powershell -wsl --install -d Ubuntu-22.04 -``` +The simulation auto-detects GPU: -2. Open Ubuntu and run: +| Priority | GPU Type | Notes | +|----------|----------|-------| +| 1 | NVIDIA | Best performance | +| 2 | Intel integrated | Good for laptops | +| 3 | AMD | Good performance | +| 4 | Software (llvmpipe) | Slow fallback | + +Check your GPU: ```bash -./setup/install_ubuntu.sh -source activate.sh -python standalone_simulation.py +glxinfo | grep "OpenGL renderer" ``` --- -## macOS - -```bash -./setup/install_macos.sh -source activate.sh -python standalone_simulation.py -``` - -**Note:** ROS 2 and Gazebo not supported. Use standalone mode. - ---- - ## Manual Install ```bash @@ -115,49 +83,28 @@ python standalone_simulation.py --- -## Verification +## Troubleshooting + +### Simulation is laggy ```bash -python -c "import pybullet; print('PyBullet OK')" -python -c "import cv2; print('OpenCV OK')" -python -c "from pymavlink import mavutil; print('pymavlink OK')" +# Check GPU (should NOT show "llvmpipe") +glxinfo | grep "OpenGL renderer" + +# Install GPU drivers +sudo apt install mesa-utils # Intel/AMD +sudo apt install nvidia-driver-535 # NVIDIA ``` ---- - -## Troubleshooting - ### MAVProxy not found ```bash -# Install pip3 install --user mavproxy - -# Add to PATH -echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc -source ~/.bashrc - -# Verify -which mavproxy.py +export PATH=$PATH:~/.local/bin ``` -### microxrceddsgen not found +### sim_vehicle.py not found ```bash -# Install (needed for ArduPilot DDS) -git clone --recurse-submodules https://github.com/eProsima/Micro-XRCE-DDS-Gen.git ~/Micro-XRCE-DDS-Gen -cd ~/Micro-XRCE-DDS-Gen -./gradlew assemble - -# Add to PATH -echo 'export PATH=$PATH:~/Micro-XRCE-DDS-Gen/scripts' >> ~/.bashrc -source ~/.bashrc -``` - -### Build errors - -```bash -# Rebuild with override flag -cd ~/ardu_ws -colcon build --packages-up-to ardupilot_gz_bringup --allow-overriding ros_gz_bridge ros_gz_sim sdformat_urdf +export PATH=$PATH:~/ardupilot/Tools/autotest ``` diff --git a/gazebo/worlds/iris_camera.sdf b/gazebo/worlds/iris_camera.sdf new file mode 100644 index 0000000..6992cc3 --- /dev/null +++ b/gazebo/worlds/iris_camera.sdf @@ -0,0 +1,225 @@ + + + + + + + + 0.001 + 1.0 + 1000 + + + + + + ogre2 + + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + + 0.4 0.4 0.4 1 + 0.7 0.7 0.9 1 + true + + + + + true + + + + + 0 0 1 + 100 100 + + + + + + + 0 0 1 + 100 100 + + + + 0.3 0.3 0.3 1 + 0.5 0.5 0.5 1 + + + + + + + + false + 0 0 0.02 0 0 0 + + + 50 + + + + + 1.5 1.5 0.04 + + + + + + + 1.5 1.5 0.04 + + + + 0.1 0.6 0.1 1 + 0.2 0.8 0.2 1 + + + + + 0 0 0.025 0 0 0 + + + 0.1 0.6 0.01 + + + + 1 1 1 1 + 1 1 1 1 + + + + 0 0 0.025 0 0 1.5708 + + + 0.1 0.3 0.01 + + + + 1 1 1 1 + 1 1 1 1 + + + + + + + /landing_pad/cmd_vel + + + + + + model://iris_with_ardupilot + iris + 0 0 0.195 0 0 0 + + + + + 0 2 0.5 0 0 0 + + + 1.5 + + 0.029 + 0.029 + 0.055 + + + + + + + 0.4 0.4 0.1 + + + + + + + + 0.4 0.4 0.1 + + + + 0.2 0.2 0.2 1 + 0.3 0.3 0.3 1 + + + + + + 0 0 -0.05 0 1.5708 0 + true + 30 + + 1.047 + + 640 + 480 + R8G8B8 + + + 0.1 + 100 + + + /drone/camera + + + + + true + 250 + /drone/imu + + + + + + /drone/cmd_vel + + + + + /drone/odometry + world + camera_drone + + + + + diff --git a/scripts/run_ardupilot_sim.sh b/scripts/run_ardupilot_sim.sh new file mode 100755 index 0000000..bd63213 --- /dev/null +++ b/scripts/run_ardupilot_sim.sh @@ -0,0 +1,163 @@ +#!/bin/bash +# ============================================================================= +# ArduPilot GPS-Denied Simulation Launcher +# ============================================================================= +# Launches Gazebo with GPU acceleration and camera support +# Automatically detects GPU: NVIDIA > Intel/AMD integrated > Software +# +# Usage: +# ./scripts/run_ardupilot_sim.sh # Default iris_runway +# ./scripts/run_ardupilot_sim.sh camera # With camera world +# ============================================================================= + +set -e + +echo "==============================================" +echo " ArduPilot GPS-Denied Simulation" +echo "==============================================" + +# ============================================================================= +# GPU DETECTION & CONFIGURATION +# ============================================================================= +echo "" +echo "[INFO] Detecting GPU..." + +# Disable software rendering by default +export LIBGL_ALWAYS_SOFTWARE=0 + +# Check for NVIDIA dedicated GPU +if command -v nvidia-smi &> /dev/null && nvidia-smi &> /dev/null; then + GPU_NAME=$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -1) + echo "[GPU] NVIDIA (dedicated): $GPU_NAME" + export __GLX_VENDOR_LIBRARY_NAME=nvidia + export __NV_PRIME_RENDER_OFFLOAD=1 + export __VK_LAYER_NV_optimus=NVIDIA_only + GPU_TYPE="nvidia" + +# Check for Intel integrated GPU +elif [ -d "/sys/class/drm/card0" ] && grep -qi "intel" /sys/class/drm/card0/device/vendor 2>/dev/null; then + echo "[GPU] Intel (integrated)" + export MESA_GL_VERSION_OVERRIDE=3.3 + export LIBVA_DRIVER_NAME=iHD # Intel media driver + GPU_TYPE="intel" + +# Check via glxinfo +elif command -v glxinfo &> /dev/null; then + GPU_NAME=$(glxinfo 2>/dev/null | grep "OpenGL renderer" | cut -d: -f2 | xargs) + + if [[ "$GPU_NAME" == *"NVIDIA"* ]]; then + echo "[GPU] NVIDIA: $GPU_NAME" + export __GLX_VENDOR_LIBRARY_NAME=nvidia + GPU_TYPE="nvidia" + elif [[ "$GPU_NAME" == *"Intel"* ]]; then + echo "[GPU] Intel: $GPU_NAME" + export MESA_GL_VERSION_OVERRIDE=3.3 + GPU_TYPE="intel" + elif [[ "$GPU_NAME" == *"AMD"* ]] || [[ "$GPU_NAME" == *"Radeon"* ]]; then + echo "[GPU] AMD: $GPU_NAME" + export MESA_GL_VERSION_OVERRIDE=3.3 + GPU_TYPE="amd" + elif [[ "$GPU_NAME" == *"llvmpipe"* ]] || [[ "$GPU_NAME" == *"software"* ]]; then + echo "[GPU] Software rendering (llvmpipe) - SLOW!" + echo "[WARN] Install GPU drivers for better performance" + GPU_TYPE="software" + else + echo "[GPU] $GPU_NAME" + export MESA_GL_VERSION_OVERRIDE=3.3 + GPU_TYPE="other" + fi + +# Fallback to Mesa defaults +else + echo "[GPU] Unknown - using Mesa defaults" + export MESA_GL_VERSION_OVERRIDE=3.3 + GPU_TYPE="unknown" +fi + +# For integrated graphics, ensure Mesa works well +if [[ "$GPU_TYPE" == "intel" ]] || [[ "$GPU_TYPE" == "amd" ]] || [[ "$GPU_TYPE" == "other" ]]; then + export MESA_LOADER_DRIVER_OVERRIDE="" + export DRI_PRIME=0 # Use primary GPU (integrated) +fi + +echo "[INFO] GPU type: $GPU_TYPE" + +# ============================================================================= +# GAZEBO PATHS +# ============================================================================= +export GZ_SIM_SYSTEM_PLUGIN_PATH="${HOME}/ardupilot_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH}" +export GZ_SIM_RESOURCE_PATH="${HOME}/ardupilot_gazebo/models:${HOME}/ardupilot_gazebo/worlds:${GZ_SIM_RESOURCE_PATH}" + +# Add local models +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +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" + 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" + exit 1 +fi + +# ============================================================================= +# SELECT WORLD +# ============================================================================= +WORLD_ARG="${1:-runway}" + +case "$WORLD_ARG" in + camera) + WORLD="${PROJECT_DIR}/gazebo/worlds/iris_camera.sdf" + echo "[INFO] Using camera world (with downward camera)" + ;; + runway) + WORLD="${HOME}/ardupilot_gazebo/worlds/iris_runway.sdf" + ;; + *) + WORLD="$WORLD_ARG" + ;; +esac + +if [ ! -f "$WORLD" ]; then + echo "[ERROR] World file not found: $WORLD" + echo "Available worlds:" + ls -1 ~/ardupilot_gazebo/worlds/*.sdf 2>/dev/null || echo " None in ardupilot_gazebo" + ls -1 "${PROJECT_DIR}/gazebo/worlds/"*.sdf 2>/dev/null || echo " None in local" + exit 1 +fi + +# ============================================================================= +# INSTRUCTIONS +# ============================================================================= +echo "" +echo "==============================================" +echo " Starting Gazebo" +echo "==============================================" +echo "" +echo "World: $WORLD" +echo "" +echo "After Gazebo starts, in another terminal run:" +echo "" +echo " sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console" +echo "" +echo "For GPS-DENIED mode, in MAVProxy console:" +echo "" +echo " param set ARMING_CHECK 0" +echo " mode stabilize" +echo " arm throttle force" +echo "" +echo "==============================================" +echo "" + +# ============================================================================= +# RUN GAZEBO +# ============================================================================= +gz sim -v4 -r "$WORLD"