Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

📝 1. Overview

Initially, the focus is on basic functionality: sending drone state data to the ground station at regular intervals and establishing two-way communication between TM and the ground station (Mission Planner).

🎯 2. Goals

Achieve transmission of GLOBAL_POSITION_INT & ATTITUDE MAVLink messages from the drone to the ground control station to be displayed on Mission Planner.

Thread 1 (translateToMavlinkThread)

Code Block
languagecpp
/**
 * @brief This thread is responsible for taking the bytes from the GSC.DMAReceiveBuffer and
 * converting them to Mavlink messages/triggering the callbacks associated with each mavlink
 * message.
 */
void translateToMavlinkThread()
{
    while (true)
    {
        MT.bytesToMavlinkMsg(GSC.DMAReceiveBuffer);

        vTaskDelay(pdMS_TO_TICKS(10)); // Adjust the delay as necessary
    }
}

Thread 2 (mavlinkToBytesThread)

Code Block
languagecpp
/**
 * @brief This thread is responsible for taking data from other managers and converting
 * them to mavlink bytes, then putting them into GSC.lowPriorityTransmitBuffer.
 */
void mavlinkToBytesThread()
{
    while (true)
    {
        // START: fill GSC.lowPriorityTransmitBuffer with data to transmit

        // END: fill GSC.lowPriorityTransmitBuffer with data to transmit

        vTaskDelay(pdMS_TO_TICKS(10)); // Adjust the delay as necessary
    }
}

DMA

Code Block
void GroundStationComms::sendToGroundStation(CircularBuffer &transmissionBuffer)
{
    // Send the bytes in transmissionBuffer to the ground station via RFD900
}

void GroundStationComms::receiveFromGroundStationISR()
    {

        // if GSC.DMAReceiveBuffer has enough space for the new data add it
        //otherwise discard the data


        //end of ISR
    }

Timer Based Interrupt

Code Block
languagecpp
void TimerInterrupt::registerTimerInterrupt(int timeIntervalMs, void (*function)())
{
    // execute the function every timeIntervalMs using a timer interrupt on the STM32
    function();
}

Timer Interrupt 1 (Low priority transmission)

Code Block
languagecpp
/**
 * @brief This interrupt service routine is called every 500ms. It is responsible for
 * sending non routine data to the ground station. Such as arm disarmed message status,
 * fufilling data requests from the ground station etc. This is the lowest priority data
 * in the GSC.lowPriorityTransmitBuffer.
 */
void TimerISR500ms()
{
    // transmit low priority the data via GSC.sendToGroundStation(); function
    GSC.sendToGroundStation(GSC.lowPriorityTransmitBuffer);
}

Timer Interrupt 2 (High priority transmission)

...

languagecpp

...

(Mission Planner) via RFD 900 radio. Any missing sensor data will be filled with sample data at this time.

🛠️ 3. Class Definitions

📡 GroundStationCommunication

Owner: Roni Kant

Description

Handles communication between the ground station and drone using RFD 900 or equivalent modules, utilizing circular buffers for MAVLink message management.

Properties

  • DMAReceiveBuffer: CircularBuffer - Stores incoming data.

  • lowPriorityTransmitBuffer: CircularBuffer - For low-priority data dispatch.

  • highPriorityTransmitBuffer: CircularBuffer - For high-priority routine data dispatch.

Methods

  • transmit(CircularBuffer &transmissionBuffer): Sends data to the ground station.

  • receiveFromGroundStationISR(): ISR for incoming data, discards if DMAReceiveBuffer is full.

Additional Notes

Flexible design compatible with various communication protocols and setups.

⏲️ TelemetryTask

Owner:

Description

This is essentially a wrapper for a FreeRTOS task that allows us to use a lambda function with access to the TM instance as a FreeRTOS task.

Constructor Signature

TelemetryTask(const char* taskName, int stackSize, UBaseType_t uxPriority, TelemetryManager& tm, Callback cbLambda)

