diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index cf615e4cef0944e6a582564fcee6ff0646b24e04..22aad502183871ff19d6affbd2478be86d74ccb0 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -332,7 +332,6 @@ FORMS += \ src/ui/JoystickAxis.ui \ src/ui/configuration/terminalconsole.ui \ src/ui/configuration/SerialSettingsDialog.ui \ - src/ui/px4_configuration/QGCPX4AirframeConfig.ui \ src/ui/px4_configuration/PX4RCCalibration.ui \ src/ui/QGCUASFileView.ui \ src/QGCQmlWidgetHolder.ui \ @@ -463,7 +462,6 @@ HEADERS += \ src/uas/UASParameterDataModel.h \ src/uas/UASParameterCommsMgr.h \ src/ui/QGCPendingParamWidget.h \ - src/ui/px4_configuration/QGCPX4AirframeConfig.h \ src/ui/QGCBaseParamWidget.h \ src/ui/px4_configuration/PX4RCCalibration.h \ src/ui/px4_configuration/RCValueWidget.h \ @@ -607,7 +605,6 @@ SOURCES += \ src/uas/UASParameterDataModel.cc \ src/uas/UASParameterCommsMgr.cc \ src/ui/QGCPendingParamWidget.cc \ - src/ui/px4_configuration/QGCPX4AirframeConfig.cc \ src/ui/QGCBaseParamWidget.cc \ src/ui/px4_configuration/PX4RCCalibration.cc \ src/ui/px4_configuration/RCValueWidget.cc \ @@ -730,6 +727,8 @@ HEADERS+= \ src/AutoPilotPlugins/PX4/FlightModesComponent.h \ src/AutoPilotPlugins/PX4/FlightModesComponentController.h \ src/AutoPilotPlugins/PX4/AirframeComponent.h \ + src/AutoPilotPlugins/PX4/AirframeComponentAirframes.h \ + src/AutoPilotPlugins/PX4/AirframeComponentController.h \ src/AutoPilotPlugins/PX4/SensorsComponent.h \ src/AutoPilotPlugins/PX4/SensorsComponentController.h \ src/AutoPilotPlugins/PX4/SafetyComponent.h \ @@ -753,6 +752,8 @@ SOURCES += \ src/AutoPilotPlugins/PX4/FlightModesComponent.cc \ src/AutoPilotPlugins/PX4/FlightModesComponentController.cc \ src/AutoPilotPlugins/PX4/AirframeComponent.cc \ + src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc \ + src/AutoPilotPlugins/PX4/AirframeComponentController.cc \ src/AutoPilotPlugins/PX4/SensorsComponent.cc \ src/AutoPilotPlugins/PX4/SensorsComponentController.cc \ src/AutoPilotPlugins/PX4/SafetyComponent.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 629936dd5b382dcb184950242994c16cc6ebb46d..da43af28ed5e3c6a5085e8532d00ecda0c6e48ad 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -244,11 +244,13 @@ src/test.qml src/QmlControls/QmlTest.qml + src/FactSystem/FactControls/qmldir src/FactSystem/FactControls/FactLabel.qml src/FactSystem/FactControls/FactTextField.qml src/FactSystem/FactControls/FactCheckBox.qml src/FactSystem/FactControls/FactComboBox.qml + src/QmlControls/qmldir src/QmlControls/QGCButton.qml src/QmlControls/QGCRadioButton.qml @@ -262,10 +264,13 @@ src/QmlControls/IndicatorButton.qml src/QmlControls/VehicleRotationCal.qml src/QmlControls/arrow-down.png + files/images/px4/airframes/octo_x.png files/images/px4/boards/px4fmu_2.x.png + src/VehicleSetup/SetupViewButtonsConnected.qml src/VehicleSetup/SetupViewButtonsDisconnected.qml + src/VehicleSetup/VehicleSummary.qml src/VehicleSetup/FirmwareUpgrade.qml src/AutoPilotPlugins/PX4/SafetyComponent.qml @@ -283,12 +288,27 @@ src/AutoPilotPlugins/PX4/Images/SafetyComponentHome.png src/AutoPilotPlugins/PX4/Images/SafetyComponentArrowDown.png src/AutoPilotPlugins/PX4/Images/SafetyComponentPlane.png + src/AutoPilotPlugins/PX4/Images/VehicleDown.png src/AutoPilotPlugins/PX4/Images/VehicleUpsideDown.png src/AutoPilotPlugins/PX4/Images/VehicleLeft.png src/AutoPilotPlugins/PX4/Images/VehicleRight.png src/AutoPilotPlugins/PX4/Images/VehicleNoseDown.png src/AutoPilotPlugins/PX4/Images/VehicleTailDown.png + + + src/AutoPilotPlugins/PX4/AirframeComponent.qml + src/AutoPilotPlugins/PX4/Images/AirframeStandardPlane.png + src/AutoPilotPlugins/PX4/Images/AirframeFlyingWing.png + src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorX.png + src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorPlus.png + src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorX.png + src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorPlus.png + src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorX.png + src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorPlus.png + src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorH.png + src/AutoPilotPlugins/PX4/Images/AirframeSimulation.png + files/Setup/cogwheels.png src/AutoPilotPlugins/PX4/Images/SensorsComponentIcon.png src/AutoPilotPlugins/PX4/Images/RadioComponentIcon.png @@ -298,12 +318,14 @@ src/AutoPilotPlugins/PX4/Images/PowerComponentIcon.png src/VehicleSetup/FirmwareUpgradeIcon.png src/VehicleSetup/VehicleSummaryIcon.png + src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_01cell.svg src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_02cell.svg src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_03cell.svg src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_04cell.svg src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_05cell.svg src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_06cell.svg + src/ui/toolbar/MainToolBar.qml diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.cc b/src/AutoPilotPlugins/PX4/AirframeComponent.cc index 04b757afc7cb4a97e0459b27d826f1c9a616d0b6..576bff02797989e09f4d55db7d570738ca9ee560 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponent.cc +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.cc @@ -25,7 +25,7 @@ /// @author Don Gagne #include "AirframeComponent.h" -#include "QGCPX4AirframeConfig.h" +#include "QGCQmlWidgetHolder.h" #if 0 // Broken by latest mavlink module changes. Not used yet. Comment out for now. @@ -179,7 +179,14 @@ QStringList AirframeComponent::paramFilterList(void) const QWidget* AirframeComponent::setupWidget(void) const { - return new QGCPX4AirframeConfig; + QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder(); + Q_CHECK_PTR(holder); + + holder->setAutoPilot(_autopilot); + + holder->setSource(QUrl::fromUserInput("qrc:/qml/AirframeComponent.qml")); + + return holder; } QUrl AirframeComponent::summaryQmlSource(void) const diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.qml b/src/AutoPilotPlugins/PX4/AirframeComponent.qml new file mode 100644 index 0000000000000000000000000000000000000000..96ea119466f74195ae5d092b7d9416558b562b0e --- /dev/null +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.qml @@ -0,0 +1,155 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 + +import QGroundControl.FactSystem 1.0 +import QGroundControl.FactControls 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Controllers 1.0 + +Rectangle { + AirframeComponentController { id: controller } + QGCPalette { id: qgcPal; colorGroupEnabled: true } + + color: qgcPal.window + + Column { + anchors.fill: parent + + QGCLabel { + text: "AIRFRAME CONFIG" + font.pointSize: 20 + } + + Item { height: 20; width: 10 } // spacer + + Row { + width: parent.width + + QGCLabel { + width: parent.width - applyButton.width + text: "Select you airframe type and specific vehicle bellow. Click 'Apply and Restart' when ready and your vehicle will be disconnected, rebooted to the new settings and re-connected." + wrapMode: Text.WordWrap + } + + QGCButton { + id: applyButton + text: "Apply and Restart" + onClicked: { controller.changeAutostart() } + } + } + + Item { height: 20; width: 10 } // spacer + + Flow { + width: parent.width + spacing: 10 + + ExclusiveGroup { + id: airframeTypeExclusive + } + + Repeater { + model: controller.airframeTypes + + // Outer summary item rectangle + Rectangle { + readonly property real titleHeight: 30 + readonly property real innerMargin: 10 + + width: 250 + height: 200 + color: qgcPal.windowShade + + Rectangle { + id: title + width: parent.width + height: parent.titleHeight + color: qgcPal.windowShadeDark + + Text { + anchors.fill: parent + + color: qgcPal.buttonText + font.pixelSize: 12 + text: modelData.name + + verticalAlignment: TextEdit.AlignVCenter + horizontalAlignment: TextEdit.AlignHCenter + } + } + + Image { + id: image + x: innerMargin + width: parent.width - (innerMargin * 2) + height: parent.height - title.height - combo.height - (innerMargin * 3) + anchors.topMargin: innerMargin + anchors.top: title.bottom + + source: modelData.imageResource + fillMode: Image.PreserveAspectFit + smooth: true + + } + + QGCCheckBox { + id: airframeCheckBox + anchors.bottom: image.bottom + anchors.right: image.right + checked: modelData.name == controller.currentAirframeType + exclusiveGroup: airframeTypeExclusive + + onCheckedChanged: { + if (checked && combo.currentIndex != -1) { + controller.autostartId = modelData.airframes[combo.currentIndex].autostartId + } + } + } + + QGCComboBox { + id: combo + objectName: modelData.airframeType + "ComboBox" + x: innerMargin + anchors.topMargin: innerMargin + anchors.top: image.bottom + width: parent.width - (innerMargin * 2) + model: modelData.airframes + currentIndex: (modelData.name == controller.currentAirframeType) ? controller.currentVehicleIndex : 0 + + onCurrentIndexChanged: { + if (airframeCheckBox.checked) { + controller.autostartId = modelData.airframes[currentIndex].autostartId + } + } + } + } + } + } + + } +} diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc b/src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc new file mode 100644 index 0000000000000000000000000000000000000000..46cf2368bf6ca7611ad25cc4627737959ee2d47b --- /dev/null +++ b/src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc @@ -0,0 +1,110 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009, 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "AirframeComponentAirframes.h" + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoStandardPlane[] = { + { "Multiplex Easystar 1/2", 2100 }, + { "Hobbyking Bixler 1/2", 2101 }, + { "3DR Skywalker", 2102 }, + { "Skyhunter (1800 mm)", 2103 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoSimulation[] = { + { "Plane (HilStar, X-Plane)", 1000 }, + { "Plane (Rascal, FlightGear)", 1004 }, + { "Quad X HIL", 1001 }, + { "Quad + HIL", 1003 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoFlyingWing[] = { + { "Z-84 Wing Wing (845 mm)", 3033 }, + { "TBS Caipirinha (850 mm)", 3100 }, + { "Bormatec Camflyer Q (800 mm)", 3030 }, + { "FX-61 Phantom FPV (1550 mm)", 3031 }, + { "FX-79 Buffalo (2000 mm)", 3034 }, + { "Skywalker X5 (1180 mm)", 3032 }, + { "Viper v2 (3000 mm)", 3035 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoQuadRotorX[] = { + { "DJI F330 8\" Quad", 4010 }, + { "DJI F450 10\" Quad", 4011 }, + { "X frame Quad UAVCAN", 4012 }, + { "AR.Drone Frame Quad", 4008 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoQuadRotorPlus[] = { + { "Generic 10\" Quad +", 5001 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoHexaRotorX[] = { + { "Standard 10\" Hexa X", 6001 }, + { "Coaxial 10\" Hexa X", 11001 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoHexaRotorPlus[] = { + { "Standard 10\" Hexa", 7001 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoOctoRotorX[] = { + { "Standard 10\" Octo", 8001 }, + { "Coaxial 10\" Octo", 12001 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoOctoRotorPlus[] = { + { "Standard 10\" Octo", 9001 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeInfo_t AirframeComponentAirframes::_rgAirframeInfoQuadRotorH[] = { + { "3DR Iris", 10016 }, + { "TBS Discovery", 10015 }, + { "SteadiDrone QU4D", 10017 }, + { NULL, 0 } +}; + +const AirframeComponentAirframes::AirframeType_t AirframeComponentAirframes::rgAirframeTypes[] = { + { "Standard Airplane", "qrc:/qml/AirframeStandardPlane.png", AirframeComponentAirframes::_rgAirframeInfoStandardPlane }, + { "Flying Wing", "qrc:/qml/AirframeFlyingWing.png", AirframeComponentAirframes::_rgAirframeInfoFlyingWing }, + { "QuadRotor X", "qrc:/qml/AirframeQuadRotorX.png", AirframeComponentAirframes::_rgAirframeInfoQuadRotorX }, + { "QuadRotor +", "qrc:/qml/AirframeQuadRotorPlus.png", AirframeComponentAirframes::_rgAirframeInfoQuadRotorPlus }, + { "HexaRotor X", "qrc:/qml/AirframeHexaRotorX.png", AirframeComponentAirframes::_rgAirframeInfoHexaRotorX }, + { "HexaRotor +", "qrc:/qml/AirframeHexaRotorPlus.png", AirframeComponentAirframes::_rgAirframeInfoHexaRotorPlus }, + { "OctoRotor X", "qrc:/qml/AirframeOctoRotorX.png", AirframeComponentAirframes::_rgAirframeInfoOctoRotorX }, + { "OctoRotor +", "qrc:/qml/AirframeOctoRotorPlus.png", AirframeComponentAirframes::_rgAirframeInfoOctoRotorPlus }, + { "QuadRotor H", "qrc:/qml/AirframeQuadRotorH.png", AirframeComponentAirframes::_rgAirframeInfoQuadRotorH }, + { "Simulation", "qrc:/qml/AirframeSimulation.png", AirframeComponentAirframes::_rgAirframeInfoSimulation }, + { NULL, NULL, NULL } +}; diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentAirframes.h b/src/AutoPilotPlugins/PX4/AirframeComponentAirframes.h new file mode 100644 index 0000000000000000000000000000000000000000..8c20e90b1ef11d9530fd4a2c823b866954ac1b56 --- /dev/null +++ b/src/AutoPilotPlugins/PX4/AirframeComponentAirframes.h @@ -0,0 +1,68 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009, 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#ifndef AIRFRAMECOMPONENTAIRFRAMES_H +#define AIRFRAMECOMPONENTAIRFRAMES_H + +#include +#include +#include + +#include "UASInterface.h" +#include "AutoPilotPlugin.h" + +/// MVC Controller for AirframeComponent.qml. +class AirframeComponentAirframes +{ +public: + typedef struct { + const char* name; + int autostartId; + } AirframeInfo_t; + + typedef struct { + const char* name; + const char* imageResource; + const AirframeInfo_t* rgAirframeInfo; + } AirframeType_t; + +public: + static const AirframeType_t rgAirframeTypes[]; + +private: + static const AirframeInfo_t _rgAirframeInfoStandardPlane[]; + static const AirframeInfo_t _rgAirframeInfoFlyingWing[]; + static const AirframeInfo_t _rgAirframeInfoQuadRotorX[]; + static const AirframeInfo_t _rgAirframeInfoQuadRotorPlus[]; + static const AirframeInfo_t _rgAirframeInfoOctoRotorX[]; + static const AirframeInfo_t _rgAirframeInfoOctoRotorPlus[]; + static const AirframeInfo_t _rgAirframeInfoHexaRotorX[]; + static const AirframeInfo_t _rgAirframeInfoHexaRotorPlus[]; + static const AirframeInfo_t _rgAirframeInfoQuadRotorH[]; + static const AirframeInfo_t _rgAirframeInfoSimulation[]; +}; + +#endif diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentController.cc b/src/AutoPilotPlugins/PX4/AirframeComponentController.cc new file mode 100644 index 0000000000000000000000000000000000000000..695b53cfa9ac2b8fd65777e60993f81ee1b1e32f --- /dev/null +++ b/src/AutoPilotPlugins/PX4/AirframeComponentController.cc @@ -0,0 +1,174 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009, 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "AirframeComponentController.h" +#include "AirframeComponentAirframes.h" +#include "QGCMAVLink.h" +#include "UASManager.h" +#include "AutoPilotPluginManager.h" +#include "QGCApplication.h" +#include "QGCMessageBox.h" + +#include +#include + +bool AirframeComponentController::_typesRegistered = false; + +AirframeComponentController::AirframeComponentController(QObject* parent) : + QObject(parent), + _uas(NULL), + _autoPilotPlugin(NULL) +{ + _uas = UASManager::instance()->getActiveUAS(); + Q_ASSERT(_uas); + + _autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas); + Q_ASSERT(_autoPilotPlugin); + Q_ASSERT(_autoPilotPlugin->pluginReady()); + + if (!_typesRegistered) { + _typesRegistered = true; + qmlRegisterUncreatableType("QGroundControl.Controllers", 1, 0, "AiframeType", "Can only reference AirframeType"); + qmlRegisterUncreatableType("QGroundControl.Controllers", 1, 0, "Aiframe", "Can only reference Airframe"); + } + + // Load up member variables + + bool autostartFound = false; + _autostartId = _autoPilotPlugin->getParameterFact("SYS_AUTOSTART")->value().toInt(); + + for (const AirframeComponentAirframes::AirframeType_t* pType=&AirframeComponentAirframes::rgAirframeTypes[0]; pType->name != NULL; pType++) { + AirframeType* airframeType = new AirframeType(pType->name, pType->imageResource, this); + Q_CHECK_PTR(airframeType); + + int index = 0; + for (const AirframeComponentAirframes::AirframeInfo_t* pInfo=&pType->rgAirframeInfo[0]; pInfo->name != NULL; pInfo++) { + if (_autostartId == pInfo->autostartId) { + Q_ASSERT(!autostartFound); + autostartFound = true; + _currentAirframeType = pType->name; + _currentVehicleName = pInfo->name; + _currentVehicleIndex = index; + } + airframeType->addAirframe(pInfo->name, pInfo->autostartId); + index++; + } + + _airframeTypes.append(QVariant::fromValue(airframeType)); + } + + // FIXME: Should be a user error + Q_ASSERT(autostartFound); + +} + +AirframeComponentController::~AirframeComponentController() +{ + +} + +void AirframeComponentController::changeAutostart(void) +{ + LinkManager* linkManager = LinkManager::instance(); + + if (linkManager->getLinks().count() > 1) { + QGCMessageBox::warning("Airframe Config", "You cannot change airframe configuration while connected to multiple vehicles."); + return; + } + + _autoPilotPlugin->getParameterFact("SYS_AUTOSTART")->setValue(_autostartId); + _autoPilotPlugin->getParameterFact("SYS_AUTOCONFIG")->setValue(1); + + // Wait for the parameters to come back to us + + qgcApp()->setOverrideCursor(Qt::WaitCursor); + + int waitSeconds = 10; + bool success = false; + + QGCUASParamManagerInterface* paramMgr = _uas->getParamManager(); + + while (true) { + if (paramMgr->countPendingParams() == 0) { + success = true; + break; + } + qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents); + QGC::SLEEP::sleep(1); + if (--waitSeconds == 0) { + break; + } + } + + + if (!success) { + qgcApp()->restoreOverrideCursor(); + QGCMessageBox::critical("Airframe Config", "Airframe Config parameters not received back from vehicle. Config has not been set."); + return; + } + + _uas->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents); + QGC::SLEEP::sleep(1); + qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents); + + qgcApp()->reconnectAfterWait(5); +} + +AirframeType::AirframeType(const QString& name, const QString& imageResource, QObject* parent) : + QObject(parent), + _name(name), + _imageResource(imageResource) +{ + +} + +AirframeType::~AirframeType() +{ + +} + +void AirframeType::addAirframe(const QString& name, int autostartId) +{ + Airframe* airframe = new Airframe(name, autostartId); + Q_CHECK_PTR(airframe); + + _airframes.append(QVariant::fromValue(airframe)); +} + +Airframe::Airframe(const QString& name, int autostartId, QObject* parent) : + QObject(parent), + _name(name), + _autostartId(autostartId) +{ + +} + +Airframe::~Airframe() +{ + +} + diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentController.h b/src/AutoPilotPlugins/PX4/AirframeComponentController.h new file mode 100644 index 0000000000000000000000000000000000000000..25ac266a348e1100d4e1418583140a1c2ebe657b --- /dev/null +++ b/src/AutoPilotPlugins/PX4/AirframeComponentController.h @@ -0,0 +1,110 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009, 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#ifndef AIRFRAMECOMPONENTCONTROLLER_H +#define AIRFRAMECOMPONENTCONTROLLER_H + +#include +#include +#include + +#include "UASInterface.h" +#include "AutoPilotPlugin.h" + +/// MVC Controller for AirframeComponent.qml. +class AirframeComponentController : public QObject +{ + Q_OBJECT + +public: + AirframeComponentController(QObject* parent = NULL); + ~AirframeComponentController(); + + Q_PROPERTY(QVariantList airframeTypes MEMBER _airframeTypes CONSTANT) + + Q_PROPERTY(QString currentAirframeType MEMBER _currentAirframeType CONSTANT) + Q_PROPERTY(QString currentVehicleName MEMBER _currentVehicleName CONSTANT) + Q_PROPERTY(int currentVehicleIndex MEMBER _currentVehicleIndex CONSTANT) + + Q_PROPERTY(int autostartId MEMBER _autostartId NOTIFY autostartIdChanged) + + Q_INVOKABLE void changeAutostart(void); + + int currentAirframeIndex(void); + void setCurrentAirframeIndex(int newIndex); + +signals: + void autostartIdChanged(int newAutostartId); + +private: + static bool _typesRegistered; + + UASInterface* _uas; + AutoPilotPlugin* _autoPilotPlugin; + QVariantList _airframeTypes; + QString _currentAirframeType; + QString _currentVehicleName; + int _currentVehicleIndex; + int _autostartId; +}; + +class Airframe : public QObject +{ + Q_OBJECT + +public: + Airframe(const QString& name, int autostartId, QObject* parent = NULL); + ~Airframe(); + + Q_PROPERTY(QString text MEMBER _name CONSTANT) + Q_PROPERTY(int autostartId MEMBER _autostartId CONSTANT) + +private: + QString _name; + int _autostartId; +}; + +class AirframeType : public QObject +{ + Q_OBJECT + +public: + AirframeType(const QString& name, const QString& imageResource, QObject* parent = NULL); + ~AirframeType(); + + Q_PROPERTY(QString name MEMBER _name CONSTANT) + Q_PROPERTY(QString imageResource MEMBER _imageResource CONSTANT) + Q_PROPERTY(QVariantList airframes MEMBER _airframes CONSTANT) + + void addAirframe(const QString& name, int autostartId); + +private: + QString _name; + QString _imageResource; + QVariantList _airframes; +}; + +#endif diff --git a/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml b/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml index c7f67f233d4df39c21477f78ed2ae29959940600..d25a8f8f80e9e43ec8f3f148ca623d9047b75f99 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml +++ b/src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml @@ -5,11 +5,14 @@ import QtQuick.Controls.Styles 1.2 import QGroundControl.FactSystem 1.0 import QGroundControl.FactControls 1.0 import QGroundControl.Controls 1.0 +import QGroundControl.Controllers 1.0 Column { anchors.fill: parent anchors.margins: 8 + AirframeComponentController { id: controller } + Row { width: parent.width @@ -24,12 +27,24 @@ Column { Row { width: parent.width - QGCLabel { id: airframe; text: "Airframe:" } + QGCLabel { id: airframeType; text: "Airframe type:" } + QGCLabel { + property Fact fact: Fact { name: "SYS_AUTOSTART" } + horizontalAlignment: Text.AlignRight + width: parent.width - airframeType.contentWidth + text: fact.value == 0 ? "Setup required" : controller.currentAirframeType + } + } + + Row { + width: parent.width + + QGCLabel { id: vehicle; text: "Vehicle:" } QGCLabel { property Fact fact: Fact { name: "SYS_AUTOSTART" } horizontalAlignment: Text.AlignRight - width: parent.width - airframe.contentWidth - text: fact.value == 0 ? "Setup required" : fact.value + width: parent.width - vehicle.contentWidth + text: fact.value == 0 ? "Setup required" : controller.currentVehicleName } } } diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeFlyingWing.png b/src/AutoPilotPlugins/PX4/Images/AirframeFlyingWing.png new file mode 100644 index 0000000000000000000000000000000000000000..b5baa87dd2b6fc1366feaac3ee43b3eea6947280 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeFlyingWing.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorPlus.png b/src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorPlus.png new file mode 100755 index 0000000000000000000000000000000000000000..486d63a04204a925d0515d9195b948d4971453c4 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorPlus.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorX.png b/src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorX.png new file mode 100755 index 0000000000000000000000000000000000000000..cd1fe507dfd4e448c5f2c1e6113f26463d7c30d1 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeHexaRotorX.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorPlus.png b/src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorPlus.png new file mode 100755 index 0000000000000000000000000000000000000000..df6eefff2e32ba8179a7d08ad1b583180b8231d6 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorPlus.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorX.png b/src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorX.png new file mode 100755 index 0000000000000000000000000000000000000000..41faf992abe13e44e973268bb9ca1c659e391203 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeOctoRotorX.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorH.png b/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorH.png new file mode 100644 index 0000000000000000000000000000000000000000..1c5efb6e8a54c169b8c3e6b22095b997927465af Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorH.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorPlus.png b/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorPlus.png new file mode 100755 index 0000000000000000000000000000000000000000..4832def6c73a6a387038774cf270225549400d9f Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorPlus.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorX.png b/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorX.png new file mode 100755 index 0000000000000000000000000000000000000000..ea6835509aa5f58fbc000d018ea72e485ebf5884 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeQuadRotorX.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeSimulation.png b/src/AutoPilotPlugins/PX4/Images/AirframeSimulation.png new file mode 100644 index 0000000000000000000000000000000000000000..583d08d01d25dea95eff062b8eef00ba35668d53 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeSimulation.png differ diff --git a/src/AutoPilotPlugins/PX4/Images/AirframeStandardPlane.png b/src/AutoPilotPlugins/PX4/Images/AirframeStandardPlane.png new file mode 100644 index 0000000000000000000000000000000000000000..583d08d01d25dea95eff062b8eef00ba35668d53 Binary files /dev/null and b/src/AutoPilotPlugins/PX4/Images/AirframeStandardPlane.png differ diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc index 3aca2983231a316a84ff2a80bd0b496e4bf8331d..995853ef12fb8024224a81ecb38585268d5f9aa8 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc @@ -27,6 +27,7 @@ #include "QGCUASParamManagerInterface.h" #include "PX4ParameterFacts.h" #include "FlightModesComponentController.h" +#include "AirframeComponentController.h" #include "QGCMessageBox.h" /// @file @@ -76,6 +77,7 @@ PX4AutoPilotPlugin::PX4AutoPilotPlugin(UASInterface* uas, QObject* parent) : Q_ASSERT(uas); qmlRegisterType("QGroundControl.Controllers", 1, 0, "FlightModesComponentController"); + qmlRegisterType("QGroundControl.Controllers", 1, 0, "AirframeComponentController"); _parameterFacts = new PX4ParameterFacts(uas, this); Q_CHECK_PTR(_parameterFacts); diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc b/src/ui/px4_configuration/QGCPX4AirframeConfig.cc deleted file mode 100644 index 5aec881fdb01d7d5601384fb6b1dd2c2129630d5..0000000000000000000000000000000000000000 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.cc +++ /dev/null @@ -1,542 +0,0 @@ -#include -#include -#include - -#include "QGCPX4AirframeConfig.h" -#include "ui_QGCPX4AirframeConfig.h" - -#include "UASManager.h" -#include "LinkManager.h" -#include "UAS.h" -#include "QGC.h" -#include "QGCMessageBox.h" - -QGCPX4AirframeConfig::QGCPX4AirframeConfig(QWidget *parent) : - QWidget(parent), - mav(NULL), - progress(NULL), - pendingParams(0), - configState(CONFIG_STATE_ABORT), - selectedId(-1), - ui(new Ui::QGCPX4AirframeConfig) -{ - ui->setupUi(this); - - // Fill the lists here manually in accordance with the list from: - // https://github.com/PX4/Firmware/blob/master/ROMFS/px4fmu_common/init.d/rcS - - ui->simComboBox->addItem(tr("Plane (HilStar, X-Plane)"), 1000); - ui->simComboBox->addItem(tr("Plane (Rascal, FlightGear)"), 1004); - ui->simComboBox->addItem(tr("Quad X HIL"), 1001); - ui->simComboBox->addItem(tr("Quad + HIL"), 1003); - - connect(ui->simPushButton, SIGNAL(clicked()), this, SLOT(simSelected())); - connect(ui->simComboBox, SIGNAL(activated(int)), this, SLOT(simSelected(int))); - ui->simPushButton->setEnabled(ui->simComboBox->count() > 0); - - ui->planeComboBox->addItem(tr("Multiplex Easystar 1/2"), 2100); - ui->planeComboBox->addItem(tr("Hobbyking Bixler 1/2"), 2101); - ui->planeComboBox->addItem(tr("3DR Skywalker"), 2102); - ui->planeComboBox->addItem(tr("Skyhunter (1800 mm)"), 2103); - - connect(ui->planePushButton, SIGNAL(clicked()), this, SLOT(planeSelected())); - connect(ui->planeComboBox, SIGNAL(activated(int)), this, SLOT(planeSelected(int))); - ui->planePushButton->setEnabled(ui->planeComboBox->count() > 0); - - ui->flyingWingComboBox->addItem(tr("Z-84 Wing Wing (845 mm)"), 3033); - ui->flyingWingComboBox->addItem(tr("TBS Caipirinha (850 mm)"), 3100); - ui->flyingWingComboBox->addItem(tr("Bormatec Camflyer Q (800 mm)"), 3030); - ui->flyingWingComboBox->addItem(tr("FX-61 Phantom FPV (1550 mm)"), 3031); - ui->flyingWingComboBox->addItem(tr("FX-79 Buffalo (2000 mm)"), 3034); - ui->flyingWingComboBox->addItem(tr("Skywalker X5 (1180 mm)"), 3032); - ui->flyingWingComboBox->addItem(tr("Viper v2 (3000 mm)"), 3035); - - connect(ui->flyingWingPushButton, SIGNAL(clicked()), this, SLOT(flyingWingSelected())); - connect(ui->flyingWingComboBox, SIGNAL(activated(int)), this, SLOT(flyingWingSelected(int))); - - ui->quadXComboBox->addItem(tr("DJI F330 8\" Quad"), 4010); - ui->quadXComboBox->addItem(tr("DJI F450 10\" Quad"), 4011); - ui->quadXComboBox->addItem(tr("X frame Quad UAVCAN"), 4012); - ui->quadXComboBox->addItem(tr("AR.Drone Frame Quad"), 4008); -// ui->quadXComboBox->addItem(tr("DJI F330 with MK BLCTRL"), 4017); -// ui->quadXComboBox->addItem(tr("Mikrokopter X frame"), 4019); - - connect(ui->quadXPushButton, SIGNAL(clicked()), this, SLOT(quadXSelected())); - connect(ui->quadXComboBox, SIGNAL(activated(int)), this, SLOT(quadXSelected(int))); - ui->quadXPushButton->setEnabled(ui->quadXComboBox->count() > 0); - - ui->quadPlusComboBox->addItem(tr("Generic 10\" Quad +"), 5001); -// ui->quadXComboBox->addItem(tr("Mikrokopter + frame"), 5020); - - connect(ui->quadPlusPushButton, SIGNAL(clicked()), this, SLOT(quadPlusSelected())); - connect(ui->quadPlusComboBox, SIGNAL(activated(int)), this, SLOT(quadPlusSelected(int))); - ui->quadPlusPushButton->setEnabled(ui->quadPlusComboBox->count() > 0); - - ui->hexaXComboBox->addItem(tr("Standard 10\" Hexa X"), 6001); - ui->hexaXComboBox->addItem(tr("Coaxial 10\" Hexa X"), 11001); - - connect(ui->hexaXPushButton, SIGNAL(clicked()), this, SLOT(hexaXSelected())); - connect(ui->hexaXComboBox, SIGNAL(activated(int)), this, SLOT(hexaXSelected(int))); - ui->hexaXPushButton->setEnabled(ui->hexaXComboBox->count() > 0); - - ui->hexaPlusComboBox->addItem(tr("Standard 10\" Hexa"), 7001); - - connect(ui->hexaPlusPushButton, SIGNAL(clicked()), this, SLOT(hexaPlusSelected())); - connect(ui->hexaPlusComboBox, SIGNAL(activated(int)), this, SLOT(hexaPlusSelected(int))); - ui->hexaPlusPushButton->setEnabled(ui->hexaPlusComboBox->count() > 0); - - ui->octoXComboBox->addItem(tr("Standard 10\" Octo"), 8001); - ui->octoXComboBox->addItem(tr("Coaxial 10\" Octo"), 12001); - - connect(ui->octoXPushButton, SIGNAL(clicked()), this, SLOT(octoXSelected())); - connect(ui->octoXComboBox, SIGNAL(activated(int)), this, SLOT(octoXSelected(int))); - ui->octoXPushButton->setEnabled(ui->octoXComboBox->count() > 0); - - ui->octoPlusComboBox->addItem(tr("Standard 10\" Octo"), 9001); - - connect(ui->octoPlusPushButton, SIGNAL(clicked()), this, SLOT(octoPlusSelected())); - connect(ui->octoPlusComboBox, SIGNAL(activated(int)), this, SLOT(octoPlusSelected(int))); - ui->octoPlusPushButton->setEnabled(ui->octoPlusComboBox->count() > 0); - - ui->hComboBox->addItem(tr("3DR Iris"), 10016); - ui->hComboBox->addItem(tr("TBS Discovery"), 10015); - ui->hComboBox->addItem(tr("SteadiDrone QU4D"), 10017); - - connect(ui->hPushButton, SIGNAL(clicked()), this, SLOT(hSelected())); - connect(ui->hComboBox, SIGNAL(activated(int)), this, SLOT(hSelected(int))); - ui->hPushButton->setEnabled(ui->hComboBox->count() > 0); - - connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(applyAndReboot())); - - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); - - uncheckAll(); - - setActiveUAS(UASManager::instance()->getActiveUAS()); -} - -void QGCPX4AirframeConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value) -{ - Q_UNUSED(uas); - Q_UNUSED(component); - - if (parameterName.contains("SYS_AUTOSTART")) - { - int index = value.toInt(); - if (index > 0) { - setAirframeID(index); - ui->statusLabel->setText(tr("Onboard start script ID: #%1").arg(index)); - } else { - uncheckAll(); - ui->statusLabel->setText(tr("System not configured for autostart.")); - } - } -} - -void QGCPX4AirframeConfig::setActiveUAS(UASInterface* uas) -{ - if (mav) - { - disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - mav = NULL; - } - - if (!uas) - return; - - mav = uas; - paramMgr = mav->getParamManager(); - - connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this, SLOT(parameterChanged(int,int,QString,QVariant))); - - // If the parameters are ready, we aren't going to get paramterChanged signals. So fake them in order to make the UI work. - if (uas->getParamManager()->parametersReady()) { - QVariant value; - static const char* param = "SYS_AUTOSTART"; - - QGCUASParamManagerInterface* paramMgr = uas->getParamManager(); - - QList compIds = paramMgr->getComponentForParam(param); - Q_ASSERT(compIds.count() == 1); - paramMgr->getParameterValue(compIds[0], param, value); - parameterChanged(uas->getUASID(), compIds[0], param, value); - } -} - -void QGCPX4AirframeConfig::uncheckAll() -{ - ui->planePushButton->setChecked(false); - ui->flyingWingPushButton->setChecked(false); - ui->quadXPushButton->setChecked(false); - ui->quadPlusPushButton->setChecked(false); - ui->hexaXPushButton->setChecked(false); - ui->hexaPlusPushButton->setChecked(false); - ui->octoXPushButton->setChecked(false); - ui->octoPlusPushButton->setChecked(false); - ui->hPushButton->setChecked(false); -} - -void QGCPX4AirframeConfig::setAirframeID(int id) -{ - - qDebug() << "setAirframeID" << id; - ui->statusLabel->setText(tr("Start script ID: #%1").arg(id)); - - selectedId = id; - - // XXX too much boilerplate code here - this widget is really just - // a quick hack to get started - uncheckAll(); - - if (id >= 1000 && id < 2000) - { - ui->simPushButton->setChecked(true); - ui->simComboBox->setCurrentIndex(ui->simComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected simulation (ID: #%1)").arg(selectedId)); - } - else if (id >= 2000 && id < 3000) - { - ui->planePushButton->setChecked(true); - ui->planeComboBox->setCurrentIndex(ui->planeComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected plane (ID: #%1)").arg(selectedId)); - } - else if (id >= 3000 && id < 4000) - { - ui->flyingWingPushButton->setChecked(true); - ui->flyingWingComboBox->setCurrentIndex(ui->flyingWingComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected flying wing (ID: #%1)").arg(selectedId)); - } - else if (id >= 4000 && id < 5000) { - ui->quadXPushButton->setChecked(true); - ui->quadXComboBox->setCurrentIndex(ui->quadXComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected quadrotor in X config (ID: #%1)").arg(selectedId)); - } - else if (id >= 5000 && id < 6000) { - ui->quadPlusPushButton->setChecked(true); - ui->quadPlusComboBox->setCurrentIndex(ui->quadPlusComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected quadrotor in + config (ID: #%1)").arg(selectedId)); - } - else if (id >= 6000 && id < 7000) { - ui->hexaXPushButton->setChecked(true); - ui->hexaXComboBox->setCurrentIndex(ui->hexaXComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected hexarotor in X config (ID: #%1)").arg(selectedId)); - } - else if (id >= 7000 && id < 8000) { - ui->hexaPlusPushButton->setChecked(true); - ui->hexaPlusComboBox->setCurrentIndex(ui->hexaPlusComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected hexarotor in + config (ID: #%1)").arg(selectedId)); - } - else if (id >= 8000 && id < 9000) { - ui->octoXPushButton->setChecked(true); - ui->octoXComboBox->setCurrentIndex(ui->octoXComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected octorotor in X config (ID: #%1)").arg(selectedId)); - } - else if (id >= 9000 && id < 10000) { - ui->octoPlusPushButton->setChecked(true); - ui->octoPlusComboBox->setCurrentIndex(ui->octoPlusComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected octorotor in + config (ID: #%1)").arg(selectedId)); - } - else if (id >= 10000 && id < 11000) - { - ui->hPushButton->setChecked(true); - ui->hComboBox->setCurrentIndex(ui->hComboBox->findData(id)); - ui->statusLabel->setText(tr("Selected H frame multirotor (ID: #%1)").arg(selectedId)); - } - - -} - -void QGCPX4AirframeConfig::applyAndReboot() -{ - // Guard against the case of an edit where we didn't receive all params yet - if (selectedId <= 0) - { - QGCMessageBox::warning(tr("No airframe selected"), - tr("Please select an airframe first.")); - return; - } - - if (!mav) - return; - - if (paramMgr->countOnboardParams() == 0 && - paramMgr->countPendingParams() == 0) - { - paramMgr->requestParameterList(); - QGC::SLEEP::msleep(300); - } - - QList components = paramMgr->getComponentForParam("SYS_AUTOSTART"); - - // Guard against the case of an edit where we didn't receive all params yet - if (paramMgr->countPendingParams() > 0 || components.count() == 0) - { - QGCMessageBox::information(tr("Parameter sync with UAS not yet complete"), - tr("Please wait a few moments and retry")); - return; - } - - // Guard against multiple components responding - this will never show in practice - if (components.count() != 1) { - QGCMessageBox::warning(tr("Invalid system setup detected"), - tr("None or more than one component advertised to provide the main system configuration option. This is an invalid system setup - please check your autopilot.")); - return; - } - - // This is really evil: 'fake' a thread by - // periodic work queue calls and clock - // through a small state machine - // ugh.. if we just had time to do this properly. - - // To the reader who can't program and wants to whine: - // this is not beautiful, but technically completely - // sound. If you want to fix it, you'd be welcome - // to rebase the link, param manager and UI classes - // on a proper threading framework - which I'd love to do - // if I just had more time.. - - configState = CONFIG_STATE_SEND; - QTimer::singleShot(200, this, SLOT(checkConfigState())); - setEnabled(false); -} - -void QGCPX4AirframeConfig::checkConfigState() -{ - - if (configState == CONFIG_STATE_SEND) - { - QList components = paramMgr->getComponentForParam("SYS_AUTOSTART"); - qDebug() << "Setting comp" << components.first() << "SYS_AUTOSTART" << (qint32)selectedId; - - paramMgr->setPendingParam(components.first(),"SYS_AUTOSTART", (qint32)selectedId); - - //need to set autoconfig in order for PX4 to pick up the selected airframe params - if (ui->defaultGainsCheckBox->checkState() == Qt::Checked) - setAutoConfig(true); - - // Send pending params and then write them to persistent storage when done - paramMgr->sendPendingParameters(true); - - configState = CONFIG_STATE_WAIT_PENDING; - pendingParams = 0; - QTimer::singleShot(2000, this, SLOT(checkConfigState())); - return; - } - - if (configState == CONFIG_STATE_WAIT_PENDING) { - // Guard against the case of an edit where we didn't receive all params yet - if (paramMgr->countPendingParams() > 0) - { - if (pendingParams == 0) { - - pendingParams = paramMgr->countPendingParams(); - - if (progress) - delete progress; - - progress = new QProgressDialog("Writing parameters", "Abort Send", 0, pendingParams, this); - progress->setWindowModality(Qt::WindowModal); - progress->setMinimumDuration(2000); - } - - qDebug() << "PENDING" << paramMgr->countPendingParams() << "PROGRESS" << pendingParams - paramMgr->countPendingParams(); - progress->setValue(pendingParams - paramMgr->countPendingParams()); - - if (progress->wasCanceled()) { - configState = CONFIG_STATE_ABORT; - setEnabled(true); - pendingParams = 0; - return; - } - } else { - pendingParams = 0; - configState = CONFIG_STATE_REBOOT; - } - - qDebug() << "PENDING PARAMS WAIT PENDING: " << paramMgr->countPendingParams(); - QTimer::singleShot(1000, this, SLOT(checkConfigState())); - return; - } - - if (configState == CONFIG_STATE_REBOOT) { - - // Reboot - //TODO right now this relies upon the above send & persist finishing before the reboot command is received... - - unsigned pendingMax = 17; - - qDebug() << "PENDING PARAMS REBOOT BEFORE" << pendingParams; - - if (pendingParams == 0) { - pendingParams = 1; - - if (progress) - delete progress; - - progress = new QProgressDialog("Waiting for autopilot reboot", "Abort", 0, pendingMax, this); - progress->setWindowModality(Qt::WindowModal); - qDebug() << "Waiting for reboot, pending" << pendingParams; - } else { - if (progress->wasCanceled()) { - configState = CONFIG_STATE_ABORT; - setEnabled(true); - pendingParams = 0; - return; - } - } - - if (pendingParams == 3) { - qDebug() << "REQUESTING REBOOT"; - mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); - mav->executeCommand(MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); - } - - if (pendingParams == 4) { - qDebug() << "DISCONNECT AIRFRAME"; - LinkManager::instance()->disconnectAll(); - } - - if (pendingParams == 14) { - qDebug() << "CONNECT AIRFRAME"; - LinkManager::instance()->connectAll(); - } - - if (pendingParams < pendingMax) { - progress->setValue(pendingParams); - QTimer::singleShot(1000, this, SLOT(checkConfigState())); - } else { - paramMgr->requestParameterList(); - progress->setValue(pendingMax); - configState = CONFIG_STATE_ABORT; - pendingParams = 0; - setEnabled(true); - return; - } - qDebug() << "PENDING PARAMS REBOOT AFTER:" << pendingParams; - pendingParams++; - return; - } -} - -void QGCPX4AirframeConfig::setAutoConfig(bool enabled) -{ - if (!mav) - return; - paramMgr->setPendingParam(0, "SYS_AUTOCONFIG", (qint32) ((enabled) ? 1 : 0)); -} - -void QGCPX4AirframeConfig::simSelected() -{ - simSelected(ui->simComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::simSelected(int index) -{ - int system_index = ui->simComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::flyingWingSelected() -{ - flyingWingSelected(ui->flyingWingComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::flyingWingSelected(int index) -{ - int system_index = ui->flyingWingComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::planeSelected() -{ - planeSelected(ui->planeComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::planeSelected(int index) -{ - int system_index = ui->planeComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::quadXSelected() -{ - quadXSelected(ui->quadXComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::quadXSelected(int index) -{ - int system_index = ui->quadXComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::quadPlusSelected() -{ - quadPlusSelected(ui->quadPlusComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::quadPlusSelected(int index) -{ - int system_index = ui->quadPlusComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::hexaXSelected() -{ - hexaXSelected(ui->hexaXComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::hexaXSelected(int index) -{ - int system_index = ui->hexaXComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::hexaPlusSelected() -{ - hexaPlusSelected(ui->hexaPlusComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::hexaPlusSelected(int index) -{ - int system_index = ui->hexaPlusComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::octoXSelected() -{ - octoXSelected(ui->octoXComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::octoXSelected(int index) -{ - int system_index = ui->octoXComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::octoPlusSelected() -{ - octoPlusSelected(ui->octoPlusComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::octoPlusSelected(int index) -{ - int system_index = ui->octoPlusComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - -void QGCPX4AirframeConfig::hSelected() -{ - hSelected(ui->hComboBox->currentIndex()); -} - -void QGCPX4AirframeConfig::hSelected(int index) -{ - int system_index = ui->hComboBox->itemData(index).toInt(); - setAirframeID(system_index); -} - - -QGCPX4AirframeConfig::~QGCPX4AirframeConfig() -{ - delete ui; -} diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.h b/src/ui/px4_configuration/QGCPX4AirframeConfig.h deleted file mode 100644 index 4ebe33890c12337800e86ef3ccd2713407957b00..0000000000000000000000000000000000000000 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef QGCPX4AIRFRAMECONFIG_H -#define QGCPX4AIRFRAMECONFIG_H - -#include -#include - -class QProgressDialog; - -namespace Ui { -class QGCPX4AirframeConfig; -} - -class QGCPX4AirframeConfig : public QWidget -{ - Q_OBJECT - -public: - explicit QGCPX4AirframeConfig(QWidget *parent = 0); - ~QGCPX4AirframeConfig(); - -public slots: - - /** - * @brief Set the system currently operated on by this widget - * @param uas The currently active / configured system - */ - void setActiveUAS(UASInterface* uas); - - /** - * @brief Handle parameter changes - * @param uas - * @param component - * @param parameterName - * @param value - */ - void parameterChanged(int uas, int component, QString parameterName, QVariant value); - - /** - * @brief Quadrotor in X configuration has been selected - */ - void quadXSelected(); - - /** - * @brief Quadrotor in X configuration has been selected with sub-type - * @param index The autostart index which maps to a particular sub-type - */ - void quadXSelected(int index); - - void simSelected(); - void simSelected(int index); - void planeSelected(); - void planeSelected(int index); - void flyingWingSelected(); - void flyingWingSelected(int index); - void quadPlusSelected(); - void quadPlusSelected(int index); - void hexaXSelected(); - void hexaXSelected(int index); - void hexaPlusSelected(); - void hexaPlusSelected(int index); - void octoXSelected(); - void octoXSelected(int index); - void octoPlusSelected(); - void octoPlusSelected(int index); - void hSelected(); - void hSelected(int index); - - /** - * @brief Apply changes and reboot system - */ - void applyAndReboot(); - -protected slots: - void checkConfigState(); - -protected: - - /** - * @brief Set the ID of the current airframe - * @param id the ID as defined by the PX4 SYS_AUTOSTART enum - */ - void setAirframeID(int id); - - /** - * @brief Enable automatic configuration - * @param enabled If true, the system sets the default gains for this platform on the next boot - */ - void setAutoConfig(bool enabled); - - void uncheckAll(); - - enum CONFIG_STATE { - CONFIG_STATE_ABORT = 0, - CONFIG_STATE_SEND, - CONFIG_STATE_WAIT_PENDING, - CONFIG_STATE_REBOOT - }; - -private: - UASInterface* mav; - QGCUASParamManagerInterface *paramMgr; - QProgressDialog* progress; - unsigned pendingParams; - enum CONFIG_STATE configState; - int selectedId; - Ui::QGCPX4AirframeConfig *ui; -}; - -#endif // QGCPX4AIRFRAMECONFIG_H diff --git a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui b/src/ui/px4_configuration/QGCPX4AirframeConfig.ui deleted file mode 100644 index 2c9f5d8195013c61c84a394db32f300f4b1bb524..0000000000000000000000000000000000000000 --- a/src/ui/px4_configuration/QGCPX4AirframeConfig.ui +++ /dev/null @@ -1,427 +0,0 @@ - - - QGCPX4AirframeConfig - - - - 0 - 0 - 802 - 471 - - - - - 0 - 0 - - - - - 802 - 471 - - - - Form - - - - - - Set default airframe settings - - - true - - - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 761 - 611 - - - - - - - - - - - - - :/files/images/px4/airframes/plane_aert.png:/files/images/px4/airframes/plane_aert.png - - - - 120 - 120 - - - - true - - - - - - - - - - Standard Plane - - - - - - - - - - - - - - - :/files/images/px4/airframes/flying_wing.png:/files/images/px4/airframes/flying_wing.png - - - - 120 - 120 - - - - true - - - - - - - - - - Flying Wing - - - - - - - - - - - - - - - :/files/images/px4/airframes/quad_x.png:/files/images/px4/airframes/quad_x.png - - - - 120 - 120 - - - - true - - - - - - - - - - Quadrotor X - - - - - - - - - - - - - - - :/files/images/px4/airframes/quad_+.png:/files/images/px4/airframes/quad_+.png - - - - 120 - 120 - - - - true - - - - - - - - - - Quadrotor + - - - - - - - - - - - - - - - :/files/images/px4/airframes/hexa_x.png:/files/images/px4/airframes/hexa_x.png - - - - 120 - 120 - - - - true - - - - - - - - - - Hexarotor X - - - - - - - - - - - - - - - :/files/images/px4/airframes/hexa_+.png:/files/images/px4/airframes/hexa_+.png - - - - 120 - 120 - - - - true - - - - - - - - - - Hexarotor + - - - - - - - - - - - - - - - :/files/images/px4/airframes/octo_x.png:/files/images/px4/airframes/octo_x.png - - - - 120 - 120 - - - - true - - - - - - - - - - Octorotor X - - - - - - - - - - - - - - - :/files/images/px4/airframes/octo_+.png:/files/images/px4/airframes/octo_+.png - - - - 120 - 120 - - - - true - - - - - - - - - - Octorotor + - - - - - - - - - - - - - - - :/files/images/px4/airframes/quad_h.png:/files/images/px4/airframes/quad_h.png - - - - 120 - 120 - - - - true - - - - - - - - - - H Frame - - - - - - - - - - - Simulation Setup - - - true - - - - - - - - - - Simulation / Experimental - - - - - - - - - - - - - Apply and Restart - - - - - - - No changes values - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - -