diff --git a/qgcresources.qrc b/qgcresources.qrc
index cc3b28fba4f74d078fdc496b3989fc31b6bc950f..52a88814a471f89efd37d2fcea09f71e680eb33d 100644
--- a/qgcresources.qrc
+++ b/qgcresources.qrc
@@ -208,6 +208,9 @@
src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml
src/AutoPilotPlugins/PX4/ParameterFactMetaData.xml
+
+ src/AutoPilotPlugins/APM/AirframeFactMetaData.xml
+
src/FirmwarePlugin/APM/apm.pdef.xml
diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 4156b72224ad910db1072a6f1274c349e7fafab5..1b793463915ed04127e7d95941b4a54b7f179332 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -282,7 +282,9 @@ HEADERS += \
src/uas/UASMessageHandler.h \
src/ui/toolbar/MainToolBarController.h \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \
+ src/AutoPilotPlugins/APM/APMAirframeLoader.h \
src/QmlControls/QGCImageProvider.h \
+ src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.h
DebugBuild {
HEADERS += \
@@ -398,7 +400,9 @@ SOURCES += \
src/uas/UASMessageHandler.cc \
src/ui/toolbar/MainToolBarController.cc \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \
+ src/AutoPilotPlugins/APM/APMAirframeLoader.cc \
src/QmlControls/QGCImageProvider.cc \
+ src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.cc
DebugBuild {
SOURCES += \
@@ -550,6 +554,8 @@ HEADERS+= \
src/AutoPilotPlugins/AutoPilotPluginManager.h \
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h \
src/AutoPilotPlugins/APM/APMAirframeComponent.h \
+ src/AutoPilotPlugins/APM/APMAirframeComponentController.h \
+ src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.h \
src/AutoPilotPlugins/APM/APMComponent.h \
src/AutoPilotPlugins/APM/APMRadioComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
@@ -601,6 +607,7 @@ SOURCES += \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc \
src/AutoPilotPlugins/APM/APMAirframeComponent.cc \
+ src/AutoPilotPlugins/APM/APMAirframeComponentController.cc \
src/AutoPilotPlugins/APM/APMComponent.cc \
src/AutoPilotPlugins/APM/APMRadioComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
@@ -610,6 +617,7 @@ SOURCES += \
src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \
src/AutoPilotPlugins/APM/APMTuningComponent.cc \
src/AutoPilotPlugins/Common/RadioComponentController.cc \
+ src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \
src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc \
@@ -654,19 +662,21 @@ INCLUDEPATH += \
HEADERS += \
src/FactSystem/Fact.h \
+ src/FactSystem/FactControls/FactPanelController.h \
src/FactSystem/FactMetaData.h \
src/FactSystem/FactSystem.h \
src/FactSystem/FactValidator.h \
src/FactSystem/ParameterLoader.h \
- src/FactSystem/FactControls/FactPanelController.h \
+ src/FactSystem/SettingsFact.h \
SOURCES += \
src/FactSystem/Fact.cc \
+ src/FactSystem/FactControls/FactPanelController.cc \
src/FactSystem/FactMetaData.cc \
src/FactSystem/FactSystem.cc \
src/FactSystem/FactValidator.cc \
src/FactSystem/ParameterLoader.cc \
- src/FactSystem/FactControls/FactPanelController.cc \
+ src/FactSystem/SettingsFact.cc \
#-------------------------------------------------------------------------------------
# Video Streaming
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponent.cc b/src/AutoPilotPlugins/APM/APMAirframeComponent.cc
index 1c90064d80b68d4ed5de33eba714fe236adb82b8..19899f11f903a068faccf89db10feea733f76082 100644
--- a/src/AutoPilotPlugins/APM/APMAirframeComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponent.cc
@@ -57,22 +57,13 @@ bool APMAirframeComponent::requiresSetup(void) const
bool APMAirframeComponent::setupComplete(void) const
{
- // You'll need to figure out which parameters trigger setup complete
-#if 0
- return _autopilot->getParameterFact(FactSystem::defaultComponentId, "SYS_AUTOSTART")->rawValue().toInt() != 0;
-#else
- return true;
-#endif
+ //: Not the correct one, but it works for the moment.
+ return _autopilot->getParameterFact(FactSystem::defaultComponentId, "FRAME")->rawValue().toInt() != -1;
}
QStringList APMAirframeComponent::setupCompleteChangedTriggerList(void) const
{
- // You'll need to figure out which parameters trigger setup complete
-#if 0
- return QStringList("SYS_AUTOSTART");
-#else
return QStringList();
-#endif
}
QUrl APMAirframeComponent::setupSource(void) const
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponent.qml b/src/AutoPilotPlugins/APM/APMAirframeComponent.qml
index e03e3e95084c396b4a52459cacec680d7616463c..1a6551e51caca5f8a8358407a8fda8b5827c5094 100644
--- a/src/AutoPilotPlugins/APM/APMAirframeComponent.qml
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponent.qml
@@ -21,7 +21,7 @@
======================================================================*/
-import QtQuick 2.2
+import QtQuick 2.5
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2
@@ -39,13 +39,214 @@ QGCView {
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }
+ property real _minW: ScreenTools.defaultFontPixelWidth * 30
+ property real _boxWidth: _minW
+ property real _boxSpace: ScreenTools.defaultFontPixelWidth
+ property Fact sysIdFact: controller.getParameterFact(-1, "FRAME")
+
+ function computeDimensions() {
+ var sw = 0
+ var rw = 0
+ var idx = Math.floor(scroll.width / (_minW + ScreenTools.defaultFontPixelWidth))
+ if(idx < 1) {
+ _boxWidth = scroll.width
+ _boxSpace = 0
+ } else {
+ _boxSpace = 0
+ if(idx > 1) {
+ _boxSpace = ScreenTools.defaultFontPixelWidth
+ sw = _boxSpace * (idx - 1)
+ }
+ rw = scroll.width - sw
+ _boxWidth = rw / idx
+ }
+ }
+
+ APMAirframeComponentController {
+ id: controller
+ factPanel: panel
+ }
+
+ Component {
+ id: applyRestartDialogComponent
+
+ QGCViewDialog {
+ id: applyRestartDialog
+
+ Connections {
+ target: controller
+ onCurrentAirframeTypeChanged: {
+ airframePicker.model = controller.currentAirframeType.airframes;
+ }
+ onCurrentAirframeChanged : {
+ hideDialog();
+ }
+ }
+
+ QGCLabel {
+ id: applyParamsText
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: _boxSpace
+ wrapMode: Text.WordWrap
+ text: "Select you drone to load the default parameters for it. "
+ }
+
+ Flow {
+ anchors.top : applyParamsText.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ spacing : _boxSpace
+ layoutDirection: Qt.Vertical;
+ anchors.margins : _boxSpace
+ Repeater {
+ id : airframePicker
+ model : controller.currentAirframeType.airframes;
+
+ delegate: QGCButton {
+ id: btnParams
+ width: parent.width / 2.1
+ height: (ScreenTools.defaultFontPixelHeight * 14) / 5
+ text: controller.currentAirframeType.airframes[index].name;
+
+ onClicked : {
+ controller.currentAirframe = controller.currentAirframeType.airframes[index]
+ }
+ }
+ }
+ }
+ }
+ }
+
QGCViewPanel {
id: panel
anchors.fill: parent
- QGCLabel {
- text: "Work in progress";
+ readonly property real spacerHeight: ScreenTools.defaultFontPixelHeight
+
+ onWidthChanged: {
+ computeDimensions()
+ }
+
+ Item {
+ id: helpApplyRow
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: Math.max(helpText.contentHeight, applyButton.height)
+
+ QGCLabel {
+ id: helpText
+ width: parent.width - applyButton.width - 5
+ text: qsTr("Please select your airframe type")
+ font.pixelSize: ScreenTools.mediumFontPixelSize
+ wrapMode: Text.WordWrap
+ }
+
+ QGCButton {
+ id: applyButton
+ anchors.right: parent.right
+ text: qsTr("Load common parameters")
+
+ onClicked: showDialog(applyRestartDialogComponent, qsTr("Load common parameters"), 50, StandardButton.Close)
+ }
+ }
+
+ Item {
+ id: lastSpacer
+ anchors.top: helpApplyRow.bottom
+ height: parent.spacerHeight
+ width: 10
}
+ Flickable {
+ id: scroll
+ anchors.top: lastSpacer.bottom
+ width: parent.width;
+ height: parent.height;
+ clip: true
+ boundsBehavior: Flickable.StopAtBounds
+ flickableDirection: Flickable.VerticalFlick
+
+ onWidthChanged: {
+ computeDimensions()
+ }
+
+ Flow {
+ id: flowView
+ width: scroll.width
+ spacing: _boxSpace
+
+ ExclusiveGroup {
+ id: airframeTypeExclusive
+ }
+
+ Repeater {
+ model: controller.airframeTypesModel
+
+ // Outer summary item rectangle
+ delegate : Rectangle {
+ id: airframeBackground
+ width: _boxWidth
+ height: ScreenTools.defaultFontPixelHeight * 14
+ color: qgcPal.windowShade;
+
+ readonly property real titleHeight: ScreenTools.defaultFontPixelHeight * 1.75
+ readonly property real innerMargin: ScreenTools.defaultFontPixelWidth
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: airframeCheckBox.checked = true;
+ }
+
+ Rectangle {
+ id: nameRect;
+ width: parent.width
+ height: parent.titleHeight
+ color: qgcPal.windowShadeDark
+
+ QGCLabel {
+ anchors.fill: parent
+ color: qgcPal.buttonText
+ verticalAlignment: TextEdit.AlignVCenter
+ horizontalAlignment: TextEdit.AlignHCenter
+ text: object.name
+ }
+ }
+
+ Image {
+ id: imageRect
+ anchors.topMargin: innerMargin
+ anchors.top: nameRect.bottom
+ width: parent.width * 0.75
+ height: parent.height - nameRect.height - (innerMargin * 3)
+ fillMode: Image.PreserveAspectFit
+ smooth: true
+ mipmap: true
+ source: object.imageResource
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ QGCCheckBox {
+ id: airframeCheckBox
+ checked: object.type == sysIdFact.value
+ exclusiveGroup: airframeTypeExclusive
+ anchors.bottom: imageRect.bottom
+ anchors.right: parent.right
+ anchors.rightMargin: innerMargin
+
+ onCheckedChanged: {
+ if (checked) {
+ controller.currentAirframeType = object
+ }
+ airframeBackground.color = checked ? qgcPal.buttonHighlight : qgcPal.windowShade;
+ }
+ }
+ }
+ }
+ }
+ } // Scroll View - summary boxes
} // QGCViewPanel
} // QGCView
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.cc b/src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ca356f2fc60427557a726918a2ba3063597433ea
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.cc
@@ -0,0 +1,60 @@
+/*=====================================================================
+
+ 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 "APMAirframeComponentAirframes.h"
+#include "APMAirframeComponentController.h"
+
+QMap APMAirframeComponentAirframes::rgAirframeTypes;
+
+QMap& APMAirframeComponentAirframes::get() {
+ return rgAirframeTypes;
+}
+
+void APMAirframeComponentAirframes::insert(const QString& group, int groupId, const QString& image,const QString& name, const QString& file)
+{
+ AirframeType_t *g;
+ if (!rgAirframeTypes.contains(group)) {
+ g = new AirframeType_t;
+ g->name = group;
+ g->type = groupId;
+ g->imageResource = QString("qrc:/qmlimages/") + (!image.isEmpty() ? image : QString("AirframeStandardPlane.png"));
+ rgAirframeTypes.insert(group, g);
+ } else {
+ g = rgAirframeTypes.value(group);
+ }
+
+ if (!name.isEmpty() && !file.isEmpty())
+ g->rgAirframeInfo.append(new APMAirframe(name, file, g->type));
+}
+
+void APMAirframeComponentAirframes::clear() {
+ QList valueList = get().values();
+ foreach(AirframeType_t *pType, valueList) {
+ qDeleteAll(pType->rgAirframeInfo);
+ delete pType;
+ }
+ rgAirframeTypes.clear();
+}
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.h b/src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d33de2e20211500b2aa6d1b591c47fb6cfdb07d
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.h
@@ -0,0 +1,62 @@
+/*=====================================================================
+
+ 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 APMAirframeComponentAirframes_H
+#define APMAirframeComponentAirframes_H
+
+#include
+#include
+#include
+#include
+
+#include "UASInterface.h"
+#include "AutoPilotPlugin.h"
+
+class APMAirframe;
+
+/// MVC Controller for AirframeComponent.qml.
+class APMAirframeComponentAirframes
+{
+public:
+ typedef struct {
+ QString name;
+ QString imageResource;
+ int type;
+ QList rgAirframeInfo;
+ } AirframeType_t;
+ typedef QMap AirframeTypeMap;
+
+ static AirframeTypeMap& get();
+ static void clear();
+ static void insert(const QString& group, int groupId, const QString& image,const QString& name = QString(), const QString& file = QString());
+
+protected:
+ static AirframeTypeMap rgAirframeTypes;
+
+private:
+};
+
+#endif
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponentController.cc b/src/AutoPilotPlugins/APM/APMAirframeComponentController.cc
new file mode 100644
index 0000000000000000000000000000000000000000..26ff996dc7c841383e086884b41ec8fb87bb04cf
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponentController.cc
@@ -0,0 +1,208 @@
+/*=====================================================================
+
+ 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 "APMAirframeComponentController.h"
+#include "APMAirframeComponentAirframes.h"
+#include "APMRemoteParamsDownloader.h"
+#include "QGCMAVLink.h"
+#include "MultiVehicleManager.h"
+#include "AutoPilotPluginManager.h"
+#include "QGCApplication.h"
+
+#include
+#include
+
+bool APMAirframeComponentController::_typesRegistered = false;
+
+APMAirframeComponentController::APMAirframeComponentController(void) :
+ _airframeTypesModel(new QmlObjectListModel(this))
+{
+ if (!_typesRegistered) {
+ _typesRegistered = true;
+ qmlRegisterUncreatableType("QGroundControl.Controllers", 1, 0, "APMAiframeType", "Can only reference APMAirframeType");
+ qmlRegisterUncreatableType("QGroundControl.Controllers", 1, 0, "APMAiframe", "Can only reference APMAirframe");
+ }
+ _fillAirFrames();
+
+ Fact *frame = getParameterFact(FactSystem::defaultComponentId, "FRAME");
+ connect(frame, &Fact::vehicleUpdated, this, &APMAirframeComponentController::_factFrameChanged);
+ _factFrameChanged(frame->rawValue());
+}
+
+APMAirframeComponentController::~APMAirframeComponentController()
+{
+
+}
+
+void APMAirframeComponentController::_factFrameChanged(QVariant value)
+{
+ FrameId v = (FrameId) value.toInt();
+
+ for(int i = 0, size = _airframeTypesModel->count(); i < size; i++ ) {
+ APMAirframeType *airframeType = qobject_cast(_airframeTypesModel->get(i));
+ Q_ASSERT(airframeType);
+ if (airframeType->type() == v) {
+ _currentAirframeType = airframeType;
+ break;
+ }
+ }
+ emit currentAirframeTypeChanged(_currentAirframeType);
+}
+
+void APMAirframeComponentController::_fillAirFrames()
+{
+ for (int tindex = 0; tindex < APMAirframeComponentAirframes::get().count(); tindex++) {
+ const APMAirframeComponentAirframes::AirframeType_t* pType = APMAirframeComponentAirframes::get().values().at(tindex);
+
+ APMAirframeType* airframeType = new APMAirframeType(pType->name, pType->imageResource, pType->type, this);
+ Q_CHECK_PTR(airframeType);
+
+ for (int index = 0; index < pType->rgAirframeInfo.count(); index++) {
+ const APMAirframe* pInfo = pType->rgAirframeInfo.at(index);
+ Q_CHECK_PTR(pInfo);
+
+ airframeType->addAirframe(pInfo->name(), pInfo->params(), pInfo->type());
+ }
+ _airframeTypesModel->append(airframeType);
+ }
+
+ emit loadAirframesCompleted();
+}
+
+void APMAirframeComponentController::_finishVehicleSetup() {
+ QDir dataLocation = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0)
+ + QDir::separator() + qApp->applicationName();
+
+ QFile parametersFile(dataLocation.absoluteFilePath(_currentAirframe->params()));
+ parametersFile.open(QIODevice::ReadOnly);
+
+ QTextStream reader(¶metersFile);
+
+ while (!reader.atEnd()) {
+ QString line = reader.readLine().trimmed();
+ if (line.isEmpty() || line.at(0) == QChar('#')) {
+ continue;
+ }
+
+ QStringList aux = line.split(',');
+ if (parameterExists(-1, aux.at(0))) {
+ Fact *param = getParameterFact(-1, aux.at(0));
+ param->setRawValue(QVariant::fromValue(aux.at(1)));
+ }
+ }
+ qgcApp()->setOverrideCursor(Qt::ArrowCursor);
+ sender()->deleteLater();
+ emit currentAirframeChanged(_currentAirframe);
+}
+
+APMAirframeType::APMAirframeType(const QString& name, const QString& imageResource, int type, QObject* parent) :
+ QObject(parent),
+ _name(name),
+ _imageResource(imageResource),
+ _type(type),
+ _dirty(false)
+{
+}
+
+APMAirframeType::~APMAirframeType()
+{
+}
+
+void APMAirframeType::addAirframe(const QString& name, const QString& file, int type)
+{
+ APMAirframe* airframe = new APMAirframe(name, file, type);
+ Q_CHECK_PTR(airframe);
+
+ _airframes.append(QVariant::fromValue(airframe));
+}
+
+APMAirframe::APMAirframe(const QString& name, const QString& paramsFile, int type, QObject* parent) :
+ QObject(parent),
+ _name(name),
+ _paramsFile(paramsFile),
+ _type(type)
+{
+}
+
+QString APMAirframe::name() const
+{
+ return _name;
+}
+
+QString APMAirframe::params() const
+{
+ return _paramsFile;
+}
+
+int APMAirframe::type() const
+{
+ return _type;
+}
+
+APMAirframe::~APMAirframe()
+{
+}
+
+QString APMAirframeType::imageResource() const
+{
+ return _imageResource;
+}
+
+QString APMAirframeType::name() const
+{
+ return _name;
+}
+
+int APMAirframeType::type() const
+{
+ return _type;
+}
+
+APMAirframeType *APMAirframeComponentController::currentAirframeType() const
+{
+ return _currentAirframeType;
+}
+
+APMAirframe *APMAirframeComponentController::currentAirframe() const
+{
+ return _currentAirframe;
+}
+
+void APMAirframeComponentController::setCurrentAirframe(APMAirframe *t)
+{
+ _currentAirframe = t;
+ qgcApp()->setOverrideCursor(Qt::WaitCursor);
+ APMRemoteParamsDownloader *paramDownloader = new APMRemoteParamsDownloader(_currentAirframe->params());
+ connect(paramDownloader, &APMRemoteParamsDownloader::finished, this, &APMAirframeComponentController::_finishVehicleSetup);
+}
+
+void APMAirframeComponentController::setCurrentAirframeType(APMAirframeType *t)
+{
+ Fact *param = getParameterFact(-1, "FRAME");
+ Q_ASSERT(param);
+ param->setRawValue(t->type());
+}
+
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponentController.h b/src/AutoPilotPlugins/APM/APMAirframeComponentController.h
new file mode 100644
index 0000000000000000000000000000000000000000..ef799ab5246960d144e73658ebb296ca5ddc5e6b
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponentController.h
@@ -0,0 +1,138 @@
+/*=====================================================================
+
+ 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 APMAirframeComponentController_H
+#define APMAirframeComponentController_H
+
+#include
+#include
+#include
+#include
+
+#include "UASInterface.h"
+#include "AutoPilotPlugin.h"
+#include "FactPanelController.h"
+#include "APMAirframeComponentAirframes.h"
+
+class APMAirframeModel;
+class APMAirframeType;
+
+/// MVC Controller for APMAirframeComponent.qml.
+class APMAirframeComponentController : public FactPanelController
+{
+ Q_OBJECT
+
+public:
+ enum FrameId{FRAME_TYPE_PLUS = 0,
+ FRAME_TYPE_X = 1,
+ FRAME_TYPE_V = 2,
+ FRAME_TYPE_H = 3,
+ FRAME_TYPE_NEWY6 = 10};
+ Q_ENUM(FrameId)
+
+ APMAirframeComponentController(void);
+ ~APMAirframeComponentController();
+
+ Q_PROPERTY(QmlObjectListModel* airframeTypesModel MEMBER _airframeTypesModel CONSTANT)
+ Q_PROPERTY(APMAirframeType* currentAirframeType READ currentAirframeType WRITE setCurrentAirframeType NOTIFY currentAirframeTypeChanged)
+ Q_PROPERTY(APMAirframe* currentAirframe READ currentAirframe WRITE setCurrentAirframe NOTIFY currentAirframeChanged)
+
+ int currentAirframeIndex(void);
+ void setCurrentAirframeIndex(int newIndex);
+
+signals:
+ void loadAirframesCompleted();
+ void currentAirframeTypeChanged(APMAirframeType* airframeType);
+ void currentAirframeChanged(APMAirframe* airframe);
+
+public slots:
+ APMAirframeType *currentAirframeType() const;
+ APMAirframe *currentAirframe() const;
+ void setCurrentAirframeType(APMAirframeType *t);
+ void setCurrentAirframe(APMAirframe *t);
+
+private slots:
+ void _fillAirFrames(void);
+ void _finishVehicleSetup(void);
+ void _factFrameChanged(QVariant v);
+
+private:
+ static bool _typesRegistered;
+ APMAirframeType *_currentAirframeType;
+ APMAirframe *_currentAirframe;
+ int _waitParamWriteSignalCount;
+ QmlObjectListModel *_airframeTypesModel;
+};
+
+class APMAirframe : public QObject
+{
+ Q_OBJECT
+
+public:
+ APMAirframe(const QString& name, const QString& paramsFile, int type, QObject* parent = NULL);
+ ~APMAirframe();
+
+ Q_PROPERTY(QString name MEMBER _name CONSTANT)
+ Q_PROPERTY(int type MEMBER _type CONSTANT)
+ Q_PROPERTY(QString params MEMBER _paramsFile CONSTANT)
+
+ QString name() const;
+ QString params() const;
+ int type() const;
+
+private:
+ QString _name;
+ QString _paramsFile;
+ int _type;
+};
+
+class APMAirframeType : public QObject
+{
+ Q_OBJECT
+
+public:
+ APMAirframeType(const QString& name, const QString& imageResource, int type, QObject* parent = NULL);
+ ~APMAirframeType();
+
+ Q_PROPERTY(QString name MEMBER _name CONSTANT)
+ Q_PROPERTY(QString imageResource MEMBER _imageResource CONSTANT)
+ Q_PROPERTY(QVariantList airframes MEMBER _airframes CONSTANT)
+ Q_PROPERTY(int type MEMBER _type CONSTANT)
+ Q_PROPERTY(bool dirty MEMBER _dirty CONSTANT)
+ void addAirframe(const QString& name, const QString& paramsFile, int type);
+
+ QString name() const;
+ QString imageResource() const;
+ int type() const;
+private:
+ QString _name;
+ QString _imageResource;
+ QVariantList _airframes;
+ int _type;
+ bool _dirty;
+};
+
+#endif
diff --git a/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml b/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml
index 975a6f8254bd010dddd228e40db2a3cc306d7a9c..3e697b1b1ba96cb498628e0c380fd21fbdc8d72e 100644
--- a/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml
+++ b/src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml
@@ -13,33 +13,27 @@ FactPanel {
color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
+ APMAirframeComponentController {
+ id: controller
+ factPanel: panel
+ }
-/*
- property Fact sysIdFact: controller.getParameterFact(-1, "MAV_SYS_ID")
- property Fact sysAutoStartFact: controller.getParameterFact(-1, "SYS_AUTOSTART")
+ property Fact sysIdFact: controller.getParameterFact(-1, "FRAME")
- property bool autoStartSet: sysAutoStartFact.value != 0
-*/
Column {
anchors.fill: parent
anchors.margins: 8
-/*
- VehicleSummaryRow {
- labelText: "System ID:"
- valueText: sysIdFact.valueString
- }
-
VehicleSummaryRow {
- labelText: "Airframe type:"
- valueText: autoStartSet ? controller.currentAirframeType : "Setup required"
- }
+ id: nameRow;
+ labelText: "Frame Type:"
+ valueText: sysIdFact.valueString === "0" ? "Plus"
+ : sysIdFact.valueString === "1" ? "X"
+ : sysIdFact.valueString === "2" ? "V"
+ : sysIdFact.valueString == "3" ? "H"
+ :/* Fact.value == 10 */ "New Y6";
- VehicleSummaryRow {
- labelText: "Vehicle:"
- valueText: autoStartSet ? controller.currentVehicleName : "Setup required"
}
-*/
}
}
diff --git a/src/AutoPilotPlugins/APM/APMAirframeLoader.cc b/src/AutoPilotPlugins/APM/APMAirframeLoader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1a189ebd2002ebf4161e1883c1c0ab30c525dc87
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMAirframeLoader.cc
@@ -0,0 +1,100 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 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 "APMAirframeLoader.h"
+#include "QGCApplication.h"
+#include "QGCLoggingCategory.h"
+#include "APMAirframeComponentAirframes.h"
+
+#include
+#include
+#include
+#include
+
+QGC_LOGGING_CATEGORY(APMAirframeLoaderLog, "APMAirframeLoaderLog")
+
+bool APMAirframeLoader::_airframeMetaDataLoaded = false;
+
+APMAirframeLoader::APMAirframeLoader(AutoPilotPlugin* autopilot, UASInterface* uas, QObject* parent)
+{
+ Q_UNUSED(autopilot);
+ Q_UNUSED(uas);
+ Q_UNUSED(parent);
+ Q_ASSERT(uas);
+}
+
+/// Load Airframe Fact meta data
+void APMAirframeLoader::loadAirframeFactMetaData(void)
+{
+ if (_airframeMetaDataLoaded) {
+ return;
+ }
+
+ qCDebug(APMAirframeLoaderLog) << "Loading APM airframe fact meta data";
+
+ Q_ASSERT(APMAirframeComponentAirframes::get().count() == 0);
+
+ QString airframeFilename = ":/AutoPilotPlugins/APM/AirframeFactMetaData.xml";
+
+ qCDebug(APMAirframeLoaderLog) << "Loading meta data file:" << airframeFilename;
+
+ QFile xmlFile(airframeFilename);
+ Q_ASSERT(xmlFile.exists());
+
+ bool success = xmlFile.open(QIODevice::ReadOnly);
+ Q_UNUSED(success);
+ Q_ASSERT(success);
+
+ QXmlStreamReader xml(xmlFile.readAll());
+ xmlFile.close();
+ if (xml.hasError()) {
+ qCWarning(APMAirframeLoaderLog) << "Badly formed XML" << xml.errorString();
+ return;
+ }
+
+ QString airframeGroup;
+ QString image;
+ int groupId = 0;
+ while (!xml.atEnd()) {
+ if (xml.isStartElement()) {
+ QString elementName = xml.name().toString();
+ QXmlStreamAttributes attr = xml.attributes();
+ if (elementName == "airframe_group") {
+ airframeGroup = attr.value("name").toString();
+ image = attr.value("image").toString();
+ groupId = attr.value("id").toInt();
+ APMAirframeComponentAirframes::insert(airframeGroup, groupId, image);
+ } else if (elementName == "airframe") {
+ QString name = attr.value("name").toString();
+ QString file = attr.value("file").toString();
+ APMAirframeComponentAirframes::insert(airframeGroup, groupId, image, name, file);
+ }
+ }
+ xml.readNext();
+ }
+
+ _airframeMetaDataLoaded = true;
+}
diff --git a/src/AutoPilotPlugins/APM/APMAirframeLoader.h b/src/AutoPilotPlugins/APM/APMAirframeLoader.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d8d4e6dac9132a217688ab039b7740b4d755664
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMAirframeLoader.h
@@ -0,0 +1,59 @@
+/*=====================================================================
+
+ 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 .
+
+ ======================================================================*/
+
+#ifndef APMAirframeLoader_H
+#define APMAirframeLoader_H
+
+#include
+#include
+#include
+#include
+
+#include "ParameterLoader.h"
+#include "FactSystem.h"
+#include "UASInterface.h"
+#include "AutoPilotPlugin.h"
+
+/// @file APMAirframeLoader.h
+/// @author Lorenz Meier
+
+Q_DECLARE_LOGGING_CATEGORY(APMAirframeLoaderLog)
+
+/// Collection of Parameter Facts for PX4 AutoPilot
+
+class APMAirframeLoader : QObject
+{
+ Q_OBJECT
+
+public:
+ /// @param uas Uas which this set of facts is associated with
+ APMAirframeLoader(AutoPilotPlugin* autpilot,UASInterface* uas, QObject* parent = NULL);
+
+ static void loadAirframeFactMetaData(void);
+
+private:
+ static bool _airframeMetaDataLoaded; ///< true: parameter meta data already loaded
+ static QMap _mapParameterName2FactMetaData; ///< Maps from a parameter name to FactMetaData
+};
+
+#endif // APMAirframeLoader_H
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
index b04d522c8c70cef108206b79007768a33921dc84..d8254a3f0790f724518cfc8ae1b392e3e3882a04 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
@@ -1,24 +1,24 @@
/*=====================================================================
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 .
-
+
======================================================================*/
#include "APMAutoPilotPlugin.h"
@@ -26,6 +26,18 @@
#include "UAS.h"
#include "FirmwarePlugin/APM/APMParameterMetaData.h" // FIXME: Hack
#include "FirmwarePlugin/APM/APMFirmwarePlugin.h" // FIXME: Hack
+#include "FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h"
+#include "APMComponent.h"
+#include "APMAirframeComponent.h"
+#include "APMAirframeComponentAirframes.h"
+#include "APMAirframeComponentController.h"
+#include "APMAirframeLoader.h"
+#include "APMRemoteParamsDownloader.h"
+#include "APMFlightModesComponent.h"
+#include "APMRadioComponent.h"
+#include "APMSafetyComponent.h"
+#include "APMTuningComponent.h"
+#include "APMSensorsComponent.h"
/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
@@ -37,8 +49,9 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
, _safetyComponent(NULL)
, _sensorsComponent(NULL)
, _tuningComponent(NULL)
+ , _airframeFacts(new APMAirframeLoader(this, vehicle->uas(), this))
{
- Q_ASSERT(vehicle);
+ APMAirframeLoader::loadAirframeFactMetaData();
}
APMAutoPilotPlugin::~APMAutoPilotPlugin()
@@ -52,12 +65,14 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
Q_ASSERT(_vehicle);
if (parametersReady()) {
- _airframeComponent = new APMAirframeComponent(_vehicle, this);
- if (_airframeComponent) {
- _airframeComponent->setupTriggerSignals();
- _components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
- } else {
- qWarning() << "new APMAirframeComponent failed";
+ if (dynamic_cast(_vehicle->firmwarePlugin())){
+ _airframeComponent = new APMAirframeComponent(_vehicle, this);
+ if(_airframeComponent) {
+ _airframeComponent->setupTriggerSignals();
+ _components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
+ } else {
+ qWarning() << "new APMAirframeComponent failed";
+ }
}
_flightModesComponent = new APMFlightModesComponent(_vehicle, this);
@@ -122,9 +137,9 @@ void APMAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters)
"Please perform a Firmware Upgrade if you wish to use Vehicle Setup.");
}
#endif
-
+ Q_UNUSED(missingParameters);
_parametersReady = true;
- _missingParameters = missingParameters;
+ _missingParameters = false; // we apply only the parameters that do exists on the FactSystem.
emit missingParametersChanged(_missingParameters);
emit parametersReadyChanged(_parametersReady);
}
diff --git a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
index c26dee7c07cd816a5774993be547bec8f7363ad5..1102cf1e77fb9f2e7b9f60c9eae75e61d668b17b 100644
--- a/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
+++ b/src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
@@ -26,12 +26,14 @@
#include "AutoPilotPlugin.h"
#include "Vehicle.h"
-#include "APMAirframeComponent.h"
-#include "APMFlightModesComponent.h"
-#include "APMRadioComponent.h"
-#include "APMSafetyComponent.h"
-#include "APMSensorsComponent.h"
-#include "APMTuningComponent.h"
+
+class APMAirframeComponent;
+class APMAirframeLoader;
+class APMFlightModesComponent;
+class APMRadioComponent;
+class APMTuningComponent;
+class APMSafetyComponent;
+class APMSensorsComponent;
/// This is the APM specific implementation of the AutoPilot class.
class APMAutoPilotPlugin : public AutoPilotPlugin
@@ -66,6 +68,7 @@ private:
APMSafetyComponent* _safetyComponent;
APMSensorsComponent* _sensorsComponent;
APMTuningComponent* _tuningComponent;
+ APMAirframeLoader* _airframeFacts;
};
#endif
diff --git a/src/AutoPilotPlugins/APM/APMComponent.cc b/src/AutoPilotPlugins/APM/APMComponent.cc
index ec3cbf9b6e91fe989b8c5c8fb445cd5698274479..e5b745b31c61477d3b33825a1ae1069f22f97f84 100644
--- a/src/AutoPilotPlugins/APM/APMComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMComponent.cc
@@ -37,10 +37,8 @@ APMComponent::APMComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject
void APMComponent::setupTriggerSignals(void)
{
- // Watch for changed on trigger list params
- foreach (QString paramName, setupCompleteChangedTriggerList()) {
+ foreach (const QString& paramName, setupCompleteChangedTriggerList()) {
Fact* fact = _autopilot->getParameterFact(FactSystem::defaultComponentId, paramName);
-
connect(fact, &Fact::valueChanged, this, &APMComponent::_triggerUpdated);
}
}
diff --git a/src/AutoPilotPlugins/APM/APMFlightModesComponent.cc b/src/AutoPilotPlugins/APM/APMFlightModesComponent.cc
index 77456548006c472c8bd2b01852c89527d346b81c..80b9baa6d86c44e269df27999a8ce5f184f48088 100644
--- a/src/AutoPilotPlugins/APM/APMFlightModesComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMFlightModesComponent.cc
@@ -23,6 +23,8 @@
#include "APMFlightModesComponent.h"
#include "APMAutoPilotPlugin.h"
+#include "APMAirframeComponent.h"
+#include "APMRadioComponent.h"
APMFlightModesComponent::APMFlightModesComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
APMComponent(vehicle, autopilot, parent),
diff --git a/src/AutoPilotPlugins/APM/APMRadioComponent.cc b/src/AutoPilotPlugins/APM/APMRadioComponent.cc
index c42a1d553b99be47d23e2660385e50ce96caf89a..5cbed197ae29d864427d7f3eaf67548546ef56f1 100644
--- a/src/AutoPilotPlugins/APM/APMRadioComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMRadioComponent.cc
@@ -23,6 +23,7 @@
#include "APMRadioComponent.h"
#include "APMAutoPilotPlugin.h"
+#include "APMAirframeComponent.h"
APMRadioComponent::APMRadioComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
APMComponent(vehicle, autopilot, parent),
diff --git a/src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.cc b/src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8b4834dbc4b3b1d909973b21020e6d2cf3df6a31
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.cc
@@ -0,0 +1,181 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 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 .
+
+ ======================================================================*/
+
+#include "APMRemoteParamsDownloader.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "APMRemoteParamsDownloader.h"
+
+#define FRAME_PARAMS_LIST QUrl("https://api.github.com/repos/diydrones/ardupilot/contents/Tools/Frame_params")
+#define FRAME_PARAMS_URL "https://raw.github.com/diydrones/ardupilot/master/Tools/Frame_params/"
+
+static QString dataLocation;
+
+APMRemoteParamsDownloader::APMRemoteParamsDownloader(const QString& file) :
+ m_fileToDownload(file),
+ m_networkReply(NULL),
+ m_downloadedParamFile(NULL)
+{
+ dataLocation = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(0)
+ + QDir::separator() + qApp->applicationName();
+ refreshParamList();
+}
+
+QString APMRemoteParamsDownloader::statusText() const
+{
+ return m_statusText;
+}
+void APMRemoteParamsDownloader::setStatusText(const QString& text)
+{
+ m_statusText = text;
+}
+
+void APMRemoteParamsDownloader::refreshParamList()
+{
+ setStatusText(tr("Refresh Param file list"));
+
+ QUrl url = FRAME_PARAMS_LIST;
+ m_networkReply->deleteLater();
+ m_networkReply = m_networkAccessManager.get(QNetworkRequest(url));
+ connect(m_networkReply, SIGNAL(finished()), this, SLOT(httpParamListFinished()));
+ connect(m_networkReply, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(updateDataReadProgress(qint64,qint64)));
+}
+
+/* Returned Json Example
+ "_links": {
+ "git":"https://api.github.com/repos/diydrones/ardupilot/git/blobs/a7074e606d695566f9a8c87724ad52e5e3baba7d",
+ "html":"https://github.com/diydrones/ardupilot/blob/master/Tools/Frame_params/Parrot_Bebop.param",
+ "self":"https://api.github.com/repos/diydrones/ardupilot/contents/Tools/Frame_params/Parrot_Bebop.param?ref=master"
+ },
+ "download_url":"https://raw.githubusercontent.com/diydrones/ardupilot/master/Tools/Frame_params/Parrot_Bebop.param",
+ "git_url":"https://api.github.com/repos/diydrones/ardupilot/git/blobs/a7074e606d695566f9a8c87724ad52e5e3baba7d",
+ "html_url":"https://github.com/diydrones/ardupilot/blob/master/Tools/Frame_params/Parrot_Bebop.param",
+ "name":"Parrot_Bebop.param","path":"Tools/Frame_params/Parrot_Bebop.param",""
+ "sha":"a7074e606d695566f9a8c87724ad52e5e3baba7d",
+ "size":533,
+ "type":"file",
+ "url":"https://api.github.com/repos/diydrones/ardupilot/contents/Tools/Frame_params/Parrot_Bebop.param?ref=master"
+*/
+void APMRemoteParamsDownloader::startFileDownloadRequest()
+{
+ QUrl url;
+
+ QJsonObject obj;
+
+ // Find the correct file from the json file list.
+ while(curr != end) {
+ obj = (*curr).toObject();
+ url = QUrl(obj["download_url"].toString());
+ QString name = obj["name"].toString();
+ if (name == m_fileToDownload) {
+ break;
+ }
+ curr++;
+ }
+ if (curr == end)
+ return;
+
+ QDir parameterDir(dataLocation);
+ if (!parameterDir.exists())
+ parameterDir.mkpath(dataLocation);
+
+ QString filename = parameterDir.absoluteFilePath(obj["name"].toString());
+
+ if(m_downloadedParamFile)
+ m_downloadedParamFile->deleteLater();
+ m_downloadedParamFile = new QFile(filename);
+ m_downloadedParamFile->open(QIODevice::WriteOnly);
+
+ m_networkReply = m_networkAccessManager.get(QNetworkRequest(url));
+ connect(m_networkReply, SIGNAL(finished()), this, SLOT(httpFinished()));
+ connect(m_networkReply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
+ connect(m_networkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64)));
+ curr++;
+}
+
+void APMRemoteParamsDownloader::httpFinished()
+{
+ m_downloadedParamFile->flush();
+ m_downloadedParamFile->close();
+
+ if (m_networkReply->error()) {
+ m_downloadedParamFile->remove();
+ setStatusText(tr("Download failed: %1.").arg(m_networkReply->errorString()));
+ }
+
+ m_networkReply->deleteLater();
+ m_networkReply = NULL;
+ delete m_downloadedParamFile;
+ m_downloadedParamFile = NULL;
+
+ emit finished();
+}
+
+void APMRemoteParamsDownloader::httpReadyRead()
+{
+ if (m_downloadedParamFile)
+ m_downloadedParamFile->write(m_networkReply->readAll());
+}
+
+void APMRemoteParamsDownloader::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
+{
+ Q_UNUSED(bytesRead);
+ Q_UNUSED(totalBytes);
+}
+
+void APMRemoteParamsDownloader::httpParamListFinished()
+{
+ if (m_networkReply->error()) {
+ qDebug() << "Download failed:" << m_networkReply->errorString();
+ return;
+ }
+ processDownloadedVersionObject(m_networkReply->readAll());
+ startFileDownloadRequest();
+}
+
+void APMRemoteParamsDownloader::processDownloadedVersionObject(const QByteArray &listObject)
+{
+ QJsonParseError jsonErrorChecker;
+ QJsonDocument jsonDocument = QJsonDocument::fromJson(listObject, &jsonErrorChecker);
+ if (jsonErrorChecker.error != QJsonParseError::NoError) {
+ qDebug() << "Json error while parsing document:" << jsonErrorChecker.errorString();
+ return;
+ }
+
+ m_documentArray = jsonDocument.array();
+ curr = m_documentArray.constBegin();
+ end = m_documentArray.constEnd();
+}
diff --git a/src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.h b/src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.h
new file mode 100644
index 0000000000000000000000000000000000000000..b635cc77e4ab743f2f448d64267a81c0aa64e7d8
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.h
@@ -0,0 +1,47 @@
+#ifndef APMREMOTEPARAMSCONTROLLER_H
+#define APMREMOTEPARAMSCONTROLLER_H
+
+#include
+#include
+#include
+#include
+
+class QNetworkReply;
+class QFile;
+class QUrl;
+
+class APMRemoteParamsDownloader : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString statusText READ statusText)
+public:
+ explicit APMRemoteParamsDownloader(const QString& file);
+ QString statusText() const;
+public slots:
+ void refreshParamList();
+ void httpParamListFinished();
+ void httpFinished();
+ void httpReadyRead();
+ void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes);
+private:
+ void setStatusText(const QString& text);
+ void startFileDownloadRequest();
+ void manualListSetup();
+ void processDownloadedVersionObject(const QByteArray& listObject);
+ void startDownloadingRemoteParams();
+signals:
+ void finished();
+private:
+ QString m_fileToDownload;
+ QString m_statusText;
+ QNetworkAccessManager m_networkAccessManager;
+ QNetworkReply* m_networkReply;
+ QFile* m_downloadedParamFile;
+
+ // the list of needed documents.
+ QJsonArray m_documentArray;
+ QJsonArray::const_iterator curr;
+ QJsonArray::const_iterator end;
+};
+
+#endif // APMREMOTEPARAMSCONTROLLER_H
diff --git a/src/AutoPilotPlugins/APM/APMSafetyComponent.cc b/src/AutoPilotPlugins/APM/APMSafetyComponent.cc
index 1346fa6e138172913a12da3d9a8ec09e8b29079a..805c02c24af88ba74df3b4ff28fe2e4874a3e3dc 100644
--- a/src/AutoPilotPlugins/APM/APMSafetyComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMSafetyComponent.cc
@@ -27,6 +27,7 @@
#include "APMSafetyComponent.h"
#include "QGCQmlWidgetHolder.h"
#include "APMAutoPilotPlugin.h"
+#include "APMAirframeComponent.h"
APMSafetyComponent::APMSafetyComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
: APMComponent(vehicle, autopilot, parent)
diff --git a/src/AutoPilotPlugins/APM/APMSensorsComponent.cc b/src/AutoPilotPlugins/APM/APMSensorsComponent.cc
index 49f4b599fe3db6326037e8feb4649943937355e8..4b1e088d8bd3f908d7e9dad1e9db72d753b192b4 100644
--- a/src/AutoPilotPlugins/APM/APMSensorsComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMSensorsComponent.cc
@@ -24,6 +24,7 @@
#include "APMSensorsComponent.h"
#include "APMAutoPilotPlugin.h"
#include "APMSensorsComponentController.h"
+#include "APMAirframeComponent.h"
// These two list must be kept in sync
diff --git a/src/AutoPilotPlugins/APM/APMTuningComponent.cc b/src/AutoPilotPlugins/APM/APMTuningComponent.cc
index ca61ec1d599568d9d0ee8a2d74c52e0c36a46d45..7275d9829a98d771b201a287993715678f9b69f0 100644
--- a/src/AutoPilotPlugins/APM/APMTuningComponent.cc
+++ b/src/AutoPilotPlugins/APM/APMTuningComponent.cc
@@ -23,6 +23,7 @@
#include "APMTuningComponent.h"
#include "APMAutoPilotPlugin.h"
+#include "APMAirframeComponent.h"
APMTuningComponent::APMTuningComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
: APMComponent(vehicle, autopilot, parent)
diff --git a/src/AutoPilotPlugins/APM/AirframeFactMetaData.xml b/src/AutoPilotPlugins/APM/AirframeFactMetaData.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b41926c02ffa0d4dd09607997ee020d52ae42656
--- /dev/null
+++ b/src/AutoPilotPlugins/APM/AirframeFactMetaData.xml
@@ -0,0 +1,30 @@
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.h b/src/AutoPilotPlugins/AutoPilotPlugin.h
index 8e24bb5c6f82f508dca8e2380dcd84d36eca8fd1..649542ae9df79e8d3512a6e720b325cc79cc404d 100644
--- a/src/AutoPilotPlugins/AutoPilotPlugin.h
+++ b/src/AutoPilotPlugins/AutoPilotPlugin.h
@@ -1,148 +1,148 @@
-/*=====================================================================
-
- QGroundControl Open Source Ground Control Station
-
- (c) 2009 - 2014 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 AUTOPILOTPLUGIN_H
-#define AUTOPILOTPLUGIN_H
-
-#include
-#include
-#include
-#include
-
-#include "VehicleComponent.h"
-#include "FactSystem.h"
-#include "Vehicle.h"
-
-class ParameterLoader;
-class Vehicle;
-class FirmwarePlugin;
-
-/// This is the base class for AutoPilot plugins
-///
-/// The AutoPilotPlugin class is an abstract base class which represent the methods and objects
-/// which are specific to a certain AutoPilot. This is the only place where AutoPilot specific
-/// code should reside in QGroundControl. The remainder of the QGroundControl source is
-/// generic to a common mavlink implementation.
-
-class AutoPilotPlugin : public QObject
-{
- Q_OBJECT
-
-public:
- AutoPilotPlugin(Vehicle* vehicle, QObject* parent);
- ~AutoPilotPlugin();
-
- /// true: parameters are ready for use
- Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged)
-
- /// true: parameters are missing from firmware response, false: all parameters received from firmware
- Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged)
-
- /// List of VehicleComponent objects
- Q_PROPERTY(QVariantList vehicleComponents READ vehicleComponents CONSTANT)
-
- /// false: One or more vehicle components require setup
- Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged)
-
- /// Reset all parameters to their default values
- Q_INVOKABLE void resetAllParametersToDefaults(void);
-
- /// Re-request the full set of parameters from the autopilot
- Q_INVOKABLE void refreshAllParameters(void);
-
- /// Request a refresh on the specific parameter
- Q_INVOKABLE void refreshParameter(int componentId, const QString& name);
-
- /// Request a refresh on all parameters that begin with the specified prefix
- Q_INVOKABLE void refreshParametersPrefix(int componentId, const QString& namePrefix);
-
- /// Returns true if the specifed parameter exists from the default component
- Q_INVOKABLE bool parameterExists(int componentId, const QString& name);
-
- /// Returns all parameter names
- QStringList parameterNames(int componentId);
-
- /// Returns the specified parameter Fact from the default component
- /// WARNING: Returns a default Fact if parameter does not exists. If that possibility exists, check for existince first with
- /// parameterExists.
- Fact* getParameterFact(int componentId, const QString& name);
-
- /// Writes the parameter facts to the specified stream
- void writeParametersToStream(QTextStream &stream);
-
- /// Reads the parameters from the stream and updates values
- /// @return Errors during load. Empty string for no errors
- QString readParametersFromStream(QTextStream &stream);
-
- /// Returns true if the specifed fact exists
- Q_INVOKABLE bool factExists(FactSystem::Provider_t provider, ///< fact provider
- int componentId, ///< fact component, -1=default component
- const QString& name); ///< fact name
-
- /// Returns the specified Fact.
- /// WARNING: Will assert if fact does not exists. If that possibility exists, check for existince first with
- /// factExists.
- Fact* getFact(FactSystem::Provider_t provider, ///< fact provider
- int componentId, ///< fact component, -1=default component
- const QString& name); ///< fact name
-
- const QMap >& getGroupMap(void);
-
- // Must be implemented by derived class
- virtual const QVariantList& vehicleComponents(void) = 0;
-
- // Property accessors
- bool parametersReady(void) { return _parametersReady; }
- bool missingParameters(void) { return _missingParameters; }
- bool setupComplete(void);
-
- Vehicle* vehicle(void) { return _vehicle; }
-
-signals:
- void parametersReadyChanged(bool parametersReady);
- void missingParametersChanged(bool missingParameters);
- void setupCompleteChanged(bool setupComplete);
- void parameterListProgress(float value);
-
-protected:
- /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
- AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
-
- Vehicle* _vehicle;
- FirmwarePlugin* _firmwarePlugin;
- bool _parametersReady;
- bool _missingParameters;
- bool _setupComplete;
-
-private slots:
- void _uasDisconnected(void);
- void _parametersReadyChanged(bool parametersReady);
-
-private:
- void _recalcSetupComplete(void);
-};
-
-#endif
+ /*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 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 AUTOPILOTPLUGIN_H
+ #define AUTOPILOTPLUGIN_H
+
+ #include
+ #include
+ #include
+ #include
+
+ #include "VehicleComponent.h"
+ #include "FactSystem.h"
+ #include "Vehicle.h"
+
+ class ParameterLoader;
+ class Vehicle;
+ class FirmwarePlugin;
+
+ /// This is the base class for AutoPilot plugins
+ ///
+ /// The AutoPilotPlugin class is an abstract base class which represent the methods and objects
+ /// which are specific to a certain AutoPilot. This is the only place where AutoPilot specific
+ /// code should reside in QGroundControl. The remainder of the QGroundControl source is
+ /// generic to a common mavlink implementation.
+
+ class AutoPilotPlugin : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ AutoPilotPlugin(Vehicle* vehicle, QObject* parent);
+ ~AutoPilotPlugin();
+
+ /// true: parameters are ready for use
+ Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged)
+
+ /// true: parameters are missing from firmware response, false: all parameters received from firmware
+ Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged)
+
+ /// List of VehicleComponent objects
+ Q_PROPERTY(QVariantList vehicleComponents READ vehicleComponents CONSTANT)
+
+ /// false: One or more vehicle components require setup
+ Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged)
+
+ /// Reset all parameters to their default values
+ Q_INVOKABLE void resetAllParametersToDefaults(void);
+
+ /// Re-request the full set of parameters from the autopilot
+ Q_INVOKABLE void refreshAllParameters(void);
+
+ /// Request a refresh on the specific parameter
+ Q_INVOKABLE void refreshParameter(int componentId, const QString& name);
+
+ /// Request a refresh on all parameters that begin with the specified prefix
+ Q_INVOKABLE void refreshParametersPrefix(int componentId, const QString& namePrefix);
+
+ /// Returns true if the specifed parameter exists from the default component
+ Q_INVOKABLE bool parameterExists(int componentId, const QString& name);
+
+ /// Returns all parameter names
+ QStringList parameterNames(int componentId);
+
+ /// Returns the specified parameter Fact from the default component
+ /// WARNING: Returns a default Fact if parameter does not exists. If that possibility exists, check for existince first with
+ /// parameterExists.
+ Fact* getParameterFact(int componentId, const QString& name);
+
+ /// Writes the parameter facts to the specified stream
+ void writeParametersToStream(QTextStream &stream);
+
+ /// Reads the parameters from the stream and updates values
+ /// @return Errors during load. Empty string for no errors
+ QString readParametersFromStream(QTextStream &stream);
+
+ /// Returns true if the specifed fact exists
+ Q_INVOKABLE bool factExists(FactSystem::Provider_t provider, ///< fact provider
+ int componentId, ///< fact component, -1=default component
+ const QString& name); ///< fact name
+
+ /// Returns the specified Fact.
+ /// WARNING: Will assert if fact does not exists. If that possibility exists, check for existince first with
+ /// factExists.
+ Fact* getFact(FactSystem::Provider_t provider, ///< fact provider
+ int componentId, ///< fact component, -1=default component
+ const QString& name); ///< fact name
+
+ const QMap >& getGroupMap(void);
+
+ // Must be implemented by derived class
+ virtual const QVariantList& vehicleComponents(void) = 0;
+
+ // Property accessors
+ bool parametersReady(void) { return _parametersReady; }
+ bool missingParameters(void) { return _missingParameters; }
+ bool setupComplete(void);
+
+ Vehicle* vehicle(void) { return _vehicle; }
+
+ signals:
+ void parametersReadyChanged(bool parametersReady);
+ void missingParametersChanged(bool missingParameters);
+ void setupCompleteChanged(bool setupComplete);
+ void parameterListProgress(float value);
+
+ protected:
+ /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
+ AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
+
+ Vehicle* _vehicle;
+ FirmwarePlugin* _firmwarePlugin;
+ bool _parametersReady;
+ bool _missingParameters;
+ bool _setupComplete;
+
+ private slots:
+ void _uasDisconnected(void);
+ void _parametersReadyChanged(bool parametersReady);
+
+ private:
+ void _recalcSetupComplete(void);
+ };
+
+ #endif
diff --git a/src/AutoPilotPlugins/PX4/SafetyComponent.qml b/src/AutoPilotPlugins/PX4/SafetyComponent.qml
index 8f04839ef20fe35cd07de6369fa15043cbba5168..695dab48947f2b5d7c54a486973fc57592aecbea 100644
--- a/src/AutoPilotPlugins/PX4/SafetyComponent.qml
+++ b/src/AutoPilotPlugins/PX4/SafetyComponent.qml
@@ -56,7 +56,7 @@ QGCView {
Flickable {
clip: true
anchors.fill: parent
- contentHeight: 7000 //rtlSettings.height
+ contentHeight: screenBottom.y + screenBottom.height
contentWidth: parent.width
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.VerticalFlick
@@ -287,27 +287,40 @@ QGCView {
}
}
- /*
QGCLabel {
- width: parent.width
- font.pixelSize: ScreenTools.mediumFontPixelSize
- text: "Warning: You have an advanced safety configuration set using the NAV_RCL_OBC parameter. The above settings may not apply.";
- visible: fact.value !== 0
- wrapMode: Text.Wrap
+ id: navRclObc
+ anchors.topMargin: _margins
+ anchors.top: rtlSettings.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ font.pixelSize: ScreenTools.mediumFontPixelSize
+ text: "Warning: You have an advanced safety configuration set using the NAV_RCL_OBC parameter. The above settings may not apply.";
+ visible: fact.value !== 0
+ wrapMode: Text.Wrap
property Fact fact: controller.getParameterFact(-1, "NAV_RCL_OBC")
}
QGCLabel {
- width: parent.width
- font.pixelSize: ScreenTools.mediumFontPixelSize
- text: "Warning: You have an advanced safety configuration set using the NAV_DLL_OBC parameter. The above settings may not apply.";
- visible: fact.value !== 0
- wrapMode: Text.Wrap
+ id: navDllObc
+ anchors.topMargin: _margins / 2
+ anchors.top: navRclObc.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ font.pixelSize: ScreenTools.mediumFontPixelSize
+ text: "Warning: You have an advanced safety configuration set using the NAV_DLL_OBC parameter. The above settings may not apply.";
+ visible: fact.value !== 0
+ wrapMode: Text.Wrap
property Fact fact: controller.getParameterFact(-1, "NAV_DLL_OBC")
}
- */
- } // Flickable
- } // QGCViewPanel
- } // QGCView
+
+ Item {
+ id: screenBottom
+ anchors.top: navDllObc.bottom
+ width: 1
+ height: 1
+ }
+ } // Flickable
+ } // QGCViewPanel
+} // QGCView
diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.qml b/src/AutoPilotPlugins/PX4/SensorsComponent.qml
index 8147775e4778e6a677dd40a8527faed1498edb66..750a9005e4da171c81ce9c8a5efba1146b458f98 100644
--- a/src/AutoPilotPlugins/PX4/SensorsComponent.qml
+++ b/src/AutoPilotPlugins/PX4/SensorsComponent.qml
@@ -90,7 +90,8 @@ QGCView {
"ROTATION_PITCH_270",
"ROTATION_ROLL_270_YAW_270",
"ROTATION_ROLL_180_PITCH_270",
- "ROTATION_PITCH_90_YAW_180"
+ "ROTATION_PITCH_90_YAW_180",
+ "ROTATION_ROLL_90_PITCH_90"
]
property Fact cal_mag0_id: controller.getParameterFact(-1, "CAL_MAG0_ID")
diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h
index f2e311c8f59eafc3d2dd3c2ca539dab4163444dd..0c6e55fdf8bcb912acf68acf231b2a9bf56b512e 100644
--- a/src/FactSystem/Fact.h
+++ b/src/FactSystem/Fact.h
@@ -136,7 +136,7 @@ signals:
/// This signal is meant for use by Fact container implementations.
void _containerRawValueChanged(const QVariant& value);
-private:
+protected:
QString _variantToString(const QVariant& variant) const;
QString _name;
diff --git a/src/FactSystem/SettingsFact.cc b/src/FactSystem/SettingsFact.cc
new file mode 100644
index 0000000000000000000000000000000000000000..de31cb7ea3af98bc0d832d8057d10921b8ce04cd
--- /dev/null
+++ b/src/FactSystem/SettingsFact.cc
@@ -0,0 +1,73 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 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 .
+
+ ======================================================================*/
+
+#include "SettingsFact.h"
+
+#include
+
+SettingsFact::SettingsFact(QObject* parent)
+ : Fact(parent)
+{
+
+}
+
+SettingsFact::SettingsFact(QString settingGroup, QString settingName, FactMetaData::ValueType_t type, const QVariant& defaultValue, QObject* parent)
+ : Fact(0, settingName, type, parent)
+ , _settingGroup(settingGroup)
+{
+ QSettings settings;
+
+ if (!_settingGroup.isEmpty()) {
+ settings.beginGroup(_settingGroup);
+ }
+
+ _rawValue = settings.value(_name, defaultValue);
+
+ connect(this, &Fact::valueChanged, this, &SettingsFact::_valueChanged);
+}
+
+SettingsFact::SettingsFact(const SettingsFact& other, QObject* parent)
+ : Fact(other, parent)
+{
+ *this = other;
+}
+
+const SettingsFact& SettingsFact::operator=(const SettingsFact& other)
+{
+ Fact::operator=(other);
+
+ _settingGroup = other._settingGroup;
+
+ return *this;
+}
+
+void SettingsFact::_valueChanged(QVariant value)
+{
+ QSettings settings;
+
+ if (!_settingGroup.isEmpty()) {
+ settings.beginGroup(_settingGroup);
+ }
+
+ settings.setValue(_name, value);
+}
diff --git a/src/FactSystem/SettingsFact.h b/src/FactSystem/SettingsFact.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb8a6b897ca2ac4febaeaa67acdabcb1558ba664
--- /dev/null
+++ b/src/FactSystem/SettingsFact.h
@@ -0,0 +1,51 @@
+/*=====================================================================
+
+ QGroundControl Open Source Ground Control Station
+
+ (c) 2009 - 2014 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 SettingsFact_H
+#define SettingsFact_H
+
+#include "Fact.h"
+
+/// @brief A SettingsFact is Fact which holds a QSettings value.
+class SettingsFact : public Fact
+{
+ Q_OBJECT
+
+public:
+ SettingsFact(QObject* parent = NULL);
+ SettingsFact(QString settingGroup, QString settingName, FactMetaData::ValueType_t type, const QVariant& defaultValue, QObject* parent = NULL);
+ SettingsFact(const SettingsFact& other, QObject* parent = NULL);
+
+ const SettingsFact& operator=(const SettingsFact& other);
+
+private slots:
+ void _valueChanged(QVariant value);
+
+private:
+ QString _settingGroup;
+};
+
+#endif
diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc
index 946f7cda7aa55666234edf9ca67d2ff54ec961d1..7808b3c045471e944fa3af1430822d2dcd7fd613 100644
--- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc
+++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc
@@ -216,12 +216,7 @@ QList PX4FirmwarePlugin::supportedMissionCommands(void)
<< MAV_CMD_NAV_LOITER_UNLIM << MAV_CMD_NAV_LOITER_TURNS << MAV_CMD_NAV_LOITER_TIME
<< MAV_CMD_NAV_RETURN_TO_LAUNCH << MAV_CMD_NAV_LAND << MAV_CMD_NAV_TAKEOFF
<< MAV_CMD_NAV_ROI
- << MAV_CMD_NAV_GUIDED_ENABLE
- << MAV_CMD_DO_SET_ROI << MAV_CMD_DO_GUIDED_LIMITS << MAV_CMD_DO_JUMP << MAV_CMD_DO_CHANGE_SPEED << MAV_CMD_DO_SET_CAM_TRIGG_DIST
- << MAV_CMD_DO_SET_RELAY << MAV_CMD_DO_REPEAT_RELAY
- << MAV_CMD_DO_SET_SERVO << MAV_CMD_DO_REPEAT_SERVO
- << MAV_CMD_DO_DIGICAM_CONFIGURE << MAV_CMD_DO_DIGICAM_CONTROL
- << MAV_CMD_DO_MOUNT_CONTROL
- << MAV_CMD_CONDITION_DELAY << MAV_CMD_CONDITION_CHANGE_ALT << MAV_CMD_CONDITION_DISTANCE << MAV_CMD_CONDITION_YAW;
+ << MAV_CMD_DO_JUMP
+ << MAV_CMD_CONDITION_DELAY;
return list;
}
diff --git a/src/MissionManager/MissionCommands.cc b/src/MissionManager/MissionCommands.cc
index 0f6a1e14fc49cfaf1718bed24e949d274b8b966e..dbbc0c05b81d9acb5307cfa8864e42d0d9953e9b 100644
--- a/src/MissionManager/MissionCommands.cc
+++ b/src/MissionManager/MissionCommands.cc
@@ -22,6 +22,10 @@ This file is part of the QGROUNDCONTROL project
#include "MissionCommands.h"
#include "FactMetaData.h"
+#include "Vehicle.h"
+#include "FirmwarePluginManager.h"
+#include "QGCApplication.h"
+#include "QGroundControlQmlGlobal.h"
#include
#include
@@ -60,7 +64,14 @@ const QString MissionCommands::_degreesUnits (QStringLiteral("deg
MissionCommands::MissionCommands(QGCApplication* app)
: QGCTool(app)
{
+
+}
+
+void MissionCommands::setToolbox(QGCToolbox* toolbox)
+{
+ QGCTool::setToolbox(toolbox);
_loadMavCmdInfoJson();
+ _createFirmwareSpecificLists();
}
bool MissionCommands::_validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList& types)
@@ -165,7 +176,6 @@ void MissionCommands::_loadMavCmdInfoJson(void)
}
_mavCmdInfoMap[mavCmdInfo->_command] = mavCmdInfo;
- _commandList.append(mavCmdInfo);
// Read params
@@ -234,16 +244,13 @@ void MissionCommands::_loadMavCmdInfoJson(void)
if (mavCmdInfo->_command != MAV_CMD_NAV_LAST) {
// Don't add fake home postion command to categories
- if (!_categories.contains(mavCmdInfo->category()) && mavCmdInfo->friendlyEdit()) {
- // Only friendly edit commands go in category list
- qCDebug(MissionCommandsLog) << "Adding new category";
- _categories.append(mavCmdInfo->category());
- _categoryToMavCmdInfoListMap[mavCmdInfo->category()] = new QmlObjectListModel(this);
- }
-
if (mavCmdInfo->friendlyEdit()) {
- // Only friendly edit commands go in category list
- _categoryToMavCmdInfoListMap[mavCmdInfo->category()]->append(mavCmdInfo);
+ // Only friendly edit commands go in category list. We use MAV_AUTOPILOT_GENERIC key to store full list.
+ if (!_categoryToMavCmdInfoListMap.contains(MAV_AUTOPILOT_GENERIC) || !_categoryToMavCmdInfoListMap[MAV_AUTOPILOT_GENERIC].contains(mavCmdInfo->category())) {
+ qCDebug(MissionCommandsLog) << "Adding new category";
+ _categoryToMavCmdInfoListMap[MAV_AUTOPILOT_GENERIC][mavCmdInfo->category()] = new QmlObjectListModel(this);
+ }
+ _categoryToMavCmdInfoListMap[MAV_AUTOPILOT_GENERIC][mavCmdInfo->category()]->append(mavCmdInfo);
}
}
@@ -259,3 +266,64 @@ void MissionCommands::_loadMavCmdInfoJson(void)
}
}
}
+
+MAV_AUTOPILOT MissionCommands::_firmwareTypeFromVehicle(Vehicle* vehicle) const
+{
+ if (vehicle) {
+ return vehicle->firmwareType();
+ } else {
+ QSettings settings;
+
+ // FIXME: Hack duplicated code from QGroundControlQmlGlobal. Had to do this for now since
+ // QGroundControlQmlGlobal is not available from C++ side.
+
+ return (MAV_AUTOPILOT)settings.value("OfflineEditingFirmwareType", MAV_AUTOPILOT_ARDUPILOTMEGA).toInt();
+ }
+}
+
+QString MissionCommands::categoryFromCommand(MavlinkQmlSingleton::Qml_MAV_CMD command) const
+{
+ return _mavCmdInfoMap[(MAV_CMD)command]->category();
+}
+
+QVariant MissionCommands::getCommandsForCategory(Vehicle* vehicle, const QString& category) const
+{
+ return QVariant::fromValue(_categoryToMavCmdInfoListMap[_firmwareTypeFromVehicle(vehicle)][category]);
+}
+
+const QStringList MissionCommands::categories(Vehicle* vehicle) const
+{
+ QStringList list;
+
+ foreach (QString category, _categoryToMavCmdInfoListMap[_firmwareTypeFromVehicle(vehicle)].keys()) {
+ list << category;
+ }
+
+ return list;
+}
+
+void MissionCommands::_createFirmwareSpecificLists(void)
+{
+ QList firmwareList;
+
+ firmwareList << MAV_AUTOPILOT_PX4 << MAV_AUTOPILOT_ARDUPILOTMEGA;
+
+ foreach (MAV_AUTOPILOT firmwareType, firmwareList) {
+ FirmwarePlugin* plugin = _toolbox->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR);
+
+ QList cmdList = plugin->supportedMissionCommands();
+ foreach (MAV_CMD command, cmdList) {
+ MavCmdInfo* mavCmdInfo = _mavCmdInfoMap[command];
+
+ if (mavCmdInfo->friendlyEdit()) {
+ if (!_categoryToMavCmdInfoListMap.contains(firmwareType) || !_categoryToMavCmdInfoListMap[firmwareType].contains(mavCmdInfo->category())) {
+ qCDebug(MissionCommandsLog) << "Adding new category" << firmwareType;
+ _categoryToMavCmdInfoListMap[firmwareType][mavCmdInfo->category()] = new QmlObjectListModel(this);
+ }
+ _categoryToMavCmdInfoListMap[firmwareType][mavCmdInfo->category()]->append(mavCmdInfo);
+ } else {
+ qWarning() << "Attempt to add non friendly edit supported command";
+ }
+ }
+ }
+}
diff --git a/src/MissionManager/MissionCommands.h b/src/MissionManager/MissionCommands.h
index ce2f214f1c9378e390d1e6e7363700df6ba4e74b..200b3e584235834ff0543bacc220cd1715a857d4 100644
--- a/src/MissionManager/MissionCommands.h
+++ b/src/MissionManager/MissionCommands.h
@@ -38,6 +38,7 @@
Q_DECLARE_LOGGING_CATEGORY(MissionCommandsLog)
class MissionCommands;
+class Vehicle;
class MavCmdParamInfo : public QObject {
@@ -129,17 +130,15 @@ class MissionCommands : public QGCTool
public:
MissionCommands(QGCApplication* app);
- Q_PROPERTY(QStringList categories READ categories CONSTANT)
- Q_PROPERTY(const QmlObjectListModel* commands READ commands CONSTANT)
-
- Q_INVOKABLE QString categoryFromCommand(MavlinkQmlSingleton::Qml_MAV_CMD command) { return _mavCmdInfoMap[(MAV_CMD)command]->category(); }
- Q_INVOKABLE const QVariant getCommandsForCategory(const QString& category) const { return QVariant::fromValue(_categoryToMavCmdInfoListMap[category]); }
-
- const QStringList categories (void) const { return _categories; }
- const QmlObjectListModel* commands (void) const { return &_commandList; }
+ Q_INVOKABLE const QStringList categories (Vehicle* vehicle) const;
+ Q_INVOKABLE QString categoryFromCommand (MavlinkQmlSingleton::Qml_MAV_CMD command) const;
+ Q_INVOKABLE QVariant getCommandsForCategory (Vehicle* vehicle, const QString& category) const;
const QMap& commandInfoMap(void) const { return _mavCmdInfoMap; };
+ // Overrides from QGCTool
+ virtual void setToolbox(QGCToolbox* toolbox);
+
static const QString _degreesUnits;
static const QString _degreesConvertUnits;
@@ -147,14 +146,14 @@ signals:
private:
void _loadMavCmdInfoJson(void);
+ void _createFirmwareSpecificLists(void);
void _setupMetaData(void);
bool _validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList& types);
+ MAV_AUTOPILOT _firmwareTypeFromVehicle(Vehicle* vehicle) const;
private:
- QStringList _categories;
- QMap _categoryToMavCmdInfoListMap;
- QmlObjectListModel _commandList;
- QMap _mavCmdInfoMap;
+ QMap > _categoryToMavCmdInfoListMap;
+ QMap _mavCmdInfoMap;
static const QString _categoryJsonKey;
static const QString _decimalPlacesJsonKey;
diff --git a/src/MissionManager/MissionItem.cc b/src/MissionManager/MissionItem.cc
index 8f477f21c4ef9ac2a81b0e577715faba3fb7a353..2cd3c699e66a1ac42bdc791abaaf21ecba051449 100644
--- a/src/MissionManager/MissionItem.cc
+++ b/src/MissionManager/MissionItem.cc
@@ -37,7 +37,6 @@ FactMetaData* MissionItem::_defaultParamMetaData = NULL;
FactMetaData* MissionItem::_frameMetaData = NULL;
FactMetaData* MissionItem::_latitudeMetaData = NULL;
FactMetaData* MissionItem::_longitudeMetaData = NULL;
-FactMetaData* MissionItem::_supportedCommandMetaData = NULL;
struct EnumInfo_s {
const char * label;
@@ -108,7 +107,6 @@ MissionItem::MissionItem(QObject* parent)
, _param7MetaData(FactMetaData::valueTypeDouble)
, _syncingAltitudeRelativeToHomeAndFrame (false)
, _syncingHeadingDegreesAndParam4 (false)
- , _syncingSupportedCommandAndCommand (false)
, _mavCmdInfoMap(qgcApp()->toolbox()->missionCommands()->commandInfoMap())
{
// Need a good command and frame before we start passing signals around
@@ -167,7 +165,6 @@ MissionItem::MissionItem(int sequenceNumber,
, _param7MetaData(FactMetaData::valueTypeDouble)
, _syncingAltitudeRelativeToHomeAndFrame (false)
, _syncingHeadingDegreesAndParam4 (false)
- , _syncingSupportedCommandAndCommand (false)
, _mavCmdInfoMap(qgcApp()->toolbox()->missionCommands()->commandInfoMap())
{
// Need a good command and frame before we start passing signals around
@@ -183,7 +180,6 @@ MissionItem::MissionItem(int sequenceNumber,
setAutoContinue(autoContinue);
_syncFrameToAltitudeRelativeToHome();
- _syncCommandToSupportedCommand(QVariant(this->command()));
_param1Fact.setRawValue(param1);
_param2Fact.setRawValue(param2);
@@ -223,7 +219,6 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent)
, _param4MetaData(FactMetaData::valueTypeDouble)
, _syncingAltitudeRelativeToHomeAndFrame (false)
, _syncingHeadingDegreesAndParam4 (false)
- , _syncingSupportedCommandAndCommand (false)
, _mavCmdInfoMap(qgcApp()->toolbox()->missionCommands()->commandInfoMap())
{
// Need a good command and frame before we start passing signals around
@@ -254,7 +249,6 @@ const MissionItem& MissionItem::operator=(const MissionItem& other)
setHomePositionValid(other._homePositionValid);
_syncFrameToAltitudeRelativeToHome();
- _syncCommandToSupportedCommand(QVariant(this->command()));
_param1Fact.setRawValue(other._param1Fact.rawValue());
_param2Fact.setRawValue(other._param2Fact.rawValue());
@@ -282,8 +276,6 @@ void MissionItem::_connectSignals(void)
connect(this, &MissionItem::sequenceNumberChanged, this, &MissionItem::_setDirtyFromSignal);
// Values from these facts must propogate back and forth between the real object storage
- connect(&_supportedCommandFact, &Fact::valueChanged, this, &MissionItem::_syncSupportedCommandToCommand);
- connect(&_commandFact, &Fact::valueChanged, this, &MissionItem::_syncCommandToSupportedCommand);
connect(&_altitudeRelativeToHomeFact, &Fact::valueChanged, this, &MissionItem::_syncAltitudeRelativeToHomeToFrame);
connect(this, &MissionItem::frameChanged, this, &MissionItem::_syncFrameToAltitudeRelativeToHome);
@@ -351,28 +343,10 @@ void MissionItem::_setupMetaData(void)
_longitudeMetaData->setUnits("deg");
_longitudeMetaData->setDecimalPlaces(7);
- enumStrings.clear();
- enumValues.clear();
- // FIXME: Hack hardcode to PX4
- QList supportedCommands = qgcApp()->toolbox()->firmwarePluginManager()->firmwarePluginForAutopilot(MAV_AUTOPILOT_PX4, MAV_TYPE_QUADROTOR)->supportedMissionCommands();
- if (supportedCommands.count()) {
- foreach (MAV_CMD command, supportedCommands) {
- enumStrings.append(_mavCmdInfoMap[command]->friendlyName());
- enumValues.append(QVariant(command));
- }
- } else {
- foreach (const MavCmdInfo* mavCmdInfo, _mavCmdInfoMap) {
- enumStrings.append(mavCmdInfo->friendlyName());
- enumValues.append(QVariant(mavCmdInfo->command()));
- }
- }
- _supportedCommandMetaData = new FactMetaData(FactMetaData::valueTypeUint32);
- _supportedCommandMetaData->setEnumInfo(enumStrings, enumValues);
}
_commandFact.setMetaData(_commandMetaData);
_frameFact.setMetaData(_frameMetaData);
- _supportedCommandFact.setMetaData(_supportedCommandMetaData);
}
MissionItem::~MissionItem()
@@ -787,24 +761,6 @@ void MissionItem::_syncFrameToAltitudeRelativeToHome(void)
}
}
-void MissionItem::_syncSupportedCommandToCommand(const QVariant& value)
-{
- if (!_syncingSupportedCommandAndCommand) {
- _syncingSupportedCommandAndCommand = true;
- _commandFact.setRawValue(value.toInt());
- _syncingSupportedCommandAndCommand = false;
- }
-}
-
-void MissionItem::_syncCommandToSupportedCommand(const QVariant& value)
-{
- if (!_syncingSupportedCommandAndCommand) {
- _syncingSupportedCommandAndCommand = true;
- _supportedCommandFact.setRawValue(value.toInt());
- _syncingSupportedCommandAndCommand = false;
- }
-}
-
void MissionItem::setDefaultsForCommand(void)
{
// We set these global defaults first, then if there are param defaults they will get reset
diff --git a/src/MissionManager/MissionItem.h b/src/MissionManager/MissionItem.h
index a0e7c832691afce9e1f66fe3c8f97d65548c52fb..31446d8cdfc3a24c459c10433481fdeddcf5e4ec 100644
--- a/src/MissionManager/MissionItem.h
+++ b/src/MissionManager/MissionItem.h
@@ -87,7 +87,6 @@ public:
Q_PROPERTY(int sequenceNumber READ sequenceNumber WRITE setSequenceNumber NOTIFY sequenceNumberChanged)
Q_PROPERTY(bool standaloneCoordinate READ standaloneCoordinate NOTIFY commandChanged)
Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate NOTIFY commandChanged)
- Q_PROPERTY(Fact* supportedCommand READ supportedCommand NOTIFY commandChanged)
// These properties are used to display the editing ui
Q_PROPERTY(QmlObjectListModel* checkboxFacts READ checkboxFacts NOTIFY uiModelChanged)
@@ -118,7 +117,6 @@ public:
int sequenceNumber (void) const { return _sequenceNumber; }
bool standaloneCoordinate(void) const;
bool specifiesCoordinate (void) const;
- Fact* supportedCommand (void) { return &_supportedCommandFact; }
QmlObjectListModel* textFieldFacts (void);
@@ -206,9 +204,7 @@ private slots:
void _sendFriendlyEditAllowedChanged(void);
void _sendUiModelChanged(void);
void _syncAltitudeRelativeToHomeToFrame(const QVariant& value);
- void _syncCommandToSupportedCommand(const QVariant& value);
void _syncFrameToAltitudeRelativeToHome(void);
- void _syncSupportedCommandToCommand(const QVariant& value);
private:
void _clearParamMetaData(void);
@@ -249,7 +245,6 @@ private:
static FactMetaData* _frameMetaData;
static FactMetaData* _latitudeMetaData;
static FactMetaData* _longitudeMetaData;
- static FactMetaData* _supportedCommandMetaData;
FactMetaData _param1MetaData;
FactMetaData _param2MetaData;
@@ -264,7 +259,6 @@ private:
bool _syncingAltitudeRelativeToHomeAndFrame; ///< true: already in a sync signal, prevents signal loop
bool _syncingHeadingDegreesAndParam4; ///< true: already in a sync signal, prevents signal loop
- bool _syncingSupportedCommandAndCommand; ///< true: already in a sync signal, prevents signal loop
const QMap& _mavCmdInfoMap;
};
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index 5dc5193e93b06f674215ab302ae8480a7b3b9ae6..d5215220b6b6de0dfe09bf87c9096e3a1307d218 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -77,6 +77,7 @@
#include "APM/ArduCopterFirmwarePlugin.h"
#include "APM/ArduPlaneFirmwarePlugin.h"
#include "APM/ArduRoverFirmwarePlugin.h"
+#include "APM/APMAirframeComponentController.h"
#include "PX4/PX4FirmwarePlugin.h"
#include "Vehicle.h"
#include "MavlinkQmlSingleton.h"
@@ -144,7 +145,11 @@ static QObject* mavlinkQmlSingletonFactory(QQmlEngine*, QJSEngine*)
static QObject* qgroundcontrolQmlGlobalSingletonFactory(QQmlEngine*, QJSEngine*)
{
- return new QGroundControlQmlGlobal(qgcApp()->toolbox());
+ // We create this object as a QGCTool even though it isn't int he toolbox
+ QGroundControlQmlGlobal* qmlGlobal = new QGroundControlQmlGlobal(qgcApp());
+ qmlGlobal->setToolbox(qgcApp()->toolbox());
+
+ return qmlGlobal;
}
/**
@@ -378,9 +383,10 @@ void QGCApplication::_initCommon(void)
qmlRegisterUncreatableType ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
qmlRegisterUncreatableType ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");
- qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
+ qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
qmlRegisterType ("QGroundControl.Controllers", 1, 0, "APMFlightModesComponentController");
qmlRegisterType ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController");
+ qmlRegisterType ("QGroundControl.Controllers", 1, 0, "APMAirframeComponentController");
qmlRegisterType ("QGroundControl.Controllers", 1, 0, "AirframeComponentController");
qmlRegisterType ("QGroundControl.Controllers", 1, 0, "APMSensorsComponentController");
qmlRegisterType ("QGroundControl.Controllers", 1, 0, "SensorsComponentController");
diff --git a/src/QmlControls/MissionCommandDialog.qml b/src/QmlControls/MissionCommandDialog.qml
index d41004f7e3660ddcc9ff793b2f1e147b9647b4e2..fc7f4f3942c6f30dd5f29d3b8da1fb40008f8189 100644
--- a/src/QmlControls/MissionCommandDialog.qml
+++ b/src/QmlControls/MissionCommandDialog.qml
@@ -32,6 +32,8 @@ import QGroundControl.Palette 1.0
QGCViewDialog {
property var missionItem
+ property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle
+
QGCPalette { id: qgcPal }
QGCLabel {
@@ -45,10 +47,10 @@ QGCViewDialog {
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: categoryLabel.right
anchors.right: parent.right
- model: QGroundControl.missionCommands.categories
+ model: QGroundControl.missionCommands.categories(_vehicle)
function categorySelected(category) {
- commandList.model = QGroundControl.missionCommands.getCommandsForCategory(category)
+ commandList.model = QGroundControl.missionCommands.getCommandsForCategory(_vehicle, category)
}
Component.onCompleted: {
@@ -109,5 +111,4 @@ QGCViewDialog {
}
}
} // ListView
-
} // QGCViewDialog
diff --git a/src/QmlControls/QGCView.qml b/src/QmlControls/QGCView.qml
index 1536effc22393a6733df29dd25d399d3d6bf233b..359d4fc5615cab47c59ae75c6ea53c7c6a4efc0c 100644
--- a/src/QmlControls/QGCView.qml
+++ b/src/QmlControls/QGCView.qml
@@ -96,7 +96,7 @@ FactPanel {
__rejectButton.text = "Cancel"
__rejectButton.visible = true
} else if (buttons & StandardButton.Close) {
- __rejectButton.text = "Cancel"
+ __rejectButton.text = "Close"
__rejectButton.visible = true
} else if (buttons & StandardButton.No) {
__rejectButton.text = "No"
diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc
index e5270782df5ba173282c3d6b613757c2ce693bc9..ca0348a9d76299c54c70a882708d8bc2088e9475 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.cc
+++ b/src/QmlControls/QGroundControlQmlGlobal.cc
@@ -25,7 +25,6 @@
/// @author Don Gagne
#include "QGroundControlQmlGlobal.h"
-#include "QGCApplication.h"
#include
@@ -33,19 +32,49 @@ static const char* kQmlGlobalKeyName = "QGCQml";
const char* QGroundControlQmlGlobal::_virtualTabletJoystickKey = "VirtualTabletJoystick";
-QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCToolbox* toolbox, QObject* parent)
- : QObject(parent)
- , _flightMapSettings(toolbox->flightMapSettings())
- , _homePositionManager(toolbox->homePositionManager())
- , _linkManager(toolbox->linkManager())
- , _missionCommands(toolbox->missionCommands())
- , _multiVehicleManager(toolbox->multiVehicleManager())
+QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app)
+ : QGCTool(app)
+ , _flightMapSettings(NULL)
+ , _homePositionManager(NULL)
+ , _linkManager(NULL)
+ , _missionCommands(NULL)
+ , _multiVehicleManager(NULL)
, _virtualTabletJoystick(false)
+ , _offlineEditingFirmwareTypeFact(QString(), "OfflineEditingFirmwareType", FactMetaData::valueTypeUint32, (uint32_t)MAV_AUTOPILOT_ARDUPILOTMEGA)
+ , _offlineEditingFirmwareTypeMetaData(FactMetaData::valueTypeUint32)
+
{
QSettings settings;
_virtualTabletJoystick = settings.value(_virtualTabletJoystickKey, false). toBool();
+
+ QStringList firmwareEnumStrings;
+ QVariantList firmwareEnumValues;
+
+ firmwareEnumStrings << "APM Flight Stack" << "PX4 Flight Stack" << "Mavlink Generic Flight Stack";
+ firmwareEnumValues << QVariant::fromValue((uint32_t)MAV_AUTOPILOT_ARDUPILOTMEGA) << QVariant::fromValue((uint32_t)MAV_AUTOPILOT_PX4) << QVariant::fromValue((uint32_t)MAV_AUTOPILOT_GENERIC);
+
+ _offlineEditingFirmwareTypeMetaData.setEnumInfo(firmwareEnumStrings, firmwareEnumValues);
+ _offlineEditingFirmwareTypeFact.setMetaData(&_offlineEditingFirmwareTypeMetaData);
+}
+
+QGroundControlQmlGlobal::~QGroundControlQmlGlobal()
+{
+
}
+
+void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox)
+{
+ QGCTool::setToolbox(toolbox);
+
+ _flightMapSettings = toolbox->flightMapSettings();
+ _homePositionManager = toolbox->homePositionManager();
+ _linkManager = toolbox->linkManager();
+ _missionCommands = toolbox->missionCommands();
+ _multiVehicleManager = toolbox->multiVehicleManager();
+}
+
+
void QGroundControlQmlGlobal::saveGlobalSetting (const QString& key, const QString& value)
{
QSettings settings;
diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h
index 599474cae5f24ee5f81e326bd6642c60fbffdd0b..ff4403052e5ac349742ef5933409022bd4d2d5f0 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.h
+++ b/src/QmlControls/QGroundControlQmlGlobal.h
@@ -27,13 +27,13 @@
#ifndef QGroundControlQmlGlobal_H
#define QGroundControlQmlGlobal_H
-#include
-
+#include "QGCToolbox.h"
#include "QGCApplication.h"
#include "LinkManager.h"
#include "HomePositionManager.h"
#include "FlightMapSettings.h"
#include "MissionCommands.h"
+#include "SettingsFact.h"
#ifdef QT_DEBUG
#include "MockLink.h"
@@ -41,12 +41,14 @@
class QGCToolbox;
-class QGroundControlQmlGlobal : public QObject
+class QGroundControlQmlGlobal : public QGCTool
{
Q_OBJECT
public:
- QGroundControlQmlGlobal(QGCToolbox* toolbox, QObject* parent = NULL);
+ QGroundControlQmlGlobal(QGCApplication* app);
+ ~QGroundControlQmlGlobal();
+
Q_PROPERTY(FlightMapSettings* flightMapSettings READ flightMapSettings CONSTANT)
Q_PROPERTY(HomePositionManager* homePositionManager READ homePositionManager CONSTANT)
@@ -72,13 +74,15 @@ public:
Q_PROPERTY(bool isVersionCheckEnabled READ isVersionCheckEnabled WRITE setIsVersionCheckEnabled NOTIFY isVersionCheckEnabledChanged)
Q_PROPERTY(int mavlinkSystemID READ mavlinkSystemID WRITE setMavlinkSystemID NOTIFY mavlinkSystemIDChanged)
+ Q_PROPERTY(Fact* offlineEditingFirmwareType READ offlineEditingFirmwareType CONSTANT)
+
Q_INVOKABLE void saveGlobalSetting (const QString& key, const QString& value);
Q_INVOKABLE QString loadGlobalSetting (const QString& key, const QString& defaultValue);
Q_INVOKABLE void saveBoolGlobalSetting (const QString& key, bool value);
Q_INVOKABLE bool loadBoolGlobalSetting (const QString& key, bool defaultValue);
- Q_INVOKABLE void deleteAllSettingsNextBoot () { qgcApp()->deleteAllSettingsNextBoot(); }
- Q_INVOKABLE void clearDeleteAllSettingsNextBoot () { qgcApp()->clearDeleteAllSettingsNextBoot(); }
+ Q_INVOKABLE void deleteAllSettingsNextBoot () { _app->deleteAllSettingsNextBoot(); }
+ Q_INVOKABLE void clearDeleteAllSettingsNextBoot () { _app->clearDeleteAllSettingsNextBoot(); }
Q_INVOKABLE void startPX4MockLink (bool sendStatusText);
Q_INVOKABLE void startGenericMockLink (bool sendStatusText);
@@ -98,16 +102,18 @@ public:
qreal zOrderWidgets () { return 100; }
qreal zOrderMapItems () { return 50; }
- bool isDarkStyle () { return qgcApp()->styleIsDark(); }
- bool isAudioMuted () { return qgcApp()->toolbox()->audioOutput()->isMuted(); }
- bool isSaveLogPrompt () { return qgcApp()->promptFlightDataSave(); }
- bool isSaveLogPromptNotArmed () { return qgcApp()->promptFlightDataSaveNotArmed(); }
+ bool isDarkStyle () { return _app->styleIsDark(); }
+ bool isAudioMuted () { return _toolbox->audioOutput()->isMuted(); }
+ bool isSaveLogPrompt () { return _app->promptFlightDataSave(); }
+ bool isSaveLogPromptNotArmed () { return _app->promptFlightDataSaveNotArmed(); }
bool virtualTabletJoystick () { return _virtualTabletJoystick; }
- bool isHeartBeatEnabled () { return qgcApp()->toolbox()->mavlinkProtocol()->heartbeatsEnabled(); }
- bool isMultiplexingEnabled () { return qgcApp()->toolbox()->mavlinkProtocol()->multiplexingEnabled(); }
- bool isVersionCheckEnabled () { return qgcApp()->toolbox()->mavlinkProtocol()->versionCheckEnabled(); }
- int mavlinkSystemID () { return qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(); }
+ bool isHeartBeatEnabled () { return _toolbox->mavlinkProtocol()->heartbeatsEnabled(); }
+ bool isMultiplexingEnabled () { return _toolbox->mavlinkProtocol()->multiplexingEnabled(); }
+ bool isVersionCheckEnabled () { return _toolbox->mavlinkProtocol()->versionCheckEnabled(); }
+ int mavlinkSystemID () { return _toolbox->mavlinkProtocol()->getSystemId(); }
+
+ Fact* offlineEditingFirmwareType () { return &_offlineEditingFirmwareTypeFact; }
//-- TODO: Make this into an actual preference.
bool isAdvancedMode () { return false; }
@@ -123,6 +129,9 @@ public:
void setIsVersionCheckEnabled (bool enable);
void setMavlinkSystemID (int id);
+ // Overrides from QGCTool
+ virtual void setToolbox(QGCToolbox* toolbox);
+
signals:
void isDarkStyleChanged (bool dark);
void isAudioMutedChanged (bool muted);
@@ -144,6 +153,9 @@ private:
bool _virtualTabletJoystick;
+ SettingsFact _offlineEditingFirmwareTypeFact;
+ FactMetaData _offlineEditingFirmwareTypeMetaData;
+
static const char* _virtualTabletJoystickKey;
};
diff --git a/src/QmlControls/SubMenuButton.qml b/src/QmlControls/SubMenuButton.qml
index 05533114dbd267df9348abd948e411128d4e2216..4d4538b13205b3f06d330ce2c93b98c89894ec92 100644
--- a/src/QmlControls/SubMenuButton.qml
+++ b/src/QmlControls/SubMenuButton.qml
@@ -13,8 +13,8 @@ Button {
text: "Button" ///< Pass in your own button text
- checkable: true
- height: ScreenTools.defaultFontPixelHeight * 2.5
+ checkable: true
+ implicitHeight: ScreenTools.defaultFontPixelHeight * 2.5
style: ButtonStyle {
id: buttonStyle
@@ -30,6 +30,8 @@ Button {
id: innerRect
color: showHighlight ? qgcPal.buttonHighlight : qgcPal.windowShade
+ implicitWidth: titleBar.x + titleBar.contentWidth + ScreenTools.defaultFontPixelWidth
+
QGCColoredImage {
id: image
anchors.leftMargin: ScreenTools.defaultFontPixelWidth
diff --git a/src/VehicleSetup/SetupView.qml b/src/VehicleSetup/SetupView.qml
index 1a782466098b6f24b9072a3d470a4d1decd7f7d3..27e8c33a131e69f4cd1650d530799dba793e4f8b 100644
--- a/src/VehicleSetup/SetupView.qml
+++ b/src/VehicleSetup/SetupView.qml
@@ -213,24 +213,42 @@ Rectangle {
Flickable {
id: buttonScroll
- width: mainWindow.menuButtonWidth
+ width: buttonColumn.width
anchors.topMargin: _defaultTextHeight / 2
anchors.top: parent.top
anchors.bottom: parent.bottom
clip: true
contentHeight: buttonColumn.height
- contentWidth: parent.width
+ contentWidth: buttonColumn.width
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.VerticalFlick
Column {
id: buttonColumn
- width: mainWindow.menuButtonWidth
+ width: _maxButtonWidth
spacing: _defaultTextHeight / 2
+ property real _maxButtonWidth: 0
+
+ Component.onCompleted: reflowWidths()
+
+ Connections {
+ target: componentRepeater
+
+ onModelChanged: buttonColumn.reflowWidths()
+ }
+
+ function reflowWidths() {
+ for (var i=0; i