Update to Bridges
This commit is contained in:
@@ -4,113 +4,107 @@ GPS-denied drone landing simulation with multiple operation modes.
|
||||
|
||||
## Operation Modes
|
||||
|
||||
### Standalone Mode (Windows/Simple)
|
||||
### 1. Standalone Mode (Any Platform)
|
||||
|
||||
All-in-one simulation - no ROS 2 or external dependencies:
|
||||
Single-process simulation - no ROS 2 or networking required:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ standalone_simulation.py │
|
||||
│ ┌──────────────────────────────────┐ │
|
||||
│ │ PyBullet Physics Engine │ │
|
||||
│ │ ┌────────┐ ┌────────────────┐ │ │
|
||||
│ │ │ Drone │ │ Landing Pad │ │ │
|
||||
│ │ └────────┘ └────────────────┘ │ │
|
||||
│ ├──────────────────────────────────┤ │
|
||||
│ │ Built-in Controller │ │
|
||||
│ │ • Landing algorithm │ │
|
||||
│ │ • Rover movement patterns │ │
|
||||
│ │ PyBullet Physics + Camera │ │
|
||||
│ │ Built-in Landing Controller │ │
|
||||
│ │ Rover Movement Patterns │ │
|
||||
│ └──────────────────────────────────┘ │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Full Mode (Linux + ROS 2)
|
||||
|
||||
Modular architecture for development and testing:
|
||||
### 2. PyBullet + ROS 2 Mode (2 Terminals)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Simulation System │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ simulation_host │◄── UDP:5555 ──────►│ ros_bridge.py │ │
|
||||
│ │ (PyBullet) │ │ (UDP ↔ ROS Bridge) │ │
|
||||
│ └──────────────────┘ └────────────┬─────────────┘ │
|
||||
│ OR │ │
|
||||
│ ┌──────────────────┐ ┌────────────┴─────────────┐ │
|
||||
│ │ Gazebo │◄── ROS Topics ────►│ gazebo_bridge.py │ │
|
||||
│ │ (Linux only) │ │ (Gazebo ↔ ROS Bridge) │ │
|
||||
│ └──────────────────┘ └────────────┬─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────▼─────────────┐ │
|
||||
│ │ controllers.py │ │
|
||||
│ │ ┌─────────────────────┐ │ │
|
||||
│ │ │ DroneController │ │ │
|
||||
│ │ │ RoverController │ │ │
|
||||
│ │ └─────────────────────┘ │ │
|
||||
│ └──────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
Terminal 1 Terminal 2
|
||||
┌──────────────────┐ ┌──────────────────────────┐
|
||||
│ simulation_host │◄─UDP───►│ run_bridge.py │
|
||||
│ (PyBullet) │ │ ┌────────────────────┐ │
|
||||
│ Port 5555 │ │ │ ROS2SimulatorBridge│ │
|
||||
│ │ │ │ DroneController │ │
|
||||
│ │ │ │ RoverController │ │
|
||||
└──────────────────┘ │ └────────────────────┘ │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
### 3. Gazebo + ROS 2 Mode (2 Terminals, Linux Only)
|
||||
|
||||
```
|
||||
Terminal 1 Terminal 2
|
||||
┌──────────────────┐ ┌──────────────────────────┐
|
||||
│ Gazebo │◄─ROS───►│ run_gazebo.py │
|
||||
│ (gz sim ...) │ │ ┌────────────────────┐ │
|
||||
│ │ │ │ GazeboBridge │ │
|
||||
│ │ │ │ DroneController │ │
|
||||
│ │ │ │ RoverController │ │
|
||||
└──────────────────┘ │ └────────────────────┘ │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### Standalone
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `standalone_simulation.py` | All-in-one simulation |
|
||||
| `simulation_host.py` | PyBullet physics server (UDP) |
|
||||
| `run_bridge.py` | PyBullet bridge + controllers |
|
||||
| `run_gazebo.py` | Gazebo bridge + controllers |
|
||||
| `drone_controller.py` | Landing algorithm |
|
||||
| `rover_controller.py` | Moving landing pad |
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| **standalone_simulation.py** | Complete simulation with built-in controller |
|
||||
## ROS Topics
|
||||
|
||||
### Full Mode
|
||||
| Topic | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `/cmd_vel` | `Twist` | Drone velocity commands |
|
||||
| `/drone/telemetry` | `String` | GPS-denied sensor data |
|
||||
| `/rover/telemetry` | `String` | Rover position (internal) |
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| **PyBullet** (`simulation_host.py`) | Physics engine, UDP networking, camera |
|
||||
| **Gazebo** | Full robotics simulator (Linux only) |
|
||||
| **ros_bridge.py** | Connects PyBullet ↔ ROS 2 via UDP |
|
||||
| **gazebo_bridge.py** | Connects Gazebo ↔ ROS 2 |
|
||||
| **controllers.py** | Runs drone + rover controllers |
|
||||
| **drone_controller.py** | GPS-denied landing logic |
|
||||
| **rover_controller.py** | Moving landing pad patterns |
|
||||
## Network Configuration
|
||||
|
||||
## ROS Topics (Full Mode)
|
||||
All components default to `0.0.0.0` for network accessibility.
|
||||
|
||||
| Topic | Type | Publisher | Subscriber |
|
||||
|-------|------|-----------|------------|
|
||||
| `/cmd_vel` | `Twist` | DroneController | Bridge |
|
||||
| `/drone/telemetry` | `String` | Bridge | DroneController |
|
||||
| `/rover/telemetry` | `String` | RoverController | DroneController |
|
||||
### Remote Setup
|
||||
|
||||
## GPS-Denied Sensor Flow
|
||||
|
||||
```
|
||||
Simulator Bridge DroneController
|
||||
│ │ │
|
||||
│ Render Camera │ │
|
||||
│ Compute Physics │ │
|
||||
│──────────────────────►│ │
|
||||
│ │ GPS-Denied Sensors: │
|
||||
│ │ - IMU │
|
||||
│ │ - Altimeter │
|
||||
│ │ - Velocity │
|
||||
│ │ - Camera Image │
|
||||
│ │ - Landing Pad Detection │
|
||||
│ │─────────────────────────►│
|
||||
│ │ /cmd_vel │
|
||||
│◄──────────────────────│◄─────────────────────────│
|
||||
**Machine 1 (with display):**
|
||||
```bash
|
||||
python simulation_host.py # Listens on 0.0.0.0:5555
|
||||
```
|
||||
|
||||
## Platform Support
|
||||
**Machine 2 (headless controller):**
|
||||
```bash
|
||||
python run_bridge.py --host 192.168.1.100
|
||||
```
|
||||
|
||||
| Mode | Windows | Linux | macOS |
|
||||
|------|---------|-------|-------|
|
||||
| Standalone | ✅ | ✅ | ✅ |
|
||||
| Full (ROS 2) | ⚠️ | ✅ | ⚠️ |
|
||||
| Gazebo | ❌ | ✅ | ❌ |
|
||||
|
||||
## UDP Protocol (Full Mode)
|
||||
### UDP Ports
|
||||
|
||||
| Port | Direction | Content |
|
||||
|------|-----------|---------|
|
||||
| 5555 | Bridge → Simulator | Command JSON |
|
||||
| 5556 | Simulator → Bridge | Telemetry JSON |
|
||||
| 5555 | Bridge → Simulator | Commands |
|
||||
| 5556 | Simulator → Bridge | Telemetry |
|
||||
|
||||
## GPS-Denied Sensors
|
||||
|
||||
All modes provide the same sensor data:
|
||||
|
||||
| Sensor | Data |
|
||||
|--------|------|
|
||||
| IMU | Orientation, angular velocity |
|
||||
| Altimeter | Altitude, vertical velocity |
|
||||
| Velocity | Estimated from optical flow |
|
||||
| Camera | 320x240 downward JPEG |
|
||||
| Landing Pad | Relative position (when visible) |
|
||||
|
||||
## Platform Support
|
||||
|
||||
| Mode | Ubuntu | Arch | macOS | Windows | WSL2 |
|
||||
|------|--------|------|-------|---------|------|
|
||||
| Standalone | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| PyBullet+ROS | ✅ | ⚠️ | ❌ | ❌ | ✅ |
|
||||
| Gazebo+ROS | ✅ | ⚠️ | ❌ | ❌ | ✅ |
|
||||
|
||||
159
docs/gazebo.md
159
docs/gazebo.md
@@ -1,17 +1,8 @@
|
||||
# Gazebo Simulation
|
||||
|
||||
Running the GPS-denied drone simulation with Gazebo.
|
||||
Running the GPS-denied drone simulation with Gazebo (Linux only).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install Gazebo and ROS-Gazebo bridge:
|
||||
|
||||
```bash
|
||||
./setup/install_ubuntu.sh
|
||||
source activate.sh
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
## Quick Start (2 Terminals)
|
||||
|
||||
**Terminal 1 - Start Gazebo:**
|
||||
```bash
|
||||
@@ -19,86 +10,54 @@ source activate.sh
|
||||
gz sim gazebo/worlds/drone_landing.sdf
|
||||
```
|
||||
|
||||
**Terminal 2 - Spawn drone and start bridge:**
|
||||
**Terminal 2 - Run Controllers:**
|
||||
```bash
|
||||
source activate.sh
|
||||
python run_gazebo.py --pattern circular --speed 0.3
|
||||
```
|
||||
|
||||
# Spawn drone
|
||||
## Options
|
||||
|
||||
```bash
|
||||
python run_gazebo.py --help
|
||||
|
||||
Options:
|
||||
--pattern stationary, linear, circular, square, random
|
||||
--speed, -s Rover speed in m/s (default: 0.5)
|
||||
--amplitude, -a Movement amplitude (default: 2.0)
|
||||
--no-rover Disable rover controller
|
||||
```
|
||||
|
||||
## Spawning the Drone
|
||||
|
||||
If the drone isn't in the world, spawn it:
|
||||
|
||||
```bash
|
||||
gz service -s /world/drone_landing_world/create \
|
||||
--reqtype gz.msgs.EntityFactory \
|
||||
--reptype gz.msgs.Boolean \
|
||||
--req 'sdf_filename: "gazebo/models/drone/model.sdf", name: "drone"'
|
||||
|
||||
# Start bridge
|
||||
python gazebo_bridge.py
|
||||
```
|
||||
|
||||
**Terminal 3 - Run controllers:**
|
||||
```bash
|
||||
source activate.sh
|
||||
python controllers.py --pattern circular --speed 0.3
|
||||
```
|
||||
## GPS-Denied Sensors
|
||||
|
||||
## World Description
|
||||
The `run_gazebo.py` script provides the same sensor interface as PyBullet:
|
||||
|
||||
The `drone_landing.sdf` world contains:
|
||||
|
||||
| Object | Description |
|
||||
|--------|-------------|
|
||||
| Ground Plane | Infinite flat surface |
|
||||
| Sun | Directional light with shadows |
|
||||
| Landing Pad | Green box with "H" marker at origin |
|
||||
|
||||
## Drone Model
|
||||
|
||||
Quadrotor drone with:
|
||||
|
||||
- **Body**: 0.3m × 0.3m × 0.1m, 1.0 kg
|
||||
- **Rotors**: 4 spinning rotors
|
||||
- **IMU**: Orientation and angular velocity
|
||||
- **Camera**: 320x240 downward-facing sensor
|
||||
- **Odometry**: Position and velocity
|
||||
|
||||
### Gazebo Plugins
|
||||
|
||||
| Plugin | Function |
|
||||
|--------|----------|
|
||||
| MulticopterMotorModel | Motor dynamics |
|
||||
| MulticopterVelocityControl | Velocity commands |
|
||||
| OdometryPublisher | Pose and twist |
|
||||
|
||||
## Camera System
|
||||
|
||||
The drone has a downward-facing camera:
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Resolution | 320 x 240 |
|
||||
| FOV | 60 degrees |
|
||||
| Format | Base64 encoded JPEG |
|
||||
| Update Rate | 30 Hz (Gazebo) / ~5 Hz (in telemetry) |
|
||||
| Topic | `/drone/camera` |
|
||||
| Sensor | Source |
|
||||
|--------|--------|
|
||||
| IMU | Gazebo odometry |
|
||||
| Altimeter | Gazebo Z position |
|
||||
| Velocity | Gazebo twist |
|
||||
| Camera | Gazebo camera sensor |
|
||||
| Landing Pad | Computed from relative position |
|
||||
|
||||
## Gazebo Topics
|
||||
|
||||
| Topic | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `/drone/cmd_vel` | `gz.msgs.Twist` | Velocity commands |
|
||||
| `/model/drone/odometry` | `gz.msgs.Odometry` | Drone state |
|
||||
| `/drone/camera` | `gz.msgs.Image` | Camera images |
|
||||
| `/drone/imu` | `gz.msgs.IMU` | IMU data |
|
||||
|
||||
## GPS-Denied Sensors
|
||||
|
||||
The `gazebo_bridge.py` converts Gazebo data to GPS-denied sensor format:
|
||||
|
||||
| Sensor | Source |
|
||||
|--------|--------|
|
||||
| IMU | Odometry orientation + angular velocity |
|
||||
| Altimeter | Odometry Z position |
|
||||
| Velocity | Odometry twist |
|
||||
| Camera | Camera sensor (base64 JPEG) |
|
||||
| Landing Pad | Computed from relative position |
|
||||
| `/drone/cmd_vel` | `Twist` | Velocity commands |
|
||||
| `/model/drone/odometry` | `Odometry` | Drone state |
|
||||
| `/drone/camera` | `Image` | Camera images |
|
||||
|
||||
## Headless Mode
|
||||
|
||||
@@ -108,51 +67,29 @@ Run without GUI:
|
||||
gz sim -s gazebo/worlds/drone_landing.sdf
|
||||
```
|
||||
|
||||
## Using the Launch File
|
||||
|
||||
For ROS 2 packages:
|
||||
|
||||
```bash
|
||||
ros2 launch <package_name> drone_landing.launch.py
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Cannot connect to display"
|
||||
|
||||
```bash
|
||||
export DISPLAY=:0
|
||||
# or use headless mode
|
||||
gz sim -s gazebo/worlds/drone_landing.sdf
|
||||
```
|
||||
|
||||
### Drone falls immediately
|
||||
|
||||
The velocity controller may need to be enabled:
|
||||
|
||||
```bash
|
||||
gz topic -t /drone/enable -m gz.msgs.Boolean -p 'data: true'
|
||||
```
|
||||
|
||||
### Topics not visible in ROS
|
||||
|
||||
Ensure the bridge is running:
|
||||
|
||||
```bash
|
||||
python gazebo_bridge.py
|
||||
```
|
||||
|
||||
### Model not found
|
||||
|
||||
Set the model path:
|
||||
|
||||
```bash
|
||||
export GZ_SIM_RESOURCE_PATH=$PWD/gazebo/models:$GZ_SIM_RESOURCE_PATH
|
||||
```
|
||||
|
||||
### Camera image not in telemetry
|
||||
### Drone falls immediately
|
||||
|
||||
Ensure PIL/Pillow is installed:
|
||||
Enable the velocity controller:
|
||||
```bash
|
||||
pip install pillow
|
||||
gz topic -t /drone/enable -m gz.msgs.Boolean -p 'data: true'
|
||||
```
|
||||
|
||||
### "Cannot connect to display"
|
||||
|
||||
Use headless mode or WSLg:
|
||||
```bash
|
||||
# Headless
|
||||
gz sim -s gazebo/worlds/drone_landing.sdf
|
||||
|
||||
# Or ensure DISPLAY is set
|
||||
export DISPLAY=:0
|
||||
```
|
||||
|
||||
107
docs/pybullet.md
107
docs/pybullet.md
@@ -2,25 +2,19 @@
|
||||
|
||||
Running the GPS-denied drone simulation with PyBullet.
|
||||
|
||||
## Windows (Standalone Mode)
|
||||
## Standalone Mode (Recommended)
|
||||
|
||||
No ROS 2 required! Run the all-in-one simulation:
|
||||
No ROS 2 required! Single terminal:
|
||||
|
||||
```powershell
|
||||
. .\activate.ps1
|
||||
python standalone_simulation.py
|
||||
```bash
|
||||
source activate.sh
|
||||
python standalone_simulation.py --pattern circular --speed 0.3
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```powershell
|
||||
# Stationary landing pad
|
||||
python standalone_simulation.py
|
||||
|
||||
# Moving rover patterns
|
||||
python standalone_simulation.py --pattern circular --speed 0.3
|
||||
python standalone_simulation.py --pattern linear --speed 0.5
|
||||
python standalone_simulation.py --pattern square --speed 0.4
|
||||
```bash
|
||||
python standalone_simulation.py --help
|
||||
|
||||
Options:
|
||||
--pattern, -p stationary, linear, circular, square
|
||||
@@ -28,11 +22,11 @@ Options:
|
||||
--amplitude, -a Movement amplitude in meters (default: 2.0)
|
||||
```
|
||||
|
||||
The simulation includes a built-in landing controller. Watch the drone automatically land on the rover!
|
||||
|
||||
---
|
||||
|
||||
## Linux (Full ROS 2 Mode)
|
||||
## ROS 2 Mode (2 Terminals)
|
||||
|
||||
For distributed or remote simulation:
|
||||
|
||||
**Terminal 1 - Simulator:**
|
||||
```bash
|
||||
@@ -40,36 +34,49 @@ source activate.sh
|
||||
python simulation_host.py
|
||||
```
|
||||
|
||||
**Terminal 2 - ROS Bridge:**
|
||||
**Terminal 2 - Controllers:**
|
||||
```bash
|
||||
source activate.sh
|
||||
python ros_bridge.py
|
||||
```
|
||||
|
||||
**Terminal 3 - Controllers:**
|
||||
```bash
|
||||
source activate.sh
|
||||
python controllers.py --pattern circular --speed 0.3
|
||||
python run_bridge.py --pattern circular --speed 0.3
|
||||
```
|
||||
|
||||
### Remote Setup
|
||||
|
||||
Run simulator on one machine, controllers on another.
|
||||
Run simulator on one machine, controllers on another:
|
||||
|
||||
**Machine 1 (with display):**
|
||||
```bash
|
||||
python simulation_host.py
|
||||
python simulation_host.py # Listens on 0.0.0.0:5555
|
||||
```
|
||||
|
||||
**Machine 2 (headless):**
|
||||
```bash
|
||||
source activate.sh
|
||||
python ros_bridge.py --host <MACHINE_1_IP>
|
||||
python controllers.py
|
||||
python run_bridge.py --host 192.168.1.100 --pattern circular
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Building Standalone Executable
|
||||
|
||||
Create a distributable executable:
|
||||
|
||||
```bash
|
||||
source activate.sh
|
||||
|
||||
# Build standalone simulation (recommended)
|
||||
python build_exe.py
|
||||
|
||||
# Build simulation_host
|
||||
python build_exe.py simulation_host
|
||||
|
||||
# Build all
|
||||
python build_exe.py all
|
||||
```
|
||||
|
||||
Executables are created in `dist/`.
|
||||
|
||||
---
|
||||
|
||||
## Simulation Parameters
|
||||
|
||||
| Parameter | Value |
|
||||
@@ -77,7 +84,7 @@ python controllers.py
|
||||
| Physics Rate | 240 Hz |
|
||||
| Telemetry Rate | 24 Hz |
|
||||
| Drone Mass | 1.0 kg |
|
||||
| Gravity | -9.81 m/s² |
|
||||
| UDP Port | 5555 (commands), 5556 (telemetry) |
|
||||
|
||||
## GPS-Denied Sensors
|
||||
|
||||
@@ -89,40 +96,18 @@ python controllers.py
|
||||
| Camera | 320x240 downward JPEG image |
|
||||
| Landing Pad | Vision-based relative position |
|
||||
|
||||
## Camera System
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Resolution | 320 x 240 |
|
||||
| FOV | 60 degrees |
|
||||
| Format | Base64 encoded JPEG |
|
||||
| Direction | Downward-facing |
|
||||
|
||||
## World Setup
|
||||
|
||||
| Object | Position | Description |
|
||||
|--------|----------|-------------|
|
||||
| Ground | z = 0 | Infinite plane |
|
||||
| Rover | (0, 0, 0.15) | 1m × 1m landing pad |
|
||||
| Drone | (0, 0, 5) | Starting position |
|
||||
|
||||
## Building Executable
|
||||
|
||||
Create standalone executable:
|
||||
|
||||
```bash
|
||||
source activate.sh
|
||||
python build_exe.py
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Cannot connect to X server"
|
||||
|
||||
PyBullet requires a display:
|
||||
- Run on machine with monitor
|
||||
- Use X11 forwarding: `ssh -X user@host`
|
||||
- Virtual display: `xvfb-run python simulation_host.py`
|
||||
PyBullet GUI requires a display:
|
||||
```bash
|
||||
# Use virtual display
|
||||
xvfb-run python standalone_simulation.py
|
||||
|
||||
# Or use X11 forwarding
|
||||
ssh -X user@host
|
||||
```
|
||||
|
||||
### Drone flies erratically
|
||||
|
||||
@@ -134,7 +119,7 @@ Kd = 0.2
|
||||
|
||||
### Camera image not appearing
|
||||
|
||||
Ensure PIL/Pillow is installed:
|
||||
Install Pillow:
|
||||
```bash
|
||||
pip install pillow
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user