diff --git a/src/VehicleSetup/FirmwareUpgrade.qml b/src/VehicleSetup/FirmwareUpgrade.qml index 2d2fd779bcd68e40978a0a999b80b1054fd1f054..864a48bf9e79d4ac4ab0a18bca6b8958ed033434 100644 --- a/src/VehicleSetup/FirmwareUpgrade.qml +++ b/src/VehicleSetup/FirmwareUpgrade.qml @@ -139,12 +139,22 @@ QGCView { QGCViewDialog { anchors.fill: parent - property bool showVersionSelection: apmFlightStack.checked || advancedMode.checked + property bool showFirmwareTypeSelection: advancedMode.checked property bool px4Flow: controller.boardType == "PX4 Flow" function accept() { hideDialog() - controller.flash(firmwareVersionCombo.model.get(firmwareVersionCombo.currentIndex).firmwareType) + 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 = vehicleTypeSelectionCombo.model.get(vehicleTypeSelectionCombo.currentIndex).vehicleType + } + controller.flash(stack, firmwareType, vehicleType) } function reject() { @@ -157,64 +167,64 @@ QGCView { } ListModel { - id: px4FirmwareTypeList + id: firmwareTypeList ListElement { text: "Standard Version (stable)"; - firmwareType: FirmwareUpgradeController.PX4StableFirmware + firmwareType: FirmwareUpgradeController.StableFirmware } ListElement { text: "Beta Testing (beta)"; - firmwareType: FirmwareUpgradeController.PX4BetaFirmware + firmwareType: FirmwareUpgradeController.BetaFirmware } ListElement { text: "Developer Build (master)"; - firmwareType: FirmwareUpgradeController.PX4DeveloperFirmware + firmwareType: FirmwareUpgradeController.DeveloperFirmware } ListElement { text: "Custom firmware file..."; - firmwareType: FirmwareUpgradeController.PX4CustomFirmware + firmwareType: FirmwareUpgradeController.CustomFirmware } } ListModel { - id: apmFirmwareTypeList + id: vehicleTypeList ListElement { - text: "ArduCopter Quad" - firmwareType: FirmwareUpgradeController.ApmArduCopterQuadFirmware + text: "Quad" + vehicleType: FirmwareUpgradeController.QuadFirmware } ListElement { - text: "ArduCopter X8" - firmwareType: FirmwareUpgradeController.ApmArduCopterX8Firmware + text: "X8" + vehicleType: FirmwareUpgradeController.X8Firmware } ListElement { - text: "ArduCopter Hexa" - firmwareType: FirmwareUpgradeController.ApmArduCopterHexaFirmware + text: "Hexa" + vehicleType: FirmwareUpgradeController.HexaFirmware } ListElement { - text: "ArduCopter Octo" - firmwareType: FirmwareUpgradeController.ApmArduCopterOctoFirmware + text: "Octo" + vehicleType: FirmwareUpgradeController.OctoFirmware } ListElement { - text: "ArduCopter Y" - firmwareType: FirmwareUpgradeController.ApmArduCopterYFirmware + text: "Y" + vehicleType: FirmwareUpgradeController.YFirmware } ListElement { - text: "ArduCopter Y6" - firmwareType: FirmwareUpgradeController.ApmArduCopterY6Firmware + text: "Y6" + vehicleType: FirmwareUpgradeController.Y6Firmware } ListElement { - text: "ArduCopter Heli" - firmwareType: FirmwareUpgradeController.ApmArduCopterHeliFirmware + text: "Heli" + vehicleType: FirmwareUpgradeController.HeliFirmware } ListElement { - text: "ArduPlane" - firmwareType: FirmwareUpgradeController.ApmArduPlaneFirmware + text: "Plane" + vehicleType: FirmwareUpgradeController.PlaneFirmware } ListElement { text: "Rover" - firmwareType: FirmwareUpgradeController.ApmRoverFirmware + vehicleType: FirmwareUpgradeController.RoverFirmware } } @@ -223,11 +233,11 @@ QGCView { ListElement { text: "Standard Version (stable)"; - firmwareType: FirmwareUpgradeController.PX4StableFirmware + firmwareType: FirmwareUpgradeController.StableFirmware } ListElement { text: "Custom firmware file..."; - firmwareType: FirmwareUpgradeController.PX4CustomFirmware + firmwareType: FirmwareUpgradeController.CustomFirmware } } @@ -252,6 +262,17 @@ QGCView { firmwareVersionCombo.currentIndex = 0 } + function vehicleTypeChanged(model) { + vehicleTypeSelectionCombo.model = null + // 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. + vehicleTypeSelectionCombo.model = null + vehicleTypeSelectionCombo.model = model + vehicleTypeSelectionCombo.currentIndex = 1 + vehicleTypeSelectionCombo.currentIndex = 0 + } + QGCRadioButton { id: px4FlightStack checked: true @@ -259,7 +280,7 @@ QGCView { text: "PX4 Flight Stack (full QGC support)" visible: !px4Flow - onClicked: parent.firmwareVersionChanged(px4FirmwareTypeList) + onClicked: parent.firmwareVersionChanged(firmwareTypeList) } QGCRadioButton { @@ -268,42 +289,55 @@ QGCView { text: "APM Flight Stack (partial QGC support)" visible: !px4Flow - onClicked: parent.firmwareVersionChanged(apmFirmwareTypeList) + onClicked: { + parent.firmwareVersionChanged(firmwareTypeList) + parent.vehicleTypeChanged(vehicleTypeList) + } } - + QGCLabel { width: parent.width wrapMode: Text.WordWrap - visible: showVersionSelection + visible: showFirmwareTypeSelection text: px4Flow ? "Select which version of the firmware you would like to install:" : "Select which version of the above flight stack you would like to install:" } - QGCComboBox { - id: firmwareVersionCombo - width: 200 - visible: showVersionSelection - model: px4Flow ? px4FlowTypeList : px4FirmwareTypeList - - onActivated: { - if (model.get(index).firmwareType == FirmwareUpgradeController.PX4BetaFirmware) { - firmwareVersionWarningLabel.visible = true - firmwareVersionWarningLabel.text = "WARNING: BETA FIRMWARE. " + - "This firmware version is ONLY intended for beta testers. " + - "Although it has received FLIGHT TESTING, it represents actively changed code. " + - "Do NOT use for normal operation." - } else if (model.get(index).firmwareType == FirmwareUpgradeController.PX4DeveloperFirmware) { - firmwareVersionWarningLabel.visible = true - firmwareVersionWarningLabel.text = "WARNING: CONTINUOUS BUILD FIRMWARE. " + - "This firmware has NOT BEEN FLIGHT TESTED. " + - "It is only intended for DEVELOPERS. " + - "Run bench tests without props first. " + - "Do NOT fly this without addional safety precautions. " + - "Follow the mailing list actively when using it." - } else { - firmwareVersionWarningLabel.visible = false + Row { + spacing: 10 + QGCComboBox { + id: firmwareVersionCombo + width: 200 + visible: showFirmwareTypeSelection + model: px4Flow ? px4FlowTypeList : firmwareTypeList + + onActivated: { + if (model.get(index).firmwareType == FirmwareUpgradeController.PX4BetaFirmware || FirmwareUpgradeController.APMBetaFirmware ) { + firmwareVersionWarningLabel.visible = true + firmwareVersionWarningLabel.text = "WARNING: BETA FIRMWARE. " + + "This firmware version is ONLY intended for beta testers. " + + "Although it has received FLIGHT TESTING, it represents actively changed code. " + + "Do NOT use for normal operation." + } else if (model.get(index).firmwareType == FirmwareUpgradeController.PX4DeveloperFirmware || FirmwareUpgradeController.APMDeveloperFirmware) { + firmwareVersionWarningLabel.visible = true + firmwareVersionWarningLabel.text = "WARNING: CONTINUOUS BUILD FIRMWARE. " + + "This firmware has NOT BEEN FLIGHT TESTED. " + + "It is only intended for DEVELOPERS. " + + "Run bench tests without props first. " + + "Do NOT fly this without addional safety precautions. " + + "Follow the mailing list actively when using it." + } else { + firmwareVersionWarningLabel.visible = false + } } - } - } + } + + QGCComboBox { + id: vehicleTypeSelectionCombo + width: 200 + visible: apmFlightStack.checked + model: vehicleTypeList + } + } QGCLabel { id: firmwareVersionWarningLabel @@ -311,8 +345,8 @@ QGCView { wrapMode: Text.WordWrap visible: false } - } - + } + QGCCheckBox { id: advancedMode anchors.bottom: parent.bottom diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index 515d8b49a1d2a68a5def0a8595f83635a5bd9082..7085ef29c8c14a90267d3ee34f1d88df7963bf31 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -30,6 +30,21 @@ #include "QGCFileDialog.h" #include "QGCMessageBox.h" + +struct FirmwareToUrlElement_t { + FirmwareUpgradeController::AutoPilotStackType_t stackType; + FirmwareUpgradeController::FirmwareType_t firmwareType; + FirmwareUpgradeController::FirmwareVehicleType_t vehicleType; + QString url; +}; + +uint qHash(const FirmwareUpgradeController::FirmwareIdentifier& firmwareId) +{ + return ( firmwareId.autopilotStackType | + (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) : _downloadManager(NULL), @@ -65,17 +80,25 @@ void FirmwareUpgradeController::startBoardSearch(void) _threadController->startFindBoardLoop(); } -void FirmwareUpgradeController::flash(FirmwareType_t firmwareType) +void FirmwareUpgradeController::flash(AutoPilotStackType_t stackType, + FirmwareType_t firmwareType, + FirmwareVehicleType_t vehicleType) { + FirmwareIdentifier firmwareId = FirmwareIdentifier(stackType, firmwareType, vehicleType); if (_bootloaderFound) { - _getFirmwareFile(firmwareType); + _getFirmwareFile(firmwareId); } else { // We haven't found the bootloader yet. Need to wait until then to flash _startFlashWhenBootloaderFound = true; - _startFlashWhenBootloaderFoundFirmwareType = firmwareType; + _startFlashWhenBootloaderFoundFirmwareIdentity = firmwareId; } } +void FirmwareUpgradeController::flash(const FirmwareIdentifier& firmwareId) +{ + flash(firmwareId.autopilotStackType, firmwareId.firmwareType, firmwareId.firmwareVehicleType); +} + void FirmwareUpgradeController::cancel(void) { _eraseTimer.stop(); @@ -105,10 +128,12 @@ void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPort case FoundBoard3drRadio: _foundBoardType = "3DR Radio"; if (!firstAttempt) { - // Radio always flashes stable firmware, so we can start right away without + // Radio always flashes latest firmware, so we can start right away without // any further user input. _startFlashWhenBootloaderFound = true; - _startFlashWhenBootloaderFoundFirmwareType = PX4StableFirmware; + _startFlashWhenBootloaderFoundFirmwareIdentity = FirmwareIdentifier(ThreeDRRadio, + StableFirmware, + DefaultVehicleFirmware); } break; } @@ -143,7 +168,135 @@ void FirmwareUpgradeController::_foundBootloader(int bootloaderVersion, int boar _appendStatusLog(QString(" Flash size: %1").arg(_bootloaderBoardFlashSize)); if (_startFlashWhenBootloaderFound) { - flash(_startFlashWhenBootloaderFoundFirmwareType); + flash(_startFlashWhenBootloaderFoundFirmwareIdentity); + } +} + + +/// @brief intializes the firmware hashes with proper urls. +/// This happens only once for a class instance first time when it is needed. +void FirmwareUpgradeController::_initFirmwareHash() +{ + // indirect check whether this function has been called before or not + // may have to be modified if _rgPX4FMUV2Firmware disappears + if (!_rgPX4FMUV2Firmware.isEmpty()) { + return; + } + + //////////////////////////////////// PX4FMUV2 firmwares ////////////////////////////////////////////////// + FirmwareToUrlElement_t rgPX4FMV2FirmwareArray[] = { + { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v2_default.px4"}, + { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v2_default.px4"}, + { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v2_default.px4"}, + { AutoPilotStackAPM, StableFirmware, QuadFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, X8Firmware, "http://firmware.diydrones.com/Copter/stable/PX4-octa-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, HexaFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-hexa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, OctoFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-octa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, YFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-tri/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, Y6Firmware, "http://firmware.diydrones.com/Copter/stable/PX4-y6/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-heli/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.diydrones.com/Plane/stable/PX4/ArduPlane-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.diydrones.com/Rover/stable/PX4/APMrover2-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, QuadFirmware, "http://firmware.diydrones.com/Copter/beta/PX4-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, X8Firmware, "http://firmware.diydrones.com/Copter/beta/PX4-octa-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, HexaFirmware, "http://firmware.diydrones.com/Copter/beta/PX4-hexa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, OctoFirmware, "http://firmware.diydrones.com/Copter/beta/PX4-octa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, YFirmware, "http://firmware.diydrones.com/Copter/beta/PX4-tri/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, Y6Firmware, "http://firmware.diydrones.com/Copter/beta/PX4-y6/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, HeliFirmware, "http://firmware.diydrones.com/Copter/beta/PX4-heli/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, PlaneFirmware, "http://firmware.diydrones.com/Plane/beta/PX4/ArduPlane-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, RoverFirmware, "http://firmware.diydrones.com/Rover/beta/PX4/APMrover2-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, QuadFirmware, "http://firmware.diydrones.com/Copter/latest/PX4-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, X8Firmware, "http://firmware.diydrones.com/Copter/latest/PX4-octa-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, HexaFirmware, "http://firmware.diydrones.com/Copter/latest/PX4-hexa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, OctoFirmware, "http://firmware.diydrones.com/Copter/latest/PX4-octa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, YFirmware, "http://firmware.diydrones.com/Copter/latest/PX4-tri/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, Y6Firmware, "http://firmware.diydrones.com/Copter/latest/PX4-y6/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, HeliFirmware, "http://firmware.diydrones.com/Copter/latest/PX4-heli/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, PlaneFirmware, "http://firmware.diydrones.com/Plane/latest/PX4/ArduPlane-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, RoverFirmware, "http://firmware.diydrones.com/Rover/latest/PX4/APMrover2-v2.px4"} + }; + + //////////////////////////////////// PX4FMU aerocore firmwares ////////////////////////////////////////////////// + FirmwareToUrlElement_t rgAeroCoreFirmwareArray[] = { + { 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"}, + { AutoPilotStackAPM, StableFirmware, QuadFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, X8Firmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/stable/PX4-octa-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, HexaFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/stable/PX4-hexa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, OctoFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/stable/PX4-octa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, YFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/stable/PX4-tri/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, StableFirmware, Y6Firmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/stable/PX4-y6/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, QuadFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, X8Firmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-octa-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, HexaFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-hexa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, OctoFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-octa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, YFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-tri/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, Y6Firmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-y6/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, HeliFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/beta/PX4-heli/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, PlaneFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Plane/beta/PX4/ArduPlane-v2.px4"}, + { AutoPilotStackAPM, BetaFirmware, RoverFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Rover/beta/PX4/APMrover2-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, QuadFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, X8Firmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-octa-quad/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, HexaFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-hexa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, OctoFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-octa/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, YFirmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-tri/ArduCopter-v2.px4"}, + { AutoPilotStackAPM, DeveloperFirmware, Y6Firmware, "http://gumstix-aerocore.s3.amazonaws.com/Copter/latest/PX4-y6/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"} + }; + + /////////////////////////////// FMUV1 firmwares /////////////////////////////////////////// + FirmwareToUrlElement_t rgPX4FMUV1FirmwareArray[] = { + { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/latest/px4fmu-v1_default.px4"}, + { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v1_default.px4"}, + { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v1_default.px4"}, + }; + + /////////////////////////////// px4flow firmwares /////////////////////////////////////// + FirmwareToUrlElement_t rgPX4FLowFirmwareArray[] = { + { PX4Flow, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Flow/master/px4flow.px4" }, + }; + + /////////////////////////////// 3dr radio firmwares /////////////////////////////////////// + FirmwareToUrlElement_t rg3DRRadioFirmwareArray[] = { + { ThreeDRRadio, StableFirmware, DefaultVehicleFirmware, "http://firmware.diydrones.com/SiK/stable/radio~hm_trp.ihx"} + }; + + // populate hashes now + int size = sizeof(rgPX4FMV2FirmwareArray)/sizeof(rgPX4FMV2FirmwareArray[0]); + for (int i = 0; i < size; i++) { + const FirmwareToUrlElement_t& element = rgPX4FMV2FirmwareArray[i]; + _rgPX4FMUV2Firmware.insert(FirmwareIdentifier(element.stackType, element.firmwareType, element.vehicleType), element.url); + } + + size = sizeof(rgAeroCoreFirmwareArray)/sizeof(rgAeroCoreFirmwareArray[0]); + for (int i = 0; i < size; i++) { + const FirmwareToUrlElement_t& element = rgAeroCoreFirmwareArray[i]; + _rgAeroCoreFirmware.insert(FirmwareIdentifier(element.stackType, element.firmwareType, element.vehicleType), element.url); + } + + size = sizeof(rgPX4FMUV1FirmwareArray)/sizeof(rgPX4FMUV1FirmwareArray[0]); + for (int i = 0; i < size; i++) { + const FirmwareToUrlElement_t& element = rgPX4FMUV1FirmwareArray[i]; + _rgPX4FMUV1Firmware.insert(FirmwareIdentifier(element.stackType, element.firmwareType, element.vehicleType), element.url); + } + + size = sizeof(rgPX4FLowFirmwareArray)/sizeof(rgPX4FLowFirmwareArray[0]); + for (int i = 0; i < size; i++) { + const FirmwareToUrlElement_t& element = rgPX4FLowFirmwareArray[i]; + _rgPX4FLowFirmware.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); } } @@ -155,116 +308,54 @@ void FirmwareUpgradeController::_bootloaderSyncFailed(void) } /// @brief Prompts the user to select a firmware file if needed and moves the state machine to the next state. -void FirmwareUpgradeController::_getFirmwareFile(FirmwareType_t firmwareType) +void FirmwareUpgradeController::_getFirmwareFile(FirmwareIdentifier firmwareId) { - static DownloadLocationByFirmwareType_t rgPX4FMUV2Firmware[] = { - { PX4StableFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v2_default.px4" }, - { PX4BetaFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v2_default.px4" }, - { PX4DeveloperFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v2_default.px4"}, - { ApmArduCopterQuadFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-quad/ArduCopter-v2.px4" }, - { ApmArduCopterX8Firmware, "http://firmware.diydrones.com/Copter/stable/PX4-octa-quad/ArduCopter-v2.px4" }, - { ApmArduCopterHexaFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-hexa/ArduCopter-v2.px4" }, - { ApmArduCopterOctoFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-octa/ArduCopter-v2.px4" }, - { ApmArduCopterYFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-tri/ArduCopter-v2.px4" }, - { ApmArduCopterY6Firmware, "http://firmware.diydrones.com/Copter/stable/PX4-y6/ArduCopter-v2.px4" }, - { ApmArduCopterHeliFirmware, "http://firmware.diydrones.com/Copter/stable/PX4-heli/ArduCopter-v2.px4" }, - { ApmArduPlaneFirmware, "http://firmware.diydrones.com/Plane/stable/PX4/ArduPlane-v2.px4" }, - { ApmRoverFirmware, "http://firmware.diydrones.com/Plane/stable/PX4/APMrover2-v2.px4" }, - }; - static const size_t crgPX4FMUV2Firmware = sizeof(rgPX4FMUV2Firmware) / sizeof(rgPX4FMUV2Firmware[0]); - - static const DownloadLocationByFirmwareType_t rgAeroCoreFirmware[] = { - { PX4StableFirmware, "http://gumstix-aerocore.s3.amazonaws.com/PX4/stable/aerocore_default.px4" }, - { PX4BetaFirmware, "http://gumstix-aerocore.s3.amazonaws.com/PX4/beta/aerocore_default.px4" }, - { PX4DeveloperFirmware, "http://gumstix-aerocore.s3.amazonaws.com/PX4/master/aerocore_default.px4" }, - { ApmArduCopterQuadFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-quad/ArduCopter-aerocore.px4" }, - { ApmArduCopterX8Firmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-octa-quad/ArduCopter-aerocore.px4" }, - { ApmArduCopterHexaFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-hexa/ArduCopter-aerocore.px4" }, - { ApmArduCopterOctoFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-octa/ArduCopter-aerocore.px4" }, - { ApmArduCopterYFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-tri/ArduCopter-aerocore.px4" }, - { ApmArduCopterY6Firmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-y6/ArduCopter-aerocore.px4" }, - { ApmArduCopterHeliFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Copter/stable/PX4-heli/ArduCopter-aerocore.px4" }, - { ApmArduPlaneFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Plane/stable/PX4/ArduPlane-aerocore.px4" }, - { ApmRoverFirmware, "http://gumstix-aerocore.s3.amazonaws.com/APM/Plane/stable/PX4/APMrover2-aerocore.px4" }, - }; - static const size_t crgAeroCoreFirmware = sizeof(rgAeroCoreFirmware) / sizeof(rgAeroCoreFirmware[0]); - - static const DownloadLocationByFirmwareType_t rgPX4FMUV1Firmware[] = { - { PX4StableFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v1_default.px4" }, - { PX4BetaFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v1_default.px4" }, - { PX4DeveloperFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v1_default.px4" }, - }; - static const size_t crgPX4FMUV1Firmware = sizeof(rgPX4FMUV1Firmware) / sizeof(rgPX4FMUV1Firmware[0]); - - static const DownloadLocationByFirmwareType_t rgPX4FlowFirmware[] = { - { PX4StableFirmware, "http://px4-travis.s3.amazonaws.com/Flow/master/px4flow.px4" }, - }; - static const size_t crgPX4FlowFirmware = sizeof(rgPX4FlowFirmware) / sizeof(rgPX4FlowFirmware[0]); - - static const DownloadLocationByFirmwareType_t rg3DRRadioFirmware[] = { - { PX4StableFirmware, "http://firmware.diydrones.com/SiK/stable/radio~hm_trp.ihx" }, - }; - static const size_t crg3DRRadioFirmware = sizeof(rg3DRRadioFirmware) / sizeof(rg3DRRadioFirmware[0]); - + // make sure the firmware hashes are populated + _initFirmwareHash(); + // Select the firmware set based on board type - const DownloadLocationByFirmwareType_t* prgFirmware; - size_t crgFirmware = 0; + QHash prgFirmware; switch (_bootloaderBoardID) { case Bootloader::boardIDPX4FMUV1: - prgFirmware = rgPX4FMUV1Firmware; - crgFirmware = crgPX4FMUV1Firmware; + prgFirmware = _rgPX4FMUV1Firmware; break; case Bootloader::boardIDPX4Flow: - prgFirmware = rgPX4FlowFirmware; - crgFirmware = crgPX4FlowFirmware; + prgFirmware = _rgPX4FLowFirmware; break; case Bootloader::boardIDPX4FMUV2: - prgFirmware = rgPX4FMUV2Firmware; - crgFirmware = crgPX4FMUV2Firmware; + prgFirmware = _rgPX4FMUV2Firmware; break; case Bootloader::boardIDAeroCore: - prgFirmware = rgAeroCoreFirmware; - crgFirmware = crgAeroCoreFirmware; + prgFirmware = _rgAeroCoreFirmware; break; case Bootloader::boardID3DRRadio: - prgFirmware = rg3DRRadioFirmware; - crgFirmware = crg3DRRadioFirmware; + prgFirmware = _rg3DRRadioFirmware; break; default: - prgFirmware = NULL; break; } - if (prgFirmware == NULL && firmwareType != PX4CustomFirmware) { + if (prgFirmware.isEmpty() && firmwareId.firmwareType != CustomFirmware) { _errorCancel("Attempting to flash an unknown board type, you must select 'Custom firmware file'"); return; } - if (firmwareType == PX4CustomFirmware) { + if (firmwareId.firmwareType == CustomFirmware) { _firmwareFilename = QGCFileDialog::getOpenFileName(NULL, // Parent to main window "Select Firmware File", // Dialog Caption QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), // Initial directory "Firmware Files (*.px4 *.bin *.ihx)"); // File filter } else { - bool found = false; - - for (size_t i=0; ifirmwareType == firmwareType) { - found = true; - break; - } - prgFirmware++; - } - - if (found) { - _firmwareFilename = prgFirmware->downloadLocation; + + if (prgFirmware.contains(firmwareId)) { + _firmwareFilename = prgFirmware.value(firmwareId); } else { _errorCancel("Unable to find specified firmware download location"); return; diff --git a/src/VehicleSetup/FirmwareUpgradeController.h b/src/VehicleSetup/FirmwareUpgradeController.h index b9c4dcde203bc9c6e2ee8de0ed0599b7a33894a6..aec35f44d52ce6d84fddf22739531c0d2d53f2c3 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.h +++ b/src/VehicleSetup/FirmwareUpgradeController.h @@ -43,33 +43,68 @@ #include +/// Supported firmware types. If you modify these you will need to update the qml file as well. + // Firmware Upgrade MVC Controller for FirmwareUpgrade.qml. class FirmwareUpgradeController : public QObject { Q_OBJECT public: + typedef enum { + AutoPilotStackPX4, + AutoPilotStackAPM, + PX4Flow, + ThreeDRRadio + } AutoPilotStackType_t; + + typedef enum { + StableFirmware, + BetaFirmware, + DeveloperFirmware, + CustomFirmware + } FirmwareType_t; + + typedef enum { + QuadFirmware, + X8Firmware, + HexaFirmware, + OctoFirmware, + YFirmware, + Y6Firmware, + HeliFirmware, + PlaneFirmware, + RoverFirmware, + DefaultVehicleFirmware + } FirmwareVehicleType_t; + + Q_ENUMS(AutoPilotStackType_t) + Q_ENUMS(FirmwareType_t) + Q_ENUMS(FirmwareVehicleType_t) + + class FirmwareIdentifier + { + public: + FirmwareIdentifier(AutoPilotStackType_t stack = AutoPilotStackPX4, + FirmwareType_t firmware = StableFirmware, + FirmwareVehicleType_t vehicle = DefaultVehicleFirmware) + : autopilotStackType(stack), firmwareType(firmware), firmwareVehicleType(vehicle) {} + + bool operator==(const FirmwareIdentifier& firmwareId) const + { + return (firmwareId.autopilotStackType == autopilotStackType && + firmwareId.firmwareType == firmwareType && + firmwareId.firmwareVehicleType == firmwareVehicleType); + } + + // members + AutoPilotStackType_t autopilotStackType; + FirmwareType_t firmwareType; + FirmwareVehicleType_t firmwareVehicleType; + }; + FirmwareUpgradeController(void); - /// Supported firmware types. If you modify these you will need to update the qml file as well. - typedef enum { - PX4StableFirmware, - PX4BetaFirmware, - PX4DeveloperFirmware, - PX4CustomFirmware, - ApmArduCopterQuadFirmware, - ApmArduCopterX8Firmware, - ApmArduCopterHexaFirmware, - ApmArduCopterOctoFirmware, - ApmArduCopterYFirmware, - ApmArduCopterY6Firmware, - ApmArduCopterHeliFirmware, - ApmArduPlaneFirmware, - ApmRoverFirmware, - } FirmwareType_t; - - Q_ENUMS(FirmwareType_t) - Q_PROPERTY(QString boardPort READ boardPort NOTIFY boardFound) Q_PROPERTY(QString boardDescription READ boardDescription NOTIFY boardFound) Q_PROPERTY(QString boardType MEMBER _foundBoardType NOTIFY boardFound) @@ -90,8 +125,13 @@ public: Q_INVOKABLE void cancel(void); /// Called when the firmware type has been selected by the user to continue the flash process. - Q_INVOKABLE void flash(FirmwareType_t firmwareType); + Q_INVOKABLE void flash(AutoPilotStackType_t stackType, + FirmwareType_t firmwareType = StableFirmware, + FirmwareVehicleType_t vehicleType = DefaultVehicleFirmware ); + // overload, not exposed to qml side + void flash(const FirmwareIdentifier& firmwareId); + // Property accessors QQuickItem* progressBar(void) { return _progressBar; } @@ -133,27 +173,30 @@ private slots: void _linkDisconnected(LinkInterface* link); private: - void _getFirmwareFile(FirmwareType_t firmwareType); + void _getFirmwareFile(FirmwareIdentifier firmwareId); + void _initFirmwareHash(); void _downloadFirmware(void); void _appendStatusLog(const QString& text, bool critical = false); void _errorCancel(const QString& msg); - typedef struct { - FirmwareType_t firmwareType; - const char* downloadLocation; - } DownloadLocationByFirmwareType_t; - QString _portName; QString _portDescription; + // firmware hashes + QHash _rgPX4FMUV2Firmware; + QHash _rgAeroCoreFirmware; + QHash _rgPX4FMUV1Firmware; + QHash _rgPX4FLowFirmware; + QHash _rg3DRRadioFirmware; + /// Information which comes back from the bootloader bool _bootloaderFound; ///< true: we have received the foundBootloader signals uint32_t _bootloaderVersion; ///< Bootloader version uint32_t _bootloaderBoardID; ///< Board ID uint32_t _bootloaderBoardFlashSize; ///< Flash size in bytes of board - bool _startFlashWhenBootloaderFound; - FirmwareType_t _startFlashWhenBootloaderFoundFirmwareType; + bool _startFlashWhenBootloaderFound; + FirmwareIdentifier _startFlashWhenBootloaderFoundFirmwareIdentity; QPixmap _boardIcon; ///< Icon used to display image of board @@ -184,4 +227,7 @@ private: FirmwareImage* _image; }; +// global hashing function +uint qHash(const FirmwareUpgradeController::FirmwareIdentifier& firmwareId); + #endif