Clone this wiki locally
Note: Most of this is relevant for the GCS implementation too
Telemetry is handled by a service so that it can exist outside the life cycle of individual activities and widgets. This also means your connection can be maintained while multitasking. The OPTelemetryService class provides this service and creates a connection through the desired physical medium. Right now Blueooth and TCP are supported and provided by the BluetoothUAVTalk and TcpUAVTalk classes, respectively.
The service receives two intents, OPTelemetryService.MSG_CONNECT and OPTelemetryService.MSG_DISCONNECT. The type of connection established is based on the stored preferences and creates it's own thread. These threads maintain their own object manager and activities and gadgets will request the handle to this object manager to get access to the data. This means, again, that the data has a life cycle longer than the individual activities.
The TcpTelemetryThread task is a private class of the OPTelemetryService started for a tcp task. This thread owns the UAVTalk, Telemetry and TelemetryMonitor and ObjectManager objjects. It will create a TcpUAVTalk object, attempt to connect, and if connected repeated process the input stream until the terminate flag is set. This is problematic as the telemetry needs to inform the service when the connection failed. Note that currently this thread is responsible for calling the processInputStream method on the UAVTalk handle.
The TcpUAVTalk class creates an appropriate input and output stream (in this case connected to a TCP socket) and passes these to a UAVTalk object which interfaces between these streams and an object manager.
TODO: In future the UAVTalk object itself should handle all the communications and the original TcpTelemetryThread should be unneeded or should be refactored into UAVTalk.
After connecting to the stream Telemetry and TelemetryMonitor objects and passed the handles to the object manager and uavtalk to monitor the connection and handle connection/disconnection as well as telemetry transactions (a higher level of packet on top of the raw uavtalk packet).
This is very much like the GCS implementation and will not be discussed here. The important point is it has no self created activity - just either receives processInputStream and various sendObject methods.
Like GCS telemetry, this class registers to all the objects and handles transactions and notifying the rest of the application architecture when an object has changed in the UAVObjectManager. This goes both ways as it tries to handle the transactions to notify the UAV when objects have changed on the GCS side. It also creates a transaction timer which persists on it's own and probably uses the parent telemetry thread Looper.
It has a two timers, one for transactions and one for periodic object updates.
Determines when the overall telemetry link goes up and down. Sends a broadcast message to update the whole system accordingly.
Packets and Transactions
The phrase transaction is used multiple times within the telemetry code and means slightly different things in different places, both in Android and in the GCS.
UAVTalk has the concept of a simple packet. Some of these packets require something back and we will call these packets a UAVTalkTransaction. These come from:
An object request expects to get a matching object packet back. An update of an object with an ack specified in it's meta data expects to get an ack back. A NACK can also be returned from the flight side to indicate that object ID is unknown and will never be returned or ack'd. So when either a packet of type TYPE_OBJ_REQ or a pack of type TYPE_OBJ for an object with an Ack set is sent, UAVTalk expect to get one back in return. Each side must determine if a UAVTalkTransaction has failed and deal with this appropriately, which is usually inform the higher level code since the behavior is context specific. Currently Android UAVTalk only supports one outgoing UAVTalkTransaction.
Telemetry performs slightly higher level transactions that UAVTalk and also takes care of performing all the periodically scheduled transmissions. Transactions at this level have retries and timeouts. We will call these TelemetryTransactions.
Telemetry maintains two queues of TelemetryTransactions (events) to perform. Events come from by listening to callbacks from the objects themselves, which are then triggered by either uavtalk or calling things like object.updated(). These events are:
- EV_UNPACKED - Object data updated by unpacking
- EV_UPDATED - Object data updated by changing the data structure
- EV_UPDATED_MANUAL - Object update event manually generated
- EV_UPDATE_REQ - Request to update object data One half of this is enqueueObjectUpdates (formerly processObjectUpdates in the GCS code) which response to object events by adding a transaction request into two queues (priority and regular). The other half is the method processObjectQueue which takes the first pending requesting and attempts to complete it.
Update requests and sending acked objects require a transaction with a response. These map to the same transactions at the UAVTalk level. This means if we want to support multiple outstanding transactions (e.g. to deal with lag at the FC side) this must be supported at the UAVTalk layer and the Telemetry layer. For now we only allow a single transaction to persist and if one is pending we delay any attempts for a new one. However we do allow other messages to go through that do not require a transaction.
The telemetry monitor sets up a number of object retrieval transactions to run at initial connection.