Parameters

  • taskName: The RTOS task name

  • stackSize: Task stack size.

  • uxPriority: Task priority.

  • tm: Reference to telemetry manager instance.

  • cbLambda: The callback function.

Note

Callback is a type alias for std::function<void(TelemetryManager&)>

Implementation Details

🔄 MavlinkTranslator

Owner: Yarema Dzulynsky

Description

Translates MAVLink messages between byte streams and the drone/ground station.

Methods

  • bytesToMavlinkMsg(CircularBuffer &rxFromGroundByteQueue): Decodes incoming bytes to MAVLink messages.

    • rxFromGroundByteQueue: Buffer for incoming ground station bytes.

  • addMavlinkMsgToByteQueue(mavlink_message_t &msg, CircularBuffer &txToGroundByteQueue): Encodes MAVLink messages for transmission.

    • msg: The MAVLink message.

    • txToGroundByteQueue: Buffer for outgoing bytes to the ground station.

Additional Notes

Crucial for continuous and intermittent data handling via encoding and decoding.

🔗 CircularBuffer

Owner: Rahul Ramkumar

Description

Manages byte streams as MAVLink messages within TM components, using a circular queue/buffer for effective data buffering.

Properties

  • MAVLinkByte: unsigned char - Data type for queue storage, subject to change based on MAVLink byte requirements.

Methods

  • remainingMemory(): Indicates available queue bytes.

    • Returns: int - Available memory.

  • dequeue(): Retrieves the next byte from the queue.

    • Returns: MAVLinkByte - The dequeued byte.

  • enqueue(MAVLinkByte byte): Adds a byte to the queue.

    • Parameters:

      • byte: MAVLinkByte - Byte to add.

  • lastFullMessageEndIndex(): Indicates the position of the end of the last complete Mavlink message.

    • Returns: int - The index of the end bit of the last complete Mavlink message.

  • currentIndex(): Indicates the current position in the buffer.

    • Returns: int - The current index in the buffer.

Additional Notes

A fundamental class for data integrity and memory efficiency in processing or waiting for transmission. Note, that we always check if the circular buffer has space before we add anything to it. This means that if one part of the program (MT.bytesToMavlinkMsg(GSC.DMAReceiveBuffer)) is accessing the buffer while an interrupt (GroundStationComms ISR) occurs, data integrity will remain if we ensure no overiting of data. The benefits of this approach are that we do not need to use mutex locks reducing the complexity. The drawback of this approach is that if we receive data, but the buffer is full, we need to discard the data.

🚀 Main Class Definition: System Initialization and Task Management

Owner:

Flow Chart

...

Expand
titleMarkdown Mermaid Flowchart Code
Code Block

Telemetry Manager Setup
```mermaid
flowchart TB
TMConstructor("Create TelemetryManager Instance")
MTConstructor("Create MavlinkTranslator Instance")
GSCConstructor("Create GroundStationCommunication Instance")

defineCallbacks["Define routineDataTransmission Task Callback"]

GSCDefine("create 
DMAReceiveBuffer, 
lowPriorityTransmitBuffer, 
highPriorityTransmitBuffer")
End("End")





TMConstructor --> MTConstructor
TMConstructor --> GSCConstructor

MTConstructor --> defineCallbacks
GSCConstructor --> defineCallbacks

GSCConstructor --> GSCDefine
defineCallbacks --> End


```

