13#include <QtCore/QRegularExpression>
14#include <QtCore/QThread>
23 qCDebug(FirmwarePluginLog) <<
this;
28 qCDebug(FirmwarePluginLog) <<
this;
38 Q_UNUSED(custom_mode);
41 const uint8_t baseModeBit;
45 static constexpr Bit2Name rgBit2Name[] = {
46 { MAV_MODE_FLAG_MANUAL_INPUT_ENABLED,
"Manual" },
47 { MAV_MODE_FLAG_STABILIZE_ENABLED,
"Stabilize" },
48 { MAV_MODE_FLAG_GUIDED_ENABLED,
"Guided" },
49 { MAV_MODE_FLAG_AUTO_ENABLED,
"Auto" },
50 { MAV_MODE_FLAG_TEST_ENABLED,
"Test" },
56 }
else if (base_mode & MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) {
59 for (
size_t i = 0; i < std::size(rgBit2Name); i++) {
60 if (base_mode & rgBit2Name[i].baseModeBit) {
76 Q_UNUSED(custom_mode);
78 qCWarning(FirmwarePluginLog) <<
"FirmwarePlugin::setFlightMode called on base class, not supported";
85 switch (vehicleClass) {
87 return QStringLiteral(
":/json/MavCmdInfoCommon.json");
89 return QStringLiteral(
":/json/MavCmdInfoFixedWing.json");
91 return QStringLiteral(
":/json/MavCmdInfoMultiRotor.json");
93 return QStringLiteral(
":/json/MavCmdInfoVTOL.json");
95 return QStringLiteral(
":/json/MavCmdInfoSub.json");
97 return QStringLiteral(
":/json/MavCmdInfoRover.json");
99 qCWarning(FirmwarePluginLog) <<
"FirmwarePlugin::missionCommandOverrides called with bad VehicleClass_t:" << vehicleClass;
106 Q_UNUSED(metaDataFile);
114 Q_UNUSED(guidedMode);
140 Q_UNUSED(takeoffAltRel);
148 Q_UNUSED(forwardFlightLoiterRadius);
197 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/VehicleGPSIndicator.qml")),
198 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/GPSResilienceIndicator.qml")),
199 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/TelemetryRSSIIndicator.qml")),
200 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/RCRSSIIndicator.qml")),
201 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Controls/BatteryIndicator.qml")),
202 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/RemoteIDIndicator.qml")),
203 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/GimbalIndicator.qml")),
204 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/EscIndicator.qml")),
205 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/JoystickIndicator.qml")),
206 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/MultiVehicleSelector.qml")),
209 QVariant::fromValue(QUrl::fromUserInput(
"qrc:/qml/QGroundControl/Toolbar/GCSControlIndicator.qml")),
219 if (vehicle->
armed()) {
223 bool vehicleArmed =
false;
229 for (
int i = 0; i < 15; i++) {
230 if (vehicle->
armed()) {
234 QThread::msleep(100);
235 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
247 bool flightModeChanged =
false;
250 for (
int retries = 0; retries < 3; retries++) {
254 for (
int i = 0; i < 13; i++) {
256 flightModeChanged =
true;
259 QThread::msleep(100);
260 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
263 if (flightModeChanged) {
268 return flightModeChanged;
283 rollSupported =
false;
284 pitchSupported =
false;
285 yawSupported =
false;
302 if (
qgcApp()->runningUnitTests()) {
303 qCDebug(FirmwarePluginLog) <<
"Skipping version check";
308 qCDebug(FirmwarePluginLog) <<
"Downloading" << versionFile;
310 (void) connect(downloader, &
QGCFileDownload::finished,
this, [vehicle,
this, versionFile](
bool success,
const QString &localFile,
const QString &errorMsg) {
313 }
else if (!errorMsg.isEmpty()) {
314 qCDebug(FirmwarePluginLog) <<
"Failed to download the latest fw version file. Error:" << errorMsg;
316 sender()->deleteLater();
319 if (!downloader->
start(versionFile)) {
320 downloader->deleteLater();
326 qCDebug(FirmwarePluginLog) <<
"Download complete" << remoteFile << localFile;
328 QFile versionFile(localFile);
329 if (!versionFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
330 qCWarning(FirmwarePluginLog) <<
"Error opening downloaded version file.";
334 QTextStream stream(&versionFile);
335 const QString versionFileContents = stream.readAll();
337 const QRegularExpressionMatch match = QRegularExpression(
_versionRegex()).match(versionFileContents);
339 qCDebug(FirmwarePluginLog) <<
"Looking for version number...";
341 if (match.hasMatch()) {
342 version = match.captured(1);
344 qCWarning(FirmwarePluginLog) <<
"Unable to parse version info from file" << remoteFile;
348 qCDebug(FirmwarePluginLog) <<
"Latest stable version = " << version;
353 if ((currType == FIRMWARE_VERSION_TYPE_OFFICIAL) && (vehicle->
versionCompare(version) < 0)) {
354 const QString currentVersionNumber = QStringLiteral(
"%1.%2.%3").arg(vehicle->
firmwareMajorVersion())
357 qgcApp()->showAppMessage(tr(
"Vehicle is not running latest stable firmware! Running %1, latest stable is %2.").arg(currentVersionNumber, version));
367 if ((currMajor == major) && (currMinor == minor) && (currPatch == patch)) {
371 if ((currMajor > major)
372 || ((currMajor == major) && (currMinor > minor))
373 || ((currMajor == major) && (currMinor == minor) && (currPatch > patch)))
383 const QStringList versionNumbers = compare.split(
".");
384 if (versionNumbers.size() != 3) {
385 qCWarning(FirmwarePluginLog) <<
"Error parsing version number: wrong format";
389 const int major = versionNumbers[0].toInt();
390 const int minor = versionNumbers[1].toInt();
391 const int patch = versionNumbers[2].toInt();
403 mavlink_follow_target_t follow_target{};
405 follow_target.timestamp =
qgcApp()->msecsSinceBoot();
406 follow_target.est_capabilities = estimationCapabilities;
407 follow_target.position_cov[0] =
static_cast<float>(motionReport.
pos_std_dev[0]);
408 follow_target.position_cov[2] =
static_cast<float>(motionReport.
pos_std_dev[2]);
409 follow_target.alt =
static_cast<float>(motionReport.
altMetersAMSL);
410 follow_target.lat = motionReport.
lat_int;
411 follow_target.lon = motionReport.
lon_int;
412 follow_target.vel[0] =
static_cast<float>(motionReport.
vxMetersPerSec);
413 follow_target.vel[1] =
static_cast<float>(motionReport.
vyMetersPerSec);
416 mavlink_msg_follow_target_encode_chan(
419 sharedLink->mavlinkChannel(),
443 qCDebug(FirmwarePluginLog) <<
"Flight Mode:" <<
flightMode.mode_name <<
" Custom Mode:" <<
flightMode.custom_mode;
450 if (existingFlightMode.custom_mode == newFlightMode.
custom_mode) {
451 qCDebug(FirmwarePluginLog) <<
"Flight Mode:" << newFlightMode.
mode_name <<
" Custom Mode:" << newFlightMode.
custom_mode
452 <<
" already exists, not adding again.";
static const QString guided_mode_not_supported_by_vehicle
QList< FirmwareFlightMode > FlightModeList
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
Unified file download utility with decompression, verification, and QML support.
#define QGC_LOGGING_CATEGORY(name, categoryStr)
virtual CommandSupportedResult anyVersionSupportsCommand(MAV_CMD) const
CommandSupportedResult getCommandSupported(MAV_CMD cmd) const
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.
bool _setFlightModeAndValidate(Vehicle *vehicle, const QString &flightMode) 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 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
int versionCompare(const Vehicle *vehicle, const QString &compare) const
virtual Autotune * createAutotune(Vehicle *vehicle) const
Creates Autotune object.
virtual AutoPilotPlugin * autopilotPlugin(Vehicle *vehicle) const
virtual void guidedModeRTL(Vehicle *vehicle, bool smartRTL) const
Command vehicle to return to launch.
virtual QString _versionRegex() const
Returns regex QString to extract version information from text.
virtual void _getParameterMetaDataVersionInfo(const QString &metaDataFile, int &majorVersion, int &minorVersion) const
virtual MavlinkCameraControl * createCameraControl(const mavlink_camera_information_t *info, Vehicle *vehicle, int compID, QObject *parent=nullptr) const
Camera control.
bool _armVehicleAndValidate(Vehicle *vehicle) const
QVariantList _toolIndicatorList
virtual void setGuidedMode(Vehicle *vehicle, bool guidedMode) const
Set guided flight mode.
virtual void guidedModeGotoLocation(Vehicle *vehicle, const QGeoCoordinate &gotoCoord, double forwardFlightLoiterRadius=0.0) const
Command vehicle to move to specified location (altitude is included and relative)
FlightModeCustomModeMap _modeEnumToString
virtual QString missionCommandOverrides(QGCMAVLink::VehicleClass_t vehicleClass) 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
Returns the mapping structure which is used to map from one parameter name to another based on firmwa...
virtual void guidedModeLand(Vehicle *vehicle) const
Command vehicle to land at current location.
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.
static int getComponentId()
Get the component id of this application.
static MAVLinkProtocol * instance()
Abstract base class for all camera controls: real and simulated.
void finished(bool success, const QString &localPath, const QString &errorMessage)
bool start(const QString &remoteUrl)
static constexpr const VehicleClass_t VehicleClassSub
static constexpr const VehicleClass_t VehicleClassFixedWing
static constexpr const VehicleClass_t VehicleClassMultiRotor
static constexpr const VehicleClass_t VehicleClassRoverBoat
static constexpr const VehicleClass_t VehicleClassVTOL
static constexpr const VehicleClass_t VehicleClassGeneric
MAVLink Camera API controller - connected to a real mavlink v2 camera.
WeakLinkInterfacePtr primaryLink() const
QString flightMode() const
VehicleLinkManager * vehicleLinkManager()
int firmwareMinorVersion() const
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
void setFlightMode(const QString &flightMode)
int firmwareVersionType() const
int firmwarePatchVersion() const
int versionCompare(const QString &compare) const
Used to check if running current version is equal or higher than the one being compared.
int firmwareMajorVersion() const
void setArmed(bool armed, bool showError)