Commit 27461b23 authored by Don Gagne's avatar Don Gagne

Merge pull request #2415 from tcanabrava/APMAirframesV8

Add the initial stub for the AirFrame configuration for APM
parents 46604020 ff32b9fe
...@@ -208,6 +208,9 @@ ...@@ -208,6 +208,9 @@
<file alias="AirframeFactMetaData.xml">src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml</file> <file alias="AirframeFactMetaData.xml">src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml</file>
<file alias="ParameterFactMetaData.xml">src/AutoPilotPlugins/PX4/ParameterFactMetaData.xml</file> <file alias="ParameterFactMetaData.xml">src/AutoPilotPlugins/PX4/ParameterFactMetaData.xml</file>
</qresource> </qresource>
<qresource prefix="/AutoPilotPlugins/APM">
<file alias="AirframeFactMetaData.xml">src/AutoPilotPlugins/APM/AirframeFactMetaData.xml</file>
</qresource>
<qresource prefix="/FirmwarePlugin/APM"> <qresource prefix="/FirmwarePlugin/APM">
<file alias="apm.pdef.xml">src/FirmwarePlugin/APM/apm.pdef.xml</file> <file alias="apm.pdef.xml">src/FirmwarePlugin/APM/apm.pdef.xml</file>
......
...@@ -282,7 +282,9 @@ HEADERS += \ ...@@ -282,7 +282,9 @@ HEADERS += \
src/uas/UASMessageHandler.h \ src/uas/UASMessageHandler.h \
src/ui/toolbar/MainToolBarController.h \ src/ui/toolbar/MainToolBarController.h \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \ src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \
src/AutoPilotPlugins/APM/APMAirframeLoader.h \
src/QmlControls/QGCImageProvider.h \ src/QmlControls/QGCImageProvider.h \
src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.h
DebugBuild { DebugBuild {
HEADERS += \ HEADERS += \
...@@ -398,7 +400,9 @@ SOURCES += \ ...@@ -398,7 +400,9 @@ SOURCES += \
src/uas/UASMessageHandler.cc \ src/uas/UASMessageHandler.cc \
src/ui/toolbar/MainToolBarController.cc \ src/ui/toolbar/MainToolBarController.cc \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \ src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \
src/AutoPilotPlugins/APM/APMAirframeLoader.cc \
src/QmlControls/QGCImageProvider.cc \ src/QmlControls/QGCImageProvider.cc \
src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.cc
DebugBuild { DebugBuild {
SOURCES += \ SOURCES += \
...@@ -550,6 +554,8 @@ HEADERS+= \ ...@@ -550,6 +554,8 @@ HEADERS+= \
src/AutoPilotPlugins/AutoPilotPluginManager.h \ src/AutoPilotPlugins/AutoPilotPluginManager.h \
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h \ src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h \
src/AutoPilotPlugins/APM/APMAirframeComponent.h \ src/AutoPilotPlugins/APM/APMAirframeComponent.h \
src/AutoPilotPlugins/APM/APMAirframeComponentController.h \
src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.h \
src/AutoPilotPlugins/APM/APMComponent.h \ src/AutoPilotPlugins/APM/APMComponent.h \
src/AutoPilotPlugins/APM/APMRadioComponent.h \ src/AutoPilotPlugins/APM/APMRadioComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponent.h \ src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
...@@ -601,6 +607,7 @@ SOURCES += \ ...@@ -601,6 +607,7 @@ SOURCES += \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \ src/AutoPilotPlugins/AutoPilotPluginManager.cc \
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc \ src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc \
src/AutoPilotPlugins/APM/APMAirframeComponent.cc \ src/AutoPilotPlugins/APM/APMAirframeComponent.cc \
src/AutoPilotPlugins/APM/APMAirframeComponentController.cc \
src/AutoPilotPlugins/APM/APMComponent.cc \ src/AutoPilotPlugins/APM/APMComponent.cc \
src/AutoPilotPlugins/APM/APMRadioComponent.cc \ src/AutoPilotPlugins/APM/APMRadioComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \ src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
...@@ -610,6 +617,7 @@ SOURCES += \ ...@@ -610,6 +617,7 @@ SOURCES += \
src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \ src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \
src/AutoPilotPlugins/APM/APMTuningComponent.cc \ src/AutoPilotPlugins/APM/APMTuningComponent.cc \
src/AutoPilotPlugins/Common/RadioComponentController.cc \ src/AutoPilotPlugins/Common/RadioComponentController.cc \
src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \ src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \ src/AutoPilotPlugins/PX4/AirframeComponent.cc \
src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc \ src/AutoPilotPlugins/PX4/AirframeComponentAirframes.cc \
......
...@@ -57,22 +57,13 @@ bool APMAirframeComponent::requiresSetup(void) const ...@@ -57,22 +57,13 @@ bool APMAirframeComponent::requiresSetup(void) const
bool APMAirframeComponent::setupComplete(void) const bool APMAirframeComponent::setupComplete(void) const
{ {
// You'll need to figure out which parameters trigger setup complete //: Not the correct one, but it works for the moment.
#if 0 return _autopilot->getParameterFact(FactSystem::defaultComponentId, "FRAME")->rawValue().toInt() != -1;
return _autopilot->getParameterFact(FactSystem::defaultComponentId, "SYS_AUTOSTART")->rawValue().toInt() != 0;
#else
return true;
#endif
} }
QStringList APMAirframeComponent::setupCompleteChangedTriggerList(void) const 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(); return QStringList();
#endif
} }
QUrl APMAirframeComponent::setupSource(void) const QUrl APMAirframeComponent::setupSource(void) const
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
======================================================================*/ ======================================================================*/
import QtQuick 2.2 import QtQuick 2.5
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2 import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
...@@ -39,13 +39,214 @@ QGCView { ...@@ -39,13 +39,214 @@ QGCView {
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled } 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 { QGCViewPanel {
id: panel id: panel
anchors.fill: parent anchors.fill: parent
QGCLabel { readonly property real spacerHeight: ScreenTools.defaultFontPixelHeight
text: "Work in progress";
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 } // QGCViewPanel
} // QGCView } // QGCView
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "APMAirframeComponentAirframes.h"
#include "APMAirframeComponentController.h"
QMap<QString, APMAirframeComponentAirframes::AirframeType_t*> APMAirframeComponentAirframes::rgAirframeTypes;
QMap<QString, APMAirframeComponentAirframes::AirframeType_t*>& 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<AirframeType_t*> valueList = get().values();
foreach(AirframeType_t *pType, valueList) {
qDeleteAll(pType->rgAirframeInfo);
delete pType;
}
rgAirframeTypes.clear();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef APMAirframeComponentAirframes_H
#define APMAirframeComponentAirframes_H
#include <QObject>
#include <QQuickItem>
#include <QList>
#include <QMap>
#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<APMAirframe*> rgAirframeInfo;
} AirframeType_t;
typedef QMap<QString, AirframeType_t*> 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
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "APMAirframeComponentController.h"
#include "APMAirframeComponentAirframes.h"
#include "APMRemoteParamsDownloader.h"
#include "QGCMAVLink.h"
#include "MultiVehicleManager.h"
#include "AutoPilotPluginManager.h"
#include "QGCApplication.h"
#include <QVariant>
#include <QQmlProperty>
bool APMAirframeComponentController::_typesRegistered = false;
APMAirframeComponentController::APMAirframeComponentController(void) :
_airframeTypesModel(new QmlObjectListModel(this))
{
if (!_typesRegistered) {
_typesRegistered = true;
qmlRegisterUncreatableType<APMAirframeType>("QGroundControl.Controllers", 1, 0, "APMAiframeType", "Can only reference APMAirframeType");
qmlRegisterUncreatableType<APMAirframe>("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<APMAirframeType*>(_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(&parametersFile);
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());
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef APMAirframeComponentController_H
#define APMAirframeComponentController_H
#include <QObject>
#include <QQuickItem>
#include <QList>
#include <QAbstractListModel>
#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
...@@ -13,33 +13,27 @@ FactPanel { ...@@ -13,33 +13,27 @@ FactPanel {
color: qgcPal.windowShadeDark color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled } QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
APMAirframeComponentController {
id: controller
factPanel: panel
}
/* property Fact sysIdFact: controller.getParameterFact(-1, "FRAME")
property Fact sysIdFact: controller.getParameterFact(-1, "MAV_SYS_ID")
property Fact sysAutoStartFact: controller.getParameterFact(-1, "SYS_AUTOSTART")
property bool autoStartSet: sysAutoStartFact.value != 0
*/
Column { Column {
anchors.fill: parent anchors.fill: parent
anchors.margins: 8 anchors.margins: 8
/*
VehicleSummaryRow {
labelText: "System ID:"
valueText: sysIdFact.valueString
}
VehicleSummaryRow { VehicleSummaryRow {
labelText: "Airframe type:" id: nameRow;
valueText: autoStartSet ? controller.currentAirframeType : "Setup required" 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"
} }
*/
} }
} }
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "APMAirframeLoader.h"
#include "QGCApplication.h"
#include "QGCLoggingCategory.h"
#include "APMAirframeComponentAirframes.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QDebug>
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;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef APMAirframeLoader_H
#define APMAirframeLoader_H
#include <QObject>
#include <QMap>
#include <QXmlStreamReader>
#include <QLoggingCategory>
#include "ParameterLoader.h"
#include "FactSystem.h"
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
/// @file APMAirframeLoader.h
/// @author Lorenz Meier <lm@qgroundcontrol.org>
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<QString, FactMetaData*> _mapParameterName2FactMetaData; ///< Maps from a parameter name to FactMetaData
};
#endif // APMAirframeLoader_H
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
#include "APMAutoPilotPlugin.h" #include "APMAutoPilotPlugin.h"
...@@ -26,6 +26,18 @@ ...@@ -26,6 +26,18 @@
#include "UAS.h" #include "UAS.h"
#include "FirmwarePlugin/APM/APMParameterMetaData.h" // FIXME: Hack #include "FirmwarePlugin/APM/APMParameterMetaData.h" // FIXME: Hack
#include "FirmwarePlugin/APM/APMFirmwarePlugin.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. /// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent) APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
...@@ -37,8 +49,9 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent) ...@@ -37,8 +49,9 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
, _safetyComponent(NULL) , _safetyComponent(NULL)
, _sensorsComponent(NULL) , _sensorsComponent(NULL)
, _tuningComponent(NULL) , _tuningComponent(NULL)
, _airframeFacts(new APMAirframeLoader(this, vehicle->uas(), this))
{ {
Q_ASSERT(vehicle); APMAirframeLoader::loadAirframeFactMetaData();
} }
APMAutoPilotPlugin::~APMAutoPilotPlugin() APMAutoPilotPlugin::~APMAutoPilotPlugin()
...@@ -52,12 +65,14 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void) ...@@ -52,12 +65,14 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
Q_ASSERT(_vehicle); Q_ASSERT(_vehicle);
if (parametersReady()) { if (parametersReady()) {
_airframeComponent = new APMAirframeComponent(_vehicle, this); if (dynamic_cast<ArduCopterFirmwarePlugin*>(_vehicle->firmwarePlugin())){
if (_airframeComponent) { _airframeComponent = new APMAirframeComponent(_vehicle, this);
_airframeComponent->setupTriggerSignals(); if(_airframeComponent) {
_components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent)); _airframeComponent->setupTriggerSignals();
} else { _components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
qWarning() << "new APMAirframeComponent failed"; } else {
qWarning() << "new APMAirframeComponent failed";
}
} }
_flightModesComponent = new APMFlightModesComponent(_vehicle, this); _flightModesComponent = new APMFlightModesComponent(_vehicle, this);
...@@ -122,9 +137,9 @@ void APMAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters) ...@@ -122,9 +137,9 @@ void APMAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters)
"Please perform a Firmware Upgrade if you wish to use Vehicle Setup."); "Please perform a Firmware Upgrade if you wish to use Vehicle Setup.");
} }
#endif #endif
Q_UNUSED(missingParameters);
_parametersReady = true; _parametersReady = true;
_missingParameters = missingParameters; _missingParameters = false; // we apply only the parameters that do exists on the FactSystem.
emit missingParametersChanged(_missingParameters); emit missingParametersChanged(_missingParameters);
emit parametersReadyChanged(_parametersReady); emit parametersReadyChanged(_parametersReady);
} }
...@@ -26,12 +26,14 @@ ...@@ -26,12 +26,14 @@
#include "AutoPilotPlugin.h" #include "AutoPilotPlugin.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "APMAirframeComponent.h"
#include "APMFlightModesComponent.h" class APMAirframeComponent;
#include "APMRadioComponent.h" class APMAirframeLoader;
#include "APMSafetyComponent.h" class APMFlightModesComponent;
#include "APMSensorsComponent.h" class APMRadioComponent;
#include "APMTuningComponent.h" class APMTuningComponent;
class APMSafetyComponent;
class APMSensorsComponent;
/// This is the APM specific implementation of the AutoPilot class. /// This is the APM specific implementation of the AutoPilot class.
class APMAutoPilotPlugin : public AutoPilotPlugin class APMAutoPilotPlugin : public AutoPilotPlugin
...@@ -66,6 +68,7 @@ private: ...@@ -66,6 +68,7 @@ private:
APMSafetyComponent* _safetyComponent; APMSafetyComponent* _safetyComponent;
APMSensorsComponent* _sensorsComponent; APMSensorsComponent* _sensorsComponent;
APMTuningComponent* _tuningComponent; APMTuningComponent* _tuningComponent;
APMAirframeLoader* _airframeFacts;
}; };
#endif #endif
...@@ -37,10 +37,8 @@ APMComponent::APMComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject ...@@ -37,10 +37,8 @@ APMComponent::APMComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject
void APMComponent::setupTriggerSignals(void) void APMComponent::setupTriggerSignals(void)
{ {
// Watch for changed on trigger list params foreach (const QString& paramName, setupCompleteChangedTriggerList()) {
foreach (QString paramName, setupCompleteChangedTriggerList()) {
Fact* fact = _autopilot->getParameterFact(FactSystem::defaultComponentId, paramName); Fact* fact = _autopilot->getParameterFact(FactSystem::defaultComponentId, paramName);
connect(fact, &Fact::valueChanged, this, &APMComponent::_triggerUpdated); connect(fact, &Fact::valueChanged, this, &APMComponent::_triggerUpdated);
} }
} }
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "APMFlightModesComponent.h" #include "APMFlightModesComponent.h"
#include "APMAutoPilotPlugin.h" #include "APMAutoPilotPlugin.h"
#include "APMAirframeComponent.h"
#include "APMRadioComponent.h"
APMFlightModesComponent::APMFlightModesComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) : APMFlightModesComponent::APMFlightModesComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
APMComponent(vehicle, autopilot, parent), APMComponent(vehicle, autopilot, parent),
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "APMRadioComponent.h" #include "APMRadioComponent.h"
#include "APMAutoPilotPlugin.h" #include "APMAutoPilotPlugin.h"
#include "APMAirframeComponent.h"
APMRadioComponent::APMRadioComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) : APMRadioComponent::APMRadioComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
APMComponent(vehicle, autopilot, parent), APMComponent(vehicle, autopilot, parent),
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#include "APMRemoteParamsDownloader.h"
#include <QMessageBox>
#include <QDesktopServices>
#include <QFile>
#include <QFileDialog>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QCryptographicHash>
#include <QApplication>
#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();
}
#ifndef APMREMOTEPARAMSCONTROLLER_H
#define APMREMOTEPARAMSCONTROLLER_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QJsonArray>
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
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "APMSafetyComponent.h" #include "APMSafetyComponent.h"
#include "QGCQmlWidgetHolder.h" #include "QGCQmlWidgetHolder.h"
#include "APMAutoPilotPlugin.h" #include "APMAutoPilotPlugin.h"
#include "APMAirframeComponent.h"
APMSafetyComponent::APMSafetyComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) APMSafetyComponent::APMSafetyComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
: APMComponent(vehicle, autopilot, parent) : APMComponent(vehicle, autopilot, parent)
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "APMSensorsComponent.h" #include "APMSensorsComponent.h"
#include "APMAutoPilotPlugin.h" #include "APMAutoPilotPlugin.h"
#include "APMSensorsComponentController.h" #include "APMSensorsComponentController.h"
#include "APMAirframeComponent.h"
// These two list must be kept in sync // These two list must be kept in sync
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "APMTuningComponent.h" #include "APMTuningComponent.h"
#include "APMAutoPilotPlugin.h" #include "APMAutoPilotPlugin.h"
#include "APMAirframeComponent.h"
APMTuningComponent::APMTuningComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) APMTuningComponent::APMTuningComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent)
: APMComponent(vehicle, autopilot, parent) : APMComponent(vehicle, autopilot, parent)
......
<?xml version='1.0' encoding='UTF-8'?>
<airframes>
<version>1</version>
<airframe_group image="AirframeQuadRotorPlus.png" name="Plus Style" id="0">
<airframe name="3DR Aero M" file="3DR_AERO_M.param"/>
<airframe name="3DR Aero RTF" file="3DR_Aero_RTF.param"/>
<airframe name="3DR Rover" file="3DR_Rover.param"/>
<airframe name="3DR Tarot" file="3DR_Tarot.bgsc"/>
<airframe name="Parrot Bebop" file="Parrot_Bebop.param"/>
<airframe name="Storm32" file="SToRM32-MAVLink.param"/>
</airframe_group>
<airframe_group image="AirframeQuadRotorX.png" name="X Style" id="1">
<airframe name="3DR X8-M RTF" file="3DR_X8-M_RTF.param"/>
<airframe name="3DR Y6A" file="3DR_Y6A_RTF.param"/>
<airframe name="3DR X8+ RTF" file="3DR_X8+_RTF.param"/>
<airframe name="3DR QUAD X4 RTF" file="3DR_QUAD_X4_RTF.param"/>
<airframe name="3DR X8" file="3DR_X8_RTF.param"/>
</airframe_group>
<airframe_group image="AirframeSimulation.png" name="V Style" id="2">
<airframe name="Iris with GoPro" file="Iris with Front Mount Go Pro.param"/>
<airframe name="Iris with Tarot" file="Iris with Tarot Gimbal.param"/>
<airframe name="3DR Iris+" file="3DR_Iris+.param"/>
<airframe name="Iris" file="Iris.param"/>
</airframe_group>
<airframe_group image="AirframeQuadRotorH.png" name="H Style" id="3">
</airframe_group>
<airframe_group image="AirframeHexaRotorX.png" name="Y6B" id="10">
<airframe name="3DR Y6B" file="3DR_Y6B_RTF.param"/>
</airframe_group>
<airframes>
This diff is collapsed.
...@@ -77,6 +77,7 @@ ...@@ -77,6 +77,7 @@
#include "APM/ArduCopterFirmwarePlugin.h" #include "APM/ArduCopterFirmwarePlugin.h"
#include "APM/ArduPlaneFirmwarePlugin.h" #include "APM/ArduPlaneFirmwarePlugin.h"
#include "APM/ArduRoverFirmwarePlugin.h" #include "APM/ArduRoverFirmwarePlugin.h"
#include "APM/APMAirframeComponentController.h"
#include "PX4/PX4FirmwarePlugin.h" #include "PX4/PX4FirmwarePlugin.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "MavlinkQmlSingleton.h" #include "MavlinkQmlSingleton.h"
...@@ -378,9 +379,10 @@ void QGCApplication::_initCommon(void) ...@@ -378,9 +379,10 @@ void QGCApplication::_initCommon(void)
qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only"); qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only"); qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");
qmlRegisterType<ParameterEditorController> ("QGroundControl.Controllers", 1, 0, "ParameterEditorController"); qmlRegisterType<ParameterEditorController> ("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
qmlRegisterType<APMFlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "APMFlightModesComponentController"); qmlRegisterType<APMFlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "APMFlightModesComponentController");
qmlRegisterType<FlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController"); qmlRegisterType<FlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController");
qmlRegisterType<APMAirframeComponentController> ("QGroundControl.Controllers", 1, 0, "APMAirframeComponentController");
qmlRegisterType<AirframeComponentController> ("QGroundControl.Controllers", 1, 0, "AirframeComponentController"); qmlRegisterType<AirframeComponentController> ("QGroundControl.Controllers", 1, 0, "AirframeComponentController");
qmlRegisterType<APMSensorsComponentController> ("QGroundControl.Controllers", 1, 0, "APMSensorsComponentController"); qmlRegisterType<APMSensorsComponentController> ("QGroundControl.Controllers", 1, 0, "APMSensorsComponentController");
qmlRegisterType<SensorsComponentController> ("QGroundControl.Controllers", 1, 0, "SensorsComponentController"); qmlRegisterType<SensorsComponentController> ("QGroundControl.Controllers", 1, 0, "SensorsComponentController");
......
...@@ -96,7 +96,7 @@ FactPanel { ...@@ -96,7 +96,7 @@ FactPanel {
__rejectButton.text = "Cancel" __rejectButton.text = "Cancel"
__rejectButton.visible = true __rejectButton.visible = true
} else if (buttons & StandardButton.Close) { } else if (buttons & StandardButton.Close) {
__rejectButton.text = "Cancel" __rejectButton.text = "Close"
__rejectButton.visible = true __rejectButton.visible = true
} else if (buttons & StandardButton.No) { } else if (buttons & StandardButton.No) {
__rejectButton.text = "No" __rejectButton.text = "No"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment