QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
FirmwarePlugin.cc
Go to the documentation of this file.
1#include "FirmwarePlugin.h"
2#include "AutoPilotPlugin.h"
3#include "Autotune.h"
5#include "MAVLinkLib.h"
6#include "MAVLinkProtocol.h"
7#include "ParameterMetaData.h"
8#include "AppMessages.h"
9#include "QGCApplication.h"
10#include "QGCCameraManager.h"
11#include "QGCFileDownload.h"
12#include "QGCLoggingCategory.h"
13#include "Vehicle.h"
14#include "VehicleLinkManager.h"
16#include "VehicleComponent.h"
17
18#include "QGCCompression.h"
19#include "QGCFileHelper.h"
20
21#include <QtCore/QDir>
22#include <QtCore/QFile>
23#include <QtCore/QRegularExpression>
24#include <QtCore/QStandardPaths>
25#include <QtCore/QThread>
26
27QGC_LOGGING_CATEGORY(FirmwarePluginLog, "FirmwarePlugin.FirmwarePlugin")
28
29static const QString guided_mode_not_supported_by_vehicle = QObject::tr("Guided mode not supported by Vehicle.");
30
32 : QObject(parent)
33{
34 qCDebug(FirmwarePluginLog) << this;
35}
36
38{
39 qCDebug(FirmwarePluginLog) << this;
40}
41
43{
44 return new GenericAutoPilotPlugin(vehicle, vehicle);
45}
46
47QString FirmwarePlugin::flightMode(uint8_t base_mode, uint32_t custom_mode) const
48{
49 Q_UNUSED(custom_mode);
50
51 struct Bit2Name {
52 const uint8_t baseModeBit;
53 const char *name;
54 };
55
56 static constexpr Bit2Name rgBit2Name[] = {
57 { MAV_MODE_FLAG_MANUAL_INPUT_ENABLED, "Manual" },
58 { MAV_MODE_FLAG_STABILIZE_ENABLED, "Stabilize" },
59 { MAV_MODE_FLAG_GUIDED_ENABLED, "Guided" },
60 { MAV_MODE_FLAG_AUTO_ENABLED, "Auto" },
61 { MAV_MODE_FLAG_TEST_ENABLED, "Test" },
62 };
63
64 QString flightMode;
65 if (base_mode == 0) {
66 flightMode = "PreFlight";
67 } else if (base_mode & MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) {
68 flightMode = _modeEnumToString.value(custom_mode, QStringLiteral("Custom:0x%1").arg(custom_mode, 0, 16));
69 } else {
70 for (size_t i = 0; i < std::size(rgBit2Name); i++) {
71 if (base_mode & rgBit2Name[i].baseModeBit) {
72 if (i != 0) {
73 flightMode += " ";
74 }
75 flightMode += rgBit2Name[i].name;
76 }
77 }
78 }
79
80 return flightMode;
81}
82
83bool FirmwarePlugin::setFlightMode(const QString &flightMode, uint8_t *base_mode, uint32_t *custom_mode) const
84{
85 Q_UNUSED(flightMode);
86 Q_UNUSED(base_mode);
87 Q_UNUSED(custom_mode);
88
89 qCWarning(FirmwarePluginLog) << "FirmwarePlugin::setFlightMode called on base class, not supported";
90
91 return false;
92}
93
95{
96 switch (vehicleClass) {
98 return QStringLiteral(":/json/MavCmdInfoCommon.json");
100 return QStringLiteral(":/json/MavCmdInfoFixedWing.json");
102 return QStringLiteral(":/json/MavCmdInfoMultiRotor.json");
104 return QStringLiteral(":/json/MavCmdInfoVTOL.json");
106 return QStringLiteral(":/json/MavCmdInfoSub.json");
108 return QStringLiteral(":/json/MavCmdInfoRover.json");
109 default:
110 qCWarning(FirmwarePluginLog) << "FirmwarePlugin::missionCommandOverrides called with bad VehicleClass_t:" << vehicleClass;
111 return QString();
112 }
113}
114
115void FirmwarePlugin::setGuidedMode(Vehicle *vehicle, bool guidedMode) const
116{
117 Q_UNUSED(vehicle);
118 Q_UNUSED(guidedMode);
120}
121
123{
124 Q_UNUSED(vehicle);
126}
127
128void FirmwarePlugin::guidedModeRTL(Vehicle *vehicle, bool smartRTL) const
129{
130 Q_UNUSED(vehicle);
131 Q_UNUSED(smartRTL);
133}
134
136{
137 Q_UNUSED(vehicle);
139}
140
141void FirmwarePlugin::guidedModeTakeoff(Vehicle *vehicle, double takeoffAltRel) const
142{
143 Q_UNUSED(vehicle);
144 Q_UNUSED(takeoffAltRel);
146}
147
148bool FirmwarePlugin::guidedModeGotoLocation(Vehicle *vehicle, const QGeoCoordinate &gotoCoord, double forwardFlightLoiterRadius) const
149{
150 Q_UNUSED(vehicle);
151 Q_UNUSED(gotoCoord);
152 Q_UNUSED(forwardFlightLoiterRadius);
154 return false;
155}
156
162
167
172
173void FirmwarePlugin::guidedModeChangeHeading(Vehicle *vehicle, const QGeoCoordinate &/*headingCoord*/) const
174{
175 Q_UNUSED(vehicle);
177}
178
179bool FirmwarePlugin::guidedModeROI(Vehicle *vehicle, const QGeoCoordinate &roiCenterCoord, double relativeAltitudeMeters) const
180{
181 // MAVLink spec path: firmware honors the frame in the command
182 _sendROICommand(vehicle, roiCenterCoord, MAV_FRAME_GLOBAL_RELATIVE_ALT, static_cast<float>(relativeAltitudeMeters));
183 return true;
184}
185
186void FirmwarePlugin::_sendROICommand(Vehicle *vehicle, const QGeoCoordinate &coord, MAV_FRAME frame, float altitude) const
187{
188 qCDebug(FirmwarePluginLog) << "_sendROICommand: lat" << coord.latitude() << "lon" << coord.longitude()
189 << "frame" << frame << "altitude" << altitude;
190
191 if (vehicle->capabilityBits() & MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
192 vehicle->sendMavCommandInt(
193 vehicle->defaultComponentId(),
194 MAV_CMD_DO_SET_ROI_LOCATION,
195 frame,
196 true, // show error if fails
197 static_cast<float>(qQNaN()),
198 static_cast<float>(qQNaN()),
199 static_cast<float>(qQNaN()),
200 static_cast<float>(qQNaN()),
201 coord.latitude(),
202 coord.longitude(),
203 altitude);
204 } else {
205 vehicle->sendMavCommand(
206 vehicle->defaultComponentId(),
207 MAV_CMD_DO_SET_ROI_LOCATION,
208 true, // show error if fails
209 static_cast<float>(qQNaN()),
210 static_cast<float>(qQNaN()),
211 static_cast<float>(qQNaN()),
212 static_cast<float>(qQNaN()),
213 static_cast<float>(coord.latitude()),
214 static_cast<float>(coord.longitude()),
215 altitude);
216 }
217}
218
220{
221 // Not supported by generic vehicle
223}
224
229
236
237const QVariantList &FirmwarePlugin::toolIndicators(const Vehicle*)
238{
239 //-- Default list of indicators for all vehicles.
240 if (_toolIndicatorList.isEmpty()) {
241 _toolIndicatorList = QVariantList({
242 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/VehicleGPSIndicator.qml")),
243 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/GPSResilienceIndicator.qml")),
244 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/TelemetryRSSIIndicator.qml")),
245 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/RCRSSIIndicator.qml")),
246 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/BatteryIndicator.qml")),
247 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/RemoteIDIndicator.qml")),
248 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/GimbalIndicator.qml")),
249 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/EscIndicator.qml")),
250 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/JoystickIndicator.qml")),
251 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/MultiVehicleSelector.qml")),
252#ifdef QT_DEBUG
253 // ControlIndicator is only available in debug builds for the moment
254 QVariant::fromValue(QUrl::fromUserInput("qrc:/qml/QGroundControl/Toolbar/GCSControlIndicator.qml")),
255#endif
256 });
257 }
258
259 return _toolIndicatorList;
260}
261
263{
264 if (vehicle->armed()) {
265 return true;
266 }
267
268 bool vehicleArmed = false;
269
270 // Only try arming the vehicle a single time. Doing retries on arming with a delay can lead to safety issues.
271 vehicle->setArmed(true, false /* showError */);
272
273 // Wait 1500 msecs for vehicle to arm (waiting for the next heartbeat)
274 for (int i = 0; i < 15; i++) {
275 if (vehicle->armed()) {
276 vehicleArmed = true;
277 break;
278 }
279 QThread::msleep(100);
280 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
281 }
282
283 return vehicleArmed;
284}
285
286bool FirmwarePlugin::_setFlightModeAndValidate(Vehicle *vehicle, const QString &flightMode) const
287{
288 if (vehicle->flightMode() == flightMode) {
289 return true;
290 }
291
292 bool flightModeChanged = false;
293
294 // We try 3 times
295 for (int retries = 0; retries < 3; retries++) {
296 vehicle->setFlightMode(flightMode);
297
298 // Wait for vehicle to return flight mode
299 for (int i = 0; i < 13; i++) {
300 if (vehicle->flightMode() == flightMode) {
301 flightModeChanged = true;
302 break;
303 }
304 QThread::msleep(100);
305 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
306 }
307
308 if (flightModeChanged) {
309 break;
310 }
311 }
312
313 return flightModeChanged;
314}
315
316
317void FirmwarePlugin::batteryConsumptionData(Vehicle *vehicle, int &mAhBattery, double &hoverAmps, double &cruiseAmps) const
318{
319 Q_UNUSED(vehicle);
320 mAhBattery = 0;
321 hoverAmps = 0;
322 cruiseAmps = 0;
323}
324
325bool FirmwarePlugin::hasGimbal(Vehicle *vehicle, bool &rollSupported, bool &pitchSupported, bool &yawSupported) const
326{
327 Q_UNUSED(vehicle);
328 rollSupported = false;
329 pitchSupported = false;
330 yawSupported = false;
331 return false;
332}
333
335{
336 return new QGCCameraManager(vehicle);
337}
338
340{
341 return new VehicleCameraControl(info, vehicle, compID, parent);
342}
343
345{
346 // This is required as mocklink uses a hardcoded firmware version
347 if (QGC::runningUnitTests()) {
348 qCDebug(FirmwarePluginLog) << "Skipping version check";
349 return;
350 }
351
352 const QString versionFile = _getLatestVersionFileUrl(vehicle);
353 qCDebug(FirmwarePluginLog) << "Downloading" << versionFile;
354 QGCFileDownload *const downloader = new QGCFileDownload(vehicle);
355 (void) connect(downloader, &QGCFileDownload::finished, this, [vehicle, this, versionFile](bool success, const QString &localFile, const QString &errorMsg) {
356 if (success) {
357 _versionFileDownloadFinished(versionFile, localFile, vehicle);
358 } else if (!errorMsg.isEmpty()) {
359 qCDebug(FirmwarePluginLog) << "Failed to download the latest fw version file. Error:" << errorMsg;
360 }
361 sender()->deleteLater();
362 });
363
364 if (!downloader->start(versionFile)) {
365 downloader->deleteLater();
366 }
367}
368
369void FirmwarePlugin::_versionFileDownloadFinished(const QString &remoteFile, const QString &localFile, const Vehicle *vehicle) const
370{
371 qCDebug(FirmwarePluginLog) << "Download complete" << remoteFile << localFile;
372 // Now read the version file and pull out the version string
373 QFile versionFile(localFile);
374 if (!versionFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
375 qCWarning(FirmwarePluginLog) << "Error opening downloaded version file.";
376 return;
377 }
378
379 QTextStream stream(&versionFile);
380 const QString versionFileContents = stream.readAll();
381 QString version;
382 const QRegularExpressionMatch match = QRegularExpression(_versionRegex()).match(versionFileContents);
383
384 qCDebug(FirmwarePluginLog) << "Looking for version number...";
385
386 if (match.hasMatch()) {
387 version = match.captured(1);
388 } else {
389 qCWarning(FirmwarePluginLog) << "Unable to parse version info from file" << remoteFile;
390 return;
391 }
392
393 qCDebug(FirmwarePluginLog) << "Latest stable version = " << version;
394
395 const int currType = vehicle->firmwareVersionType();
396
397 // Check if lower version than stable or same version but different type
398 if ((currType == FIRMWARE_VERSION_TYPE_OFFICIAL) && (vehicle->versionCompare(version) < 0)) {
399 const QString currentVersionNumber = QStringLiteral("%1.%2.%3").arg(vehicle->firmwareMajorVersion())
400 .arg(vehicle->firmwareMinorVersion())
401 .arg(vehicle->firmwarePatchVersion());
402 QGC::showAppMessage(tr("Vehicle is not running latest stable firmware! Running %1, latest stable is %2.").arg(currentVersionNumber, version));
403 }
404}
405
406int FirmwarePlugin::versionCompare(const Vehicle *vehicle, int major, int minor, int patch) const
407{
408 const int currMajor = vehicle->firmwareMajorVersion();
409 const int currMinor = vehicle->firmwareMinorVersion();
410 const int currPatch = vehicle->firmwarePatchVersion();
411
412 if ((currMajor == major) && (currMinor == minor) && (currPatch == patch)) {
413 return 0;
414 }
415
416 if ((currMajor > major)
417 || ((currMajor == major) && (currMinor > minor))
418 || ((currMajor == major) && (currMinor == minor) && (currPatch > patch)))
419 {
420 return 1;
421 }
422
423 return -1;
424}
425
426int FirmwarePlugin::versionCompare(const Vehicle *vehicle, const QString &compare) const
427{
428 const QStringList versionNumbers = compare.split(".");
429 if (versionNumbers.size() != 3) {
430 qCWarning(FirmwarePluginLog) << "Error parsing version number: wrong format";
431 return -1;
432 }
433
434 const int major = versionNumbers[0].toInt();
435 const int minor = versionNumbers[1].toInt();
436 const int patch = versionNumbers[2].toInt();
437
438 return versionCompare(vehicle, major, minor, patch);
439}
440
441void FirmwarePlugin::sendGCSMotionReport(Vehicle *vehicle, const FollowMe::GCSMotionReport &motionReport, uint8_t estimationCapabilities) const
442{
443 SharedLinkInterfacePtr sharedLink = vehicle->vehicleLinkManager()->primaryLink().lock();
444 if (!sharedLink) {
445 return;
446 }
447
448 mavlink_follow_target_t follow_target{};
449
450 follow_target.timestamp = qgcApp()->msecsSinceBoot();
451 follow_target.est_capabilities = estimationCapabilities;
452 follow_target.position_cov[0] = static_cast<float>(motionReport.pos_std_dev[0]);
453 follow_target.position_cov[2] = static_cast<float>(motionReport.pos_std_dev[2]);
454 follow_target.alt = static_cast<float>(motionReport.altMetersAMSL);
455 follow_target.lat = motionReport.lat_int;
456 follow_target.lon = motionReport.lon_int;
457 follow_target.vel[0] = static_cast<float>(motionReport.vxMetersPerSec);
458 follow_target.vel[1] = static_cast<float>(motionReport.vyMetersPerSec);
459
460 mavlink_message_t message{};
461 mavlink_msg_follow_target_encode_chan(
462 static_cast<uint8_t>(MAVLinkProtocol::instance()->getSystemId()),
463 static_cast<uint8_t>(MAVLinkProtocol::getComponentId()),
464 sharedLink->mavlinkChannel(),
465 &message,
466 &follow_target
467 );
468
469 (void) vehicle->sendMessageOnLinkThreadSafe(sharedLink.get(), message);
470}
471
473{
474 return new Autotune(vehicle);
475}
476
478{
479 _flightModeList.clear();
480 _modeEnumToString.clear();
481
482 for (FirmwareFlightMode &flightMode : flightModeList) {
483 _modeEnumToString[flightMode.custom_mode] = flightMode.mode_name;
485 }
486
488 qCDebug(FirmwarePluginLog) << "Flight Mode:" << flightMode.mode_name << " Custom Mode:" << flightMode.custom_mode;
489 }
490}
491
493{
494 for (const FirmwareFlightMode &existingFlightMode : _flightModeList) {
495 if (existingFlightMode.custom_mode == newFlightMode.custom_mode) {
496 qCDebug(FirmwarePluginLog) << "Flight Mode:" << newFlightMode.mode_name << " Custom Mode:" << newFlightMode.custom_mode
497 << " already exists, not adding again.";
498 return;
499 }
500 }
501 _flightModeList += newFlightMode;
502}
503
504/*===========================================================================*/
505
506static constexpr const char *kCachedMetaDataFilePrefix = "ParameterFactMetaData";
507
508static QDir _parameterMetaDataCacheDir(bool ensureExists = false)
509{
510 const QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
511 + QStringLiteral("/ParameterMetaData");
512 if (ensureExists) {
514 }
515 return QDir(path);
516}
517
519{
521 if (!metaData) {
522 if (_autopilotType() == MAV_AUTOPILOT_GENERIC) {
523 qCDebug(FirmwarePluginLog) << "No parameter metadata parser for firmware plugin" << this << "(expected for generic firmware)";
524 } else {
525 qCWarning(FirmwarePluginLog) << "No parameter metadata parser for firmware plugin" << this;
526 }
527 return nullptr;
528 }
529
530 const QString metaDataFile = _cachedParameterMetaDataFile(vehicle);
531 if (!metaDataFile.isEmpty()) {
532 metaData->loadParameterFactMetaDataFile(metaDataFile);
533 }
534 return metaData;
535}
536
538{
539 const MAV_AUTOPILOT autopilot = _autopilotType();
540 if (autopilot == MAV_AUTOPILOT_GENERIC) {
541 return _internalParameterMetaDataFile(vehicle);
542 }
543
544 const QString internalFile = _internalParameterMetaDataFile(vehicle);
545 QVersionNumber internalVersion = ParameterMetaData::versionFromFileName(internalFile);
546 if (internalVersion.isNull()) {
547 internalVersion = ParameterMetaData::versionFromMetaDataFile(internalFile);
548 }
549
550 // Without a known internal version we can't safely compare against
551 // cache — use the bundled file to avoid stale overrides.
552 if (internalVersion.isNull() || QGC::runningUnitTests()) {
553 qCDebug(FirmwarePluginLog) << "Using internal parameter metadata:" << internalFile;
554 return internalFile;
555 }
556
557 const int wantedMajorVersion = internalVersion.majorVersion();
558
559 const QDir cacheDir = _parameterMetaDataCacheDir();
560 const QString wildcard = QStringLiteral("%1_%2.*.json").arg(kCachedMetaDataFilePrefix).arg(autopilot);
561 const QStringList entries = cacheDir.entryList(QStringList(wildcard), QDir::Files);
562
563 QString bestFile;
564 QVersionNumber bestVersion;
565 for (const QString &entry : entries) {
566 const QVersionNumber ver = ParameterMetaData::versionFromFileName(entry);
567 if (ver.isNull() || ver.majorVersion() != wantedMajorVersion) {
568 continue;
569 }
570 if (bestVersion.isNull() || ver > bestVersion) {
571 bestVersion = ver;
572 bestFile = cacheDir.filePath(entry);
573 }
574 }
575
576 if (bestFile.isEmpty()) {
577 qCDebug(FirmwarePluginLog) << "No cached parameter metadata found, using internal:" << internalFile;
578 return internalFile;
579 }
580
581 if (internalVersion.majorVersion() == wantedMajorVersion && bestVersion <= internalVersion) {
582 qCDebug(FirmwarePluginLog) << "Internal metadata" << internalVersion.toString() << ">= cache" << bestVersion.toString()
583 << "— using internal:" << internalFile;
584 return internalFile;
585 }
586 qCDebug(FirmwarePluginLog) << "Using cached parameter metadata" << bestVersion.toString() << ":" << bestFile;
587 return bestFile;
588}
589
590void FirmwarePlugin::cacheParameterMetaDataFile(const QString &metaDataFile)
591{
592 const MAV_AUTOPILOT autopilot = _autopilotType();
593 if (autopilot == MAV_AUTOPILOT_GENERIC) {
594 return;
595 }
596
597 QString readError;
598 const QByteArray data = QGCCompression::readFile(metaDataFile, &readError);
599 if (data.isEmpty()) {
600 qCWarning(FirmwarePluginLog) << "Cannot cache parameter metadata: failed to read" << metaDataFile << readError;
601 return;
602 }
603
604 // Reject non-JSON content (e.g. XML from older PX4 firmware images)
605 // and extract the catalog version in a single parse pass.
606 bool validJson = false;
607 QVersionNumber newVersion = ParameterMetaData::versionFromJsonData(data, &validJson);
608 if (!validJson) {
609 qCDebug(FirmwarePluginLog) << "Skipping cache of non-JSON parameter metadata:" << metaDataFile;
610 return;
611 }
612 if (newVersion.isNull()) {
613 // Valid JSON but no version stamps — use fallback so unversioned
614 // files still get cached with a major version that matches the
615 // default wantedMajorVersion in _cachedParameterMetaDataFile.
616 newVersion = QVersionNumber(1, 0);
617 }
618
619 const int majorVersion = newVersion.majorVersion();
620 const QDir cacheDir = _parameterMetaDataCacheDir(true);
621
622 const QString wildcard = QStringLiteral("%1_%2.%3.*.json").arg(kCachedMetaDataFilePrefix).arg(autopilot).arg(majorVersion);
623 const QStringList existing = cacheDir.entryList(QStringList(wildcard), QDir::Files);
624
625 for (const QString &file : existing) {
626 const QVersionNumber existingVersion = ParameterMetaData::versionFromFileName(file);
627 // Strict less-than: equal versions are replaced so that
628 // re-flashing with corrected metadata (same version stamp)
629 // updates the cache.
630 if (!existingVersion.isNull() && newVersion < existingVersion) {
631 return;
632 }
633 }
634
635 const QString cachePath = cacheDir.filePath(
636 QStringLiteral("%1_%2.%3.%4.json").arg(kCachedMetaDataFilePrefix).arg(autopilot).arg(majorVersion).arg(newVersion.minorVersion()));
637 if (!QGCFileHelper::atomicWrite(cachePath, data)) {
638 qCWarning(FirmwarePluginLog) << "Failed to cache parameter metadata to" << cachePath;
639 return;
640 }
641
642 for (const QString &file : existing) {
643 const QString fullPath = cacheDir.filePath(file);
644 if (fullPath != cachePath && !QFile::remove(fullPath)) {
645 qCWarning(FirmwarePluginLog) << "Failed to remove old cache file:" << file;
646 }
647 }
648}
649
650/*===========================================================================*/
651
static constexpr const char * kCachedMetaDataFilePrefix
static const QString guided_mode_not_supported_by_vehicle
static QDir _parameterMetaDataCacheDir(bool ensureExists=false)
QList< FirmwareFlightMode > FlightModeList
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
#define qgcApp()
struct __mavlink_message mavlink_message_t
Unified file download utility with decompression, verification, and QML support.
#define QGC_LOGGING_CATEGORY(name, categoryStr)
struct __mavlink_camera_information_t mavlink_camera_information_t
The AutoPilotPlugin class is an abstract base class which represents the methods and objects which ar...
virtual CommandSupportedResult anyVersionSupportsCommand(MAV_CMD) const
CommandSupportedResult getCommandSupported(MAV_CMD cmd) const
The FirmwarePlugin class represents the methods and objects which are specific to a certain Firmware ...
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 void checkIfIsLatestStable(Vehicle *vehicle) const
Used to check if running firmware is latest stable version.
FlightModeList _flightModeList
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
virtual ~FirmwarePlugin()
virtual void guidedModeTakeoff(Vehicle *vehicle, double takeoffAltRel) const
Command vehicle to takeoff from current location to the specified height.
void _sendROICommand(Vehicle *vehicle, const QGeoCoordinate &coord, MAV_FRAME frame, float altitude) const
Build + send MAV_CMD_DO_SET_ROI_LOCATION (COMMAND_INT when the vehicle supports it).
void cacheParameterMetaDataFile(const QString &metaDataFile)
virtual QString missionCommandOverrides(QGCMAVLinkTypes::VehicleClass_t vehicleClass) const
bool _setFlightModeAndValidate(Vehicle *vehicle, const QString &flightMode) const
virtual QString _internalParameterMetaDataFile(const Vehicle *) const
virtual QString _getLatestVersionFileUrl(Vehicle *) const
returns url with latest firmware release information.
void _updateFlightModeList(FlightModeList &flightModeList)
virtual void guidedModeChangeHeading(Vehicle *vehicle, const QGeoCoordinate &headingCoord) const
Command vehicle to rotate towards specified location.
virtual bool guidedModeGotoLocation(Vehicle *vehicle, const QGeoCoordinate &gotoCoord, double forwardFlightLoiterRadius=0.0) const
virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode) const
virtual void startTakeoff(Vehicle *vehicle) const
Command the vehicle to start a takeoff.
void _addNewFlightMode(FirmwareFlightMode &flightMode)
virtual void pauseVehicle(Vehicle *vehicle) const
virtual MAV_AUTOPILOT _autopilotType() const
int versionCompare(const Vehicle *vehicle, const QString &compare) const
virtual Autotune * createAutotune(Vehicle *vehicle) const
Creates Autotune object.
ParameterMetaData * loadParameterMetaData(const Vehicle *vehicle)
virtual AutoPilotPlugin * autopilotPlugin(Vehicle *vehicle) const
virtual void guidedModeRTL(Vehicle *vehicle, bool smartRTL) const
Command vehicle to return to launch.
virtual ParameterMetaData * _createParameterMetaData()
virtual QString _versionRegex() const
Returns regex QString to extract version information from text.
bool _armVehicleAndValidate(Vehicle *vehicle) const
QVariantList _toolIndicatorList
QString _cachedParameterMetaDataFile(const Vehicle *vehicle) const
virtual void setGuidedMode(Vehicle *vehicle, bool guidedMode) const
Set guided flight mode.
FlightModeCustomModeMap _modeEnumToString
virtual bool guidedModeROI(Vehicle *vehicle, const QGeoCoordinate &roiCenterCoord, double relativeAltitudeMeters) const
virtual void batteryConsumptionData(Vehicle *vehicle, int &mAhBattery, double &hoverAmps, double &cruiseAmps) const
virtual QGCCameraManager * createCameraManager(Vehicle *vehicle) const
Creates vehicle camera manager.
virtual void sendGCSMotionReport(Vehicle *vehicle, const FollowMe::GCSMotionReport &motionReport, uint8_t estimationCapabilities) const
Sends the appropriate mavlink message for follow me support.
QMap< int, remapParamNameMinorVersionRemapMap_t > remapParamNameMajorVersionMap_t
virtual const remapParamNameMajorVersionMap_t & paramNameRemapMajorVersionMap() const
virtual void guidedModeLand(Vehicle *vehicle) const
Command vehicle to land at current location.
virtual MavlinkCameraControlInterface * createCameraControl(const mavlink_camera_information_t *info, Vehicle *vehicle, int compID, QObject *parent=nullptr) const
Camera control.
virtual bool hasGimbal(Vehicle *vehicle, bool &rollSupported, bool &pitchSupported, bool &yawSupported) const
virtual void _versionFileDownloadFinished(const QString &remoteFile, const QString &localFile, const Vehicle *vehicle) const
Callback to process file with latest release information.
This is the generic implementation of the AutoPilotPlugin class for mavs we do not have a specific Au...
static int getComponentId()
static MAVLinkProtocol * instance()
Abstract base class for all camera controls: real and simulated.
static QVersionNumber versionFromMetaDataFile(const QString &metaDataFile)
static QVersionNumber versionFromJsonData(const QByteArray &jsonData)
void loadParameterFactMetaDataFile(const QString &metaDataFile)
static QVersionNumber versionFromFileName(const QString &fileName)
Camera Manager.
File download with progress, decompression, and hash verification.
void finished(bool success, const QString &localPath, const QString &errorMessage)
bool start(const QString &remoteUrl)
MAVLink Camera API controller - connected to a real mavlink v2 camera.
WeakLinkInterfacePtr primaryLink() const
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)
Definition Vehicle.cc:2146
QString flightMode() const
Definition Vehicle.cc:1468
uint64_t capabilityBits() const
Definition Vehicle.h:709
VehicleLinkManager * vehicleLinkManager()
Definition Vehicle.h:579
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)
Definition Vehicle.cc:2175
int firmwareMinorVersion() const
Definition Vehicle.h:662
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
Definition Vehicle.cc:1392
void setFlightMode(const QString &flightMode)
Definition Vehicle.cc:1478
int firmwareVersionType() const
Definition Vehicle.h:664
int defaultComponentId() const
Definition Vehicle.h:682
int firmwarePatchVersion() const
Definition Vehicle.h:663
bool armed() const
Definition Vehicle.h:456
Q_INVOKABLE int versionCompare(const QString &compare) const
Used to check if running current version is equal or higher than the one being compared.
Definition Vehicle.cc:2730
int firmwareMajorVersion() const
Definition Vehicle.h:661
void setArmed(bool armed, bool showError)
Definition Vehicle.cc:1439
QByteArray readFile(const QString &filePath, QString *errorString, qint64 maxBytes)
Read file contents, transparently decompressing .gz/.xz/.zst/.bz2/.lz4 files.
bool atomicWrite(const QString &filePath, const QByteArray &data)
bool ensureDirectoryExists(const QString &path)
bool runningUnitTests()
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.
Definition AppMessages.cc:9
static constexpr VehicleClass_t VehicleClassGeneric