STM32-Jetson-Ground Communication Architecture
Goals
Read POGI data from STM32 to Jetson for use by the CV system
Send PIGO data from Jetson to STM32 for use by autopilot
Read ground data from STM32 to send to ground
Send data from ground to STM32
Principles
Flexible data scheme at the interface layer, schema is defined at the FltConnRecieve/FltConnSend modules.
Communication protocol is implemented at the interface layer, therefore any logic that can change depending on the protocol used should be isolated at the interface. Note, the Endpoint concept is shared between a USB implementation (using a strict endpoint) and the UART implementation (just a serial port).
Interface Logic
All the interface logic will be isolated in a class called USBInterface/UARTInterface. The class is described below.
USBInterface/UARTInterface |
---|
+read(endpointId): Issues a read command in either serial (UART) or pyusb (USB). EndpointId can be the specific serial port to use or the usb endpoint to be used. +write(endpointId, data): Issues a write command in either serial or pyusb. Data parameter should be a buffer. +create_endpoint_FC(): Returns a new endpoint, either a Serial object (UART) or Endpoint object (USB), that points to our flightcontroller. |
-endpoints: Dictionary {endpointId: endpoint object (Serial object or Endpoint object)}. The first one is populated by calling the create_endpoint_FC() function in the constructor. |
A similar version of this will be used for the XBee Interface. This will not use the CommsInterface base class.
XBee Interface |
---|
+read_callback(): Sets up a callback that is executed when a message is recieved. self.function_dict is a dictionary of functions which are called when a message is receieved. When you get a message, decode it then call self.functionDict[device_id](data). +write(deviceId, data): Issues a send command to that device_id +create_device(read_function, device_port): This function should perform steps 2-3 from the tutorial, then call use add_data_recieved_callback, like in this tutorial to register read_callback as the callback function, then store the created xbee device in a dictionary with the ID as the key, {0: device, …}. Then it should set self.functionDict[device_id] = read_function. Return ID. |
-device_dict: Dictionary {device_id: device object}. The first one is populated by calling the create_endpoint in the constructor. -function_dict: Dictionary{device_id: function}, a dictionary of functions that the read callback can call once it receives a message, mapped by device_id. The default will just be {'main': main_read(…)} where main_read is whatever function is used in the GroundConnRecieve module. |
Schema
To ensure ease of communication, we’ll define a specific schema for messages being sent out from the jetson as a request and messages being received by the jetson as a response. Therefore, any call to FltConnSend or GroundSend or FltConnReceive or FltConnSend will follow this schema.
Request/Response Schema (General):
{
"type": “QR_COORDINATES” | “QR_INFO”| “TARGET_COORDINATES” | "STATE_INFO", // Limited to a specific list of types
"data": {...} // Dictionary whose schema depends on request type
}
Valid Types:
Request: “QR_COORDINATES”, “QR_INFO”, “TARGET_COORDINATES”
Response: “STATE_INFO”
Schemas by type
Schema for QR_COORDINATES, TARGET_COORDINATES and STATE_INFO are based off encodings with flight controller found here. Schema for QR_Info is also defined in CONOPS for 2021-2022.
// QR_COORDINATES and TARGET_COORDINATES
{
lattitude: double,
longtitude: double
}
// QR_INFO
{
info: string, // Encompasses the second line of the QR scan result
date: string,
time: string,
device_id: string,
sensor_id: string
}
//STATE_INFO
{
lattitude: double,
longtitude: double,
altitude: double,
yaw: double,
pitch: double,
roll: double
}
Reference
PyUSB implementation overview (see here for what the Endpoint object is etc.)
https://pyserial.readthedocs.io/en/latest/pyserial.html#overview