TinyRobotics
Loading...
Searching...
No Matches
MavlinkMessageSource.h
1#pragma once
2#include <SimpleMavlinkDrone.h> // https://github.com/pschatzmann/ArduinoMavlinkDrone
4#include "TinyRobotics/utils/Common.h"
5
6namespace tinyrobotics {
7
8/**
9 * @class MavlinkMessageSource
10 * @ingroup communication
11 * @brief Message source for MAVLink integration using ArduinoMavlinkDrone.
12 *
13 * @note This class depends on the ArduinoMavlinkDrone library:
14 * https://github.com/pschatzmann/ArduinoMavlinkDrone
15 *
16 * This class connects to a MAVLink drone and translates MAVLink telemetry and
17 * control messages into TinyRobotics Message objects. It can be used to bridge
18 * MAVLink-based vehicles with the TinyRobotics message bus and control
19 * framework.
20 *
21 * Usage:
22 * MavlinkMessageSource mavlink(drone);
23 * mavlink.begin();
24 * // In loop: mavlink.update();
25 *
26 */
28public:
29 MavlinkMessageSource(SimpleMavlinkDrone& drone,
30 ControlScenario scenario = ControlScenario::Car)
31 : drone(drone), scenario(scenario) {}
32
33 /// Start the message source
34
35 bool begin(ControlScenario scenario = ControlScenario::Car) {
36 this->scenario = scenario;
37 is_active_ = true;
38 return true;
39 }
40
41 /// Stop the message source
42 void end() { is_active_ = false; }
43
44 /// Call this in your main loop to handle MAVLink messages
45 void update() {
46 if (!is_active_) return;
47 drone.loop();
48 if (drone.isArmed()) {
49 publishScenario();
50 }
51 }
52
53 /// @brief Defines the max steering ange in degrees: default 45
54 /// @param angleDeg
55 void setMaxSteeringAngle(float angleDeg) {
56 max_steering_deg = angleDeg;
57 }
58
59 protected:
60 SimpleMavlinkDrone& drone;
61 ControlScenario scenario;
62 bool is_active_ = false;
63 float max_steering_deg = 45.0f;
64
65 void publishScenario() {
66 switch (scenario) {
67 case ControlScenario::Car:
68 publishCar();
69 break;
70 case ControlScenario::Boat:
71 publishBoat();
72 break;
73 case ControlScenario::Drone:
74 publishDrone();
75 break;
76 case ControlScenario::Plane:
77 publishPlane();
78 break;
79 }
80 }
81
82 void publishCar() {
83 // Car: SteeringAngle (YAW), Throttle
84 float steeringAngle = -drone.getValue(YAW) * max_steering_deg / 100.0f;
85 steeringAngle = normalizeAngleDeg(steeringAngle);
86 float throttle = drone.getValue(THROTTLE) * 100.0f; // 0..1 to percent
87 publish(Message(MessageContent::SteeringAngle, steeringAngle, Unit::AngleDegree));
88 publish(Message(MessageContent::Throttle, throttle, Unit::Percent));
89 }
90
91 void publishBoat() {
92 // Boat: SteeringAngle (YAW), Throttle
93 float steeringAngle = -drone.getValue(YAW) * max_steering_deg / 100.0f;
94 steeringAngle = normalizeAngleDeg(steeringAngle);
95 float throttle = drone.getValue(THROTTLE) * 100.0f; // 0..1 to percent
96 publish(Message(MessageContent::SteeringAngle, steeringAngle, Unit::AngleDegree));
97 publish(Message(MessageContent::Throttle, throttle, Unit::Percent));
98 }
99
100 void publishDrone() {
101 // Drone: Roll, Pitch, Throttle, Yaw
102 float roll = drone.getValue(ROLL);
103 float pitch = drone.getValue(PITCH);
104 float throttle = drone.getValue(THROTTLE) * 100.0f;
105 float yaw = -drone.getValue(YAW); // Convert to ROS: positive is right
106 publish(Message(MessageContent::Roll, roll, Unit::Percent));
107 publish(Message(MessageContent::Pitch, pitch, Unit::Percent));
108 publish(Message(MessageContent::Throttle, throttle, Unit::Percent));
109 publish(Message(MessageContent::Yaw, yaw, Unit::Percent));
110 }
111
112 void publishPlane() {
113 // Plane: Roll (Aileron), Pitch (Elevator), Throttle, Yaw (Rudder)
114 float aileron = drone.getValue(ROLL);
115 float elevator = drone.getValue(PITCH);
116 float throttle = drone.getValue(THROTTLE) * 100.0f;
117 float rudder = -drone.getValue(YAW); // Convert to ROS: positive is right
118 publish(Message(MessageContent::Roll, aileron, Unit::Percent));
119 publish(Message(MessageContent::Pitch, elevator, Unit::Percent));
120 publish(Message(MessageContent::Throttle, throttle, Unit::Percent));
121 publish(Message(MessageContent::Yaw, rudder, Unit::Percent));
122 }
123
124 // Overload for publishing Message<float>
125 void publish(const Message<float>& msg) {
126 Message<float> m = msg;
127 sendMessage(m);
128 }
129
130 // Helper for float mapping (Arduino's map only works for long)
131 static float mapFloat(float x, float in_min, float in_max, float out_min,
132 float out_max) {
133 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
134 }
135};
136
137} // namespace tinyrobotics
Message source for MAVLink integration using ArduinoMavlinkDrone.
Definition: MavlinkMessageSource.h:27
void setMaxSteeringAngle(float angleDeg)
Defines the max steering ange in degrees: default 45.
Definition: MavlinkMessageSource.h:55
bool begin(ControlScenario scenario=ControlScenario::Car)
Start the message source.
Definition: MavlinkMessageSource.h:35
void end()
Stop the message source.
Definition: MavlinkMessageSource.h:42
void update()
Call this in your main loop to handle MAVLink messages.
Definition: MavlinkMessageSource.h:45
Base class for message sources in the TinyRobotics communication framework.
Definition: MessageSource.h:35
ControlScenario
Control scenario types for remote control vehicles.
Definition: Common.h:68
Unit
Units for message values.
Definition: Common.h:45
@ AngleDegree
Angle in degrees.
@ Percent
Percentage (0-100)
Generic message structure for communication, parameterized by value type.
Definition: Message.h:72