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..fed4ba2436e1b8dc83a761d8f48f56e78d7607c6 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 \
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/QGCApplication.cc b/src/QGCApplication.cc
index 5dc5193e93b06f674215ab302ae8480a7b3b9ae6..2ce5823e0469bf03bb79ce20a9409b2a06bf55cf 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"
@@ -378,9 +379,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/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"