1. Introduction
This project establishes the foundational architecture for the MAVLink communication system, enabling the seamless encoding and decoding of MAVLink messages from raw data inputs.
2. Features & Functionalities
Encoding of Data: Convert raw data inputs into MAVLink formatted messages.
Buffer Storage: Store the MAVLink formatted messages into a buffer for transmission or further processing.
Decoding of MAVLink Bytestreams: Parse buffer to retrieve MAVLink message.
3. Classes & Methods
MavlinkEncoder
This class serves as the core component responsible for encoding MAVLink messages from raw data inputs contained within the IncomingData
struct. It provides functionalities for encoding different MAVLink messages and packing them into a single buffer array.
Constructor: MavlinkEncoder::MavlinkEncoder()
Purpose: Initializes the
MavlinkEncoder
object.
Method: packIntoMavlinkByteArray
Purpose: Encodes incoming data into MAVLink formatted messages and packs these messages into an output buffer.
Parameters:
IncomingData &data
: Reference to the raw data that needs to be encoded.uint8_t outputBuffer[]
: Target buffer where the MAVLink messages will be stored.size_t maxBufferSize
: Maximum allowable size of the target buffer to prevent overflow.
Return Value:
Returns the actual size of the data packed into the output buffer. Note that the output buffer provided in the parameter will be filled with the encoded MAVLink messages.
Notes:
Uses a temporary buffer (
tempBuffer
) to first store the MAVLink message before copying it to the output buffer.Checks for the initialization of various data fields (like latitude, longitude, altitude) and encodes the corresponding MAVLink message.
Does not contain an error handling like overwriting the outputBuffer.
Macro: ENCODE_MESSAGE(baseName, ...)
Overview:
The ENCODE_MESSAGE
macro stands as an integral tool within the MavlinkEncoder
class. Its role is pivotal in effortlessly packing MAVLink messages spanning a variety of types. With its parameters, this macro simplifies the task of enveloping MAVLink messages within a byte buffer and retrieving the buffer length.
Macro Parameters:
baseName (string)
Description: Symbolizes the root name of the MAVLink message being encoded.
Purpose: Helps in identifying and forming the MAVLink message's packing function name, ensuring consistency in the packing process.
... (Varargs)
Description: These represent variable arguments that correspond specifically to the MAVLink message type.
Purpose: The dynamic nature of these arguments allows for diverse field population depending on the MAVLink message type in question.
How it Works:
Upon the macro's invocation:
An anonymous lambda function is generated. This function is tailored to pack the provided arguments into a MAVLink message and translate the resultant message into a byte buffer.
Inside this lambda:
The MAVLink packing function pertaining to the
baseName
is called to pack the message.The packed message is then translated into a byte buffer, and its length is computed.
This lambda function can subsequently be used to pack MAVLink messages and fetch the length of the populated buffer.
Example Usage:
To elaborate:
ENCODE_MESSAGE(HEARTBEAT, 1, 2, 3, 4, 5, 6, 7, 8, 9)(msg, buffer);
Here, "HEARTBEAT" denotes the base name of the MAVLink message, while the integers 1 through 9 act as specific arguments for the HEARTBEAT
message. The parameters msg
and buffer
are supplied to the lambda function to store the encoded message and the buffer containing it, respectively.
Notes:
The
ENCODE_MESSAGE
macro leverages the power of lambda functions, ensuring the packing process is both encapsulated and efficient for varied MAVLink message types.The design ensures that the
MavlinkEncoder
class is equipped with a modular and robust approach to MAVLink message encoding, bolstering clarity and maintainability of the code.
MavlinkDecoder
This class acts as the principal mechanism for decoding MAVLink messages into their respective structured representations. The decoded data can then be utilized for further application-specific processing. The decoder leverages callback-based techniques, registering specific decoder functions for each MAVLink message type. When a message is detected, the appropriate decoder function is triggered.
Constructor: MavlinkDecoder::MavlinkDecoder()
Purpose: Sets up the registered decoders for the MAVLink message types, mapping each message type to its corresponding decoding function.
Method: parseBytesToMavlinkMsgs
Purpose: Iterates through a provided byte buffer, attempts to construct valid MAVLink messages, and subsequently decodes them.
Parameters:
*u_int8_t buffer: Pointer to the source buffer containing raw bytes.
std::size_t bufferSize: The size of the provided buffer, denoting how many bytes to process.
Notes:
Relies on the
mavlink_parse_char
function to recognize and create MAVLink messages.Uses the constructed MAVLink message and tries to decode it employing the registered decoder functions.
Macro: REGISTER_DECODER(msgId, baseName, postProcessor)
Overview: The REGISTER_DECODER
macro is a crucial component within the MavlinkDecoder
class. It allows for streamlined registration of decoder functions for distinct MAVLink message types. The macro, combined with its three parameters, facilitates the integration of a decoding function with a post-processing phase for handling decoded data.
Macro Parameters:
msgId (int)
Description: The unique identifier for the MAVLink message type set for decoding.
Purpose: Helps distinguish various MAVLink messages and associate them with their respective decoding functions.
baseName (string)
Description: Denotes the base name of the MAVLink message type.
Purpose: Extracted from the MAVLink message type's name by excluding the "mavlink_" prefix and the "_t" suffix. This assists in forming the decoder function name adhering to a specific naming pattern.
postProcessor (Lambda Function)
Description: A function executed after the decoding process.
Purpose: Enables further operations or processing on the decoded data. It's adaptable, letting users craft various functionalities as needed.
How it Works:
When invoking the macro, a fresh entry is appended to the
decodingFunctions
map (or an equivalent structure). ThemsgId
is used as the key, which maps to the lambda function designated to decode and then post-process the MAVLink message.Inside this lambda function:
A new message object (
msgType
) is instantiated using thebaseName
.MAVLink decoding function decodes the message.
The post-processing function (
postProcessor
) is triggered, allowing custom operations on the decoded data.
Example Usage:
To illustrate:
REGISTER_DECODER(MAVLINK_MSG_ID_ATTITUDE, attitude, [](mavlink_attitude_t &message) { // Display the message's attributes std::cout << "ATTITUDE" << std::endl; std::cout << "roll: " << message.roll << std::endl; std::cout << "pitch: " << message.pitch << std::endl; std::cout << "yaw: " << message.yaw << std::endl; std::cout << "rollspeed: " << message.rollspeed << std::endl; std::cout << "pitchspeed: " << message.pitchspeed << std::endl; });
This demonstrates the registration of the mavlink_attitude_t
type with the decoder and the subsequent display of its attributes post-decoding.
Notes:
The macro promotes clean and understandable code, thus enhancing maintainability and readability.
It encourages efficient exploitation of MAVLink decoding functions, ensuring the
MavlinkDecoder
class remains flexible and modular.
IncomingData
The IncomingData
structure represents incoming data for the drone. However, this struct is just a starting point. It's designed to hold various parameters such as latitude, longitude, velocities in different axes, altitude, and the pitch, roll, and yaw angles. A dedicated boolean flag accompanies each data point to signify if that data point has been initialized, ensuring data validity before processing.
Member Variables:
Variable Name | Data Type | Description | Initialization Flag |
---|---|---|---|
latitude | float | Latitude of the drone in degrees. | isLatitudeInitialized |
longitude | float | Longitude of the drone in degrees. | isLongitudeInitialized |
vx | float | Velocity in the X-axis (m/s). | isVxInitialized |
vy | float | Velocity in the Y-axis (m/s). | isVyInitialized |
vz | float | Velocity in the Z-axis (m/s). | isVzInitialized |
altitude | int | Altitude of the drone in meters. | isAltitudeInitialized |
pitch | float | Pitch angle of the drone in degrees. | isPitchInitialized |
roll | float | Roll angle of the drone in degrees. | isRollInitialized |
yaw | float | Yaw angle of the drone in degrees. | isYawInitialized |
Note: This structure MUST be modified as needed to align with the project's requirements (the required fields for the project). The current structure serves as a starting point.
4. Usage Example
Initialize the
IncomingData
object with data values.Use
findPackingFunction
fromMavlinkEncoder
to encode data into a buffer.Demonstrate decoding using the placeholder
MavlinkDecoder
class.
5. Testing
Manual Testing
Sample data initialized and encoding verified by observing the buffer output.
Placeholder decoding demonstrated with the sample buffer to ensure data integrity.
Unit Testing
None
6. Future Improvements
Implement error-handling for buffer overflow scenarios.
7. References
**Chat-GPT was use to help generate these docs**
Add Comment