diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml b/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml index b9aeead..9097ce4 100644 --- a/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml +++ b/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml @@ -32,5 +32,10 @@ FactPanel { : /* Fact.value == 10 */ "New Y6"); } + + VehicleSummaryRow { + labelText: qsTr("Firmware Version:") + valueText: activeVehicle.firmwareMajorVersion == -1 ? qsTr("Unknown") : activeVehicle.firmwareMajorVersion + "." + activeVehicle.firmwareMinorVersion + "." + activeVehicle.firmwarePatchVersion + activeVehicle.firmwareVersionTypeString + } } } diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml b/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml index 2494f55..d95371e 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml +++ b/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml @@ -34,5 +34,10 @@ FactPanel { labelText: qsTr("Vehicle:") valueText: autoStartSet ? controller.currentVehicleName : qsTr("Setup required") } + + VehicleSummaryRow { + labelText: qsTr("Firmware Version:") + valueText: activeVehicle.firmwareMajorVersion == -1 ? qsTr("Unknown") : activeVehicle.firmwareMajorVersion + "." + activeVehicle.firmwareMinorVersion + "." + activeVehicle.firmwarePatchVersion + activeVehicle.firmwareVersionTypeString + } } } diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 858a140..961fab5 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -126,6 +126,7 @@ Vehicle::Vehicle(LinkInterface* link, , _firmwareMajorVersion(versionNotSetValue) , _firmwareMinorVersion(versionNotSetValue) , _firmwarePatchVersion(versionNotSetValue) + , _firmwareVersionType(FIRMWARE_VERSION_TYPE_OFFICIAL) , _rollFact (0, _rollFactName, FactMetaData::valueTypeDouble) , _pitchFact (0, _pitchFactName, FactMetaData::valueTypeDouble) , _headingFact (0, _headingFactName, FactMetaData::valueTypeDouble) @@ -208,6 +209,9 @@ Vehicle::Vehicle(LinkInterface* link, connect(_parameterLoader, &ParameterLoader::parametersReady, _autopilotPlugin, &AutoPilotPlugin::_parametersReadyPreChecks); connect(_parameterLoader, &ParameterLoader::parameterListProgress, _autopilotPlugin, &AutoPilotPlugin::parameterListProgress); + // Ask the vehicle for firmware version info + doCommandLong(MAV_COMP_ID_ALL, MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 1 /* request firmware version */); + _firmwarePlugin->initializeVehicle(this); _sendMultipleTimer.start(_sendMessageMultipleIntraMessageDelay); @@ -437,6 +441,9 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes case MAVLINK_MSG_ID_COMMAND_ACK: _handleCommandAck(message); break; + case MAVLINK_MSG_ID_AUTOPILOT_VERSION: + _handleAutopilotVersion(message); + break; // Following are ArduPilot dialect messages @@ -450,6 +457,23 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes _uas->receiveMessage(message); } +void Vehicle::_handleAutopilotVersion(mavlink_message_t& message) +{ + mavlink_autopilot_version_t autopilotVersion; + mavlink_msg_autopilot_version_decode(&message, &autopilotVersion); + + if (autopilotVersion.flight_sw_version != 0) { + int majorVersion, minorVersion, patchVersion; + FIRMWARE_VERSION_TYPE versionType; + + majorVersion = (autopilotVersion.flight_sw_version >> (8*3)) & 0xFF; + minorVersion = (autopilotVersion.flight_sw_version >> (8*2)) & 0xFF; + patchVersion = (autopilotVersion.flight_sw_version >> (8*1)) & 0xFF; + versionType = (FIRMWARE_VERSION_TYPE)((autopilotVersion.flight_sw_version >> (8*0)) & 0xFF); + setFirmwareVersion(majorVersion, minorVersion, patchVersion, versionType); + } +} + void Vehicle::_handleCommandAck(mavlink_message_t& message) { mavlink_command_ack_t ack; @@ -1638,13 +1662,36 @@ void Vehicle::_prearmErrorTimeout(void) setPrearmError(QString()); } -void Vehicle::setFirmwareVersion(int majorVersion, int minorVersion, int patchVersion) +void Vehicle::setFirmwareVersion(int majorVersion, int minorVersion, int patchVersion, FIRMWARE_VERSION_TYPE versionType) { _firmwareMajorVersion = majorVersion; _firmwareMinorVersion = minorVersion; _firmwarePatchVersion = patchVersion; + _firmwareVersionType = versionType; + emit firmwareMajorVersionChanged(_firmwareMajorVersion); + emit firmwareMinorVersionChanged(_firmwareMinorVersion); + emit firmwarePatchVersionChanged(_firmwarePatchVersion); + emit firmwareVersionTypeChanged(_firmwareVersionType); +} + +QString Vehicle::firmwareVersionTypeString(void) const +{ + switch (_firmwareVersionType) { + case FIRMWARE_VERSION_TYPE_DEV: + return QStringLiteral("dev"); + case FIRMWARE_VERSION_TYPE_ALPHA: + return QStringLiteral("alpha"); + case FIRMWARE_VERSION_TYPE_BETA: + return QStringLiteral("beta"); + case FIRMWARE_VERSION_TYPE_RC: + return QStringLiteral("rc"); + case FIRMWARE_VERSION_TYPE_OFFICIAL: + default: + return QStringLiteral(""); + } } + void Vehicle::rebootVehicle() { doCommandLong(id(), MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index d35c69e..43c7534 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -316,6 +316,12 @@ public: Q_PROPERTY(FactGroup* wind READ windFactGroup CONSTANT) Q_PROPERTY(FactGroup* vibration READ vibrationFactGroup CONSTANT) + Q_PROPERTY(int firmwareMajorVersion READ firmwareMajorVersion NOTIFY firmwareMajorVersionChanged) + Q_PROPERTY(int firmwareMinorVersion READ firmwareMinorVersion NOTIFY firmwareMinorVersionChanged) + Q_PROPERTY(int firmwarePatchVersion READ firmwarePatchVersion NOTIFY firmwarePatchVersionChanged) + Q_PROPERTY(int firmwareVersionType READ firmwareVersionType NOTIFY firmwareVersionTypeChanged) + Q_PROPERTY(QString firmwareVersionTypeString READ firmwareVersionTypeString NOTIFY firmwareVersionTypeChanged) + /// Resets link status counters Q_INVOKABLE void resetCounters (); @@ -530,7 +536,9 @@ public: int firmwareMajorVersion(void) const { return _firmwareMajorVersion; } int firmwareMinorVersion(void) const { return _firmwareMinorVersion; } int firmwarePatchVersion(void) const { return _firmwarePatchVersion; } - void setFirmwareVersion(int majorVersion, int minorVersion, int patchVersion); + int firmwareVersionType(void) const { return _firmwareVersionType; } + QString firmwareVersionTypeString(void) const; + void setFirmwareVersion(int majorVersion, int minorVersion, int patchVersion, FIRMWARE_VERSION_TYPE versionType = FIRMWARE_VERSION_TYPE_OFFICIAL); static const int versionNotSetValue = -1; public slots: @@ -579,6 +587,11 @@ signals: void flowImageIndexChanged (); void rcRSSIChanged (int rcRSSI); + void firmwareMajorVersionChanged(int major); + void firmwareMinorVersionChanged(int minor); + void firmwarePatchVersionChanged(int patch); + void firmwareVersionTypeChanged(int type); + /// New RC channel values /// @param channelCount Number of available channels, cMaxRcChannels max /// @param pwmValues -1 signals channel not available @@ -637,6 +650,7 @@ private: void _handleVibration(mavlink_message_t& message); void _handleExtendedSysState(mavlink_message_t& message); void _handleCommandAck(mavlink_message_t& message); + void _handleAutopilotVersion(mavlink_message_t& message); void _missionManagerError(int errorCode, const QString& errorMsg); void _mapTrajectoryStart(void); void _mapTrajectoryStop(void); @@ -747,6 +761,7 @@ private: int _firmwareMajorVersion; int _firmwareMinorVersion; int _firmwarePatchVersion; + FIRMWARE_VERSION_TYPE _firmwareVersionType; static const int _lowBatteryAnnounceRepeatMSecs; // Amount of time in between each low battery announcement QElapsedTimer _lowBatteryAnnounceTimer; diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index deff7b6..8e704a9 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -727,7 +727,6 @@ void FirmwareUpgradeController::_loadAPMVersions(QGCSerialPortInfo::BoardType_t } } - void FirmwareUpgradeController::_apmVersionDownloadFinished(QString remoteFile, QString localFile) { qCDebug(FirmwareUpgradeLog) << "Download complete" << remoteFile << localFile; diff --git a/src/comm/MockLink.cc b/src/comm/MockLink.cc index a0aa47d..ad45267 100644 --- a/src/comm/MockLink.cc +++ b/src/comm/MockLink.cc @@ -803,6 +803,10 @@ void MockLink::_handleCommandLong(const mavlink_message_t& msg) case MAV_CMD_PREFLIGHT_STORAGE: commandResult = MAV_RESULT_ACCEPTED; break; + case MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES: + commandResult = MAV_RESULT_ACCEPTED; + _respondWithAutopilotVersion(); + break; } mavlink_message_t commandAck; @@ -814,6 +818,31 @@ void MockLink::_handleCommandLong(const mavlink_message_t& msg) respondWithMavlinkMessage(commandAck); } +void MockLink::_respondWithAutopilotVersion(void) +{ + mavlink_message_t msg; + + uint8_t customVersion[8]; + memset(customVersion, 0, sizeof(customVersion)); + + // Only flight_sw_version is supported a this point + mavlink_msg_autopilot_version_pack(_vehicleSystemId, + _vehicleComponentId, + &msg, + 0, // capabilities, + (1 << (8*3)) | FIRMWARE_VERSION_TYPE_DEV, // flight_sw_version, + 0, // middleware_sw_version, + 0, // os_sw_version, + 0, // board_version, + (uint8_t *)&customVersion, // flight_custom_version, + (uint8_t *)&customVersion, // middleware_custom_version, + (uint8_t *)&customVersion, // os_custom_version, + 0, // vendor_id, + 0, // product_id, + 0); // uid + respondWithMavlinkMessage(msg); +} + void MockLink::setMissionItemFailureMode(MockLinkMissionItemHandler::FailureMode_t failureMode) { _missionItemHandler.setMissionItemFailureMode(failureMode); diff --git a/src/comm/MockLink.h b/src/comm/MockLink.h index 395907e..917dece 100644 --- a/src/comm/MockLink.h +++ b/src/comm/MockLink.h @@ -185,6 +185,7 @@ private: void _sendGpsRawInt(void); void _sendVibration(void); void _sendStatusTextMessages(void); + void _respondWithAutopilotVersion(void); static MockLink* _startMockLink(MockConfiguration* mockConfig);