UAVTalk
The UAVTalk Protocol
The UAVTalk protocol implements the low level communication between the GCS and the autopilot. It simply provides the transport of the data structures defined by the UAVObjects. To make the addition of UAVObjects easier, the UAVTalk protocol does not need to know the details of the data structure as this is handled by the UAVObject instead. UAVTalk is only responsible of sending byte arrays and routing received byte arrays to the correct object for unpacking.
Message part | Field | Length (bytes) | Value |
---|---|---|---|
Header | Sync Val | 1 | 0x3C |
Message Type | 1 | Lower nibble means the kind of message:
Higher nibble has the following meaning
| |
Length | 2 | Not needed since object ID predicts this but needed for blind parsing. Length of header and data, not checksum. | |
Object ID | 4 | Unique object ID (generated by parser, also used for framing and version control) | |
Instance ID | 2 | Unique object instance ID. Always 0 for single instance UAVObjects | |
Timestamp (only if Message Type && 0x80) | 2 | Timestamp for timestamped objects (not handled by GCS) | |
Data | Data | 0-255 | Serialized (packed) object. The length of data is inherent knowledge about that particular object's size as identified by ObjectID. Be aware that before serializing the object, the parser sorts the fields according to length. |
Checksum | Checksum | 1 | CRC-8 checksum (Header and Data) |
There are currently a total of three different type of transactions, each one is described below.
The data field is packed with values stored as little endian. This is consistent with x86, and ARM in the default little endian mode, but requires translation for big endian processors.
Protocol Version
Bits 7 to 4 of the message type field are used to indicate the UAVTalk version used in the message. Packets with unrecognized protocol versions should be ignored.
Object Message
The object message is a simple one way update of an object. Once this message is received the unpack function of the corresponding object is invoked and the object fields are updated. No response is sent on OBJ messages and they are typically used on periodic updates (see below).
Object Request Message
Object requests are sent whenever the latest value of an object is required by the sender. The OBJ_REQ message has no payload (length field is 10 / 0x0a00) and the recipient immediately responds by packing the object data and sending an OBJ message.
In case the ObjectID requested is not found, the receiver will answer with a OBJ_NACK message, instead of the OBJ message (see description of OBJ_NACK below).
Acknowledged Object Message
The OBJ_ACK message is similar to a regular OBJ message but this time an acknowledgment is sent back to the sender to confirm that the object was received by the remote end. The acknowledgement is in the form of an ACK message with no payload.
Negative-Acknowledged Object Message
OBJ_NACK is a message with no payload.
OBJ_NACK is sent in response to a OBJ_REQ message, whenever the requested ObjectID does not exist on the remote side. The non-existent requested objectID is sent back with the OBJ_NACK so that the sender can take into account the absence of this ObjectID on the remote side, and act accordingly.
Object ID
The object ID is a unique 32-bit integer identifying the object the message data represent. The UAVTalk layer routes all received payloads to the appropriate object for unpacking. The object ID is automatically generated by the parser by applying a hash on the XML definition of the object. This has two advantages, first the ID is unique (very small probability of collision exists but it is insignificant) so there is no need for a centralized database of IDs, objects can be added without worrying about choosing a unique ID. Second each time the object definition is changed the ID will also change, this is a convenient way to make sure that UAVObjects on the GCS and autopilot have the same definition (i.e. have the same version).
Framing
The message type and object ID fields (first 5 bytes) also serve as framing bytes and used to detect the start of a packet. There are only a very small set of values out of all possible combinations of the first 5 bytes that are used for actual messages. In other words, the probability that the first five bytes randomly form a valid object header is very small and therefore they can be used for framing.
Automatic updates
The UAVTalk layer is also responsible for periodic object updates. Each registered object has a timer associated with it, when the timer expires an OBJ message is sent. The timer values can be dynamically updated.
Following message exchange examples are not yet up to date to latest changes in UAVTalk. While the sequences are fine, some details on the message are not correct (i.e. Instance id that is no more optional)
Metadata
Object metadata can be requested and sent by using the ObjectId +1. The metadata object has the same format as a normal object with instance 0 and the metadata fields in the following format:
Field | Field length (bit) | Flag details | Flag Length (bit) | Value |
---|---|---|---|---|
Flags | 16 | access | 1 | Defines the access level for the local transactions (readonly=0 and readwrite=1) |
gcsAccess | 1 | Defines the access level for the local GCS transactions (readonly=0 and readwrite=1), not used in the flight s/w | ||
telemetryAcked | 1 | Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) | ||
gcsTelemetryAcked | 1 | Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) | ||
telemetryUpdateMode | 2 | Update mode used by the telemetry module (UAVObjUpdateMode) | ||
gcsTelemetryUpdateMode | 2 | Update mode used by the GCS (UAVObjUpdateMode) | ||
LoggingUpdateMode | 2 | Update mode used by the logging module (UAVObjUpdateMode) | ||
flightTelemetryUpdatePeriod | 16 | Defines flags for update and logging modes and whether an update should be ACK'd (bits defined above) | ||
gcsTelemetryUpdatePeriod | 16 | Update period used by the GCS (only if telemetry mode is PERIODIC) | ||
loggingUpdatePeriod | 16 | Update period used by the logging module (only if logging mode is PERIODIC) |
UavUopdateMode:
UPDATEMODE_MANUAL = 0, /** Manually update object, by calling the updated() function */ UPDATEMODE_PERIODIC = 1, /** Automatically update object at periodic intervals */ UPDATEMODE_ONCHANGE = 2, /** Only update object when its data changes */ UPDATEMODE_THROTTLED = 3 /** Object is updated on change, but not more often than the interval time */
Telemetry handshake
Telemetry between Copter Control and GCS over a serial link is established by a sequence of changes in the Status field of the FlightTelemetryStatus and GCSTelemetryStatus UAVObjects. The sequence passes through Status values DISCONNECTED = 0, HANDSHAKEREQ = 1, HANDSHAKEACK = 2, and CONNECTED = 3 as in this example from the Feb 1, 2012 release.
In a Serial Data Monitor the transmission looks like this:
Port opened by process "openpilotgcs.exe" (PID: 2812)
Answer: 27/01/2012 03:59:00 p.m..98164
3C 22 1D 00 E8 B7 75 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5
Request: 27/01/2012 03:59:00 p.m..98264 (+0.0010 seconds)
3C 23 08 00 E8 B7 75 3F 73 3C 22 1D 00 E4 46 C3 B6 01 00 00 10 41 00 00 F0 41 00 00 00 00 00 00 00 00 00 00 00 00 B2
Answer: 27/01/2012 03:59:00 p.m..02064 (+0.0370 seconds)
3C 23 08 00 E4 46 C3 B6 1B 3C 22 1D 00 E8 B7 75 3F 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6A
Request: 27/01/2012 03:59:00 p.m..02164 (+0.0010 seconds)
3C 23 08 00 E8 B7 75 3F 73 3C 22 1D 00 E4 46 C3 B6 03 00 00 1C 42 00 00 1C 42 00 00 00 00 00 00 00 00 00 00 00 00 09
Answer: 27/01/2012 03:59:00 p.m..13364 (+0.1110 seconds)
3C 23 08 00 E4 46 C3 B6 1B
An explanation of the above data is described in the next table:
Side | Sync Val | Message Type | Length | Object ID | Data | Checksum | Comment |
---|---|---|---|---|---|---|---|
CC | 3C | 22 | 1D 00 | E8 B7 75 3F | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | E5 | CC sends Disconnected Status and Object Acknowledge Request |
Obj acknowledge request | 30 | FlightTelemetryStats | |||||
GCS | 3C | 23 | 08 00 | E8 B7 75 3F | 73 | GCS Responds Object Acknowledge | |
Obj acknowledge response | 8 | FlightTelemetryStats | |||||
3C | 22 | 1D 00 | E4 46 C3 B6 | 01 00 00 10 41 00 00 F0 41 00 00 00 00 00 00 00 00 00 00 00 00 | B2 | GCS sends Handshake Request and Object Acknowledge request | |
Obj acknowledge request | 30 | GCSTelemetryStats | |||||
CC | 3C | 23 | 08 00 | E4 46 C3 B6 | 1B | CC responds Object Acknowledge | |
Obj Acknowledge response | 8 | GCSTelemetryStats | |||||
3C | 22 | 1D 00 | E8 B7 75 3F | 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 6A | CC responds Handshake Acknowledge and sends Object Acknowledge request | |
Obj acknowledge request | 30 | FlightTelemetryStats | |||||
GCS | 3C | 23 | 08 00 | E8 B7 75 3F | 73 | GCS respond Object Acknowledge | |
Obj acknowledge response | 8 | FlightTelemetryStats | |||||
3C | 22 | 1D 00 | E4 46 C3 B6 | 03 00 00 1C 42 00 00 1C 42 00 00 00 00 00 00 00 00 00 00 00 00 | 09 | GCS sends Connected Status | |
Obj acknowledge request | 30 | GCSTelemetryStats | |||||
CC | 3C | 23 | 08 00 | E4 46 C3 B6 | 1B | CC respond Obj Acknowledge | |
Obj Acknowledge response | 8 | GCSTelemetryStats |
As you can see, every time that GCS sends an Object, it sends an Object Acknowledge Request which is responded to by the CC, and vice versa. The other important things are that the order of the bytes of Length and Object Id are swapped (ie. 0x0800 = d8), and the first byte of the data (in boldface font) represents the Status byte.
UAVObjects and the Parser
UAVObjects are the actual object containers and are the main interface to the plugins and core application for both the GCS and autopilot. Normally the UAVTalk layer is only used through the UAVObjects and not directly by the application. The UAVObjects maintain a number of data fields and provide the packing and unpacking functions to the UAVTalk layer. The actual code for the UAVObject is generated by the parser based on an XML definition of the object and its fields. The parser will then generate the necessary autopilot and GCS code of the UAVObject. There will be multiple UAVObjects one for each object defined in the XML. It is expected that each plugin will have its own XML and set of UAVObjects. In addition the parser will generate the functions required for generic access to the data, this will be used by parts of the GCS that does not need to know the actual object type (e.g. the GCS plotting feature).
The parser will also generate the fields required to remotely configure the period of the automatic object updates.
Example – Updating navigation data
This is a fairly straight forward example, the fields of the navigation object will be defined in an XML and the parser will generate the necessary UAVObject for the GCS and autopilot. The autopilot will use the generated UAVObject for sharing the navigation data internally (with plugins for example) and with the GCS. At a configurable interval the object will be packed and sent to the GCS.
Example – Accessing airframe configuration options
The airframe configuration can be easily represented by an UAVObject, the different configuration fields and their type will be defined in a XML file. The parser will generate the UAVObject code for the GCS and autopilot. On power-up the autopilot will load the airframe configuration from the ini file stored in the SD card and initialize the object fields. Every time a field needs to be updated the GCS application will simply update the corresponding field in the GCS UAVObject and through the UAVTalk layer the update will be propagated to the autopilot.
Example – Log recording and replay
Log recording can also easily achieved by the UAVTalk layer. On configurable intervals the objects will be packed and stored in SD memory with a time stamp. The same log can then be replayed in the GCS by feeding the recorded objects in the UAVTalk layer, the UAVObjects and application will not be aware that the updates are coming from a recorded log. A similar approach can be used for plotting the data from a log or exporting them to a text file.
OPL format
OPL format is a simple binary format used by GCS to save the Telemetry log.
An opl file is made of a series of block having the structure shown in the following table:
Field | Length (bytes) | Description |
---|---|---|
Timestamp | 4, quint32 | timestamp of the save operation |
Data Block Size | 8, quint64 | Length of the datablock saved |
Data Block | "DataBlock Size" | This is the UAVTalk package, complete with header and Crc. |