Simulation Container
| Port | Protocol | Purpose |
|---|---|---|
| 9090 | gRPC | ros2-bridge (telemetry streaming + MAVLink command relay) |
Flight Sequence
PX4 requires a specific command sequence to enter velocity control. The agent (or MCP tools) must follow these steps in order:OFFBOARD
Switch to OFFBOARD mode. PX4 now accepts external velocity setpoints. The bridge must stream setpoints at 20Hz or PX4 will revert to the previous mode.
Velocity Control
WASM controllers write body velocity commands at 100Hz. The bridge relays these as MAVLink
SET_POSITION_TARGET_LOCAL_NED messages at 20Hz.WASM Channels
TheChannelManifest::quadcopter() manifest defines 4 body velocity command channels and 4 position state channels at 100Hz.
Command Channels (4)
| Index | Name | Unit | Limits | Max Rate of Change |
|---|---|---|---|---|
| 0 | body/velocity.x | m/s | -5.0 to 5.0 | 2.0 m/s per tick |
| 1 | body/velocity.y | m/s | -5.0 to 5.0 | 2.0 m/s per tick |
| 2 | body/velocity.z | m/s | -3.0 to 3.0 | 1.5 m/s per tick |
| 3 | body/yaw_rate | rad/s | -pi/2 to pi/2 | 1.0 rad/s per tick |
State Channels (4)
| Index | Name | Unit | Type |
|---|---|---|---|
| 0 | body/position.x | m | Position |
| 1 | body/position.y | m | Position |
| 2 | body/position.z | m | Position |
| 3 | body/yaw | rad | Position |
NED Frame Convention
MAVLink Bridge
The gRPC bridge handles all MAVLink protocol details:- Companion heartbeat: The bridge sends a heartbeat on the onboard port so PX4 recognizes it as a companion computer.
- 20Hz setpoint streaming: OFFBOARD mode requires continuous setpoints. The bridge maintains a 20Hz stream, using the latest WASM output each cycle.
- COMMAND_LONG: Flight mode transitions (ARM, TAKEOFF, LAND, OFFBOARD) use
COMMAND_LONGmessages. The bridge handles acknowledgment and retry.
PX4 requires
NaN for unused COMMAND_LONG parameters. The bridge fills unused parameter slots with f32::NAN — do not use 0.0 as a placeholder.Example
A WASM controller that moves the drone forward and up:Real Hardware
For a physical PX4 drone (no Docker container):- Connect via MAVLink over serial (TELEM2) or UDP to the flight controller
- The bridge communicates on PX4’s onboard MAVLink instance (companion port)
- Same WASM channels and safety filter apply — velocity commands are clamped before reaching the flight controller
Source Code
- Channel manifest:
crates/roz-core/src/channels.rs(ChannelManifest::quadcopter()) - MAVLink bridge:
crates/roz-worker/