Commit 57d0292d authored by DonLakeFlyer's avatar DonLakeFlyer

parent a32d84f8
...@@ -6,6 +6,7 @@ Note: This file only contains high level features or important fixes. ...@@ -6,6 +6,7 @@ Note: This file only contains high level features or important fixes.
### 3.6.0 - Daily Build ### 3.6.0 - Daily Build
* ArduPilot: Rework Airframe setup ui
* Plan/Pattern: Support named presets to simplify commonly used settings setup. Currently only supported by Survey. * Plan/Pattern: Support named presets to simplify commonly used settings setup. Currently only supported by Survey.
* ArduCopter: Handle 3.7 parameter name change from CH#_OPT to RC#_OPTION. * ArduCopter: Handle 3.7 parameter name change from CH#_OPT to RC#_OPTION.
* Improved support for flashing/connecting to ChibiOS bootloaders boards. * Improved support for flashing/connecting to ChibiOS bootloaders boards.
......
...@@ -984,9 +984,7 @@ APMFirmwarePlugin { ...@@ -984,9 +984,7 @@ APMFirmwarePlugin {
HEADERS += \ HEADERS += \
src/AutoPilotPlugins/APM/APMAirframeComponent.h \ src/AutoPilotPlugins/APM/APMAirframeComponent.h \
src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.h \
src/AutoPilotPlugins/APM/APMAirframeComponentController.h \ src/AutoPilotPlugins/APM/APMAirframeComponentController.h \
src/AutoPilotPlugins/APM/APMAirframeLoader.h \
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h \ src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h \
src/AutoPilotPlugins/APM/APMCameraComponent.h \ src/AutoPilotPlugins/APM/APMCameraComponent.h \
src/AutoPilotPlugins/APM/APMCompassCal.h \ src/AutoPilotPlugins/APM/APMCompassCal.h \
...@@ -1011,9 +1009,7 @@ APMFirmwarePlugin { ...@@ -1011,9 +1009,7 @@ APMFirmwarePlugin {
SOURCES += \ SOURCES += \
src/AutoPilotPlugins/APM/APMAirframeComponent.cc \ src/AutoPilotPlugins/APM/APMAirframeComponent.cc \
src/AutoPilotPlugins/APM/APMAirframeComponentAirframes.cc \
src/AutoPilotPlugins/APM/APMAirframeComponentController.cc \ src/AutoPilotPlugins/APM/APMAirframeComponentController.cc \
src/AutoPilotPlugins/APM/APMAirframeLoader.cc \
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc \ src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc \
src/AutoPilotPlugins/APM/APMCameraComponent.cc \ src/AutoPilotPlugins/APM/APMCameraComponent.cc \
src/AutoPilotPlugins/APM/APMCompassCal.cc \ src/AutoPilotPlugins/APM/APMCompassCal.cc \
......
...@@ -22,90 +22,155 @@ import QGroundControl.ScreenTools 1.0 ...@@ -22,90 +22,155 @@ import QGroundControl.ScreenTools 1.0
SetupPage { SetupPage {
id: airframePage id: airframePage
pageComponent: _useOldFrameParam ? oldFramePageComponent: newFramePageComponent pageComponent: pageComponent
property real _margins: ScreenTools.defaultFontPixelWidth
property bool _useOldFrameParam: controller.parameterExists(-1, "FRAME")
property Fact _oldFrameParam: controller.getParameterFact(-1, "FRAME", false)
property Fact _newFrameParam: controller.getParameterFact(-1, "FRAME_CLASS", false)
property Fact _frameTypeParam: controller.getParameterFact(-1, "FRAME_TYPE", false)
APMAirframeComponentController {
id: controller
factPanel: airframePage.viewPanel
}
ExclusiveGroup {
id: airframeTypeExclusive
}
Component { Component {
id: oldFramePageComponent id: pageComponent
Column { ColumnLayout {
width: availableWidth id: mainColumn
height: 1000 width: availableWidth
spacing: _margins
property real _minW: ScreenTools.defaultFontPixelWidth * 20
RowLayout { property real _boxWidth: _minW
anchors.left: parent.left property real _boxSpace: ScreenTools.defaultFontPixelWidth
anchors.right: parent.right property real _margins: ScreenTools.defaultFontPixelWidth
spacing: _margins property Fact _frameClass: controller.getParameterFact(-1, "FRAME_CLASS")
property Fact _frameType: controller.getParameterFact(-1, "FRAME_TYPE")
QGCLabel {
font.pointSize: ScreenTools.mediumFontPointSize readonly property real spacerHeight: ScreenTools.defaultFontPixelHeight
wrapMode: Text.WordWrap
text: qsTr("Please select your airframe type") onWidthChanged: computeDimensions()
Layout.fillWidth: true Component.onCompleted: computeDimensions()
function computeDimensions() {
var sw = 0
var rw = 0
var idx = Math.floor(mainColumn.width / (_minW + ScreenTools.defaultFontPixelWidth))
if(idx < 1) {
_boxWidth = mainColumn.width
_boxSpace = 0
} else {
_boxSpace = 0
if(idx > 1) {
_boxSpace = ScreenTools.defaultFontPixelWidth
sw = _boxSpace * (idx - 1)
}
rw = mainColumn.width - sw
_boxWidth = rw / idx
} }
} }
Repeater { APMAirframeComponentController {
model: controller.airframeTypesModel id: controller
factPanel: airframePage.viewPanel
}
QGCRadioButton { QGCLabel {
text: object.name id: helpText
checked: controller.currentAirframeType == object Layout.fillWidth: true
exclusiveGroup: airframeTypeExclusive text: (_frameClass.rawValue === 0 ?
qsTr("Airframe is currently not set.") :
qsTr("Currently set to frame class '%1' and frame type '%2'.").arg(_frameClass.enumStringValue).arg(_frameType.enumStringValue)) +
qsTr(" To change this configuration, select the desired frame class below and frame type.")
font.family: ScreenTools.demiboldFontFamily
wrapMode: Text.WordWrap
}
onCheckedChanged: { Item {
if (checked) { id: lastSpacer
controller.currentAirframeType = object height: parent.spacerHeight
} width: 10
}
}
} }
} // Column
} // Component - oldFramePageComponent
Component { Flow {
id: newFramePageComponent id: flowView
Layout.fillWidth: true
spacing: _boxSpace
Grid { ExclusiveGroup {
width: availableWidth id: airframeTypeExclusive
spacing: _margins }
columns: 2
QGCLabel { Repeater {
text: qsTr("Frame Class:") model: controller.frameClassModel
}
FactComboBox { // Outer summary item rectangle
fact: _newFrameParam Rectangle {
indexModel: false id: outerRect
width: ScreenTools.defaultFontPixelWidth * 15 width: _boxWidth
} height: ScreenTools.defaultFontPixelHeight * 14
color: qgcPal.window
QGCLabel { readonly property real titleHeight: ScreenTools.defaultFontPixelHeight * 1.75
text: qsTr("Frame Type:") readonly property real innerMargin: ScreenTools.defaultFontPixelWidth
}
FactComboBox { MouseArea {
fact: _frameTypeParam anchors.fill: parent
indexModel: false onClicked: airframeCheckBox.checked = true
width: ScreenTools.defaultFontPixelWidth * 15 }
}
} QGCLabel {
} id: title
text: object.name
}
Rectangle {
anchors.topMargin: ScreenTools.defaultFontPixelHeight / 2
anchors.top: title.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
color: airframeCheckBox.checked ? qgcPal.buttonHighlight : qgcPal.windowShade
ColumnLayout {
anchors.margins: innerMargin
anchors.fill: parent
spacing: innerMargin
Image {
id: image
Layout.fillWidth: true
Layout.fillHeight: true
fillMode: Image.PreserveAspectFit
smooth: true
mipmap: true
source: object.imageResource
}
QGCCheckBox {
// Although this item is invisible we still use it to manage state
id: airframeCheckBox
checked: object.frameClass === _frameClass.rawValue
exclusiveGroup: airframeTypeExclusive
visible: false
onCheckedChanged: {
if (checked) {
_frameClass.rawValue = object.frameClass
}
}
}
QGCLabel {
text: qsTr("Frame Type")
font.pointSize: ScreenTools.smallFontPointSize
color: qgcPal.buttonHighlightText
visible: airframeCheckBox.checked && object.frameTypeSupported
}
FactComboBox {
id: combo
Layout.fillWidth: true
fact: _frameType
indexModel: false
visible: airframeCheckBox.checked && object.frameTypeSupported
}
}
}
}
} // Repeater - summary boxes
} // Flow - summary boxes
} // Column
} // Component
} // SetupPage } // SetupPage
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
/// @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 = image.isEmpty() ? QString() : QStringLiteral("qrc:/qmlimages/") + image;
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();
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
/// @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
...@@ -7,12 +7,7 @@ ...@@ -7,12 +7,7 @@
* *
****************************************************************************/ ****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "APMAirframeComponentController.h" #include "APMAirframeComponentController.h"
#include "APMAirframeComponentAirframes.h"
#include "QGCMAVLink.h" #include "QGCMAVLink.h"
#include "MultiVehicleManager.h" #include "MultiVehicleManager.h"
#include "QGCApplication.h" #include "QGCApplication.h"
...@@ -26,71 +21,113 @@ ...@@ -26,71 +21,113 @@
#include <QJsonParseError> #include <QJsonParseError>
#include <QJsonObject> #include <QJsonObject>
bool APMAirframeComponentController::_typesRegistered = false;
const char* APMAirframeComponentController::_oldFrameParam = "FRAME";
const char* APMAirframeComponentController::_newFrameParam = "FRAME_CLASS";
APMAirframeComponentController::APMAirframeComponentController(void) : // These should match the FRAME_CLASS parameter enum meta data
_airframeTypesModel(new QmlObjectListModel(this)) #define FRAME_CLASS_UNDEFINED 0
{ #define FRAME_CLASS_QUAD 1
if (!_typesRegistered) { #define FRAME_CLASS_HEX 2
_typesRegistered = true; #define FRAME_CLASS_OCTA 3
qmlRegisterUncreatableType<APMAirframeType>("QGroundControl.Controllers", 1, 0, "APMAirframeType", QStringLiteral("Can only reference APMAirframeType")); #define FRAME_CLASS_OCTAQUAD 4
} #define FRAME_CLASS_Y6 5
_fillAirFrames(); #define FRAME_CLASS_HELI 6
#define FRAME_CLASS_TRI 7
Fact* frame = NULL; #define FRAME_CLASS_SINGLECOPTER 8
if (parameterExists(FactSystem::defaultComponentId, _oldFrameParam)) { #define FRAME_CLASS_COAXCOPTER 9
frame = getParameterFact(FactSystem::defaultComponentId, _oldFrameParam); #define FRAME_CLASS_BICOPTER 10
} else if (parameterExists(FactSystem::defaultComponentId, _newFrameParam)){ #define FRAME_CLASS_HELI_DUAL 11
frame = getParameterFact(FactSystem::defaultComponentId, _newFrameParam); #define FRAME_CLASS_DODECAHEXA 12
#define FRAME_CLASS_HELIQUAD 13
// These should match the FRAME_TYPE parameter enum meta data
#define FRAME_TYPE_PLUS 0
#define FRAME_TYPE_X 1
#define FRAME_TYPE_V 2
#define FRAME_TYPE_H 3
#define FRAME_TYPE_V_TAIL 4
#define FRAME_TYPE_A_TAIL 5
#define FRAME_TYPE_Y6B 10
#define FRAME_TYPE_Y6F 11
#define FRAME_TYPE_BETAFLIGHTX 12
#define FRAME_TYPE_DJIX 13
#define FRAME_TYPE_CLOCKWISEX 14
typedef struct {
int frameClass;
int frameType;
const char* imageResource;
} FrameToImageInfo_t;
static const FrameToImageInfo_t s_rgFrameToImage[] = {
{ FRAME_CLASS_QUAD, FRAME_TYPE_PLUS, "QuadRotorPlus" },
{ FRAME_CLASS_QUAD, FRAME_TYPE_X, "QuadRotorX" },
{ FRAME_CLASS_QUAD, FRAME_TYPE_V, "QuadRotorWide" },
{ FRAME_CLASS_QUAD, FRAME_TYPE_H, "QuadRotorH" },
{ FRAME_CLASS_QUAD, FRAME_TYPE_V_TAIL, "QuadRotorVTail" },
{ FRAME_CLASS_QUAD, FRAME_TYPE_A_TAIL, "QuadRotorATail" },
{ FRAME_CLASS_HEX, FRAME_TYPE_PLUS, "HexaRotorPlus" },
{ FRAME_CLASS_HEX, FRAME_TYPE_X, "HexaRotorX" },
{ FRAME_CLASS_OCTA, FRAME_TYPE_PLUS, "OctoRotorPlus" },
{ FRAME_CLASS_OCTA, FRAME_TYPE_X, "OctoRotorX" },
{ FRAME_CLASS_OCTAQUAD, FRAME_TYPE_PLUS, "OctoRotorPlusCoaxial" },
{ FRAME_CLASS_OCTAQUAD, FRAME_TYPE_X, "OctoRotorXCoaxial" },
{ FRAME_CLASS_Y6, FRAME_TYPE_Y6B, "Y6B" },
{ FRAME_CLASS_Y6, FRAME_TYPE_Y6F, "AirframeUnknown" },
{ FRAME_CLASS_Y6, -1, "Y6A" },
{ FRAME_CLASS_HELI, -1, "Helicopter" },
{ FRAME_CLASS_TRI, -1, "YPlus" },
};
static QString s_findImageResource(int frameClass, int frameType)
{
for (size_t i=0; i<sizeof(s_rgFrameToImage)/sizeof(s_rgFrameToImage[0]); i++) {
const FrameToImageInfo_t* pFrameToImageInfo = &s_rgFrameToImage[i];
if (pFrameToImageInfo->frameClass == frameClass && pFrameToImageInfo->frameType == frameType) {
return pFrameToImageInfo->imageResource;
} else if (pFrameToImageInfo->frameClass == frameClass && pFrameToImageInfo->frameType == -1) {
return pFrameToImageInfo->imageResource;
}
} }
if (frame) { return QStringLiteral("AirframeUnknown");
connect(frame, &Fact::rawValueChanged, this, &APMAirframeComponentController::_factFrameChanged);
_factFrameChanged(frame->rawValue());
}
} }
APMAirframeComponentController::~APMAirframeComponentController() APMAirframeComponentController::APMAirframeComponentController(void)
: _frameClassFact (getParameterFact(FactSystem::defaultComponentId, QStringLiteral("FRAME_CLASS")))
, _frameTypeFact (getParameterFact(FactSystem::defaultComponentId, QStringLiteral("FRAME_TYPE")))
, _frameClassModel (new QmlObjectListModel(this))
{ {
_fillFrameClasses();
} }
void APMAirframeComponentController::_factFrameChanged(QVariant value) APMAirframeComponentController::~APMAirframeComponentController()
{ {
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() void APMAirframeComponentController::_fillFrameClasses()
{ {
for (int tindex = 0; tindex < APMAirframeComponentAirframes::get().count(); tindex++) { QList<int> frameTypeNotSupported;
const APMAirframeComponentAirframes::AirframeType_t* pType = APMAirframeComponentAirframes::get().values().at(tindex);
APMAirframeType* airframeType = new APMAirframeType(pType->name, pType->imageResource, pType->type, this); frameTypeNotSupported << FRAME_CLASS_HELI
Q_CHECK_PTR(airframeType); << FRAME_CLASS_SINGLECOPTER
<< FRAME_CLASS_COAXCOPTER
<< FRAME_CLASS_BICOPTER
<< FRAME_CLASS_HELI_DUAL
<< FRAME_CLASS_HELIQUAD;
for (int index = 0; index < pType->rgAirframeInfo.count(); index++) { for (int i=1; i<_frameClassFact->enumStrings().count(); i++) {
const APMAirframe* pInfo = pType->rgAirframeInfo.at(index); QString frameClassName = _frameClassFact->enumStrings()[i];
Q_CHECK_PTR(pInfo); int frameClass = _frameClassFact->enumValues()[i].toInt();
int defaultFrameType;
airframeType->addAirframe(pInfo->name(), pInfo->params(), pInfo->type()); if (frameTypeNotSupported.contains(frameClass)) {
defaultFrameType = -1;
} else {
defaultFrameType = FRAME_TYPE_X;
} }
_airframeTypesModel->append(airframeType); _frameClassModel->append(new APMFrameClass(frameClassName, frameClass, _frameTypeFact, defaultFrameType, _frameClassModel));
} }
emit loadAirframesCompleted();
} }
void APMAirframeComponentController::_loadParametersFromDownloadFile(const QString& downloadedParamFile) void APMAirframeComponentController::_loadParametersFromDownloadFile(const QString& downloadedParamFile)
...@@ -120,86 +157,6 @@ void APMAirframeComponentController::_loadParametersFromDownloadFile(const QStri ...@@ -120,86 +157,6 @@ void APMAirframeComponentController::_loadParametersFromDownloadFile(const QStri
_vehicle->parameterManager()->refreshAllParameters(); _vehicle->parameterManager()->refreshAllParameters();
} }
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;
}
QString APMAirframeComponentController::currentAirframeTypeName() const
{
return _vehicle->vehicleTypeName();
}
void APMAirframeComponentController::setCurrentAirframeType(APMAirframeType *t)
{
Fact *param = getParameterFact(-1, QStringLiteral("FRAME"));
Q_ASSERT(param);
param->setRawValue(t->type());
}
void APMAirframeComponentController::loadParameters(const QString& paramFile) void APMAirframeComponentController::loadParameters(const QString& paramFile)
{ {
qgcApp()->setOverrideCursor(Qt::WaitCursor); qgcApp()->setOverrideCursor(Qt::WaitCursor);
...@@ -258,3 +215,25 @@ void APMAirframeComponentController::_paramFileDownloadError(QString errorMsg) ...@@ -258,3 +215,25 @@ void APMAirframeComponentController::_paramFileDownloadError(QString errorMsg)
qgcApp()->showMessage(tr("Param file download failed: %1").arg(errorMsg)); qgcApp()->showMessage(tr("Param file download failed: %1").arg(errorMsg));
qgcApp()->restoreOverrideCursor(); qgcApp()->restoreOverrideCursor();
} }
APMFrameClass::APMFrameClass(const QString& name, int frameClass, Fact* frameTypeFact, int defaultFrameType, QObject* parent)
: QObject (parent)
, _name (name)
, _frameClass (frameClass)
, _defaultFrameType (defaultFrameType)
, _frameTypeSupported (defaultFrameType != -1)
, _frameTypeFact (frameTypeFact)
{
connect(frameTypeFact, &Fact::rawValueChanged, this, &APMFrameClass::imageResourceChanged);
connect(frameTypeFact, &Fact::rawValueChanged, this, &APMFrameClass::frameTypeChanged);
}
APMFrameClass::~APMFrameClass()
{
}
QString APMFrameClass::imageResource(void)
{
return QStringLiteral("/qmlimages/Airframe/%1").arg(s_findImageResource(_frameClass, _frameTypeFact->rawValue().toInt()));
}
...@@ -7,12 +7,7 @@ ...@@ -7,12 +7,7 @@
* *
****************************************************************************/ ****************************************************************************/
#pragma once
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef APMAirframeComponentController_H
#define APMAirframeComponentController_H
#include <QObject> #include <QObject>
#include <QQuickItem> #include <QQuickItem>
...@@ -22,7 +17,6 @@ ...@@ -22,7 +17,6 @@
#include "UASInterface.h" #include "UASInterface.h"
#include "AutoPilotPlugin.h" #include "AutoPilotPlugin.h"
#include "FactPanelController.h" #include "FactPanelController.h"
#include "APMAirframeComponentAirframes.h"
class APMAirframeModel; class APMAirframeModel;
class APMAirframeType; class APMAirframeType;
...@@ -33,98 +27,56 @@ class APMAirframeComponentController : public FactPanelController ...@@ -33,98 +27,56 @@ class APMAirframeComponentController : public FactPanelController
Q_OBJECT Q_OBJECT
public: 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(void);
~APMAirframeComponentController(); ~APMAirframeComponentController();
Q_PROPERTY(QmlObjectListModel* airframeTypesModel MEMBER _airframeTypesModel CONSTANT) Q_PROPERTY(QmlObjectListModel* frameClassModel MEMBER _frameClassModel CONSTANT)
Q_PROPERTY(APMAirframeType* currentAirframeType READ currentAirframeType WRITE setCurrentAirframeType NOTIFY currentAirframeTypeChanged)
Q_INVOKABLE void loadParameters(const QString& paramFile); Q_INVOKABLE void loadParameters(const QString& paramFile);
int currentAirframeIndex(void);
void setCurrentAirframeIndex(int newIndex);
signals:
void loadAirframesCompleted();
void currentAirframeTypeChanged(APMAirframeType* airframeType);
public slots:
APMAirframeType *currentAirframeType() const;
Q_INVOKABLE QString currentAirframeTypeName() const;
void setCurrentAirframeType(APMAirframeType *t);
private slots: private slots:
void _fillAirFrames(void);
void _factFrameChanged(QVariant v);
void _githubJsonDownloadFinished(QString remoteFile, QString localFile); void _githubJsonDownloadFinished(QString remoteFile, QString localFile);
void _githubJsonDownloadError(QString errorMsg); void _githubJsonDownloadError(QString errorMsg);
void _paramFileDownloadFinished(QString remoteFile, QString localFile); void _paramFileDownloadFinished(QString remoteFile, QString localFile);
void _paramFileDownloadError(QString errorMsg); void _paramFileDownloadError(QString errorMsg);
private: private:
void _fillFrameClasses(void);
void _loadParametersFromDownloadFile(const QString& downloadedParamFile); void _loadParametersFromDownloadFile(const QString& downloadedParamFile);
APMAirframeType *_currentAirframeType; Fact* _frameClassFact;
QmlObjectListModel *_airframeTypesModel; Fact* _frameTypeFact;
QmlObjectListModel* _frameClassModel;
static bool _typesRegistered;
static const char* _oldFrameParam;
static const char* _newFrameParam;
}; };
class APMAirframe : public QObject class APMFrameClass : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
APMAirframe(const QString& name, const QString& paramsFile, int type, QObject* parent = NULL); APMFrameClass(const QString& name, int frameClass, Fact* frameTypeFact, int defaultFrameType, QObject* parent = nullptr);
~APMAirframe(); ~APMFrameClass();
Q_PROPERTY(QString name MEMBER _name CONSTANT) Q_PROPERTY(QString name MEMBER _name CONSTANT)
Q_PROPERTY(int type MEMBER _type CONSTANT) Q_PROPERTY(int frameClass MEMBER _frameClass CONSTANT)
Q_PROPERTY(QString params MEMBER _paramsFile CONSTANT) Q_PROPERTY(int frameType READ frameType NOTIFY frameTypeChanged)
Q_PROPERTY(int defaultFrameType MEMBER _defaultFrameType CONSTANT)
QString name() const; Q_PROPERTY(QString imageResource READ imageResource NOTIFY imageResourceChanged)
QString params() const; Q_PROPERTY(bool frameTypeSupported MEMBER _frameTypeSupported CONSTANT)
int type() const;
int frameType (void) { return _frameTypeFact->rawValue().toInt(); };
QString imageResource (void);
private:
QString _name; QString _name;
QString _paramsFile; QString _imageResource;
int _type; int _frameClass;
}; int _defaultFrameType;
bool _frameTypeSupported;
class APMAirframeType : public QObject signals:
{ void imageResourceChanged(void);
Q_OBJECT void frameTypeChanged();
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: private:
QString _name; Fact* _frameTypeFact;
QString _imageResource;
QVariantList _airframes;
int _type;
bool _dirty;
}; };
#endif
<?xml version='1.0' encoding='UTF-8'?>
<airframes>
<version>1</version>
<airframe_group image="AirframeQuadRotorPlus.png" name="Plus Style: Quad, Hexa, Octo, Heli" 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, Y6A Style: Quad, Hexa, Octo, X8, Tri, Y6A" 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="AirframeQuadRotorH.png" name="V (3DR Iris)" 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="V Tail" id="4">
</airframe_group>
<airframe_group image="AirframeQuadRotorH.png" name="A Tail" id="5">
</airframe_group>
<airframe_group name="H: X and H differ in prop rotation" id="3">
</airframe_group>
<airframe_group name="Y6B Frame (3DR TriCopter): Y6B and Y6A differ in prop rotation" id="10">
<airframe name="3DR Y6B" file="3DR_Y6B_RTF.param"/>
</airframe_group>
<airframes>
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
/// @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(QStringLiteral(":/AutoPilotPlugins/APM/APMAirframeFactMetaData.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 == QLatin1Literal("airframe_group")) {
airframeGroup = attr.value(QStringLiteral("name")).toString();
image = attr.value(QStringLiteral("image")).toString();
groupId = attr.value(QStringLiteral("id")).toInt();
APMAirframeComponentAirframes::insert(airframeGroup, groupId, image);
} else if (elementName == QLatin1Literal("airframe")) {
QString name = attr.value(QStringLiteral("name")).toString();
QString file = attr.value(QStringLiteral("file")).toString();
APMAirframeComponentAirframes::insert(airframeGroup, groupId, image, name, file);
}
}
xml.readNext();
}
_airframeMetaDataLoaded = true;
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#ifndef APMAirframeLoader_H
#define APMAirframeLoader_H
#include <QObject>
#include <QMap>
#include <QXmlStreamReader>
#include <QLoggingCategory>
#include "ParameterManager.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
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
#include "FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h" #include "FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h"
#include "VehicleComponent.h" #include "VehicleComponent.h"
#include "APMAirframeComponent.h" #include "APMAirframeComponent.h"
#include "APMAirframeComponentAirframes.h"
#include "APMAirframeLoader.h"
#include "APMFlightModesComponent.h" #include "APMFlightModesComponent.h"
#include "APMRadioComponent.h" #include "APMRadioComponent.h"
#include "APMSafetyComponent.h" #include "APMSafetyComponent.h"
...@@ -30,6 +28,7 @@ ...@@ -30,6 +28,7 @@
#include "ESP8266Component.h" #include "ESP8266Component.h"
#include "APMHeliComponent.h" #include "APMHeliComponent.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "ParameterManager.h"
#if !defined(NO_SERIAL_LINK) && !defined(__android__) #if !defined(NO_SERIAL_LINK) && !defined(__android__)
#include <QSerialPortInfo> #include <QSerialPortInfo>
...@@ -50,12 +49,9 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent) ...@@ -50,12 +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))
, _esp8266Component (NULL) , _esp8266Component (NULL)
, _heliComponent (NULL) , _heliComponent (NULL)
{ {
APMAirframeLoader::loadAirframeFactMetaData();
#if !defined(NO_SERIAL_LINK) && !defined(__android__) #if !defined(NO_SERIAL_LINK) && !defined(__android__)
connect(vehicle->parameterManager(), &ParameterManager::parametersReadyChanged, this, &APMAutoPilotPlugin::_checkForBadCubeBlack); connect(vehicle->parameterManager(), &ParameterManager::parametersReadyChanged, this, &APMAutoPilotPlugin::_checkForBadCubeBlack);
#endif #endif
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "Vehicle.h" #include "Vehicle.h"
class APMAirframeComponent; class APMAirframeComponent;
class APMAirframeLoader;
class APMFlightModesComponent; class APMFlightModesComponent;
class APMRadioComponent; class APMRadioComponent;
class APMTuningComponent; class APMTuningComponent;
...@@ -55,7 +54,6 @@ protected: ...@@ -55,7 +54,6 @@ protected:
APMSafetyComponent* _safetyComponent; APMSafetyComponent* _safetyComponent;
APMSensorsComponent* _sensorsComponent; APMSensorsComponent* _sensorsComponent;
APMTuningComponent* _tuningComponent; APMTuningComponent* _tuningComponent;
APMAirframeLoader* _airframeFacts;
ESP8266Component* _esp8266Component; ESP8266Component* _esp8266Component;
APMHeliComponent* _heliComponent; APMHeliComponent* _heliComponent;
......
...@@ -37,9 +37,6 @@ ...@@ -37,9 +37,6 @@
<file alias="APM/MavCmdInfoSub.json">MavCmdInfoSub.json</file> <file alias="APM/MavCmdInfoSub.json">MavCmdInfoSub.json</file>
<file alias="APM/MavCmdInfoVTOL.json">MavCmdInfoVTOL.json</file> <file alias="APM/MavCmdInfoVTOL.json">MavCmdInfoVTOL.json</file>
</qresource> </qresource>
<qresource prefix="/AutoPilotPlugins/APM">
<file alias="APMAirframeFactMetaData.xml">../../AutoPilotPlugins/APM/APMAirframeFactMetaData.xml</file>
</qresource>
<qresource prefix="/FirmwarePlugin/APM"> <qresource prefix="/FirmwarePlugin/APM">
<file alias="APMParameterFactMetaData.Plane.3.3.xml">APMParameterFactMetaData.Plane.3.3.xml</file> <file alias="APMParameterFactMetaData.Plane.3.3.xml">APMParameterFactMetaData.Plane.3.3.xml</file>
<file alias="APMParameterFactMetaData.Plane.3.5.xml">APMParameterFactMetaData.Plane.3.5.xml</file> <file alias="APMParameterFactMetaData.Plane.3.5.xml">APMParameterFactMetaData.Plane.3.5.xml</file>
......
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