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);