docs: Improve quick start, ArduPilot setup, and troubleshooting, and add GPS mode option.
This commit is contained in:
60
README.md
60
README.md
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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
|
||||||
|
```
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user