TinyRobotics
Loading...
Searching...
No Matches
AirplaneOdometryModel3D.h
1#include "TinyRobotics/communication/Message.h"
2#pragma once
3#include "TinyRobotics/communication/MessageHandler.h"
4#include "TinyRobotics/odometry/IOdometryModel3D.h"
5#include "TinyRobotics/units/Units.h"
6
7namespace tinyrobotics {
8
9/**
10 * @class AirplaneOdometryModel3D
11 * @ingroup odometry
12 * @brief IOdometryModel3D implementation for fixed-wing airplanes using control
13 * surface and throttle inputs.
14 *
15 * This model computes linear and angular velocities for a fixed-wing airplane
16 * based on control inputs:
17 * - Throttle (0..100%): Sets forward speed as a percentage of maxSpeed.
18 * - Aileron (degrees, typically -45..45): Sets roll rate as a fraction of
19 * maxRollRate.
20 * - Elevator (degrees, typically -45..45): Sets pitch rate as a fraction of
21 * maxPitchRate.
22 * - Rudder (degrees, typically -45..45): Sets yaw rate as a fraction of
23 * maxYawRate.
24 *
25 * ## Features
26 * - Maps control surface deflections and throttle to body-frame velocities for
27 * odometry integration.
28 * - Supports message-driven control via onMessage() (handles
29 * MessageContent::Throttle, ::Roll, ::Pitch, ::Yaw).
30 * - All input values are clamped to safe ranges.
31 * - Suitable for simulation, estimation, or as a reference model for real-time
32 * control.
33 *
34 * ## Usage Example
35 * @code
36 * AirplaneOdometryModel3D model;
37 * model.setThrottle(80); // 80% throttle
38 * model.setAileron(10); // 10 degrees right aileron
39 * model.setElevator(-5); // 5 degrees down elevator
40 * model.setRudder(0); // Centered rudder
41 * float vx, vy, vz, wx, wy, wz;
42 * model.getLinearVelocity(vx, vy, vz);
43 * model.getAngularVelocity(wx, wy, wz);
44 * // vx will be 0.8 * maxSpeed, wx will be 10/45 * maxRollRate, etc.
45 * @endcode
46 *
47 * ## Message Integration
48 * The model can be updated from messages (e.g., from an RC receiver or
49 * autopilot):
50 * @code
51 * Message<float> msg;
52 * msg.content = MessageContent::Throttle;
53 * msg.value = 75;
54 * model.onMessage(msg); // Sets throttle to 75%
55 * @endcode
56 */
58 public:
59
60 /**
61 * @brief Register a callback to be invoked on relevant events (e.g., input change).
62 */
63 void registerCallback(void (*callback)(void*), void* userData) override {
64 this->callback = callback;
65 this->userData = userData;
66 }
67
68 /**
69 * @brief Construct an AirplaneOdometryModel3D with configurable max rates.
70 *
71 * @param maxSpeed Maximum forward speed (m/s). Typical: 20–40 m/s for small UAVs.
72 * @param maxRollRate Maximum roll rate (deg/s). Typical: 40–85 deg/s (converted to rad/s internally).
73 * @param maxPitchRate Maximum pitch rate (deg/s). Typical: 30–60 deg/s (converted to rad/s internally).
74 * @param maxYawRate Maximum yaw rate (deg/s). Typical: 17–40 deg/s (converted to rad/s internally).
75 *
76 * These values should be set to match the physical or simulated aircraft's limits.
77 * For most fixed-wing RC airplanes:
78 * - maxSpeed: 25–35 m/s (90–125 km/h)
79 * - maxRollRate: 57 deg/s
80 * - maxPitchRate: 40 deg/s
81 * - maxYawRate: 29 deg/s
82 *
83 * Note: The constructor will convert the rates from deg/s to rad/s for internal use.
84 * Example:
85 * AirplaneOdometryModel3D(30.0f, 57.0f, 40.0f, 29.0f); // 30 m/s, 57°/s, 40°/s, 29°/s
86 */
87 AirplaneOdometryModel3D(float maxSpeed = 30.0f, float maxRollRate = 57.0f,
88 float maxPitchRate = 40.0f, float maxYawRate = 29.0f)
89 : throttlePercent(0),
90 aileronDeg(0),
91 elevatorDeg(0),
92 rudderDeg(0),
93 maxSpeed(maxSpeed),
94 maxRollRate(maxRollRate * 0.01745329252f),
95 maxPitchRate(maxPitchRate * 0.01745329252f),
96 maxYawRate(maxYawRate * 0.01745329252f) {}
97
98 /**
99 * @brief Handle incoming control messages to set airplane control surfaces
100 * and throttle. Supports MessageContent::Throttle, ::Roll, ::Pitch, ::Yaw
101 * (float values).
102 * @return true if message was handled
103 */
104 bool onMessage(const Message<float>& msg) {
105 switch (msg.content) {
106 case MessageContent::Throttle:
107 setThrottle(msg.value);
108 return true;
109 case MessageContent::Roll: // aileron
110 setAileron(msg.value);
111 return true;
112 case MessageContent::Pitch: // elevator
113 setElevator(msg.value);
114 return true;
115 case MessageContent::Yaw: // rudder
116 setRudder(msg.value);
117 return true;
118 default:
119 return false;
120 }
121 }
122
123 // Control input setters
124 // Throttle: 0..100 (%)
125 void setThrottle(float percent) {
126 throttlePercent = clamp(percent, 0.0f, 100.0f);
127 if (callback) callback(userData);
128 }
129 // Control surfaces: degrees (typically -30..30)
130 void setAileron(float deg) {
131 aileronDeg = clamp(deg, -45.0f, 45.0f);
132 if (callback) callback(userData);
133 }
134 void setElevator(float deg) {
135 elevatorDeg = clamp(deg, -45.0f, 45.0f);
136 if (callback) callback(userData);
137 }
138 void setRudder(float deg) {
139 rudderDeg = clamp(deg, -45.0f, 45.0f);
140 if (callback) callback(userData);
141 }
142
143 void getLinearVelocity(float& vx, float& vy, float& vz) const override {
144 // Forward speed proportional to throttle percent (0..100)
145 vx = (throttlePercent / 100.0f) * maxSpeed;
146 vy = 0.0f;
147 vz = 0.0f;
148 }
149
150 void getAngularVelocity(float& wx, float& wy, float& wz) const override {
151 // Control surfaces in degrees, convert to radians for rates
152 constexpr float deg2rad = 0.01745329252f;
153 wx = (aileronDeg / 45.0f) * maxRollRate; // normalized to max deflection
154 wy = (elevatorDeg / 45.0f) * maxPitchRate;
155 wz = (rudderDeg / 45.0f) * maxYawRate;
156 // Optionally, scale by actual deflection in radians if desired:
157 // wx = aileronDeg * deg2rad * rollRatePerRad;
158 // ...
159 }
160
161 protected:
162 void (*callback)(void*) = nullptr;
163 void* userData = nullptr;
164 float throttlePercent; // 0..100
165 float aileronDeg; // degrees
166 float elevatorDeg; // degrees
167 float rudderDeg; // degrees
168 float maxSpeed; // m/s
169 float maxRollRate; // rad/s
170 float maxPitchRate; // rad/s
171 float maxYawRate; // rad/s
172
173 static float clamp(float v, float min, float max) {
174 return (v < min) ? min : (v > max) ? max : v;
175 }
176};
177
178} // namespace tinyrobotics
IOdometryModel3D implementation for fixed-wing airplanes using control surface and throttle inputs.
Definition: AirplaneOdometryModel3D.h:57
void registerCallback(void(*callback)(void *), void *userData) override
Register a callback to be invoked on relevant events (e.g., input change).
Definition: AirplaneOdometryModel3D.h:63
bool onMessage(const Message< float > &msg)
Handle incoming control messages to set airplane control surfaces and throttle. Supports MessageConte...
Definition: AirplaneOdometryModel3D.h:104
void getAngularVelocity(float &wx, float &wy, float &wz) const override
Get the current angular velocity (wx, wy, wz) in rad/s (robot frame).
Definition: AirplaneOdometryModel3D.h:150
AirplaneOdometryModel3D(float maxSpeed=30.0f, float maxRollRate=57.0f, float maxPitchRate=40.0f, float maxYawRate=29.0f)
Construct an AirplaneOdometryModel3D with configurable max rates.
Definition: AirplaneOdometryModel3D.h:87
void getLinearVelocity(float &vx, float &vy, float &vz) const override
Get the current linear velocity (vx, vy, vz) in m/s (robot frame).
Definition: AirplaneOdometryModel3D.h:143
Abstract interface for 3D odometry models. Provides access to current linear and angular velocities f...
Definition: IOdometryModel3D.h:14
Generic message structure for communication, parameterized by value type.
Definition: Message.h:72