Vorpal 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.
Note: in the descriptions below, character encodings for literal characters are 7-bit ASCII.
Gamepad to Hexapod Communication Packet
A communication packet from the gamepad to the hexapod has the following format. In this discussion, literal characters are understood to be encoded in ASCII, for example literal 'V' is an eight bit byte encoded as decimal value 86.
- 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, literal characters from the set: W, D, or F (and if running V3 software, double click modes: X, Y, Z which correspond to double click on W, D, F respectively).
- A mode number: literal characters from the set: 1, 2, 3, or 4 (Note well: these are literal characters, not numeric values)
- A D-PAD letter, literal characters from the set: f, b, l, r, s, w.
- For example, W2f which means that the function to execute is walk mode 2 with the forward D-PAD button pressed. As such, this type of command always starts with a literal character of W, D, or F.
- For another example, if running V3 or later hexapod code, 'X3b' would mean the function to execute is double-click on W3, and pressing backward D-PAD.
- 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 may be used to set any number of legs to servo positions of a single particular value. 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 bitmask 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. (Note that only the first 12 servos correspond to legs, and this command can therefore also set additional servos beyond the legs if desired.) 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.
- An 8 byte "Gait" command. This command can be used to invoke a modification of internal gaits. The packet consists of:
- The literal 'G' for Gait
- A 1 byte gait style specification, one of:
- numeric 0: tripod gait
- numeric 1: turn in place gait
- numeric 2: ripple gait
- numeric 3: sidestep gait
- A 1 byte direction specification, one of:
- numeric 0: forward
- numeric 1: backward
- A 1 byte numeric value indicating the hip forward angle
- A 1 byte numeric value indicating the hip backward angle
- A 1 byte numeric value indicating the knee up value
- A 1 byte numeric value indicating the knee down value
- A 1 byte lean angle, numeric in the range of 0 to 139 with 70 meaning no lean, numbers under 70 specifying leaning forward and numbers over 70 meaning leaning backward
In order to make it easier to create apps that control the hexapod, a simplified control mode is available which does not require checksums. This can be used directly with existing control apps that allow you to program what sequence is transmitted for each button.
The 4-byte simplified mode format is:
- The literal character ASCII '@'
- A 3-byte gamepad function specification, which consists of:
- A mode letter, literal characters from the set: W, D, or F (and X, Y, Z if running V3 software or later).
- A mode number: literal characters from the set: 1, 2, 3, or 4
- A D-PAD letter, literal characters from the set: f, b, l (lower case letter L), r, s, w.
- For example, '@W2f' which means that the function to execute is walk mode 2 with the forward D-PAD button pressed. As such, this type of command always starts with a literal character of W, D, or F (and in V3 or later X, Y or Z as well).
- For double click modes, X means a double click on a W row command, Y for a D row command, and Z for an F row command.
If the gamepad is booted while holding down button W1, then it enters trim mode. This allows fine adjustment of the robot's servos so they are all centered. The trim values are stored on the robot in its EEPROM.
Trim mode packets sent from the gamepad to the robot are in this format:
- The literal character 'T'
- One command character
Note that there is no length or checksum. If the command letter is not a valid command then the trim packet is ignored. The command character can be one of these literal characters:
- f: Raise current knee servo signal by 1 microsecond
- b: Lower current knee 1 microsecond
- l: Move current hip clockwise 1 microsecond
- r: Move current hip counterclockwise 1 microsecond
- w: Move to next leg, the leg will twitch to indicate
- s: Do nothing, just hold steady
- S: Save all the current trim values
- P: Toggle the pose between standing and adjust mode
- R: Show untrimmed stance in the current pose
- E: Erase all the current trim values, resetting them to 0 microseconds
When I say "microseconds" I am referring to the servo signal timing. One microsecond of signal translates to approximately one tenth of one degree of servo rotation.
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 the literal 'S' followed by four sets of 2-byte words, high byte first, for a total of 9 bytes. These four words report sensor data as requested by the sensor command. The four words give the sensor values, in order, of A3, A6, A7, and the fully computed rangefinder distance in centimeters. See hexapod build documentation on the correct ports to hook up the rangefinder to for this to work.
- 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 start" 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.
- A "record end" command:
- The same as record start, however the 3-byte mode button/DPAD button specification is the special value 'SSS' which means stop recording.
- A "recording erase" command:
- The same as record start, however the 3-byte mode button/DPAD button specification is the special value 'DDD' which means erase all files on the SD card. This is useful when you just want to start over with a clean card.
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 (see above).
The Gamepad may also send debugging information to Scratch. Any communication from the gamepad that contains debugging messages starts with a # character, and the message continues until a newline character. Scratch will echo this data out to the developer console of the Chrome browser. If the gamepad code is compiled with any of the "debug" mode flags enabled, then these messages will become voluminous and might cause performance issues with Scratch programs.
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 100 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.
Vorpal The Hexapod Quick Links
|Sign Up For Our NEWSLETTER||VORPAL FORUM: Join the Discussion|
Getting & Giving Vorpal