Skip to content

Latest commit

 

History

History
125 lines (94 loc) · 6.07 KB

File metadata and controls

125 lines (94 loc) · 6.07 KB

Protocol Reference

The daemon and GUI communicate over UDP using a binary frame format inspired by MAVLink v1. All multi-byte integers are big-endian on the wire.


Port assignments

Port Direction Content
5555 GUI → daemon Commands
5556 daemon → GUI Telemetry
5557 daemon → GUI Video (separate framing — see below)

Default addresses: GUI connects to 192.168.50.3. Override in daemon/daemon.toml under [transport].


Command / telemetry frame format

┌──────┬─────┬─────┬──────────┬────────────────┬────────────┐
│ STX  │ len │ seq │  msg_id  │    payload     │   crc16    │
│ 0xFE │ 1 B │ 1 B │   2 B    │   len bytes    │    2 B     │
└──────┴─────┴─────┴──────────┴────────────────┴────────────┘
Field Size Description
STX 1 byte Start-of-frame marker, always 0xFE
len 1 byte Payload length in bytes (max 255)
seq 1 byte Sequence counter, wraps at 255
msg_id 2 bytes BE Message type identifier
payload len bytes JSON-encoded UTF-8 string
crc16 2 bytes BE CRC-16-CCITT over [len, seq, msg_id_lo, msg_id_hi] + payload

CRC algorithm: CRC-16-CCITT, polynomial 0x1021, init 0xFFFF. msg_id is big-endian on the wire but the CRC input uses little-endian byte order for msg_id (lo byte first) — matches MAVLink v1. STX is not included in the CRC.

Implementation: daemon/core/link_protocol.py (Python) and godot/core/LinkProtocol.gd (GDScript).


Message ID table

msg_id Name Direction Payload fields
0 heartbeat both {}
1 ESTOP GUI → daemon {} — fast path, retry until SAFETY_ACK
2 REARM GUI → daemon {} — fast path, retry until SAFETY_ACK
3 SAFETY_ACK daemon → GUI {"action": "estop"|"rearm"}
4 battery daemon → GUI {"charge_pct": float, "voltage": float, "current": float, "estimated_runtime_s": float}
5 odometry daemon → GUI {"x": float, "y": float, "heading": float} (metres / radians, SE2)
6 lease_status daemon → GUI {"lease_owner": str, "estop_active": bool}
7 velocity_command GUI → daemon see Velocity command fields
8 video daemon → GUI separate port / framing — see Video
9 example_plugin daemon → GUI {"count": int, "timestamp": float} — example only
10 dock GUI → daemon {} — dock to configured station
11 dock_stations daemon → GUI {"ranges": [[id_start, id_end], ...]}
12 undock GUI → daemon {}
13 camera_select GUI → daemon {"source": str} — camera name or device index
14 camera_list daemon → GUI {"spot_sources": [str, ...], "device_indices": [int, ...]}
15 dock_status daemon → GUI {"state": "idle"|"searching"|"docking"|"docked"|"undocking"|"failed", "station_id": int|null}
16 waypoint_command GUI → daemon see Waypoint command fields
17 waypoint_status daemon → GUI {"state": "idle"|"navigating", "current": str|null, "waypoints": [str, ...]}

msg_ids 0–3 are fast-pathed in the daemon receive loop before bus dispatch. msg_ids 18+ are available for new handlers.


Velocity command fields

Sent as msg_id = 7. All fields are optional; omitted fields default to 0 / false.

Field Type Description
vx float Forward velocity (m/s)
vy float Lateral velocity (m/s)
vrot float Rotational velocity (rad/s)
sit_stand bool true = stand, false = sit (rising-edge on daemon)
abort_requested bool Safe power off (not ESTOP — use msg_id 1 for ESTOP)
pitch_delta float Body pitch increment this tick (rad), clamped ±0.5
roll_delta float Body roll increment this tick (rad), clamped ±0.5
yaw_delta float Body yaw increment this tick (rad), clamped ±1.5
height_delta float Body height increment this tick (m), clamped −0.10 to +0.15

Walk mode activates when vx, vy, or vrot are present. Stand mode activates when only pose delta fields are present. Each velocity command expires 500 ms after issue — Spot stops if no new command arrives.


Waypoint command fields

Sent as msg_id = 16. The action field is always required.

Action Additional fields Description
"save" name: str Snapshot current pose as a named waypoint
"go" name: str Navigate to named waypoint
"go_sequence" Navigate to all waypoints in saved order
"stop" Abort current navigation
"delete" name: str Remove named waypoint

Waypoints are stored on the Jetson at ~/.spot-waypoints.json.


Video framing

Video uses a separate UDP port (5557) with its own fragmentation header. It does not use the command/telemetry frame format above.

┌──────────┬──────────┬─────────┬─────────────┬──────────────┐
│ codec_id │ frame_id │ frag_id │ total_frags │    data      │
│   1 B    │   2 B    │   1 B   │     1 B     │  remainder   │
└──────────┴──────────┴─────────┴─────────────┴──────────────┘
Field Description
codec_id 1 = H.264, 2 = H.265
frame_id 2-byte frame counter; wraps at 65535
frag_id 0-based fragment index within this frame
total_frags Total fragments for this frame
data Raw compressed video bytes for this fragment

Reassemble by collecting all fragments with the same frame_id until frag_id == total_frags - 1.