Commit f1cac3e3 authored by Don Gagne's avatar Don Gagne

Merge pull request #1132 from DonLakeFlyer/GenericPlugin

Generic AutopilotPlugin full implementation
parents 7c25663f acbc19aa
......@@ -669,7 +669,9 @@ HEADERS += \
src/qgcunittest/MainWindowTest.h \
src/AutoPilotPlugins/PX4/Tests/FlightModeConfigTest.h \
src/qgcunittest/MavlinkLogTest.h \
src/FactSystem/FactSystemTest.h
src/FactSystem/FactSystemTestBase.h \
src/FactSystem/FactSystemTestPX4.h \
src/FactSystem/FactSystemTestGeneric.h
SOURCES += \
src/qgcunittest/UnitTest.cc \
......@@ -691,7 +693,9 @@ SOURCES += \
src/qgcunittest/MainWindowTest.cc \
src/AutoPilotPlugins/PX4/Tests/FlightModeConfigTest.cc \
src/qgcunittest/MavlinkLogTest.cc \
src/FactSystem/FactSystemTest.cc
src/FactSystem/FactSystemTestBase.cc \
src/FactSystem/FactSystemTestPX4.cc \
src/FactSystem/FactSystemTestGeneric.cc
}
#
......@@ -713,6 +717,7 @@ HEADERS+= \
src/AutoPilotPlugins/AutoPilotPluginManager.h \
src/AutoPilotPlugins/AutoPilotPlugin.h \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \
src/AutoPilotPlugins/Generic/GenericParameterFacts.h \
src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h \
src/AutoPilotPlugins/PX4/PX4Component.h \
src/AutoPilotPlugins/PX4/RadioComponent.h \
......@@ -730,6 +735,7 @@ SOURCES += \
src/VehicleSetup/VehicleComponentSummaryItem.cc \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/Generic/GenericParameterFacts.cc \
src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc \
src/AutoPilotPlugins/PX4/PX4Component.cc \
src/AutoPilotPlugins/PX4/RadioComponent.cc \
......@@ -750,9 +756,11 @@ HEADERS += \
src/FactSystem/Fact.h \
src/FactSystem/FactMetaData.h \
src/FactSystem/FactValidator.h \
src/FactSystem/FactLoader.h \
SOURCES += \
src/FactSystem/FactSystem.cc \
src/FactSystem/Fact.cc \
src/FactSystem/FactMetaData.cc \
src/FactSystem/FactValidator.cc \
src/FactSystem/FactLoader.cc \
......@@ -89,7 +89,7 @@ void AutoPilotPluginManager::_uasDeleted(UASInterface* uas)
{
Q_ASSERT(uas);
MAV_AUTOPILOT autopilotType = static_cast<MAV_AUTOPILOT>(uas->getAutopilotType());
MAV_AUTOPILOT autopilotType = _installedAutopilotType(static_cast<MAV_AUTOPILOT>(uas->getAutopilotType()));
int uasId = uas->getUASID();
Q_ASSERT(uasId != 0);
......@@ -103,7 +103,7 @@ AutoPilotPlugin* AutoPilotPluginManager::getInstanceForAutoPilotPlugin(UASInterf
{
Q_ASSERT(uas);
MAV_AUTOPILOT autopilotType = static_cast<MAV_AUTOPILOT>(uas->getAutopilotType());
MAV_AUTOPILOT autopilotType = _installedAutopilotType(static_cast<MAV_AUTOPILOT>(uas->getAutopilotType()));
int uasId = uas->getUASID();
Q_ASSERT(uasId != 0);
......@@ -134,3 +134,9 @@ QString AutoPilotPluginManager::getShortModeText(uint8_t baseMode, uint32_t cust
return GenericAutoPilotPlugin::getShortModeText(baseMode, customMode);
}
}
/// If autopilot is not an installed plugin, returns MAV_AUTOPILOT_GENERIC
MAV_AUTOPILOT AutoPilotPluginManager::_installedAutopilotType(MAV_AUTOPILOT autopilot)
{
return _pluginMap.contains(autopilot) ? autopilot : MAV_AUTOPILOT_GENERIC;
}
......@@ -71,6 +71,8 @@ private:
AutoPilotPluginManager(QObject* parent = NULL);
~AutoPilotPluginManager();
MAV_AUTOPILOT _installedAutopilotType(MAV_AUTOPILOT autopilot);
QMap<MAV_AUTOPILOT, QMap<int, AutoPilotPlugin*> > _pluginMap; ///< Map of AutoPilot plugins _pluginMap[MAV_TYPE][UASid]
};
......
......@@ -30,6 +30,12 @@ GenericAutoPilotPlugin::GenericAutoPilotPlugin(UASInterface* uas, QObject* paren
AutoPilotPlugin(parent)
{
Q_UNUSED(uas);
_parameterFacts = new GenericParameterFacts(uas, this);
Q_CHECK_PTR(_parameterFacts);
connect(_parameterFacts, &GenericParameterFacts::factsReady, this, &GenericAutoPilotPlugin::pluginReady);
}
QList<AutoPilotPluginManager::FullMode_t> GenericAutoPilotPlugin::getModes(void)
......@@ -84,24 +90,17 @@ void GenericAutoPilotPlugin::clearStaticData(void)
const QVariantList& GenericAutoPilotPlugin::components(void)
{
static QVariantList staticList;
static QVariantList emptyList;
Q_ASSERT_X(false, "Not yet implemented", "");
return staticList;
return emptyList;
}
const QVariantMap& GenericAutoPilotPlugin::parameters(void)
{
static QVariantMap staticMap;
Q_ASSERT_X(false, "Not yet implemented", "");
return staticMap;
return _parameterFacts->factMap();
}
QUrl GenericAutoPilotPlugin::setupBackgroundImage(void)
{
static QUrl url;
Q_ASSERT_X(false, "Not yet implemented", "");
return url;
return QUrl::fromUserInput("qrc:/qml/px4fmu_2.x.png");
}
......@@ -26,6 +26,7 @@
#include "AutoPilotPlugin.h"
#include "AutoPilotPluginManager.h"
#include "GenericParameterFacts.h"
/// @file
/// @brief This is the generic implementation of the AutoPilotPlugin class for mavs
......@@ -40,7 +41,7 @@ public:
GenericAutoPilotPlugin(UASInterface* uas, QObject* parent = NULL);
// Overrides from AutoPilotPlugin
virtual bool pluginIsReady(void) const { return true; }
virtual bool pluginIsReady(void) const { return _parameterFacts->factsAreReady(); }
virtual QUrl setupBackgroundImage(void);
virtual const QVariantList& components(void);
virtual const QVariantMap& parameters(void);
......@@ -49,7 +50,8 @@ public:
static QString getShortModeText(uint8_t baseMode, uint32_t customMode);
static void clearStaticData(void);
protected:
private:
GenericParameterFacts* _parameterFacts;
};
#endif
/*=====================================================================
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 "GenericParameterFacts.h"
#include "QGCApplication.h"
#include <QFile>
#include <QDebug>
GenericParameterFacts::GenericParameterFacts(UASInterface* uas, QObject* parent) :
FactLoader(uas, parent)
{
Q_ASSERT(uas);
}
/*=====================================================================
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/>.
======================================================================*/
#ifndef GenericParameterFacts_h
#define GenericParameterFacts_h
#include <QObject>
#include <QMap>
#include <QXmlStreamReader>
#include <QLoggingCategory>
#include "FactSystem.h"
#include "UASInterface.h"
/// @file
/// @author Don Gagne <don@thegagnes.com>
/// Collection of Parameter Facts for Generic AutoPilot
class GenericParameterFacts : public FactLoader
{
Q_OBJECT
public:
/// @param uas Uas which this set of facts is associated with
GenericParameterFacts(UASInterface* uas, QObject* parent = NULL);
};
#endif
\ No newline at end of file
......@@ -56,7 +56,6 @@ public:
private:
UASInterface* _uas;
PX4ParameterFacts* _parameterFacts;
bool _pluginReady;
QVariantList _components;
};
......
......@@ -30,42 +30,15 @@
#include <QFile>
#include <QDebug>
Q_LOGGING_CATEGORY(PX4ParameterFactsLog, "PX4ParameterFactsLog")
Q_LOGGING_CATEGORY(PX4ParameterFactsMetaDataLog, "PX4ParameterFactsMetaDataLog")
bool PX4ParameterFacts::_parameterMetaDataLoaded = false;
QMap<QString, FactMetaData*> PX4ParameterFacts::_mapParameterName2FactMetaData;
PX4ParameterFacts::PX4ParameterFacts(UASInterface* uas, QObject* parent) :
QObject(parent),
_lastSeenComponent(-1),
_paramMgr(NULL),
_factsReady(false)
FactLoader(uas, parent)
{
Q_ASSERT(uas);
_uasId = uas->getUASID();
_paramMgr = uas->getParamManager();
Q_ASSERT(_paramMgr);
// We need to be initialized before param mgr starts sending parameters so we catch each one
Q_ASSERT(!_paramMgr->parametersReady());
// We need to know when the param mgr is done sending the initial set of paramters
connect(_paramMgr, SIGNAL(parameterListUpToDate()), this, SLOT(_paramMgrParameterListUpToDate()));
// UASInterface::parameterChanged has multiple overrides so we need to use SIGNAL/SLOT style connect
connect(uas, SIGNAL(parameterChanged(int, int, QString, QVariant)), this, SLOT(_parameterChanged(int, int, QString, QVariant)));
}
PX4ParameterFacts::~PX4ParameterFacts()
{
foreach(Fact* fact, _mapFact2ParameterName.keys()) {
delete fact;
}
_mapParameterName2Variant.clear();
_mapFact2ParameterName.clear();
}
void PX4ParameterFacts::deleteParameterFactMetaData(void)
......@@ -76,88 +49,6 @@ void PX4ParameterFacts::deleteParameterFactMetaData(void)
_mapParameterName2FactMetaData.clear();
}
/// Connected to QGCUASParmManager::parameterChanged
///
/// When a new parameter is seen it is added to the system. If the parameter is already known it is updated.
void PX4ParameterFacts::_parameterChanged(int uas, int component, QString parameterName, QVariant value)
{
// Is this for our uas?
if (uas != _uasId) {
return;
}
if (_lastSeenComponent == -1) {
_lastSeenComponent = component;
} else {
// Code cannot handle parameters coming form different components yets
Q_ASSERT(component == _lastSeenComponent);
}
if (!_mapParameterName2Variant.contains(parameterName)) {
Fact* fact = new Fact(this);
if (_mapParameterName2FactMetaData.contains(parameterName)) {
fact->setMetaData(_mapParameterName2FactMetaData[parameterName]);
} else {
qDebug() << "FactSystem meta data out of date. Missing parameter:" << parameterName;
}
_mapParameterName2Variant[parameterName] = QVariant::fromValue(fact);
_mapFact2ParameterName[fact] = parameterName;
// We need to know when the fact changes so that we can send the new value to the parameter manager
connect(fact, &Fact::_containerValueChanged, this, &PX4ParameterFacts::_valueUpdated);
qCDebug(PX4ParameterFactsLog) << "Adding new fact" << parameterName;
}
Q_ASSERT(_mapParameterName2Variant.contains(parameterName));
qCDebug(PX4ParameterFactsLog) << "Updating fact value" << parameterName << value;
Fact* fact = _mapParameterName2Variant[parameterName].value<Fact*>();
Q_ASSERT(fact);
fact->_containerSetValue(value);
}
/// Connected to Fact::valueUpdated
///
/// Sets the new value into the Parameter Manager. Paramter is persisted after send.
void PX4ParameterFacts::_valueUpdated(QVariant value)
{
Fact* fact = qobject_cast<Fact*>(sender());
Q_ASSERT(fact);
Q_ASSERT(_lastSeenComponent != -1);
Q_ASSERT(_paramMgr);
Q_ASSERT(_mapFact2ParameterName.contains(fact));
QVariant typedValue;
switch (fact->type()) {
case FactMetaData::valueTypeInt8:
case FactMetaData::valueTypeInt16:
case FactMetaData::valueTypeInt32:
typedValue = QVariant(value.value<int>());
case FactMetaData::valueTypeUint8:
case FactMetaData::valueTypeUint16:
case FactMetaData::valueTypeUint32:
typedValue = QVariant(value.value<uint>());
break;
case FactMetaData::valueTypeFloat:
typedValue = QVariant(value.toFloat());
break;
case FactMetaData::valueTypeDouble:
typedValue = QVariant(value.toDouble());
break;
}
_paramMgr->setParameter(_lastSeenComponent, _mapFact2ParameterName[fact], typedValue);
_paramMgr->sendPendingParameters(true /* persistAfterSend */, false /* forceSend */);
}
/// Parse the Parameter element of parameter xml meta data
/// @param[in] xml stream reader
/// @param[in] group fact group associated with this Param element
......@@ -327,7 +218,7 @@ void PX4ParameterFacts::loadParameterFactMetaData(void)
// Just move to next state
} else if (elementName == "group") {
factGroup = xml.attributes().value("name").toString();
qCDebug(PX4ParameterFactsLog) << "Found group: " << factGroup;
qCDebug(PX4ParameterFactsMetaDataLog) << "Found group: " << factGroup;
} else if (elementName == "parameter") {
metaData = _parseParameter(xml, factGroup);
} else if (elementName == "short_desc") {
......@@ -365,23 +256,6 @@ void PX4ParameterFacts::loadParameterFactMetaData(void)
}
}
// Called when param mgr list is up to date
void PX4ParameterFacts::_paramMgrParameterListUpToDate(void)
{
if (!_factsReady) {
_factsReady = true;
// We don't need this any more
disconnect(_paramMgr, SIGNAL(parameterListUpToDate()), this, SLOT(_paramMgrParameterListUpToDate()));
// There may be parameterUpdated signals still in our queue. Flush them out.
qgcApp()->processEvents();
// We should have all paramters now so we can signal ready
emit factsReady();
}
}
void PX4ParameterFacts::clearStaticData(void)
{
foreach(QString parameterName, _mapParameterName2FactMetaData.keys()) {
......
......@@ -29,27 +29,17 @@
#include <QXmlStreamReader>
#include <QLoggingCategory>
#include "Fact.h"
#include "FactSystem.h"
#include "UASInterface.h"
/// @file
/// @author Don Gagne <don@thegagnes.com>
// FIXME: This file should be auto-generated from the Parameter XML file.
Q_DECLARE_LOGGING_CATEGORY(PX4ParameterFactsLog)
Q_DECLARE_LOGGING_CATEGORY(PX4ParameterFactsMetaDataLog)
/// Collection of Parameter Facts for PX4 AutoPilot
///
/// These Facts are available for binding within QML code. For example:
/// @code{.unparsed}
/// TextInput {
/// text: parameters["RC_MAP_THROTTLE"].value
/// }
/// @endcode
class PX4ParameterFacts : public QObject
class PX4ParameterFacts : public FactLoader
{
Q_OBJECT
......@@ -57,45 +47,17 @@ public:
/// @param uas Uas which this set of facts is associated with
PX4ParameterFacts(UASInterface* uas, QObject* parent = NULL);
~PX4ParameterFacts();
/// Returns true if the full set of facts are ready
bool factsAreReady(void) { return _factsReady; }
/// Returns the fact QVariantMap
const QVariantMap& factMap(void) { return _mapParameterName2Variant; }
static void loadParameterFactMetaData(void);
static void deleteParameterFactMetaData(void);
static void clearStaticData(void);
signals:
/// Signalled when the full set of facts are ready
void factsReady(void);
private slots:
void _parameterChanged(int uas, int component, QString parameterName, QVariant value);
void _valueUpdated(QVariant value);
void _paramMgrParameterListUpToDate(void);
private:
static FactMetaData* _parseParameter(QXmlStreamReader& xml, const QString& group);
static void _initMetaData(FactMetaData* metaData);
static QVariant _stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool failOk = false);
QMap<Fact*, QString> _mapFact2ParameterName; ///< Maps from a Fact to a parameter name
static bool _parameterMetaDataLoaded; ///< true: parameter meta data already loaded
static QMap<QString, FactMetaData*> _mapParameterName2FactMetaData; ///< Maps from a parameter name to FactMetaData
int _uasId; ///< Id for uas which this set of Facts are associated with
int _lastSeenComponent;
QGCUASParamManagerInterface* _paramMgr;
QVariantMap _mapParameterName2Variant;
bool _factsReady; ///< All facts received from param mgr
};
#endif
\ No newline at end of file
/*=====================================================================
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 "FactLoader.h"
#include "QGCApplication.h"
#include <QFile>
#include <QDebug>
Q_LOGGING_CATEGORY(FactLoaderLog, "FactLoaderLog")
FactLoader::FactLoader(UASInterface* uas, QObject* parent) :
QObject(parent),
_lastSeenComponent(-1),
_paramMgr(NULL),
_factsReady(false)
{
Q_ASSERT(uas);
_uasId = uas->getUASID();
_paramMgr = uas->getParamManager();
Q_ASSERT(_paramMgr);
// We need to be initialized before param mgr starts sending parameters so we catch each one
Q_ASSERT(!_paramMgr->parametersReady());
// We need to know when the param mgr is done sending the initial set of paramters
connect(_paramMgr, SIGNAL(parameterListUpToDate()), this, SLOT(_paramMgrParameterListUpToDate()));
// We track parameters changes to keep Facts up to date. UASInterface::parameterChanged has multiple overrides so we need to
// use SIGNAL/SLOT style connect
connect(uas, SIGNAL(parameterChanged(int, int, QString, QVariant)), this, SLOT(_parameterChanged(int, int, QString, QVariant)));
}
FactLoader::~FactLoader()
{
foreach(Fact* fact, _mapFact2ParameterName.keys()) {
delete fact;
}
_mapParameterName2Variant.clear();
_mapFact2ParameterName.clear();
}
/// Connected to QGCUASParmManager::parameterChanged
///
/// When a new parameter is seen it is added to the system. If the parameter is already known it is updated.
void FactLoader::_parameterChanged(int uas, int component, QString parameterName, QVariant value)
{
// Is this for our uas?
if (uas != _uasId) {
return;
}
if (_lastSeenComponent == -1) {
_lastSeenComponent = component;
} else {
// Code cannot handle parameters coming form different components yets
Q_ASSERT(component == _lastSeenComponent);
}
if (!_mapParameterName2Variant.contains(parameterName)) {
Fact* fact = new Fact(this);
_mapParameterName2Variant[parameterName] = QVariant::fromValue(fact);
_mapFact2ParameterName[fact] = parameterName;
// We need to know when the fact changes from QML so that we can send the new value to the parameter manager
connect(fact, &Fact::_containerValueChanged, this, &FactLoader::_valueUpdated);
qCDebug(FactLoaderLog) << "Adding new fact" << parameterName;
}
Q_ASSERT(_mapParameterName2Variant.contains(parameterName));
qCDebug(FactLoaderLog) << "Updating fact value" << parameterName << value;
Fact* fact = _mapParameterName2Variant[parameterName].value<Fact*>();
Q_ASSERT(fact);
fact->_containerSetValue(value);
}
/// Connected to Fact::valueUpdated
///
/// Sets the new value into the Parameter Manager. Paramter is persisted after send.
void FactLoader::_valueUpdated(QVariant value)
{
Fact* fact = qobject_cast<Fact*>(sender());
Q_ASSERT(fact);
Q_ASSERT(_lastSeenComponent != -1);
Q_ASSERT(_paramMgr);
Q_ASSERT(_mapFact2ParameterName.contains(fact));
QVariant typedValue;
switch (fact->type()) {
case FactMetaData::valueTypeInt8:
case FactMetaData::valueTypeInt16:
case FactMetaData::valueTypeInt32:
typedValue = QVariant(value.value<int>());
case FactMetaData::valueTypeUint8:
case FactMetaData::valueTypeUint16:
case FactMetaData::valueTypeUint32:
typedValue = QVariant(value.value<uint>());
break;
case FactMetaData::valueTypeFloat:
typedValue = QVariant(value.toFloat());
break;
case FactMetaData::valueTypeDouble:
typedValue = QVariant(value.toDouble());
break;
}
_paramMgr->setParameter(_lastSeenComponent, _mapFact2ParameterName[fact], typedValue);
_paramMgr->sendPendingParameters(true /* persistAfterSend */, false /* forceSend */);
}
// Called when param mgr list is up to date
void FactLoader::_paramMgrParameterListUpToDate(void)
{
if (!_factsReady) {
_factsReady = true;
// We don't need this any more
disconnect(_paramMgr, SIGNAL(parameterListUpToDate()), this, SLOT(_paramMgrParameterListUpToDate()));
// There may be parameterUpdated signals still in our queue. Flush them out.
qgcApp()->processEvents();
// We should have all paramters now so we can signal ready
emit factsReady();
}
}
/*=====================================================================
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/>.
======================================================================*/
#ifndef FactLoader_h
#define FactLoader_h
#include <QObject>
#include <QMap>
#include <QXmlStreamReader>
#include <QLoggingCategory>
#include "Fact.h"
#include "UASInterface.h"
/// @file
/// @author Don Gagne <don@thegagnes.com>
Q_DECLARE_LOGGING_CATEGORY(FactLoaderLog)
/// Connects to Parameter Manager to load/update Facts
///
/// These Facts are available for binding within QML code. For example:
/// @code{.unparsed}
/// TextInput {
/// text: autopilot.parameters["RC_MAP_THROTTLE"].value
/// }
/// @endcode
class FactLoader : public QObject
{
Q_OBJECT
public:
/// @param uas Uas which this set of facts is associated with
FactLoader(UASInterface* uas, QObject* parent = NULL);
~FactLoader();
/// Returns true if the full set of facts are ready
bool factsAreReady(void) { return _factsReady; }
/// Returns the fact QVariantMap
const QVariantMap& factMap(void) { return _mapParameterName2Variant; }
signals:
/// Signalled when the full set of facts are ready
void factsReady(void);
private slots:
void _parameterChanged(int uas, int component, QString parameterName, QVariant value);
void _valueUpdated(QVariant value);
void _paramMgrParameterListUpToDate(void);
private:
static QVariant _stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool failOk = false);
QMap<Fact*, QString> _mapFact2ParameterName; ///< Maps from a Fact to a parameter name
int _uasId; ///< Id for uas which this set of Facts are associated with
int _lastSeenComponent;
QGCUASParamManagerInterface* _paramMgr;
QVariantMap _mapParameterName2Variant;
bool _factsReady; ///< All facts received from param mgr
};
#endif
\ No newline at end of file
......@@ -28,6 +28,7 @@
#define FactSystem_h
#include "Fact.h"
#include "FactLoader.h"
#include "FactMetaData.h"
#include "UASInterface.h"
#include "QGCSingleton.h"
......
......@@ -24,7 +24,7 @@
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "FactSystemTest.h"
#include "FactSystemTestBase.h"
#include "LinkManager.h"
#include "MockLink.h"
#include "AutoPilotPluginManager.h"
......@@ -34,21 +34,20 @@
#include <QQuickItem>
UT_REGISTER_TEST(FactSystemTest)
/// FactSystem Unit Test
FactSystemTest::FactSystemTest(void)
FactSystemTestBase::FactSystemTestBase(void)
{
}
void FactSystemTest::init(void)
void FactSystemTestBase::_init(MAV_AUTOPILOT autopilot)
{
UnitTest::init();
LinkManager* _linkMgr = LinkManager::instance();
MockLink* link = new MockLink();
link->setAutopilotType(autopilot);
_linkMgr->addLink(link);
_linkMgr->connectLink(link);
......@@ -80,13 +79,13 @@ void FactSystemTest::init(void)
Q_ASSERT(_plugin->pluginIsReady());
}
void FactSystemTest::cleanup(void)
void FactSystemTestBase::_cleanup(void)
{
UnitTest::cleanup();
}
/// Basic test of parameter values in Fact System
void FactSystemTest::_parameter_test(void)
void FactSystemTestBase::_parameter_test(void)
{
// Get the parameter facts from the AutoPilot
......@@ -106,7 +105,7 @@ void FactSystemTest::_parameter_test(void)
}
/// Test that QML can reference a Fact
void FactSystemTest::_qml_test(void)
void FactSystemTestBase::_qml_test(void)
{
QGCQuickWidget* widget = new QGCQuickWidget;
......@@ -126,7 +125,7 @@ void FactSystemTest::_qml_test(void)
}
// Test correct behavior when the Param Manager gets a parameter update
void FactSystemTest::_paramMgrSignal_test(void)
void FactSystemTestBase::_paramMgrSignal_test(void)
{
// Get the parameter Fact from the AutoPilot
......@@ -156,7 +155,7 @@ void FactSystemTest::_paramMgrSignal_test(void)
}
/// Test QML getting an updated Fact value
void FactSystemTest::_qmlUpdate_test(void)
void FactSystemTestBase::_qmlUpdate_test(void)
{
QGCQuickWidget* widget = new QGCQuickWidget;
......
......@@ -24,31 +24,30 @@
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef FactSystemTest_H
#define FactSystemTest_H
#ifndef FactSystemTestBase_H
#define FactSystemTestBase_H
#include "UnitTest.h"
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
// Unit Test for Fact System
class FactSystemTest : public UnitTest
// Base class for FactSystemTest[PX4|Generic] unit tests
class FactSystemTestBase : public UnitTest
{
Q_OBJECT
public:
FactSystemTest(void);
FactSystemTestBase(void);
private slots:
void init(void);
void cleanup(void);
protected:
void _init(MAV_AUTOPILOT autopilot);
void _cleanup(void);
void _parameter_test(void);
void _qml_test(void);
void _paramMgrSignal_test(void);
void _qmlUpdate_test(void);
private:
UASInterface* _uas;
QGCUASParamManagerInterface* _paramMgr;
AutoPilotPlugin* _plugin;
......
/*=====================================================================
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 "FactSystemTestGeneric.h"
#include "LinkManager.h"
#include "MockLink.h"
#include "AutoPilotPluginManager.h"
#include "UASManager.h"
#include "QGCApplication.h"
#include "QGCQuickWidget.h"
#include <QQuickItem>
UT_REGISTER_TEST(FactSystemTestGeneric)
/// FactSystem Unit Test for PX4 autpilot
FactSystemTestGeneric::FactSystemTestGeneric(void)
{
}
void FactSystemTestGeneric::init(void)
{
UnitTest::init();
_init(MAV_AUTOPILOT_ARDUPILOTMEGA);
}
/*=====================================================================
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>
#ifndef FactSystemTestGeneric_H
#define FactSystemTestGeneric_H
#include "FactSystemTestBase.h"
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
// Unit Test for Fact System on PX4 autopilot
class FactSystemTestGeneric : public FactSystemTestBase
{
Q_OBJECT
public:
FactSystemTestGeneric(void);
private slots:
void init(void);
void cleanup(void) { _cleanup(); }
void parameter_test(void) { _parameter_test(); }
void qml_test(void) { _qml_test(); }
void paramMgrSignal_test(void) { _paramMgrSignal_test(); }
void qmlUpdate_test(void) { _qmlUpdate_test(); }
};
#endif
/*=====================================================================
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 "FactSystemTestPX4.h"
#include "LinkManager.h"
#include "MockLink.h"
#include "AutoPilotPluginManager.h"
#include "UASManager.h"
#include "QGCApplication.h"
#include "QGCQuickWidget.h"
#include <QQuickItem>
UT_REGISTER_TEST(FactSystemTestPX4)
/// FactSystem Unit Test for PX4 autpilot
FactSystemTestPX4::FactSystemTestPX4(void)
{
}
void FactSystemTestPX4::init(void)
{
UnitTest::init();
_init(MAV_AUTOPILOT_PX4);
}
/*=====================================================================
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>
#ifndef FactSystemTestPX4_H
#define FactSystemTestPX4_H
#include "FactSystemTestBase.h"
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
// Unit Test for Fact System on PX4 autopilot
class FactSystemTestPX4 : public FactSystemTestBase
{
Q_OBJECT
public:
FactSystemTestPX4(void);
private slots:
void init(void);
void cleanup(void) { _cleanup(); }
void parameter_test(void) { _parameter_test(); }
void qml_test(void) { _qml_test(); }
void paramMgrSignal_test(void) { _paramMgrSignal_test(); }
void qmlUpdate_test(void) { _qmlUpdate_test(); }
};
#endif
......@@ -69,13 +69,14 @@ void MainWindowTest::_clickThrough_test(void)
}
void MainWindowTest::_connectWindowClose_test(void)
void MainWindowTest::_connectWindowClose_test(MAV_AUTOPILOT autopilot)
{
LinkManager* linkMgr = LinkManager::instance();
Q_CHECK_PTR(linkMgr);
MockLink* link = new MockLink();
Q_CHECK_PTR(link);
link->setAutopilotType(autopilot);
LinkManager::instance()->addLink(link);
linkMgr->connectLink(link);
QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through
......@@ -92,3 +93,11 @@ void MainWindowTest::_connectWindowClose_test(void)
QTest::qWait(1000); // Need to allow signals to move between threads
checkExpectedFileDialog();
}
void MainWindowTest::_connectWindowClosePX4_test(void) {
_connectWindowClose_test(MAV_AUTOPILOT_PX4);
}
void MainWindowTest::_connectWindowCloseGeneric_test(void) {
_connectWindowClose_test(MAV_AUTOPILOT_ARDUPILOTMEGA);
}
......@@ -44,9 +44,11 @@ private slots:
void cleanup(void);
void _clickThrough_test(void);
void _connectWindowClose_test(void);
void _connectWindowClosePX4_test(void);
void _connectWindowCloseGeneric_test(void);
private:
void _connectWindowClose_test(MAV_AUTOPILOT autopilot);
MainWindow* _mainWindow;
};
......
......@@ -74,7 +74,8 @@ MockLink::MockLink(void) :
_inNSH(false),
_mavlinkStarted(false),
_mavBaseMode(MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_CUSTOM_MODE_ENABLED),
_mavState(MAV_STATE_STANDBY)
_mavState(MAV_STATE_STANDBY),
_autopilotType(MAV_AUTOPILOT_PX4)
{
union px4_custom_mode px4_cm;
......@@ -145,20 +146,20 @@ void MockLink::run(void)
void MockLink::_run1HzTasks(void)
{
if (_mavlinkStarted) {
if (_mavlinkStarted && _connected) {
_sendHeartBeat();
}
}
void MockLink::_run10HzTasks(void)
{
if (_mavlinkStarted) {
if (_mavlinkStarted && _connected) {
}
}
void MockLink::_run50HzTasks(void)
{
if (_mavlinkStarted) {
if (_mavlinkStarted && _connected) {
}
}
......@@ -219,7 +220,7 @@ void MockLink::_sendHeartBeat(void)
_vehicleComponentId,
&msg,
MAV_TYPE_QUADROTOR, // MAV_TYPE
MAV_AUTOPILOT_PX4, // MAV_AUTOPILOT
_autopilotType, // MAV_AUTOPILOT
_mavBaseMode, // MAV_MODE
_mavCustomMode, // custom mode
_mavState); // MAV_STATE
......
......@@ -54,6 +54,10 @@ public:
virtual qint64 getConnectionSpeed(void) const { return 100000000; }
virtual qint64 bytesAvailable(void) { return 0; }
// MockLink methods
MAV_AUTOPILOT getAutopilotType(void) { return _autopilotType; }
void setAutopilotType(MAV_AUTOPILOT autopilot) { _autopilotType = autopilot; }
// These are left unimplemented in order to cause linker errors which indicate incorrect usage of
// connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
bool connect(void);
......@@ -122,6 +126,8 @@ private:
uint8_t _mavBaseMode;
uint8_t _mavCustomMode;
uint8_t _mavState;
MAV_AUTOPILOT _autopilotType;
};
#endif
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