Network Architecture¶
Communication Topology¶
┌─────────────────────────────────────────────────────────────────────┐
│ Client Devices │
│ (Laptop / Phone / Tablet) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Web Control │ │ Web Basic │ │ DTLS Control Client │ │
│ │ (TS + WS) │ │ (HTML + WS) │ │ (Custom App) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────────┬───────────┘ │
└─────────┼────────────────────┼──────────────────────┼───────────────┘
│ WebSocket │ WebSocket │ DTLS/UDP
│ port 9090 │ port 9090 │ port 5684
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Companion Computer (RPi 5) │
│ │
│ ┌──────────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ rosbridge_server │ │ Nav2 Stack │ │ micro-ROS Agent│ │
│ │ (WebSocket ↔ ROS) │ │ (Navigation) │ │ (Serial Bridge)│ │
│ └──────────────────┘ └──────────────┘ └────────┬────────┘ │
│ │ │
│ ROS2 DDS (shared topic bus) │ │
└────────────────────────────────────────────────────────┼─────────────┘
│ UART
│ 921600 baud
▼
┌─────────────────────────────────────────────────────────────────────┐
│ ESP32-S3 (Firmware) │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ micro-ROS │ │ DTLS │ │ UDP │ │ Safety │ │
│ │ (Topics + │ │ Server │ │ Telemetry │ │ Subsystem │ │
│ │ Services) │ │ (Control) │ │ (Read-only)│ │ (E-stop + │ │
│ └────────────┘ └────────────┘ └────────────┘ │ Watchdog) │ │
│ └──────────────┘ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ Motors │ │ Encoders │ │ Ultrasonic │ │ IMU │ │
│ │ (DRV8833) │ │ (PCNT) │ │ (RMT) │ │ (BNO055) │ │
│ └────────────┘ └────────────┘ └────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Communication Channels¶
1. micro-ROS (Primary — Sensor/Control Data)¶
| Property | Value |
|---|---|
| Transport | UART serial |
| Baudrate | 921,600 bps |
| Protocol | DDS-XRCE (micro-ROS) |
| Agent | micro_ros_agent serial --dev /dev/ttyUSB0 --baudrate 921600 |
| Direction | Bidirectional |
| Latency | < 5ms typical |
micro-ROS exposes all sensor data and motor control to the ROS2 ecosystem. The companion computer runs the micro-ROS agent which bridges serial frames to DDS topics.
2. DTLS Encrypted Control (Direct Wi-Fi)¶
| Property | Value |
|---|---|
| Transport | UDP + DTLS 1.2 |
| Port | 5684 |
| Authentication | PSK (Pre-Shared Key) |
| PSK Identity | Derived from ESP32 MAC address |
| Ciphers | AES-128-GCM, AES-256-GCM (AEAD only) |
| Session cache | Yes (resume within ~60s without re-handshake) |
| Direction | Bidirectional |
| Cookie DoS protection | Yes |
Direct encrypted channel from a client app to the ESP32's Wi-Fi interface. Can send motor commands without the companion computer. Subject to the same safety limits as ROS2 commands.
Authority Model: Only one DTLS session at a time can hold "authority" (permission to send motor commands). A session claims authority by being the first authenticated client to send a command. Authority is released after an idle timeout (configurable, default ~30s of no commands from the holder). Other connected sessions receive telemetry but cannot issue motor commands until authority is released or transferred. This prevents conflicting control inputs from multiple clients.
Operator Allowlist: An optional NVS-stored operator list restricts which PSK identities can claim authority. If configured, only pre-approved operators can send motor commands.
3. UDP Telemetry (Plaintext Fallback)¶
| Property | Value |
|---|---|
| Transport | UDP |
| Command Port | 8888 (receive) |
| Telemetry Port | 9999 (send) |
| Authentication | None |
| Direction | Read-only (ESP32 → Client) by default |
| Use case | Debugging, real-time visualization |
Unencrypted telemetry stream. By default (CONFIG_ROBOT_ALLOW_PLAINTEXT_CTRL disabled), received UDP packets are dropped — no motor commands accepted over plaintext. Useful for quick debugging without DTLS setup.
4. Rosbridge WebSocket (Browser ↔ ROS2)¶
| Property | Value |
|---|---|
| Transport | WebSocket (ws:// or wss://) |
| Port | 9090 |
| Protocol | rosbridge v2.0 JSON |
| Authentication | None (by default) |
| Direction | Bidirectional |
| Use case | Web UI access to all ROS2 topics/services |
The rosbridge_server runs on the companion computer and exposes the full ROS2 topic/service graph to browser-based clients via WebSocket.
Port Assignment Table¶
| Port | Protocol | Service | Direction | Auth |
|---|---|---|---|---|
| 9090 | WebSocket | rosbridge (ROS2 ↔ browser) | Bidirectional | None |
| 5684 | UDP/DTLS | Direct motor control (authority model) | Bidirectional | PSK |
| 8888 | UDP | Command receive (plaintext, dropped by default) | Client → ESP32 | None |
| 9999 | UDP | Telemetry stream | ESP32 → Client | None |
| 921600 baud | Serial | micro-ROS primary transport | Bidirectional | Physical |
Security Model¶
Who Can Send Motor Commands?¶
| Channel | Motor Control | Requires |
|---|---|---|
| micro-ROS (serial) | Yes | Physical UART connection |
| DTLS (port 5684) | Yes | Valid PSK + authority claim |
| Rosbridge (port 9090) | Yes | Network access to companion |
| UDP plaintext (8888) | No (default) | CONFIG_ROBOT_ALLOW_PLAINTEXT_CTRL to enable |
Safety Enforcement (All Channels)¶
Regardless of which channel delivers a motor command, the firmware enforces:
- Speed clamping — velocity limited to
safety_get_speed_limit()(configurable, NVS-persisted, default 1.0 m/s, hard cap 1.2 m/s) - E-stop priority — hardware E-stop cuts power via relay; software cannot override
- cmd_vel timeout — if no
/cmd_velreceived for 500ms, motors stop - System watchdog — if control loop stalls for 1000ms, full E-stop triggered (armed-on-first-feed: only activates after first
safety_feed_watchdog()call) - Relay self-test — dual-channel relay feedback verified at boot and continuously monitored; 3 faults escalate to permanent RELAY_FAULT requiring physical service
- DRV8833 nFAULT — motor driver fault pins monitored via MCP23017; debounced 3-cycle detection triggers motor stop
- Thermal protection — INA219-based temperature monitoring can trigger motor shutdown at critical thresholds
PSK Provisioning¶
The DTLS PSK identity and key are stored in ESP32 NVS (non-volatile storage):
- Identity: robot-<MAC_HEX> (full 6-byte MAC as 12 hex characters, e.g. robot-AABBCCDDEEFF)
- Key: 16-byte minimum random, provisioned during initial setup via NVS namespace security/dtls_psk
- Rotation: requires re-flashing NVS partition or OTA config update
Data Flow Examples¶
Joystick → Motor¶
Browser Joystick → WebSocket → rosbridge → /cmd_vel topic
→ micro-ROS agent → UART → ESP32 cmd_vel_callback()
→ safety_clamp_speed() → motor_mecanum_drive() → PWM
Sensor → Dashboard¶
ESP32 ultrasonic_get_last() → range_timer_callback()
→ rcl_publish(/ultrasonic/front) → UART → micro-ROS agent
→ ROS2 DDS → rosbridge → WebSocket → <robot-sensor-radar>
Emergency Stop¶
Physical button press → GPIO ISR (debounced 50ms)
→ state = SAFETY_ESTOPPED → motor_stop_all()
→ micro-ROS publishes /emergency_stop_state
→ Web UI <robot-estop-button> shows active E-stop
Recovery flow (two-step):
1. Release physical button → safety_reset() → state = SAFETY_RECOVERY_PENDING
2. Operator confirmation → safety_confirm_reset() → state = SAFETY_NORMAL
3. If confirm not received within 10s → auto-revert to SAFETY_ESTOPPED
Wi-Fi Configuration¶
The firmware connects to Wi-Fi using credentials stored in NVS. Configuration methods:
- Captive portal — On first boot (or if stored credentials fail), the ESP32 creates an AP (
RobotPlatform_XXXX) and serves a captive portal page for credential entry. After receiving valid Wi-Fi credentials, the device restarts and connects to the configured network. - NVS provisioning — Write credentials to the
wifiNVS namespace before first boot viaprovision-keystool - Build-time — Set
CONFIG_WIFI_SSID/CONFIG_WIFI_PASSWORDinsdkconfig(development only)