Skip to content

Commit e073ea0

Browse files
committed
add protocol documentation
1 parent a0e3d53 commit e073ea0

File tree

2 files changed

+378
-0
lines changed

2 files changed

+378
-0
lines changed

PROTOCOL.md

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
# Romi Control Protocol
2+
3+
The Romi uses a websocket to communicate all of these packets. The address of the websocket
4+
is `ws://{ROMI_ADDRESS}/test` where `ROMI_ADDRESS` depends on the connection method. It is
5+
`192.168.4.1` when running in AP mode.
6+
7+
## Data Types
8+
All data sent or received should be [Little Endian](https://en.wikipedia.org/wiki/Endianness).
9+
10+
| Name | Size (bytes) |
11+
|-------------- |-------------- |
12+
| Unsigned Int | 4 |
13+
| Float | 4 |
14+
| String | >4 |
15+
| Bytes | 0+ |
16+
17+
### Strings
18+
Strings are encoded as an int representing the length followed
19+
by the character data.
20+
21+
## Server(Romi)bound
22+
23+
### Joystick Update
24+
Updates the position of the "virtual joystick" in the Romi. The position determines movement
25+
of the Romi.
26+
27+
The web client implementation is to dispatch this packet a maximum of 1000 times per second.
28+
The packet is _not_ sent if the position has not changed.
29+
30+
Note: The X and Y positions in the packet are ignored by the Romi. The web client always sets them to 1.0.
31+
32+
<table>
33+
<thead>
34+
<tr>
35+
<th>Packet ID</th>
36+
<th>Field Name</th>
37+
<th>Field Type</th>
38+
<th>Notes</th>
39+
</tr>
40+
</thead>
41+
<tbody>
42+
<tr>
43+
<td rowspan="4">0x20</td>
44+
<td>Position X</td>
45+
<td>Float</td>
46+
<td>0.0 - 1.0</td>
47+
</tr>
48+
<tr>
49+
<td>Position Y</td>
50+
<td>Float</td>
51+
<td>0.0 - 1.0</td>
52+
</tr>
53+
<tr>
54+
<td>Angle</td>
55+
<td>Float</td>
56+
<td>Polar angle, in radians.</td>
57+
</tr>
58+
<tr>
59+
<td>Magnitude</td>
60+
<td>Float</td>
61+
<td>Polar magnitude, 0.0 - 1.0</td>
62+
</tr>
63+
</tbody>
64+
</table>
65+
66+
### Slider Update
67+
Updates the position of a slider with the provided ID.
68+
69+
The web client implementation always sends ID 0.
70+
The Romi has 4 slider slots, 0 corresponds to the lifting arm.
71+
72+
<table>
73+
<thead>
74+
<tr>
75+
<th>Packet ID</th>
76+
<th>Field Name</th>
77+
<th>Field Type</th>
78+
<th>Notes</th>
79+
</tr>
80+
</thead>
81+
<tbody>
82+
<tr>
83+
<td rowspan="2">0x30</td>
84+
<td>Slider Number</td>
85+
<td>Unsigned Int</td>
86+
<td>The slider to update</td>
87+
</tr>
88+
<tr>
89+
<td>Value</td>
90+
<td>Float</td>
91+
<td>0.0 - 1.0</td>
92+
</tr>
93+
</tbody>
94+
</table>
95+
96+
### Button Update
97+
Updates the button state for the given ID.
98+
99+
The web client implementation does not dispatch this packet.
100+
The Romi does nothing when it receives this packet.
101+
102+
<table>
103+
<thead>
104+
<tr>
105+
<th>Packet ID</th>
106+
<th>Field Name</th>
107+
<th>Field Type</th>
108+
<th>Notes</th>
109+
</tr>
110+
</thead>
111+
<tbody>
112+
<tr>
113+
<td rowspan="2">0x40</td>
114+
<td>Button ID</td>
115+
<td>Unsigned Int</td>
116+
<td>The button to update</td>
117+
</tr>
118+
<tr>
119+
<td>State</td>
120+
<td>Unsigned Int</td>
121+
<td>0 is up, 1 is down</td>
122+
</tr>
123+
</tbody>
124+
</table>
125+
126+
### Heartbeat
127+
Keeps the websocket alive.
128+
129+
The web client implementation sends a heartbeat every 1 second.
130+
The Romi keeps track of the latest uuid sent by the client.
131+
132+
<table>
133+
<thead>
134+
<tr>
135+
<th>Packet ID</th>
136+
<th>Field Name</th>
137+
<th>Field Type</th>
138+
<th>Notes</th>
139+
</tr>
140+
</thead>
141+
<tbody>
142+
<tr>
143+
<td>0x50</td>
144+
<td>Random "UUID"</td>
145+
<td>Unsigned Int</td>
146+
<td>A random integer, cannot be zero.</td>
147+
</tr>
148+
</tbody>
149+
</table>
150+
151+
## Clientbound
152+
153+
### Value Update (Single)
154+
This packet is designed to update a single data value on the client.
155+
156+
Note: This packet is not implemented by the web client, and it is never dispatched by the Romi.
157+
158+
<table>
159+
<thead>
160+
<tr>
161+
<th>Packet ID</th>
162+
<th>Field Name</th>
163+
<th>Field Type</th>
164+
<th>Notes</th>
165+
</tr>
166+
</thead>
167+
<tbody>
168+
<tr>
169+
<td rowspan=2>0x10</td>
170+
<td>Index</td>
171+
<td>Unsigned Int</td>
172+
<td>The index to update.</td>
173+
</tr>
174+
<tr>
175+
<td>Data</td>
176+
<td>Unsigned Int | Float</td>
177+
<td>The new data.</td>
178+
</tr>
179+
</tbody>
180+
</table>
181+
182+
### PID Values Update
183+
Updates the client display for PID values. These are separate from the dynamic values.
184+
185+
The web client implementation is to log the values to the console.
186+
187+
<table>
188+
<thead>
189+
<tr>
190+
<th>Packet ID</th>
191+
<th>Field Name</th>
192+
<th>Field Type</th>
193+
<th>Notes</th>
194+
</tr>
195+
</thead>
196+
<tbody>
197+
<tr>
198+
<td rowspan="4">0x60</td>
199+
<td>PID Channel</td>
200+
<td>Unsigned Int</td>
201+
<td>The motor relevant to the PID values.</td>
202+
</tr>
203+
<tr>
204+
<td>P</td>
205+
<td>Float</td>
206+
<td></td>
207+
</tr>
208+
<tr>
209+
<td>I</td>
210+
<td>Float</td>
211+
<td></td>
212+
</tr>
213+
<tr>
214+
<td>D</td>
215+
<td>Float</td>
216+
<td></td>
217+
</tr>
218+
</tbody>
219+
</table>
220+
221+
### Heartbeat
222+
Keeps the websocket alive, and proves that the Romi is still active.
223+
224+
<table>
225+
<thead>
226+
<tr>
227+
<th>Packet ID</th>
228+
<th>Field Name</th>
229+
<th>Field Type</th>
230+
<th>Notes</th>
231+
</tr>
232+
</thead>
233+
<tbody>
234+
<tr>
235+
<td>0x50</td>
236+
<td>Random "UUID"</td>
237+
<td>Unsigned Int</td>
238+
<td>A random integer, cannot be zero.</td>
239+
</tr>
240+
</tbody>
241+
</table>
242+
243+
### Console Data
244+
Used to send an arbitrary log string to the client.
245+
246+
The web client implementation is to `console.log` the data.
247+
248+
<table>
249+
<thead>
250+
<tr>
251+
<th>Packet ID</th>
252+
<th>Field Name</th>
253+
<th>Field Type</th>
254+
<th>Notes</th>
255+
</tr>
256+
</thead>
257+
<tbody>
258+
<tr>
259+
<td>0x11</td>
260+
<td>Data</td>
261+
<td>String</td>
262+
<td>See String encoding above.</td>
263+
</tr>
264+
</tbody>
265+
</table>
266+
267+
### Bulk Label Update
268+
Updates or creates a variable number of value indices in the client value dictionary.
269+
270+
<table>
271+
<thead>
272+
<tr>
273+
<th>Packet ID</th>
274+
<th colspan="2">Field Name</th>
275+
<th>Field Type</th>
276+
<th>Notes</th>
277+
</tr>
278+
</thead>
279+
<tbody>
280+
<tr>
281+
<td rowspan="6">0x1d</td>
282+
<td colspan="2">Number of labels (n)</td>
283+
<td>Unsigned Int</td>
284+
<td></td>
285+
</tr>
286+
<tr>
287+
<td colspan="2">Start of string data</td>
288+
<td>Unsigned Int</td>
289+
<td>The start position of the Raw String Data, relative to this position, AKA n * 12.</td>
290+
</tr>
291+
<tr>
292+
<td rowspan="3">Once for each n</td>
293+
<td>Index</td>
294+
<td>Unsigned Int</td>
295+
<td>The label index to update.</td>
296+
</tr>
297+
<tr>
298+
<td>String Offset</td>
299+
<td>Unsigned Int</td>
300+
<td>The start position of the String, relative to the start of the Raw String Data.</td>
301+
</tr>
302+
<tr>
303+
<td>String Length</td>
304+
<td>Unsigned Int</td>
305+
<td></td>
306+
</tr>
307+
<tr>
308+
<td colspan="2">Raw String Data</td>
309+
<td>Bytes</td>
310+
<td>All of the labels concatenated.</td>
311+
</tr>
312+
</tbody>
313+
</table>
314+
315+
### Bulk Value Update
316+
Updates a variable number of values in the client value dictionary.
317+
318+
<table>
319+
<thead>
320+
<tr>
321+
<th>Packet ID</th>
322+
<th colspan="2">Field Name</th>
323+
<th>Field Type</th>
324+
<th>Notes</th>
325+
</tr>
326+
</thead>
327+
<tbody>
328+
<tr>
329+
<td rowspan="3">0x1e</td>
330+
<td colspan="2">Number of updates (n)</td>
331+
<td>Unsigned Int</td>
332+
<td>The number (n) of updates to perform.</td>
333+
</tr>
334+
<tr>
335+
<td rowspan="2">Once for each n.</td>
336+
<td>Index</td>
337+
<td>Unsigned Int</td>
338+
<td></td>
339+
</tr>
340+
<tr>
341+
<td>Value</td>
342+
<td>Unsigned Int</td>
343+
<td>The new value for the index.</td>
344+
</tr>
345+
</tbody>
346+
</table>
347+
348+
### New Value Index
349+
Creates a new value index in the client value dictionary.
350+
351+
Note: This packet is not implemented by the web client, or dispatched by the Romi.
352+
353+
<table>
354+
<thead>
355+
<tr>
356+
<th>Packet ID</th>
357+
<th>Field Name</th>
358+
<th>Field Type</th>
359+
<th>Notes</th>
360+
</tr>
361+
</thead>
362+
<tbody>
363+
<tr>
364+
<td rowspan="2">0x1F</td>
365+
<td>Index</td>
366+
<td>Unsigned Int</td>
367+
<td></td>
368+
</tr>
369+
<tr>
370+
<td>Name</td>
371+
<td>String</td>
372+
<td>See String encoding above.</td>
373+
</tr>
374+
</tbody>
375+
</table>
376+

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ The RC controller is hosted by the ESP32 as a website.
2323

2424
The Detailed documentation is here: https://github.com/madhephaestus/Esp32WifiManager
2525

26+
Protocol information is here: https://github.com/WPIRoboticsEngineering/RBE1001Lib/blob/master/PROTOCOL.md
27+
2628

2729
## Infrastructure network
2830

0 commit comments

Comments
 (0)