UAVTalk

Introduction

UAVTalk is a highly efficient, extremely flexible and completely open binary protocol designed specifically for communication with UAVs. It is licensed under the Creative Commons BY-SA license so it can be implemented in commercial as well as Free software.

The UAVTalk Protocol uses the concept of telemetry objects, this object orientation makes the protocol extremely flexible and scalable. The object based design also allows the protocol to be optimised for low speed telemetry channels but conversely can also be configured for rapid update times and large object payloads for high bandwidth links.

The protocol is channel independent since it is expected that it will be used over a variety of wireless modems and channels. All channels are expected to support bi-directional communication. Although many channels will be half-duplex , full-duplex operation will be emulated in most cases (e.g. Xbee modems are half-duplex over the wireless channel but behave as full duplex over the serial link). The downlink will support telemetry messages containing GPS, leveler, navigation and other information that is needed by the GCS. The uplink will be used to control the autopilot, limited access to the SD memory will also be given for updating flight-plans, settings and possibly plug-ins. Some precautions will need to be taken to avoid transferring large files or possibly limiting some commands during flight.

To support a variety of data objects, the low level protocol is not aware of the structure of the data transmitted. Packing, unpacking and interpretation of the data is handled by the upper layers. The diagram below shows the structure of the protocol and it is described in more detail in the following sections.

In this page
 

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 partFieldLength (bytes)Value








Header

Sync Val

10x3C




Message Type




1

Lower nibble means the kind of message:

  • 0x0 Object Data (OBJ) 
  • 0x1 Object request (OBJ_REQ)
  • 0x2 Object with acknowledge request (OBJ_ACK)
  • 0x3 Acknowledge (ACK)
  • 0x4 Negative-Acknowledge (NACK) 

Higher nibble has the following meaning

  • bits 5-7 Protocol version ( current version is 2, 0x20)
  • bit 8 (0x80) indicates a timestamped message.
Length2

Not needed since object ID predicts this but needed for blind parsing.

Length of header and data, not checksum.

Object ID4Unique object ID (generated by parser, also used for framing and version control)
Instance ID2Unique object instance ID. Always 0 for single instance UAVObjects

Timestamp

(only if Message Type && 0x80)

2Timestamp for timestamped objects (not handled by GCS)
DataData0-255Serialized (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.
ChecksumChecksum1CRC-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:

FieldField length (bit)Flag detailsFlag Length (bit)Value





   Flags





16

access1Defines the access level for the local transactions (readonly=0 and readwrite=1)
gcsAccess1Defines the access level for the local GCS transactions (readonly=0 and readwrite=1), not used in the flight s/w
telemetryAcked1Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
gcsTelemetryAcked1Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
telemetryUpdateMode2Update mode used by the telemetry module (UAVObjUpdateMode)
gcsTelemetryUpdateMode2Update mode used by the GCS (UAVObjUpdateMode)
LoggingUpdateMode2Update 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:

SideSync ValMessage TypeLengthObject IDDataChecksumComment
CC3C221D 00E8 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 request30FlightTelemetryStats


 GCS  3C 2308 00 E8 B7 75 3F
73 GCS Responds Object Acknowledge 


Obj acknowledge response 8FlightTelemetryStats



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 request30GCSTelemetryStats


CC3C2308 00E4 46 C3 B6
1BCC responds Object Acknowledge


Obj Acknowledge response8GCSTelemetryStats



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 request30FlightTelemetryStats


GCS3C2308 00E8 B7 75 3F
73GCS respond Object Acknowledge


Obj acknowledge response8FlightTelemetryStats



3C221D 00E4 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

and Object Acknowledge request


Obj acknowledge request30GCSTelemetryStats


CC3C

23

08 00E4 46 C3 B6
1BCC respond Obj Acknowledge


Obj Acknowledge response8GCSTelemetryStats


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:

FieldLength (bytes)Description
Timestamp4, quint32timestamp of the save operation
Data Block Size8, quint64Length of the datablock saved
Data Block"DataBlock Size"This is the UAVTalk package, complete with header and Crc.