Telemetry Manager Operation
```mermaid
flowchart TB

%% TELEMETRY MANAGER


%% Routine Data Transmission Functionality

routineDataTransmission("RTOS Task: routineDataTransmission")

ingestStateData["Ingest drone state data
and convert to Mavlink bytes"]

packHPBuffer["Pack drone state data 
(Mavlink bytes) into 
GSC.highPriorityTransmitBuffer"]

transmitStateData["Transmit GSC.highPriorityTransmitBuffer 
contents via GSC.transmit()"]

RTOSDelay["RTOS delay: 500ms"]

routineDataTransmission --> ingestStateData
ingestStateData --> packHPBuffer
packHPBuffer --> transmitStateData
transmitStateData --> RTOSDelay
RTOSDelay --> ingestStateData


%% DMA Receive Functionality


DMAInterrupt("RFD900 Interrupt: receiveInterruptServiceRoutine")
receiveData["Receive data"]
checkBufferSpace{"GSC.DMAReceiveBuffer 
enough space?"}
addDataToBuffer["Add new data to GSC.DMAReceiveBuffer"]
discardData["Discard new data"]
DMAInterruptEnd("DMA Interrupt Handler End")

DMAInterrupt --> receiveData
receiveData --> checkBufferSpace
checkBufferSpace --> |Yes| addDataToBuffer
checkBufferSpace --> |No| discardData
addDataToBuffer --> DMAInterruptEnd
discardData --> DMAInterruptEnd

%% Loop Update Functionality

loopUpdate("SM Managed: update")

translateMavlink["Translate Mavlink bytes 
(to callback actions) from 
GSC.DMAReceiveBuffer and 
trigger associated callbakcs"]

fillLowPriorityBuffer["Fill GSC.lowPriorityTransmitBuffer"]

transmitLowPriorityBuffer["Transmit GSC.lowPriorityTransmitBuffer"]

loopUpdate --> translateMavlink
translateMavlink --> fillLowPriorityBuffer
fillLowPriorityBuffer --> transmitLowPriorityBuffer
transmitLowPriorityBuffer --> |SM Managed Delay| translateMavlink
```

Instances

  • GroundStationComms GSC: Oversees ground station comms.

  • MavlinkTranslator MT: MAVLink message and byte stream translator.

🌐 Function: init

Description

Sets up timer interrupts and FreeRTOS tasks for MAVLink communication and translation.

Components

  • Timer Interrupts: Configured for 500ms and 1000ms operation intervals.

  • FreeRTOS Tasks:

    • translateToMavlinkThread: Processes GSC.DMAReceiveBuffer bytes into MAVLink messages.

    • mavlinkToBytesThread: Loads MAVLink bytes into GSC.lowPriorityTransmitBuffer.

  • Scheduler: Engages the FreeRTOS scheduler for task oversight.

🔄 Tasks and ISRs

  • translateToMavlinkThread & mavlinkToBytesThread: Converts between MAVLink messages and byte streams for drone-ground station communication.

  • TimerISR500ms & TimerISR1000ms: Ensures regular data dispatch from both GSC.lowPriorityTransmitBuffer and GSC.highPriorityTransmitBuffer.

⚙️ 5. Integration Points

Details subsystem interactions within the project and with external entities, focusing on integration mechanisms and their objectives.

PREVIOUS PAGE IGNORE:

TM Will:

  1. Drone to Ground Station Communication via RFD 900 Radio

    1. RX

      1. Receive raw MAVLink bytes from the ground station.

    2. TX

      1. Transmit raw MAVLink bytes from the ground station.

  2. Encode & Decode Raw MAVLink Data

    1. Encode

      1. Into Mavlink bytes to send to Mission Planner transmitted via RFD 900

    2. Decode

      1. Decode raw Mavlink bytes received from Mission Planner, received via RFD 900.

  3. Ingest Drone State Data (Lat, Lng, Velocity, Pitch, etc) via C++ references

    1. Should these references be passed at TM instantiation?

    2. Is there a finite list of drone state data TM will be ingesting?

    3. Sample rate?

  4. TM will communicate with other managers via [UNDEFINED COMMUNICATION MEDIUM]: Maybe for TM, this should go in M3?

    1. ROS LCM?

    2. Byte Streams?

    3. MQTT Style?

  5. TM will have an input/output testing strategy

    1. ?