A combination of a C# server and an arduino program that allows you to control a bunch of Hull Pixelbots at once. Currently a work in progress - it should be amazing once it's done!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

11 KiB

PixelHub Protocol Documentation

Version 0.1

The PixelHub Protocol is a communication protocol for WiFi-capable Hull PixelBots to communicate with and be controlled by a remote server. While the protocol is binary, it is designed to be fairly easy to parse and implement.

Basic Information

The PixelHub Protocol is conducted over a single TCP connection. Obtaining these details can be done automatically by listening to the UDP multicast beacon set up by the server.

In this specification document, when referring to bytes, The C++ notation will be used. Examples: 0b00000000, 0b01010101.

Each PixelHub message is terminated by a null byte (0b00000000).

The current Protocol Version is 1.

Conversation Flow

  • [ Hub -> Bot ]: Send instruction
  • [ Bot -> Hub ]: Acknowledge instruction
  • [ Bot ]: Execute command
  • [ Bot -> Hub ]: Notify about instruction completion

Message Struture

Basic Message Structure

This is the basic structure of a PixelHub Protocol message. The labels are explained below:

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| ushort Protocol Version | ushort Message Type     |
| uint Message Id                                   |
| uint Message Length                               |
| byte[] Message Contents                           |
| byte null  | 
  • ushort Protocol Version - The pixelhub protocol version, as an unsigned short, that is being spoken. Either the server or the client reserve the right to kill any connections (and optionally send an incorrect protocol version packet) to any parties not speaking their protocol version.
  • ushort Message Type - The type of message, as an unsigned short, of message that is being sent. The values for this may be mapped into an enum.
  • uint Message Id - The message id, as an unsigned integer. Should be randomly generated. Message replies must contain instead the id to of the message they are replying to.
  • uint Message Length - The length of the following message contents, in 8 bit bytes.
  • byte[] Message Contents - The content of the message that has been sent. Once the message itself has been parsed, the body can be extracted and passedto the appropriate handler for parsing.
  • byte null - A single null byte (0b00000000). This signifiest he end o the message. Even though it's technically not needed because of the Message Length included above, it's been added anyway to simplify initial parsing and message end detection.

Error: When bots complain

Error messages are in direct response to a message that the sending party recieved that it didn't like. The body is optional, but if specified, should contain the following:

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| uint Error Code                                   |
| char* Error Message                               |
  • uint Error Code - The code attached to the error message. Error codes are a positive integer. Numbers 1-10000 are reserved for the server. See the error code section at the end of this document.
  • char* Error Message - Additional human-readable details about the error in question that has occurred. May be empty, especially if the server is complaining to the client, as the client probably won't have anything to do with it unless it's being debugged.

HandshakeRequest: Beginning a handshake

In the PixelHub protocol, handshakes are initiated by the client, and completed by the server. The server may close a connection if it hasn't received a handshake within a given length of time (the server can decide on this, but it shouldn't be less than 5 seconds).

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| char* PixelBot Type                               |
  • char* PixelBot Type - The type of pixelbot sending the handshake request. This should be an array of characters, terminated by a null character. It shouldn't be more than 32 characters in length.

HandshakeResponse: Completing a handshake

The counterpart to the above is the HandshakeResponse message. It's a direct response to a HandshakeRequest message, and is documented below:

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| uint Id											|
  • uint Id - The id that the PixelHub server is assigning to the PixelBot.

Move: Asking a PixelBot to move

