QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
PX4SimpleFlightModesController.cc
Go to the documentation of this file.
2#include "Fact.h"
3#include "Vehicle.h"
4#include "ParameterManager.h"
5
7 : _activeFlightMode(0)
8
9{
10 QStringList usedParams;
11 usedParams << QStringLiteral("COM_FLTMODE1") << QStringLiteral("COM_FLTMODE2") << QStringLiteral("COM_FLTMODE3")
12 << QStringLiteral("COM_FLTMODE4") << QStringLiteral("COM_FLTMODE5") << QStringLiteral("COM_FLTMODE6")
13 << QStringLiteral("RC_MAP_FLTMODE");
15 return;
16 }
17
18 connect(_vehicle, &Vehicle::rcChannelsChanged, this, &PX4SimpleFlightModesController::channelValuesChanged);
19}
20
22void PX4SimpleFlightModesController::channelValuesChanged(QVector<int> pwmValues)
23{
24 int channelCount = pwmValues.size();
25
26 _rcChannelValues.clear();
27 for (int i=0; i<channelCount; i++) {
28 _rcChannelValues.append(pwmValues[i]);
29 }
31
32 if (channelCount != _channelCount) {
33 _channelCount = channelCount;
35 }
36
37 Fact* pFact = getParameterFact(-1, "RC_MAP_FLTMODE");
38 if(!pFact) {
39#if defined _MSC_VER
40 qCritical() << "RC_MAP_FLTMODE Fact is NULL in" << __FILE__ << __LINE__;
41#else
42 qCritical() << "RC_MAP_FLTMODE Fact is NULL in" << __func__ << __FILE__ << __LINE__;
43#endif
44 return;
45 }
46
47 int flightModeChannel = pFact->rawValue().toInt() - 1;
48 if (flightModeChannel == -1) {
49 // Flight mode channel not set, can't track active flight mode
50 _activeFlightMode = 0;
51 emit activeFlightModeChanged(_activeFlightMode);
52 return;
53 }
54
55 pFact = getParameterFact(-1, QString("RC%1_REV").arg(flightModeChannel + 1));
56 if(!pFact) {
57#if defined _MSC_VER
58 qCritical() << QString("RC%1_REV").arg(flightModeChannel + 1) << "Fact is NULL in" << __FILE__ << __LINE__;
59#else
60 qCritical() << QString("RC%1_REV").arg(flightModeChannel + 1) << " Fact is NULL in" << __func__ << __FILE__ << __LINE__;
61#endif
62 return;
63 }
64
65 int pwmRev = pFact->rawValue().toInt();
66
67 pFact = getParameterFact(-1, QString("RC%1_MIN").arg(flightModeChannel + 1));
68 if(!pFact) {
69#if defined _MSC_VER
70 qCritical() << QString("RC%1_MIN").arg(flightModeChannel + 1) << "Fact is NULL in" << __FILE__ << __LINE__;
71#else
72 qCritical() << QString("RC%1_MIN").arg(flightModeChannel + 1) << " Fact is NULL in" << __func__ << __FILE__ << __LINE__;
73#endif
74 return;
75 }
76
77 int pwmMin = pFact->rawValue().toInt();
78
79 pFact = getParameterFact(-1, QString("RC%1_MAX").arg(flightModeChannel + 1));
80 if(!pFact) {
81#if defined _MSC_VER
82 qCritical() << QString("RC%1_MAX").arg(flightModeChannel + 1) << "Fact is NULL in" << __FILE__ << __LINE__;
83#else
84 qCritical() << QString("RC%1_MAX").arg(flightModeChannel + 1) << " Fact is NULL in" << __func__ << __FILE__ << __LINE__;
85#endif
86 return;
87 }
88
89 int pwmMax = pFact->rawValue().toInt();
90
91 pFact = getParameterFact(-1, QString("RC%1_TRIM").arg(flightModeChannel + 1));
92 if(!pFact) {
93#if defined _MSC_VER
94 qCritical() << QString("RC%1_TRIM").arg(flightModeChannel + 1) << "Fact is NULL in" << __FILE__ << __LINE__;
95#else
96 qCritical() << QString("RC%1_TRIM").arg(flightModeChannel + 1) << " Fact is NULL in" << __func__ << __FILE__ << __LINE__;
97#endif
98 return;
99 }
100
101 int pwmTrim = pFact->rawValue().toInt();
102
103 if (flightModeChannel < 0 || flightModeChannel > channelCount) {
104 return;
105 }
106
107 _activeFlightMode = 0;
108 int channelValue = pwmValues[flightModeChannel];
109
110 if (channelValue != -1) {
111 /* the half width of the range of a slot is the total range
112 * divided by the number of slots, again divided by two
113 */
114
115 const unsigned num_slots = 6;
116
117 const float slot_width_half = 2.0f / num_slots / 2.0f;
118
119 /* min is -1, max is +1, range is 2. We offset below min and max */
120 const float slot_min = -1.0f - 0.05f;
121 const float slot_max = 1.0f + 0.05f;
122
123 /* the slot gets mapped by first normalizing into a 0..1 interval using min
124 * and max. Then the right slot is obtained by multiplying with the number of
125 * slots. And finally we add half a slot width to ensure that integer rounding
126 * will take us to the correct final index.
127 */
128
129 float calibrated_value;
130
131 if (channelValue > pwmTrim) {
132 calibrated_value = (channelValue - pwmTrim) / (float)(pwmMax - pwmTrim);
133
134 } else if (channelValue < pwmTrim) {
135 calibrated_value = (channelValue - pwmTrim) / (float)(pwmTrim - pwmMin);
136
137 } else {
138 /* at the trim position, output zero */
139 calibrated_value = 0.0f;
140 }
141
142 calibrated_value *= pwmRev;
143
144 _activeFlightMode = (((((calibrated_value - slot_min) * num_slots) + slot_width_half) /
145 (slot_max - slot_min)) + (1.0f / num_slots));
146
147 if (_activeFlightMode >= static_cast<int>(num_slots)) {
148 _activeFlightMode = num_slots - 1;
149 }
150
151 // move to 1-based index
152 _activeFlightMode++;
153 }
154
155 emit activeFlightModeChanged(_activeFlightMode);
156}
bool _allParametersExists(int componentId, const QStringList &names) const
A Fact is used to hold a single value within the system.
Definition Fact.h:19
int activeFlightMode READ activeFlightMode NOTIFY activeFlightModeChanged(int channelCount MEMBER _channelCount NOTIFY channelCountChanged) 1(QVariantList rcChannelValues MEMBER _rcChannelValues NOTIFY rcChannelValuesChanged) int activeFlightMode(void) const
static constexpr int defaultComponentId
void rcChannelsChanged(QVector< int > channelValues)