Update Install Scripts
This commit is contained in:
300
README.md
300
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).
|
||||
|
||||
13
models/iris_with_ardupilot/model.config
Normal file
13
models/iris_with_ardupilot/model.config
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<model>
|
||||
<name>Iris with ArduPilot</name>
|
||||
<version>1.0</version>
|
||||
<sdf version="1.6">model.sdf</sdf>
|
||||
<author>
|
||||
<name>UAV-UGV Simulation</name>
|
||||
</author>
|
||||
<description>
|
||||
Iris quadcopter with ArduPilot SITL plugin for GPS-denied navigation testing.
|
||||
Includes forward and downward cameras for visual odometry.
|
||||
</description>
|
||||
</model>
|
||||
311
models/iris_with_ardupilot/model.sdf
Normal file
311
models/iris_with_ardupilot/model.sdf
Normal file
@@ -0,0 +1,311 @@
|
||||
<?xml version="1.0" ?>
|
||||
<sdf version="1.6">
|
||||
<model name="iris_with_ardupilot">
|
||||
<pose>0 0 0.194923 0 0 0</pose>
|
||||
|
||||
<link name="base_link">
|
||||
<inertial>
|
||||
<pose>0 0 0 0 0 0</pose>
|
||||
<mass>1.5</mass>
|
||||
<inertia>
|
||||
<ixx>0.029125</ixx>
|
||||
<ixy>0</ixy>
|
||||
<ixz>0</ixz>
|
||||
<iyy>0.029125</iyy>
|
||||
<iyz>0</iyz>
|
||||
<izz>0.055225</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
|
||||
<collision name="base_collision">
|
||||
<pose>0 0 -0.08 0 0 0</pose>
|
||||
<geometry>
|
||||
<box><size>0.47 0.47 0.11</size></box>
|
||||
</geometry>
|
||||
</collision>
|
||||
|
||||
<visual name="base_visual">
|
||||
<pose>0 0 0 0 0 0</pose>
|
||||
<geometry>
|
||||
<mesh>
|
||||
<uri>model://iris/meshes/iris.dae</uri>
|
||||
<scale>1 1 1</scale>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</visual>
|
||||
|
||||
<!-- Fallback visual if mesh not found -->
|
||||
<visual name="body_box">
|
||||
<pose>0 0 0 0 0 0</pose>
|
||||
<geometry>
|
||||
<box><size>0.3 0.3 0.1</size></box>
|
||||
</geometry>
|
||||
<material>
|
||||
<ambient>0.2 0.2 0.8 1</ambient>
|
||||
<diffuse>0.2 0.2 0.8 1</diffuse>
|
||||
</material>
|
||||
</visual>
|
||||
|
||||
<!-- IMU Sensor -->
|
||||
<sensor name="imu_sensor" type="imu">
|
||||
<always_on>true</always_on>
|
||||
<update_rate>200</update_rate>
|
||||
<imu>
|
||||
<angular_velocity>
|
||||
<x><noise type="gaussian"><mean>0</mean><stddev>0.0003</stddev></noise></x>
|
||||
<y><noise type="gaussian"><mean>0</mean><stddev>0.0003</stddev></noise></y>
|
||||
<z><noise type="gaussian"><mean>0</mean><stddev>0.0003</stddev></noise></z>
|
||||
</angular_velocity>
|
||||
<linear_acceleration>
|
||||
<x><noise type="gaussian"><mean>0</mean><stddev>0.017</stddev></noise></x>
|
||||
<y><noise type="gaussian"><mean>0</mean><stddev>0.017</stddev></noise></y>
|
||||
<z><noise type="gaussian"><mean>0</mean><stddev>0.017</stddev></noise></z>
|
||||
</linear_acceleration>
|
||||
</imu>
|
||||
</sensor>
|
||||
</link>
|
||||
|
||||
<!-- Rotor 0 (Front Right CW) -->
|
||||
<link name="rotor_0">
|
||||
<pose>0.13 -0.22 0.023 0 0 0</pose>
|
||||
<inertial>
|
||||
<mass>0.025</mass>
|
||||
<inertia>
|
||||
<ixx>9.75e-06</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.000166704</iyy><iyz>0</iyz><izz>0.000167604</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
</link>
|
||||
<joint name="rotor_0_joint" type="revolute">
|
||||
<parent>base_link</parent>
|
||||
<child>rotor_0</child>
|
||||
<axis>
|
||||
<xyz>0 0 1</xyz>
|
||||
<limit><lower>-1e16</lower><upper>1e16</upper></limit>
|
||||
</axis>
|
||||
</joint>
|
||||
|
||||
<!-- Rotor 1 (Back Left CW) -->
|
||||
<link name="rotor_1">
|
||||
<pose>-0.13 0.22 0.023 0 0 0</pose>
|
||||
<inertial>
|
||||
<mass>0.025</mass>
|
||||
<inertia>
|
||||
<ixx>9.75e-06</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.000166704</iyy><iyz>0</iyz><izz>0.000167604</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
</link>
|
||||
<joint name="rotor_1_joint" type="revolute">
|
||||
<parent>base_link</parent>
|
||||
<child>rotor_1</child>
|
||||
<axis>
|
||||
<xyz>0 0 1</xyz>
|
||||
<limit><lower>-1e16</lower><upper>1e16</upper></limit>
|
||||
</axis>
|
||||
</joint>
|
||||
|
||||
<!-- Rotor 2 (Front Left CCW) -->
|
||||
<link name="rotor_2">
|
||||
<pose>0.13 0.22 0.023 0 0 0</pose>
|
||||
<inertial>
|
||||
<mass>0.025</mass>
|
||||
<inertia>
|
||||
<ixx>9.75e-06</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.000166704</iyy><iyz>0</iyz><izz>0.000167604</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
</link>
|
||||
<joint name="rotor_2_joint" type="revolute">
|
||||
<parent>base_link</parent>
|
||||
<child>rotor_2</child>
|
||||
<axis>
|
||||
<xyz>0 0 1</xyz>
|
||||
<limit><lower>-1e16</lower><upper>1e16</upper></limit>
|
||||
</axis>
|
||||
</joint>
|
||||
|
||||
<!-- Rotor 3 (Back Right CCW) -->
|
||||
<link name="rotor_3">
|
||||
<pose>-0.13 -0.22 0.023 0 0 0</pose>
|
||||
<inertial>
|
||||
<mass>0.025</mass>
|
||||
<inertia>
|
||||
<ixx>9.75e-06</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.000166704</iyy><iyz>0</iyz><izz>0.000167604</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
</link>
|
||||
<joint name="rotor_3_joint" type="revolute">
|
||||
<parent>base_link</parent>
|
||||
<child>rotor_3</child>
|
||||
<axis>
|
||||
<xyz>0 0 1</xyz>
|
||||
<limit><lower>-1e16</lower><upper>1e16</upper></limit>
|
||||
</axis>
|
||||
</joint>
|
||||
|
||||
<!-- Forward Camera for Visual Odometry -->
|
||||
<link name="forward_camera_link">
|
||||
<pose>0.1 0 0 0 0 0</pose>
|
||||
<inertial>
|
||||
<mass>0.01</mass>
|
||||
<inertia>
|
||||
<ixx>1e-5</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>1e-5</iyy><iyz>0</iyz><izz>1e-5</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><box><size>0.02 0.02 0.02</size></box></geometry>
|
||||
<material><ambient>0 0 0 1</ambient></material>
|
||||
</visual>
|
||||
<sensor name="forward_camera" type="camera">
|
||||
<camera>
|
||||
<horizontal_fov>1.57</horizontal_fov>
|
||||
<image>
|
||||
<width>640</width>
|
||||
<height>480</height>
|
||||
<format>R8G8B8</format>
|
||||
</image>
|
||||
<clip><near>0.1</near><far>100</far></clip>
|
||||
</camera>
|
||||
<always_on>1</always_on>
|
||||
<update_rate>30</update_rate>
|
||||
<visualize>true</visualize>
|
||||
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
|
||||
<ros>
|
||||
<namespace>/uav</namespace>
|
||||
<remapping>image_raw:=camera/forward/image_raw</remapping>
|
||||
<remapping>camera_info:=camera/forward/camera_info</remapping>
|
||||
</ros>
|
||||
<camera_name>forward_camera</camera_name>
|
||||
<frame_name>forward_camera_link</frame_name>
|
||||
</plugin>
|
||||
</sensor>
|
||||
</link>
|
||||
<joint name="forward_camera_joint" type="fixed">
|
||||
<parent>base_link</parent>
|
||||
<child>forward_camera_link</child>
|
||||
</joint>
|
||||
|
||||
<!-- Downward Camera for Optical Flow -->
|
||||
<link name="downward_camera_link">
|
||||
<pose>0 0 -0.05 0 1.5708 0</pose>
|
||||
<inertial>
|
||||
<mass>0.01</mass>
|
||||
<inertia>
|
||||
<ixx>1e-5</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>1e-5</iyy><iyz>0</iyz><izz>1e-5</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<sensor name="downward_camera" type="camera">
|
||||
<camera>
|
||||
<horizontal_fov>1.2</horizontal_fov>
|
||||
<image>
|
||||
<width>320</width>
|
||||
<height>240</height>
|
||||
<format>R8G8B8</format>
|
||||
</image>
|
||||
<clip><near>0.1</near><far>50</far></clip>
|
||||
</camera>
|
||||
<always_on>1</always_on>
|
||||
<update_rate>60</update_rate>
|
||||
<visualize>false</visualize>
|
||||
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
|
||||
<ros>
|
||||
<namespace>/uav</namespace>
|
||||
<remapping>image_raw:=camera/downward/image_raw</remapping>
|
||||
<remapping>camera_info:=camera/downward/camera_info</remapping>
|
||||
</ros>
|
||||
<camera_name>downward_camera</camera_name>
|
||||
<frame_name>downward_camera_link</frame_name>
|
||||
</plugin>
|
||||
</sensor>
|
||||
</link>
|
||||
<joint name="downward_camera_joint" type="fixed">
|
||||
<parent>base_link</parent>
|
||||
<child>downward_camera_link</child>
|
||||
</joint>
|
||||
|
||||
<!-- ArduPilot Plugin -->
|
||||
<plugin name="ardupilot_plugin" filename="libArduPilotPlugin.so">
|
||||
<fdm_addr>127.0.0.1</fdm_addr>
|
||||
<fdm_port_in>9002</fdm_port_in>
|
||||
<fdm_port_out>9003</fdm_port_out>
|
||||
<modelXYZToAirplaneXForwardZDown>0 0 0 3.141593 0 0</modelXYZToAirplaneXForwardZDown>
|
||||
<gazeboXYZToNED>0 0 0 3.141593 0 0</gazeboXYZToNED>
|
||||
<imuName>iris_with_ardupilot::base_link::imu_sensor</imuName>
|
||||
<connectionTimeoutMaxCount>5</connectionTimeoutMaxCount>
|
||||
|
||||
<!-- Motor configuration -->
|
||||
<control channel="0">
|
||||
<jointName>rotor_0_joint</jointName>
|
||||
<type>VELOCITY</type>
|
||||
<offset>0</offset>
|
||||
<p_gain>0.20</p_gain>
|
||||
<i_gain>0</i_gain>
|
||||
<d_gain>0</d_gain>
|
||||
<i_max>0</i_max>
|
||||
<i_min>0</i_min>
|
||||
<cmd_max>2.5</cmd_max>
|
||||
<cmd_min>-2.5</cmd_min>
|
||||
<multiplier>838</multiplier>
|
||||
</control>
|
||||
<control channel="1">
|
||||
<jointName>rotor_1_joint</jointName>
|
||||
<type>VELOCITY</type>
|
||||
<offset>0</offset>
|
||||
<p_gain>0.20</p_gain>
|
||||
<i_gain>0</i_gain>
|
||||
<d_gain>0</d_gain>
|
||||
<i_max>0</i_max>
|
||||
<i_min>0</i_min>
|
||||
<cmd_max>2.5</cmd_max>
|
||||
<cmd_min>-2.5</cmd_min>
|
||||
<multiplier>838</multiplier>
|
||||
</control>
|
||||
<control channel="2">
|
||||
<jointName>rotor_2_joint</jointName>
|
||||
<type>VELOCITY</type>
|
||||
<offset>0</offset>
|
||||
<p_gain>0.20</p_gain>
|
||||
<i_gain>0</i_gain>
|
||||
<d_gain>0</d_gain>
|
||||
<i_max>0</i_max>
|
||||
<i_min>0</i_min>
|
||||
<cmd_max>2.5</cmd_max>
|
||||
<cmd_min>-2.5</cmd_min>
|
||||
<multiplier>-838</multiplier>
|
||||
</control>
|
||||
<control channel="3">
|
||||
<jointName>rotor_3_joint</jointName>
|
||||
<type>VELOCITY</type>
|
||||
<offset>0</offset>
|
||||
<p_gain>0.20</p_gain>
|
||||
<i_gain>0</i_gain>
|
||||
<d_gain>0</d_gain>
|
||||
<i_max>0</i_max>
|
||||
<i_min>0</i_min>
|
||||
<cmd_max>2.5</cmd_max>
|
||||
<cmd_min>-2.5</cmd_min>
|
||||
<multiplier>-838</multiplier>
|
||||
</control>
|
||||
</plugin>
|
||||
</model>
|
||||
</sdf>
|
||||
@@ -1,24 +1,90 @@
|
||||
<?xml version="1.0" ?>
|
||||
<sdf version="1.6">
|
||||
<!-- Simple quadcopter model for testing without ArduPilot -->
|
||||
<model name="iris_with_camera">
|
||||
<include>
|
||||
<uri>model://iris</uri>
|
||||
</include>
|
||||
<pose>0 0 0.1 0 0 0</pose>
|
||||
|
||||
<link name="forward_camera_link">
|
||||
<pose>0.1 0 0 0 0 0</pose>
|
||||
<!-- Base/Body -->
|
||||
<link name="base_link">
|
||||
<inertial>
|
||||
<mass>0.01</mass>
|
||||
<mass>1.5</mass>
|
||||
<inertia>
|
||||
<ixx>0.00001</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.00001</iyy><iyz>0</iyz><izz>0.00001</izz>
|
||||
<ixx>0.029125</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.029125</iyy><iyz>0</iyz><izz>0.055225</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><box><size>0.02 0.02 0.02</size></box></geometry>
|
||||
|
||||
<!-- Main body -->
|
||||
<visual name="body_visual">
|
||||
<geometry>
|
||||
<box><size>0.3 0.3 0.1</size></box>
|
||||
</geometry>
|
||||
<material>
|
||||
<ambient>0.2 0.2 0.8 1</ambient>
|
||||
<diffuse>0.2 0.2 0.8 1</diffuse>
|
||||
</material>
|
||||
</visual>
|
||||
|
||||
<collision name="body_collision">
|
||||
<geometry>
|
||||
<box><size>0.3 0.3 0.1</size></box>
|
||||
</geometry>
|
||||
</collision>
|
||||
|
||||
<!-- Arms -->
|
||||
<visual name="arm1_visual">
|
||||
<pose>0.15 0.15 0 0 0 0.785</pose>
|
||||
<geometry><box><size>0.3 0.02 0.02</size></box></geometry>
|
||||
<material><ambient>0.3 0.3 0.3 1</ambient></material>
|
||||
</visual>
|
||||
<visual name="arm2_visual">
|
||||
<pose>-0.15 0.15 0 0 0 -0.785</pose>
|
||||
<geometry><box><size>0.3 0.02 0.02</size></box></geometry>
|
||||
<material><ambient>0.3 0.3 0.3 1</ambient></material>
|
||||
</visual>
|
||||
<visual name="arm3_visual">
|
||||
<pose>-0.15 -0.15 0 0 0 0.785</pose>
|
||||
<geometry><box><size>0.3 0.02 0.02</size></box></geometry>
|
||||
<material><ambient>0.3 0.3 0.3 1</ambient></material>
|
||||
</visual>
|
||||
<visual name="arm4_visual">
|
||||
<pose>0.15 -0.15 0 0 0 -0.785</pose>
|
||||
<geometry><box><size>0.3 0.02 0.02</size></box></geometry>
|
||||
<material><ambient>0.3 0.3 0.3 1</ambient></material>
|
||||
</visual>
|
||||
|
||||
<!-- Rotors -->
|
||||
<visual name="rotor1">
|
||||
<pose>0.22 0.22 0.05 0 0 0</pose>
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
<visual name="rotor2">
|
||||
<pose>-0.22 0.22 0.05 0 0 0</pose>
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
<visual name="rotor3">
|
||||
<pose>-0.22 -0.22 0.05 0 0 0</pose>
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
<visual name="rotor4">
|
||||
<pose>0.22 -0.22 0.05 0 0 0</pose>
|
||||
<geometry><cylinder><radius>0.1</radius><length>0.01</length></cylinder></geometry>
|
||||
<material><ambient>0.1 0.1 0.1 1</ambient></material>
|
||||
</visual>
|
||||
|
||||
<!-- Forward camera (small black box) -->
|
||||
<visual name="forward_camera_visual">
|
||||
<pose>0.18 0 0 0 0 0</pose>
|
||||
<geometry><box><size>0.03 0.03 0.03</size></box></geometry>
|
||||
<material><ambient>0 0 0 1</ambient></material>
|
||||
</visual>
|
||||
|
||||
<!-- Forward Camera Sensor -->
|
||||
<sensor name="forward_camera" type="camera">
|
||||
<pose>0.18 0 0 0 0 0</pose>
|
||||
<camera>
|
||||
<horizontal_fov>1.57</horizontal_fov>
|
||||
<image>
|
||||
@@ -31,37 +97,11 @@
|
||||
<always_on>1</always_on>
|
||||
<update_rate>30</update_rate>
|
||||
<visualize>true</visualize>
|
||||
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
|
||||
<ros>
|
||||
<namespace>/uav</namespace>
|
||||
<remapping>image_raw:=camera/forward/image_raw</remapping>
|
||||
<remapping>camera_info:=camera/forward/camera_info</remapping>
|
||||
</ros>
|
||||
<camera_name>forward_camera</camera_name>
|
||||
<frame_name>forward_camera_link</frame_name>
|
||||
</plugin>
|
||||
</sensor>
|
||||
</link>
|
||||
|
||||
<joint name="forward_camera_joint" type="fixed">
|
||||
<parent>iris::base_link</parent>
|
||||
<child>forward_camera_link</child>
|
||||
</joint>
|
||||
|
||||
<link name="downward_camera_link">
|
||||
<pose>0 0 -0.05 0 1.5708 0</pose>
|
||||
<inertial>
|
||||
<mass>0.01</mass>
|
||||
<inertia>
|
||||
<ixx>0.00001</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.00001</iyy><iyz>0</iyz><izz>0.00001</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<visual name="visual">
|
||||
<geometry><box><size>0.02 0.02 0.02</size></box></geometry>
|
||||
<material><ambient>0.3 0.3 0.3 1</ambient></material>
|
||||
</visual>
|
||||
<!-- Downward Camera Sensor -->
|
||||
<sensor name="downward_camera" type="camera">
|
||||
<pose>0 0 -0.06 0 1.5708 0</pose>
|
||||
<camera>
|
||||
<horizontal_fov>1.2</horizontal_fov>
|
||||
<image>
|
||||
@@ -74,55 +114,7 @@
|
||||
<always_on>1</always_on>
|
||||
<update_rate>30</update_rate>
|
||||
<visualize>false</visualize>
|
||||
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
|
||||
<ros>
|
||||
<namespace>/uav</namespace>
|
||||
<remapping>image_raw:=camera/downward/image_raw</remapping>
|
||||
<remapping>camera_info:=camera/downward/camera_info</remapping>
|
||||
</ros>
|
||||
<camera_name>downward_camera</camera_name>
|
||||
<frame_name>downward_camera_link</frame_name>
|
||||
</plugin>
|
||||
</sensor>
|
||||
</link>
|
||||
|
||||
<joint name="downward_camera_joint" type="fixed">
|
||||
<parent>iris::base_link</parent>
|
||||
<child>downward_camera_link</child>
|
||||
</joint>
|
||||
|
||||
<link name="rangefinder_link">
|
||||
<pose>0 0 -0.06 0 1.5708 0</pose>
|
||||
<inertial>
|
||||
<mass>0.005</mass>
|
||||
<inertia>
|
||||
<ixx>0.000001</ixx><ixy>0</ixy><ixz>0</ixz>
|
||||
<iyy>0.000001</iyy><iyz>0</iyz><izz>0.000001</izz>
|
||||
</inertia>
|
||||
</inertial>
|
||||
<sensor name="rangefinder" type="ray">
|
||||
<ray>
|
||||
<scan>
|
||||
<horizontal><samples>1</samples><resolution>1</resolution><min_angle>0</min_angle><max_angle>0</max_angle></horizontal>
|
||||
</scan>
|
||||
<range><min>0.1</min><max>10</max><resolution>0.01</resolution></range>
|
||||
</ray>
|
||||
<always_on>1</always_on>
|
||||
<update_rate>30</update_rate>
|
||||
<plugin name="range_plugin" filename="libgazebo_ros_ray_sensor.so">
|
||||
<ros>
|
||||
<namespace>/uav</namespace>
|
||||
<remapping>~/out:=rangefinder/range</remapping>
|
||||
</ros>
|
||||
<output_type>sensor_msgs/Range</output_type>
|
||||
<frame_name>rangefinder_link</frame_name>
|
||||
</plugin>
|
||||
</sensor>
|
||||
</link>
|
||||
|
||||
<joint name="rangefinder_joint" type="fixed">
|
||||
<parent>iris::base_link</parent>
|
||||
<child>rangefinder_link</child>
|
||||
</joint>
|
||||
</model>
|
||||
</sdf>
|
||||
|
||||
@@ -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 " --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"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 # Default world"
|
||||
echo " $0 worlds/indoor_warehouse.world # Indoor environment"
|
||||
echo " $0 --software-render # For WSL without GPU"
|
||||
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
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
@@ -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 ""
|
||||
542
setup.sh
542
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
|
||||
fi
|
||||
}
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Install ROS 2 repository
|
||||
install_ros2_repo() {
|
||||
print_info "Setting up ROS 2 repository..."
|
||||
print_header "UAV-UGV Simulation - Complete Setup"
|
||||
echo "GPS-Denied Navigation with Geofencing"
|
||||
echo ""
|
||||
|
||||
sudo apt-get install -y software-properties-common curl gnupg lsb-release
|
||||
detect_environment
|
||||
|
||||
# Add ROS 2 GPG key
|
||||
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
|
||||
|
||||
# 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
|
||||
# ============================================================================
|
||||
# STEP 9: Configure Environment
|
||||
# ============================================================================
|
||||
print_step $STEP "Configuring environment"
|
||||
|
||||
# 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
|
||||
# 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}"
|
||||
|
||||
@@ -15,6 +15,21 @@
|
||||
<uri>model://ground_plane</uri>
|
||||
</include>
|
||||
|
||||
<!-- UAV - Iris Quadcopter with Cameras -->
|
||||
<include>
|
||||
<uri>model://iris_with_camera</uri>
|
||||
<name>uav</name>
|
||||
<pose>0 0 0.1 0 0 0</pose>
|
||||
</include>
|
||||
|
||||
<!-- UGV - Ground Vehicle -->
|
||||
<include>
|
||||
<uri>model://custom_ugv</uri>
|
||||
<name>ugv</name>
|
||||
<pose>2 2 0.1 0 0 0</pose>
|
||||
</include>
|
||||
|
||||
<!-- Visual Markers for GPS-Denied Navigation -->
|
||||
<model name="visual_markers">
|
||||
<static>true</static>
|
||||
<link name="marker_0">
|
||||
@@ -55,6 +70,7 @@
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<!-- Origin Marker (Yellow) -->
|
||||
<model name="origin_marker">
|
||||
<static>true</static>
|
||||
<pose>0 0 0.01 0 0 0</pose>
|
||||
@@ -74,6 +90,7 @@
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<!-- Spherical coordinates for geofencing reference -->
|
||||
<spherical_coordinates>
|
||||
<surface_model>EARTH_WGS84</surface_model>
|
||||
<latitude_deg>47.397742</latitude_deg>
|
||||
|
||||
106
worlds/iris_runway.world
Normal file
106
worlds/iris_runway.world
Normal file
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" ?>
|
||||
<sdf version="1.6">
|
||||
<world name="iris_runway">
|
||||
<physics type="ode">
|
||||
<ode>
|
||||
<solver>
|
||||
<type>quick</type>
|
||||
<iters>100</iters>
|
||||
<sor>1.0</sor>
|
||||
</solver>
|
||||
<constraints>
|
||||
<cfm>0.0</cfm>
|
||||
<erp>0.9</erp>
|
||||
<contact_max_correcting_vel>0.1</contact_max_correcting_vel>
|
||||
<contact_surface_layer>0.0</contact_surface_layer>
|
||||
</constraints>
|
||||
</ode>
|
||||
<max_step_size>0.001</max_step_size>
|
||||
<real_time_factor>1.0</real_time_factor>
|
||||
<real_time_update_rate>1000</real_time_update_rate>
|
||||
</physics>
|
||||
|
||||
<include>
|
||||
<uri>model://sun</uri>
|
||||
</include>
|
||||
|
||||
<include>
|
||||
<uri>model://ground_plane</uri>
|
||||
</include>
|
||||
|
||||
<!-- ArduPilot Iris Quadcopter -->
|
||||
<model name="iris">
|
||||
<include>
|
||||
<uri>model://iris_with_ardupilot</uri>
|
||||
</include>
|
||||
</model>
|
||||
|
||||
<!-- Visual Navigation Markers -->
|
||||
<model name="marker_red">
|
||||
<static>true</static>
|
||||
<pose>10 0 0.01 0 0 0</pose>
|
||||
<link name="link">
|
||||
<visual name="visual">
|
||||
<geometry><box><size>1 1 0.02</size></box></geometry>
|
||||
<material>
|
||||
<ambient>1 0 0 1</ambient>
|
||||
<diffuse>1 0 0 1</diffuse>
|
||||
</material>
|
||||
</visual>
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<model name="marker_green">
|
||||
<static>true</static>
|
||||
<pose>10 10 0.01 0 0 0</pose>
|
||||
<link name="link">
|
||||
<visual name="visual">
|
||||
<geometry><box><size>1 1 0.02</size></box></geometry>
|
||||
<material>
|
||||
<ambient>0 1 0 1</ambient>
|
||||
<diffuse>0 1 0 1</diffuse>
|
||||
</material>
|
||||
</visual>
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<model name="marker_blue">
|
||||
<static>true</static>
|
||||
<pose>0 10 0.01 0 0 0</pose>
|
||||
<link name="link">
|
||||
<visual name="visual">
|
||||
<geometry><box><size>1 1 0.02</size></box></geometry>
|
||||
<material>
|
||||
<ambient>0 0 1 1</ambient>
|
||||
<diffuse>0 0 1 1</diffuse>
|
||||
</material>
|
||||
</visual>
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<model name="origin_marker">
|
||||
<static>true</static>
|
||||
<pose>0 0 0.01 0 0 0</pose>
|
||||
<link name="link">
|
||||
<visual name="visual">
|
||||
<geometry>
|
||||
<cylinder><radius>0.5</radius><length>0.02</length></cylinder>
|
||||
</geometry>
|
||||
<material>
|
||||
<ambient>1 1 0 1</ambient>
|
||||
<diffuse>1 1 0 1</diffuse>
|
||||
</material>
|
||||
</visual>
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<!-- Spherical coordinates for GPS geofencing -->
|
||||
<spherical_coordinates>
|
||||
<surface_model>EARTH_WGS84</surface_model>
|
||||
<latitude_deg>-35.363262</latitude_deg>
|
||||
<longitude_deg>149.165237</longitude_deg>
|
||||
<elevation>584</elevation>
|
||||
<heading_deg>0</heading_deg>
|
||||
</spherical_coordinates>
|
||||
</world>
|
||||
</sdf>
|
||||
Reference in New Issue
Block a user