diff --git a/src/VehicleSetup/FirmwareUpgrade.qml b/src/VehicleSetup/FirmwareUpgrade.qml index d20ee293134aa3861f6c1d1ef30ce2d551d356dd..adf0b7ba9167b7d171206836041d4e0b6364eab6 100644 --- a/src/VehicleSetup/FirmwareUpgrade.qml +++ b/src/VehicleSetup/FirmwareUpgrade.qml @@ -45,6 +45,8 @@ QGCView { property bool initialBoardSearch: true property string firmwareName + property bool _singleFirmwareMode: QGroundControl.corePlugin.options.firmwareUpgradeSingleURL.length != 0 ///< true: running in special single firmware download mode + function cancelFlash() { statusTextArea.append(highlightPrefix + qsTr("Upgrade cancelled") + highlightSuffix) statusTextArea.append("------------------------------------------") @@ -147,17 +149,21 @@ QGCView { function accept() { hideDialog() - var stack = apmFlightStack.checked ? FirmwareUpgradeController.AutoPilotStackAPM : FirmwareUpgradeController.AutoPilotStackPX4 - if (px4Flow) { - stack = FirmwareUpgradeController.PX4Flow - } + if (_singleFirmwareMode) { + controller.flashSingleFirmwareMode() + } else { + var stack = apmFlightStack.checked ? FirmwareUpgradeController.AutoPilotStackAPM : FirmwareUpgradeController.AutoPilotStackPX4 + if (px4Flow) { + stack = FirmwareUpgradeController.PX4Flow + } - var firmwareType = firmwareVersionCombo.model.get(firmwareVersionCombo.currentIndex).firmwareType - var vehicleType = FirmwareUpgradeController.DefaultVehicleFirmware - if (apmFlightStack.checked) { - vehicleType = controller.vehicleTypeFromVersionIndex(vehicleTypeSelectionCombo.currentIndex) + var firmwareType = firmwareVersionCombo.model.get(firmwareVersionCombo.currentIndex).firmwareType + var vehicleType = FirmwareUpgradeController.DefaultVehicleFirmware + if (apmFlightStack.checked) { + vehicleType = controller.vehicleTypeFromVersionIndex(vehicleTypeSelectionCombo.currentIndex) + } + controller.flash(stack, firmwareType, vehicleType) } - controller.flash(stack, firmwareType, vehicleType) } function reject() { @@ -203,6 +209,19 @@ QGCView { } } + ListModel { + id: singleFirmwareModeTypeList + + ListElement { + text: qsTr("Standard Version") + firmwareType: FirmwareUpgradeController.StableFirmware + } + ListElement { + text: qsTr("Custom firmware file...") + firmwareType: FirmwareUpgradeController.CustomFirmware + } + } + Column { anchors.fill: parent spacing: defaultTextHeight @@ -210,7 +229,11 @@ QGCView { QGCLabel { width: parent.width wrapMode: Text.WordWrap - text: px4Flow ? "Detected PX4 Flow board. You can select from the following firmware:" : "Detected Pixhawk board. You can select from the following flight stacks:" + text: _singleFirmwareMode ? _singleFirmwareLabel : (px4Flow ? _px4FlowLabel : _pixhawkLabel) + + readonly property string _px4FlowLabel: qsTr("Detected PX4 Flow board. You can select from the following firmware:") + readonly property string _pixhawkLabel: qsTr("Detected Pixhawk board. You can select from the following flight stacks:") + readonly property string _singleFirmwareLabel: qsTr("Press Ok to upgrade your vehicle.") } function firmwareVersionChanged(model) { @@ -229,7 +252,7 @@ QGCView { checked: true exclusiveGroup: firmwareGroup text: qsTr("PX4 Flight Stack ") - visible: !px4Flow + visible: !_singleFirmwareMode && !px4Flow onClicked: parent.firmwareVersionChanged(firmwareTypeList) } @@ -238,7 +261,7 @@ QGCView { id: apmFlightStack exclusiveGroup: firmwareGroup text: qsTr("ArduPilot Flight Stack") - visible: !px4Flow + visible: !_singleFirmwareMode && !px4Flow onClicked: parent.firmwareVersionChanged(firmwareTypeList) } @@ -295,7 +318,7 @@ QGCView { anchors.left: parent.left anchors.right: parent.right visible: showFirmwareTypeSelection - model: px4Flow ? px4FlowTypeList : firmwareTypeList + model: _singleFirmwareMode ? singleFirmwareModeTypeList: (px4Flow ? px4FlowTypeList : firmwareTypeList) currentIndex: controller.selectedFirmwareType onActivated: { diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index bf83ef8cc5ee9e36ee052464eb3268279211b202..0378805d88ef9825f037d7ac05e46494597031f2 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -17,6 +17,8 @@ #include "QGCFileDialog.h" #include "QGCApplication.h" #include "QGCFileDownload.h" +#include "QGCOptions.h" +#include "QGCCorePlugin.h" #include #include @@ -41,7 +43,9 @@ uint qHash(const FirmwareUpgradeController::FirmwareIdentifier& firmwareId) /// @Brief Constructs a new FirmwareUpgradeController Widget. This widget is used within the PX4VehicleConfig set of screens. FirmwareUpgradeController::FirmwareUpgradeController(void) - : _downloadManager(NULL) + : _singleFirmwareURL(qgcApp()->toolbox()->corePlugin()->options()->firmwareUpgradeSingleURL()) + , _singleFirmwareMode(!_singleFirmwareURL.isEmpty()) + , _downloadManager(NULL) , _downloadNetworkReply(NULL) , _statusLog(NULL) , _selectedFirmwareType(StableFirmware) @@ -110,6 +114,11 @@ void FirmwareUpgradeController::flash(const FirmwareIdentifier& firmwareId) flash(firmwareId.autopilotStackType, firmwareId.firmwareType, firmwareId.firmwareVehicleType); } +void FirmwareUpgradeController::flashSingleFirmwareMode(void) +{ + flash(SingleFirmwareMode, StableFirmware, DefaultVehicleFirmware); +} + void FirmwareUpgradeController::cancel(void) { _eraseTimer.stop(); @@ -202,7 +211,8 @@ void FirmwareUpgradeController::_initFirmwareHash() { AutoPilotStackAPM, DeveloperFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/latest/PX4/ArduCopter-v4.px4"}, { AutoPilotStackAPM, DeveloperFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/latest/PX4-heli/ArduCopter-v4.px4"}, { AutoPilotStackAPM, DeveloperFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/latest/PX4/ArduPlane-v4.px4"}, - { AutoPilotStackAPM, DeveloperFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/latest/PX4/APMrover2-v4.px4"} + { AutoPilotStackAPM, DeveloperFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/latest/PX4/APMrover2-v4.px4"}, + { SingleFirmwareMode,StableFirmware, DefaultVehicleFirmware, _singleFirmwareURL}, }; //////////////////////////////////// PX4FMUV2 firmwares ////////////////////////////////////////////////// @@ -228,6 +238,7 @@ void FirmwareUpgradeController::_initFirmwareHash() { AutoPilotStackAPM, DeveloperFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/latest/PX4/ArduPlane-v2.px4"}, { AutoPilotStackAPM, DeveloperFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/latest/PX4/APMrover2-v2.px4"}, { AutoPilotStackAPM, DeveloperFirmware, SubFirmware, "http://firmware.ardupilot.org/Sub/latest/PX4/ArduSub-v2.px4"}, + { SingleFirmwareMode,StableFirmware, DefaultVehicleFirmware, _singleFirmwareURL}, }; //////////////////////////////////// PX4FMU aerocore firmwares ////////////////////////////////////////////////// @@ -299,6 +310,7 @@ void FirmwareUpgradeController::_initFirmwareHash() { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/tap-v1_default.px4"}, { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/tap-v1_default.px4"}, { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/tap-v1_default.px4"}, + { SingleFirmwareMode,StableFirmware, DefaultVehicleFirmware, _singleFirmwareURL}, }; //////////////////////////////////// ASCV1 firmwares ////////////////////////////////////////////////// FirmwareToUrlElement_t rgASCV1FirmwareArray[] = { @@ -376,6 +388,12 @@ void FirmwareUpgradeController::_initFirmwareHash() const FirmwareToUrlElement_t& element = rg3DRRadioFirmwareArray[i]; _rg3DRRadioFirmware.insert(FirmwareIdentifier(element.stackType, element.firmwareType, element.vehicleType), element.url); } + + size = sizeof(rg3DRRadioFirmwareArray)/sizeof(rg3DRRadioFirmwareArray[0]); + for (int i = 0; i < size; i++) { + const FirmwareToUrlElement_t& element = rg3DRRadioFirmwareArray[i]; + _rg3DRRadioFirmware.insert(FirmwareIdentifier(element.stackType, element.firmwareType, element.vehicleType), element.url); + } } /// @brief Called when the findBootloader process is unable to sync to the bootloader. Moves the state @@ -429,7 +447,6 @@ void FirmwareUpgradeController::_getFirmwareFile(FirmwareIdentifier firmwareId) QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), // Initial directory "Firmware Files (*.px4 *.bin *.ihx)"); // File filter } else { - if (prgFirmware->contains(firmwareId)) { _firmwareFilename = prgFirmware->value(firmwareId); } else { diff --git a/src/VehicleSetup/FirmwareUpgradeController.h b/src/VehicleSetup/FirmwareUpgradeController.h index 1209135dfd51ec4d374dd42d00eaba2588e4f361..6ce335d6caa2a0eb561e34b161a111bf05322dd8 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.h +++ b/src/VehicleSetup/FirmwareUpgradeController.h @@ -42,7 +42,8 @@ public: AutoPilotStackPX4, AutoPilotStackAPM, PX4Flow, - ThreeDRRadio + ThreeDRRadio, + SingleFirmwareMode } AutoPilotStackType_t; typedef enum { @@ -122,6 +123,9 @@ public: FirmwareType_t firmwareType = StableFirmware, FirmwareVehicleType_t vehicleType = DefaultVehicleFirmware ); + /// Called to flash when upgrade is running in singleFirmwareMode + Q_INVOKABLE void flashSingleFirmwareMode(void); + Q_INVOKABLE FirmwareVehicleType_t vehicleTypeFromVersionIndex(int index); // overload, not exposed to qml side @@ -191,6 +195,8 @@ private: QHash* _firmwareHashForBoardId(int boardId); void _determinePX4StableVersion(void); + QString _singleFirmwareURL; + bool _singleFirmwareMode; QString _portName; QString _portDescription; diff --git a/src/api/QGCOptions.h b/src/api/QGCOptions.h index baf6cb678c8126adacadda4a5ba05ae0b6c20952..d21b5920e7b2f2929aa404983d8bf1662abba620 100644 --- a/src/api/QGCOptions.h +++ b/src/api/QGCOptions.h @@ -35,6 +35,7 @@ public: Q_PROPERTY(bool showSensorCalibrationAirspeed READ showSensorCalibrationAirspeed NOTIFY showSensorCalibrationAirspeedChanged) Q_PROPERTY(bool showSensorCalibrationOrient READ showSensorCalibrationOrient NOTIFY showSensorCalibrationOrientChanged) Q_PROPERTY(bool showFirmwareUpgrade READ showFirmwareUpgrade NOTIFY showFirmwareUpgradeChanged) + Q_PROPERTY(QString firmwareUpgradeSingleURL READ firmwareUpgradeSingleURL CONSTANT) /// Should QGC hide its settings menu and colapse it into one single menu (Settings and Vehicle Setup)? /// @return true if QGC should consolidate both menus into one. @@ -53,14 +54,19 @@ public: virtual CustomInstrumentWidget* instrumentWidget(); /// By returning false you can hide the following sensor calibration pages - virtual bool showSensorCalibrationCompass () const { return true; } - virtual bool showSensorCalibrationGyro () const { return true; } - virtual bool showSensorCalibrationAccel () const { return true; } - virtual bool showSensorCalibrationLevel () const { return true; } - virtual bool showSensorCalibrationAirspeed () const { return true; } - virtual bool showSensorCalibrationOrient () const { return true; } + virtual bool showSensorCalibrationCompass () const { return true; } + virtual bool showSensorCalibrationGyro () const { return true; } + virtual bool showSensorCalibrationAccel () const { return true; } + virtual bool showSensorCalibrationLevel () const { return true; } + virtual bool showSensorCalibrationAirspeed () const { return true; } + virtual bool showSensorCalibrationOrient () const { return true; } - virtual bool showFirmwareUpgrade () const { return true; } + virtual bool showFirmwareUpgrade () const { return true; } + + /// If returned QString in non-empty it means that firmware upgrade will run in a mode which only + /// supports downloading a single firmware file from the URL. It also supports custom install through + /// the Advanced options. + virtual QString firmwareUpgradeSingleURL () const { return QString(); } signals: void showSensorCalibrationCompassChanged (bool show);