diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 67da3fd..5dbf682 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -599,6 +599,7 @@ HEADERS += \
src/Settings/AppSettings.h \
src/Settings/AutoConnectSettings.h \
src/Settings/BrandImageSettings.h \
+ src/Settings/FirmwareUpgradeSettings.h \
src/Settings/FlightMapSettings.h \
src/Settings/FlyViewSettings.h \
src/Settings/OfflineMapsSettings.h \
@@ -803,6 +804,7 @@ SOURCES += \
src/Settings/AppSettings.cc \
src/Settings/AutoConnectSettings.cc \
src/Settings/BrandImageSettings.cc \
+ src/Settings/FirmwareUpgradeSettings.cc \
src/Settings/FlightMapSettings.cc \
src/Settings/FlyViewSettings.cc \
src/Settings/OfflineMapsSettings.cc \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 4e1ff77..a203b16 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -224,6 +224,7 @@
src/Settings/AutoConnect.SettingsGroup.json
src/Settings/BrandImage.SettingsGroup.json
src/MissionManager/CameraSection.FactMetaData.json
+ src/Settings/FirmwareUpgrade.SettingsGroup.json
src/Settings/FlightMap.SettingsGroup.json
src/MissionManager/FWLandingPattern.FactMetaData.json
src/Settings/FlyView.SettingsGroup.json
diff --git a/src/Settings/FirmwareUpgrade.SettingsGroup.json b/src/Settings/FirmwareUpgrade.SettingsGroup.json
new file mode 100644
index 0000000..97711ac
--- /dev/null
+++ b/src/Settings/FirmwareUpgrade.SettingsGroup.json
@@ -0,0 +1,22 @@
+[
+{
+ "name": "defaultFirmwareType",
+ "shortDescription": "Default firmware type for flashing",
+ "type": "uint32",
+ "defaultValue": 12
+},
+{
+ "name": "apmChibiOS",
+ "type": "uint32",
+ "enumStrings": "ChibiOS,NuttX",
+ "enumValues": "0,1",
+ "defaultValue": 0
+},
+{
+ "name": "apmVehicleType",
+ "type": "uint32",
+ "enumStrings": "Multi-Rotor,Helicopter,Plane,Rover,Sub",
+ "enumValues": "0,1,2,3,4",
+ "defaultValue": 0
+}
+]
diff --git a/src/Settings/FirmwareUpgradeSettings.cc b/src/Settings/FirmwareUpgradeSettings.cc
new file mode 100644
index 0000000..0adab2b
--- /dev/null
+++ b/src/Settings/FirmwareUpgradeSettings.cc
@@ -0,0 +1,22 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+#include "FirmwareUpgradeSettings.h"
+
+#include
+#include
+
+DECLARE_SETTINGGROUP(FirmwareUpgrade, "FirmwareUpgrade")
+{
+ qmlRegisterUncreatableType("QGroundControl.SettingsManager", 1, 0, "FirmwareUpgradeSettings", "Reference only");
+}
+
+DECLARE_SETTINGSFACT(FirmwareUpgradeSettings, defaultFirmwareType)
+DECLARE_SETTINGSFACT(FirmwareUpgradeSettings, apmChibiOS)
+DECLARE_SETTINGSFACT(FirmwareUpgradeSettings, apmVehicleType)
diff --git a/src/Settings/FirmwareUpgradeSettings.h b/src/Settings/FirmwareUpgradeSettings.h
new file mode 100644
index 0000000..5e7fe17
--- /dev/null
+++ b/src/Settings/FirmwareUpgradeSettings.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+#pragma once
+
+#include "SettingsGroup.h"
+#include "QGCMAVLink.h"
+
+class FirmwareUpgradeSettings : public SettingsGroup
+{
+ Q_OBJECT
+
+public:
+ FirmwareUpgradeSettings(QObject* parent = nullptr);
+
+ DEFINE_SETTING_NAME_GROUP()
+
+ DEFINE_SETTINGFACT(defaultFirmwareType)
+ DEFINE_SETTINGFACT(apmChibiOS)
+ DEFINE_SETTINGFACT(apmVehicleType)
+};
diff --git a/src/Settings/SettingsManager.cc b/src/Settings/SettingsManager.cc
index 963e1bf..4b6968f 100644
--- a/src/Settings/SettingsManager.cc
+++ b/src/Settings/SettingsManager.cc
@@ -27,6 +27,7 @@ SettingsManager::SettingsManager(QGCApplication* app, QGCToolbox* toolbox)
, _planViewSettings (nullptr)
, _brandImageSettings (nullptr)
, _offlineMapsSettings (nullptr)
+ , _firmwareUpgradeSettings (nullptr)
#if !defined(NO_ARDUPILOT_DIALECT)
, _apmMavlinkStreamRateSettings (nullptr)
#endif
@@ -40,20 +41,21 @@ void SettingsManager::setToolbox(QGCToolbox *toolbox)
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType("QGroundControl.SettingsManager", 1, 0, "SettingsManager", "Reference only");
- _unitsSettings = new UnitsSettings (this); // Must be first since AppSettings references it
- _appSettings = new AppSettings (this);
- _autoConnectSettings = new AutoConnectSettings (this);
- _videoSettings = new VideoSettings (this);
- _flightMapSettings = new FlightMapSettings (this);
- _rtkSettings = new RTKSettings (this);
- _flyViewSettings = new FlyViewSettings (this);
- _planViewSettings = new PlanViewSettings (this);
- _brandImageSettings = new BrandImageSettings (this);
- _offlineMapsSettings = new OfflineMapsSettings (this);
+ _unitsSettings = new UnitsSettings (this); // Must be first since AppSettings references it
+ _appSettings = new AppSettings (this);
+ _autoConnectSettings = new AutoConnectSettings (this);
+ _videoSettings = new VideoSettings (this);
+ _flightMapSettings = new FlightMapSettings (this);
+ _rtkSettings = new RTKSettings (this);
+ _flyViewSettings = new FlyViewSettings (this);
+ _planViewSettings = new PlanViewSettings (this);
+ _brandImageSettings = new BrandImageSettings (this);
+ _offlineMapsSettings = new OfflineMapsSettings (this);
+ _firmwareUpgradeSettings = new FirmwareUpgradeSettings (this);
#if !defined(NO_ARDUPILOT_DIALECT)
- _apmMavlinkStreamRateSettings = new APMMavlinkStreamRateSettings (this);
+ _apmMavlinkStreamRateSettings = new APMMavlinkStreamRateSettings(this);
#endif
#if defined(QGC_AIRMAP_ENABLED)
- _airMapSettings = new AirMapSettings (this);
+ _airMapSettings = new AirMapSettings (this);
#endif
}
diff --git a/src/Settings/SettingsManager.h b/src/Settings/SettingsManager.h
index 141730f..6c3f867 100644
--- a/src/Settings/SettingsManager.h
+++ b/src/Settings/SettingsManager.h
@@ -25,6 +25,7 @@
#include "BrandImageSettings.h"
#include "OfflineMapsSettings.h"
#include "APMMavlinkStreamRateSettings.h"
+#include "FirmwareUpgradeSettings.h"
#if defined(QGC_AIRMAP_ENABLED)
#include "AirMapSettings.h"
#endif
@@ -50,7 +51,8 @@ public:
Q_PROPERTY(QObject* flyViewSettings READ flyViewSettings CONSTANT)
Q_PROPERTY(QObject* planViewSettings READ planViewSettings CONSTANT)
Q_PROPERTY(QObject* brandImageSettings READ brandImageSettings CONSTANT)
- Q_PROPERTY(QObject* offlineMapsSettings READ offlineMapsSettings CONSTANT)
+ Q_PROPERTY(QObject* offlineMapsSettings READ offlineMapsSettings CONSTANT)
+ Q_PROPERTY(QObject* firmwareUpgradeSettings READ firmwareUpgradeSettings CONSTANT)
#if !defined(NO_ARDUPILOT_DIALECT)
Q_PROPERTY(QObject* apmMavlinkStreamRateSettings READ apmMavlinkStreamRateSettings CONSTANT)
#endif
@@ -70,6 +72,7 @@ public:
PlanViewSettings* planViewSettings (void) { return _planViewSettings; }
BrandImageSettings* brandImageSettings (void) { return _brandImageSettings; }
OfflineMapsSettings* offlineMapsSettings (void) { return _offlineMapsSettings; }
+ FirmwareUpgradeSettings* firmwareUpgradeSettings (void) { return _firmwareUpgradeSettings; }
#if !defined(NO_ARDUPILOT_DIALECT)
APMMavlinkStreamRateSettings* apmMavlinkStreamRateSettings(void) { return _apmMavlinkStreamRateSettings; }
#endif
@@ -87,6 +90,7 @@ private:
PlanViewSettings* _planViewSettings;
BrandImageSettings* _brandImageSettings;
OfflineMapsSettings* _offlineMapsSettings;
+ FirmwareUpgradeSettings* _firmwareUpgradeSettings;
#if !defined(NO_ARDUPILOT_DIALECT)
APMMavlinkStreamRateSettings* _apmMavlinkStreamRateSettings;
#endif
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 099b02c..8ee1190 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -3334,6 +3334,10 @@ void Vehicle::_handleCommandAck(mavlink_message_t& message)
//_startPlanRequest();
}
+ if (ack.command == MAV_CMD_FLASH_BOOTLOADER && ack.result == MAV_RESULT_ACCEPTED) {
+ qgcApp()->showMessage(tr("Bootloader flash succeeded"));
+ }
+
if (_mavCommandQueue.count() && ack.command == _mavCommandQueue[0].command) {
_mavCommandAckTimer.stop();
showError = _mavCommandQueue[0].showError;
diff --git a/src/VehicleSetup/FirmwareUpgrade.qml b/src/VehicleSetup/FirmwareUpgrade.qml
index 113506a..74bef1e 100644
--- a/src/VehicleSetup/FirmwareUpgrade.qml
+++ b/src/VehicleSetup/FirmwareUpgrade.qml
@@ -60,8 +60,9 @@ SetupPage {
readonly property int _defaultFimwareTypePX4: 12
readonly property int _defaultFimwareTypeAPM: 3
- property var _defaultFirmwareFact: QGroundControl.settingsManager.appSettings.defaultFirmwareType
- property bool _defaultFirmwareIsPX4: true
+ property var _firmwareUpgradeSettings: QGroundControl.settingsManager.firmwareUpgradeSettings
+ property var _defaultFirmwareFact: _firmwareUpgradeSettings.defaultFirmwareType
+ property bool _defaultFirmwareIsPX4: true
property string firmwareWarningMessage
property bool controllerCompleted: false
@@ -76,6 +77,17 @@ SetupPage {
controller.cancel()
}
+ function firmwareVersionChanged(model) {
+ firmwareVersionWarningLabel.visible = false
+ // All of this bizarre, setting model to null and index to 1 and then to 0 is to work around
+ // strangeness in the combo box implementation. This sequence of steps correctly changes the combo model
+ // without generating any warnings and correctly updates the combo text with the new selection.
+ firmwareBuildTypeCombo.model = null
+ firmwareBuildTypeCombo.model = model
+ firmwareBuildTypeCombo.currentIndex = 1
+ firmwareBuildTypeCombo.currentIndex = 0
+ }
+
QGCPalette { id: qgcPal; colorGroupEnabled: true }
FirmwareUpgradeController {
@@ -155,7 +167,7 @@ SetupPage {
function updatePX4VersionDisplay() {
var versionString = ""
if (_advanced.checked) {
- switch (controller.selectedFirmwareType) {
+ switch (controller.selectedFirmwareBuildType) {
case FirmwareUpgradeController.StableFirmware:
versionString = controller.px4StableVersion
break
@@ -166,8 +178,8 @@ SetupPage {
} else {
versionString = controller.px4StableVersion
}
- px4FlightStackRadio1.text = qsTr("PX4 Flight Stack ") + versionString
- px4FlightStackRadio2.text = qsTr("PX4 Flight Stack ") + versionString
+ px4FlightStackRadio.text = qsTr("PX4 Pro ") + versionString
+ //px4FlightStackRadio2.text = qsTr("PX4 Pro ") + versionString
}
Component.onCompleted: {
@@ -177,12 +189,11 @@ SetupPage {
}
function accept() {
- hideDialog()
if (_singleFirmwareMode) {
- controller.flashSingleFirmwareMode(controller.selectedFirmwareType)
+ controller.flashSingleFirmwareMode(controller.selectedFirmwareBuildType)
} else {
var stack
- var firmwareType = firmwareVersionCombo.model.get(firmwareVersionCombo.currentIndex).firmwareType
+ var firmwareBuildType = firmwareBuildTypeCombo.model.get(firmwareBuildTypeCombo.currentIndex).firmwareType
var vehicleType = FirmwareUpgradeController.DefaultVehicleFirmware
if (px4Flow) {
@@ -191,11 +202,25 @@ SetupPage {
} else {
stack = apmFlightStack.checked ? FirmwareUpgradeController.AutoPilotStackAPM : FirmwareUpgradeController.AutoPilotStackPX4
if (apmFlightStack.checked) {
- vehicleType = controller.vehicleTypeFromVersionIndex(vehicleTypeSelectionCombo.currentIndex)
+ if (firmwareBuildType === FirmwareUpgradeController.CustomFirmware) {
+ vehicleType = apmVehicleTypeCombo.currentIndex
+ } else {
+ if (controller.apmFirmwareNames.length === 0) {
+ // Not ready yet, or no firmware available
+ return
+ }
+ var firmwareUrl = controller.apmFirmwareUrls[ardupilotFirmwareSelectionCombo.currentIndex]
+ if (firmwareUrl == "") {
+ return
+ }
+ controller.flashFirmwareUrl(controller.apmFirmwareUrls[ardupilotFirmwareSelectionCombo.currentIndex])
+ hideDialog()
+ return
+ }
}
}
-
- controller.flash(stack, firmwareType, vehicleType)
+ controller.flash(stack, firmwareBuildType, vehicleType)
+ hideDialog()
}
}
@@ -215,7 +240,7 @@ SetupPage {
}
ListModel {
- id: firmwareTypeList
+ id: firmwareBuildTypeList
ListElement {
text: qsTr("Standard Version (stable)")
@@ -288,66 +313,85 @@ SetupPage {
readonly property string _singleFirmwareLabel: qsTr("Press Ok to upgrade your vehicle.")
}
- function firmwareVersionChanged(model) {
- firmwareVersionWarningLabel.visible = false
- // All of this bizarre, setting model to null and index to 1 and then to 0 is to work around
- // strangeness in the combo box implementation. This sequence of steps correctly changes the combo model
- // without generating any warnings and correctly updates the combo text with the new selection.
- firmwareVersionCombo.model = null
- firmwareVersionCombo.model = model
- firmwareVersionCombo.currentIndex = 1
- firmwareVersionCombo.currentIndex = 0
- }
+ QGCLabel { text: qsTr("Flight Stack") }
+
+ RowLayout {
+ spacing: _margins
+ layoutDirection: px4FlightStackRadio.checked ? Qt.LeftToRight : Qt.RightToLeft
- // The following craziness of three radio buttons to represent two radio buttons is so that the
- // order can be changed such that the default firmware button is always on the top
+ // The following craziness of three radio buttons to represent two radio buttons is so that the
+ // order can be changed such that the default firmware button is always on the top
- QGCRadioButton {
- id: px4FlightStackRadio1
- exclusiveGroup: _defaultFirmwareIsPX4 ? firmwareGroup : null
- text: qsTr("PX4 Flight Stack ")
- textBold: _defaultFirmwareIsPX4
- checked: _defaultFirmwareIsPX4
- visible: _defaultFirmwareIsPX4 && !_singleFirmwareMode && !px4Flow
+ QGCRadioButton {
+ id: px4FlightStackRadio
+ exclusiveGroup: firmwareGroup
+ text: qsTr("PX4 Pro ")
+ textBold: _defaultFirmwareIsPX4
+ checked: _defaultFirmwareIsPX4
+ visible: !_singleFirmwareMode && !px4Flow
- onClicked: {
- _defaultFirmwareFact.rawValue = _defaultFimwareTypePX4
- parent.firmwareVersionChanged(firmwareTypeList)
+ onClicked: {
+ _defaultFirmwareFact.rawValue = _defaultFimwareTypePX4
+ firmwareVersionChanged(firmwareBuildTypeList)
+ }
}
- }
- QGCRadioButton {
- id: apmFlightStack
- exclusiveGroup: firmwareGroup
- text: qsTr("ArduPilot Flight Stack")
- textBold: !_defaultFirmwareIsPX4
- checked: !_defaultFirmwareIsPX4
- visible: !_singleFirmwareMode && !px4Flow
-
- onClicked: {
- _defaultFirmwareFact.rawValue = _defaultFimwareTypeAPM
- parent.firmwareVersionChanged(firmwareTypeList)
+ QGCRadioButton {
+ id: apmFlightStack
+ exclusiveGroup: firmwareGroup
+ text: qsTr("ArduPilot")
+ textBold: !_defaultFirmwareIsPX4
+ checked: !_defaultFirmwareIsPX4
+ visible: !_singleFirmwareMode && !px4Flow
+
+ onClicked: {
+ _defaultFirmwareFact.rawValue = _defaultFimwareTypeAPM
+ firmwareVersionChanged(firmwareBuildTypeList)
+ }
}
}
- QGCRadioButton {
- id: px4FlightStackRadio2
- exclusiveGroup: _defaultFirmwareIsPX4 ? null : firmwareGroup
- text: qsTr("PX4 Flight Stack ")
- visible: !_defaultFirmwareIsPX4 && !_singleFirmwareMode && !px4Flow
+ FactComboBox {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ visible: !px4Flow && apmFlightStack.checked
+ fact: _firmwareUpgradeSettings.apmChibiOS
+ indexModel: false
+ }
- onClicked: {
- _defaultFirmwareFact.rawValue = _defaultFimwareTypePX4
- parent.firmwareVersionChanged(firmwareTypeList)
- }
+ FactComboBox {
+ id: apmVehicleTypeCombo
+ anchors.left: parent.left
+ anchors.right: parent.right
+ visible: !px4Flow && apmFlightStack.checked
+ fact: _firmwareUpgradeSettings.apmVehicleType
+ indexModel: false
}
QGCComboBox {
- id: vehicleTypeSelectionCombo
+ id: ardupilotFirmwareSelectionCombo
anchors.left: parent.left
anchors.right: parent.right
- visible: !px4Flow && apmFlightStack.checked
- model: controller.apmAvailableVersions
+ visible: !px4Flow && apmFlightStack.checked && !controller.downloadingFirmwareList && controller.apmFirmwareNames.length !== 0
+ model: controller.apmFirmwareNames
+
+ onModelChanged: console.log("model", model)
+ }
+
+ QGCLabel {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ wrapMode: Text.WordWrap
+ text: qsTr("Downloading list of available firmwares...")
+ visible: controller.downloadingFirmwareList
+ }
+
+ QGCLabel {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ wrapMode: Text.WordWrap
+ text: qsTr("No Firmware Available")
+ visible: !controller.downloadingFirmwareList && controller.apmFirmwareNames.length === 0
}
QGCComboBox {
@@ -377,7 +421,7 @@ SetupPage {
checked: px4Flow ? true : false
onClicked: {
- firmwareVersionCombo.currentIndex = 0
+ firmwareBuildTypeCombo.currentIndex = 0
firmwareVersionWarningLabel.visible = false
updatePX4VersionDisplay()
}
@@ -399,15 +443,15 @@ SetupPage {
}
QGCComboBox {
- id: firmwareVersionCombo
+ id: firmwareBuildTypeCombo
anchors.left: parent.left
anchors.right: parent.right
visible: showFirmwareTypeSelection
- model: _singleFirmwareMode ? singleFirmwareModeTypeList : (px4Flow ? px4FlowTypeList : firmwareTypeList)
- currentIndex: controller.selectedFirmwareType
+ model: _singleFirmwareMode ? singleFirmwareModeTypeList : (px4Flow ? px4FlowTypeList : firmwareBuildTypeList)
+ currentIndex: controller.selectedFirmwareBuildType
onActivated: {
- controller.selectedFirmwareType = model.get(index).firmwareType
+ controller.selectedFirmwareBuildType = model.get(index).firmwareType
if (model.get(index).firmwareType === FirmwareUpgradeController.BetaFirmware) {
firmwareVersionWarningLabel.visible = true
firmwareVersionWarningLabel.text = qsTr("WARNING: BETA FIRMWARE. ") +
diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc
index 365e5d0..5132f66 100644
--- a/src/VehicleSetup/FirmwareUpgradeController.cc
+++ b/src/VehicleSetup/FirmwareUpgradeController.cc
@@ -7,11 +7,6 @@
*
****************************************************************************/
-
-/// @file
-/// @brief PX4 Firmware Upgrade UI
-/// @author Don Gagne
-
#include "FirmwareUpgradeController.h"
#include "Bootloader.h"
#include "QGCQFileDialog.h"
@@ -19,6 +14,8 @@
#include "QGCFileDownload.h"
#include "QGCOptions.h"
#include "QGCCorePlugin.h"
+#include "FirmwareUpgradeSettings.h"
+#include "SettingsManager.h"
#include
#include
@@ -27,31 +24,57 @@
#include
#include
+const char* FirmwareUpgradeController::_manifestFirmwareJsonKey = "firmware";
+const char* FirmwareUpgradeController::_manifestBoardIdJsonKey = "board_id";
+const char* FirmwareUpgradeController::_manifestMavTypeJsonKey = "mav-type";
+const char* FirmwareUpgradeController::_manifestFormatJsonKey = "format";
+const char* FirmwareUpgradeController::_manifestUrlJsonKey = "url";
+const char* FirmwareUpgradeController::_manifestMavFirmwareVersionTypeJsonKey = "mav-firmware-version-type";
+const char* FirmwareUpgradeController::_manifestUSBIDJsonKey = "USBID";
+const char* FirmwareUpgradeController::_manifestMavFirmwareVersionJsonKey = "mav-firmware-version";
+const char* FirmwareUpgradeController::_manifestBootloaderStrJsonKey = "bootloader_str";
+const char* FirmwareUpgradeController::_manifestLatestKey = "latest";
+const char* FirmwareUpgradeController::_manifestPlatformKey = "platform";
+const char* FirmwareUpgradeController::_manifestBrandNameKey = "brand_name";
+
struct FirmwareToUrlElement_t {
- FirmwareUpgradeController::AutoPilotStackType_t stackType;
- FirmwareUpgradeController::FirmwareType_t firmwareType;
- FirmwareUpgradeController::FirmwareVehicleType_t vehicleType;
- QString url;
+ FirmwareUpgradeController::AutoPilotStackType_t stackType;
+ FirmwareUpgradeController::FirmwareBuildType_t firmwareType;
+ FirmwareUpgradeController::FirmwareVehicleType_t vehicleType;
+ QString url;
};
uint qHash(const FirmwareUpgradeController::FirmwareIdentifier& firmwareId)
{
return static_cast(( firmwareId.autopilotStackType |
- (firmwareId.firmwareType << 8) |
- (firmwareId.firmwareVehicleType << 16) ));
+ (firmwareId.firmwareType << 8) |
+ (firmwareId.firmwareVehicleType << 16) ));
}
/// @Brief Constructs a new FirmwareUpgradeController Widget. This widget is used within the PX4VehicleConfig set of screens.
FirmwareUpgradeController::FirmwareUpgradeController(void)
: _singleFirmwareURL (qgcApp()->toolbox()->corePlugin()->options()->firmwareUpgradeSingleURL())
, _singleFirmwareMode (!_singleFirmwareURL.isEmpty())
+ , _downloadingFirmwareList (false)
, _downloadManager (nullptr)
, _downloadNetworkReply (nullptr)
, _statusLog (nullptr)
- , _selectedFirmwareType (StableFirmware)
+ , _selectedFirmwareBuildType (StableFirmware)
, _image (nullptr)
, _apmBoardDescriptionReplaceText ("")
+ , _apmChibiOSSetting (qgcApp()->toolbox()->settingsManager()->firmwareUpgradeSettings()->apmChibiOS())
+ , _apmVehicleTypeSetting (qgcApp()->toolbox()->settingsManager()->firmwareUpgradeSettings()->apmVehicleType())
{
+ _manifestMavFirmwareVersionTypeToFirmwareBuildTypeMap["OFFICIAL"] = StableFirmware;
+ _manifestMavFirmwareVersionTypeToFirmwareBuildTypeMap["BETA"] = BetaFirmware;
+ _manifestMavFirmwareVersionTypeToFirmwareBuildTypeMap["DEV"] = DeveloperFirmware;
+
+ _manifestMavTypeToFirmwareVehicleTypeMap["Copter"] = CopterFirmware;
+ _manifestMavTypeToFirmwareVehicleTypeMap["HELICOPTER"] = HeliFirmware;
+ _manifestMavTypeToFirmwareVehicleTypeMap["FIXED_WING"] = PlaneFirmware;
+ _manifestMavTypeToFirmwareVehicleTypeMap["GROUND_ROVER"] = RoverFirmware;
+ _manifestMavTypeToFirmwareVehicleTypeMap["SUBMARINE"] = SubFirmware;
+
_threadController = new PX4FirmwareUpgradeThreadController(this);
Q_CHECK_PTR(_threadController);
@@ -70,8 +93,12 @@ FirmwareUpgradeController::FirmwareUpgradeController(void)
connect(&_eraseTimer, &QTimer::timeout, this, &FirmwareUpgradeController::_eraseProgressTick);
+ connect(_apmChibiOSSetting, &Fact::rawValueChanged, this, &FirmwareUpgradeController::_buildAPMFirmwareNames);
+ connect(_apmVehicleTypeSetting, &Fact::rawValueChanged, this, &FirmwareUpgradeController::_buildAPMFirmwareNames);
+
_initFirmwareHash();
_determinePX4StableVersion();
+ _downloadArduPilotManifest();
}
FirmwareUpgradeController::~FirmwareUpgradeController()
@@ -97,7 +124,7 @@ void FirmwareUpgradeController::startBoardSearch(void)
}
void FirmwareUpgradeController::flash(AutoPilotStackType_t stackType,
- FirmwareType_t firmwareType,
+ FirmwareBuildType_t firmwareType,
FirmwareVehicleType_t vehicleType)
{
qCDebug(FirmwareUpgradeLog) << "_flash stackType:firmwareType:vehicleType" << stackType << firmwareType << vehicleType;
@@ -108,6 +135,18 @@ void FirmwareUpgradeController::flash(AutoPilotStackType_t stackType,
// We haven't found the bootloader yet. Need to wait until then to flash
_startFlashWhenBootloaderFound = true;
_startFlashWhenBootloaderFoundFirmwareIdentity = firmwareId;
+ _firmwareFilename.clear();
+ }
+}
+
+void FirmwareUpgradeController::flashFirmwareUrl(QString firmwareFlashUrl)
+{
+ _firmwareFilename = firmwareFlashUrl;
+ if (_bootloaderFound) {
+ _downloadFirmware();
+ } else {
+ // We haven't found the bootloader yet. Need to wait until then to flash
+ _startFlashWhenBootloaderFound = true;
}
}
@@ -116,7 +155,7 @@ void FirmwareUpgradeController::flash(const FirmwareIdentifier& firmwareId)
flash(firmwareId.autopilotStackType, firmwareId.firmwareType, firmwareId.firmwareVehicleType);
}
-void FirmwareUpgradeController::flashSingleFirmwareMode(FirmwareType_t firmwareType)
+void FirmwareUpgradeController::flashSingleFirmwareMode(FirmwareBuildType_t firmwareType)
{
flash(SingleFirmwareMode, firmwareType, DefaultVehicleFirmware);
}
@@ -129,9 +168,12 @@ void FirmwareUpgradeController::cancel(void)
void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPortInfo& info, int boardType, QString boardName)
{
- _foundBoardInfo = info;
- _foundBoardType = static_cast(boardType);
- _foundBoardTypeName = boardName;
+ _foundBoardInfo = info;
+ _foundBoardType = static_cast(boardType);
+ _foundBoardTypeName = boardName;
+
+ qDebug() << info.manufacturer() << info.description();
+
_startFlashWhenBootloaderFound = false;
if (_foundBoardType == QGCSerialPortInfo::BoardTypeSiKRadio) {
@@ -178,7 +220,9 @@ void FirmwareUpgradeController::_foundBootloader(int bootloaderVersion, int boar
flash(_startFlashWhenBootloaderFoundFirmwareIdentity);
}
- _loadAPMVersions(_bootloaderBoardID);
+ if (_rgManifestFirmwareInfo.count()) {
+ _buildAPMFirmwareNames();
+ }
}
@@ -197,19 +241,6 @@ void FirmwareUpgradeController::_initFirmwareHash()
{ AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://gumstix-aerocore.s3.amazonaws.com/PX4/stable/aerocore_default.px4"},
{ AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://gumstix-aerocore.s3.amazonaws.com/PX4/beta/aerocore_default.px4"},
{ AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://gumstix-aerocore.s3.amazonaws.com/PX4/master/aerocore_default.px4"},
- #if !defined(NO_ARDUPILOT_DIALECT)
- { AutoPilotStackAPM, BetaFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/beta/PX4/ArduCopter-v2.px4"},
- { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/stable/PX4-heli/ArduCopter-v2.px4"},
- { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Plane/stable/PX4/ArduPlane-v2.px4"},
- { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Rover/stable/PX4/APMrover2-v2.px4"},
- { AutoPilotStackAPM, BetaFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/beta/PX4-heli/ArduCopter-v2.px4"},
- { AutoPilotStackAPM, BetaFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/beta/PX4/ArduPlane-v2.px4"},
- { AutoPilotStackAPM, BetaFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/beta/PX4/APMrover2-v2.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, CopterFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4/ArduCopter-v2.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, HeliFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-heli/ArduCopter-v2.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, PlaneFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Plane/latest/PX4/ArduPlane-v2.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, RoverFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Rover/latest/PX4/APMrover2-v2.px4"}
- #endif
};
//////////////////////////////////// AUAVX2_1 firmwares //////////////////////////////////////////////////
@@ -217,23 +248,6 @@ void FirmwareUpgradeController::_initFirmwareHash()
{ AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/auav-x21_default.px4"},
{ AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/auav-x21_default.px4"},
{ AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/auav-x21_default.px4"},
- #if !defined(NO_ARDUPILOT_DIALECT)
- { AutoPilotStackAPM, StableFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4/ArduCopter-v3.px4"},
- { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v3.px4"},
- { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v2.px4"},
- { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v2.px4"},
- { AutoPilotStackAPM, StableFirmware, SubFirmware, "http://firmware.ardupilot.org/Sub/stable/PX4/ArduSub-v2.px4"},
- { AutoPilotStackAPM, BetaFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/beta/PX4/ArduCopter-v3.px4"},
- { AutoPilotStackAPM, BetaFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/beta/PX4-heli/ArduCopter-v3.px4"},
- { AutoPilotStackAPM, BetaFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/beta/PX4/ArduPlane-v3.px4"},
- { AutoPilotStackAPM, BetaFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/beta/PX4/APMrover2-v3.px4"},
- { AutoPilotStackAPM, BetaFirmware, SubFirmware, "http://firmware.ardupilot.org/Sub/beta/PX4/ArduSub-v3.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/latest/PX4/ArduCopter-v3.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/latest/PX4-heli/ArduCopter-v3.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/latest/PX4/ArduPlane-v3.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/latest/PX4/APMrover2-v3.px4"},
- { AutoPilotStackAPM, DeveloperFirmware, SubFirmware, "http://firmware.ardupilot.org/Sub/latest/PX4/ArduSub-v3.px4"}
- #endif
};
//////////////////////////////////// MindPXFMUV2 firmwares //////////////////////////////////////////////////
FirmwareToUrlElement_t rgMindPXFMUV2FirmwareArray[] = {
@@ -288,7 +302,7 @@ void FirmwareUpgradeController::_initFirmwareHash()
{ ThreeDRRadio, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/SiK/stable/radio~hm_trp.ihx"}
};
- // We build the maps for PX4 and ArduPilot firmwares dynamically using the data below
+ // We build the maps for PX4 firmwares dynamically using the data below
#if 0
Example URLs for PX4 and ArduPilot
@@ -298,77 +312,14 @@ void FirmwareUpgradeController::_initFirmwareHash()
#endif
QString px4Url ("http://px4-travis.s3.amazonaws.com/Firmware/%1/px4fmu-%2_default.px4");
- QString apmUrl ("http://firmware.ardupilot.org/%1/%2/%3/%4-v%5.px4");
- QString apmChibiOSUrl ("http://firmware.ardupilot.org/%1/%2/fmuv%3%4/%5.apj");
- QMap px4MapFirmwareTypeToDir;
+ QMap px4MapFirmwareTypeToDir;
px4MapFirmwareTypeToDir[StableFirmware] = QStringLiteral("stable");
px4MapFirmwareTypeToDir[BetaFirmware] = QStringLiteral("beta");
px4MapFirmwareTypeToDir[DeveloperFirmware] = QStringLiteral("master");
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmMapVehicleTypeToDir;
- apmMapVehicleTypeToDir[CopterFirmware] = QStringLiteral("Copter");
- apmMapVehicleTypeToDir[HeliFirmware] = QStringLiteral("Copter");
- apmMapVehicleTypeToDir[PlaneFirmware] = QStringLiteral("Plane");
- apmMapVehicleTypeToDir[RoverFirmware] = QStringLiteral("Rover");
- apmMapVehicleTypeToDir[SubFirmware] = QStringLiteral("Sub");
-#endif
-
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmChibiOSMapVehicleTypeToDir;
- apmChibiOSMapVehicleTypeToDir[CopterChibiOSFirmware] = QStringLiteral("Copter");
- apmChibiOSMapVehicleTypeToDir[HeliChibiOSFirmware] = QStringLiteral("Copter");
- apmChibiOSMapVehicleTypeToDir[PlaneChibiOSFirmware] = QStringLiteral("Plane");
- apmChibiOSMapVehicleTypeToDir[RoverChibiOSFirmware] = QStringLiteral("Rover");
- apmChibiOSMapVehicleTypeToDir[SubChibiOSFirmware] = QStringLiteral("Sub");
-#endif
-
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmMapFirmwareTypeToDir;
- apmMapFirmwareTypeToDir[StableFirmware] = QStringLiteral("stable");
- apmMapFirmwareTypeToDir[BetaFirmware] = QStringLiteral("beta");
- apmMapFirmwareTypeToDir[DeveloperFirmware] = QStringLiteral("latest");
-#endif
-
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmMapVehicleTypeToPX4Dir;
- apmMapVehicleTypeToPX4Dir[CopterFirmware] = QStringLiteral("PX4");
- apmMapVehicleTypeToPX4Dir[HeliFirmware] = QStringLiteral("PX4-heli");
- apmMapVehicleTypeToPX4Dir[PlaneFirmware] = QStringLiteral("PX4");
- apmMapVehicleTypeToPX4Dir[RoverFirmware] = QStringLiteral("PX4");
- apmMapVehicleTypeToPX4Dir[SubFirmware] = QStringLiteral("PX4");
-#endif
-
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmMapVehicleTypeToFilename;
- apmMapVehicleTypeToFilename[CopterFirmware] = QStringLiteral("ArduCopter");
- apmMapVehicleTypeToFilename[HeliFirmware] = QStringLiteral("ArduCopter");
- apmMapVehicleTypeToFilename[PlaneFirmware] = QStringLiteral("ArduPlane");
- apmMapVehicleTypeToFilename[RoverFirmware] = QStringLiteral("APMrover2");
- apmMapVehicleTypeToFilename[SubFirmware] = QStringLiteral("ArduSub");
-#endif
-
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmChibiOSMapVehicleTypeToFmuDir;
- apmChibiOSMapVehicleTypeToFmuDir[CopterChibiOSFirmware] = QString();
- apmChibiOSMapVehicleTypeToFmuDir[HeliChibiOSFirmware] = QStringLiteral("-heli");
- apmChibiOSMapVehicleTypeToFmuDir[PlaneChibiOSFirmware] = QString();
- apmChibiOSMapVehicleTypeToFmuDir[RoverChibiOSFirmware] = QString();
- apmChibiOSMapVehicleTypeToFmuDir[SubChibiOSFirmware] = QString();
-#endif
-
-#if !defined(NO_ARDUPILOT_DIALECT)
- QMap apmChibiOSMapVehicleTypeToFilename;
- apmChibiOSMapVehicleTypeToFilename[CopterChibiOSFirmware] = QStringLiteral("arducopter");
- apmChibiOSMapVehicleTypeToFilename[HeliChibiOSFirmware] = QStringLiteral("arducopter-heli");
- apmChibiOSMapVehicleTypeToFilename[PlaneChibiOSFirmware] = QStringLiteral("arduplane");
- apmChibiOSMapVehicleTypeToFilename[RoverChibiOSFirmware] = QStringLiteral("ardurover");
- apmChibiOSMapVehicleTypeToFilename[SubChibiOSFirmware] = QStringLiteral("ardusub");
-#endif
-
// PX4 Firmwares
- for (const FirmwareType_t& firmwareType: px4MapFirmwareTypeToDir.keys()) {
+ for (const FirmwareBuildType_t& firmwareType: px4MapFirmwareTypeToDir.keys()) {
QString dir = px4MapFirmwareTypeToDir[firmwareType];
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v5"));
_rgFMUV4PROFirmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v4pro"));
@@ -377,49 +328,6 @@ void FirmwareUpgradeController::_initFirmwareHash()
_rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v2"));
}
-#if !defined(NO_ARDUPILOT_DIALECT)
- // ArduPilot non-ChibiOS Firmwares for direct board id to fmu mappings
- for (const FirmwareType_t& firmwareType: apmMapFirmwareTypeToDir.keys()) {
- QString firmwareTypeDir = apmMapFirmwareTypeToDir[firmwareType];
- for (const FirmwareVehicleType_t& vehicleType: apmMapVehicleTypeToDir.keys()) {
- QString vehicleTypeDir = apmMapVehicleTypeToDir[vehicleType];
- QString px4Dir = apmMapVehicleTypeToPX4Dir[vehicleType];
- QString filename = apmMapVehicleTypeToFilename[vehicleType];
- _rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("5"));
- _rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("4"));
- _rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("3"));
- _rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("2"));
- }
- }
-
- // ArduPilot ChibiOS Firmwares for direct board id to fmu mappings. Used when bootloader is not new ArduPilot bootloader.
- for (const FirmwareType_t& firmwareType: apmMapFirmwareTypeToDir.keys()) {
- QString firmwareTypeDir = apmMapFirmwareTypeToDir[firmwareType];
- for (const FirmwareVehicleType_t& vehicleType: apmChibiOSMapVehicleTypeToDir.keys()) {
- QString vehicleTypeDir = apmChibiOSMapVehicleTypeToDir[vehicleType];
- QString fmuDir = apmChibiOSMapVehicleTypeToFmuDir[vehicleType];
- QString filename = apmChibiOSMapVehicleTypeToFilename[vehicleType];
- _rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("5").arg(fmuDir).arg(filename));
- _rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("4").arg(fmuDir).arg(filename));
- _rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("3").arg(fmuDir).arg(filename));
- _rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("2").arg(fmuDir).arg(filename));
- }
- }
-
- // ArduPilot ChibiOS Firmwares when board id is an unknown type but follows ArduPilot port info naming conventions.
- // This is only used if the board is using the new ArduPilot bootloader port naming scheme.
- for (const FirmwareType_t& firmwareType: apmMapFirmwareTypeToDir.keys()) {
- QString firmwareTypeDir = apmMapFirmwareTypeToDir[firmwareType];
- for (const FirmwareVehicleType_t& vehicleType: apmChibiOSMapVehicleTypeToDir.keys()) {
- QString namedURL("http://firmware.ardupilot.org/%1/%2/%3%4/%5.apj");
- QString vehicleTypeDir = apmChibiOSMapVehicleTypeToDir[vehicleType];
- QString fmuDir = apmChibiOSMapVehicleTypeToFmuDir[vehicleType];
- QString filename = apmChibiOSMapVehicleTypeToFilename[vehicleType];
- _rgAPMChibiosReplaceNamedBoardFirmware.insert(FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), namedURL.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(_apmBoardDescriptionReplaceText).arg(fmuDir).arg(filename));
- }
- }
-#endif
-
int size = sizeof(rgAeroCoreFirmwareArray)/sizeof(rgAeroCoreFirmwareArray[0]);
for (int i = 0; i < size; i++) {
const FirmwareToUrlElement_t& element = rgAeroCoreFirmwareArray[i];
@@ -550,24 +458,6 @@ QHash* FirmwareUpgradeCo
break;
}
- // Check for ArduPilot ChibiOS bootloader
- QStringList rgManufacturers = { QStringLiteral("ArduPilot"), QStringLiteral("Hex/ProfiCNC"), QStringLiteral("Holybro") };
- QString apmDescriptionSuffix("-BL");
- if (rgManufacturers.contains(_foundBoardInfo.manufacturer()) && _foundBoardInfo.description().endsWith(apmDescriptionSuffix)) {
- // Board ios using a ChibiOS bootloader. Prefer naming scheme from that over board ids for ArduPilot entries.
-
- // First remove the ChibiOS by board id entries from the list
- for (const FirmwareIdentifier& firmwareId: _rgAPMChibiosReplaceNamedBoardFirmware.keys()) {
- _rgFirmwareDynamic.remove(firmwareId);
- }
-
- // Now add the ChibiOS by board description entries to the list
- for (const FirmwareIdentifier& firmwareId: _rgAPMChibiosReplaceNamedBoardFirmware.keys()) {
- QString namedUrl = _rgAPMChibiosReplaceNamedBoardFirmware[firmwareId];
- _rgFirmwareDynamic.insert(firmwareId, namedUrl.replace(_apmBoardDescriptionReplaceText, _foundBoardInfo.description().left(_foundBoardInfo.description().length() - apmDescriptionSuffix.length())));
- }
- }
-
return &_rgFirmwareDynamic;
}
@@ -659,7 +549,7 @@ void FirmwareUpgradeController::_firmwareDownloadError(QString errorMsg)
}
/// @brief returns firmware type as a string
-QString FirmwareUpgradeController::firmwareTypeAsString(FirmwareType_t type) const
+QString FirmwareUpgradeController::firmwareTypeAsString(FirmwareBuildType_t type) const
{
switch (type) {
case StableFirmware:
@@ -757,119 +647,62 @@ void FirmwareUpgradeController::_eraseComplete(void)
_eraseTimer.stop();
}
-void FirmwareUpgradeController::_loadAPMVersions(uint32_t bootloaderBoardID)
+void FirmwareUpgradeController::setSelectedFirmwareBuildType(FirmwareBuildType_t firmwareType)
{
- _apmVersionMap.clear();
-
- QHash* prgFirmware = _firmwareHashForBoardId(static_cast(bootloaderBoardID));
-
- for (FirmwareIdentifier firmwareId: prgFirmware->keys()) {
- if (firmwareId.autopilotStackType == AutoPilotStackAPM) {
- QString versionFile = QFileInfo(prgFirmware->value(firmwareId)).path() + "/git-version.txt";
-
- qCDebug(FirmwareUpgradeLog) << "Downloading" << versionFile;
- QGCFileDownload* downloader = new QGCFileDownload(this);
- connect(downloader, &QGCFileDownload::downloadFinished, this, &FirmwareUpgradeController::_apmVersionDownloadFinished);
- downloader->download(versionFile);
- }
- }
+ _selectedFirmwareBuildType = firmwareType;
+ emit selectedFirmwareBuildTypeChanged(_selectedFirmwareBuildType);
+ _buildAPMFirmwareNames();
}
-void FirmwareUpgradeController::_apmVersionDownloadFinished(QString remoteFile, QString localFile)
+void FirmwareUpgradeController::_buildAPMFirmwareNames(void)
{
- qCDebug(FirmwareUpgradeLog) << "Download complete" << remoteFile << localFile;
-
- // Now read the version file and pull out the version string
+ qCDebug(FirmwareUpgradeLog) << "_buildAPMFirmwareNames";
- QFile versionFile(localFile);
- versionFile.open(QIODevice::ReadOnly | QIODevice::Text);
- QTextStream stream(&versionFile);
- QString versionContents = stream.readAll();
+ bool chibios = _apmChibiOSSetting->rawValue().toInt() == 0;
+ FirmwareVehicleType_t vehicleType = static_cast(_apmVehicleTypeSetting->rawValue().toInt());
- QString version;
- QRegularExpression re("APMVERSION: (.*)$");
- QRegularExpressionMatch match = re.match(versionContents);
- if (match.hasMatch()) {
- version = match.captured(1);
- }
-
- if (version.isEmpty()) {
- qWarning() << "Unable to parse version info from file" << remoteFile;
- sender()->deleteLater();
- return;
- }
+ _apmFirmwareNames.clear();
+ _apmFirmwareUrls.clear();
- // In order to determine the firmware and vehicle type for this file we find the matching entry in the firmware list
+ QString apmDescriptionSuffix("-BL");
+ bool bootloaderMatch = _foundBoardInfo.description().endsWith(apmDescriptionSuffix);
+
+ for (const ManifestFirmwareInfo_t& firmwareInfo: _rgManifestFirmwareInfo) {
+ bool match = false;
+ if (firmwareInfo.firmwareBuildType == _selectedFirmwareBuildType && firmwareInfo.chibios == chibios && firmwareInfo.vehicleType == vehicleType) {
+ if (bootloaderMatch) {
+ if (firmwareInfo.rgBootloaderPortString.contains(_foundBoardInfo.description())) {
+ qCDebug(FirmwareUpgradeLog) << "Bootloader match:" << firmwareInfo.friendlyName << _foundBoardInfo.description() << firmwareInfo.rgBootloaderPortString << firmwareInfo.url << firmwareInfo.vehicleType;
+ match = true;
+ }
+ } else {
+ if (firmwareInfo.rgVID.contains(_foundBoardInfo.vendorIdentifier()) && firmwareInfo.rgPID.contains(_foundBoardInfo.productIdentifier())) {
+ qCDebug(FirmwareUpgradeLog) << "Fallback match:" << firmwareInfo.friendlyName << _foundBoardInfo.vendorIdentifier() << _foundBoardInfo.productIdentifier() << _bootloaderBoardID << firmwareInfo.url << firmwareInfo.vehicleType;
+ match = true;
+ }
+ }
+ }
- QHash* prgFirmware = _firmwareHashForBoardId(static_cast(_bootloaderBoardID));
+ // Do a final filter on fmuv2/fmuv3
+ if (match && _bootloaderBoardID == Bootloader::boardIDPX4FMUV3) {
+ match = !firmwareInfo.fmuv2;
+ }
- QString remotePath = QFileInfo(remoteFile).path();
- for (FirmwareIdentifier firmwareId: prgFirmware->keys()) {
- if (remotePath == QFileInfo((*prgFirmware)[firmwareId]).path()) {
- qCDebug(FirmwareUpgradeLog) << "Adding version to map, version:firwmareType:vehicleType" << version << firmwareId.firmwareType << firmwareId.firmwareVehicleType;
- _apmVersionMap[firmwareId.firmwareType][firmwareId.firmwareVehicleType] = version;
+ if (match) {
+ _apmFirmwareNames.append(firmwareInfo.friendlyName);
+ _apmFirmwareUrls.append(firmwareInfo.url);
}
}
- emit apmAvailableVersionsChanged();
- sender()->deleteLater();
-}
-
-void FirmwareUpgradeController::setSelectedFirmwareType(FirmwareType_t firmwareType)
-{
- _selectedFirmwareType = firmwareType;
- emit selectedFirmwareTypeChanged(_selectedFirmwareType);
- emit apmAvailableVersionsChanged();
-}
-
-QStringList FirmwareUpgradeController::apmAvailableVersions(void)
-{
- QStringList list;
- QList vehicleTypes;
-
- // This allows us to force the order of the combo box display
- vehicleTypes << CopterChibiOSFirmware << HeliChibiOSFirmware << PlaneChibiOSFirmware << RoverChibiOSFirmware << SubChibiOSFirmware << CopterFirmware << HeliFirmware << PlaneFirmware << RoverFirmware << SubFirmware;
-
- _apmVehicleTypeFromCurrentVersionList.clear();
-
- for (FirmwareVehicleType_t vehicleType: vehicleTypes) {
- if (_apmVersionMap[_selectedFirmwareType].contains(vehicleType)) {
- QString version;
-
- switch (vehicleType) {
- case CopterFirmware:
- version = tr("NuttX - MultiRotor:");
- break;
- case HeliFirmware:
- version = tr("NuttX - Heli:");
- break;
- case CopterChibiOSFirmware:
- version = tr("ChibiOS- MultiRotor:");
- break;
- case HeliChibiOSFirmware:
- version = tr("ChibiOS - Heli:");
- break;
- case PlaneChibiOSFirmware:
- case RoverChibiOSFirmware:
- case SubChibiOSFirmware:
- version = tr("ChibiOS - ");
- break;
- default:
- version = tr("NuttX - ");
- break;
- }
-
- version += _apmVersionMap[_selectedFirmwareType][vehicleType];
- _apmVehicleTypeFromCurrentVersionList.append(vehicleType);
-
- list << version;
- }
+ if (_apmFirmwareNames.count() > 1) {
+ _apmFirmwareNames.prepend(tr("Choose board type"));
+ _apmFirmwareUrls.prepend(QString());
}
- return list;
+ emit apmFirmwareNamesChanged();
}
-FirmwareUpgradeController::FirmwareVehicleType_t FirmwareUpgradeController::vehicleTypeFromVersionIndex(int index)
+FirmwareUpgradeController::FirmwareVehicleType_t FirmwareUpgradeController::vehicleTypeFromFirmwareSelectionIndex(int index)
{
if (index < 0 || index >= _apmVehicleTypeFromCurrentVersionList.count()) {
qWarning() << "Invalid index, index:count" << index << _apmVehicleTypeFromCurrentVersionList.count();
@@ -944,3 +777,147 @@ void FirmwareUpgradeController::_px4ReleasesGithubDownloadError(QString errorMsg
{
qCWarning(FirmwareUpgradeLog) << "PX4 releases github download failed" << errorMsg;
}
+
+void FirmwareUpgradeController::_downloadArduPilotManifest(void)
+{
+ _downloadingFirmwareList = true;
+ emit downloadingFirmwareListChanged(true);
+
+ QGCFileDownload* downloader = new QGCFileDownload(this);
+ connect(downloader, &QGCFileDownload::downloadFinished, this, &FirmwareUpgradeController::_ardupilotManifestDownloadFinished);
+ connect(downloader, &QGCFileDownload::error, this, &FirmwareUpgradeController::_ardupilotManifestDownloadError);
+#if 0
+ downloader->download(QStringLiteral("http://firmware.ardupilot.org/manifest.json.gz"));
+#else
+ downloader->download(QStringLiteral("http://firmware.ardupilot.org/manifest.json"));
+#endif
+}
+
+void FirmwareUpgradeController::_ardupilotManifestDownloadFinished(QString remoteFile, QString localFile)
+{
+ Q_UNUSED(remoteFile);
+
+ // Delete the QGCFileDownload object
+ sender()->deleteLater();
+
+ qDebug() << "_ardupilotManifestDownloadFinished" << remoteFile << localFile;
+
+#if 0
+ QFile gzipFile(localFile);
+ if (!gzipFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot firmware manifest file" << localFile << gzipFile.errorString();
+ QFile::remove(localFile);
+ return;
+ }
+
+ // Store decompressed size as first four bytes. This is required by qUncompress routine.
+ QByteArray raw;
+ int decompressedSize = 3073444;
+ raw.append((unsigned char)((decompressedSize >> 24) & 0xFF));
+ raw.append((unsigned char)((decompressedSize >> 16) & 0xFF));
+ raw.append((unsigned char)((decompressedSize >> 8) & 0xFF));
+ raw.append((unsigned char)((decompressedSize >> 0) & 0xFF));
+
+ raw.append(gzipFile.readAll());
+ QByteArray bytes = qUncompress(raw);
+#else
+
+
+ QFile jsonFile(localFile);
+ if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot firmware manifest file" << localFile << jsonFile.errorString();
+ QFile::remove(localFile);
+ return;
+ }
+ QByteArray bytes = jsonFile.readAll();
+ jsonFile.close();
+#endif
+ QFile::remove(localFile);
+
+ QJsonParseError jsonParseError;
+ QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError);
+ if (jsonParseError.error != QJsonParseError::NoError) {
+ qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot manifest json document" << localFile << jsonParseError.errorString();
+ }
+
+
+
+
+ QJsonObject json = doc.object();
+ QJsonArray rgFirmware = json[_manifestFirmwareJsonKey].toArray();
+
+ for (int i=0; i(firmwareJson[_manifestBoardIdJsonKey].toInt());
+ firmwareInfo.firmwareBuildType = firmwareBuildType;
+ firmwareInfo.vehicleType = firmwareVehicleType;
+ firmwareInfo.url = firmwareJson[_manifestUrlJsonKey].toString();
+ firmwareInfo.version = firmwareJson[_manifestMavFirmwareVersionJsonKey].toString();
+ firmwareInfo.chibios = format == QStringLiteral("apj");
+ firmwareInfo.fmuv2 = platform.contains(QStringLiteral("fmuv2"));
+
+ QJsonArray bootloaderArray = firmwareJson[_manifestBootloaderStrJsonKey].toArray();
+ for (int j=0; j
-
-#ifndef FirmwareUpgradeController_H
-#define FirmwareUpgradeController_H
+#pragma once
#include "PX4FirmwareUpgradeThread.h"
#include "LinkManager.h"
#include "FirmwareImage.h"
+#include "Fact.h"
#include
#include
@@ -38,7 +34,7 @@ class FirmwareUpgradeController : public QObject
public:
typedef enum {
- AutoPilotStackPX4,
+ AutoPilotStackPX4 = 0,
AutoPilotStackAPM,
PX4FlowPX4,
PX4FlowAPM,
@@ -47,35 +43,30 @@ public:
} AutoPilotStackType_t;
typedef enum {
- StableFirmware,
+ StableFirmware = 0,
BetaFirmware,
DeveloperFirmware,
CustomFirmware
- } FirmwareType_t;
+ } FirmwareBuildType_t;
typedef enum {
- CopterFirmware,
+ CopterFirmware = 0,
HeliFirmware,
PlaneFirmware,
RoverFirmware,
SubFirmware,
- CopterChibiOSFirmware,
- HeliChibiOSFirmware,
- PlaneChibiOSFirmware,
- RoverChibiOSFirmware,
- SubChibiOSFirmware,
DefaultVehicleFirmware
} FirmwareVehicleType_t;
Q_ENUM(AutoPilotStackType_t)
- Q_ENUM(FirmwareType_t)
+ Q_ENUM(FirmwareBuildType_t)
Q_ENUM(FirmwareVehicleType_t)
class FirmwareIdentifier
{
public:
FirmwareIdentifier(AutoPilotStackType_t stack = AutoPilotStackPX4,
- FirmwareType_t firmware = StableFirmware,
+ FirmwareBuildType_t firmware = StableFirmware,
FirmwareVehicleType_t vehicle = DefaultVehicleFirmware)
: autopilotStackType(stack), firmwareType(firmware), firmwareVehicleType(vehicle) {}
@@ -88,22 +79,24 @@ public:
// members
AutoPilotStackType_t autopilotStackType;
- FirmwareType_t firmwareType;
+ FirmwareBuildType_t firmwareType;
FirmwareVehicleType_t firmwareVehicleType;
};
FirmwareUpgradeController(void);
~FirmwareUpgradeController();
- Q_PROPERTY(QString boardPort READ boardPort NOTIFY boardFound)
- Q_PROPERTY(QString boardDescription READ boardDescription NOTIFY boardFound)
- Q_PROPERTY(QString boardType MEMBER _foundBoardTypeName NOTIFY boardFound)
- Q_PROPERTY(bool pixhawkBoard READ pixhawkBoard NOTIFY boardFound)
- Q_PROPERTY(bool px4FlowBoard READ px4FlowBoard NOTIFY boardFound)
- Q_PROPERTY(FirmwareType_t selectedFirmwareType READ selectedFirmwareType WRITE setSelectedFirmwareType NOTIFY selectedFirmwareTypeChanged)
- Q_PROPERTY(QStringList apmAvailableVersions READ apmAvailableVersions NOTIFY apmAvailableVersionsChanged)
- Q_PROPERTY(QString px4StableVersion READ px4StableVersion NOTIFY px4StableVersionChanged)
- Q_PROPERTY(QString px4BetaVersion READ px4BetaVersion NOTIFY px4BetaVersionChanged)
+ Q_PROPERTY(bool downloadingFirmwareList MEMBER _downloadingFirmwareList NOTIFY downloadingFirmwareListChanged)
+ Q_PROPERTY(QString boardPort READ boardPort NOTIFY boardFound)
+ Q_PROPERTY(QString boardDescription READ boardDescription NOTIFY boardFound)
+ Q_PROPERTY(QString boardType MEMBER _foundBoardTypeName NOTIFY boardFound)
+ Q_PROPERTY(bool pixhawkBoard READ pixhawkBoard NOTIFY boardFound)
+ Q_PROPERTY(bool px4FlowBoard READ px4FlowBoard NOTIFY boardFound)
+ Q_PROPERTY(FirmwareBuildType_t selectedFirmwareBuildType READ selectedFirmwareBuildType WRITE setSelectedFirmwareBuildType NOTIFY selectedFirmwareBuildTypeChanged)
+ Q_PROPERTY(QStringList apmFirmwareNames MEMBER _apmFirmwareNames NOTIFY apmFirmwareNamesChanged)
+ Q_PROPERTY(QStringList apmFirmwareUrls MEMBER _apmFirmwareUrls NOTIFY apmFirmwareNamesChanged)
+ Q_PROPERTY(QString px4StableVersion READ px4StableVersion NOTIFY px4StableVersionChanged)
+ Q_PROPERTY(QString px4BetaVersion READ px4BetaVersion NOTIFY px4BetaVersionChanged)
/// TextArea for log output
Q_PROPERTY(QQuickItem* statusLog READ statusLog WRITE setStatusLog)
@@ -119,13 +112,15 @@ public:
/// Called when the firmware type has been selected by the user to continue the flash process.
Q_INVOKABLE void flash(AutoPilotStackType_t stackType,
- FirmwareType_t firmwareType = StableFirmware,
+ FirmwareBuildType_t firmwareType = StableFirmware,
FirmwareVehicleType_t vehicleType = DefaultVehicleFirmware );
+ Q_INVOKABLE void flashFirmwareUrl(QString firmwareUrl);
+
/// Called to flash when upgrade is running in singleFirmwareMode
- Q_INVOKABLE void flashSingleFirmwareMode(FirmwareType_t firmwareType);
+ Q_INVOKABLE void flashSingleFirmwareMode(FirmwareBuildType_t firmwareType);
- Q_INVOKABLE FirmwareVehicleType_t vehicleTypeFromVersionIndex(int index);
+ Q_INVOKABLE FirmwareVehicleType_t vehicleTypeFromFirmwareSelectionIndex(int index);
// overload, not exposed to qml side
void flash(const FirmwareIdentifier& firmwareId);
@@ -141,28 +136,28 @@ public:
QString boardPort(void) { return _foundBoardInfo.portName(); }
QString boardDescription(void) { return _foundBoardInfo.description(); }
- FirmwareType_t selectedFirmwareType(void) { return _selectedFirmwareType; }
- void setSelectedFirmwareType(FirmwareType_t firmwareType);
- QString firmwareTypeAsString(FirmwareType_t type) const;
+ FirmwareBuildType_t selectedFirmwareBuildType(void) { return _selectedFirmwareBuildType; }
+ void setSelectedFirmwareBuildType(FirmwareBuildType_t firmwareType);
+ QString firmwareTypeAsString(FirmwareBuildType_t type) const;
- QStringList apmAvailableVersions(void);
- QString px4StableVersion(void) { return _px4StableVersion; }
- QString px4BetaVersion(void) { return _px4BetaVersion; }
+ QString px4StableVersion (void) { return _px4StableVersion; }
+ QString px4BetaVersion (void) { return _px4BetaVersion; }
bool pixhawkBoard(void) const { return _foundBoardType == QGCSerialPortInfo::BoardTypePixhawk; }
bool px4FlowBoard(void) const { return _foundBoardType == QGCSerialPortInfo::BoardTypePX4Flow; }
signals:
- void boardFound(void);
- void noBoardFound(void);
- void boardGone(void);
- void flashComplete(void);
- void flashCancelled(void);
- void error(void);
- void selectedFirmwareTypeChanged(FirmwareType_t firmwareType);
- void apmAvailableVersionsChanged(void);
- void px4StableVersionChanged(const QString& px4StableVersion);
- void px4BetaVersionChanged(const QString& px4BetaVersion);
+ void boardFound (void);
+ void noBoardFound (void);
+ void boardGone (void);
+ void flashComplete (void);
+ void flashCancelled (void);
+ void error (void);
+ void selectedFirmwareBuildTypeChanged(FirmwareBuildType_t firmwareType);
+ void apmFirmwareNamesChanged (void);
+ void px4StableVersionChanged (const QString& px4StableVersion);
+ void px4BetaVersionChanged (const QString& px4BetaVersion);
+ void downloadingFirmwareListChanged (bool downloadingFirmwareList);
private slots:
void _firmwareDownloadProgress(qint64 curr, qint64 total);
@@ -180,22 +175,25 @@ private slots:
void _eraseStarted(void);
void _eraseComplete(void);
void _eraseProgressTick(void);
- void _apmVersionDownloadFinished(QString remoteFile, QString localFile);
void _px4ReleasesGithubDownloadFinished(QString remoteFile, QString localFile);
void _px4ReleasesGithubDownloadError(QString errorMsg);
+ void _ardupilotManifestDownloadFinished(QString remoteFile, QString localFile);
+ void _ardupilotManifestDownloadError(QString errorMsg);
+ void _buildAPMFirmwareNames(void);
private:
- void _getFirmwareFile(FirmwareIdentifier firmwareId);
- void _initFirmwareHash();
- void _downloadFirmware(void);
- void _appendStatusLog(const QString& text, bool critical = false);
- void _errorCancel(const QString& msg);
- void _loadAPMVersions(uint32_t bootloaderBoardID);
QHash* _firmwareHashForBoardId(int boardId);
- void _determinePX4StableVersion(void);
+ void _getFirmwareFile(FirmwareIdentifier firmwareId);
+ void _initFirmwareHash (void);
+ void _downloadFirmware (void);
+ void _appendStatusLog (const QString& text, bool critical = false);
+ void _errorCancel (const QString& msg);
+ void _determinePX4StableVersion (void);
+ void _downloadArduPilotManifest (void);
QString _singleFirmwareURL;
bool _singleFirmwareMode;
+ bool _downloadingFirmwareList;
QString _portName;
QString _portDescription;
@@ -220,7 +218,7 @@ private:
QHash _rgAPMChibiosReplaceNamedBoardFirmware;
QHash _rgFirmwareDynamic;
- QMap > _apmVersionMap;
+ QMap > _apmVersionMap;
QList _apmVehicleTypeFromCurrentVersionList;
/// Information which comes back from the bootloader
@@ -259,7 +257,7 @@ private:
QGCSerialPortInfo::BoardType_t _foundBoardType;
QString _foundBoardTypeName;
- FirmwareType_t _selectedFirmwareType;
+ FirmwareBuildType_t _selectedFirmwareBuildType;
FirmwareImage* _image;
@@ -267,9 +265,46 @@ private:
QString _px4BetaVersion; // Version strange for latest PX4 beta
const QString _apmBoardDescriptionReplaceText;
+
+ static const char* _manifestFirmwareJsonKey;
+ static const char* _manifestBoardIdJsonKey;
+ static const char* _manifestMavTypeJsonKey;
+ static const char* _manifestFormatJsonKey;
+ static const char* _manifestUrlJsonKey;
+ static const char* _manifestMavFirmwareVersionTypeJsonKey;
+ static const char* _manifestUSBIDJsonKey;
+ static const char* _manifestMavFirmwareVersionJsonKey;
+ static const char* _manifestBootloaderStrJsonKey;
+ static const char* _manifestLatestKey;
+ static const char* _manifestPlatformKey;
+ static const char* _manifestBrandNameKey;
+
+ typedef struct {
+ uint32_t boardId;
+ FirmwareBuildType_t firmwareBuildType;
+ FirmwareVehicleType_t vehicleType;
+ QString url;
+ QString version;
+ QStringList rgBootloaderPortString;
+ QList rgVID;
+ QList rgPID;
+ QString friendlyName;
+ bool chibios;
+ bool fmuv2;
+ } ManifestFirmwareInfo_t;
+
+
+ QList _rgManifestFirmwareInfo;
+ QMap _manifestMavFirmwareVersionTypeToFirmwareBuildTypeMap;
+ QMap _manifestMavTypeToFirmwareVehicleTypeMap;
+ QStringList _apmFirmwareNames;
+ QStringList _apmFirmwareUrls;
+ Fact* _apmChibiOSSetting;
+ Fact* _apmVehicleTypeSetting;
+
+ FirmwareBuildType_t _manifestMavFirmwareVersionTypeToFirmwareBuildType (const QString& manifestMavFirmwareVersionType);
+ FirmwareVehicleType_t _manifestMavTypeToFirmwareVehicleType (const QString& manifestMavType);
};
// global hashing function
uint qHash(const FirmwareUpgradeController::FirmwareIdentifier& firmwareId);
-
-#endif