From acbc19aa3d5cb666be7e2ced22d1ee1dc1e71bfb Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Sun, 21 Dec 2014 15:51:27 -0800 Subject: [PATCH] Generic AutopilotPlugin full implementation --- qgroundcontrol.pro | 12 +- src/AutoPilotPlugins/AutoPilotPluginManager.cc | 10 +- src/AutoPilotPlugins/AutoPilotPluginManager.h | 2 + .../Generic/GenericAutoPilotPlugin.cc | 21 ++- .../Generic/GenericAutoPilotPlugin.h | 6 +- .../Generic/GenericParameterFacts.cc | 37 +++++ .../Generic/GenericParameterFacts.h | 49 ++++++ src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h | 1 - src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc | 130 +-------------- src/AutoPilotPlugins/PX4/PX4ParameterFacts.h | 42 +---- src/FactSystem/FactLoader.cc | 159 ++++++++++++++++++ src/FactSystem/FactLoader.h | 89 ++++++++++ src/FactSystem/FactSystem.h | 1 + src/FactSystem/FactSystemTest.cc | 182 --------------------- src/FactSystem/FactSystemTest.h | 58 ------- src/FactSystem/FactSystemTestBase.cc | 181 ++++++++++++++++++++ src/FactSystem/FactSystemTestBase.h | 57 +++++++ src/FactSystem/FactSystemTestGeneric.cc | 49 ++++++ src/FactSystem/FactSystemTestGeneric.h | 52 ++++++ src/FactSystem/FactSystemTestPX4.cc | 49 ++++++ src/FactSystem/FactSystemTestPX4.h | 52 ++++++ src/qgcunittest/MainWindowTest.cc | 11 +- src/qgcunittest/MainWindowTest.h | 4 +- src/qgcunittest/MockLink.cc | 11 +- src/qgcunittest/MockLink.h | 6 + 25 files changed, 838 insertions(+), 433 deletions(-) create mode 100644 src/AutoPilotPlugins/Generic/GenericParameterFacts.cc create mode 100644 src/AutoPilotPlugins/Generic/GenericParameterFacts.h create mode 100644 src/FactSystem/FactLoader.cc create mode 100644 src/FactSystem/FactLoader.h delete mode 100644 src/FactSystem/FactSystemTest.cc delete mode 100644 src/FactSystem/FactSystemTest.h create mode 100644 src/FactSystem/FactSystemTestBase.cc create mode 100644 src/FactSystem/FactSystemTestBase.h create mode 100644 src/FactSystem/FactSystemTestGeneric.cc create mode 100644 src/FactSystem/FactSystemTestGeneric.h create mode 100644 src/FactSystem/FactSystemTestPX4.cc create mode 100644 src/FactSystem/FactSystemTestPX4.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index b2a1b62..73a8d4d 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -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 \ diff --git a/src/AutoPilotPlugins/AutoPilotPluginManager.cc b/src/AutoPilotPlugins/AutoPilotPluginManager.cc index c2a2206..0971982 100644 --- a/src/AutoPilotPlugins/AutoPilotPluginManager.cc +++ b/src/AutoPilotPlugins/AutoPilotPluginManager.cc @@ -89,7 +89,7 @@ void AutoPilotPluginManager::_uasDeleted(UASInterface* uas) { Q_ASSERT(uas); - MAV_AUTOPILOT autopilotType = static_cast(uas->getAutopilotType()); + MAV_AUTOPILOT autopilotType = _installedAutopilotType(static_cast(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(uas->getAutopilotType()); + MAV_AUTOPILOT autopilotType = _installedAutopilotType(static_cast(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; +} diff --git a/src/AutoPilotPlugins/AutoPilotPluginManager.h b/src/AutoPilotPlugins/AutoPilotPluginManager.h index c1417c2..03c7607 100644 --- a/src/AutoPilotPlugins/AutoPilotPluginManager.h +++ b/src/AutoPilotPlugins/AutoPilotPluginManager.h @@ -71,6 +71,8 @@ private: AutoPilotPluginManager(QObject* parent = NULL); ~AutoPilotPluginManager(); + MAV_AUTOPILOT _installedAutopilotType(MAV_AUTOPILOT autopilot); + QMap > _pluginMap; ///< Map of AutoPilot plugins _pluginMap[MAV_TYPE][UASid] }; diff --git a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc index d6fd7b3..03ebb8e 100644 --- a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc @@ -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 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"); } diff --git a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h index 9e9b4f8..5a2262b 100644 --- a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h +++ b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h @@ -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 diff --git a/src/AutoPilotPlugins/Generic/GenericParameterFacts.cc b/src/AutoPilotPlugins/Generic/GenericParameterFacts.cc new file mode 100644 index 0000000..c37d05d --- /dev/null +++ b/src/AutoPilotPlugins/Generic/GenericParameterFacts.cc @@ -0,0 +1,37 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "GenericParameterFacts.h" +#include "QGCApplication.h" + +#include +#include + +GenericParameterFacts::GenericParameterFacts(UASInterface* uas, QObject* parent) : + FactLoader(uas, parent) +{ + Q_ASSERT(uas); +} diff --git a/src/AutoPilotPlugins/Generic/GenericParameterFacts.h b/src/AutoPilotPlugins/Generic/GenericParameterFacts.h new file mode 100644 index 0000000..ae363b4 --- /dev/null +++ b/src/AutoPilotPlugins/Generic/GenericParameterFacts.h @@ -0,0 +1,49 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#ifndef GenericParameterFacts_h +#define GenericParameterFacts_h + +#include +#include +#include +#include + +#include "FactSystem.h" +#include "UASInterface.h" + +/// @file +/// @author Don Gagne + +/// 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 diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h index 6607983..abb65c4 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h @@ -56,7 +56,6 @@ public: private: UASInterface* _uas; PX4ParameterFacts* _parameterFacts; - bool _pluginReady; QVariantList _components; }; diff --git a/src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc b/src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc index f71945d..b3f20f4 100644 --- a/src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc +++ b/src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc @@ -30,42 +30,15 @@ #include #include -Q_LOGGING_CATEGORY(PX4ParameterFactsLog, "PX4ParameterFactsLog") Q_LOGGING_CATEGORY(PX4ParameterFactsMetaDataLog, "PX4ParameterFactsMetaDataLog") bool PX4ParameterFacts::_parameterMetaDataLoaded = false; QMap 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(); - 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(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()); - - case FactMetaData::valueTypeUint8: - case FactMetaData::valueTypeUint16: - case FactMetaData::valueTypeUint32: - typedValue = QVariant(value.value()); - 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()) { diff --git a/src/AutoPilotPlugins/PX4/PX4ParameterFacts.h b/src/AutoPilotPlugins/PX4/PX4ParameterFacts.h index e896413..01771a2 100644 --- a/src/AutoPilotPlugins/PX4/PX4ParameterFacts.h +++ b/src/AutoPilotPlugins/PX4/PX4ParameterFacts.h @@ -29,27 +29,17 @@ #include #include -#include "Fact.h" +#include "FactSystem.h" #include "UASInterface.h" /// @file /// @author Don Gagne -// 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 _mapFact2ParameterName; ///< Maps from a Fact to a parameter name - static bool _parameterMetaDataLoaded; ///< true: parameter meta data already loaded static QMap _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 diff --git a/src/FactSystem/FactLoader.cc b/src/FactSystem/FactLoader.cc new file mode 100644 index 0000000..c1ad528 --- /dev/null +++ b/src/FactSystem/FactLoader.cc @@ -0,0 +1,159 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "FactLoader.h" +#include "QGCApplication.h" + +#include +#include + +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(); + 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(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()); + + case FactMetaData::valueTypeUint8: + case FactMetaData::valueTypeUint16: + case FactMetaData::valueTypeUint32: + typedValue = QVariant(value.value()); + 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(); + } +} diff --git a/src/FactSystem/FactLoader.h b/src/FactSystem/FactLoader.h new file mode 100644 index 0000000..ed9503d --- /dev/null +++ b/src/FactSystem/FactLoader.h @@ -0,0 +1,89 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#ifndef FactLoader_h +#define FactLoader_h + +#include +#include +#include +#include + +#include "Fact.h" +#include "UASInterface.h" + +/// @file +/// @author Don Gagne + +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 _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 diff --git a/src/FactSystem/FactSystem.h b/src/FactSystem/FactSystem.h index 1883ed6..8a9b533 100644 --- a/src/FactSystem/FactSystem.h +++ b/src/FactSystem/FactSystem.h @@ -28,6 +28,7 @@ #define FactSystem_h #include "Fact.h" +#include "FactLoader.h" #include "FactMetaData.h" #include "UASInterface.h" #include "QGCSingleton.h" diff --git a/src/FactSystem/FactSystemTest.cc b/src/FactSystem/FactSystemTest.cc deleted file mode 100644 index bc0f606..0000000 --- a/src/FactSystem/FactSystemTest.cc +++ /dev/null @@ -1,182 +0,0 @@ -/*===================================================================== - - QGroundControl Open Source Ground Control Station - - (c) 2009 - 2014 QGROUNDCONTROL PROJECT - - This file is part of the QGROUNDCONTROL project - - QGROUNDCONTROL is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - QGROUNDCONTROL is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with QGROUNDCONTROL. If not, see . - - ======================================================================*/ - -/// @file -/// @author Don Gagne - -#include "FactSystemTest.h" -#include "LinkManager.h" -#include "MockLink.h" -#include "AutoPilotPluginManager.h" -#include "UASManager.h" -#include "QGCApplication.h" -#include "QGCQuickWidget.h" - -#include - -UT_REGISTER_TEST(FactSystemTest) - -/// FactSystem Unit Test -FactSystemTest::FactSystemTest(void) -{ - -} - -void FactSystemTest::init(void) -{ - UnitTest::init(); - - LinkManager* _linkMgr = LinkManager::instance(); - - MockLink* link = new MockLink(); - _linkMgr->addLink(link); - _linkMgr->connectLink(link); - - // Wait for the uas to work it's way through the various threads - - QSignalSpy spyUas(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*))); - QCOMPARE(spyUas.wait(5000), true); - - _uas = UASManager::instance()->getActiveUAS(); - Q_ASSERT(_uas); - - _paramMgr = _uas->getParamManager(); - Q_ASSERT(_paramMgr); - - // Get the plugin for the uas - - AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance(); - Q_ASSERT(pluginMgr); - - _plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas); - Q_ASSERT(_plugin); - - // Wait for the plugin to be ready - - QSignalSpy spyPlugin(_plugin, SIGNAL(pluginReady())); - if (!_plugin->pluginIsReady()) { - QCOMPARE(spyPlugin.wait(5000), true); - } - Q_ASSERT(_plugin->pluginIsReady()); -} - -void FactSystemTest::cleanup(void) -{ - UnitTest::cleanup(); -} - -/// Basic test of parameter values in Fact System -void FactSystemTest::_parameter_test(void) -{ - // Get the parameter facts from the AutoPilot - - const QVariantMap& parameterFacts = _plugin->parameters(); - - // Compare the value in the Parameter Manager with the value from the FactSystem - - Fact* fact = parameterFacts["RC_MAP_THROTTLE"].value(); - QVERIFY(fact != NULL); - QVariant factValue = fact->value(); - QCOMPARE(factValue.isValid(), true); - - QVariant paramValue; - Q_ASSERT(_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramValue)); - - QCOMPARE(factValue.toInt(), paramValue.toInt()); -} - -/// Test that QML can reference a Fact -void FactSystemTest::_qml_test(void) -{ - QGCQuickWidget* widget = new QGCQuickWidget; - - widget->setAutoPilot(_plugin); - - widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml")); - - QQuickItem* rootObject = widget->rootObject(); - QObject* control = rootObject->findChild("testControl"); - QVERIFY(control != NULL); - QVariant qmlValue = control->property("text").toInt(); - - QVariant paramMgrValue; - Q_ASSERT(_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramMgrValue)); - - QCOMPARE(qmlValue.toInt(), paramMgrValue.toInt()); -} - -// Test correct behavior when the Param Manager gets a parameter update -void FactSystemTest::_paramMgrSignal_test(void) -{ - // Get the parameter Fact from the AutoPilot - - const QVariantMap& parameterFacts = _plugin->parameters(); - - Fact* fact = parameterFacts["RC_MAP_THROTTLE"].value(); - QVERIFY(fact != NULL); - - // Setting a new value into the parameter should trigger a valueChanged signal on the Fact - - QSignalSpy spyFact(fact, SIGNAL(valueChanged(QVariant))); - - QVariant paramValue = 12; - _paramMgr->setParameter(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramValue); - _paramMgr->sendPendingParameters(true, false); - - // Wait for the Fact::valueChanged signal to come through - QCOMPARE(spyFact.wait(5000), true); - - // Make sure the signal has the right value - QList arguments = spyFact.takeFirst(); - qDebug() << arguments.at(0).type(); - QCOMPARE(arguments.at(0).toInt(), 12); - - // Make sure the Fact has the new value - QCOMPARE(fact->value().toInt(), 12); -} - -/// Test QML getting an updated Fact value -void FactSystemTest::_qmlUpdate_test(void) -{ - QGCQuickWidget* widget = new QGCQuickWidget; - - widget->setAutoPilot(_plugin); - - widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml")); - - // Change the value using param manager - - QVariant paramValue = 12; - _paramMgr->setParameter(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramValue); - _paramMgr->sendPendingParameters(true, false); - - QTest::qWait(500); // Let the signals flow through - - // Make sure the qml has the right value - - QQuickItem* rootObject = widget->rootObject(); - QObject* control = rootObject->findChild("testControl"); - QVERIFY(control != NULL); - QCOMPARE(control->property("text").toInt(), 12); -} - diff --git a/src/FactSystem/FactSystemTest.h b/src/FactSystem/FactSystemTest.h deleted file mode 100644 index 07d43f2..0000000 --- a/src/FactSystem/FactSystemTest.h +++ /dev/null @@ -1,58 +0,0 @@ -/*===================================================================== - - QGroundControl Open Source Ground Control Station - - (c) 2009 - 2014 QGROUNDCONTROL PROJECT - - This file is part of the QGROUNDCONTROL project - - QGROUNDCONTROL is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - QGROUNDCONTROL is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with QGROUNDCONTROL. If not, see . - - ======================================================================*/ - -/// @file -/// @author Don Gagne - -#ifndef FactSystemTest_H -#define FactSystemTest_H - -#include "UnitTest.h" -#include "UASInterface.h" -#include "AutoPilotPlugin.h" - -// Unit Test for Fact System -class FactSystemTest : public UnitTest -{ - Q_OBJECT - -public: - FactSystemTest(void); - -private slots: - void init(void); - 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; - LinkManager* _linkMgr; -}; - -#endif diff --git a/src/FactSystem/FactSystemTestBase.cc b/src/FactSystem/FactSystemTestBase.cc new file mode 100644 index 0000000..d8bf606 --- /dev/null +++ b/src/FactSystem/FactSystemTestBase.cc @@ -0,0 +1,181 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "FactSystemTestBase.h" +#include "LinkManager.h" +#include "MockLink.h" +#include "AutoPilotPluginManager.h" +#include "UASManager.h" +#include "QGCApplication.h" +#include "QGCQuickWidget.h" + +#include + +/// FactSystem Unit Test +FactSystemTestBase::FactSystemTestBase(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); + + // Wait for the uas to work it's way through the various threads + + QSignalSpy spyUas(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*))); + QCOMPARE(spyUas.wait(5000), true); + + _uas = UASManager::instance()->getActiveUAS(); + Q_ASSERT(_uas); + + _paramMgr = _uas->getParamManager(); + Q_ASSERT(_paramMgr); + + // Get the plugin for the uas + + AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance(); + Q_ASSERT(pluginMgr); + + _plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas); + Q_ASSERT(_plugin); + + // Wait for the plugin to be ready + + QSignalSpy spyPlugin(_plugin, SIGNAL(pluginReady())); + if (!_plugin->pluginIsReady()) { + QCOMPARE(spyPlugin.wait(5000), true); + } + Q_ASSERT(_plugin->pluginIsReady()); +} + +void FactSystemTestBase::_cleanup(void) +{ + UnitTest::cleanup(); +} + +/// Basic test of parameter values in Fact System +void FactSystemTestBase::_parameter_test(void) +{ + // Get the parameter facts from the AutoPilot + + const QVariantMap& parameterFacts = _plugin->parameters(); + + // Compare the value in the Parameter Manager with the value from the FactSystem + + Fact* fact = parameterFacts["RC_MAP_THROTTLE"].value(); + QVERIFY(fact != NULL); + QVariant factValue = fact->value(); + QCOMPARE(factValue.isValid(), true); + + QVariant paramValue; + Q_ASSERT(_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramValue)); + + QCOMPARE(factValue.toInt(), paramValue.toInt()); +} + +/// Test that QML can reference a Fact +void FactSystemTestBase::_qml_test(void) +{ + QGCQuickWidget* widget = new QGCQuickWidget; + + widget->setAutoPilot(_plugin); + + widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml")); + + QQuickItem* rootObject = widget->rootObject(); + QObject* control = rootObject->findChild("testControl"); + QVERIFY(control != NULL); + QVariant qmlValue = control->property("text").toInt(); + + QVariant paramMgrValue; + Q_ASSERT(_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramMgrValue)); + + QCOMPARE(qmlValue.toInt(), paramMgrValue.toInt()); +} + +// Test correct behavior when the Param Manager gets a parameter update +void FactSystemTestBase::_paramMgrSignal_test(void) +{ + // Get the parameter Fact from the AutoPilot + + const QVariantMap& parameterFacts = _plugin->parameters(); + + Fact* fact = parameterFacts["RC_MAP_THROTTLE"].value(); + QVERIFY(fact != NULL); + + // Setting a new value into the parameter should trigger a valueChanged signal on the Fact + + QSignalSpy spyFact(fact, SIGNAL(valueChanged(QVariant))); + + QVariant paramValue = 12; + _paramMgr->setParameter(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramValue); + _paramMgr->sendPendingParameters(true, false); + + // Wait for the Fact::valueChanged signal to come through + QCOMPARE(spyFact.wait(5000), true); + + // Make sure the signal has the right value + QList arguments = spyFact.takeFirst(); + qDebug() << arguments.at(0).type(); + QCOMPARE(arguments.at(0).toInt(), 12); + + // Make sure the Fact has the new value + QCOMPARE(fact->value().toInt(), 12); +} + +/// Test QML getting an updated Fact value +void FactSystemTestBase::_qmlUpdate_test(void) +{ + QGCQuickWidget* widget = new QGCQuickWidget; + + widget->setAutoPilot(_plugin); + + widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml")); + + // Change the value using param manager + + QVariant paramValue = 12; + _paramMgr->setParameter(_paramMgr->getDefaultComponentId(), "RC_MAP_THROTTLE", paramValue); + _paramMgr->sendPendingParameters(true, false); + + QTest::qWait(500); // Let the signals flow through + + // Make sure the qml has the right value + + QQuickItem* rootObject = widget->rootObject(); + QObject* control = rootObject->findChild("testControl"); + QVERIFY(control != NULL); + QCOMPARE(control->property("text").toInt(), 12); +} + diff --git a/src/FactSystem/FactSystemTestBase.h b/src/FactSystem/FactSystemTestBase.h new file mode 100644 index 0000000..818f765 --- /dev/null +++ b/src/FactSystem/FactSystemTestBase.h @@ -0,0 +1,57 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#ifndef FactSystemTestBase_H +#define FactSystemTestBase_H + +#include "UnitTest.h" +#include "UASInterface.h" +#include "AutoPilotPlugin.h" + +// Base class for FactSystemTest[PX4|Generic] unit tests +class FactSystemTestBase : public UnitTest +{ + Q_OBJECT + +public: + FactSystemTestBase(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); + + UASInterface* _uas; + QGCUASParamManagerInterface* _paramMgr; + AutoPilotPlugin* _plugin; + LinkManager* _linkMgr; +}; + +#endif diff --git a/src/FactSystem/FactSystemTestGeneric.cc b/src/FactSystem/FactSystemTestGeneric.cc new file mode 100644 index 0000000..dc86e1f --- /dev/null +++ b/src/FactSystem/FactSystemTestGeneric.cc @@ -0,0 +1,49 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "FactSystemTestGeneric.h" +#include "LinkManager.h" +#include "MockLink.h" +#include "AutoPilotPluginManager.h" +#include "UASManager.h" +#include "QGCApplication.h" +#include "QGCQuickWidget.h" + +#include + +UT_REGISTER_TEST(FactSystemTestGeneric) + +/// FactSystem Unit Test for PX4 autpilot +FactSystemTestGeneric::FactSystemTestGeneric(void) +{ + +} + +void FactSystemTestGeneric::init(void) +{ + UnitTest::init(); + _init(MAV_AUTOPILOT_ARDUPILOTMEGA); +} diff --git a/src/FactSystem/FactSystemTestGeneric.h b/src/FactSystem/FactSystemTestGeneric.h new file mode 100644 index 0000000..0435ccf --- /dev/null +++ b/src/FactSystem/FactSystemTestGeneric.h @@ -0,0 +1,52 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#ifndef 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 diff --git a/src/FactSystem/FactSystemTestPX4.cc b/src/FactSystem/FactSystemTestPX4.cc new file mode 100644 index 0000000..2e30f72 --- /dev/null +++ b/src/FactSystem/FactSystemTestPX4.cc @@ -0,0 +1,49 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "FactSystemTestPX4.h" +#include "LinkManager.h" +#include "MockLink.h" +#include "AutoPilotPluginManager.h" +#include "UASManager.h" +#include "QGCApplication.h" +#include "QGCQuickWidget.h" + +#include + +UT_REGISTER_TEST(FactSystemTestPX4) + +/// FactSystem Unit Test for PX4 autpilot +FactSystemTestPX4::FactSystemTestPX4(void) +{ + +} + +void FactSystemTestPX4::init(void) +{ + UnitTest::init(); + _init(MAV_AUTOPILOT_PX4); +} diff --git a/src/FactSystem/FactSystemTestPX4.h b/src/FactSystem/FactSystemTestPX4.h new file mode 100644 index 0000000..54118e9 --- /dev/null +++ b/src/FactSystem/FactSystemTestPX4.h @@ -0,0 +1,52 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#ifndef 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 diff --git a/src/qgcunittest/MainWindowTest.cc b/src/qgcunittest/MainWindowTest.cc index 3aa5b71..da0dec5 100644 --- a/src/qgcunittest/MainWindowTest.cc +++ b/src/qgcunittest/MainWindowTest.cc @@ -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); +} diff --git a/src/qgcunittest/MainWindowTest.h b/src/qgcunittest/MainWindowTest.h index 87eb827..e37cf9e 100644 --- a/src/qgcunittest/MainWindowTest.h +++ b/src/qgcunittest/MainWindowTest.h @@ -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; }; diff --git a/src/qgcunittest/MockLink.cc b/src/qgcunittest/MockLink.cc index cad0dcc..16a00e6 100644 --- a/src/qgcunittest/MockLink.cc +++ b/src/qgcunittest/MockLink.cc @@ -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 diff --git a/src/qgcunittest/MockLink.h b/src/qgcunittest/MockLink.h index d6814b4..5fbfdc0 100644 --- a/src/qgcunittest/MockLink.h +++ b/src/qgcunittest/MockLink.h @@ -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