QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
StandardModes.cc
Go to the documentation of this file.
1#include "StandardModes.h"
2
3#include <algorithm>
4
5#include "MAVLinkLib.h"
7#include "QGCMAVLink.h"
8#include "Vehicle.h"
9
10QGC_LOGGING_CATEGORY(StandardModesLog, "Vehicle.StandardModes")
11
12static void requestMessageResultHandler(void *resultHandlerData, MAV_RESULT result,
13 VehicleTypes::RequestMessageResultHandlerFailureCode_t failureCode,
14 const mavlink_message_t &message)
15{
16 StandardModes* standardModes = static_cast<StandardModes*>(resultHandlerData);
17 standardModes->gotMessage(result, failureCode, message);
18}
19
20StandardModes::StandardModes(QObject *parent, Vehicle *vehicle)
21 : QObject(parent), _vehicle(vehicle)
22{
23}
24
26{
27 _requestActive = false;
28 if (_wantReset) {
29 _wantReset = false;
30 request();
31 return;
32 }
33
34 if (result == MAV_RESULT_ACCEPTED) {
35 mavlink_available_modes_t availableModes;
36 mavlink_msg_available_modes_decode(&message, &availableModes);
37 bool cannotBeSet = availableModes.properties & MAV_MODE_PROPERTY_NOT_USER_SELECTABLE;
38 bool advanced = availableModes.properties & MAV_MODE_PROPERTY_ADVANCED;
39 availableModes.mode_name[sizeof(availableModes.mode_name)-1] = '\0';
40 QString name = availableModes.mode_name;
41 switch (availableModes.standard_mode) {
42 case MAV_STANDARD_MODE_POSITION_HOLD:
43 name = "Position";
44 break;
45 case MAV_STANDARD_MODE_ORBIT:
46 name = "Orbit";
47 cannotBeSet = true; // These are exposed in the UI as separate buttons
48 break;
49 case MAV_STANDARD_MODE_CRUISE:
50 name = "Cruise";
51 break;
52 case MAV_STANDARD_MODE_ALTITUDE_HOLD:
53 name = "Altitude";
54 break;
55 case MAV_STANDARD_MODE_SAFE_RECOVERY:
56 name = "Safe Recovery";
57 break;
58 case MAV_STANDARD_MODE_MISSION:
59 name = "Mission";
60 break;
61 case MAV_STANDARD_MODE_LAND:
62 name = "Land";
63 break;
64 case MAV_STANDARD_MODE_TAKEOFF:
65 name = "Takeoff";
66 break;
67 }
68
69 qCDebug(StandardModesLog) << "Available mode received - name:" << name <<
70 "index:" << availableModes.mode_index <<
71 "standard_mode:" << availableModes.standard_mode <<
72 "advanced:" << advanced <<
73 "cannotBeSet:" << cannotBeSet <<
74 "custom_mode:" << availableModes.custom_mode;
75
76 const auto existingMode =
77 std::find_if(_modeList.cbegin(), _modeList.cend(), [&availableModes](const FirmwareFlightMode& mode) {
78 return mode.custom_mode == availableModes.custom_mode;
79 });
80 if (existingMode == _modeList.cend()) {
81 _modeList += FirmwareFlightMode{
82 name, availableModes.standard_mode, availableModes.custom_mode, !cannotBeSet, advanced,
83 true, // fixed wing - Since we don't know at this point we assume fixed wing support
84 true // multi-rotor - Since we don't know at this point we assume multi-rotor support as well
85 };
86 } else if (existingMode->mode_name == name) {
87 qCDebug(StandardModesLog) << "Ignoring duplicate mode - name:" << name
88 << "custom_mode:" << availableModes.custom_mode;
89 } else {
90 qCWarning(StandardModesLog) << "Ignoring mode with conflicting name - custom_mode:"
91 << availableModes.custom_mode << "existing:" << existingMode->mode_name
92 << "new:" << name;
93 }
94
95 if (availableModes.mode_index >= availableModes.number_modes) { // We are done
96 qCDebug(StandardModesLog) << "Completed, num modes:" << availableModes.number_modes;
97 ensureUniqueModeNames();
98 _vehicle->firmwarePlugin()->updateAvailableFlightModes(_modeList);
99 emit modesUpdated();
100 emit requestCompleted();
101 } else {
102 requestMode(availableModes.mode_index + 1);
103 }
104 } else {
105 qCWarning(StandardModesLog) << "Failed to retrieve available modes - REQUEST_MESSAGE:MAV_RESULT" << QGCMAVLink::mavResultToString(result) << "failureCode:" << failureCode;
106 emit requestCompleted();
107 }
108}
109
110void StandardModes::ensureUniqueModeNames()
111{
112 // Ensure mode names are unique. This should generally already be the case, but e.g. during development when
113 // restarting dynamic modes, it might not be.
114 for (auto iter = _modeList.begin(); iter != _modeList.end(); ++iter) {
115 int duplicateIdx = 0;
116 for (auto iter2 = std::next(iter); iter2 != _modeList.end(); ++iter2) {
117 if ((*iter).mode_name == (*iter2).mode_name) {
118 (*iter2).mode_name += QStringLiteral(" (%1)").arg(duplicateIdx + 1);
119 ++duplicateIdx;
120 }
121 }
122 }
123}
124
126{
127 if (_requestActive) {
128 // If we are in the middle of waiting for a request, wait for the response first
129 _wantReset = true;
130 return;
131 }
132
133 qCDebug(StandardModesLog) << "Requesting available modes";
134 // Request one at a time. This could be improved by requesting all, but we can't use Vehicle::requestMessage for that
135 _modeList.clear();
136 StandardModes::requestMode(1);
137}
138
139void StandardModes::requestMode(int modeIndex)
140{
141 _requestActive = true;
142 _vehicle->requestMessage(
144 this,
145 MAV_COMP_ID_AUTOPILOT1,
146 MAVLINK_MSG_ID_AVAILABLE_MODES, modeIndex);
147}
148
150{
151 if (_lastSeq != seq) {
152 qCDebug(StandardModesLog) << "Available modes changed, re-requesting";
153 _lastSeq = seq;
154 request();
155 }
156}
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static void requestMessageResultHandler(void *resultHandlerData, MAV_RESULT result, VehicleTypes::RequestMessageResultHandlerFailureCode_t failureCode, const mavlink_message_t &message)
virtual void updateAvailableFlightModes(FlightModeList &flightModeList)
Update Available flight modes received from vehicle.
void modesUpdated()
void gotMessage(MAV_RESULT result, VehicleTypes::RequestMessageResultHandlerFailureCode_t failureCode, const mavlink_message_t &message)
StandardModes(QObject *parent, Vehicle *vehicle)
void requestCompleted()
void availableModesMonitorReceived(uint8_t seq)
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
Definition Vehicle.h:462
void requestMessage(RequestMessageResultHandler resultHandler, void *resultHandlerData, int compId, int messageId, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f)
Definition Vehicle.cc:2282
RequestMessageResultHandlerFailureCode_t