Development UAVTalk Protocol
Clone this wiki locally
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.
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.
The packet format is shown below.
|Message type||1||Object (OBJ): 0x20, Object request (OBJ_REQ): 0x21, Object with acknowledge request (OBJ_ACK): 0x22, Acknowledge (ACK): 0x23, Negative-Acknowledge (NACK) : 0x24. If the flag 0x80 is present it indicates this is a timestamped packet. Note: The most significant 4 bits indicate the protocol version (v2 current).|
|Length||2||Not needed since object ID predicts this but useful 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 (optional)||2||Unique object instance ID. Only present in UAVObjects that are NOT of type 'single instance'|
|Timestamp (optional)||2||For packet types with the timestamp flag (0x80 set) this field will contain a two byte timestamp in milliseconds|
|Data||0-255||Serialized (packed) object. The length of data is inherent knowledge about that particular object's size as identified by ObjectID.|
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.
Bits 7 to 4 of the message type field are used to indicate the UAVTalk version used in the message. Packets with unrecognised protocol versions should be ignored.
Object Message (OBJ)
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 (OBJ_REQ)
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 zero) 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 NACK message, instead of the OBJ message (see description of NACK below).
Object with Acknowledge Request Message (OBJ_ACK)
The OBJ_ACK message is similar to a regular OBJ message but this time an acknowledgment shall be 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. It does have the instance ID in the case of a multiple instance object.
Proposed (pending) precision: in case the receiver of the message does not know about the Object that is being sent (i.e. the object's ObjecID is unknown on the receiving end), then it will reply with a NACK message.
Negative-Acknowledge Message (NACK)
NACK is a message with no payload except an optional Instance ID based on the object type (none for a single instance object)
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 NACK message so that the sender can take into account the absence of this ObjectID on the remote side, and act accordingly.
Proposed (pending) change: a NACK message shall be sent in case the receiver receives an Acknowledged Object message (OBJ_ACK) and does not recognize the ObjectID of that object.
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).
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.
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.
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.
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.