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