From here on only the Message Content will be displayed in the diagrams. It must be wrapped in the [Basic Message](#Basic Message) structure described above.

Asking a PixelBot to move is done quite simply. A pixelbot can either move forward or backwards, or turn left or right on the spot. This is evident in the movement command syntax, shown below:

Message Type: 20

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| byte       |                         |
| Movement   | ushort Tick Count       |
| Type       |                         |
  • byte Movement Type - The type of movement that should be made. See the [Movement Types](#Movement Types) table below.
  • ushort Tick Count - The number of ticks that the movement should be made for.

Movement Types

Type Name Description
0 Stop No movement at all.
1 Forwards Moving forwards.
2 Backwards Moving backwards.
3 Left Turning left.
4 Right Turning right.

CommandOk: When the PixelBot is ok with a command

This message doesn't have a body, but it is sent by a PixelBot to say that it is going to perform the command that was sent previously.

This message is a direct response to a Move command.

CommandComplete: When a PixelBot completes a command

This message doesn't have a body, but is sent by a PixelBot when it finished executing a Move command. It should be in direct response the Move command sent by the server.

CommandFailed: PixelBot Complaints

This message doesn't have a body, but it's sent by PixelBots who can't complete an instruction they've been given. It should be in direct response to the Move command that it is complaining about.

InfoRequest: Requesting information

An InfoRequest can be used by the server to request information from the client. Information held by a PixelBot is accessed by the server in a key / value format. All keys and values are formatted as a char* - the server needs to parse the result sent by the PixelBot into the appropriate type. It does have a body, and it is formatted like this:

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| char* Key                                         |
  • char* Key - The key. Must not contain a null byte - there's one at the end of the message.

InfoResponse: Responding with information

The response to an InfoRequest. Must be in direct reply to the InfoRequest that it is responding to. The possible keys and values are detailed in the [keys and values](#Information keys and values) section.

|   Byte 1   |   Byte 2   |   Byte 3   |   Byte 4   |
| char* Value                                       |
  • char* Value - The value that corresponds to the key requested in the InfoRequest. Numbers should be converted to their string representation - i.e. converted to ASCII / UTF8. Must not contain a null byte - there's one at the end of the message.

Information keys and values

Information requests enable the server to request several different pieces of information from a PixelBot.

Key Value description
Id The PixelBot's unique id.
TicksTravelled The number of ticks that the PixelBot has been moving for.
LastMoveDirection The direction that the PixelBot last moved in. See the [Movement Types](#Movement Types) section.
LastMoveDuration The duration that the PixelBot last moved for in ticks.
PixelBotType The type of PixelBot that this bot is. SHould be the same character array from the HandshakeRequest.
TicksPerRevolution The number of ticks that this PixelBot needs in order to do one ful revolution of it's wheels.

If a key is not found, then a blank InfoResponse must be returned.

Message Types

Message types, as briefly described in the [Basic Message Structure](#Basic Message Structure), are represented as an unsigned short number. All the possible message types are documented below:

Type Name Description
0 Reset Hard-resets the PixelBot. Useful if something has gone wrong, or to reset it's internal state.
1 Error May be sent by either party. Indicates that one or the other doesn't like a message that was sent by the other party.
5 HandshakeRequest Sent by a PixelBot upon connection.
6 HandshakeResponse Sent by the server in response to a HandshakeRequest.
11 Move Instructs a PixelBot to perform a movement.
12 CommandOk Sent by a pixelbot to indicate that the command sent by the server is ok, and that it will proceed to execute it.
13 CommandComplete Sent by a pixelbot to indicate that it has completed executing the command sent previously.
14 CommandFailed Sent by a pixelbot to indicate that it has failed to complete the execution of a command it received previously.
20 InfoRequest Sent by the server to request information from a PixelBot. This could be from sensors, configuration, statistics, etc.
21 InfoResponse Sent by a PixelBot in response to an InfoRequest message.

Note that a status message isn't actually contained in this protocol. This is becaue it is rather awkward to respond to network messages in the middle of a movement, so it will always be something along the lines of 'idle'.

Error Codes

It's highly likely that an error will occur sooner or later. In the PixelHub protocol, all errors have their own number, where no number is ever thrown in the same place in the code base twice, allowing for errors to be reliably traced back ot their source without a usable stack trace. The following caregories of error have been assigned:

  • 0 - A general error. Please try not to use this if at all possible.
  • 1-9,999 - Server errors.
  • 10,00-19,999 - PixelBot errors.