Update to Bridges

This commit is contained in:
2026-01-01 01:08:30 +00:00
parent 2b01f636fe
commit 4b44c3de91
9 changed files with 578 additions and 324 deletions

View File

@@ -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 | ✅ | ⚠️ | ❌ | ❌ | ✅ |

View File

@@ -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
```

View File

@@ -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
```