Skip to content
This repository was archived by the owner on Jun 28, 2025. It is now read-only.

Commit 711c857

Browse files
Mavlink Translator (#58)
Co-authored-by: Roni Kant <[email protected]>
1 parent cfcbd14 commit 711c857

21 files changed

+905
-279
lines changed

Drivers/common/circular_buffer/src/circular_buffer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ CircularBuffer::CircularBuffer(uint8_t* buf, uint16_t size) {
88
}
99

1010
CircularBuffer::CircularBuffer(const CircularBuffer& other) {
11-
11+
buf_ = other.buf_;
12+
size_ = other.size_;
13+
readPtr_ = other.readPtr_;
14+
writePtr_ = other.writePtr_;
1215
}
1316

1417
bool CircularBuffer::peek(uint8_t& byte, uint16_t index) {

SystemManager/Inc/SystemManager.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "rcreceiver_datatypes.h"
1010
#include "independent_watchdog.h"
1111
#include "ZP_D_PWMChannel.hpp"
12+
#include "TelemetryManager.hpp"
1213

1314
#define SBUS_THRESHOLD 25
1415
#define SBUS_MIN 0
@@ -20,6 +21,9 @@ class SystemManager {
2021
SystemManager();
2122
~SystemManager();
2223

24+
/* Other managers*/
25+
TelemetryManager *telemetryManager;
26+
2327
/* Class Functions */
2428
void flyManually();
2529

SystemManager/Src/SystemManager.cpp

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,101 @@
44
//
55

66
#include "SystemManager.hpp"
7-
#include "sbus_receiver.hpp"
8-
#include "sbus_defines.h"
9-
#include "rcreceiver_datatypes.h"
7+
108
#include "drivers_config.hpp"
119
#include "independent_watchdog.h"
10+
#include "rcreceiver_datatypes.h"
11+
#include "sbus_defines.h"
12+
#include "sbus_receiver.hpp"
1213
#include "tim.h"
1314

14-
#define TIMEOUT_CYCLES 250000 // 25k = 1 sec fro testing 10/14/2023 => 250k = 10 sec
15+
#define TIMEOUT_CYCLES 250000 // 25k = 1 sec fro testing 10/14/2023 => 250k = 10 sec
1516

1617
static uint32_t DisconnectionCount = 0;
1718
float prevthrottle;
1819
float prevyaw;
1920
float prevroll;
2021
float prevpitch;
2122

22-
SystemManager::SystemManager():
23-
rcController_(sbus_pointer),
24-
throttleMotorChannel_(&htim2, TIM_CHANNEL_1),
25-
yawMotorChannel_(&htim2, TIM_CHANNEL_2),
26-
rollMotorChannel_(&htim2, TIM_CHANNEL_3),
27-
pitchMotorChannel_(&htim2, TIM_CHANNEL_4),
28-
invertedRollMotorChannel_(&htim3, TIM_CHANNEL_1),
29-
watchdog_(&hiwdg)
30-
{}
23+
SystemManager::SystemManager()
24+
: rcController_(sbus_pointer),
25+
throttleMotorChannel_(&htim2, TIM_CHANNEL_1),
26+
yawMotorChannel_(&htim2, TIM_CHANNEL_2),
27+
rollMotorChannel_(&htim2, TIM_CHANNEL_3),
28+
pitchMotorChannel_(&htim2, TIM_CHANNEL_4),
29+
invertedRollMotorChannel_(&htim3, TIM_CHANNEL_1),
30+
watchdog_(&hiwdg) {
31+
// VARIABLES FOR TELEMETRY MANAGER TO HAVE AS REFERENCES THEY OBV SHOULD BE PUT SOMEWHERE ELSE,
32+
// BUT I FEEL LIKE SM PM WOULD KNOW WHERE. MAYBE IN THE HPP FILE? IDK HOW YOU ARE PLANNING ON
33+
// GATHERING THE DATA. I JUST PUT THEM HERE FOR NOW
34+
int32_t lat = 0;
35+
int32_t lon = 0;
36+
int32_t alt = 0;
37+
int32_t relative_alt = 0;
38+
int16_t vx = 0;
39+
int16_t vy = 0;
40+
int16_t vz = 0;
41+
uint16_t hdg = 0;
42+
int32_t time_boot_ms = 0;
43+
MAV_STATE state = MAV_STATE::MAV_STATE_STANDBY;
44+
MAV_MODE_FLAG mode = MAV_MODE_FLAG::MAV_MODE_FLAG_MANUAL_INPUT_ENABLED;
45+
float roll = 0;
46+
float pitch = 0;
47+
float yaw = 0;
48+
float rollspeed = 0;
49+
float pitchspeed = 0;
50+
float yawspeed = 0;
51+
52+
this->telemetryManager =
53+
new TelemetryManager(lat, lon, alt, relative_alt, vx, vy, vz, hdg, time_boot_ms, state,
54+
mode, roll, pitch, yaw, rollspeed, pitchspeed, yawspeed);
55+
this->telemetryManager->init();
56+
// IDK WHERE SM PLANS TO DO THIS, BUT telemetryManager.update() NEEDS TO BE CALLED AT A SEMI
57+
// REGULAR INTERVAL AS IT DEALS WITH MESSAGE DECODING AND LOW PRIORITY DATA TRANSMISSION
58+
}
3159

3260
SystemManager::~SystemManager() {}
3361

3462
void SystemManager::flyManually() {
35-
for(;;){
63+
for (;;) {
3664
this->rcInputs_ = rcController_->GetRCControl();
3765

38-
//TO-DO: need to implement it using is_Data_New;
39-
// boolean is true if data has not changed since the last cycle
40-
bool is_unchanged{
41-
rcInputs_.throttle == prevthrottle &&
42-
rcInputs_.yaw == prevyaw &&
43-
rcInputs_.roll == prevroll &&
44-
rcInputs_.pitch == prevpitch
45-
};
66+
// TO-DO: need to implement it using is_Data_New;
67+
// boolean is true if data has not changed since the last cycle
68+
bool is_unchanged{rcInputs_.throttle == prevthrottle && rcInputs_.yaw == prevyaw &&
69+
rcInputs_.roll == prevroll && rcInputs_.pitch == prevpitch};
4670

4771
if (is_unchanged) {
48-
DisconnectionCount += 1; // if its not changed we increment the timeout counter
49-
if (DisconnectionCount > TIMEOUT_CYCLES) { // if timeout has occured
50-
DisconnectionCount = TIMEOUT_CYCLES+1; // avoid overflow but keep value above threshold
51-
this->rcInputs_.arm = 0; // failsafe
52-
}
72+
DisconnectionCount += 1; // if its not changed we increment the timeout counter
73+
if (DisconnectionCount > TIMEOUT_CYCLES) { // if timeout has occured
74+
DisconnectionCount =
75+
TIMEOUT_CYCLES + 1; // avoid overflow but keep value above threshold
76+
this->rcInputs_.arm = 0; // failsafe
77+
}
5378
} else {
54-
DisconnectionCount = 0; //if the data has changed we want to reset out counter
79+
DisconnectionCount = 0; // if the data has changed we want to reset out counter
5580
}
5681

57-
watchdog_.refreshWatchdog(); // always hit the dog
82+
watchdog_.refreshWatchdog(); // always hit the dog
5883

59-
if(this->rcInputs_.arm >= (SBUS_MAX/2)) {
60-
this->throttleMotorChannel_.set(rcInputs_.throttle);
61-
this->yawMotorChannel_.set(rcInputs_.yaw);
62-
this->rollMotorChannel_.set(SBUS_MAX - rcInputs_.roll);
63-
this->pitchMotorChannel_.set(SBUS_MAX - rcInputs_.pitch);
64-
this->invertedRollMotorChannel_.set(SBUS_MAX - rcInputs_.roll);
84+
if (this->rcInputs_.arm >= (SBUS_MAX / 2)) {
85+
this->throttleMotorChannel_.set(rcInputs_.throttle);
86+
this->yawMotorChannel_.set(rcInputs_.yaw);
87+
this->rollMotorChannel_.set(SBUS_MAX - rcInputs_.roll);
88+
this->pitchMotorChannel_.set(SBUS_MAX - rcInputs_.pitch);
89+
this->invertedRollMotorChannel_.set(SBUS_MAX - rcInputs_.roll);
6590

66-
prevthrottle = rcInputs_.throttle;
67-
prevyaw = rcInputs_.yaw;
68-
prevroll = rcInputs_.roll;
69-
prevpitch = rcInputs_.pitch;
91+
prevthrottle = rcInputs_.throttle;
92+
prevyaw = rcInputs_.yaw;
93+
prevroll = rcInputs_.roll;
94+
prevpitch = rcInputs_.pitch;
7095

71-
72-
}
73-
else{
96+
} else {
7497
this->throttleMotorChannel_.set(0);
75-
this->yawMotorChannel_.set(SBUS_MAX/2);
76-
this->rollMotorChannel_.set(SBUS_MAX/2);
77-
this->pitchMotorChannel_.set(SBUS_MAX/2);
78-
this->invertedRollMotorChannel_.set(SBUS_MAX/2);
98+
this->yawMotorChannel_.set(SBUS_MAX / 2);
99+
this->rollMotorChannel_.set(SBUS_MAX / 2);
100+
this->pitchMotorChannel_.set(SBUS_MAX / 2);
101+
this->invertedRollMotorChannel_.set(SBUS_MAX / 2);
79102
}
80103
}
81104
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @file MavlinkEncoder.hpp
3+
* @brief This file is responsible for decoding MAVLink messages received from the ground station.
4+
*
5+
* @note Anything future maintainers should know about this file?
6+
*
7+
* @version Milestone 2
8+
* @date 2023-08-24
9+
* @author Yarema Dzulynsky: initial structure & implementation
10+
*
11+
* @warning Any issues you think are important/foresee in the future?
12+
*/
13+
14+
#ifndef MAVLINKDECODER_H
15+
#define MAVLINKDECODER_H
16+
17+
#include <functional>
18+
// #include <iostream>
19+
// #include <unordered_map>
20+
21+
#include "Official_Mavlink_2_Library/common/mavlink.h"
22+
23+
/**
24+
* Macro for registering a decoder function for a specific message type.
25+
* @param msgId (int) - the message id of the message type to be decoded.
26+
* @param baseName (string) - the base name of the message type to be decoded. Ex. for
27+
* mavlink_attitude_t, the base name is attitude. Essentially, whatever is in between mavlink_ and
28+
* _t form the message you would like to register. The base name is used to generate the decoder
29+
* function name. Ex. for mavlink_attitude_t, the decoder function name is
30+
* mavlink_msg_attitude_decode.
31+
* @param postProcessor ([](mavlink_**baseName**_t &message)) - the post processor function to be
32+
* called after the message. This function must take in a reference to the message type that is
33+
* being decoded. You can then use this reference to access the message fields. Ex. message.roll,
34+
* message.pitch, etc. Now do what you want with them! :)
35+
* @example REGISTER_DECODER(MAVLINK_MSG_ID_ATTITUDE, attitude, [](mavlink_attitude_t &message) {
36+
* //print out the message
37+
* std::cout << "ATTITUDE" << std::endl;
38+
* std::cout << "roll: " << message.roll << std::endl;
39+
* std::cout << "pitch: " << message.pitch << std::endl;
40+
* std::cout << "yaw: " << message.yaw << std::endl;
41+
* std::cout << "rollspeed: " << message.rollspeed << std::endl;
42+
* std::cout << "pitchspeed: " << message.pitchspeed << std::endl;
43+
* };
44+
*/
45+
// #define REGISTER_DECODER(msgId, baseName, postProcessor) \
46+
// decodingFunctions[msgId] = [](mavlink_message_t &msg) { \
47+
// mavlink_##baseName##_t msgType; \
48+
// mavlink_msg_##baseName##_decode(&msg, &msgType); \
49+
// postProcessor(msgType); \
50+
// };
51+
52+
class MavlinkDecoder {
53+
public:
54+
// The number of messages that have been decoded - used for testing purposes.
55+
long messagesHandledSuccessfully = 0;
56+
57+
// std::unordered_map<int, std::function<void(mavlink_message_t &)>> decodingFunctions;
58+
/**
59+
* Default constructor.
60+
*/
61+
MavlinkDecoder();
62+
63+
/**
64+
* Default destructor.
65+
*/
66+
~MavlinkDecoder();
67+
68+
/**
69+
* Unpacks the message, triggering the respective callback set in the switch statement.
70+
* @param msg - The preformatted mavlink message, ready for decoding.
71+
*/
72+
73+
bool decodeMsg(mavlink_message_t &msg);
74+
75+
/**
76+
* Transforms a byte sequence into mavlink messages, then activates the respective callbacks.
77+
* @param buffer - Byte sequence for parsing.
78+
* @param bufferSize - Length of the byte sequence.
79+
*/
80+
void parseBytesToMavlinkMsgs(uint8_t *buffer, std::size_t bufferSize);
81+
};
82+
83+
#endif
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @file MavlinkEncoder.hpp
3+
* @brief This file is responsible for encoding MAVLink messages to send to the ground station.
4+
*
5+
* @note Anything future maintainers should know about this file?
6+
*
7+
* @version Milestone 2
8+
* @date 2023-08-24
9+
* @author Yarema Dzulynsky: initial structure & implementation
10+
*
11+
* @warning Any issues you think are important/foresee in the future?
12+
*/
13+
14+
#ifndef MAVLINKENCODER_H
15+
#define MAVLINKENCODER_H
16+
17+
#include <iostream>
18+
19+
#include "Official_Mavlink_2_Library/common/mavlink.h"
20+
#include "TMCircularBuffer.hpp"
21+
22+
/**
23+
* @brief Class dedicated to MAVLink message encoding.
24+
*
25+
* The 'MavlinkEncoder' class provides an interface and underlying functionality for MAVLink message
26+
* encoding, using associated parameters and defined message types.
27+
*/
28+
class MavlinkEncoder {
29+
public:
30+
// The message object that's currently targeted for encoding.
31+
mavlink_message_t currentMessage;
32+
33+
// Default constructor for the MavlinkEncoder class.
34+
MavlinkEncoder();
35+
36+
// Default destructor for the MavlinkEncoder class.
37+
~MavlinkEncoder();
38+
39+
/**
40+
* @brief Helper function to pack a mavlink message into a buffer.
41+
*
42+
* @param msg The mavlink message to be packed into the buffer.
43+
* @param txToGroundByteQueue The buffer to pack the message into.
44+
*/
45+
bool encodeMsgIntoBuffer(mavlink_message_t& msg, TMCircularBuffer& txToGroundByteQueue);
46+
};
47+
48+
#endif

TelemetryManager/Inc/MavlinkTranslator.hpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
/**
22
* @file MavlinkTranslator.hpp
3-
* @brief What does this file do?
3+
* @brief This file is responsible for decoding/encoding MAVLink messages received_from/sent_to the ground station.
44
*
55
* @note Anything future maintainers should know about this file?
66
*
7-
* @version 1.0
7+
* @version Milestone 2
88
* @date 2023-08-24
99
* @author Yarema Dzulynsky: initial structure & implementation
1010
*
1111
* @warning Any issues you think are important/foresee in the future?
1212
*/
1313

14-
#include "TMCircularBuffer.hpp"
14+
#include "MavlinkDecoder.hpp"
15+
#include "MavlinkEncoder.hpp"
1516
#include "Official_Mavlink_2_Library/common/mavlink.h"
17+
#include "TMCircularBuffer.hpp"
1618
#ifndef MAVLINKTRANSLATOR_H
1719
#define MAVLINKTRANSLATOR_H
1820

1921
class MavlinkTranslator {
20-
public:
22+
public:
23+
// The decoder and encoder objects.
24+
MavlinkDecoder decoder;
25+
MavlinkEncoder encoder;
26+
// The number of messages that have been decoded - used for testing purposes.
27+
long decodedMessages = 0;
2128
/**
2229
* @brief Construct a new MavlinkTranslator object. Do whatever needs to be done here.
2330
*
@@ -47,8 +54,7 @@ class MavlinkTranslator {
4754
* @param txToGroundByteQueue The CircularBuffer containing the bytes to be sent to the ground
4855
* station.
4956
*/
50-
void addMavlinkMsgToByteQueue(mavlink_message_t &msg,
51-
TMCircularBuffer &txToGroundByteQueue);
57+
void addMavlinkMsgToByteQueue(mavlink_message_t &msg, TMCircularBuffer &txToGroundByteQueue);
5258
};
5359

5460
#endif // MAVLINKTRANSLATOR_H

0 commit comments

Comments
 (0)