86#include <QtCore/QDateTime>
90#define UPDATE_TIMER 50
91#define DEFAULT_LAT 38.965767f
92#define DEFAULT_LON -120.083923f
96#define REQUEST_OPERATOR_CONTROL_ALLOW_TAKEOVER_TIMEOUT_MSECS 10000
103 int defaultComponentId,
104 MAV_AUTOPILOT firmwareType,
105 MAV_TYPE vehicleType,
108 , _systemID (vehicleId)
109 , _defaultComponentId (defaultComponentId)
110 , _firmwareType (firmwareType)
111 , _vehicleType (vehicleType)
112 , _defaultCruiseSpeed (
SettingsManager::instance()->appSettings()->offlineEditingCruiseSpeed()->rawValue().toDouble())
113 , _defaultHoverSpeed (
SettingsManager::instance()->appSettings()->offlineEditingHoverSpeed()->rawValue().toDouble())
117 , _orbitMapCircle (std::make_unique<
QGCMapCircle>(this))
118 , _mavlinkStreamConfig (std::make_unique<
MAVLinkStreamConfig>(std::bind(&
Vehicle::_setMessageInterval, this, std::placeholders::_1, std::placeholders::_2)))
119 , _vehicleFactGroup (this)
146 _autopilotPlugin->setParent(
this);
149 connect(&_prearmErrorTimer, &QTimer::timeout,
this, &Vehicle::_prearmErrorTimeout);
150 _prearmErrorTimer.setInterval(_prearmErrorTimeoutMSecs);
151 _prearmErrorTimer.setSingleShot(
true);
166 _sendMultipleTimer.start(_sendMessageMultipleIntraMessageDelay);
167 connect(&_sendMultipleTimer, &QTimer::timeout,
this, &Vehicle::_sendMessageMultipleNext);
169 connect(&_orbitTelemetryTimer, &QTimer::timeout,
this, &Vehicle::_orbitTelemetryTimeout);
172 connect(&_csvLogTimer, &QTimer::timeout,
this, &Vehicle::_writeCsvLine);
173 _csvLogTimer.start(1000);
179 MAV_TYPE vehicleType,
183 , _defaultComponentId (MAV_COMP_ID_ALL)
184 , _offlineEditingVehicle (true)
185 , _firmwareType (firmwareType)
186 , _vehicleType (vehicleType)
187 , _defaultCruiseSpeed (
SettingsManager::instance()->appSettings()->offlineEditingCruiseSpeed()->rawValue().toDouble())
188 , _defaultHoverSpeed (
SettingsManager::instance()->appSettings()->offlineEditingHoverSpeed()->rawValue().toDouble())
189 , _capabilityBitsKnown (true)
190 , _capabilityBits (MAV_PROTOCOL_CAPABILITY_MISSION_FENCE | MAV_PROTOCOL_CAPABILITY_MISSION_RALLY)
194 , _orbitMapCircle (std::make_unique<
QGCMapCircle>(this))
195 , _mavlinkStreamConfig (std::make_unique<
MAVLinkStreamConfig>(std::bind(&
Vehicle::_setMessageInterval, this, std::placeholders::_1, std::placeholders::_2)))
196 , _vehicleFactGroup (this)
203 _commonInit(
nullptr );
289 this, &Vehicle::_gotProgressUpdate);
332 if (!_offlineEditingVehicle) {
338 _createImageProtocolManager();
339 _createStatusTextHandler();
340 _createMAVLinkLogManager();
341 _createSigningController();
342 _createMAVLinkEventManager();
365 QMap<QString, FactGroup*>* fwFactGroups = _firmwarePlugin->
factGroups();
367 for (
auto it = fwFactGroups->keyValueBegin(); it != fwFactGroups->keyValueEnd(); ++it) {
372 _flightTimeUpdater.setInterval(1000);
373 _flightTimeUpdater.setSingleShot(
false);
374 connect(&_flightTimeUpdater, &QTimer::timeout,
this, &Vehicle::_updateFlightTime);
385 _createCameraManager();
390 qCDebug(VehicleLog) <<
"~Vehicle" <<
this;
397 _mavCmdQueue->
stop();
399 _sendMultipleTimer.stop();
400 _sendMultipleTimer.disconnect();
401 _prearmErrorTimer.stop();
402 _prearmErrorTimer.disconnect();
407 delete _autopilotPlugin;
408 _autopilotPlugin =
nullptr;
437void Vehicle::_deleteCameraManager()
441 _cameraManager->disconnect();
442 delete _cameraManager;
443 _cameraManager =
nullptr;
447void Vehicle::_deleteGimbalController()
449 if (_gimbalController) {
451 _gimbalController->disconnect();
452 delete _gimbalController;
453 _gimbalController =
nullptr;
457void Vehicle::_stopCommandProcessing()
459 qCDebug(VehicleLog) <<
"_stopCommandProcessing - stopping timers and clearing pending commands";
465 _mavCmdQueue->
stop();
468 _reqMsgCoord->
stop();
470 _sendMultipleTimer.stop();
471 _sendMultipleTimer.disconnect();
476 _firmwareType =
static_cast<MAV_AUTOPILOT
>(varFirmwareType.toInt());
478 if (_firmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA) {
479 _capabilityBits |= MAV_PROTOCOL_CAPABILITY_TERRAIN;
481 _capabilityBits &= ~MAV_PROTOCOL_CAPABILITY_TERRAIN;
489 _vehicleType =
static_cast<MAV_TYPE
>(varVehicleType.toInt());
493void Vehicle::_offlineCruiseSpeedSettingChanged(QVariant value)
495 _defaultCruiseSpeed = value.toDouble();
499void Vehicle::_offlineHoverSpeedSettingChanged(QVariant value)
501 _defaultHoverSpeed = value.toDouble();
512 _messagesReceived = 0;
521 if (message.sysid != _systemID && message.sysid != 0) {
535 if(message.msgid == MAVLINK_MSG_ID_HEARTBEAT) {
537 _compID = message.compid;
538 _messageSeq = message.seq + 1;
541 if(_compID == message.compid) {
542 uint16_t seq_received =
static_cast<uint16_t
>(message.seq);
543 uint16_t packet_lost_count = 0;
545 if(seq_received < _messageSeq) {
546 packet_lost_count = (seq_received + 255) - _messageSeq;
548 packet_lost_count = seq_received - _messageSeq;
550 _messageSeq = message.seq + 1;
551 _messagesLost += packet_lost_count;
552 if(packet_lost_count)
571 _parameterManager->mavlinkMessageReceived(message);
572 (void) QMetaObject::invokeMethod(_imageProtocolManager,
"mavlinkMessageReceived", Qt::AutoConnection, message);
583 factGroup->handleMessage(
this, message);
588 switch (message.msgid) {
589 case MAVLINK_MSG_ID_HOME_POSITION:
590 _handleHomePosition(message);
592 case MAVLINK_MSG_ID_HEARTBEAT:
593 _handleHeartbeat(message);
595 case MAVLINK_MSG_ID_RC_CHANNELS:
596 _handleRCChannels(message);
598 case MAVLINK_MSG_ID_SERVO_OUTPUT_RAW:
600 mavlink_servo_output_raw_t servoOutputRaw;
601 mavlink_msg_servo_output_raw_decode(&message, &servoOutputRaw);
604 const uint16_t rawValues[16] = {
605 servoOutputRaw.servo1_raw,
606 servoOutputRaw.servo2_raw,
607 servoOutputRaw.servo3_raw,
608 servoOutputRaw.servo4_raw,
609 servoOutputRaw.servo5_raw,
610 servoOutputRaw.servo6_raw,
611 servoOutputRaw.servo7_raw,
612 servoOutputRaw.servo8_raw,
613 servoOutputRaw.servo9_raw,
614 servoOutputRaw.servo10_raw,
615 servoOutputRaw.servo11_raw,
616 servoOutputRaw.servo12_raw,
617 servoOutputRaw.servo13_raw,
618 servoOutputRaw.servo14_raw,
619 servoOutputRaw.servo15_raw,
620 servoOutputRaw.servo16_raw
623 for (
int servoIndex = 0; servoIndex <
_servoOutputRawValues.size() && servoIndex < 16; servoIndex++) {
624 _servoOutputRawValues[servoIndex] = (rawValues[servoIndex] == UINT16_MAX) ? -1 : static_cast<int>(rawValues[servoIndex]);
630 case MAVLINK_MSG_ID_BATTERY_STATUS:
631 _handleBatteryStatus(message);
633 case MAVLINK_MSG_ID_SYS_STATUS:
634 _handleSysStatus(message);
636 case MAVLINK_MSG_ID_EXTENDED_SYS_STATE:
637 _handleExtendedSysState(message);
639 case MAVLINK_MSG_ID_COMMAND_ACK:
640 _handleCommandAck(message);
642 case MAVLINK_MSG_ID_LOGGING_DATA:
643 _handleMavlinkLoggingData(message);
645 case MAVLINK_MSG_ID_LOGGING_DATA_ACKED:
646 _handleMavlinkLoggingDataAcked(message);
648 case MAVLINK_MSG_ID_GPS_RAW_INT:
649 _handleGpsRawInt(message);
651 case MAVLINK_MSG_ID_GLOBAL_POSITION_INT:
652 _handleGlobalPositionInt(message);
654 case MAVLINK_MSG_ID_CAMERA_IMAGE_CAPTURED:
655 _handleCameraImageCaptured(message);
657 case MAVLINK_MSG_ID_ADSB_VEHICLE:
660 case MAVLINK_MSG_ID_HIGH_LATENCY:
661 _handleHighLatency(message);
663 case MAVLINK_MSG_ID_HIGH_LATENCY2:
664 _handleHighLatency2(message);
666 case MAVLINK_MSG_ID_STATUSTEXT:
669 case MAVLINK_MSG_ID_ORBIT_EXECUTION_STATUS:
670 _handleOrbitExecutionStatus(message);
672 case MAVLINK_MSG_ID_PING:
673 _handlePing(link, message);
675 case MAVLINK_MSG_ID_OBSTACLE_DISTANCE:
676 _handleObstacleDistance(message);
678 case MAVLINK_MSG_ID_FENCE_STATUS:
679 _handleFenceStatus(message);
682 case MAVLINK_MSG_ID_EVENT:
683 case MAVLINK_MSG_ID_CURRENT_EVENT_SEQUENCE:
684 case MAVLINK_MSG_ID_RESPONSE_EVENT_ERROR:
685 _handleEventMessage(message);
688 case MAVLINK_MSG_ID_SERIAL_CONTROL:
690 mavlink_serial_control_t ser;
691 mavlink_msg_serial_control_decode(&message, &ser);
692 if (
static_cast<size_t>(ser.count) >
sizeof(ser.data)) {
693 qCWarning(VehicleLog) <<
"Invalid count for SERIAL_CONTROL, discarding." << ser.count;
696 QByteArray(
reinterpret_cast<const char*
>(ser.data), ser.count));
700 case MAVLINK_MSG_ID_AVAILABLE_MODES_MONITOR:
704 mavlink_available_modes_monitor_t availableModesMonitor;
705 mavlink_msg_available_modes_monitor_decode(&message, &availableModesMonitor);
710 case MAVLINK_MSG_ID_CURRENT_MODE:
711 _handleCurrentMode(message);
715 case MAVLINK_MSG_ID_CAMERA_FEEDBACK:
716 _handleCameraFeedback(message);
718 case MAVLINK_MSG_ID_LOG_ENTRY:
720 mavlink_log_entry_t log{};
721 mavlink_msg_log_entry_decode(&message, &log);
722 emit
logEntry(log.time_utc, log.size, log.id, log.num_logs, log.last_log_num);
725 case MAVLINK_MSG_ID_LOG_DATA:
727 mavlink_log_data_t log{};
728 mavlink_msg_log_data_decode(&message, &log);
729 if (
static_cast<size_t>(log.count) >
sizeof(log.data)) {
730 qCWarning(VehicleLog) <<
"Invalid count for LOG_DATA, discarding." << log.count;
732 emit
logData(log.ofs, log.id, log.count, log.data);
736 case MAVLINK_MSG_ID_MESSAGE_INTERVAL:
741 case MAVLINK_MSG_ID_CONTROL_STATUS:
742 _handleControlStatus(message);
744 case MAVLINK_MSG_ID_COMMAND_LONG:
745 _handleCommandLong(message);
758 if (_cameraImageCapturedMessageAvailable) {
762 mavlink_camera_feedback_t feedback;
764 mavlink_msg_camera_feedback_decode(&message, &feedback);
766 QGeoCoordinate imageCoordinate((
double)feedback.lat / qPow(10.0, 7.0), (
double)feedback.lng / qPow(10.0, 7.0), feedback.alt_msl);
767 qCDebug(VehicleLog) <<
"_handleCameraFeedback coord:index" << imageCoordinate << feedback.img_idx;
773 mavlink_orbit_execution_status_t orbitStatus;
775 mavlink_msg_orbit_execution_status_decode(&message, &orbitStatus);
777 double newRadius = qAbs(
static_cast<double>(orbitStatus.radius));
778 if (!
QGC::fuzzyCompare(_orbitMapCircle->radius()->rawValue().toDouble(), newRadius)) {
779 _orbitMapCircle->radius()->setRawValue(newRadius);
782 bool newOrbitClockwise = orbitStatus.radius > 0 ? true :
false;
783 if (_orbitMapCircle->clockwiseRotation() != newOrbitClockwise) {
784 _orbitMapCircle->setClockwiseRotation(newOrbitClockwise);
787 QGeoCoordinate newCenter(
static_cast<double>(orbitStatus.x) / qPow(10.0, 7.0),
static_cast<double>(orbitStatus.y) / qPow(10.0, 7.0));
788 if (_orbitMapCircle->center() != newCenter) {
789 _orbitMapCircle->setCenter(newCenter);
794 _orbitMapCircle->setShowRotation(
true);
798 _orbitTelemetryTimer.start(_orbitTelemetryTimeoutMsecs);
801void Vehicle::_orbitTelemetryTimeout()
803 _orbitActive =
false;
809 mavlink_camera_image_captured_t feedback;
811 mavlink_msg_camera_image_captured_decode(&message, &feedback);
813 if (!_cameraImageCapturedMessageAvailable) {
814 _cameraImageCapturedMessageAvailable =
true;
816 if (_cameraTriggerPoints->count() > 0) {
821 QGeoCoordinate imageCoordinate((
double)feedback.lat / qPow(10.0, 7.0), (
double)feedback.lon / qPow(10.0, 7.0), feedback.alt);
822 qCDebug(VehicleLog) <<
"_handleCameraFeedback coord:index" << imageCoordinate << feedback.image_index << feedback.capture_result;
823 if (feedback.capture_result == 1) {
831 if (message.compid != _defaultComponentId) {
835 mavlink_gps_raw_int_t gpsRawInt;
836 mavlink_msg_gps_raw_int_decode(&message, &gpsRawInt);
838 _gpsRawIntMessageAvailable =
true;
840 if (gpsRawInt.fix_type >= GPS_FIX_TYPE_3D_FIX) {
841 if (!_globalPositionIntMessageAvailable) {
842 QGeoCoordinate newPosition(gpsRawInt.lat / (
double)1E7, gpsRawInt.lon / (
double)1E7, gpsRawInt.alt / 1000.0);
843 if (newPosition != _coordinate) {
844 _coordinate = newPosition;
857 if (message.compid != _defaultComponentId) {
861 mavlink_global_position_int_t globalPositionInt;
862 mavlink_msg_global_position_int_decode(&message, &globalPositionInt);
871 if (globalPositionInt.lat == 0 && globalPositionInt.lon == 0) {
875 _globalPositionIntMessageAvailable =
true;
876 QGeoCoordinate newPosition(globalPositionInt.lat / (
double)1E7, globalPositionInt.lon / (
double)1E7, globalPositionInt.alt / 1000.0);
877 if (newPosition != _coordinate) {
878 _coordinate = newPosition;
886 mavlink_high_latency_t highLatency;
887 mavlink_msg_high_latency_decode(&message, &highLatency);
889 QString previousFlightMode;
890 if (_base_mode != 0 || _custom_mode != 0){
895 _base_mode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED;
902 if (_armed !=
true) {
910 const double altitude;
912 highLatency.latitude / (double)1E7,
913 highLatency.longitude / (
double)1E7,
914 static_cast<double>(highLatency.altitude_amsl)
918 _coordinate.setLongitude(
coordinate.longitude);
934 mavlink_msg_high_latency2_decode(&message, &highLatency2);
936 QString previousFlightMode;
937 if (_base_mode != 0 || _custom_mode != 0){
943 if (highLatency2.autopilot == MAV_AUTOPILOT_ARDUPILOTMEGA) {
944 _base_mode = (uint8_t)highLatency2.custom0;
946 _base_mode = MAV_MODE_FLAG_CUSTOM_MODE_ENABLED;
953 if (highLatency2.autopilot == MAV_AUTOPILOT_ARDUPILOTMEGA) {
954 if ((uint8_t)highLatency2.custom0 & MAV_MODE_FLAG_SAFETY_ARMED && _armed !=
true) {
957 }
else if (!((uint8_t)highLatency2.custom0 & MAV_MODE_FLAG_SAFETY_ARMED) && _armed !=
false) {
963 if (_armed !=
true) {
969 _coordinate.setLatitude(highLatency2.latitude / (
double)1E7);
970 _coordinate.setLongitude(highLatency2.longitude / (
double)1E7);
971 _coordinate.setAltitude(highLatency2.altitude);
983 if (newOnboardControlSensorsEnabled != _onboardControlSensorsEnabled) {
984 _onboardControlSensorsEnabled = newOnboardControlSensorsEnabled;
985 _onboardControlSensorsPresent = newOnboardControlSensorsEnabled;
986 _onboardControlSensorsUnhealthy = 0;
990void Vehicle::_setCapabilities(uint64_t capabilityBits)
993 _capabilityBitsKnown =
true;
998 QString doesNotSupport(
"does not support");
1000 qCDebug(VehicleLog) << QString(
"Vehicle %1 Mavlink 2.0").arg(_capabilityBits & MAV_PROTOCOL_CAPABILITY_MAVLINK2 ?
supports : doesNotSupport);
1001 qCDebug(VehicleLog) << QString(
"Vehicle %1 MISSION_ITEM_INT").arg(_capabilityBits & MAV_PROTOCOL_CAPABILITY_MISSION_INT ?
supports : doesNotSupport);
1002 qCDebug(VehicleLog) << QString(
"Vehicle %1 MISSION_COMMAND_INT").arg(_capabilityBits & MAV_PROTOCOL_CAPABILITY_COMMAND_INT ?
supports : doesNotSupport);
1003 qCDebug(VehicleLog) << QString(
"Vehicle %1 GeoFence").arg(_capabilityBits & MAV_PROTOCOL_CAPABILITY_MISSION_FENCE ?
supports : doesNotSupport);
1004 qCDebug(VehicleLog) << QString(
"Vehicle %1 RallyPoints").arg(_capabilityBits & MAV_PROTOCOL_CAPABILITY_MISSION_RALLY ?
supports : doesNotSupport);
1005 qCDebug(VehicleLog) << QString(
"Vehicle %1 Terrain").arg(_capabilityBits & MAV_PROTOCOL_CAPABILITY_TERRAIN ?
supports : doesNotSupport);
1011 uint8_t* pUid = (uint8_t*)(
void*)&_uid;
1012 uid = uid.asprintf(
"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1026 if (message.compid != _defaultComponentId) {
1030 mavlink_extended_sys_state_t extendedState;
1031 mavlink_msg_extended_sys_state_decode(&message, &extendedState);
1033 switch (extendedState.landed_state) {
1034 case MAV_LANDED_STATE_ON_GROUND:
1038 case MAV_LANDED_STATE_TAKEOFF:
1039 case MAV_LANDED_STATE_IN_AIR:
1043 case MAV_LANDED_STATE_LANDING:
1060bool Vehicle::_apmArmingNotRequired()
1062 QString armingRequireParam(
"ARMING_REQUIRE");
1069 if (message.compid != _defaultComponentId) {
1073 mavlink_sys_status_t sysStatus;
1074 mavlink_msg_sys_status_decode(&message, &sysStatus);
1076 _sysStatusSensorInfo->update(sysStatus);
1078 if (sysStatus.onboard_control_sensors_enabled & MAV_SYS_STATUS_PREARM_CHECK) {
1079 if (!_readyToFlyAvailable) {
1080 _readyToFlyAvailable =
true;
1084 bool newReadyToFly = sysStatus.onboard_control_sensors_health & MAV_SYS_STATUS_PREARM_CHECK;
1085 if (newReadyToFly != _readyToFly) {
1086 _readyToFly = newReadyToFly;
1091 bool newAllSensorsHealthy = (sysStatus.onboard_control_sensors_enabled & sysStatus.onboard_control_sensors_health) == sysStatus.onboard_control_sensors_enabled;
1092 if (newAllSensorsHealthy != _allSensorsHealthy) {
1093 _allSensorsHealthy = newAllSensorsHealthy;
1097 if (_onboardControlSensorsPresent != sysStatus.onboard_control_sensors_present) {
1098 _onboardControlSensorsPresent = sysStatus.onboard_control_sensors_present;
1102 if (_onboardControlSensorsEnabled != sysStatus.onboard_control_sensors_enabled) {
1103 _onboardControlSensorsEnabled = sysStatus.onboard_control_sensors_enabled;
1106 if (_onboardControlSensorsHealth != sysStatus.onboard_control_sensors_health) {
1107 _onboardControlSensorsHealth = sysStatus.onboard_control_sensors_health;
1115 _updateArmed(_onboardControlSensorsEnabled & MAV_SYS_STATUS_SENSOR_MOTOR_OUTPUTS);
1118 uint32_t newSensorsUnhealthy = _onboardControlSensorsEnabled & ~_onboardControlSensorsHealth;
1119 if (newSensorsUnhealthy != _onboardControlSensorsUnhealthy) {
1120 _onboardControlSensorsUnhealthy = newSensorsUnhealthy;
1127 mavlink_battery_status_t batteryStatus;
1128 mavlink_msg_battery_status_decode(&message, &batteryStatus);
1134 QString batteryMessage;
1136 switch (batteryStatus.charge_state) {
1137 case MAV_BATTERY_CHARGE_STATE_OK:
1140 case MAV_BATTERY_CHARGE_STATE_LOW:
1143 batteryMessage = tr(
"battery %1 level low");
1146 case MAV_BATTERY_CHARGE_STATE_CRITICAL:
1149 batteryMessage = tr(
"battery %1 level is critical");
1152 case MAV_BATTERY_CHARGE_STATE_EMERGENCY:
1155 batteryMessage = tr(
"battery %1 level emergency");
1158 case MAV_BATTERY_CHARGE_STATE_FAILED:
1161 batteryMessage = tr(
"battery %1 failed");
1164 case MAV_BATTERY_CHARGE_STATE_UNHEALTHY:
1167 batteryMessage = tr(
"battery %1 unhealthy");
1172 if (!batteryMessage.isEmpty()) {
1173 QString batteryIdStr(
"%1");
1175 batteryIdStr = batteryIdStr.arg(batteryStatus.id);
1177 batteryIdStr = batteryIdStr.arg(
"");
1179 _say(tr(
"warning"));
1180 _say(QStringLiteral(
"%1 %2 ").arg(_vehicleIdSpeech()).arg(batteryMessage.arg(batteryIdStr)));
1186 if (homeCoord != _homePosition) {
1187 _homePosition = homeCoord;
1188 qCDebug(VehicleLog) <<
"new home location set at coordinate: " << homeCoord;
1195 if (message.compid != _defaultComponentId) {
1199 mavlink_home_position_t homePos;
1201 mavlink_msg_home_position_decode(&message, &homePos);
1203 QGeoCoordinate newHomePosition (homePos.latitude / 10000000.0,
1204 homePos.longitude / 10000000.0,
1205 homePos.altitude / 1000.0);
1209void Vehicle::_updateArmed(
bool armed)
1211 if (_armed !=
armed) {
1216 _trajectoryPoints->
start();
1217 _flightTimerStart();
1218 _clearCameraTriggerPoints();
1222 _trajectoryPoints->
stop();
1237 qCDebug(VehicleLog) <<
"_handlePing: primary link gone!";
1241 mavlink_ping_t ping;
1244 mavlink_msg_ping_decode(&message, &ping);
1246 if ((ping.target_system == 0) && (ping.target_component == 0)) {
1251 sharedLink->mavlinkChannel(),
1262 const QString &metadataJsonFileName,
1263 const QJsonDocument &metadataJson)
1273 if (message.compid != _defaultComponentId) {
1277 mavlink_heartbeat_t heartbeat;
1279 mavlink_msg_heartbeat_decode(&message, &heartbeat);
1281 bool newArmed = heartbeat.base_mode & MAV_MODE_FLAG_DECODE_POSITION_SAFETY;
1287 if (!_apmArmingNotRequired() || !(_onboardControlSensorsPresent & MAV_SYS_STATUS_SENSOR_MOTOR_OUTPUTS)) {
1289 _updateArmed(newArmed);
1293 _updateArmed(newArmed);
1296 if (heartbeat.base_mode != _base_mode || heartbeat.custom_mode != _custom_mode) {
1297 QString previousFlightMode;
1298 if (_base_mode != 0 || _custom_mode != 0){
1303 _base_mode = heartbeat.base_mode;
1304 _custom_mode = heartbeat.custom_mode;
1313 if (message.compid != _defaultComponentId) {
1317 mavlink_current_mode_t currentMode;
1318 mavlink_msg_current_mode_decode(&message, ¤tMode);
1319 if (currentMode.intended_custom_mode != 0) {
1320 _has_custom_mode_user_intention =
true;
1322 bool changed = _custom_mode_user_intention != currentMode.intended_custom_mode;
1323 _custom_mode_user_intention = currentMode.intended_custom_mode;
1324 if (changed && previousFlightMode !=
flightMode()) {
1332 mavlink_rc_channels_t channels;
1334 mavlink_msg_rc_channels_decode(&message, &channels);
1336 QVector<uint16_t> rawChannelValues({
1346 channels.chan10_raw,
1347 channels.chan11_raw,
1348 channels.chan12_raw,
1349 channels.chan13_raw,
1350 channels.chan14_raw,
1351 channels.chan15_raw,
1352 channels.chan16_raw,
1353 channels.chan17_raw,
1354 channels.chan18_raw,
1358 int validChannelCount = 0;
1359 int firstUnusedChannelIndex = -1;
1360 for (
int i=0; i<rawChannelValues.size(); i++) {
1361 if (rawChannelValues[i] != UINT16_MAX) {
1362 validChannelCount++;
1363 }
else if (firstUnusedChannelIndex == -1) {
1364 firstUnusedChannelIndex = i;
1367 if (firstUnusedChannelIndex != -1 && firstUnusedChannelIndex != validChannelCount) {
1368 qCWarning(VehicleLog) <<
"Non-contiguous RC channels detected. Not publishing data from RC_CHANNELS.";
1372 QVector<int> channelValues(validChannelCount);
1373 QVector<int> clampedValues(validChannelCount);
1374 for (
int channelIndex = 0; channelIndex < validChannelCount; ++channelIndex) {
1375 channelValues[channelIndex] = rawChannelValues[channelIndex];
1376 clampedValues[channelIndex] = std::clamp(channelValues[channelIndex], 1000, 2000);
1389 qCDebug(VehicleLog) <<
"sendMessageOnLinkThreadSafe" << link <<
"not connected!";
1406 uint8_t frameType = 0;
1407 if (_vehicleType == MAV_TYPE_SUBMARINE) {
1423void Vehicle::_activeVehicleChanged(
Vehicle *newActiveVehicle)
1425 _isActiveVehicle = newActiveVehicle ==
this;
1430 return _homePosition;
1437 MAV_CMD_COMPONENT_ARM_DISARM,
1439 armed ? 1.0f : 0.0f);
1445 MAV_CMD_COMPONENT_ARM_DISARM,
1464 return _firmwarePlugin->
flightMode(_base_mode, _custom_mode);
1467bool Vehicle::setFlightModeCustom(
const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode)
1475 uint32_t custom_mode;
1477 if (setFlightModeCustom(
flightMode, &base_mode, &custom_mode)) {
1480 qCDebug(VehicleLog) <<
"setFlightMode: primary link gone!";
1484 uint8_t newBaseMode = _base_mode & ~MAV_MODE_FLAG_DECODE_POSITION_CUSTOM_MODE;
1488 newBaseMode |= base_mode;
1492 MAV_CMD_DO_SET_MODE,
1494 MAV_MODE_FLAG_CUSTOM_MODE_ENABLED,
1500 sharedLink->mavlinkChannel(),
1508 qCWarning(VehicleLog) <<
"FirmwarePlugin::setFlightMode failed, flightMode:" <<
flightMode;
1513QVariantList Vehicle::links()
const {
1516 for(
const auto &item: _links )
1517 ret << QVariant::fromValue(item);
1527 qCDebug(VehicleLog) <<
"requestDataStream: primary link gone!";
1532 mavlink_request_data_stream_t dataStream;
1534 memset(&dataStream, 0,
sizeof(dataStream));
1536 dataStream.req_stream_id = stream;
1537 dataStream.req_message_rate = rate;
1538 dataStream.start_stop = 1;
1539 dataStream.target_system =
id();
1540 dataStream.target_component = _defaultComponentId;
1544 sharedLink->mavlinkChannel(),
1556void Vehicle::_sendMessageMultipleNext()
1558 if (_nextSendMessageMultipleIndex < _sendMessageMultipleList.count()) {
1559 uint32_t msgId = _sendMessageMultipleList[_nextSendMessageMultipleIndex].message.msgid;
1560 const mavlink_message_info_t* info = mavlink_get_message_info_by_id(msgId);
1561 QString msgName = info ? info->name : QString::number(msgId);
1562 qCDebug(VehicleLog) <<
"_sendMessageMultipleNext:" << msgName;
1569 if (--_sendMessageMultipleList[_nextSendMessageMultipleIndex].retryCount <= 0) {
1570 _sendMessageMultipleList.removeAt(_nextSendMessageMultipleIndex);
1572 _nextSendMessageMultipleIndex++;
1576 if (_nextSendMessageMultipleIndex >= _sendMessageMultipleList.count()) {
1577 _nextSendMessageMultipleIndex = 0;
1583 SendMessageMultipleInfo_t info;
1585 info.message = message;
1586 info.retryCount = _sendMessageMultipleRetries;
1588 _sendMessageMultipleList.append(info);
1591void Vehicle::_missionManagerError(
int errorCode,
const QString& errorMsg)
1593 Q_UNUSED(errorCode);
1597void Vehicle::_geoFenceManagerError(
int errorCode,
const QString& errorMsg)
1599 Q_UNUSED(errorCode);
1603void Vehicle::_rallyPointManagerError(
int errorCode,
const QString& errorMsg)
1605 Q_UNUSED(errorCode);
1609void Vehicle::_clearCameraTriggerPoints()
1611 _cameraImageCapturedMessageAvailable =
false;
1612 _cameraTriggerPoints->clearAndDeleteContents();
1615void Vehicle::_flightTimerStart()
1617 _flightTimer.start();
1618 _flightTimeUpdater.start();
1623void Vehicle::_flightTimerStop()
1625 _flightTimeUpdater.stop();
1628void Vehicle::_updateFlightTime()
1633void Vehicle::_gotProgressUpdate(
float progressValue)
1639 progressValue = 0.f;
1641 _loadProgress = progressValue;
1645void Vehicle::_firstMissionLoadComplete()
1650void Vehicle::_firstGeoFenceLoadComplete()
1655void Vehicle::_firstRallyPointLoadComplete()
1658 _initialPlanRequestComplete =
true;
1662void Vehicle::_parametersReady(
bool parametersReady)
1664 qCDebug(VehicleLog) <<
"_parametersReady" << parametersReady;
1667 _sendQGCTimeToVehicle();
1669 _sendQGCTimeToVehicle();
1670 if (parametersReady) {
1672 _setupAutoDisarmSignalling();
1682void Vehicle::_sendQGCTimeToVehicle()
1686 qCDebug(VehicleLog) <<
"_sendQGCTimeToVehicle: primary link gone!";
1691 mavlink_system_time_t cmd;
1694 cmd.time_unix_usec = QDateTime::currentDateTime().currentMSecsSinceEpoch()*1000;
1696 cmd.time_boot_ms = 0;
1699 sharedLink->mavlinkChannel(),
1711 if (!joystickEnabled) {
1713 static_cast<float>(
roll),
1714 static_cast<float>(
pitch),
1715 static_cast<float>(yaw),
1716 static_cast<float>(thrust),
1718 NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN);
1722void Vehicle::_say(
const QString& text)
1773QString Vehicle::_vehicleIdSpeech()
1776 return tr(
"Vehicle %1 ").arg(
id());
1782void Vehicle::_handleFlightModeChanged(
const QString& flightMode)
1784 if (
flightMode != _lastAnnouncedFlightMode) {
1786 _say(tr(
"%1 %2 flight mode").arg(_vehicleIdSpeech()).arg(
flightMode));
1791void Vehicle::_announceArmedChanged(
bool armed)
1793 _say(QString(
"%1 %2").arg(_vehicleIdSpeech()).arg(
armed ? tr(
"armed") : tr(
"disarmed")));
1796 _armedPosition = _coordinate;
1896 if (!gotoCoord.isValid()) {
1900 if (
coordinate().distanceTo(gotoCoord) > maxDistance) {
1949 static_cast<float>(radius),
1950 static_cast<float>(qQNaN()),
1951 static_cast<float>(ORBIT_YAW_BEHAVIOUR_UNCHANGED),
1952 static_cast<float>(qQNaN()),
1953 centerCoord.latitude(), centerCoord.longitude(),
static_cast<float>(amslAltitude));
1959 static_cast<float>(radius),
1960 static_cast<float>(qQNaN()),
1961 static_cast<float>(ORBIT_YAW_BEHAVIOUR_UNCHANGED),
1962 static_cast<float>(qQNaN()),
1963 static_cast<float>(centerCoord.latitude()),
1964 static_cast<float>(centerCoord.longitude()),
1965 static_cast<float>(amslAltitude));
1971 if (!centerCoord.isValid()) {
1974 if (!_vehicleSupports->
roiMode()) {
1987 if ((centerCoord.altitude() >= 83000) || (centerCoord.altitude() <= -83000)) {
1999 if (!_vehicleSupports->
roiMode()) {
2006 MAV_CMD_DO_SET_ROI_NONE,
2009 static_cast<float>(qQNaN()),
2010 static_cast<float>(qQNaN()),
2011 static_cast<float>(qQNaN()),
2012 static_cast<float>(qQNaN()),
2013 static_cast<double>(qQNaN()),
2014 static_cast<double>(qQNaN()),
2015 static_cast<float>(qQNaN()));
2019 MAV_CMD_DO_SET_ROI_NONE,
2021 static_cast<float>(qQNaN()),
2022 static_cast<float>(qQNaN()),
2023 static_cast<float>(qQNaN()),
2024 static_cast<float>(qQNaN()),
2025 static_cast<float>(qQNaN()),
2026 static_cast<float>(qQNaN()),
2027 static_cast<float>(qQNaN()));
2054 MAV_CMD_DO_GO_AROUND,
2056 static_cast<float>(climbOutAltitude));
2078 _defaultComponentId,
2079 MAV_CMD_COMPONENT_ARM_DISARM,
2089 MAV_CMD_AIRFRAME_CONFIGURATION,
2099 MAV_CMD_AIRFRAME_CONFIGURATION,
2116 qCDebug(VehicleLog) <<
"setCurrentMissionSequence: primary link gone!";
2123 mavlink_msg_mission_set_current_pack_chan(
2126 sharedLink->mavlinkChannel(),
2128 static_cast<uint8_t
>(
id()),
2130 static_cast<uint16_t
>(seq));
2134 MAV_CMD_DO_SET_MISSION_CURRENT,
2136 static_cast<uint16_t
>(seq)
2140void Vehicle::sendMavCommand(
int compId, MAV_CMD command,
bool showError,
float param1,
float param2,
float param3,
float param4,
float param5,
float param6,
float param7)
2142 _mavCmdQueue->
sendCommand(
compId, command, showError, param1, param2, param3, param4, param5, param6, param7);
2145void Vehicle::sendMavCommandDelayed(
int compId, MAV_CMD command,
bool showError,
int milliseconds,
float param1,
float param2,
float param3,
float param4,
float param5,
float param6,
float param7)
2147 _mavCmdQueue->
sendCommandDelayed(
compId, command, showError, milliseconds, param1, param2, param3, param4, param5, param6, param7);
2150void Vehicle::sendCommand(
int compId,
int command,
bool showError,
double param1,
double param2,
double param3,
double param4,
double param5,
double param6,
double param7)
2153 compId,
static_cast<MAV_CMD
>(command),
2155 static_cast<float>(param1),
2156 static_cast<float>(param2),
2157 static_cast<float>(param3),
2158 static_cast<float>(param4),
2159 static_cast<float>(param5),
2160 static_cast<float>(param6),
2161 static_cast<float>(param7));
2169void Vehicle::sendMavCommandInt(
int compId, MAV_CMD command, MAV_FRAME frame,
bool showError,
float param1,
float param2,
float param3,
float param4,
double param5,
double param6,
float param7)
2171 _mavCmdQueue->
sendCommandInt(
compId, command, frame, showError, param1, param2, param3, param4, param5, param6, param7);
2174void Vehicle::sendMavCommandIntWithHandler(
const MavCmdAckHandlerInfo_t* ackHandlerInfo,
int compId, MAV_CMD command, MAV_FRAME frame,
float param1,
float param2,
float param3,
float param4,
double param5,
double param6,
float param7)
2176 _mavCmdQueue->
sendCommandIntWithHandler(ackHandlerInfo,
compId, command, frame, param1, param2, param3, param4, param5, param6, param7);
2179void Vehicle::sendMavCommandWithLambdaFallback(std::function<
void()> lambda,
int compId, MAV_CMD command,
bool showError,
float param1,
float param2,
float param3,
float param4,
float param5,
float param6,
float param7)
2181 _mavCmdQueue->
sendCommandWithLambdaFallback(std::move(lambda),
compId, command, showError, param1, param2, param3, param4, param5, param6, param7);
2184void Vehicle::sendMavCommandIntWithLambdaFallback(std::function<
void()> lambda,
int compId, MAV_CMD command, MAV_FRAME frame,
bool showError,
float param1,
float param2,
float param3,
float param4,
double param5,
double param6,
float param7)
2186 _mavCmdQueue->
sendCommandIntWithLambdaFallback(std::move(lambda),
compId, command, frame, showError, param1, param2, param3, param4, param5, param6, param7);
2191 return _mavCmdQueue->
isPending(targetCompId, command);
2207 mavlink_msg_command_ack_decode(&message, &ack);
2210 QString logMsg = QStringLiteral(
"_handleCommandAck command(%1) result(%2)").arg(rawCommandName).arg(
QGCMAVLink::mavResultToString(
static_cast<MAV_RESULT
>(ack.result)));
2213 if (ack.command == MAV_CMD_REQUEST_MESSAGE) {
2214 const int entryIndex = _mavCmdQueue->
findEntryIndex(message.compid,
static_cast<MAV_CMD
>(ack.command));
2215 if (entryIndex != -1) {
2218 logMsg += QStringLiteral(
" (entry=%1)").arg(entryIndex);
2222 qCDebug(VehicleLog) << logMsg;
2225 if (ack.command == MAV_CMD_DO_SET_ROI_LOCATION && ack.result == MAV_RESULT_ACCEPTED) {
2226 _isROIEnabled =
true;
2229 if (ack.command == MAV_CMD_DO_SET_ROI_NONE && ack.result == MAV_RESULT_ACCEPTED) {
2230 _isROIEnabled =
false;
2233 if (ack.command == MAV_CMD_PREFLIGHT_STORAGE) {
2236 if (ack.command == MAV_CMD_FLASH_BOOTLOADER && ack.result == MAV_RESULT_ACCEPTED) {
2244 if (ack.command == MAV_CMD_SET_MESSAGE_INTERVAL) {
2245 _mavlinkStreamConfig->gotSetMessageIntervalAck();
2249void Vehicle::requestMessage(RequestMessageResultHandler resultHandler,
void* resultHandlerData,
int compId,
int messageId,
float param1,
float param2,
float param3,
float param4,
float param5)
2251 _reqMsgCoord->
requestMessage(resultHandler, resultHandlerData,
compId, messageId, param1, param2, param3, param4, param5);
2259 if (!_prearmError.isEmpty()) {
2260 _prearmErrorTimer.start();
2264void Vehicle::_prearmErrorTimeout()
2271 _firmwareMajorVersion = majorVersion;
2272 _firmwareMinorVersion = minorVersion;
2273 _firmwarePatchVersion = patchVersion;
2274 _firmwareVersionType = versionType;
2280 _firmwareCustomMajorVersion = majorVersion;
2281 _firmwareCustomMinorVersion = minorVersion;
2282 _firmwareCustomPatchVersion = patchVersion;
2291void Vehicle::_rebootCommandResultHandler(
void* resultHandlerData,
int ,
const mavlink_command_ack_t& ack, MavCmdResultFailureCode_t failureCode)
2295 if (ack.result != MAV_RESULT_ACCEPTED) {
2296 switch (failureCode) {
2298 qCDebug(VehicleLog) << QStringLiteral(
"MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN error(%1)").arg(ack.result);
2301 qCDebug(VehicleLog) <<
"MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN failed: no response from vehicle";
2304 qCDebug(VehicleLog) <<
"MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN failed: duplicate command";
2326 qCDebug(VehicleLog) <<
"startCalibration: primary link gone!";
2392 sharedLink->mavlinkChannel(),
2396 MAV_CMD_PREFLIGHT_CALIBRATION,
2398 param1, param2, param3, param4, param5, param6, param7);
2405 MAV_CMD_PREFLIGHT_CALIBRATION,
2419 MAV_CMD_PREFLIGHT_UAVCAN,
2427 MAV_CMD_PREFLIGHT_UAVCAN,
2442 sendMavCommand(_defaultComponentId, MAV_CMD_DO_MOTOR_TEST, showError, motor, MOTOR_TEST_THROTTLE_PERCENT, percent, timeoutSecs, 0, MOTOR_TEST_ORDER_BOARD);
2447 if (_offlineEditingVehicle) {
2450 qCWarning(VehicleLog) <<
"Call to Vehicle::setOfflineEditingDefaultComponentId on vehicle which is not offline";
2458 MAV_CMD_DO_VTOL_TRANSITION,
2467 sendMavCommand(_defaultComponentId, MAV_CMD_LOGGING_START,
false );
2472 sendMavCommand(_defaultComponentId, MAV_CMD_LOGGING_STOP,
false );
2475void Vehicle::_ackMavlinkLogData(uint16_t sequence)
2479 qCDebug(VehicleLog) <<
"_ackMavlinkLogData: primary link gone!";
2484 mavlink_logging_ack_t ack;
2486 memset(&ack, 0,
sizeof(ack));
2487 ack.sequence = sequence;
2488 ack.target_component = _defaultComponentId;
2489 ack.target_system =
id();
2490 mavlink_msg_logging_ack_encode_chan(
2493 sharedLink->mavlinkChannel(),
2501 mavlink_logging_data_t log;
2502 mavlink_msg_logging_data_decode(&message, &log);
2503 if (
static_cast<size_t>(log.length) >
sizeof(log.data)) {
2504 qWarning() <<
"Invalid length for LOGGING_DATA, discarding." << log.length;
2506 emit
mavlinkLogData(
this, log.target_system, log.target_component, log.sequence,
2507 log.first_message_offset, QByteArray((
const char*)log.data, log.length),
false);
2513 mavlink_logging_data_acked_t log;
2514 mavlink_msg_logging_data_acked_decode(&message, &log);
2515 _ackMavlinkLogData(log.sequence);
2516 if (
static_cast<size_t>(log.length) >
sizeof(log.data)) {
2517 qWarning() <<
"Invalid length for LOGGING_DATA_ACKED, discarding." << log.length;
2519 emit
mavlinkLogData(
this, log.target_system, log.target_component, log.sequence,
2520 log.first_message_offset, QByteArray((
const char*)log.data, log.length),
false);
2593 if(_firmwarePlugin) {
2596 static QVariantList emptyList;
2600void Vehicle::_setupAutoDisarmSignalling()
2617 return fact->
rawValue().toDouble() > 0;
2623void Vehicle::_updateDistanceHeadingHome()
2641void Vehicle::_updateHeadingToNextWP()
2646 if(llist.size()>currentIndex && currentIndex!=-1
2647 && llist[currentIndex]->coordinate().longitude()!=0.0
2657void Vehicle::_updateMissionItemIndex()
2661 unsigned offset = 0;
2669void Vehicle::_updateDistanceHeadingGCS()
2672 if (
coordinate().isValid() && gcsPosition.isValid()) {
2681void Vehicle::_updateHomepoint()
2685 if(setHomeCmdSupported && updateHomeActivated){
2687 if (
coordinate().isValid() && gcsPosition.isValid()) {
2689 MAV_CMD_DO_SET_HOME,
false,
2692 static_cast<float>(gcsPosition.latitude()) ,
2693 static_cast<float>(gcsPosition.longitude()),
2694 static_cast<float>(gcsPosition.altitude()));
2699void Vehicle::_updateHobbsMeter()
2706 _initialPlanRequestComplete =
true;
2720void Vehicle::_vehicleParamLoaded(
bool ready)
2729void Vehicle::_mavlinkMessageStatus(
int uasId, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss,
float lossPercent)
2731 if(uasId == _systemID) {
2732 _mavlinkSentCount = totalSent;
2733 _mavlinkReceivedCount = totalReceived;
2734 _mavlinkLossCount = totalLoss;
2735 _mavlinkLossPercent = lossPercent;
2747 return _firmwarePlugin->
versionCompare(
this, major, minor, patch);
2760 _mavlinkStreamConfig->restoreDefaults();
2763 _mavlinkStreamConfig->setHighRateRateAndAttitude();
2766 _mavlinkStreamConfig->setHighRateVelAndPos();
2769 _mavlinkStreamConfig->setHighRateAltAirspeed();
2780void Vehicle::_setMessageInterval(
int messageId,
int rate)
2783 MAV_CMD_SET_MESSAGE_INTERVAL,
2789QString Vehicle::_formatMavCommand(MAV_CMD command,
float param1)
2793 if (command == MAV_CMD_REQUEST_MESSAGE && param1 > 0) {
2794 const mavlink_message_info_t* info = mavlink_get_message_info_by_id(
static_cast<uint32_t
>(param1));
2795 QString param1Str = info ? QString(
"%1(%2)").arg(param1).arg(info->name) : QString::number(param1);
2796 return QString(
"%1: %2").arg(commandName).arg(param1Str);
2798 return QString(
"%1: %2").arg(commandName).arg(param1);
2806void Vehicle::_initializeCsv()
2811 QString now = QDateTime::currentDateTime().toString(
"yyyy-MM-dd hh-mm-ss");
2812 QString fileName = QString(
"%1 vehicle%2.csv").arg(now).arg(_systemID);
2814 _csvLogFile.setFileName(saveDir.absoluteFilePath(fileName));
2816 if (!_csvLogFile.open(QIODevice::Append)) {
2817 qCWarning(VehicleLog) <<
"unable to open file for csv logging, Stopping csv logging!";
2821 QTextStream stream(&_csvLogFile);
2822 QStringList allFactNames;
2826 allFactNames << QString(
"%1.%2").arg(groupName, factName);
2829 qCDebug(VehicleLog) <<
"Facts logged to csv:" << allFactNames;
2830 stream <<
"Timestamp," << allFactNames.join(
",") <<
"\n";
2833void Vehicle::_writeCsvLine()
2836 if(!_csvLogFile.isOpen() &&
2841 if(!_csvLogFile.isOpen()){
2845 QStringList allFactValues;
2846 QTextStream stream(&_csvLogFile);
2849 allFactValues << QDateTime::currentDateTime().toString(QStringLiteral(
"yyyy-MM-dd hh:mm:ss.zzz"));
2851 for (
const QString& factName :
factNames()) {
2861 stream << allFactValues.join(
",") <<
"\n";
2872 mavlink_msg_obstacle_distance_decode(&message, &o);
2873 _objectAvoidance->
update(&o);
2878 mavlink_fence_status_t fenceStatus;
2880 mavlink_msg_fence_status_decode(&message, &fenceStatus);
2882 qCDebug(VehicleLog) <<
"_handleFenceStatus breach_status" << fenceStatus.breach_status;
2884 static qint64 lastUpdate = 0;
2885 qint64 now = QDateTime::currentMSecsSinceEpoch();
2886 if (fenceStatus.breach_status == 1) {
2887 if (now - lastUpdate > 3000) {
2889 QString breachTypeStr;
2890 switch (fenceStatus.breach_type) {
2891 case FENCE_BREACH_NONE:
2893 case FENCE_BREACH_MINALT:
2894 breachTypeStr = tr(
"minimum altitude");
2896 case FENCE_BREACH_MAXALT:
2897 breachTypeStr = tr(
"maximum altitude");
2899 case FENCE_BREACH_BOUNDARY:
2900 breachTypeStr = tr(
"boundary");
2906 _say(breachTypeStr +
" " + tr(
"fence breached"));
2918void Vehicle::sendParamMapRC(
const QString& paramName,
double scale,
double centerValue,
int tuningID,
double minValue,
double maxValue)
2922 qCDebug(VehicleLog) <<
"sendParamMapRC: primary link gone!";
2928 char param_id_cstr[MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN] = {};
2930 for (
unsigned int i = 0; i <
sizeof(param_id_cstr); i++) {
2931 if ((
int)i < paramName.length()) {
2932 param_id_cstr[i] = paramName.toLatin1()[i];
2938 sharedLink->mavlinkChannel(),
2941 MAV_COMP_ID_AUTOPILOT1,
2944 static_cast<uint8_t
>(tuningID),
2945 static_cast<float>(centerValue),
2946 static_cast<float>(scale),
2947 static_cast<float>(minValue),
2948 static_cast<float>(maxValue));
2956 qCDebug(VehicleLog)<<
"clearAllParamMapRC: primary link gone!";
2960 char param_id_cstr[MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN] = {};
2962 for (
int i = 0; i < 3; i++) {
2966 sharedLink->mavlinkChannel(),
2969 MAV_COMP_ID_AUTOPILOT1,
2978void Vehicle::sendJoystickDataThreadSafe(
float roll,
float pitch,
float yaw,
float thrust, quint16 buttons, quint16 buttons2,
float pitchExtension,
float rollExtension,
float aux1,
float aux2,
float aux3,
float aux4,
float aux5,
float aux6)
2982 qCDebug(VehicleLog)<<
"sendJoystickDataThreadSafe: primary link gone!";
2986 if (sharedLink->linkConfiguration()->isHighLatency()) {
2992 float axesScaling = 1.0 * 1000.0;
2993 uint8_t extensions = 0;
2996 float newRollCommand =
roll * axesScaling;
2997 float newPitchCommand =
pitch * axesScaling;
2998 float newYawCommand = yaw * axesScaling;
2999 float newThrustCommand = thrust * axesScaling;
3002 float incomingExtensionValues[] = { pitchExtension, rollExtension, aux1, aux2, aux3, aux4, aux5, aux6 };
3003 int16_t outgoingExtensionValues[std::size(incomingExtensionValues)];
3004 for (
size_t i = 0; i < std::size(incomingExtensionValues); i++) {
3005 int16_t scaledValue = 0;
3006 if (!qIsNaN(incomingExtensionValues[i])) {
3007 scaledValue =
static_cast<int16_t
>(incomingExtensionValues[i] * axesScaling);
3008 extensions |= (1 << i);
3010 outgoingExtensionValues[i] = scaledValue;
3012 mavlink_msg_manual_control_pack_chan(
3015 sharedLink->mavlinkChannel(),
3017 static_cast<uint8_t
>(_systemID),
3018 static_cast<int16_t
>(newPitchCommand),
3019 static_cast<int16_t
>(newRollCommand),
3020 static_cast<int16_t
>(newThrustCommand),
3021 static_cast<int16_t
>(newYawCommand),
3024 outgoingExtensionValues[0],
3025 outgoingExtensionValues[1],
3026 outgoingExtensionValues[2],
3027 outgoingExtensionValues[3],
3028 outgoingExtensionValues[4],
3029 outgoingExtensionValues[5],
3030 outgoingExtensionValues[6],
3031 outgoingExtensionValues[7]
3042 qCDebug(VehicleLog) <<
"sendJoystickAuxRcOverrideThreadSafe: primary link gone!";
3046 if (sharedLink->linkConfiguration()->isHighLatency()) {
3050 bool anyEnabledChannel =
false;
3051 for (
bool enabled : channelEnabled) {
3053 anyEnabledChannel =
true;
3058 if (!useRcOverride || !anyEnabledChannel) {
3060 bool expected =
true;
3061 if (!_joystickAuxRcOverrideActive.compare_exchange_strong(expected,
false)) {
3066 mavlink_msg_rc_channels_override_pack_chan(
3069 sharedLink->mavlinkChannel(),
3071 static_cast<uint8_t
>(_systemID),
3072 static_cast<uint8_t
>(_defaultComponentId),
3081 static_cast<uint16_t
>(UINT16_MAX - 1),
3082 static_cast<uint16_t
>(UINT16_MAX - 1),
3096 mavlink_msg_rc_channels_override_pack_chan(
3099 sharedLink->mavlinkChannel(),
3101 static_cast<uint8_t
>(_systemID),
3102 static_cast<uint8_t
>(_defaultComponentId),
3107 channelEnabled[0] ? channelValues[0] :
static_cast<uint16_t
>(0),
3108 channelEnabled[1] ? channelValues[1] :
static_cast<uint16_t
>(0),
3109 channelEnabled[2] ? channelValues[2] :
static_cast<uint16_t
>(0),
3110 channelEnabled[3] ? channelValues[3] :
static_cast<uint16_t
>(0),
3111 channelEnabled[4] ? channelValues[4] :
static_cast<uint16_t
>(UINT16_MAX - 1),
3112 channelEnabled[5] ? channelValues[5] :
static_cast<uint16_t
>(UINT16_MAX - 1),
3122 _joystickAuxRcOverrideActive =
true;
3128 MAV_CMD_DO_DIGICAM_CONTROL,
3137 _defaultComponentId,
3148 [
this, centerCoord]() {
3152 MAV_CMD_DO_SET_GLOBAL_ORIGIN,
3155 0.0f, 0.0f, 0.0f, 0.0f,
3156 centerCoord.latitude(),
3157 centerCoord.longitude(),
3158 static_cast<float>(centerCoord.altitude())
3166 qCDebug(VehicleLog) <<
"setEstimatorOrigin: primary link gone!";
3171 mavlink_msg_set_gps_global_origin_pack_chan(
3174 sharedLink->mavlinkChannel(),
3177 centerCoord.latitude() * 1e7,
3178 centerCoord.longitude() * 1e7,
3179 centerCoord.altitude() * 1e3,
3180 static_cast<float>(qQNaN())
3188 MAV_CMD_START_RX_PAIR,
3196 _timerRevertAllowTakeover.stop();
3197 _timerRevertAllowTakeover.setSingleShot(
true);
3198 _timerRevertAllowTakeover.setInterval(operatorControlTakeoverTimeoutMsecs());
3200 disconnect(&_timerRevertAllowTakeover, &QTimer::timeout,
nullptr,
nullptr);
3202 connect(&_timerRevertAllowTakeover, &QTimer::timeout,
this, [
this](){
3207 _timerRevertAllowTakeover.start();
3212 int safeRequestTimeoutSecs;
3215 if (requestTimeoutSecs >= requestTimeoutSecsMin && requestTimeoutSecs <= requestTimeoutSecsMax) {
3216 safeRequestTimeoutSecs = requestTimeoutSecs;
3222 const MavCmdAckHandlerInfo_t handlerInfo = {&Vehicle::_requestOperatorControlAckHandler,
this,
nullptr,
nullptr};
3225 _defaultComponentId,
3226 MAV_CMD_REQUEST_OPERATOR_CONTROL,
3229 allowOverride ? 1 : 0,
3230 safeRequestTimeoutSecs
3234 if (requestTimeoutSecs > 0) {
3235 requestOperatorControlStartTimer(requestTimeoutSecs * 1000);
3239void Vehicle::_requestOperatorControlAckHandler(
void* resultHandlerData,
int compId,
const mavlink_command_ack_t& ack, MavCmdResultFailureCode_t failureCode)
3245 switch (failureCode) {
3261 if (ack.result == MAV_RESULT_ACCEPTED) {
3262 qCDebug(VehicleLog) <<
"Operator control request accepted";
3264 qCDebug(VehicleLog) <<
"Operator control request rejected";
3268void Vehicle::requestOperatorControlStartTimer(
int requestTimeoutMsecs)
3271 _sendControlRequestAllowed =
false;
3274 _timerRequestOperatorControl.stop();
3275 _timerRequestOperatorControl.setSingleShot(
true);
3276 _timerRequestOperatorControl.setInterval(requestTimeoutMsecs);
3278 disconnect(&_timerRequestOperatorControl, &QTimer::timeout,
nullptr,
nullptr);
3279 connect(&_timerRequestOperatorControl, &QTimer::timeout,
this, [
this](){
3280 _sendControlRequestAllowed =
true;
3283 _timerRequestOperatorControl.start();
3288 mavlink_control_status_t controlStatus;
3289 mavlink_msg_control_status_decode(&message, &controlStatus);
3291 bool updateControlStatusSignals =
false;
3292 if (_gcsControlStatusFlags != controlStatus.flags) {
3293 _gcsControlStatusFlags = controlStatus.flags;
3294 _gcsControlStatusFlags_SystemManager = controlStatus.flags & GCS_CONTROL_STATUS_FLAGS_SYSTEM_MANAGER;
3295 _gcsControlStatusFlags_TakeoverAllowed = controlStatus.flags & GCS_CONTROL_STATUS_FLAGS_TAKEOVER_ALLOWED;
3296 updateControlStatusSignals =
true;
3299 if (_gcsMain != controlStatus.gcs_main) {
3300 _gcsMain = controlStatus.gcs_main;
3301 updateControlStatusSignals =
true;
3304 if (!_firstControlStatusReceived) {
3305 _firstControlStatusReceived =
true;
3306 updateControlStatusSignals =
true;
3309 if (updateControlStatusSignals) {
3315 if (!sendControlRequestAllowed() && _gcsControlStatusFlags_TakeoverAllowed) {
3316 disconnect(&_timerRequestOperatorControl, &QTimer::timeout,
nullptr,
nullptr);
3317 _sendControlRequestAllowed =
true;
3330 mavlink_msg_command_long_decode(&message, &commandLong);
3335 if (commandLong.command == MAV_CMD_REQUEST_OPERATOR_CONTROL) {
3336 _handleCommandRequestOperatorControl(commandLong);
3340int Vehicle::operatorControlTakeoverTimeoutMsecs()
const
3379 MAV_CMD_FLASH_BOOTLOADER,
3391 MAV_CMD_DO_AUX_FUNCTION,
3394 enable ? MAV_CMD_DO_AUX_FUNCTION_SWITCH_LEVEL_HIGH : MAV_CMD_DO_AUX_FUNCTION_SWITCH_LEVEL_LOW);
3413void Vehicle::_createStatusTextHandler()
3423void Vehicle::_onStatusTextFromEvent(uint8_t compid,
int severity,
const QString &text,
const QString &description)
3426 static_cast<MAV_SEVERITY
>(severity), text, description);
3429void Vehicle::_textMessageReceived(MAV_COMPONENT componentid, MAV_SEVERITY severity, QString text, QString description)
3433 qCDebug(VehicleLog) <<
"Dropping message (expected as event):" << text;
3437 bool skipSpoken =
false;
3438 const bool ardupilotPrearm = text.startsWith(QStringLiteral(
"PreArm"));
3439 const bool px4Prearm = text.startsWith(QStringLiteral(
"preflight"), Qt::CaseInsensitive) && (severity >= MAV_SEVERITY::MAV_SEVERITY_CRITICAL);
3440 if (ardupilotPrearm || px4Prearm) {
3441 if (_healthAndArmingChecksSupported(componentid)) {
3442 qCDebug(VehicleLog) <<
"Dropping preflight message (expected as event):" << text;
3447 if (_noisySpokenPrearmMap.contains(text) && _noisySpokenPrearmMap.value(text).msecsTo(QTime::currentTime()) < (10 * 1000)) {
3450 (void) _noisySpokenPrearmMap.insert(text, QTime::currentTime());
3455 bool readAloud =
false;
3457 if (text.startsWith(
"#")) {
3458 (void) text.remove(0, 1);
3460 }
else if (severity <= MAV_SEVERITY::MAV_SEVERITY_NOTICE) {
3464 if (readAloud && !skipSpoken) {
3472void Vehicle::_errorMessageReceived(QString message)
3474 QString vehicleIdPrefix;
3477 vehicleIdPrefix = tr(
"Vehicle %1: ").arg(
id());
3487void Vehicle::_createSigningController()
3497void Vehicle::_createImageProtocolManager()
3502 qgcApp()->qgcImageProvider()->setImage(image, _systemID);
3508 return (_imageProtocolManager ? _imageProtocolManager->
flowImageIndex() : 0);
3516void Vehicle::_createMAVLinkLogManager()
3523 return _mavlinkLogManager;
3531void Vehicle::_createCameraManager()
3533 if (!_cameraManager && _firmwarePlugin) {
3541 if (_cameraManager) {
3545 static QVariantList emptyCameraList;
3546 return emptyCameraList;
3554void Vehicle::_createMAVLinkEventManager()
3556 _eventManager = std::make_unique<MAVLinkEventManager>(
this);
3563 _eventManager->handleEventMessage(msg);
3566bool Vehicle::_healthAndArmingChecksSupported(uint8_t compid)
3568 return _eventManager->healthAndArmingChecksSupported(compid);
3573 return _eventManager->healthAndArmingCheckReport();
3578 _eventManager->setMetadata(compid, metadataJsonFileName);
3580 sendMavCommand(_defaultComponentId, MAV_CMD_RUN_PREARM_CHECKS,
false);
static const QString guided_mode_not_supported_by_vehicle
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
struct __mavlink_command_ack_t mavlink_command_ack_t
struct __mavlink_high_latency2_t mavlink_high_latency2_t
struct __mavlink_command_long_t mavlink_command_long_t
struct __mavlink_obstacle_distance_t mavlink_obstacle_distance_t
#define REQUEST_OPERATOR_CONTROL_ALLOW_TAKEOVER_TIMEOUT_MSECS
const QString guided_mode_not_supported_by_vehicle
void mavlinkMessageReceived(const mavlink_message_t &message)
static ADSBVehicleManager * instance()
void load(const QString &json_file, const QJsonDocument &metadata)
void say(const QString &text, TextMods textMods=TextMod::None)
static AudioOutput * instance()
void handleMessageForFactGroupCreation(Vehicle *vehicle, const mavlink_message_t &message)
Allows for creation/updating of dynamic FactGroups based on incoming messages.
Used to group Facts together into an object hierarachy.
const QMap< QString, FactGroup * > & factGroups() const
Q_INVOKABLE Fact * getFact(const QString &name) const
QStringList factNames() const
void _addFactGroup(FactGroup *factGroup, const QString &name)
Q_INVOKABLE FactGroup * getFactGroup(const QString &name) const
QStringList factGroupNames() const
Q_INVOKABLE void setLiveUpdates(bool liveUpdates)
Turning on live updates will allow value changes to flow through as they are received.
A Fact is used to hold a single value within the system.
FactMetaData * metaData()
void rawValueChanged(const QVariant &value)
void setRawValue(const QVariant &value)
QString cookedValueString() const
QVariant rawValue() const
FirmwarePlugin * firmwarePluginForAutopilot(MAV_AUTOPILOT firmwareType, MAV_TYPE vehicleType)
static FirmwarePluginManager * instance()
virtual QString motorDetectionFlightMode() const
Returns the flight mode for Motor Detection.
virtual QString pauseFlightMode() const
Returns The flight mode which indicates the vehicle is paused.
virtual void guidedModeChangeEquivalentAirspeedMetersSecond(Vehicle *vehicle, double airspeed_equiv) const
virtual void guidedModeChangeAltitude(Vehicle *vehicle, double altitudeChange, bool pauseVehicle)
virtual void startMission(Vehicle *vehicle) const
Command the vehicle to start the mission.
virtual bool multiRotorCoaxialMotors(Vehicle *) const
virtual double minimumEquivalentAirspeed(Vehicle *) const
virtual const QVariantList & toolIndicators(const Vehicle *vehicle)
virtual void guidedModeChangeGroundSpeedMetersSecond(Vehicle *vehicle, double groundspeed) const
virtual bool setFlightMode(const QString &flightMode, uint8_t *base_mode, uint32_t *custom_mode) const
@ SetFlightModeCapability
FirmwarePlugin::setFlightMode method is supported.
virtual QString vehicleImageOutline(const Vehicle *) const
Return the resource file which contains the vehicle icon used in the flight view when the view is lig...
virtual void guidedModeTakeoff(Vehicle *vehicle, double takeoffAltRel) const
Command vehicle to takeoff from current location to the specified height.
virtual bool isCapable(const Vehicle *, FirmwareCapabilities) const
virtual double maximumEquivalentAirspeed(Vehicle *) const
virtual QString missionFlightMode() const
Returns the flight mode for running missions.
virtual void adjustMetaData(MAV_TYPE, FactMetaData *)
virtual bool adjustIncomingMavlinkMessage(Vehicle *, mavlink_message_t *)
virtual bool fixedWingAirSpeedLimitsAvailable(Vehicle *) const
virtual void guidedModeChangeHeading(Vehicle *vehicle, const QGeoCoordinate &headingCoord) const
Command vehicle to rotate towards specified location.
virtual QString smartRTLFlightMode() const
Returns the flight mode for Smart RTL.
virtual bool guidedModeGotoLocation(Vehicle *vehicle, const QGeoCoordinate &gotoCoord, double forwardFlightLoiterRadius=0.0) const
virtual bool multiRotorXConfig(Vehicle *) const
virtual QString takeControlFlightMode() const
Returns the flight mode to use when the operator wants to take back control from autonomouse flight.
virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode) const
virtual QString vehicleImageOpaque(const Vehicle *) const
Return the resource file which contains the vehicle icon used in the flight view when the view is dar...
virtual void startTakeoff(Vehicle *vehicle) const
Command the vehicle to start a takeoff.
virtual void pauseVehicle(Vehicle *vehicle) const
virtual QVariant expandedToolbarIndicatorSource(const Vehicle *, const QString &) const
virtual bool mulirotorSpeedLimitsAvailable(Vehicle *) const
int versionCompare(const Vehicle *vehicle, const QString &compare) const
virtual bool hasGripper(const Vehicle *) const
virtual QString landFlightMode() const
Returns the flight mode for Land.
virtual QString gotoFlightMode() const
Returns the flight mode which the vehicle will be in if it is performing a goto location.
virtual Autotune * createAutotune(Vehicle *vehicle) const
Creates Autotune object.
virtual QStringList flightModes(Vehicle *) const
virtual AutoPilotPlugin * autopilotPlugin(Vehicle *vehicle) const
virtual void guidedModeRTL(Vehicle *vehicle, bool smartRTL) const
Command vehicle to return to launch.
virtual QList< MAV_CMD > supportedMissionCommands(QGCMAVLinkTypes::VehicleClass_t) const
List of supported mission commands. Empty list for all commands supported.
virtual QString autoDisarmParameter(Vehicle *) const
virtual QString stabilizedFlightMode() const
Returns the flight mode for Stabilized.
virtual void adjustOutgoingMavlinkMessageThreadSafe(Vehicle *, LinkInterface *, mavlink_message_t *)
void toolIndicatorsChanged()
virtual void setGuidedMode(Vehicle *vehicle, bool guidedMode) const
Set guided flight mode.
virtual QString followFlightMode() const
Returns the flight mode which the vehicle will be for follow me.
virtual uint32_t highLatencyCustomModeTo32Bits(uint16_t hlCustomMode) const
Convert from HIGH_LATENCY2.custom_mode value to correct 32 bit value.
virtual QGCCameraManager * createCameraManager(Vehicle *vehicle) const
Creates vehicle camera manager.
virtual QMap< QString, FactGroup * > * factGroups()
Returns a pointer to a dictionary of firmware-specific FactGroups.
virtual void initializeVehicle(Vehicle *)
Called when Vehicle is first created to perform any firmware specific setup.
virtual bool MAV_CMD_DO_SET_MODE_is_supported() const
returns true if this flight stack supports MAV_CMD_DO_SET_MODE
virtual QString rtlFlightMode() const
Returns the flight mode for RTL.
virtual double maximumHorizontalSpeedMultirotorMetersSecond(Vehicle *) const
virtual void guidedModeLand(Vehicle *vehicle) const
Command vehicle to land at current location.
virtual bool sendHomePositionToVehicle() const
virtual bool isGuidedMode(const Vehicle *) const
Returns whether the vehicle is in guided mode or not.
virtual double minimumTakeoffAltitudeMeters(Vehicle *) const
virtual QString getHobbsMeter(Vehicle *vehicle) const
gets hobbs meter from autopilot. This should be reimplmeented for each firmware
This is the base class for firmware specific geofence managers.
void error(int errorCode, const QString &errorMsg)
Supports the Mavlink image transmission protocol (https://mavlink.io/en/services/image_transmission....
uint32_t flowImageIndex() const
void flowImageIndexChanged(uint32_t index)
void imageReady(const QImage &image)
bool activeJoystickEnabledForActiveVehicle() const
static JoystickManager * instance()
The link interface defines the interface for all links used to communicate with the ground station ap...
void sendMessageThreadSafe(mavlink_message_t &message)
virtual bool isConnected() const =0
void statusTextMessageFromEvent(uint8_t compid, int severity, const QString &text, const QString &description)
static int getComponentId()
void mavlinkMessageStatus(int sysid, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent)
void messageReceived(LinkInterface *link, const mavlink_message_t &message)
static MAVLinkProtocol * instance()
Allows to configure a set of mavlink streams to a specific rate, and restore back to default.
Owns the COMMAND_LONG / COMMAND_INT send/retry/ack pipeline for a single Vehicle.
void sendCommandInt(int compId, MAV_CMD command, MAV_FRAME frame, bool showError, float param1, float param2, float param3, float param4, double param5, double param6, float param7)
static QString failureCodeToString(MavCmdResultFailureCode_t failureCode)
void commandResult(int vehicleId, int targetComponent, int command, int ackResult, int failureCode)
Emitted for every terminal ack that has no user-provided resultHandler.
void sendCommandIntWithHandler(const MavCmdAckHandlerInfo_t *ackHandlerInfo, int compId, MAV_CMD command, MAV_FRAME frame, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, double param5=0.0, double param6=0.0, float param7=0.0f)
void sendCommandWithHandler(const MavCmdAckHandlerInfo_t *ackHandlerInfo, int compId, MAV_CMD command, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
void handleCommandAck(const mavlink_message_t &message, const mavlink_command_ack_t &ack)
Process a COMMAND_ACK — match it to a pending entry and fire callbacks.
void sendCommandDelayed(int compId, MAV_CMD command, bool showError, int milliseconds, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
bool isPending(int targetCompId, MAV_CMD command) const
True if a matching (targetCompId, command) is already queued or awaiting ack.
static void showCommandAckError(const mavlink_command_ack_t &ack)
void sendCommand(int compId, MAV_CMD command, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
int findEntryIndex(int targetCompId, MAV_CMD command) const
Index of a matching entry in the pending queue, or -1. Exposed for test use.
void sendCommandIntWithLambdaFallback(std::function< void()> lambda, int compId, MAV_CMD command, MAV_FRAME frame, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, double param5=0.0, double param6=0.0, float param7=0.0f)
void sendCommandWithLambdaFallback(std::function< void()> lambda, int compId, MAV_CMD command, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
Tracks per-component MAVLink message intervals and mediates SET_MESSAGE_INTERVAL commands plus MESSAG...
void handleMessageInterval(const mavlink_message_t &message)
void mavlinkMsgIntervalsChanged(uint8_t compid, uint16_t msgId, int32_t rate)
void setMessageRate(uint8_t compId, uint16_t msgId, int32_t rate)
int32_t getMessageRate(uint8_t compId, uint16_t msgId)
static MissionCommandTree * instance()
QString rawName(MAV_CMD command) const
Returns the raw name for the specified command.
int currentIndex(void) const
Current mission item as reported by MISSION_CURRENT.
static MultiVehicleManager * instance()
Vehicle * activeVehicle() const
void parameterReadyVehicleAvailableChanged(bool parameterReadyVehicleAvailable)
void activeVehicleChanged(Vehicle *activeVehicle)
Fact * getParameter(int componentId, const QString ¶mName)
void parametersReadyChanged(bool parametersReady)
static constexpr int defaultComponentId
void loadProgressChanged(float value)
void currentIndexChanged(int currentIndex)
void sendComplete(bool error)
void newMissionItemsAvailable(bool removeAllRequested)
const QList< MissionItem * > & missionItems(void)
void error(int errorCode, const QString &errorMsg)
static void sendPlanToVehicle(Vehicle *vehicle, const QString &filename)
const QVariantList & cameraList() const
void showAdvancedUIChanged(bool showAdvancedUI)
static QGCCorePlugin * instance()
static bool isMultiRotor(MAV_TYPE mavType)
static uint32_t highLatencyFailuresToMavSysStatus(mavlink_high_latency2_t &highLatency2)
static QString mavTypeToString(MAV_TYPE mavType)
static int motorCount(MAV_TYPE mavType, uint8_t frameType=0)
static bool isAirship(MAV_TYPE mavType)
@ CalibrationAPMPressureAirspeed
@ CalibrationAPMAccelSimple
@ CalibrationAPMCompassMot
@ CalibrationAPMPreFlight
static bool isSpacecraft(MAV_TYPE mavType)
static QString firmwareClassToString(FirmwareClass_t firmwareClass)
static bool isVTOL(MAV_TYPE mavType)
static QString firmwareVersionTypeToString(FIRMWARE_VERSION_TYPE firmwareVersionType)
static bool isFixedWing(MAV_TYPE mavType)
static QString mavResultToString(uint8_t result)
static bool isSub(MAV_TYPE mavType)
static QString vehicleClassToInternalString(VehicleClass_t vehicleClass)
static bool isRoverBoat(MAV_TYPE mavType)
The QGCMapCircle represents a circular area which can be displayed on a Map control.
static QGCPositionManager * instance()
QGeoCoordinate gcsPosition() const
void gcsPositionChanged(QGeoCoordinate gcsPosition)
This is a QGeoCoordinate within a QObject such that it can be used on a QmlObjectListModel.
static QGCPressure * instance()
void progressUpdate(float progress)
int count() const override final
Radio link telemetry decoded from MAVLINK_MSG_ID_RADIO_STATUS.
This is the base class for firmware specific rally point managers. A rally point manager is responsib...
void error(int errorCode, const QString &errorMsg)
void mavlinkMessageReceived(mavlink_message_t &message)
Coordinates MAV_CMD_REQUEST_MESSAGE workflows: per-component queueing, ack/message correlation,...
void handleReceivedMessage(const mavlink_message_t &message)
static QString failureCodeToString(RequestMessageResultHandlerFailureCode_t failureCode)
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)
void stop()
Clear pending state without firing callbacks (used during vehicle shutdown).
Provides access to all app settings.
static SettingsManager * instance()
VideoSettings * videoSettings() const
FlyViewSettings * flyViewSettings() const
MavlinkSettings * mavlinkSettings() const
void availableModesMonitorReceived(uint8_t seq)
bool messageTypeNone() const
bool messageTypeError() const
void handleHTMLEscapedTextMessage(MAV_COMPONENT componentid, MAV_SEVERITY severity, const QString &text, const QString &description)
bool messageTypeNormal() const
void newErrorMessage(QString message)
void resetErrorLevelMessages()
void mavlinkMessageReceived(const mavlink_message_t &message)
void messageCountChanged(uint32_t newCount)
void textMessageReceived(MAV_COMPONENT componentid, MAV_SEVERITY severity, QString text, QString description)
uint32_t messageCount() const
void newFormattedMessage(QString message)
QString formattedMessages() const
void messageTypeChanged()
bool messageTypeWarning() const
Class which represents sensor info from the SYS_STATUS mavlink message.
bool mavlinkMessageReceived(const mavlink_message_t &message)
Coordinates the three terrain-query workflows attached to a Vehicle:
void updateAltAboveTerrain()
void roiWithTerrain(const QGeoCoordinate &coord)
void sendROICommand(const QGeoCoordinate &coord, MAV_FRAME frame, float altitude)
void doSetHomeWithTerrain(const QGeoCoordinate &coord)
Fact _headingFromHomeFact
Fact * altitudeRelative()
Fact _altitudeRelativeFact
void handleMessage(Vehicle *vehicle, const mavlink_message_t &message) override
Allows a FactGroup to parse incoming messages and fill in values.
void updateRCRSSI(uint8_t rssi)
Fact _missionItemIndexFact
Fact _altitudeTuningSetpointFact
Fact _headingToNextWPFact
bool _altitudeMessageAvailable
void bindToGps(VehicleGPSFactGroup *gps1, VehicleGPSFactGroup *gps2)
WeakLinkInterfacePtr primaryLink() const
void mavlinkMessageReceived(LinkInterface *link, const mavlink_message_t &message)
bool containsLink(LinkInterface *link)
void update(mavlink_obstacle_distance_t *message)
Per-vehicle signing facade. Owns the wiring between Vehicle and the active SigningController (which l...
bool changeHeading() const
bool pauseVehicle() const
Q_INVOKABLE void triggerSimpleCamera(void)
Trigger camera using MAV_CMD_DO_DIGICAM_CONTROL command.
bool isInitialConnectComplete() const
Q_INVOKABLE void guidedModeChangeAltitude(double altitudeChange, bool pauseVehicle)
void _setLanding(bool landing)
Vehicle(LinkInterface *link, int vehicleId, int defaultComponentId, MAV_AUTOPILOT firmwareType, MAV_TYPE vehicleType, QObject *parent=nullptr)
Q_INVOKABLE void motorInterlock(bool enable)
Command vehicle to Enable/Disable Motor Interlock.
Q_INVOKABLE void virtualTabletJoystickValue(double roll, double pitch, double yaw, double thrust)
int32_t getMessageRate(uint8_t compId, uint16_t msgId)
VehicleDistanceSensorFactGroup * _distanceSensorFactGroup
TerrainProtocolHandler * _terrainProtocolHandler
void firmwareTypeChanged()
QGCMAVLink::VehicleClass_t vehicleClass(void) const
void setInitialGCSPressure(qreal pressure)
Q_INVOKABLE void flashBootloader()
void sensorsPresentBitsChanged(int sensorsPresentBits)
void defaultHoverSpeedChanged(double hoverSpeed)
friend class InitialConnectStateMachine
const QString _vibrationFactGroupName
bool _multirotor_speed_limits_available
void gcsControlStatusChanged()
void defaultCruiseSpeedChanged(double cruiseSpeed)
bool messageTypeError() const
const QString _gpsFactGroupName
FactGroup * localPositionFactGroup()
void setActuatorsMetadata(uint8_t compid, const QString &metadataJsonFileName, const QJsonDocument &metadataJson)
void haveMRSpeedLimChanged()
FactGroup * vibrationFactGroup()
void sendMavCommandWithLambdaFallback(std::function< void()> lambda, int compId, MAV_CMD command, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
BatteryFactGroupListModel * _batteryFactGroupListModel
void sendMavCommand(int compId, MAV_CMD command, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
VehicleLocalPositionFactGroup * _localPositionFactGroup
const QString _hygrometerFactGroupName
void messagesLostChanged()
Q_INVOKABLE void rebootVehicle()
Reboot vehicle.
FactGroup * gpsAggregateFactGroup()
VehicleRPMFactGroup * _rpmFactGroup
const QString _localPositionFactGroupName
void vtolInFwdFlightChanged(bool vtolInFwdFlight)
QString missionFlightMode() const
void readyToFlyAvailableChanged(bool readyToFlyAvailable)
void forceInitialPlanRequestComplete()
void isROIEnabledChanged()
Q_INVOKABLE void guidedModeOrbit(const QGeoCoordinate ¢erCoord, double radius, double amslAltitude)
const QString _terrainFactGroupName
const QString _temperatureFactGroupName
void _offlineVehicleTypeSettingChanged(QVariant varVehicleType)
Q_INVOKABLE void guidedModeTakeoff(double altitudeRelative)
Command vehicle to takeoff from current location.
Q_INVOKABLE void sendGripperAction(GRIPPER_ACTIONS gripperOption)
QString flightMode() const
static QString mavCmdResultFailureCodeToString(MavCmdResultFailureCode_t failureCode)
QString stabilizedFlightMode() const
const QVariantList & staticCameraList() const
void requestOperatorControlReceived(int sysIdRequestingControl, int allowTakeover, int requestTimeoutSecs)
Q_INVOKABLE QVariant expandedToolbarIndicatorSource(const QString &indicatorName)
void sendJoystickAuxRcOverrideThreadSafe(const std::array< uint16_t, kAuxRcOverrideChannelCount > &channelValues, const std::array< bool, kAuxRcOverrideChannelCount > &channelEnabled, bool useRcOverride)
void setSoloFirmware(bool soloFirmware)
void requestDataStream(MAV_DATA_STREAM stream, uint16_t rate, bool sendMultiple=true)
FactGroup * rpmFactGroup()
QGeoCoordinate homePosition()
const QString _estimatorStatusFactGroupName
const QString _radioStatusFactGroupName
QString vehicleImageOutline() const
MissionManager * _missionManager
VehicleLocalPositionSetpointFactGroup * _localPositionSetpointFactGroup
void textMessageReceived(int sysid, int componentid, int severity, QString text, QString description)
void initialPlanRequestCompleteChanged(bool initialPlanRequestComplete)
Q_INVOKABLE double minimumEquivalentAirspeed()
const QString _clockFactGroupName
Q_INVOKABLE void stopGuidedModeROI()
void firmwareCustomVersionChanged()
QString pauseFlightMode() const
QString prearmError() const
EscStatusFactGroupListModel * _escStatusFactGroupListModel
Q_INVOKABLE void guidedModeROI(const QGeoCoordinate ¢erCoord)
const QString _efiFactGroupName
void inFwdFlightChanged()
void flyingChanged(bool flying)
void setFirmwarePluginInstanceData(FirmwarePluginInstanceData *firmwarePluginInstanceData)
Q_INVOKABLE double maximumHorizontalSpeedMultirotorMetersSecond()
void sendMessageMultiple(mavlink_message_t message)
void capabilityBitsChanged(uint64_t capabilityBits)
bool messageTypeNone() const
void _setHomePosition(QGeoCoordinate &homeCoord)
VehicleClockFactGroup * _clockFactGroup
uint64_t capabilityBits() const
Q_INVOKABLE void abortLanding(double climbOutAltitude)
Command vehicle to abort landing.
void setGuidedMode(bool guidedMode)
void readyToFlyChanged(bool readyToFy)
QString firmwareVersionTypeString() const
QString landFlightMode() const
static void showCommandAckError(const mavlink_command_ack_t &ack)
void newFormattedMessage(QString formattedMessage)
MAV_TYPE vehicleType() const
VehicleLinkManager * vehicleLinkManager()
void cameraManagerChanged()
Q_INVOKABLE void sendParamMapRC(const QString ¶mName, double scale, double centerValue, int tuningID, double minValue, double maxValue)
Sends PARAM_MAP_RC message to vehicle.
HealthAndArmingCheckReport * healthAndArmingCheckReport()
void armedChanged(bool armed)
void firmwareVersionChanged()
FactGroup * distanceSensorFactGroup()
void logEntry(uint32_t time_utc, uint32_t size, uint16_t id, uint16_t num_logs, uint16_t last_log_num)
void sendControlRequestAllowedChanged(bool sendControlRequestAllowed)
FactGroup * generatorFactGroup()
void rcChannelsRawChanged(QVector< int > channelValues)
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
void sendMavCommandInt(int compId, MAV_CMD command, MAV_FRAME frame, bool showError, float param1, float param2, float param3, float param4, double param5, double param6, float param7)
Q_INVOKABLE double minimumTakeoffAltitudeMeters()
InitialConnectStateMachine * _initialConnectStateMachine
void sensorsParametersResetAck(bool success)
void sendMavCommandDelayed(int compId, MAV_CMD command, bool showError, int milliseconds, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
void setEstimatorOrigin_SET_GPS_GLOBAL_ORIGIN(const QGeoCoordinate ¢erCoord)
Fallback for setEstimatorOrigin which sends the deprecated SET_GPS_GLOBAL_ORIGIN message.
const QString _distanceSensorFactGroupName
Q_INVOKABLE double maximumEquivalentAirspeed()
@ ModeAltitudeAndAirspeed
@ ModeVelocityAndPosition
void setPrearmError(const QString &prearmError)
VehicleVibrationFactGroup * _vibrationFactGroup
void setFirmwareCustomVersion(int majorVersion, int minorVersion, int patchVersion)
Q_INVOKABLE void startTimerRevertAllowTakeover()
VehicleGeneratorFactGroup * _generatorFactGroup
const QString _generatorFactGroupName
void messagesSentChanged()
Q_INVOKABLE void sendPlan(QString planFile)
bool vtolInFwdFlight() const
Q_INVOKABLE void startMission()
bool isMavCommandPending(int targetCompId, MAV_CMD command)
isMavCommandPending Query whether the specified MAV_CMD is in queue to be sent or has already been se...
void capabilitiesKnownChanged(bool capabilitiesKnown)
Q_INVOKABLE void requestOperatorControl(bool allowOverride, int requestTimeoutSecs=0)
void rcChannelsClampedChanged(QVector< int > channelValues)
VehicleEstimatorStatusFactGroup * _estimatorStatusFactGroup
VehicleTemperatureFactGroup * _temperatureFactGroup
bool soloFirmware() const
void coordinateChanged(QGeoCoordinate coordinate)
QString vehicleImageOpaque() const
float _altitudeTuningOffset
Q_INVOKABLE void setPIDTuningTelemetryMode(PIDTuningTelemetryMode mode)
void mavlinkLogData(Vehicle *vehicle, uint8_t target_system, uint8_t target_component, uint16_t sequence, uint8_t first_message, QByteArray data, bool acked)
Q_INVOKABLE void emergencyStop()
Command vehicle to kill all motors no matter what state.
void updateFlightDistance(double distance)
const QString _gpsAggregateFactGroupName
Q_INVOKABLE bool guidedModeGotoLocation(const QGeoCoordinate &gotoCoord, double forwardFlightLoiterRadius=0.0f)
void pairRX(int rxType, int rxSubType)
const QString _setpointFactGroupName
Q_INVOKABLE void setCurrentMissionSequence(int seq)
Alter the current mission item on the vehicle.
FactGroup * gps2FactGroup()
void toolIndicatorsChanged()
void sensorsUnhealthyBitsChanged(int sensorsUnhealthyBits)
void landingChanged(bool landing)
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
VehicleWindFactGroup * _windFactGroup
const QString _rpmFactGroupName
FactGroup * hygrometerFactGroup()
static const MAV_AUTOPILOT MAV_AUTOPILOT_TRACK
Q_INVOKABLE void startTakeoff()
Q_INVOKABLE void resetAllMessages()
VehicleHygrometerFactGroup * _hygrometerFactGroup
void setFlightMode(const QString &flightMode)
bool messageTypeWarning() const
Q_INVOKABLE void sendCommand(int compId, int command, bool showError, double param1=0.0, double param2=0.0, double param3=0.0, double param4=0.0, double param5=0.0, double param6=0.0, double param7=0.0)
Same as sendMavCommand but available from Qml.
void loadProgressChanged(float value)
QString smartRTLFlightMode() const
QString followFlightMode() const
bool _fixed_wing_airspeed_limits_available
Q_INVOKABLE void motorTest(int motor, int percent, int timeoutSecs, bool showError)
void mavlinkMessageReceived(const mavlink_message_t &message)
void setMessageRate(uint8_t compId, uint16_t msgId, int32_t rate)
Q_INVOKABLE void resetCounters()
< Flight mode vehicle is in while performing goto
const QVariantList & toolIndicators()
void _offlineFirmwareTypeSettingChanged(QVariant varFirmwareType)
FactGroup * localPositionSetpointFactGroup()
Q_INVOKABLE void guidedModeChangeEquivalentAirspeedMetersSecond(double airspeed)
QmlObjectListModel * escs()
void guidedModeChanged(bool guidedMode)
FactGroup * efiFactGroup()
void setEventsMetadata(uint8_t compid, const QString &metadataJsonFileName)
QString formattedMessages() const
int _findMavCommandListEntryIndex(int targetCompId, MAV_CMD command)
Test-only helper: forwards to MavCommandQueue::findEntryIndex.
QObject * sysStatusSensorInfo()
QString motorDetectionFlightMode() const
Q_INVOKABLE void resetErrorLevelMessages()
void sendMavCommandIntWithLambdaFallback(std::function< void()> lambda, int compId, MAV_CMD command, MAV_FRAME frame, bool showError, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, double param5=0.0, double param6=0.0, float param7=0.0f)
void orbitActiveChanged(bool orbitActive)
bool messageTypeNormal() const
void allSensorsHealthyChanged(bool allSensorsHealthy)
Q_INVOKABLE void guidedModeRTL(bool smartRTL)
Command vehicle to return to launch.
VehicleGPS2FactGroup * _gps2FactGroup
void trackFirmwareVehicleTypeChanges(void)
Q_INVOKABLE void landingGearDeploy()
Command vichecle to deploy landing gear.
void armedPositionChanged()
VehicleEFIFactGroup * _efiFactGroup
static QString requestMessageResultHandlerFailureCodeToString(RequestMessageResultHandlerFailureCode_t failureCode)
RemoteIDManager * _remoteIDManager
Q_INVOKABLE void doSetHome(const QGeoCoordinate &coord)
Set home from flight map coordinate.
void stopUAVCANBusConfig(void)
void soloFirmwareChanged(bool soloFirmware)
uint32_t flowImageIndex() const
void homePositionChanged(const QGeoCoordinate &homePosition)
QMap< uint8_t, uint8_t > _lowestBatteryChargeStateAnnouncedMap
FactGroup * radioStatusFactGroup()
Q_INVOKABLE void pauseVehicle()
void stopTrackingFirmwareVehicleTypeChanges(void)
FactGroup * windFactGroup()
void flightModesChanged()
const QString _gps2FactGroupName
FactGroup * temperatureFactGroup()
Q_INVOKABLE void closeVehicle()
Removes the vehicle from the system.
void flightModeChanged(const QString &flightMode)
void flowImageIndexChanged()
void roiCoordChanged(const QGeoCoordinate ¢erCoord)
Q_INVOKABLE void clearAllParamMapRC(void)
Clears all PARAM_MAP_RC settings from vehicle.
void messageTypeChanged()
FactGroup * estimatorStatusFactGroup()
Q_INVOKABLE void setEstimatorOrigin(const QGeoCoordinate ¢erCoord)
void setVtolInFwdFlight(bool vtolInFwdFlight)
Q_INVOKABLE void guidedModeChangeGroundSpeedMetersSecond(double groundspeed)
int defaultComponentId() const
void setInitialGCSTemperature(qreal temperature)
void mavlinkStatusChanged()
MAVLinkLogManager * mavlinkLogManager() const
Q_INVOKABLE void clearMessages()
FactGroup * setpointFactGroup()
void sendJoystickDataThreadSafe(float roll, float pitch, float yaw, float thrust, quint16 buttons, quint16 buttons2, float pitchExtension, float rollExtension, float aux1, float aux2, float aux3, float aux4, float aux5, float aux6)
QmlObjectListModel * cameraTriggerPoints()
GeoFenceManager * _geoFenceManager
bool flightModeSetAvailable()
ParameterManager * parameterManager()
VehicleGPSFactGroup * _gpsFactGroup
void sensorsHealthBitsChanged(int sensorsHealthBits)
void _setFlying(bool flying)
Q_INVOKABLE void guidedModeChangeHeading(const QGeoCoordinate &headingCoord)
QString takeControlFlightMode() const
void messagesReceivedChanged()
const QString _localPositionSetpointFactGroupName
void setOfflineEditingDefaultComponentId(int defaultComponentId)
Sets the default component id for an offline editing vehicle.
void setFirmwareVersion(int majorVersion, int minorVersion, int patchVersion, FIRMWARE_VERSION_TYPE versionType=FIRMWARE_VERSION_TYPE_OFFICIAL)
QString rtlFlightMode() const
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)
QGeoCoordinate coordinate()
void startCalibration(QGCMAVLink::CalibrationType calType)
QVector< int > _servoOutputRawValues
QString firmwareTypeString() const
FactGroup * clockFactGroup()
void stopCalibration(bool showError)
void messageCountChanged()
friend class VehicleLinkManager
QmlObjectListModel * batteries()
void haveFWSpeedLimChanged()
RallyPointManager * _rallyPointManager
void startUAVCANBusConfig(void)
RadioStatusFactGroup * _radioStatusFactGroup
QString gotoFlightMode() const
void sendMavCommandIntWithHandler(const MavCmdAckHandlerInfo_t *ackHandlerInfo, int compId, MAV_CMD command, MAV_FRAME frame, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, double param5=0.0f, double param6=0.0f, float param7=0.0f)
Q_INVOKABLE void landingGearRetract()
Command vichecle to retract landing gear.
VehicleSupports * supports()
const QString _windFactGroupName
void mavCommandResult(int vehicleId, int targetComponent, int command, int ackResult, int failureCode)
VehicleGPSAggregateFactGroup * _gpsAggregateFactGroup
FactGroup * gpsFactGroup()
void sensorsEnabledBitsChanged(int sensorsEnabledBits)
class FirmwarePluginInstanceData * firmwarePluginInstanceData()
VehicleSetpointFactGroup * _setpointFactGroup
Q_INVOKABLE int versionCompare(const QString &compare) const
Used to check if running current version is equal or higher than the one being compared.
TerrainFactGroup * _terrainFactGroup
Q_INVOKABLE void forceArm()
void requiresGpsFixChanged()
void setArmed(bool armed, bool showError)
QStringList flightModes()
void mavlinkMsgIntervalsChanged(uint8_t compid, uint16_t msgId, int32_t rate)
FactGroup * terrainFactGroup()
void mavlinkSerialControl(uint8_t device, uint8_t flags, uint16_t timeout, uint32_t baudrate, QByteArray data)
Q_INVOKABLE QString vehicleClassInternalName() const
VehicleLinkManager * _vehicleLinkManager
void servoOutputsChanged(QVector< int > servoValues)
TerrainQueryCoordinator * _terrainQueryCoordinator
void prearmErrorChanged(const QString &prearmError)
void vehicleTypeChanged()
Q_INVOKABLE void guidedModeLand()
Command vehicle to land at current location.
void sendMavCommandWithHandler(const MavCmdAckHandlerInfo_t *ackHandlerInfo, int compId, MAV_CMD command, float param1=0.0f, float param2=0.0f, float param3=0.0f, float param4=0.0f, float param5=0.0f, float param6=0.0f, float param7=0.0f)
Sends the command and calls the callback with the result.
StandardModes * _standardModes
friend class GimbalController
QString vehicleTypeString() const
void logData(uint32_t ofs, uint16_t id, uint8_t count, const uint8_t *data)
static VideoManager * instance()
Q_INVOKABLE void stopVideo()
static constexpr const char * videoSourceUDPH264
static constexpr const char * videoDisabled
bool fuzzyCompare(double value1, double value2)
Returns true if the two values are equal or close. Correctly handles 0 and NaN values.
void showCriticalVehicleMessage(const QString &message)
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.
Callback info bundle for sendMavCommandWithHandler.
MavCmdResultHandler resultHandler
nullptr for no handler
MavCmdResultFailureCode_t
@ MavCmdResultFailureDuplicateCommand
Unable to send command since duplicate is already being waited on for response.
@ MavCmdResultCommandResultOnly
commandResult specifies full success/fail info
@ MavCmdResultFailureNoResponseToCommand
No response from vehicle to command.
RequestMessageResultHandlerFailureCode_t