diff --git a/README.md b/README.md
index da85877..0bdcb7e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# UAV-UGV Gazebo SITL Simulation
## GPS-Denied Navigation with Geofencing
-A complete simulation environment for UAV (drone) and UGV (ground vehicle) development using **GPS-denied navigation** with vision-based localization, while maintaining GPS-based geofencing for safety.
+A production-ready simulation environment for UAV (drone) and UGV (ground vehicle) development using **GPS-denied navigation** with vision-based localization, while maintaining GPS-based geofencing for safety.
## Key Feature: GPS-Denied Navigation
@@ -14,15 +14,78 @@ A complete simulation environment for UAV (drone) and UGV (ground vehicle) devel
**GPS Usage**: GPS is ONLY used for:
- Geofencing (safety boundaries)
-- Initial position reference (optional)
- NOT used for waypoint navigation
- NOT used for position control
-This simulates real-world GPS-denied environments like:
-- Indoor spaces
-- Urban canyons
-- GPS-jammed areas
-- Under bridges/tunnels
+## System Requirements
+
+- **Ubuntu 22.04 LTS** (or 24.04)
+- **16GB RAM** recommended (8GB minimum)
+- **50GB disk space** (for ArduPilot + Gazebo)
+- NVIDIA GPU recommended but not required
+
+### Supported Platforms
+- Native Ubuntu Linux
+- Windows WSL2 with Ubuntu 22.04
+
+## Installation (One Command)
+
+```bash
+# Clone the repository
+git clone https://git.sirblob.co/SirBlob/simulation.git
+cd simulation
+
+# Run the complete setup (installs everything)
+bash setup.sh
+```
+
+The setup script installs:
+- ROS 2 Humble
+- Gazebo 11
+- ArduPilot SITL
+- ardupilot_gazebo plugin
+- MAVROS
+- Python dependencies
+
+**Note**: Full installation takes 20-40 minutes depending on your internet speed.
+
+## Quick Start
+
+```bash
+# Navigate to project
+cd ~/simulation # or wherever you cloned it
+
+# Activate environment (sets up ROS 2, Gazebo, ArduPilot, Python)
+source activate_venv.sh
+
+# Run simulation
+bash scripts/run_simulation.sh
+
+# For WSL (if graphics issues):
+bash scripts/run_simulation.sh --software-render
+```
+
+## Controlling the UAV
+
+Once the simulation is running, control via ROS 2:
+
+```bash
+# Arm the drone
+ros2 service call /mavros/cmd/arming mavros_msgs/srv/CommandBool "{value: true}"
+
+# Set GUIDED mode (allows position control)
+ros2 service call /mavros/set_mode mavros_msgs/srv/SetMode "{custom_mode: 'GUIDED'}"
+
+# Takeoff to 5 meters
+ros2 service call /mavros/cmd/takeoff mavros_msgs/srv/CommandTOL "{altitude: 5}"
+
+# Fly to position (LOCAL coordinates - no GPS!)
+ros2 topic pub /mavros/setpoint_position/local geometry_msgs/PoseStamped \
+ "{header: {frame_id: 'map'}, pose: {position: {x: 10, y: 5, z: 5}}}"
+
+# Land
+ros2 service call /mavros/cmd/land mavros_msgs/srv/CommandTOL "{}"
+```
## Features
@@ -30,73 +93,10 @@ This simulates real-world GPS-denied environments like:
- **Ground vehicle (UGV)** with vision sensors
- **Visual odometry** - camera-based position estimation
- **Optical flow** - velocity estimation from downward camera
-- **Landmark navigation** - visual feature tracking
- **GPS geofencing** - safety boundaries only
-- **Single command launch** - everything runs from one script
-- **NVIDIA GPU acceleration** support
-- **Python virtual environment** for isolated dependencies
-- **GPS-denied worlds** - indoor and urban environments
-
-## System Requirements
-
-- **Ubuntu 22.04 LTS** (or 24.04 with ROS 2 Jazzy)
-- **Python 3.10+**
-- **ROS 2 Humble** (or Jazzy for Ubuntu 24.04)
-- 8GB RAM minimum (16GB recommended)
-- NVIDIA GPU recommended
-
-### WSL2 Support (Windows)
-
-This project supports **Windows Subsystem for Linux (WSL2)**:
-- Windows 10 (21H2+) or Windows 11
-- WSL2 with Ubuntu 22.04
-- GUI support via WSLg (Windows 11) or VcXsrv (Windows 10)
-- See [WSL Setup Guide](docs/wsl_setup_guide.md) for detailed instructions
-
-## Quick Start
-
-### Linux (Native)
-
-```bash
-# 1. Clone repository
-cd ~/ros2_ws/src
-git clone https://git.sirblob.co/SirBlob/simulation.git uav_ugv_simulation
-cd uav_ugv_simulation
-
-# 2. Run setup (installs everything)
-bash setup.sh
-
-# 3. Restart terminal or reload bash
-source ~/.bashrc
-
-# 4. Activate virtual environment and run
-source activate_venv.sh
-bash scripts/run_simulation.sh
-```
-
-### WSL2 (Windows)
-
-```bash
-# 1. Clone repository
-cd ~
-git clone https://git.sirblob.co/SirBlob/simulation.git uav_ugv_simulation
-cd uav_ugv_simulation
-
-# 2. Run WSL-specific setup
-bash scripts/setup_wsl.sh
-
-# 3. Restart terminal
-exit
-# Reopen WSL terminal
-
-# 4. Run simulation
-cd ~/uav_ugv_simulation
-source activate_venv.sh
-bash scripts/run_simulation.sh
-
-# If graphics are slow, use software rendering:
-bash scripts/run_simulation.sh --software-render
-```
+- **ArduPilot SITL** - real flight controller firmware
+- **MAVROS** - ROS 2 interface for MAVLink
+- **Multiple worlds** - indoor warehouse, urban canyon
## GPS-Denied Navigation Architecture
@@ -121,103 +121,57 @@ bash scripts/run_simulation.sh --software-render
│
▼
┌─────────────────────────────────────────────────────┐
-│ Navigation Controller │
-│ Commands: "Move 5m forward, 3m right" │
-│ (Relative coordinates only, NO GPS waypoints) │
+│ ArduPilot Flight Controller │
+│ Receives position via MAVROS (external nav) │
+│ Controls motors based on local setpoints │
└─────────────────────────────────────────────────────┘
-
- SEPARATE SAFETY LAYER (GPS-based):
-┌─────────────────────────────────────────────────────┐
-│ Geofence Monitor │
-│ GPS position → Check against boundaries │
-│ If outside: Emergency RTL or hold │
-└─────────────────────────────────────────────────────┘
-```
-
-## Navigation Modes
-
-### 1. **Vision-Only Mode** (Default)
-- Uses camera for all position estimates
-- Suitable for structured environments
-- Requires good lighting and visual features
-
-### 2. **Optical Flow Mode**
-- Uses downward camera for velocity
-- Works well at low altitudes
-- Good for hovering and slow flight
-
-### 3. **Hybrid Mode**
-- Combines visual odometry + optical flow + IMU
-- Most robust approach
-- Recommended for complex missions
-
-## Geofencing Configuration
-
-Edit `config/geofence_params.yaml`:
-
-```yaml
-geofence:
- enabled: true
- use_gps: true # GPS ONLY for geofence
-
- # Define boundaries (GPS coordinates)
- fence_type: "polygon" # or "circle"
-
- # Polygon fence (lat/lon points)
- polygon_points:
- - {lat: 47.397742, lon: 8.545594} # Point 1
- - {lat: 47.398242, lon: 8.545594} # Point 2
- - {lat: 47.398242, lon: 8.546094} # Point 3
- - {lat: 47.397742, lon: 8.546094} # Point 4
-
- # Or circle fence
- center_lat: 47.397742
- center_lon: 8.545594
- radius_meters: 100
-
- # Actions on breach
- action: "RTL" # Return to launch
- max_altitude: 50 # meters
-```
-
-## Example Mission (Relative Coordinates)
-
-```python
-# Example: Navigate to visual landmark
-
-# Define mission in RELATIVE coordinates
-mission_waypoints = [
- {"x": 0, "y": 0, "z": 5}, # Takeoff to 5m
- {"x": 10, "y": 0, "z": 5}, # Move 10m forward
- {"x": 10, "y": 5, "z": 5}, # Move 5m right
- {"x": 0, "y": 5, "z": 5}, # Return to start (offset)
- {"x": 0, "y": 0, "z": 5}, # Back to takeoff point
- {"x": 0, "y": 0, "z": 0}, # Land
-]
-
-# GPS is NEVER used for these waypoints
-# Position estimated from visual odometry
```
## Project Structure
-- `launch/` - ROS 2 launch files
-- `worlds/` - Gazebo world files (indoor, urban)
-- `models/` - Robot models (Iris with cameras, UGV)
-- `src/vision/` - Visual odometry, optical flow
-- `src/localization/` - Position estimation, sensor fusion
-- `src/navigation/` - Path planning (relative coordinates)
-- `src/safety/` - Geofencing (GPS-based)
-- `config/` - Configuration files
+```
+simulation/
+├── setup.sh # One-command installation
+├── activate_venv.sh # Environment activation
+├── scripts/
+│ ├── run_simulation.sh # Launch full simulation
+│ └── kill_simulation.sh # Stop all processes
+├── worlds/ # Gazebo world files
+├── models/ # UAV and UGV models
+├── src/
+│ ├── vision/ # Visual odometry, optical flow
+│ ├── localization/ # EKF sensor fusion
+│ ├── navigation/ # Path planning
+│ ├── control/ # UAV/UGV controllers
+│ └── safety/ # Geofencing
+├── config/ # Configuration files
+└── docs/ # Documentation
+```
## Documentation
-- [Setup Guide](docs/setup_guide.md) - Linux installation
-- [WSL Setup Guide](docs/wsl_setup_guide.md) - Windows WSL2 installation
-- [Usage Guide](docs/usage.md)
-- [Architecture Overview](docs/architecture.md)
-- [GPS-Denied Navigation](docs/gps_denied_navigation.md)
-- [Troubleshooting](docs/troubleshooting.md)
+- [Setup Guide](docs/setup_guide.md) - Detailed installation
+- [WSL Setup Guide](docs/wsl_setup_guide.md) - Windows WSL2
+- [Usage Guide](docs/usage.md) - How to use
+- [Architecture](docs/architecture.md) - System design
+- [GPS-Denied Navigation](docs/gps_denied_navigation.md) - Navigation approach
+- [Troubleshooting](docs/troubleshooting.md) - Common issues
+
+## Simulation Options
+
+```bash
+# Default (ArduPilot Iris world)
+bash scripts/run_simulation.sh
+
+# Custom world
+bash scripts/run_simulation.sh --world worlds/indoor_warehouse.world
+
+# Rover instead of copter
+bash scripts/run_simulation.sh --vehicle rover
+
+# Software rendering (WSL/no GPU)
+bash scripts/run_simulation.sh --software-render
+```
## Key Differences from GPS Navigation
@@ -229,25 +183,3 @@ mission_waypoints = [
| Indoor Capability | No | Yes |
| Drift | Minimal | Accumulates over time |
| Geofencing | GPS-based | GPS-based (safety only) |
-| Use Cases | Outdoor, open sky | Indoor, urban, GPS-jammed |
-
-## Running Different Scenarios
-
-```bash
-# Indoor warehouse (no GPS available)
-bash scripts/run_simulation.sh --world worlds/indoor_warehouse.world
-
-# Urban canyon (degraded GPS)
-bash scripts/run_simulation.sh --world worlds/urban_canyon.world
-
-# Open outdoor (GPS available but not used for nav)
-bash scripts/run_simulation.sh --world worlds/empty_custom.world
-```
-
-## License
-
-MIT License
-
-## Contributing
-
-Contributions welcome! Please ensure all navigation remains GPS-denied (except geofencing).
diff --git a/models/iris_with_ardupilot/model.config b/models/iris_with_ardupilot/model.config
new file mode 100644
index 0000000..899e26b
--- /dev/null
+++ b/models/iris_with_ardupilot/model.config
@@ -0,0 +1,13 @@
+
+
+ Iris with ArduPilot
+ 1.0
+ model.sdf
+
+ UAV-UGV Simulation
+
+
+ Iris quadcopter with ArduPilot SITL plugin for GPS-denied navigation testing.
+ Includes forward and downward cameras for visual odometry.
+
+
diff --git a/models/iris_with_ardupilot/model.sdf b/models/iris_with_ardupilot/model.sdf
new file mode 100644
index 0000000..cf49256
--- /dev/null
+++ b/models/iris_with_ardupilot/model.sdf
@@ -0,0 +1,311 @@
+
+
+
+ 0 0 0.194923 0 0 0
+
+
+
+ 0 0 0 0 0 0
+ 1.5
+
+ 0.029125
+ 0
+ 0
+ 0.029125
+ 0
+ 0.055225
+
+
+
+
+ 0 0 -0.08 0 0 0
+
+ 0.47 0.47 0.11
+
+
+
+
+ 0 0 0 0 0 0
+
+
+ model://iris/meshes/iris.dae
+ 1 1 1
+
+
+
+
+
+
+ 0 0 0 0 0 0
+
+ 0.3 0.3 0.1
+
+
+ 0.2 0.2 0.8 1
+ 0.2 0.2 0.8 1
+
+
+
+
+
+ true
+ 200
+
+
+ 00.0003
+ 00.0003
+ 00.0003
+
+
+ 00.017
+ 00.017
+ 00.017
+
+
+
+
+
+
+
+ 0.13 -0.22 0.023 0 0 0
+
+ 0.025
+
+ 9.75e-0600
+ 0.00016670400.000167604
+
+
+
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+
+ base_link
+ rotor_0
+
+ 0 0 1
+ -1e161e16
+
+
+
+
+
+ -0.13 0.22 0.023 0 0 0
+
+ 0.025
+
+ 9.75e-0600
+ 0.00016670400.000167604
+
+
+
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+
+ base_link
+ rotor_1
+
+ 0 0 1
+ -1e161e16
+
+
+
+
+
+ 0.13 0.22 0.023 0 0 0
+
+ 0.025
+
+ 9.75e-0600
+ 0.00016670400.000167604
+
+
+
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+
+ base_link
+ rotor_2
+
+ 0 0 1
+ -1e161e16
+
+
+
+
+
+ -0.13 -0.22 0.023 0 0 0
+
+ 0.025
+
+ 9.75e-0600
+ 0.00016670400.000167604
+
+
+
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+
+ base_link
+ rotor_3
+
+ 0 0 1
+ -1e161e16
+
+
+
+
+
+ 0.1 0 0 0 0 0
+
+ 0.01
+
+ 1e-500
+ 1e-501e-5
+
+
+
+ 0.02 0.02 0.02
+ 0 0 0 1
+
+
+
+ 1.57
+
+ 640
+ 480
+ R8G8B8
+
+ 0.1100
+
+ 1
+ 30
+ true
+
+
+ /uav
+ image_raw:=camera/forward/image_raw
+ camera_info:=camera/forward/camera_info
+
+ forward_camera
+ forward_camera_link
+
+
+
+
+ base_link
+ forward_camera_link
+
+
+
+
+ 0 0 -0.05 0 1.5708 0
+
+ 0.01
+
+ 1e-500
+ 1e-501e-5
+
+
+
+
+ 1.2
+
+ 320
+ 240
+ R8G8B8
+
+ 0.150
+
+ 1
+ 60
+ false
+
+
+ /uav
+ image_raw:=camera/downward/image_raw
+ camera_info:=camera/downward/camera_info
+
+ downward_camera
+ downward_camera_link
+
+
+
+
+ base_link
+ downward_camera_link
+
+
+
+
+ 127.0.0.1
+ 9002
+ 9003
+ 0 0 0 3.141593 0 0
+ 0 0 0 3.141593 0 0
+ iris_with_ardupilot::base_link::imu_sensor
+ 5
+
+
+
+ rotor_0_joint
+ VELOCITY
+ 0
+ 0.20
+ 0
+ 0
+ 0
+ 0
+ 2.5
+ -2.5
+ 838
+
+
+ rotor_1_joint
+ VELOCITY
+ 0
+ 0.20
+ 0
+ 0
+ 0
+ 0
+ 2.5
+ -2.5
+ 838
+
+
+ rotor_2_joint
+ VELOCITY
+ 0
+ 0.20
+ 0
+ 0
+ 0
+ 0
+ 2.5
+ -2.5
+ -838
+
+
+ rotor_3_joint
+ VELOCITY
+ 0
+ 0.20
+ 0
+ 0
+ 0
+ 0
+ 2.5
+ -2.5
+ -838
+
+
+
+
diff --git a/models/iris_with_camera/model.sdf b/models/iris_with_camera/model.sdf
index f7917bf..f5252bf 100644
--- a/models/iris_with_camera/model.sdf
+++ b/models/iris_with_camera/model.sdf
@@ -1,24 +1,90 @@
+
-
- model://iris
-
+ 0 0 0.1 0 0 0
-
- 0.1 0 0 0 0 0
+
+
- 0.01
+ 1.5
- 0.0000100
- 0.0000100.00001
+ 0.02912500
+ 0.02912500.055225
-
- 0.02 0.02 0.02
+
+
+
+
+ 0.3 0.3 0.1
+
+
+ 0.2 0.2 0.8 1
+ 0.2 0.2 0.8 1
+
+
+
+
+
+ 0.3 0.3 0.1
+
+
+
+
+
+ 0.15 0.15 0 0 0 0.785
+ 0.3 0.02 0.02
+ 0.3 0.3 0.3 1
+
+
+ -0.15 0.15 0 0 0 -0.785
+ 0.3 0.02 0.02
+ 0.3 0.3 0.3 1
+
+
+ -0.15 -0.15 0 0 0 0.785
+ 0.3 0.02 0.02
+ 0.3 0.3 0.3 1
+
+
+ 0.15 -0.15 0 0 0 -0.785
+ 0.3 0.02 0.02
+ 0.3 0.3 0.3 1
+
+
+
+
+ 0.22 0.22 0.05 0 0 0
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+ -0.22 0.22 0.05 0 0 0
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+ -0.22 -0.22 0.05 0 0 0
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+ 0.22 -0.22 0.05 0 0 0
+ 0.10.01
+ 0.1 0.1 0.1 1
+
+
+
+
+ 0.18 0 0 0 0 0
+ 0.03 0.03 0.03
0 0 0 1
+
+
+ 0.18 0 0 0 0 0
1.57
@@ -31,37 +97,11 @@
1
30
true
-
-
- /uav
- image_raw:=camera/forward/image_raw
- camera_info:=camera/forward/camera_info
-
- forward_camera
- forward_camera_link
-
-
-
-
- iris::base_link
- forward_camera_link
-
-
-
- 0 0 -0.05 0 1.5708 0
-
- 0.01
-
- 0.0000100
- 0.0000100.00001
-
-
-
- 0.02 0.02 0.02
- 0.3 0.3 0.3 1
-
+
+
+ 0 0 -0.06 0 1.5708 0
1.2
@@ -74,55 +114,7 @@
1
30
false
-
-
- /uav
- image_raw:=camera/downward/image_raw
- camera_info:=camera/downward/camera_info
-
- downward_camera
- downward_camera_link
-
-
-
- iris::base_link
- downward_camera_link
-
-
-
- 0 0 -0.06 0 1.5708 0
-
- 0.005
-
- 0.00000100
- 0.00000100.000001
-
-
-
-
-
- 1100
-
- 0.1100.01
-
- 1
- 30
-
-
- /uav
- ~/out:=rangefinder/range
-
- sensor_msgs/Range
- rangefinder_link
-
-
-
-
-
- iris::base_link
- rangefinder_link
-
diff --git a/scripts/run_simulation.sh b/scripts/run_simulation.sh
index c93743b..206ba28 100755
--- a/scripts/run_simulation.sh
+++ b/scripts/run_simulation.sh
@@ -1,7 +1,9 @@
#!/bin/bash
+# Full simulation launch script with ArduPilot SITL
+# This script launches Gazebo, ArduPilot SITL, and MAVROS
+
set -e
-# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
@@ -35,16 +37,26 @@ done
if [ -z "$ROS_DISTRO" ]; then
echo -e "${RED}ERROR: No ROS 2 installation found!${NC}"
- echo "Please install ROS 2 first. See docs/setup_guide.md or docs/wsl_setup_guide.md"
+ echo "Please install ROS 2 first. See docs/setup_guide.md"
exit 1
fi
echo -e "${GREEN}Using ROS 2: $ROS_DISTRO${NC}"
-# Source ROS 2
+# Check ArduPilot installation
+ARDUPILOT_HOME="${ARDUPILOT_HOME:-$HOME/ardupilot}"
+if [ ! -d "$ARDUPILOT_HOME" ]; then
+ echo -e "${RED}ERROR: ArduPilot not found at $ARDUPILOT_HOME${NC}"
+ echo ""
+ echo "Please install ArduPilot first:"
+ echo " bash scripts/install_ardupilot.sh"
+ echo ""
+ exit 1
+fi
+
+# Source environments
source /opt/ros/${ROS_DISTRO}/setup.bash
-# Source Gazebo setup (CRITICAL for shader paths)
if [ -f /usr/share/gazebo/setup.bash ]; then
source /usr/share/gazebo/setup.bash
elif [ -f /usr/share/gazebo-11/setup.bash ]; then
@@ -52,9 +64,10 @@ elif [ -f /usr/share/gazebo-11/setup.bash ]; then
fi
# Parse arguments
-WORLD=""
+WORLD="$PROJECT_DIR/worlds/iris_runway.world"
+VEHICLE="copter"
USE_SOFTWARE_RENDER=false
-HEADLESS=false
+INSTANCE=0
while [[ $# -gt 0 ]]; do
case $1 in
@@ -62,34 +75,32 @@ while [[ $# -gt 0 ]]; do
WORLD="$2"
shift 2
;;
- --headless)
- HEADLESS=true
- shift
+ --vehicle)
+ VEHICLE="$2"
+ shift 2
;;
- --no-gpu|--software-render)
+ --software-render)
USE_SOFTWARE_RENDER=true
shift
;;
+ --instance)
+ INSTANCE="$2"
+ shift 2
+ ;;
--help)
- echo "Usage: $0 [OPTIONS] [WORLD_FILE]"
+ echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
- echo " --world FILE Specify world file (default: empty_custom.world)"
- echo " --headless Run without GUI (gzserver only)"
- echo " --software-render Force software rendering (recommended for WSL)"
- echo " --help Show this help"
- echo ""
- echo "Examples:"
- echo " $0 # Default world"
- echo " $0 worlds/indoor_warehouse.world # Indoor environment"
- echo " $0 --software-render # For WSL without GPU"
+ echo " --world FILE World file (default: iris_runway.world)"
+ echo " --vehicle TYPE Vehicle type: copter, rover (default: copter)"
+ echo " --software-render Force software rendering (for WSL)"
+ echo " --instance N Vehicle instance number (default: 0)"
+ echo " --help Show this help"
exit 0
;;
*)
if [ -f "$1" ]; then
WORLD="$1"
- elif [ -f "$PROJECT_DIR/$1" ]; then
- WORLD="$PROJECT_DIR/$1"
elif [ -f "$PROJECT_DIR/worlds/$1" ]; then
WORLD="$PROJECT_DIR/worlds/$1"
fi
@@ -98,109 +109,172 @@ while [[ $# -gt 0 ]]; do
esac
done
-# Default world
-if [ -z "$WORLD" ]; then
- WORLD="$PROJECT_DIR/worlds/empty_custom.world"
-fi
-
-# Validate world file
-if [ ! -f "$WORLD" ]; then
- echo -e "${RED}ERROR: World file not found: $WORLD${NC}"
- echo "Available worlds:"
- ls -1 "$PROJECT_DIR/worlds/"*.world 2>/dev/null || echo " (none found)"
- exit 1
-fi
-
# Setup Gazebo paths
export GAZEBO_MODEL_PATH="$PROJECT_DIR/models:${GAZEBO_MODEL_PATH:-}"
export GAZEBO_RESOURCE_PATH="$PROJECT_DIR/worlds:${GAZEBO_RESOURCE_PATH:-}"
-# ArduPilot Gazebo paths (if installed)
if [ -d "$HOME/ardupilot_gazebo" ]; then
export GAZEBO_MODEL_PATH="$HOME/ardupilot_gazebo/models:$GAZEBO_MODEL_PATH"
export GAZEBO_RESOURCE_PATH="$HOME/ardupilot_gazebo/worlds:$GAZEBO_RESOURCE_PATH"
fi
-# WSL-specific setup
+# WSL/Display setup
if $IS_WSL; then
- # Source WSL environment if exists
if [ -f "$PROJECT_DIR/wsl_env.sh" ]; then
source "$PROJECT_DIR/wsl_env.sh"
fi
-
- # Set DISPLAY if not set
if [ -z "$DISPLAY" ]; then
- if [ -d "/mnt/wslg" ]; then
- export DISPLAY=:0
- else
- export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
- fi
+ export DISPLAY=:0
fi
-
echo -e "${BLUE}DISPLAY: $DISPLAY${NC}"
-
- # Force software rendering in WSL by default if having issues
- if ! $USE_SOFTWARE_RENDER; then
- echo -e "${YELLOW}TIP: If Gazebo crashes or has rendering issues, use --software-render${NC}"
- fi
fi
-# Apply software rendering if requested or in WSL with issues
if $USE_SOFTWARE_RENDER; then
echo -e "${YELLOW}Using software rendering${NC}"
export LIBGL_ALWAYS_SOFTWARE=1
export MESA_GL_VERSION_OVERRIDE=3.3
- export MESA_GLSL_VERSION_OVERRIDE=330
fi
# Cleanup function
cleanup() {
echo ""
echo -e "${YELLOW}Shutting down simulation...${NC}"
+
+ # Kill processes
+ pkill -f "sim_vehicle.py" 2>/dev/null || true
+ pkill -f "mavproxy" 2>/dev/null || true
+ pkill -f "ArduCopter" 2>/dev/null || true
+ pkill -f "ArduRover" 2>/dev/null || true
pkill -f "gzserver" 2>/dev/null || true
pkill -f "gzclient" 2>/dev/null || true
pkill -f "gazebo" 2>/dev/null || true
- sleep 1
+ pkill -f "mavros" 2>/dev/null || true
+
+ sleep 2
echo -e "${GREEN}Cleanup complete.${NC}"
}
trap cleanup EXIT INT TERM
-# Activate virtual environment if exists
+# Activate virtual environment
if [ -f "$PROJECT_DIR/venv/bin/activate" ]; then
source "$PROJECT_DIR/venv/bin/activate"
fi
-# Source workspace if built
-if [ -f "$PROJECT_DIR/../install/setup.bash" ]; then
- source "$PROJECT_DIR/../install/setup.bash"
-elif [ -f "$PROJECT_DIR/install/setup.bash" ]; then
- source "$PROJECT_DIR/install/setup.bash"
-fi
-
-echo ""
-echo -e "${GREEN}Starting simulation with world: $(basename $WORLD)${NC}"
-echo -e "${BLUE}World path: $WORLD${NC}"
-echo ""
-
-# Check if ROS package exists
-ROS_PKG_EXISTS=false
-if ros2 pkg list 2>/dev/null | grep -q "uav_ugv_simulation"; then
- ROS_PKG_EXISTS=true
-fi
-
-# Launch simulation
-if $ROS_PKG_EXISTS; then
- echo -e "${GREEN}Launching via ROS 2...${NC}"
- ros2 launch uav_ugv_simulation full_simulation.launch.py world:="$WORLD"
-else
- echo -e "${YELLOW}ROS package not built. Launching Gazebo directly...${NC}"
- echo -e "${BLUE}To build the package: cd ~/ros2_ws && colcon build --packages-select uav_ugv_simulation${NC}"
- echo ""
-
- if $HEADLESS; then
- gzserver --verbose "$WORLD"
+# Use ardupilot_gazebo iris world if no custom world specified
+if [ ! -f "$WORLD" ]; then
+ if [ -f "$HOME/ardupilot_gazebo/worlds/iris_arducopter_runway.world" ]; then
+ WORLD="$HOME/ardupilot_gazebo/worlds/iris_arducopter_runway.world"
else
- gazebo --verbose "$WORLD"
+ echo -e "${RED}ERROR: World file not found: $WORLD${NC}"
+ exit 1
fi
fi
+
+echo ""
+echo -e "${GREEN}Configuration:${NC}"
+echo " Vehicle: $VEHICLE"
+echo " World: $(basename $WORLD)"
+echo " Instance: $INSTANCE"
+echo ""
+
+# Calculate ports
+MAVLINK_PORT=$((14550 + INSTANCE * 10))
+SITL_PORT=$((5760 + INSTANCE * 10))
+
+# Start Gazebo in background
+echo -e "${GREEN}Starting Gazebo...${NC}"
+gazebo --verbose "$WORLD" &
+GAZEBO_PID=$!
+
+sleep 5
+
+# Check if Gazebo started
+if ! kill -0 $GAZEBO_PID 2>/dev/null; then
+ echo -e "${RED}ERROR: Gazebo failed to start${NC}"
+ exit 1
+fi
+
+echo -e "${GREEN}Gazebo running (PID: $GAZEBO_PID)${NC}"
+
+# Start ArduPilot SITL
+echo -e "${GREEN}Starting ArduPilot SITL...${NC}"
+cd "$ARDUPILOT_HOME"
+
+if [ "$VEHICLE" = "copter" ]; then
+ VEHICLE_DIR="ArduCopter"
+ FRAME="gazebo-iris"
+elif [ "$VEHICLE" = "rover" ]; then
+ VEHICLE_DIR="Rover"
+ FRAME="gazebo-rover"
+else
+ VEHICLE_DIR="ArduCopter"
+ FRAME="gazebo-iris"
+fi
+
+cd "$ARDUPILOT_HOME/$VEHICLE_DIR"
+
+# Start sim_vehicle.py in background
+python3 "$ARDUPILOT_HOME/Tools/autotest/sim_vehicle.py" \
+ -v "$VEHICLE_DIR" \
+ -f "$FRAME" \
+ --no-mavproxy \
+ -I "$INSTANCE" \
+ --no-rebuild \
+ &
+SITL_PID=$!
+
+sleep 10
+
+# Check if SITL started
+if ! kill -0 $SITL_PID 2>/dev/null; then
+ echo -e "${RED}ERROR: ArduPilot SITL failed to start${NC}"
+ exit 1
+fi
+
+echo -e "${GREEN}ArduPilot SITL running (PID: $SITL_PID)${NC}"
+
+# Start MAVROS
+echo -e "${GREEN}Starting MAVROS...${NC}"
+ros2 run mavros mavros_node --ros-args \
+ -p fcu_url:="udp://127.0.0.1:${MAVLINK_PORT}@" \
+ -p gcs_url:="" \
+ -p target_system_id:=1 \
+ -p target_component_id:=1 \
+ &>/dev/null &
+MAVROS_PID=$!
+
+sleep 5
+
+echo ""
+echo -e "${GREEN}==========================================${NC}"
+echo -e "${GREEN} Simulation Running${NC}"
+echo -e "${GREEN}==========================================${NC}"
+echo ""
+echo -e "${BLUE}Components:${NC}"
+echo " - Gazebo: PID $GAZEBO_PID"
+echo " - ArduPilot SITL: PID $SITL_PID"
+echo " - MAVROS: PID $MAVROS_PID"
+echo ""
+echo -e "${BLUE}MAVROS Topics:${NC}"
+echo " ros2 topic list | grep mavros"
+echo ""
+echo -e "${BLUE}Control UAV:${NC}"
+echo " # Arm"
+echo " ros2 service call /mavros/cmd/arming mavros_msgs/srv/CommandBool \"{value: true}\""
+echo ""
+echo " # Set mode to GUIDED"
+echo " ros2 service call /mavros/set_mode mavros_msgs/srv/SetMode \"{base_mode: 0, custom_mode: 'GUIDED'}\""
+echo ""
+echo " # Takeoff to 5 meters"
+echo " ros2 service call /mavros/cmd/takeoff mavros_msgs/srv/CommandTOL \"{altitude: 5}\""
+echo ""
+echo " # Send position setpoint (x, y, z in meters)"
+echo " ros2 topic pub /mavros/setpoint_position/local geometry_msgs/PoseStamped \\"
+echo " \"{header: {frame_id: 'map'}, pose: {position: {x: 10, y: 5, z: 5}}}\""
+echo ""
+echo -e "${YELLOW}Press Ctrl+C to stop simulation${NC}"
+echo ""
+
+# Wait for all processes
+wait
diff --git a/scripts/setup_gazebo_nvidia.sh b/scripts/setup_gazebo_nvidia.sh
deleted file mode 100755
index 8257265..0000000
--- a/scripts/setup_gazebo_nvidia.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-echo "Setting up NVIDIA GPU for Gazebo..."
-
-if ! command -v nvidia-smi &> /dev/null; then
- echo "NVIDIA driver not found. Skipping GPU setup."
- exit 0
-fi
-
-echo "NVIDIA GPU detected:"
-nvidia-smi --query-gpu=name,driver_version --format=csv,noheader
-
-export __NV_PRIME_RENDER_OFFLOAD=1
-export __GLX_VENDOR_LIBRARY_NAME=nvidia
-export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json
-
-if [ -f /usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.0 ]; then
- export __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json
-fi
-
-echo "NVIDIA GPU environment configured."
-echo ""
-echo "Add these to your ~/.bashrc for permanent setup:"
-echo " export __NV_PRIME_RENDER_OFFLOAD=1"
-echo " export __GLX_VENDOR_LIBRARY_NAME=nvidia"
diff --git a/scripts/setup_wsl.sh b/scripts/setup_wsl.sh
deleted file mode 100755
index 20ae761..0000000
--- a/scripts/setup_wsl.sh
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/bin/bash
-# WSL Quick Setup Script
-# This script sets up the simulation environment specifically for WSL2
-
-set -e
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-BLUE='\033[0;34m'
-NC='\033[0m'
-
-echo -e "${BLUE}==========================================${NC}"
-echo -e "${BLUE} UAV-UGV Simulation - WSL Setup${NC}"
-echo -e "${BLUE}==========================================${NC}"
-echo ""
-
-# Check if running in WSL
-if ! grep -qEi "(microsoft|wsl)" /proc/version 2>/dev/null; then
- echo -e "${YELLOW}This script is designed for WSL. Running anyway...${NC}"
-fi
-
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Detect Ubuntu version
-. /etc/os-release
-echo -e "${BLUE}Detected: Ubuntu $VERSION_ID ($VERSION_CODENAME)${NC}"
-
-# Determine ROS distro
-case "$VERSION_ID" in
- "22.04") ROS_DISTRO="humble" ;;
- "24.04") ROS_DISTRO="jazzy" ;;
- *) ROS_DISTRO="humble"; echo -e "${YELLOW}Unknown Ubuntu version, defaulting to Humble${NC}" ;;
-esac
-
-echo -e "${BLUE}Target ROS 2 distro: $ROS_DISTRO${NC}"
-echo ""
-
-# Step 1: Update and install prerequisites
-echo -e "${GREEN}[1/6] Installing prerequisites...${NC}"
-sudo apt-get update
-sudo apt-get install -y \
- software-properties-common \
- curl \
- gnupg \
- lsb-release \
- x11-apps \
- x11-xserver-utils \
- dbus-x11 \
- mesa-utils \
- libgl1-mesa-glx
-
-# Step 2: Add ROS 2 repository
-echo -e "${GREEN}[2/6] Adding ROS 2 repository...${NC}"
-if [ ! -f /usr/share/keyrings/ros-archive-keyring.gpg ]; then
- sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
- -o /usr/share/keyrings/ros-archive-keyring.gpg
-fi
-
-if [ ! -f /etc/apt/sources.list.d/ros2.list ]; then
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
- http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | \
- sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
-fi
-
-sudo apt-get update
-
-# Step 3: Install ROS 2
-echo -e "${GREEN}[3/6] Installing ROS 2 $ROS_DISTRO...${NC}"
-if [ ! -d "/opt/ros/$ROS_DISTRO" ]; then
- sudo apt-get install -y ros-${ROS_DISTRO}-desktop python3-colcon-common-extensions || {
- echo -e "${YELLOW}Desktop install failed, trying base...${NC}"
- sudo apt-get install -y ros-${ROS_DISTRO}-ros-base
- }
-else
- echo -e "${BLUE}ROS 2 $ROS_DISTRO already installed${NC}"
-fi
-
-# Step 4: Install ROS packages
-echo -e "${GREEN}[4/6] Installing ROS 2 packages...${NC}"
-sudo apt-get install -y \
- ros-${ROS_DISTRO}-mavros \
- ros-${ROS_DISTRO}-mavros-extras \
- ros-${ROS_DISTRO}-cv-bridge \
- ros-${ROS_DISTRO}-image-transport \
- ros-${ROS_DISTRO}-tf2-ros 2>/dev/null || {
- echo -e "${YELLOW}Some packages unavailable for $ROS_DISTRO${NC}"
-}
-
-# Gazebo (different for Humble vs Jazzy)
-if [ "$ROS_DISTRO" = "humble" ]; then
- sudo apt-get install -y ros-humble-gazebo-ros-pkgs 2>/dev/null || true
-elif [ "$ROS_DISTRO" = "jazzy" ]; then
- sudo apt-get install -y ros-jazzy-ros-gz 2>/dev/null || true
-fi
-
-# GeographicLib datasets
-echo -e "${GREEN}[5/6] Installing GeographicLib datasets...${NC}"
-GEOGRAPHICLIB_SCRIPT="/opt/ros/${ROS_DISTRO}/lib/mavros/install_geographiclib_datasets.sh"
-if [ -f "$GEOGRAPHICLIB_SCRIPT" ] && [ ! -f /usr/share/GeographicLib/geoids/egm96-5.pgm ]; then
- sudo "$GEOGRAPHICLIB_SCRIPT" || echo -e "${YELLOW}GeographicLib install failed${NC}"
-fi
-
-# Step 5: Setup Python environment
-echo -e "${GREEN}[6/6] Setting up Python environment...${NC}"
-cd "$PROJECT_DIR"
-
-sudo apt-get install -y python3-pip python3-venv python3-opencv libopencv-dev
-
-if [ ! -d "venv" ]; then
- python3 -m venv venv
-fi
-
-source venv/bin/activate
-pip install --upgrade pip
-pip install -r requirements.txt 2>/dev/null || echo -e "${YELLOW}Some pip packages failed${NC}"
-
-# Create WSL environment file
-cat > "$PROJECT_DIR/wsl_env.sh" << 'EOF'
-#!/bin/bash
-# WSL Environment Setup
-
-# DISPLAY configuration
-if [ -d "/mnt/wslg" ]; then
- # WSLg (Windows 11)
- export DISPLAY=:0
-else
- # X server (Windows 10)
- export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
-fi
-
-# OpenGL settings for WSL
-export LIBGL_ALWAYS_INDIRECT=0
-export MESA_GL_VERSION_OVERRIDE=3.3
-
-# Uncomment for software rendering if GPU issues:
-# export LIBGL_ALWAYS_SOFTWARE=1
-
-# Gazebo performance
-export OGRE_RTT_MODE=Copy
-EOF
-chmod +x "$PROJECT_DIR/wsl_env.sh"
-
-# Add to bashrc
-if ! grep -q "wsl_env.sh" ~/.bashrc 2>/dev/null; then
- echo "" >> ~/.bashrc
- echo "# UAV-UGV Simulation WSL environment" >> ~/.bashrc
- echo "[ -f \"$PROJECT_DIR/wsl_env.sh\" ] && source \"$PROJECT_DIR/wsl_env.sh\"" >> ~/.bashrc
- echo "[ -f /opt/ros/${ROS_DISTRO}/setup.bash ] && source /opt/ros/${ROS_DISTRO}/setup.bash" >> ~/.bashrc
-fi
-
-# Make scripts executable
-chmod +x "$PROJECT_DIR/scripts/"*.sh 2>/dev/null || true
-chmod +x "$PROJECT_DIR/setup.sh" 2>/dev/null || true
-chmod +x "$PROJECT_DIR/activate_venv.sh" 2>/dev/null || true
-
-echo ""
-echo -e "${GREEN}==========================================${NC}"
-echo -e "${GREEN} WSL Setup Complete!${NC}"
-echo -e "${GREEN}==========================================${NC}"
-echo ""
-echo -e "${BLUE}Next steps:${NC}"
-echo " 1. Close and reopen your terminal (or run: source ~/.bashrc)"
-echo " 2. Test GUI: xcalc (should open calculator)"
-echo " 3. Test Gazebo: gazebo --verbose"
-echo " 4. Run simulation: source activate_venv.sh && bash scripts/run_simulation.sh"
-echo ""
-echo -e "${YELLOW}WSL Tips:${NC}"
-echo " - Windows 11: GUI works out of the box (WSLg)"
-echo " - Windows 10: Install VcXsrv and run XLaunch first"
-echo " - Slow graphics? Run with: bash scripts/run_simulation.sh --software-render"
-echo " - See docs/wsl_setup_guide.md for detailed help"
-echo ""
diff --git a/setup.sh b/setup.sh
index 2225717..e4cfd8b 100755
--- a/setup.sh
+++ b/setup.sh
@@ -1,17 +1,21 @@
#!/bin/bash
+# UAV-UGV Simulation - Complete Installation Script
+# Installs everything needed for GPS-denied navigation simulation
+# Compatible with Ubuntu 22.04/24.04 and WSL2
+
set -e
-# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
-NC='\033[0m' # No Color
+CYAN='\033[0;36m'
+NC='\033[0m'
print_header() {
+ echo ""
echo -e "${BLUE}==========================================${NC}"
- echo -e "${BLUE} UAV-UGV Simulation Setup${NC}"
- echo -e "${BLUE} GPS-Denied Navigation with Geofencing${NC}"
+ echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}==========================================${NC}"
echo ""
}
@@ -20,6 +24,10 @@ print_step() {
echo -e "${GREEN}[$1/$TOTAL_STEPS] $2${NC}"
}
+print_info() {
+ echo -e "${CYAN}INFO: $1${NC}"
+}
+
print_warning() {
echo -e "${YELLOW}WARNING: $1${NC}"
}
@@ -28,21 +36,14 @@ print_error() {
echo -e "${RED}ERROR: $1${NC}"
}
-print_info() {
- echo -e "${BLUE}INFO: $1${NC}"
-}
-
# Detect environment
detect_environment() {
IS_WSL=false
IS_WSL2=false
- UBUNTU_VERSION=""
- ROS_DISTRO=""
- # Detect WSL
if grep -qEi "(microsoft|wsl)" /proc/version 2>/dev/null; then
IS_WSL=true
- if grep -qi "wsl2" /proc/version 2>/dev/null || [ -f /run/WSL ]; then
+ if [ -f /run/WSL ] || grep -qi "wsl2" /proc/version 2>/dev/null; then
IS_WSL2=true
fi
fi
@@ -54,330 +55,319 @@ detect_environment() {
UBUNTU_CODENAME="$VERSION_CODENAME"
fi
- # Determine ROS distro based on Ubuntu version
+ # Determine ROS distro
case "$UBUNTU_VERSION" in
- "22.04")
- ROS_DISTRO="humble"
- ;;
- "24.04")
- ROS_DISTRO="jazzy"
- ;;
- "20.04")
- ROS_DISTRO="galactic"
- ;;
- *)
- ROS_DISTRO="humble" # Default fallback
- ;;
+ "22.04") ROS_DISTRO="humble" ;;
+ "24.04") ROS_DISTRO="jazzy" ;;
+ "20.04") ROS_DISTRO="galactic" ;;
+ *) ROS_DISTRO="humble" ;;
esac
-
- echo -e "${BLUE}Detected Environment:${NC}"
- echo " - Ubuntu: $UBUNTU_VERSION ($UBUNTU_CODENAME)"
- echo " - WSL: $IS_WSL"
- echo " - WSL2: $IS_WSL2"
- echo " - ROS 2 Distro: $ROS_DISTRO"
- echo ""
}
-# Check if ROS 2 is installed
-check_ros2_installed() {
- if [ -d "/opt/ros/$ROS_DISTRO" ]; then
- return 0
- else
- return 1
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+cd "$SCRIPT_DIR"
+
+print_header "UAV-UGV Simulation - Complete Setup"
+echo "GPS-Denied Navigation with Geofencing"
+echo ""
+
+detect_environment
+
+echo -e "${CYAN}Detected Environment:${NC}"
+echo " Ubuntu: $UBUNTU_VERSION ($UBUNTU_CODENAME)"
+echo " WSL: $IS_WSL | WSL2: $IS_WSL2"
+echo " ROS 2 Target: $ROS_DISTRO"
+echo ""
+
+TOTAL_STEPS=10
+STEP=1
+
+# ============================================================================
+# STEP 1: System Update
+# ============================================================================
+print_step $STEP "Updating system packages"
+sudo apt-get update
+sudo apt-get upgrade -y
+((STEP++))
+
+# ============================================================================
+# STEP 2: Install Base Dependencies
+# ============================================================================
+print_step $STEP "Installing base dependencies"
+sudo apt-get install -y \
+ curl \
+ gnupg \
+ lsb-release \
+ software-properties-common \
+ wget \
+ git \
+ gitk \
+ build-essential \
+ cmake \
+ python3-dev \
+ python3-pip \
+ python3-venv \
+ python3-opencv \
+ python3-matplotlib \
+ python3-lxml \
+ python3-yaml \
+ python3-scipy \
+ python3-future \
+ libopencv-dev \
+ libxml2-dev \
+ libxslt1-dev \
+ ccache \
+ gawk \
+ libtool-bin
+
+# WSL-specific packages
+if $IS_WSL; then
+ print_info "Installing WSL GUI support packages"
+ sudo apt-get install -y \
+ x11-apps \
+ x11-xserver-utils \
+ dbus-x11 \
+ mesa-utils \
+ libgl1-mesa-glx
+fi
+((STEP++))
+
+# ============================================================================
+# STEP 3: Install ROS 2
+# ============================================================================
+print_step $STEP "Installing ROS 2 $ROS_DISTRO"
+
+if [ ! -d "/opt/ros/$ROS_DISTRO" ]; then
+ # Add ROS 2 repository
+ if [ ! -f /usr/share/keyrings/ros-archive-keyring.gpg ]; then
+ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
+ -o /usr/share/keyrings/ros-archive-keyring.gpg
fi
-}
-
-# Install ROS 2 repository
-install_ros2_repo() {
- print_info "Setting up ROS 2 repository..."
- sudo apt-get install -y software-properties-common curl gnupg lsb-release
-
- # Add ROS 2 GPG key
- sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
- -o /usr/share/keyrings/ros-archive-keyring.gpg
-
- # Add repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt-get update
-}
-
-# Setup WSL-specific configurations
-setup_wsl() {
- print_info "Configuring WSL-specific settings..."
-
- # Create WSL environment setup
- WSL_ENV_FILE="$SCRIPT_DIR/wsl_env.sh"
-
- cat > "$WSL_ENV_FILE" << 'WSLEOF'
-#!/bin/bash
-# WSL-specific environment variables
-
-# Detect WSL version and set DISPLAY
-if grep -qi "wsl2" /proc/version 2>/dev/null || [ -f /run/WSL ]; then
- # WSL2 with WSLg (Windows 11)
- if [ -d "/mnt/wslg" ]; then
- export DISPLAY=:0
- else
- # WSL2 without WSLg (Windows 10) - use X server
- export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
- fi
+ sudo apt-get install -y ros-${ROS_DISTRO}-desktop python3-colcon-common-extensions
else
- # WSL1
- export DISPLAY=localhost:0
+ print_info "ROS 2 $ROS_DISTRO already installed"
fi
-
-# Performance settings for Gazebo in WSL
-export LIBGL_ALWAYS_INDIRECT=0
-
-# If GPU acceleration isn't working, uncomment this:
-# export LIBGL_ALWAYS_SOFTWARE=1
-
-# Mesa driver settings (helps with some rendering issues)
-export MESA_GL_VERSION_OVERRIDE=3.3
-export MESA_GLSL_VERSION_OVERRIDE=330
-
-# Gazebo specific
-export OGRE_RTT_MODE=Copy
-WSLEOF
-
- chmod +x "$WSL_ENV_FILE"
-
- # Add to bashrc if not already present
- if ! grep -q "wsl_env.sh" ~/.bashrc 2>/dev/null; then
- echo "" >> ~/.bashrc
- echo "# WSL environment for UAV-UGV simulation" >> ~/.bashrc
- echo "if [ -f \"$WSL_ENV_FILE\" ]; then source \"$WSL_ENV_FILE\"; fi" >> ~/.bashrc
- fi
-
- print_info "WSL environment configured. Source ~/.bashrc to apply."
-}
-
-# Setup X11 for GUI applications
-setup_x11_wsl() {
- print_info "Installing X11 utilities for GUI support..."
-
- sudo apt-get install -y \
- x11-apps \
- x11-xserver-utils \
- dbus-x11 \
- libgl1-mesa-glx \
- mesa-utils 2>/dev/null || true
-}
-
-# Main setup
-print_header
-
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-cd "$SCRIPT_DIR"
-
-# Detect environment
-detect_environment
-
-# Determine total steps based on what's needed
-if check_ros2_installed; then
- TOTAL_STEPS=7
-else
- TOTAL_STEPS=9
- print_warning "ROS 2 $ROS_DISTRO not found. Will attempt to install."
-fi
-
-if $IS_WSL; then
- TOTAL_STEPS=$((TOTAL_STEPS + 1))
-fi
-
-STEP=1
-
-# Step: Update system
-print_step $STEP "Updating system packages..."
-sudo apt-get update
((STEP++))
-# Step: WSL-specific setup
-if $IS_WSL; then
- print_step $STEP "Setting up WSL environment..."
- setup_wsl
- setup_x11_wsl
- ((STEP++))
-fi
-
-# Step: Install ROS 2 if not present
-if ! check_ros2_installed; then
- print_step $STEP "Installing ROS 2 repository..."
- install_ros2_repo
- ((STEP++))
-
- print_step $STEP "Installing ROS 2 $ROS_DISTRO..."
- sudo apt-get install -y ros-${ROS_DISTRO}-desktop || {
- print_warning "Failed to install ros-${ROS_DISTRO}-desktop, trying base..."
- sudo apt-get install -y ros-${ROS_DISTRO}-ros-base
- }
- ((STEP++))
-fi
-
-# Step: Install system dependencies
-print_step $STEP "Installing system dependencies..."
+# ============================================================================
+# STEP 4: Install ROS 2 Packages
+# ============================================================================
+print_step $STEP "Installing ROS 2 packages"
sudo apt-get install -y \
- python3-pip \
- python3-venv \
- python3-opencv \
- libopencv-dev \
- python3-colcon-common-extensions \
- build-essential \
- cmake \
- git || true
-((STEP++))
+ ros-${ROS_DISTRO}-mavros \
+ ros-${ROS_DISTRO}-mavros-extras \
+ ros-${ROS_DISTRO}-cv-bridge \
+ ros-${ROS_DISTRO}-image-transport \
+ ros-${ROS_DISTRO}-tf2 \
+ ros-${ROS_DISTRO}-tf2-ros \
+ ros-${ROS_DISTRO}-tf2-geometry-msgs \
+ ros-${ROS_DISTRO}-gazebo-ros-pkgs 2>/dev/null || \
+ print_warning "Some ROS packages not available for $ROS_DISTRO"
-# Step: Install ROS 2 packages
-print_step $STEP "Installing ROS 2 packages..."
-ROS_PACKAGES=(
- "ros-${ROS_DISTRO}-mavros"
- "ros-${ROS_DISTRO}-mavros-extras"
- "ros-${ROS_DISTRO}-cv-bridge"
- "ros-${ROS_DISTRO}-image-transport"
- "ros-${ROS_DISTRO}-tf2"
- "ros-${ROS_DISTRO}-tf2-ros"
- "ros-${ROS_DISTRO}-tf2-geometry-msgs"
-)
-
-# Gazebo packages differ by distro
-if [ "$ROS_DISTRO" = "humble" ]; then
- ROS_PACKAGES+=("ros-${ROS_DISTRO}-gazebo-ros-pkgs")
-elif [ "$ROS_DISTRO" = "jazzy" ]; then
- # Jazzy uses Gazebo Harmonic (gz-sim)
- ROS_PACKAGES+=("ros-${ROS_DISTRO}-ros-gz")
-fi
-
-# Install available packages (some may not exist for all distros)
-for pkg in "${ROS_PACKAGES[@]}"; do
- sudo apt-get install -y "$pkg" 2>/dev/null || {
- print_warning "Package $pkg not available, skipping..."
- }
-done
-((STEP++))
-
-# Step: Install MAVROS GeographicLib datasets
-print_step $STEP "Installing MAVROS GeographicLib datasets..."
+# Install GeographicLib datasets for MAVROS
GEOGRAPHICLIB_SCRIPT="/opt/ros/${ROS_DISTRO}/lib/mavros/install_geographiclib_datasets.sh"
if [ -f "$GEOGRAPHICLIB_SCRIPT" ]; then
if [ ! -f /usr/share/GeographicLib/geoids/egm96-5.pgm ]; then
- sudo "$GEOGRAPHICLIB_SCRIPT" || print_warning "GeographicLib datasets installation failed"
- else
- print_info "GeographicLib datasets already installed"
+ print_info "Installing GeographicLib datasets (this may take a minute)"
+ sudo "$GEOGRAPHICLIB_SCRIPT" || print_warning "GeographicLib installation failed"
fi
-else
- print_warning "MAVROS not installed, skipping GeographicLib datasets"
fi
((STEP++))
-# Step: Create Python virtual environment
-print_step $STEP "Creating Python virtual environment..."
+# ============================================================================
+# STEP 5: Install Gazebo
+# ============================================================================
+print_step $STEP "Installing Gazebo"
+sudo apt-get install -y gazebo libgazebo-dev || \
+sudo apt-get install -y gazebo11 libgazebo11-dev || \
+print_warning "Gazebo installation may require manual setup"
+((STEP++))
+
+# ============================================================================
+# STEP 6: Install ArduPilot SITL
+# ============================================================================
+print_step $STEP "Installing ArduPilot SITL"
+
+ARDUPILOT_HOME="$HOME/ardupilot"
+if [ ! -d "$ARDUPILOT_HOME" ]; then
+ print_info "Cloning ArduPilot repository..."
+ cd "$HOME"
+ git clone --recurse-submodules https://github.com/ArduPilot/ardupilot.git
+ cd ardupilot
+ git submodule update --init --recursive
+else
+ print_info "ArduPilot already exists, updating..."
+ cd "$ARDUPILOT_HOME"
+ git fetch origin
+ git submodule update --init --recursive
+fi
+
+# Install ArduPilot prerequisites
+print_info "Installing ArduPilot prerequisites..."
+cd "$ARDUPILOT_HOME"
+USER_NONINTERACTIVE=1 Tools/environment_install/install-prereqs-ubuntu.sh -y || true
+
+# Reload profile
+. ~/.profile 2>/dev/null || true
+
+# Build ArduPilot SITL
+print_info "Building ArduPilot SITL (this may take several minutes)..."
+cd "$ARDUPILOT_HOME"
+./waf configure --board sitl
+./waf copter
+./waf rover
+((STEP++))
+
+# ============================================================================
+# STEP 7: Install ardupilot_gazebo Plugin
+# ============================================================================
+print_step $STEP "Installing ardupilot_gazebo plugin"
+
+ARDUPILOT_GAZEBO_HOME="$HOME/ardupilot_gazebo"
+if [ ! -d "$ARDUPILOT_GAZEBO_HOME" ]; then
+ print_info "Cloning ardupilot_gazebo..."
+ cd "$HOME"
+ git clone https://github.com/ArduPilot/ardupilot_gazebo.git
+else
+ print_info "ardupilot_gazebo already exists, updating..."
+ cd "$ARDUPILOT_GAZEBO_HOME"
+ git pull origin main || true
+fi
+
+cd "$ARDUPILOT_GAZEBO_HOME"
+mkdir -p build && cd build
+cmake ..
+make -j$(nproc)
+sudo make install
+((STEP++))
+
+# ============================================================================
+# STEP 8: Setup Python Virtual Environment
+# ============================================================================
+print_step $STEP "Setting up Python environment"
+
+cd "$SCRIPT_DIR"
+
if [ ! -d "venv" ]; then
python3 -m venv venv
fi
+
source venv/bin/activate
-
-# Upgrade pip and install dependencies
pip install --upgrade pip
-pip install -r requirements.txt || {
- print_warning "Some Python packages failed to install. Check requirements.txt"
-}
+pip install -r requirements.txt || print_warning "Some Python packages failed"
+deactivate
((STEP++))
-# Step: Build ROS 2 package
-print_step $STEP "Building ROS 2 package..."
-if [ -f "/opt/ros/${ROS_DISTRO}/setup.bash" ]; then
- source /opt/ros/${ROS_DISTRO}/setup.bash
-
- # Try to build if in a ROS workspace
- if [ -d "$SCRIPT_DIR/../src" ] || [ -f "$SCRIPT_DIR/package.xml" ]; then
- cd "$SCRIPT_DIR/.."
- colcon build --packages-select uav_ugv_simulation --symlink-install 2>/dev/null || {
- print_warning "Colcon build skipped. To build manually:"
- print_info " cd ~/ros2_ws && colcon build --packages-select uav_ugv_simulation"
- }
- cd "$SCRIPT_DIR"
- fi
+# ============================================================================
+# STEP 9: Configure Environment
+# ============================================================================
+print_step $STEP "Configuring environment"
+
+# Create WSL environment file
+if $IS_WSL; then
+ cat > "$SCRIPT_DIR/wsl_env.sh" << 'WSLEOF'
+#!/bin/bash
+# WSL Environment for UAV-UGV Simulation
+
+if [ -d "/mnt/wslg" ]; then
+ export DISPLAY=:0
else
- print_warning "ROS 2 not found, skipping package build"
+ export DISPLAY=$(cat /etc/resolv.conf 2>/dev/null | grep nameserver | awk '{print $2}'):0
fi
-((STEP++))
-# Step: Make scripts executable and create activation script
-print_step $STEP "Finalizing setup..."
-chmod +x scripts/*.sh 2>/dev/null || true
+export LIBGL_ALWAYS_INDIRECT=0
+export MESA_GL_VERSION_OVERRIDE=3.3
+export MESA_GLSL_VERSION_OVERRIDE=330
+export OGRE_RTT_MODE=Copy
+
+# Source Gazebo setup
+[ -f /usr/share/gazebo/setup.bash ] && source /usr/share/gazebo/setup.bash
+[ -f /usr/share/gazebo-11/setup.bash ] && source /usr/share/gazebo-11/setup.bash
+WSLEOF
+ chmod +x "$SCRIPT_DIR/wsl_env.sh"
+fi
# Create activation script
-cat > activate_venv.sh << EOF
+cat > "$SCRIPT_DIR/activate_venv.sh" << EOF
#!/bin/bash
SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
-# Activate Python virtual environment
+# ROS 2
+source /opt/ros/${ROS_DISTRO}/setup.bash
+
+# Gazebo
+[ -f /usr/share/gazebo/setup.bash ] && source /usr/share/gazebo/setup.bash
+[ -f /usr/share/gazebo-11/setup.bash ] && source /usr/share/gazebo-11/setup.bash
+
+# Python venv
source "\$SCRIPT_DIR/venv/bin/activate"
-# Source ROS 2
-if [ -f "/opt/ros/${ROS_DISTRO}/setup.bash" ]; then
- source /opt/ros/${ROS_DISTRO}/setup.bash
-fi
-
-# Source workspace if built
-if [ -f "\$SCRIPT_DIR/../install/setup.bash" ]; then
- source "\$SCRIPT_DIR/../install/setup.bash"
-elif [ -f "\$SCRIPT_DIR/install/setup.bash" ]; then
- source "\$SCRIPT_DIR/install/setup.bash"
-fi
-
# Gazebo paths
-export GAZEBO_MODEL_PATH="\$SCRIPT_DIR/models:\$GAZEBO_MODEL_PATH"
-export GAZEBO_RESOURCE_PATH="\$SCRIPT_DIR/worlds:\$GAZEBO_RESOURCE_PATH"
+export GAZEBO_MODEL_PATH="\$SCRIPT_DIR/models:\$HOME/ardupilot_gazebo/models:\${GAZEBO_MODEL_PATH:-}"
+export GAZEBO_RESOURCE_PATH="\$SCRIPT_DIR/worlds:\$HOME/ardupilot_gazebo/worlds:\${GAZEBO_RESOURCE_PATH:-}"
-# ArduPilot Gazebo (if installed)
-if [ -d "\$HOME/ardupilot_gazebo" ]; then
- export GAZEBO_MODEL_PATH="\$HOME/ardupilot_gazebo/models:\$GAZEBO_MODEL_PATH"
- export GAZEBO_RESOURCE_PATH="\$HOME/ardupilot_gazebo/worlds:\$GAZEBO_RESOURCE_PATH"
-fi
+# ArduPilot
+export PATH="\$PATH:\$HOME/ardupilot/Tools/autotest"
+export ARDUPILOT_HOME="\$HOME/ardupilot"
-# WSL environment (if applicable)
-if [ -f "\$SCRIPT_DIR/wsl_env.sh" ]; then
- source "\$SCRIPT_DIR/wsl_env.sh"
+# WSL
+if grep -qEi "(microsoft|wsl)" /proc/version 2>/dev/null; then
+ [ -f "\$SCRIPT_DIR/wsl_env.sh" ] && source "\$SCRIPT_DIR/wsl_env.sh"
fi
echo -e "\033[0;32mEnvironment activated (ROS 2 ${ROS_DISTRO})\033[0m"
-echo "Run: bash scripts/run_simulation.sh"
-EOF
-chmod +x activate_venv.sh
-
-# Summary
echo ""
-echo -e "${GREEN}==========================================${NC}"
-echo -e "${GREEN} Setup Complete!${NC}"
-echo -e "${GREEN}==========================================${NC}"
+echo "Run simulation: bash scripts/run_simulation.sh"
+echo "With rendering: bash scripts/run_simulation.sh --software-render"
+EOF
+chmod +x "$SCRIPT_DIR/activate_venv.sh"
+
+((STEP++))
+
+# ============================================================================
+# STEP 10: Make Scripts Executable
+# ============================================================================
+print_step $STEP "Finalizing installation"
+chmod +x "$SCRIPT_DIR/scripts/"*.sh 2>/dev/null || true
+chmod +x "$SCRIPT_DIR/activate_venv.sh" 2>/dev/null || true
+((STEP++))
+
+# ============================================================================
+# COMPLETE
+# ============================================================================
+print_header "Installation Complete!"
+
+echo -e "${GREEN}All components installed:${NC}"
+echo " - ROS 2 $ROS_DISTRO"
+echo " - Gazebo"
+echo " - ArduPilot SITL ($ARDUPILOT_HOME)"
+echo " - ardupilot_gazebo ($ARDUPILOT_GAZEBO_HOME)"
+echo " - MAVROS"
+echo " - Python dependencies"
echo ""
if $IS_WSL; then
echo -e "${YELLOW}WSL Setup Notes:${NC}"
- echo " - WSL environment file created: wsl_env.sh"
- echo " - For GUI apps, ensure X server is running (Windows 11 has WSLg built-in)"
- echo " - See docs/wsl_setup_guide.md for detailed instructions"
+ echo " - GUI apps require WSLg (Windows 11) or VcXsrv (Windows 10)"
+ echo " - Use --software-render flag if graphics are slow"
echo ""
fi
-echo -e "${BLUE}Next steps:${NC}"
-echo " 1. source ~/.bashrc"
-echo " 2. source activate_venv.sh"
-echo " 3. bash scripts/run_simulation.sh"
+echo -e "${CYAN}To run the simulation:${NC}"
echo ""
-echo -e "${BLUE}GPS-Denied Navigation:${NC}"
-echo " - All navigation uses LOCAL coordinates"
-echo " - GPS is ONLY used for geofencing"
+echo " cd $SCRIPT_DIR"
+echo " source activate_venv.sh"
+echo " bash scripts/run_simulation.sh"
+if $IS_WSL; then
echo ""
-
-if ! check_ros2_installed && [ ! -f "/opt/ros/${ROS_DISTRO}/setup.bash" ]; then
- echo -e "${YELLOW}IMPORTANT:${NC}"
- echo " ROS 2 installation may have failed. Please install manually:"
- echo " See: https://docs.ros.org/en/${ROS_DISTRO}/Installation.html"
- echo ""
+echo " # Or with software rendering for WSL:"
+echo " bash scripts/run_simulation.sh --software-render"
fi
+echo ""
+echo -e "${GREEN}==========================================${NC}"
diff --git a/worlds/empty_custom.world b/worlds/empty_custom.world
index 20751dd..2fc7a46 100644
--- a/worlds/empty_custom.world
+++ b/worlds/empty_custom.world
@@ -15,6 +15,21 @@
model://ground_plane
+
+
+ model://iris_with_camera
+ uav
+ 0 0 0.1 0 0 0
+
+
+
+
+ model://custom_ugv
+ ugv
+ 2 2 0.1 0 0 0
+
+
+
true
@@ -55,6 +70,7 @@
+
true
0 0 0.01 0 0 0
@@ -74,6 +90,7 @@
+
EARTH_WGS84
47.397742
diff --git a/worlds/iris_runway.world b/worlds/iris_runway.world
new file mode 100644
index 0000000..d33d790
--- /dev/null
+++ b/worlds/iris_runway.world
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+ quick
+ 100
+ 1.0
+
+
+ 0.0
+ 0.9
+ 0.1
+ 0.0
+
+
+ 0.001
+ 1.0
+ 1000
+
+
+
+ model://sun
+
+
+
+ model://ground_plane
+
+
+
+
+
+ model://iris_with_ardupilot
+
+
+
+
+
+ true
+ 10 0 0.01 0 0 0
+
+
+ 1 1 0.02
+
+ 1 0 0 1
+ 1 0 0 1
+
+
+
+
+
+
+ true
+ 10 10 0.01 0 0 0
+
+
+ 1 1 0.02
+
+ 0 1 0 1
+ 0 1 0 1
+
+
+
+
+
+
+ true
+ 0 10 0.01 0 0 0
+
+
+ 1 1 0.02
+
+ 0 0 1 1
+ 0 0 1 1
+
+
+
+
+
+
+ true
+ 0 0 0.01 0 0 0
+
+
+
+ 0.50.02
+
+
+ 1 1 0 1
+ 1 1 0 1
+
+
+
+
+
+
+
+ EARTH_WGS84
+ -35.363262
+ 149.165237
+ 584
+ 0
+
+
+