Vorpal Combat Hexapod Radio Protocol Technical Information
Vorpal Combat Hexapod Quick Links:
WARNING: This is highly technical information and is meant only for advanced users who need to dig deeper! It is here so advanced users can understand how the data flows between the robot and gamepad, in case anyone wants to extend or enhance the Arduino code running on the hexapod or gamepad. So don't be scared! Typical Vorpal Hexapod users need never know any of this information in order to operate the hexapod successfully. This page is written assuming the reader has some familiarity with radio protocols and data transmission.
Gamepad to Hexapod Communication Packet
A communication packet from the gamepad to the hexapod has the following format:
- The literal character 'V' starts the packet.
- The literal character '1' indicates protocol version 1.
- A one-byte length, called L in this description. This is the length of the payload data only, it does not include the 'V1' header, the length byte, or the checksum byte.
- The actual payload data consisting of a number of bytes equal to L.
- A checksum byte. This is the modulo 256 sum of the length byte L and all of the payload bytes.
The payload can contain one or more commands to the hexapod. There are several different formats for these commands:
- A 3-byte gamepad function specification, which consists of:
- A mode letter: W, D, or F
- A mode number: the literal characters 1, 2, 3, or 4
- A DPAD letter: f, b, l, r, s, w.
- For example, W2f which means that the function to execute is walk mode 2 with the forward DPAD button pressed. As such, this type of command always starts with a literal character of W, D, or F.
- A 5-byte beep command. This command consists of:
- Starts with the literal letter 'B'
- A 2-byte frequency, high byte first. Frequency is only effective between about 50 and 2000 Hertz.
- A 2-byte duration, high byte first. This is the duration of the beep in milliseconds, interpreted as an unsigned integer.
- NOTE: There is a planned enhancement in the future which would allow the robot to queue up to 32 beep commands which would be played in succession in accordance with their duration. However, currently you would have to wait between beep commands (for example when programming using scratch).
- A 4-byte leg motion command. This command consists of:
- The literal character L.
- The next byte is the leg selection mask, which has one bit for each leg that is affected by the command. The low bit is leg 0, the next higher bit is leg 1, etc.
- A 1-byte bitmaks of flags. Currently, the flags may take the numeric value 0 or 1, where 0 means no flags and 1 means that hip motions should be mirrored on the left and right sides of the robot (useful for most types of walking).
- The hip position value, from 0 to 179, followed by the knee value, from 0 to 179.
- For either the hip or knee position, the special value 255 means no movement is required. This allows the leg motion command to move just the hips or just the knees.
- There may be several of these concatenated in order to move different groups of legs to different positions in a single packet.
- A 1 byte sensor report command, consisting of:
- The literal character 'S'
- Currently all sensors are sent all the time, in the future the plan is to add a bitmask option to this command to allow selective return of sensor values.
- An 18 byte "Raw Servo" command which can set all 16 servo values or any subset of values. The 18 byte packet consists of:
- The literal character 'R' (for "Raw")
- A 1 byte operator specification. This currently can be one of:
- The numeric value 0 to mean "set equal to" the position value given below.
- The numeric value 1 meaning "add the position value to the current servo position".
- The numeric value 2 meaning "subtract the position value from the current servo position".
- Sixteen position values, one for each servo, in order from servo port 0 to 15. These position values can be one of these values:
- The special value numeric 255 meaning "do not change position". This value ignores the operator specification.
- The special value numeric 254 meaning "put servo to sleep". This value ignores the operator specification. Power will be cut to the servo motor and it will go slack.
- A degree value from 0 to 180. Depending on the operator value, each servo is either set to the literal position value, has the position value added, or has the position value subtracted. If an add or subtract operation would take the servo out of the range 0 to 180 then values are clamped to the range 0 to 180.
Hexapod to Gamepad Communication Packet
The hexapod only responds when it receives a sensor command (see above). Typically this sensor data is relayed by the gamepad over its serial port to be used by a Scratch X program. The format of the return data is:
- The literal character 'V'
- The literal character '1' which is the protocol version number
- The payload length, which will be referred to as L in this section.
- The payload bytes, of length L.
- The payload consists of 2-byte words, high byte first, reporting sensor data as requested by the sensor command.
- A checksum value which is a modulo 256 single byte sum of the payload bytes plus the L value.
Sensor data is currently hard coded to the following values (two bytes unsigned integers, high byte first)
- Ultrasonic rangerfinder distance in centimeters (1000 cm if nothing detected)
- CMUCam5 signature
- CMUCam5 x coordinate of largest object found
- CMUCam5 y coordinate of largest object found
- CMUCam5 width of largest object found
- CMUCam5 height of largest object found
NOTE: CMUCAM5 testing is still in progress, this is considered an experimental feature right now. At some times this may be commented out of the code.
Scratch to Gamepad Communication
A Scratch program may send two kinds of data packet to the gamepade over the serial port:
- A normal hexapod packet, which can be any of the possible data packets that the gamepad would send to the hexapod.
- A "record" command, which consists of:
- The literal character 'R'
- The literal character '1' which is the protocol version number.
- A 3-byte mode button/DPAD button specification which indicates which gamepad buttons trigger the recording. For example, W1f would store the recording on the Walk mode 1 button and would be triggered when the forward DPAD button is pressed.
- The 3-byte mode button/DPAD button specification can also be the special value 'SSS' which means stop recording.
Because communication over the serial port is not error prone, there is no checksum on this protocol.
Gamepad to Scratch Communication
The Gamepad simply relays any data it receives from the robot (over the Bluetooth connection) to its USB serial port for use by Scratch X programs. Right now, the only thing the robot sends back to Scratch is sensor data.
Some Notes on Bluetooth Transmissions
Although the Bluetooth modules can send and receive at the same time, the SoftwareSerial Arduino library is used on both the hexapod and gamepad, and that library is unable to support simultaneous transmission and reception. For this reason, the Scratch X extension only sends data once every 100 milliseconds and the protocol sends back sensor data in the empty air time between these transmissions.
Analysis for those who are interested: The Scratch program transmission is guaranteed not to exceed 44 bytes, and at the 38,400 baud data rate that amount of data will be transmitted in about 10 milliseconds, meaning there is guaranteed to be about 90 milliseconds of clear air after a packet is sent from Scratch through the gamepad. The Hexapod is programmed to send sensor data immediately after it receives commands over Bluetooth, and this sensor data transmission completes in less than about 5 milliseconds, and so easily completes before the next set of commands are sent. This strategy ensures that neither the gamepad nor the hexapod are ever simultaneously sending and receiving Bluetooth traffic, in fact there is a quite conservative margin of error built into the protocol.
It may be possible to increase the data rate coming from Scratch (and the gamepad as well), cutting the delay time from the current 100 milliseconds to perhaps 50 to 60 milliseconds and still have an acceptable margin to avoid sends and receives from happening at the same time. In practice, most users report that the gamepad responsiveness does not feel "laggy", and it takes about 50 to 00 milliseconds for servos to move in response to most types of command anyway. There would be other considerations that would have to be tested and analysed, such as whether inexpensive SD cards could still write fast enough with this higher transmission rate (for record mode).
Also, in the current implementation, sensor data is always requested by Scratch regardless of whether the Scratch program is using it. When a Scratch program tests the value of a sensor, it is testing whatever value was most recently received. This could be changed if necessary to allow faster data rates when sensors are not being used and there is no fear of simultaneous receive/transmit operations occurring.