diff options
author | lonkaars <loek@pipeframe.xyz> | 2022-05-10 20:28:24 +0200 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2022-05-10 20:28:24 +0200 |
commit | cbf90c6983e2dfe90a9c5f607a5978d76565fefe (patch) | |
tree | 4ed715fc48538042a829445da5f9010967a58b02 | |
parent | aaf6d7963314c1fcb86b84442cd3d960bc87297b (diff) |
added updated protocol spec
-rw-r--r-- | protocol.md | 317 | ||||
-rw-r--r-- | robot/readme.md | 8 |
2 files changed, 233 insertions, 92 deletions
diff --git a/protocol.md b/protocol.md index 0317d05..f5bb0cc 100644 --- a/protocol.md +++ b/protocol.md @@ -2,13 +2,11 @@ under construction! -## client/robot - the included wixel is used for bidirectional wireless serial data transfer. it has built-in error correction and other features that make sure data gets to the robot losslessly, so data loss is not accounted for. -### important constants +## important constants |property|value|unit| |-|-|-| @@ -16,148 +14,297 @@ the robot losslessly, so data loss is not accounted for. |max byte timeout|5|ms| |byte order|big-endian|-| -### commands +## commands -each command consists of an opcode, and then a payload. each opcode defines -logic to handle payload length, so certain commands might expect a fixed-length -payload, a variable-length payload, or none at all. +each command consists of a start byte, opcode, and a payload. each opcode +defines logic to handle payload length, so certain commands might expect a +fixed-length payload, a variable-length payload, or none at all. the start byte +is `0xff`, and because most data sent is in binary format, if the data contains +an `0xff` byte, it will be escaped by replacing it with two `0xff` bytes. this +is converted to a single `0xff` on the receiving end, so these duplicated bytes +and the starting byte don't count towards message length. -opcodes are picked sequentially, but bit 0 is reserved to indicate a transfer -from robot to client. this means that the opcode for a sensor data request -would be `0x14`, but the response opcode would be `0x15`. a c header is -provided that contains consts of these opcodes for code readability. +opcodes are picked sequentially, but the direction bit (LSB) is reserved to +indicate a transfer from robot to client. this means that the opcode for a +sensor data request would be `0x12`, but the response opcode would be `0x13`. +these opcodes are stored as enum constants inside consts.h for code +readability. |code|name|implemented|directions|full name| |--:|---|:-:|:-:|---| -|`0x00`|[BOMD](#bomd)|no|`r <=> c`|<u>b</u>ack<u>o</u>rder <u>m</u>o<u>d</u>ify -|`0x00`|[CORD](#cord)|no|`r <=> c`|<u>co</u>o<u>rd</u>inate -|`0x00`|[EXFL](#exfl)|no|`r <-- c`|<u>ex</u>ecution <u>fl</u>ow -|`0x00`|[SRES](#sres)|no|`r <-- c`|<u>s</u>oft <u>res</u>et -|`0x00`|[EXPT](#expt)|no|`r --> c`|<u>ex</u>ce<u>pt</u>ion -|`0x00`|[SPED](#sped)|no|`r <-- c`|<u>spe</u>e<u>d</u> -|`0x00`|[DIRC](#dirc)|no|`r <-- c`|<u>dir</u>ect <u>c</u>ontrol -|`0x00`|[DISP](#disp)|no|`r <-- c`|<u>disp</u>lay control -|`0x00`|[SENS](#sens)|no|`r <=> c`|<u>sens</u>or data -|`0x00`|[MAPS](#maps)|no|`r <-- c`|<u>map</u> <u>s</u>end |`0x00`|[PING](#ping)|no|`r <=> c`|<u>ping</u> -|`0x00`|[PLAY](#play)|no|`r <-- c`|<u>play</u> midi -|`0x00`|[CLED](#cled)|no|`r <-- c`|<u>c</u>ontrol <u>led</u>s +|`0x02`|[EXPT](#expt)|no|`r --> c`|<u>ex</u>ce<u>pt</u>ion +|`0x04`|[MODE](#mode)|no|`r <=> c`|<u>mode</u> +|`0x06`|[SPED](#sped)|no|`r <-- c`|<u>spe</u>e<u>d</u> +|`0x08`|[DIRC](#dirc)|no|`r <-- c`|<u>dir</u>ect <u>c</u>ontrol +|`0x0a`|[CORD](#cord)|no|`r <=> c`|<u>co</u>o<u>rd</u>inate +|`0x0c`|[BOMD](#bomd)|no|`r <=> c`|<u>b</u>ack<u>o</u>rder <u>m</u>o<u>d</u>ify +|`0x0e`|[SRES](#sres)|no|`r <-- c`|<u>s</u>oft <u>res</u>et +|`0x10`|[MCFG](#mcfg)|no|`r <-- c`|<u>m</u>ap <u>c</u>on<u>f</u>i<u>g</u> +|`0x12`|[SENS](#sens)|no|`r <-> c`|<u>sens</u>or data +|`0x14`|[INFO](#info)|no|`r <-> c`|<u>info</u> +|`0x16`|[DISP](#disp)|no|`r <-- c`|<u>disp</u>lay control +|`0x18`|[PLAY](#play)|no|`r <-- c`|<u>play</u> midi +|`0x1a`|[CLED](#cled)|no|`r <-- c`|<u>c</u>ontrol <u>led</u>s + +the DISP, PLAY, and CLED commands have low implementation priority, and should +be considered extra features + +a double stroke arrow means that the command can be initiated from either the +robot or the client, while a single arrow indicates a request-response +structure. + +### PING + +#### ping (`r <=> c`) (2 bytes) + +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x00 + 0` or `0x00 + 1`)| +|`uint8_t`|ping id| + +**ping** sends back an identical message either way with the direction bit +toggled. _ping id_ is a random 8-bit value that makes sure the same ping +doesn't keep bouncing back and forth indefinitely. + +### EXPT + +#### exception (`r --> c`) (3+ bytes) + +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x02 + 1`)| +|`uint8_t`|error code| +|`uint8_t`|length| +|`uint8_t[length]`|message contents| + +the **exception** instruction is used by the robot to send errors, warnings, +and other messages back to the client. an error can also optionally contain a +message between 0 and 255 characters long. message length is sent before the +message, and can be 0 in case of no message. + +### MODE + +#### set mode (`r <-- c`) (2 bytes) -#### BOMD +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x04 + 0`)| +|`uint8_t`|mode code| -##### backorder append +when initiated from the client, the **mode** command forces the robot to change +execution mode. the mode codes are undetermined as of now. -- length: 2 bytes -- client to robot +#### get mode (`r --> c`) (2 bytes) |type|description| |-:|-| -|`uint8_t`|opcode (`0x00 + 0`)| -|`uint8_t`|action| +|`uint8_t`|opcode (`0x04 + 1`)| +|`uint8_t`|mode code| -_action_ is a byte containing `0bXXXXXXYY` where X+1 is the amount of times -action Y gets repeated. Y can be: -- 0: move 1 tile forward -- 1: move 1 tile backward -- 2: turn right 90° -- 3: turn left 90° +the **mode** command is send by the robot when it switches into another mode. +the mode codes are undetermined as of now. -examples: -- move forward 4 tiles: `0b00001100` (`0x10`) -- turn 180°: `0b00000110` (`0x06`) or `0b00000111` (`0x07`) +<!-- TODO: mode codes in client and robot --> -##### backorder index +### SPED -- length: 9 bytes -- robot to client +#### set speed modifier (`r <-- c`) (2 bytes) |type|description| |-:|-| -|`uint8_t`|opcode (`0x00 + 1`)| -|`uint32_t`|backorder buffer length| -|`uint32_t`|backorder buffer index| +|`uint8_t`|opcode (`0x06 + 0`)| +|`uint8_t`|speed modifier| -#### CORD +scales motor output power from 0% (0x00) to 100% (0xff). -##### set position +### DIRC -- length: 6 bytes -- client to robot +#### set motor speed (`r <-- c`) (5 bytes) |type|description| |-:|-| -|`uint8_t`|opcode (`0x00 + 0`)| +|`uint8_t`|opcode (`0x08 + 0`)| +|`int16_t`|left motor speed| +|`int16_t`|right motor speed| + +directly set left and right motor speed values. only works in direct control +mode (unimplemented!). motor values range from -255 to 255. speed is sent as a +signed 16-bit integer (`short`). + +### CORD + +#### set position (`r <-- c`) (6 bytes) + +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x0a + 0`)| |`uint32_t`|position| |`uint8_t`|orientation| -_position_ = y * width + x +manually correct robot position and orientation in grid portion of the map. + +_position_ = y * width + x _orientation_: - 0: west - 1: north - 2: east - 3: south -##### get position - -- length: 6 bytes -- robot to client +#### get position (`r --> c`) (6 bytes) |type|description| |-:|-| -|`uint8_t`|opcode (`0x00 + 1`)| +|`uint8_t`|opcode (`0x0a + 1`)| |`uint32_t`|position| |`uint8_t`|orientation| -_position_ = y * width + x +sent by the robot in the grid portion of the map when a transition to a new +_position_ is finished. + +_position_ = y * width + x _orientation_: - 0: west - 1: north - 2: east - 3: south -#### EXFL +### BOMD + +#### append order (`r <-- c`) (9 bytes) + +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x0c + 0`)| +|`uint32_t`|order identifier| +|`uint32_t`|position| + +add a new order to the backorder list (queue). + +_position_ = y * width + x + +#### order status (`r --> c`) (6 bytes) + +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x0c + 1`)| +|`uint32_t`|order identifier| +|`uint8_t`|status| + +sent by the robot in the grid portion of the map when the status of an order +changes. also used to confirm orders are received successfully. + +_status_ is one of: +- 0: received +- 1: processing (begin) +- 2: reached +- 3: finished + +### SRES + +#### soft reset (`r <-- c`) (2 bytes) -##### set execution flow +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x0e + 0`)| +|`uint8_t`|type| + +_type_ is one of: +- 0: reinitialize all global state +- 1: reset emergency mode + +### MCFG -- length: 2 bytes -- client to robot +#### configure map (`r <-- c`) (4+ bytes) |type|description| |-:|-| -|`uint8_t`|opcode (`0x00 + 0`)| -|`uint8_t`|action| +|`uint8_t`|opcode (`0x10 + 0`)| +|`uint8_t`|width| +|`uint8_t`|height| +|`uint8_t`|length| +|`feature[length]`|features| + +> _feature_ is a struct containing: +> +> |type|description| +> |-:|-| +> |`uint16_t`|position| +> |`uint8_t`|kind| +> +> where _position_ = y * width + x +> and _kind_ = 0bXXYYYYYY where X = _orientation_ and Y = _type_ +> +> _orientation_: +> - 0: west +> - 1: north +> - 2: east +> - 3: south +> +> _type_: +> - 0: entrance / exit +> + +sends the map layout to the robot. the map is an automatically generated grid +of the specified size, starting at coordinates (1, 1) to keep a margin around +the grid for the maze-grid transition. + +example hexdump of 5x5 map with a north-facing entrance/exit at (3, 0) for +later reference: +``` +10 05 05 01 00 03 40 +``` + +### SENS + +#### request sensor data (`r <-- c`) (1 byte) -_action_ is: -- 0: suspend all operation -- 1: resume operation +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x12 + 0`)| -#### SRES +requests sensor data -##### soft reset +#### sensor data response (`r --> c`) (??? bytes) -- length: 1 byte -- client to robot +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x12 + 1`)| +|`???`|???| + +sensor data response. contains all sensor data (distance, ir, buttons) in one +packet. format yet to be determined. + +### INFO + +#### request robot info (`r <-- c`) (1 byte) |type|description| |-:|-| -|`uint8_t`|opcode (`0x00 + 0`)| +|`uint8_t`|opcode (`0x14 + 0`)| -#### EXPT -#### SPED -#### DIRC -#### DISP -DCLR display clear -DPOS display cursor position -DWSR display write string -DWBM display write bitmap -#### SENS -#### MAPS -#### PING -#### PLAY -#### CLED +requests robot info +#### robot info response (`r --> c`) (41 bytes) -## client/websocket +|type|description| +|-:|-| +|`uint8_t`|opcode (`0x14 + 1`)| +|`uint8_t[32]`|build string| +|`uint8_t`|errcatch module cycle time (ms)| +|`uint8_t`|io module cycle time (ms)| +|`uint8_t`|sercomm module cycle time (ms)| +|`uint8_t`|modes module cycle time (ms)| +|`uint32_t`|total robot uptime (s)| + +robot info response + +<!-- +### DISP +- DCLR display clear +- DPOS display cursor position +- DWSR display write string +- DWBM display write bitmap +--> -TBD diff --git a/robot/readme.md b/robot/readme.md index fa5774c..ebf2e3c 100644 --- a/robot/readme.md +++ b/robot/readme.md @@ -100,7 +100,7 @@ global todo: - [ ] clear global timer at start of cycle instead of just for mode selection module (for last ping time measurement) - [ ] calibrate (line-detecting) light sensors in setup.c, or manually by - placing the robot and pressing a button + placing the robot and pressing a button (maybe make this a seperate mode) ### hypervisor @@ -109,9 +109,6 @@ provides all other modules with a central place for defining global variables. ### pc communication -> this mode can't be implemented until the pc-communication protocol spec is -> finished - the pc communication module sends messages in a binary format over the serial connection provided by the wixel modules. this module should also send a 'ping' command each cycle to check if the connection is still intact. the pc will also @@ -190,9 +187,6 @@ implementation details for this mode are yet to be determined. ### emergency stop -> this mode can't be implemented until the pc-communication protocol spec is -> finished - the emergency stop mode stops the robot from doing anything until the user determines it is safe to resume execution. |