Commit 5f5c6204 authored by Don Gagne's avatar Don Gagne

Merge pull request #1606 from DonLakeFlyer/FactPanel

FactPanel V2 (much better missing parameter handling)
parents c8b92a9a 1856e1cb
......@@ -620,7 +620,6 @@ INCLUDEPATH += \
HEADERS += \
src/FactSystem/Fact.h \
src/FactSystem/FactBinder.h \
src/FactSystem/FactMetaData.h \
src/FactSystem/FactSystem.h \
src/FactSystem/FactValidator.h \
......@@ -629,7 +628,6 @@ HEADERS += \
SOURCES += \
src/FactSystem/Fact.cc \
src/FactSystem/FactBinder.cc \
src/FactSystem/FactMetaData.cc \
src/FactSystem/FactSystem.cc \
src/FactSystem/FactValidator.cc \
......
......@@ -43,6 +43,11 @@ AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
connect(this, &AutoPilotPlugin::pluginReadyChanged, this, &AutoPilotPlugin::_pluginReadyChanged);
}
AutoPilotPlugin::~AutoPilotPlugin()
{
}
void AutoPilotPlugin::_uasDisconnected(void)
{
_pluginReady = false;
......@@ -112,14 +117,14 @@ void AutoPilotPlugin::refreshParametersPrefix(int componentId, const QString& na
_getParameterLoader()->refreshParametersPrefix(componentId, namePrefix);
}
bool AutoPilotPlugin::parameterExists(const QString& name)
bool AutoPilotPlugin::parameterExists(int componentId, const QString& name)
{
return _getParameterLoader()->parameterExists(FactSystem::defaultComponentId, name);
return _getParameterLoader()->parameterExists(componentId, name);
}
Fact* AutoPilotPlugin::getParameterFact(const QString& name)
Fact* AutoPilotPlugin::getParameterFact(int componentId, const QString& name)
{
return _getParameterLoader()->getFact(FactSystem::defaultComponentId, name);
return _getParameterLoader()->getFact(componentId, name);
}
bool AutoPilotPlugin::factExists(FactSystem::Provider_t provider, int componentId, const QString& name)
......
......@@ -51,6 +51,7 @@ class AutoPilotPlugin : public QObject
public:
AutoPilotPlugin(UASInterface* uas, QObject* parent);
~AutoPilotPlugin();
/// true: plugin is ready for use, plugin should no longer be used
Q_PROPERTY(bool pluginReady READ pluginReady NOTIFY pluginReadyChanged)
......@@ -71,16 +72,16 @@ public:
Q_INVOKABLE void refreshParametersPrefix(int componentId, const QString& namePrefix);
/// Returns true if the specifed parameter exists from the default component
Q_INVOKABLE bool parameterExists(const QString& name);
Q_INVOKABLE bool parameterExists(int componentId, const QString& name);
/// Returns all parameter names
/// FIXME: component id missing, generic to fact
QStringList parameterNames(void);
/// Returns the specified parameter Fact from the default component
/// WARNING: Will assert if fact does not exists. If that possibility exists, check for existince first with
/// factExists.
Fact* getParameterFact(const QString& name);
/// WARNING: Returns a default Fact if parameter does not exists. If that possibility exists, check for existince first with
/// parameterExists.
Fact* getParameterFact(int componentId, const QString& name);
/// Writes the parameter facts to the specified stream
void writeParametersToStream(QTextStream &stream);
......
......@@ -74,13 +74,13 @@ void AutoPilotPluginManager::_uasCreated(UASInterface* uas)
case MAV_AUTOPILOT_PX4:
plugin = new PX4AutoPilotPlugin(uas, this);
Q_CHECK_PTR(plugin);
_pluginMap[MAV_AUTOPILOT_PX4][uasId] = plugin;
_pluginMap[MAV_AUTOPILOT_PX4][uasId] = QSharedPointer<AutoPilotPlugin>(plugin);
break;
case MAV_AUTOPILOT_GENERIC:
default:
plugin = new GenericAutoPilotPlugin(uas, this);
Q_CHECK_PTR(plugin);
_pluginMap[MAV_AUTOPILOT_GENERIC][uasId] = plugin;
_pluginMap[MAV_AUTOPILOT_GENERIC][uasId] = QSharedPointer<AutoPilotPlugin>(plugin);
}
}
......@@ -94,12 +94,12 @@ void AutoPilotPluginManager::_uasDeleted(UASInterface* uas)
Q_ASSERT(uasId != 0);
if (_pluginMap.contains(autopilotType) && _pluginMap[autopilotType].contains(uasId)) {
delete _pluginMap[autopilotType][uasId];
_pluginMap[autopilotType][uasId].clear();
_pluginMap[autopilotType].remove(uasId);
}
}
AutoPilotPlugin* AutoPilotPluginManager::getInstanceForAutoPilotPlugin(UASInterface* uas)
QSharedPointer<AutoPilotPlugin> AutoPilotPluginManager::getInstanceForAutoPilotPlugin(UASInterface* uas)
{
Q_ASSERT(uas);
......
......@@ -47,9 +47,10 @@ class AutoPilotPluginManager : public QGCSingleton
DECLARE_QGC_SINGLETON(AutoPilotPluginManager, AutoPilotPluginManager)
public:
/// Returns the singleton AutoPilotPlugin instance for the specified uas.
/// Returns the singleton AutoPilotPlugin instance for the specified uas. Returned as QSharedPointer
/// to prevent shutdown ordering problems with Qml destruction happening after Facts are destroyed.
/// @param uas Uas to get plugin for
AutoPilotPlugin* getInstanceForAutoPilotPlugin(UASInterface* uas);
QSharedPointer<AutoPilotPlugin> getInstanceForAutoPilotPlugin(UASInterface* uas);
typedef struct {
uint8_t baseMode;
......@@ -73,7 +74,7 @@ private:
MAV_AUTOPILOT _installedAutopilotType(MAV_AUTOPILOT autopilot);
QMap<MAV_AUTOPILOT, QMap<int, AutoPilotPlugin*> > _pluginMap; ///< Map of AutoPilot plugins _pluginMap[MAV_TYPE][UASid]
QMap<MAV_AUTOPILOT, QMap<int, QSharedPointer<AutoPilotPlugin> > > _pluginMap; ///< Map of AutoPilot plugins _pluginMap[MAV_TYPE][UASid]
};
#endif
......@@ -142,7 +142,7 @@ bool AirframeComponent::requiresSetup(void) const
bool AirframeComponent::setupComplete(void) const
{
return _autopilot->getParameterFact("SYS_AUTOSTART")->value().toInt() != 0;
return _autopilot->getParameterFact(FactSystem::defaultComponentId, "SYS_AUTOSTART")->value().toInt() != 0;
}
QString AirframeComponent::setupStateDescription(void) const
......
......@@ -31,6 +31,7 @@ import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
QGCView {
id: rootQGCView
......@@ -67,7 +68,7 @@ QGCView {
"This configuration can only be modified through the Parameter Editor.\n\n" +
"If you want to Reset your airframe configuration and select a standard configuration, click 'Reset' above."
Fact { id: sys_autostart; name: "SYS_AUTOSTART" }
property Fact sys_autostart: controller.getParameterFact(-1, "SYS_AUTOSTART")
function accept() {
sys_autostart.value = 0
......@@ -107,7 +108,7 @@ QGCView {
QGCLabel {
id: header
width: parent.width
font.pointSize: 20
font.pointSize: ScreenTools.largeFontPointSize
text: "AIRFRAME CONFIG"
}
......
......@@ -48,16 +48,16 @@ AirframeComponentController::AirframeComponentController(void) :
qmlRegisterUncreatableType<Airframe>("QGroundControl.Controllers", 1, 0, "Aiframe", "Can only reference Airframe");
}
QStringList usedFacts;
usedFacts << "SYS_AUTOSTART" << "SYS_AUTOCONFIG";
if (!_allFactsExists(usedFacts)) {
QStringList usedParams;
usedParams << "SYS_AUTOSTART" << "SYS_AUTOCONFIG";
if (!_allParametersExists(FactSystem::defaultComponentId, usedParams)) {
return;
}
// Load up member variables
bool autostartFound = false;
_autostartId = _autopilot->getParameterFact("SYS_AUTOSTART")->value().toInt();
_autostartId = getParameterFact(FactSystem::defaultComponentId, "SYS_AUTOSTART")->value().toInt();
for (const AirframeComponentAirframes::AirframeType_t* pType=&AirframeComponentAirframes::rgAirframeTypes[0]; pType->name != NULL; pType++) {
AirframeType* airframeType = new AirframeType(pType->name, pType->imageResource, this);
......@@ -99,9 +99,8 @@ void AirframeComponentController::changeAutostart(void)
qgcApp()->setOverrideCursor(Qt::WaitCursor);
_autopilot->getParameterFact("SYS_AUTOSTART")->setValue(_autostartId);
_autopilot->getParameterFact("SYS_AUTOCONFIG")->setValue(1);
getParameterFact(-1, "SYS_AUTOSTART")->setValue(_autostartId);
getParameterFact(-1, "SYS_AUTOCONFIG")->setValue(1);
// Wait for the parameters to flow through system
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
......
......@@ -5,15 +5,18 @@ import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.Palette 1.0
FactPanel {
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
AirframeComponentController { id: controller; factPanel: panel }
Fact { id: sysIdFact; name: "MAV_SYS_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: sysAutoStartFact; name: "SYS_AUTOSTART"; onFactMissing: showMissingFactOverlay(name) }
property Fact sysIdFact: controller.getParameterFact(-1, "MAV_SYS_ID")
property Fact sysAutoStartFact: controller.getParameterFact(-1, "SYS_AUTOSTART")
property bool autoStartSet: sysAutoStartFact.value != 0
......
......@@ -73,7 +73,7 @@ bool FlightModesComponent::requiresSetup(void) const
bool FlightModesComponent::setupComplete(void) const
{
return _autopilot->getParameterFact("RC_MAP_MODE_SW")->value().toInt() != 0;
return _autopilot->getParameterFact(FactSystem::defaultComponentId, "RC_MAP_MODE_SW")->value().toInt() != 0;
}
QString FlightModesComponent::setupStateDescription(void) const
......
......@@ -34,13 +34,14 @@ import QGroundControl.ScreenTools 1.0
Item {
Loader {
property FlightModesComponentController controller: FlightModesComponentController { }
id: loader
anchors.fill: parent
sourceComponent: controller.validConfiguration ? validComponent : invalidComponent
property FlightModesComponentController controller: FlightModesComponentController { factPanel: loader.item }
property QGCPalette qgcPal: QGCPalette { colorGroupEnabled: true }
property bool loading: true
anchors.fill: parent
sourceComponent: controller.validConfiguration ? validComponent : invalidComponent
onLoaded: loading = false
}
......@@ -48,30 +49,28 @@ Item {
id: validComponent
FactPanel {
Fact { id: rc_map_throttle; name: "RC_MAP_THROTTLE"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_yaw; name: "RC_MAP_YAW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_pitch; name: "RC_MAP_PITCH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_roll; name: "RC_MAP_ROLL"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_flaps; name: "RC_MAP_FLAPS"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_aux1; name: "RC_MAP_AUX1"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_aux2; name: "RC_MAP_AUX2"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_mode_sw; name: "RC_MAP_MODE_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_posctl_sw; name: "RC_MAP_POSCTL_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_return_sw; name: "RC_MAP_RETURN_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_offboard_sw; name: "RC_MAP_OFFB_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_loiter_sw; name: "RC_MAP_LOITER_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_map_acro_sw; name: "RC_MAP_ACRO_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_posctl_th; name: "RC_POSCTL_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_return_th; name: "RC_RETURN_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_offboard_th; name: "RC_OFFB_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_loiter_th; name: "RC_LOITER_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_acro_th; name: "RC_ACRO_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_assist_th; name: "RC_ASSIST_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_auto_th; name: "RC_AUTO_TH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: rc_th_user; name: "RC_TH_USER"; onFactMissing: showMissingFactOverlay(name) }
property Fact rc_map_throttle: controller.getParameterFact(-1, "RC_MAP_THROTTLE")
property Fact rc_map_yaw: controller.getParameterFact(-1, "RC_MAP_YAW")
property Fact rc_map_pitch: controller.getParameterFact(-1, "RC_MAP_PITCH")
property Fact rc_map_roll: controller.getParameterFact(-1, "RC_MAP_ROLL")
property Fact rc_map_flaps: controller.getParameterFact(-1, "RC_MAP_FLAPS")
property Fact rc_map_aux1: controller.getParameterFact(-1, "RC_MAP_AUX1")
property Fact rc_map_aux2: controller.getParameterFact(-1, "RC_MAP_AUX2")
property Fact rc_map_mode_sw: controller.getParameterFact(-1, "RC_MAP_MODE_SW")
property Fact rc_map_posctl_sw: controller.getParameterFact(-1, "RC_MAP_POSCTL_SW")
property Fact rc_map_return_sw: controller.getParameterFact(-1, "RC_MAP_RETURN_SW")
property Fact rc_map_offboard_sw: controller.getParameterFact(-1, "RC_MAP_OFFB_SW")
property Fact rc_map_loiter_sw: controller.getParameterFact(-1, "RC_MAP_LOITER_SW")
property Fact rc_assist_th: controller.getParameterFact(-1, "RC_ASSIST_TH")
property Fact rc_posctl_th: controller.getParameterFact(-1, "RC_POSCTL_TH")
property Fact rc_auto_th: controller.getParameterFact(-1, "RC_AUTO_TH")
property Fact rc_loiter_th: controller.getParameterFact(-1, "RC_LOITER_TH")
property Fact rc_return_th: controller.getParameterFact(-1, "RC_RETURN_TH")
property Fact rc_offboard_th: controller.getParameterFact(-1, "RC_OFFB_TH")
property Fact rc_th_user: controller.getParameterFact(-1, "RC_TH_USER")
property int throttleChannel: rc_map_throttle.value
property int yawChannel: rc_map_yaw.value
......@@ -135,7 +134,7 @@ Item {
id: unassignedModeTileComponent
Rectangle {
Fact { id: fact; name: tileParam; onFactMissing: showMissingFactOverlay(name) }
property Fact fact: controller.getParameterFact(-1, tileParam)
property bool dragEnabled: fact.value == 0
id: outerRect
......@@ -221,7 +220,8 @@ Item {
id: assignedModeTileComponent
Rectangle {
Fact { id: fact; name: tileDragEnabled ? tileParam : ""; onFactMissing: showMissingFactOverlay(name) }
Fact{ id: nullFact }
property Fact fact: tileDragEnabled ? controller.getParameterFact(-1, tileParam) : nullFact
width: tileWidth
height: tileHeight
......@@ -362,7 +362,7 @@ Item {
QGCLabel {
text: "FLIGHT MODES CONFIG"
font.pointSize: ScreenTools.fontPointFactor * (20);
font.pointSize: ScreenTools.largeFontPointSize
}
Item { height: 20; width: 10 } // spacer
......@@ -624,10 +624,10 @@ Item {
Item { height: 20; width: 10 } // spacer
FactCheckBox {
checkedValue: 0
checkedValue: 0
uncheckedValue: 1
fact: rc_th_user
text: "Allow setup to generate the thresholds for the flight mode positions within a switch (recommended)"
fact: rc_th_user
text: "Allow setup to generate the thresholds for the flight mode positions within a switch (recommended)"
}
Item { height: 20; width: 10 } // spacer
......@@ -639,8 +639,9 @@ Item {
text: "Switch Display"
}
QGCCheckBox {
checked: controller.sendLiveRCSwitchRanges
text: "Show live RC display"
checked: controller.sendLiveRCSwitchRanges
text: "Show live RC display"
onClicked: {
controller.sendLiveRCSwitchRanges = checked
}
......@@ -650,11 +651,11 @@ Item {
Item { height: 20; width: 10 } // spacer
Row {
property bool modeSwitchVisible: modeChannel != 0
property bool loiterSwitchVisible: loiterChannel != 0 && loiterChannel != modeChannel && loiterChannel != returnChannel
property bool posCtlSwitchVisible: posCtlChannel != 0 && posCtlChannel != modeChannel
property bool returnSwitchVisible: returnChannel != 0
property bool offboardSwitchVisible: offboardChannel != 0
property bool modeSwitchVisible: modeChannel != 0
property bool loiterSwitchVisible: loiterChannel != 0 && loiterChannel != modeChannel && loiterChannel != returnChannel
property bool posCtlSwitchVisible: posCtlChannel != 0 && posCtlChannel != modeChannel
property bool returnSwitchVisible: returnChannel != 0
property bool offboardSwitchVisible: offboardChannel != 0
width: parent.width
spacing: 20
......@@ -882,7 +883,7 @@ Item {
Component {
id: invalidComponent
Rectangle {
FactPanel {
anchors.fill: parent
color: qgcPal.window
......
......@@ -32,20 +32,17 @@
#include <QVariant>
#include <QQmlProperty>
FlightModesComponentController::FlightModesComponentController(QObject* parent) :
QObject(parent),
FlightModesComponentController::FlightModesComponentController(void) :
_liveRCValues(false),
_validConfiguration(false),
_channelCount(18),
_autoPilotPlugin(NULL)
_channelCount(18)
{
_uas = UASManager::instance()->getActiveUAS();
Q_ASSERT(_uas);
QStringList usedParams;
usedParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2" << "RC_MAP_ACRO_SW";
if (!_allParametersExists(FactSystem::defaultComponentId, usedParams)) {
return;
}
_autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas);
Q_ASSERT(_autoPilotPlugin);
Q_ASSERT(_autoPilotPlugin->pluginReady());
_initRcValues();
_validateConfiguration();
}
......@@ -69,16 +66,14 @@ void FlightModesComponentController::_validateConfiguration(void)
{
_validConfiguration = true;
_channelCount = _autoPilotPlugin->parameterExists("RC_CHAN_CNT") ?
_autoPilotPlugin->getParameterFact("RC_CHAN_CNT")->value().toInt() :
_chanMax;
_channelCount = parameterExists(FactSystem::defaultComponentId, "RC_CHAN_CNT") ? getParameterFact(FactSystem::defaultComponentId, "RC_CHAN_CNT")->value().toInt() : _chanMax;
if (_channelCount <= 0 || _channelCount > _chanMax) {
// Parameter exists, but has not yet been set or is invalid. Use default
_channelCount = _chanMax;
}
// Acro is not full supported yet. If Acro is mapped you uhave to set up the hard way.
if (_autoPilotPlugin->getParameterFact("RC_MAP_ACRO_SW")->value().toInt() != 0) {
if (getParameterFact(FactSystem::defaultComponentId, "RC_MAP_ACRO_SW")->value().toInt() != 0) {
_validConfiguration = false;
_configurationErrors += "Flight Mode setup does not yet support Acro switch";
}
......@@ -92,7 +87,7 @@ void FlightModesComponentController::_validateConfiguration(void)
switchNames << "Mode Switch" << "Return Switch" << "Loiter Switch" << "PosCtl Switch" << "Offboard Switch";
for(int i=0; i<switchParams.count(); i++) {
int map = _autoPilotPlugin->getParameterFact(switchParams[i])->value().toInt();
int map = getParameterFact(FactSystem::defaultComponentId, switchParams[i])->value().toInt();
switchMappings << map;
if (map < 0 || map > _channelCount) {
......@@ -109,7 +104,7 @@ void FlightModesComponentController::_validateConfiguration(void)
attitudeNames << "Throttle" << "Yaw" << "Pitch" << "Roll" << "Flaps" << "Aux1" << "Aux2" << "Acro";
for (int i=0; i<attitudeParams.count(); i++) {
int map = _autoPilotPlugin->getParameterFact(attitudeParams[i])->value().toInt();
int map = getParameterFact(FactSystem::defaultComponentId, attitudeParams[i])->value().toInt();
for (int j=0; j<switchParams.count(); j++) {
if (map != 0 && map == switchMappings[j]) {
......@@ -127,7 +122,7 @@ void FlightModesComponentController::_validateConfiguration(void)
singleSwitchNames << "Return Switch" << "Offboard Switch";
for (int i=0; i<singleSwitchParams.count(); i++) {
int map = _autoPilotPlugin->getParameterFact(singleSwitchParams[i])->value().toInt();
int map = getParameterFact(FactSystem::defaultComponentId, singleSwitchParams[i])->value().toInt();
for (int j=0; j<switchParams.count(); j++) {
if (map != 0 && singleSwitchParams[i] != switchParams[j] && map == switchMappings[j]) {
......@@ -152,10 +147,10 @@ void FlightModesComponentController::setSendLiveRCSwitchRanges(bool start)
QVariant value;
_rgRCMin[i] = _autoPilotPlugin->getParameterFact(rcMinParam)->value().toInt();
_rgRCMax[i] = _autoPilotPlugin->getParameterFact(rcMaxParam)->value().toInt();
_rgRCMin[i] = getParameterFact(FactSystem::defaultComponentId, rcMinParam)->value().toInt();
_rgRCMax[i] = getParameterFact(FactSystem::defaultComponentId, rcMaxParam)->value().toInt();
float floatReversed = _autoPilotPlugin->getParameterFact(rcRevParam)->value().toFloat();
float floatReversed = getParameterFact(-1, rcRevParam)->value().toFloat();
_rgRCReversed[i] = floatReversed == -1.0f;
}
......@@ -196,7 +191,7 @@ double FlightModesComponentController::_switchLiveRange(const QString& param)
{
QVariant value;
int channel = _autoPilotPlugin->getParameterFact(param)->value().toInt();
int channel = getParameterFact(-1, param)->value().toInt();
if (channel == 0) {
return 1.0;
} else {
......
......@@ -33,14 +33,15 @@
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
#include "FactPanelController.h"
/// MVC Controller for FlightModesComponent.qml.
class FlightModesComponentController : public QObject
class FlightModesComponentController : public FactPanelController
{
Q_OBJECT
public:
FlightModesComponentController(QObject* parent = NULL);
FlightModesComponentController(void);
~FlightModesComponentController();
Q_PROPERTY(bool validConfiguration MEMBER _validConfiguration CONSTANT)
......@@ -79,8 +80,6 @@ private:
static const int _chanMax = 18;
UASInterface* _uas;
QList<double> _rcValues;
bool _liveRCValues;
int _rgRCMin[_chanMax];
......@@ -90,8 +89,6 @@ private:
bool _validConfiguration;
QString _configurationErrors;
int _channelCount;
AutoPilotPlugin* _autoPilotPlugin;
};
#endif
......@@ -4,14 +4,20 @@ import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
FactPanel {
anchors.fill: parent
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
Fact { id: modeSwFact; name: "RC_MAP_MODE_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: posCtlSwFact; name: "RC_MAP_POSCTL_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: loiterSwFact; name: "RC_MAP_LOITER_SW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: returnSwFact; name: "RC_MAP_RETURN_SW"; onFactMissing: showMissingFactOverlay(name) }
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact modeSwFact: controller.getParameterFact(-1, "RC_MAP_MODE_SW")
property Fact posCtlSwFact: controller.getParameterFact(-1, "RC_MAP_POSCTL_SW")
property Fact loiterSwFact: controller.getParameterFact(-1, "RC_MAP_LOITER_SW")
property Fact returnSwFact: controller.getParameterFact(-1, "RC_MAP_RETURN_SW")
Column {
anchors.fill: parent
......
......@@ -249,7 +249,7 @@ void PX4AutoPilotPlugin::_pluginReadyPreChecks(void)
// Check for older parameter version set
// FIXME: Firmware is moving to version stamp parameter set. Once that is complete the version stamp
// should be used instead.
if (parameterExists("SENS_GYRO_XOFF")) {
if (parameterExists(FactSystem::defaultComponentId, "SENS_GYRO_XOFF")) {
_incorrectParameterVersion = true;
QGCMessageBox::warning("Setup", "This version of GroundControl can only perform vehicle setup on a newer version of firmware. "
"Please perform a Firmware Upgrade if you wish to use Vehicle Setup.");
......
......@@ -39,7 +39,7 @@ void PX4Component::setupTriggerSignals(void)
{
// Watch for changed on trigger list params
foreach (QString paramName, setupCompleteChangedTriggerList()) {
Fact* fact = _autopilot->getParameterFact(paramName);
Fact* fact = _autopilot->getParameterFact(FactSystem::defaultComponentId, paramName);
connect(fact, &Fact::valueChanged, this, &PX4Component::_triggerUpdated);
}
......
......@@ -58,9 +58,9 @@ bool PowerComponent::requiresSetup(void) const
bool PowerComponent::setupComplete(void) const
{
QVariant cvalue, evalue, nvalue;
return _autopilot->getParameterFact("BAT_V_CHARGED")->value().toFloat() != 0.0f &&
_autopilot->getParameterFact("BAT_V_EMPTY")->value().toFloat() != 0.0f &&
_autopilot->getParameterFact("BAT_N_CELLS")->value().toInt() != 0;
return _autopilot->getParameterFact(FactSystem::defaultComponentId, "BAT_V_CHARGED")->value().toFloat() != 0.0f &&
_autopilot->getParameterFact(FactSystem::defaultComponentId, "BAT_V_EMPTY")->value().toFloat() != 0.0f &&
_autopilot->getParameterFact(FactSystem::defaultComponentId, "BAT_N_CELLS")->value().toInt() != 0;
}
QString PowerComponent::setupStateDescription(void) const
......
......@@ -55,9 +55,10 @@ QGCView {
property int firstColumnWidth: 220
property int textEditWidth: 80
property Fact battNumCells: Fact { name: "BAT_N_CELLS"; onFactMissing: showMissingFactOverlay(name) }
property Fact battHighVolt: Fact { name: "BAT_V_CHARGED"; onFactMissing: showMissingFactOverlay(name) }
property Fact battLowVolt: Fact { name: "BAT_V_EMPTY"; onFactMissing: showMissingFactOverlay(name) }
property Fact battNumCells: controller.getParameterFact(-1, "BAT_N_CELLS")
property Fact battHighVolt: controller.getParameterFact(-1, "BAT_V_CHARGED")
property Fact battLowVolt: controller.getParameterFact(-1, "BAT_V_EMPTY")
property Fact battVoltLoadDrop: controller.getParameterFact(-1, "BAT_V_LOAD_DROP")
property alias battHigh: battHighRow
property alias battLow: battLowRow
......@@ -150,7 +151,7 @@ QGCView {
FactTextField {
id: cellsField
width: textEditWidth
fact: Fact { name: "BAT_N_CELLS"; onFactMissing: showMissingFactOverlay(name) }
fact: battNumCells
showUnits: true
}
}
......@@ -161,7 +162,7 @@ QGCView {
FactTextField {
id: battHighField
width: textEditWidth
fact: Fact { name: "BAT_V_CHARGED"; onFactMissing: showMissingFactOverlay(name) }
fact: battHighVolt
showUnits: true
}
}
......@@ -172,7 +173,7 @@ QGCView {
FactTextField {
id: battLowField
width: textEditWidth
fact: Fact { name: "BAT_V_EMPTY"; onFactMissing: showMissingFactOverlay(name) }
fact: battLowVolt
showUnits: true
}
}
......@@ -332,7 +333,7 @@ QGCView {
FactTextField {
id: battDropField
width: textEditWidth
fact: Fact { name: "BAT_V_LOAD_DROP"; onFactMissing: showMissingFactOverlay(name) }
fact: battVoltLoadDrop
showUnits: true
}
}
......
......@@ -31,13 +31,19 @@ import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
FactPanel {
anchors.fill: parent
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
Fact { id: batVChargedFact; name: "BAT_V_CHARGED"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: batVEmptyFact; name: "BAT_V_EMPTY"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: batCellsFact; name: "BAT_N_CELLS"; onFactMissing: showMissingFactOverlay(name) }
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact batVChargedFact: controller.getParameterFact(-1, "BAT_V_CHARGED")
property Fact batVEmptyFact: controller.getParameterFact(-1, "BAT_V_EMPTY")
property Fact batCellsFact: controller.getParameterFact(-1, "BAT_N_CELLS")
Column {
anchors.fill: parent
......
......@@ -62,7 +62,7 @@ bool RadioComponent::setupComplete(void) const
QStringList attitudeMappings;
attitudeMappings << "RC_MAP_ROLL" << "RC_MAP_PITCH" << "RC_MAP_YAW" << "RC_MAP_THROTTLE";
foreach(QString mapParam, attitudeMappings) {
if (_autopilot->getParameterFact(mapParam)->value().toInt() == 0) {
if (_autopilot->getParameterFact(FactSystem::defaultComponentId, mapParam)->value().toInt() == 0) {
return false;
}
}
......@@ -80,13 +80,13 @@ bool RadioComponent::setupComplete(void) const
QString param;
param = QString("RC%1_MIN").arg(i);
rcMin = _autopilot->getParameterFact(param)->value().toInt();
rcMin = _autopilot->getParameterFact(FactSystem::defaultComponentId, param)->value().toInt();
param = QString("RC%1_MAX").arg(i);
rcMax = _autopilot->getParameterFact(param)->value().toInt();
rcMax = _autopilot->getParameterFact(FactSystem::defaultComponentId, param)->value().toInt();
param = QString("RC%1_TRIM").arg(i);
rcTrim = _autopilot->getParameterFact(param)->value().toInt();
rcTrim = _autopilot->getParameterFact(FactSystem::defaultComponentId, param)->value().toInt();
if (rcMin == rcMinDefault && rcMax == rcMaxDefault && rcTrim == rcTrimDefault) {
return false;
......
......@@ -4,17 +4,23 @@ import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
FactPanel {
anchors.fill: parent
Fact { id: mapRollFact; name: "RC_MAP_ROLL"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: mapPitchFact; name: "RC_MAP_PITCH"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: mapYawFact; name: "RC_MAP_YAW"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: mapThrottleFact; name: "RC_MAP_THROTTLE"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: mapFlapsFact; name: "RC_MAP_FLAPS"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: mapAux1Fact; name: "RC_MAP_AUX1"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: mapAux2Fact; name: "RC_MAP_AUX2"; onFactMissing: showMissingFactOverlay(name) }
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact mapRollFact: controller.getParameterFact(-1, "RC_MAP_ROLL")
property Fact mapPitchFact: controller.getParameterFact(-1, "RC_MAP_PITCH")
property Fact mapYawFact: controller.getParameterFact(-1, "RC_MAP_YAW")
property Fact mapThrottleFact: controller.getParameterFact(-1, "RC_MAP_THROTTLE")
property Fact mapFlapsFact: controller.getParameterFact(-1, "RC_MAP_FLAPS")
property Fact mapAux1Fact: controller.getParameterFact(-1, "RC_MAP_AUX1")
property Fact mapAux2Fact: controller.getParameterFact(-1, "RC_MAP_AUX2")
Column {
anchors.fill: parent
......
......@@ -4,15 +4,21 @@ import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
FactPanel {
anchors.fill: parent
Fact { id: returnAltFact; name: "RTL_RETURN_ALT"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: descendAltFact; name: "RTL_DESCEND_ALT"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: landDelayFact; name: "RTL_LAND_DELAY"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: commDLLossFact; name: "COM_DL_LOSS_EN"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: commRCLossFact; name: "COM_RC_LOSS_T"; onFactMissing: showMissingFactOverlay(name) }
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact returnAltFact: controller.getParameterFact(-1, "RTL_RETURN_ALT")
property Fact descendAltFact: controller.getParameterFact(-1, "RTL_DESCEND_ALT")
property Fact landDelayFact: controller.getParameterFact(-1, "RTL_LAND_DELAY")
property Fact commDLLossFact: controller.getParameterFact(-1, "COM_DL_LOSS_EN")
property Fact commRCLossFact: controller.getParameterFact(-1, "COM_RC_LOSS_T")
Column {
anchors.fill: parent
......
......@@ -62,7 +62,7 @@ bool SensorsComponent::requiresSetup(void) const
bool SensorsComponent::setupComplete(void) const
{
foreach(QString triggerParam, setupCompleteChangedTriggerList()) {
if (_autopilot->getParameterFact(triggerParam)->value().toFloat() == 0.0f) {
if (_autopilot->getParameterFact(FactSystem::defaultComponentId, triggerParam)->value().toFloat() == 0.0f) {
return false;
}
}
......
......@@ -91,12 +91,19 @@ QGCView {
"ROTATION_ROLL_270_YAW_270"
]
Fact { id: cal_mag0_id; name: "CAL_MAG0_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: cal_mag1_id; name: "CAL_MAG1_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: cal_mag2_id; name: "CAL_MAG2_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: cal_mag0_rot; name: "CAL_MAG0_ROT"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: cal_mag1_rot; name: "CAL_MAG1_ROT"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: cal_mag2_rot; name: "CAL_MAG2_ROT"; onFactMissing: showMissingFactOverlay(name) }
property Fact cal_mag0_id: controller.getParameterFact(-1, "CAL_MAG0_ID")
property Fact cal_mag1_id: controller.getParameterFact(-1, "CAL_MAG1_ID")
property Fact cal_mag2_id: controller.getParameterFact(-1, "CAL_MAG2_ID")
property Fact cal_mag0_rot: controller.getParameterFact(-1, "CAL_MAG0_ROT")
property Fact cal_mag1_rot: controller.getParameterFact(-1, "CAL_MAG1_ROT")
property Fact cal_mag2_rot: controller.getParameterFact(-1, "CAL_MAG2_ROT")
property Fact cal_gyro0_id: controller.getParameterFact(-1, "CAL_GYRO0_ID")
property Fact cal_acc0_id: controller.getParameterFact(-1, "CAL_ACC0_ID")
property Fact sens_board_rot: controller.getParameterFact(-1, "SENS_BOARD_ROT")
property Fact sens_board_x_off: controller.getParameterFact(-1, "SENS_BOARD_X_OFF")
property Fact sens_dpres_off: controller.getParameterFact(-1, "SENS_DPRES_OFF")
// Id > = signals compass available, rot < 0 signals internal compass
property bool showCompass0Rot: cal_mag0_id.value > 0 && cal_mag0_rot.value >= 0
......@@ -165,7 +172,7 @@ QGCView {
width: rotationColumnWidth
model: rotations
visible: preCalibrationDialogType != "airspeed" && (preCalibrationDialogType != "gyro")
fact: Fact { name: "SENS_BOARD_ROT"; onFactMissing: showMissingFactOverlay(name) }
fact: sens_board_rot
}
}
}
......@@ -204,7 +211,7 @@ QGCView {
id: compass0RotationCombo
width: rotationColumnWidth
model: rotations
fact: Fact { name: "CAL_MAG0_ROT"; onFactMissing: showMissingFactOverlay(name) }
fact: cal_mag0_rot
}
}
Loader { sourceComponent: showCompass0Rot ? compass0ComponentLabel : null }
......@@ -222,7 +229,7 @@ QGCView {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: Fact { name: "CAL_MAG1_ROT"; onFactMissing: showMissingFactOverlay(name) }
fact: cal_mag1_rot
}
}
Loader { sourceComponent: showCompass1Rot ? compass1ComponentLabel : null }
......@@ -241,7 +248,7 @@ QGCView {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: Fact { name: "CAL_MAG2_ROT"; onFactMissing: showMissingFactOverlay(name) }
fact: cal_mag2_rot
}
}
Loader { sourceComponent: showCompass2Rot ? compass2ComponentLabel : null }
......@@ -285,7 +292,7 @@ QGCView {
QGCLabel {
text: "SENSORS CONFIG"
font.pointSize: ScreenTools.fontPointFactor * (20);
font.pointSize: ScreenTools.largeFontPointSize
}
Item { height: 20; width: 10 } // spacer
......@@ -298,12 +305,10 @@ QGCView {
QGCLabel { text: "Calibrate:"; anchors.baseline: compassButton.baseline }
IndicatorButton {
property Fact fact: Fact { name: "CAL_MAG0_ID" }
id: compassButton
width: parent.buttonWidth
text: "Compass"
indicatorGreen: fact.value != 0
indicatorGreen: cal_mag0_id.value != 0
onClicked: {
preCalibrationDialogType = "compass"
......@@ -313,12 +318,10 @@ QGCView {
}
IndicatorButton {
property Fact fact: Fact { name: "CAL_GYRO0_ID" }
id: gyroButton
width: parent.buttonWidth
text: "Gyroscope"
indicatorGreen: fact.value != 0
indicatorGreen: cal_gyro0_id.value != 0
onClicked: {
preCalibrationDialogType = "gyro"
......@@ -328,12 +331,10 @@ QGCView {
}
IndicatorButton {
property Fact fact: Fact { name: "CAL_ACC0_ID" }
id: accelButton
width: parent.buttonWidth
text: "Accelerometer"
indicatorGreen: fact.value != 0
indicatorGreen: cal_acc0_id.value != 0
onClicked: {
preCalibrationDialogType = "accel"
......@@ -343,15 +344,11 @@ QGCView {
}
IndicatorButton {
property Fact fact: Fact { name: "SENS_BOARD_X_OFF" }
property Fact checkAcc: Fact { name: "CAL_ACC0_ID" }
property Fact checkGyro: Fact { name: "CAL_GYRO0_ID" }
id: levelButton
width: parent.buttonWidth
text: "Level Horizon"
indicatorGreen: fact.value != 0
enabled: checkAcc.value != 0 && checkGyro.value != 0
indicatorGreen: sens_board_x_off.value != 0
enabled: cal_acc0_id.value != 0 && cal_gyro0_id.value != 0
onClicked: {
preCalibrationDialogType = "level"
......@@ -361,13 +358,11 @@ QGCView {
}
IndicatorButton {
property Fact fact: Fact { name: "SENS_DPRES_OFF" }
id: airspeedButton
width: parent.buttonWidth
text: "Airspeed"
visible: controller.fixedWing
indicatorGreen: fact.value != 0
indicatorGreen: sens_dpres_off.value != 0
onClicked: {
preCalibrationDialogType = "airspeed"
......@@ -511,7 +506,7 @@ QGCView {
id: boardRotationCombo
width: rotationColumnWidth;
model: rotations
fact: Fact { name: "SENS_BOARD_ROT" }
fact: sens_board_rot
}
}
......@@ -534,7 +529,7 @@ QGCView {
id: compass0RotationCombo
width: rotationColumnWidth
model: rotations
fact: Fact { name: "CAL_MAG0_ROT" }
fact: cal_mag0_rot
}
}
Loader { sourceComponent: showCompass0Rot ? compass0ComponentLabel2 : null }
......@@ -559,7 +554,7 @@ QGCView {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: Fact { name: "CAL_MAG1_ROT" }
fact: cal_mag1_rot
}
}
Loader { sourceComponent: showCompass1Rot ? compass1ComponentLabel2 : null }
......@@ -584,7 +579,7 @@ QGCView {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: Fact { name: "CAL_MAG2_ROT" }
fact: cal_mag2_rot
}
}
Loader { sourceComponent: showCompass2Rot ? compass2ComponentLabel2 : null }
......
......@@ -69,13 +69,7 @@ SensorsComponentController::SensorsComponentController(void) :
_unknownFirmwareVersion(false),
_waitingForCancel(false)
{
// Mag rotation parameters are optional
_showCompass0 = _autopilot->parameterExists("CAL_MAG0_ROT") &&
_autopilot->getParameterFact("CAL_MAG0_ROT")->value().toInt() >= 0;
_showCompass1 = _autopilot->parameterExists("CAL_MAG1_ROT") &&
_autopilot->getParameterFact("CAL_MAG1_ROT")->value().toInt() >= 0;
_showCompass2 = _autopilot->parameterExists("CAL_MAG2_ROT") &&
_autopilot->getParameterFact("CAL_MAG2_ROT")->value().toInt() >= 0;
}
/// Appends the specified text to the status log area in the ui
......
......@@ -135,10 +135,6 @@ private:
bool _showGyroCalArea;
bool _showOrientationCalArea;
bool _showCompass0;
bool _showCompass1;
bool _showCompass2;
bool _gyroCalInProgress;
bool _magCalInProgress;
bool _accelCalInProgress;
......
......@@ -5,17 +5,23 @@ import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
/*
IMPORTANT NOTE: Any changes made here must also be made to SensorsComponentSummary.qml
*/
FactPanel {
anchors.fill: parent
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
Fact { id: mag0IdFact; name: "CAL_MAG0_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: gyro0IdFact; name: "CAL_GYRO0_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: accel0IdFact; name: "CAL_ACC0_ID"; onFactMissing: showMissingFactOverlay(name) }
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact mag0IdFact: controller.getParameterFact(-1, "CAL_MAG0_ID")
property Fact gyro0IdFact: controller.getParameterFact(-1, "CAL_GYRO0_ID")
property Fact accel0IdFact: controller.getParameterFact(-1, "CAL_ACC0_ID")
Column {
anchors.fill: parent
......
......@@ -4,18 +4,24 @@ import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
/*
IMPORTANT NOTE: Any changes made here must also be made to SensorsComponentSummary.qml
*/
FactPanel {
anchors.fill: parent
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
Fact { id: mag0IdFact; name: "CAL_MAG0_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: gyro0IdFact; name: "CAL_GYRO0_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: accel0IdFact; name: "CAL_ACC0_ID"; onFactMissing: showMissingFactOverlay(name) }
Fact { id: dPressOffFact; name: "SENS_DPRES_OFF"; onFactMissing: showMissingFactOverlay(name) }
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact mag0IdFact: controller.getParameterFact(-1, "CAL_MAG0_ID")
property Fact gyro0IdFact: controller.getParameterFact(-1, "CAL_GYRO0_ID")
property Fact accel0IdFact: controller.getParameterFact(-1, "CAL_ACC0_ID")
property Fact dpresssOffFact: controller.getParameterFact(-1, "SENS_DPRES_OFF")
Column {
anchors.fill: parent
......
......@@ -28,14 +28,25 @@
#include <QtQml>
Fact::Fact(void) :
_componentId(-1),
_value(0),
_type(FactMetaData::valueTypeInt32),
_metaData(NULL)
{
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
}
Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent) :
QObject(parent),
_name(name),
_componentId(componentId),
_value(0),
_type(type),
_metaData(NULL)
{
_value = 0;
}
void Fact::setValue(const QVariant& value)
......
......@@ -40,8 +40,24 @@ class Fact : public QObject
Q_OBJECT
public:
Fact(void);
Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent = NULL);
Q_PROPERTY(int componentId READ componentId CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged)
Q_PROPERTY(QString units READ units CONSTANT)
Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT)
Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT)
Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged)
Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT)
Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT)
Q_PROPERTY(QString longDescription READ longDescription CONSTANT)
Q_PROPERTY(QVariant min READ min CONSTANT)
Q_PROPERTY(QVariant max READ max CONSTANT)
Q_PROPERTY(QString group READ group CONSTANT)
// Property system methods
QString name(void) const;
......
/*=====================================================================
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 "FactBinder.h"
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include "QGCApplication.h"
#include <QDebug>
FactBinder::FactBinder(void) :
_autopilotPlugin(NULL),
_fact(NULL),
_componentId(FactSystem::defaultComponentId),
_factMissingSignalConnected(false)
{
UASInterface* uas = UASManager::instance()->getActiveUAS();
Q_ASSERT(uas);
_autopilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(uas);
Q_ASSERT(_autopilotPlugin);
Q_ASSERT(_autopilotPlugin->pluginReady());
}
QString FactBinder::name(void) const
{
if (_fact) {
return _fact->name();
} else {
return QString();
}
}
int FactBinder::componentId(void) const
{
return _componentId;
}
void FactBinder::setName(const QString& name)
{
if (_fact) {
disconnect(_fact, &Fact::valueChanged, this, &FactBinder::valueChanged);
_fact = NULL;
}
if (!name.isEmpty()) {
QString parsedName = name;
// Component id + name combination?
if (name.contains(":")) {
QStringList parts = name.split(":");
if (parts.count() == 2) {
parsedName = parts[0];
_componentId = parts[1].toInt();
}
}
if (_autopilotPlugin->factExists(FactSystem::ParameterProvider, _componentId, parsedName)) {
_fact = _autopilotPlugin->getFact(FactSystem::ParameterProvider, _componentId, parsedName);
connect(_fact, &Fact::valueChanged, this, &FactBinder::valueChanged);
emit valueChanged();
emit nameChanged();
emit metaDataChanged();
} else {
qgcApp()->reportMissingFact(name);
if (_factMissingSignalConnected) {
emit factMissing(name);
} else {
_missedFactMissingSignals << name;
}
}
}
}
QVariant FactBinder::value(void) const
{
if (_fact) {
return _fact->value();
} else {
return QVariant(0);
}
}
void FactBinder::setValue(const QVariant& value)
{
if (_fact) {
_fact->setValue(value);
} else {
qWarning() << "FAILED SETTING PARAM VALUE" << _fact->name() << ": PARAM DOES NOT EXIST ON SYSTEM!";
Q_ASSERT(false);
}
}
QString FactBinder::valueString(void) const
{
if (_fact) {
return _fact->valueString();
} else {
return QString();
}
}
QString FactBinder::units(void) const
{
if (_fact) {
return _fact->units();
} else {
return QString();
}
}
QVariant FactBinder::defaultValue(void)
{
if (_fact) {
return _fact->defaultValue();
} else {
return QVariant(0);
}
}
FactMetaData::ValueType_t FactBinder::type(void)
{
if (_fact) {
return _fact->type();
} else {
return FactMetaData::valueTypeUint32;
}
}
QString FactBinder::shortDescription(void)
{
if (_fact) {
return _fact->shortDescription();
} else {
return QString();
}
}
QString FactBinder::longDescription(void)
{
if (_fact) {
return _fact->longDescription();
} else {
return QString();
}
}
QVariant FactBinder::min(void)
{
if (_fact) {
return _fact->min();
} else {
return QVariant(0);
}
}
QVariant FactBinder::max(void)
{
if (_fact) {
return _fact->max();
} else {
return QVariant(0);
}
}
QString FactBinder::group(void)
{
if (_fact) {
return _fact->group();
} else {
return QString();
}
}
bool FactBinder::defaultValueAvailable(void)
{
if (_fact) {
return _fact->defaultValueAvailable();
} else {
return false;
}
}
bool FactBinder::valueEqualsDefault(void)
{
if (_fact) {
return _fact->valueEqualsDefault();
} else {
return false;
}
}
void FactBinder::connectNotify(const QMetaMethod & signal)
{
if (signal == QMetaMethod::fromSignal(&FactBinder::factMissing)) {
_factMissingSignalConnected = true;
if (_missedFactMissingSignals.count()) {
QTimer::singleShot(10, this, &FactBinder::_delayedFactMissing);
}
}
}
void FactBinder::disconnectNotify(const QMetaMethod & signal)
{
if (signal == QMetaMethod::fromSignal(&FactBinder::factMissing)) {
_factMissingSignalConnected = false;
}
}
void FactBinder::_delayedFactMissing(void)
{
foreach (QString name, _missedFactMissingSignals) {
emit factMissing(name);
}
}
\ 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>
#ifndef FACTBINDER_H
#define FACTBINDER_H
#include "Fact.h"
#include "AutoPilotPlugin.h"
#include <QObject>
#include <QString>
/// This object is used to instantiate a connection to a Fact from within Qml.
class FactBinder : public QObject
{
Q_OBJECT
Q_PROPERTY(int componentId READ componentId NOTIFY nameChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(QVariant valueString READ valueString NOTIFY valueChanged)
Q_PROPERTY(QString units READ units NOTIFY metaDataChanged)
Q_PROPERTY(QVariant defaultValue READ defaultValue NOTIFY metaDataChanged)
Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable NOTIFY metaDataChanged)
Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged)
Q_PROPERTY(FactMetaData::ValueType_t type READ type NOTIFY metaDataChanged)
Q_PROPERTY(QString shortDescription READ shortDescription NOTIFY metaDataChanged)
Q_PROPERTY(QString longDescription READ longDescription NOTIFY metaDataChanged)
Q_PROPERTY(QVariant min READ min NOTIFY metaDataChanged)
Q_PROPERTY(QVariant max READ max NOTIFY metaDataChanged)
Q_PROPERTY(QString group READ group NOTIFY metaDataChanged)
public:
FactBinder(void);
int componentId(void) const;
QString name(void) const;
void setName(const QString& name);
QVariant value(void) const;
void setValue(const QVariant& value);
QString valueString(void) const;
QString units(void) const;
QVariant defaultValue(void);
bool defaultValueAvailable(void);
bool valueEqualsDefault(void);
FactMetaData::ValueType_t type(void);
QString shortDescription(void);
QString longDescription(void);
QVariant min(void);
QVariant max(void);
QString group(void);
signals:
void factMissing(const QString& name);
void nameChanged(void);
void valueChanged(void);
void metaDataChanged(void);
private slots:
void _delayedFactMissing(void);
private:
// Overrides from QObject
void connectNotify(const QMetaMethod & signal);
void disconnectNotify(const QMetaMethod & signal);
AutoPilotPlugin* _autopilotPlugin;
Fact* _fact;
int _componentId;
bool _factMissingSignalConnected;
QStringList _missedFactMissingSignals;
};
#endif
\ No newline at end of file
......@@ -36,18 +36,24 @@ Rectangle {
QGCPalette { id: __qgcPal; colorGroupEnabled: true }
property string __missingFacts: ""
property string __missingParams: ""
property string __errorMsg: ""
function showMissingFactOverlay(missingFactName) {
if (__missingFacts.length != 0) {
__missingFacts = __missingFacts.concat(", ")
function showMissingParameterOverlay(missingParamName) {
if (__missingParams.length != 0) {
__missingParams = __missingParams.concat(", ")
}
__missingFacts = __missingFacts.concat(missingFactName)
__missingFactOverlay.visible = true
__missingParams = __missingParams.concat(missingParamName)
__missingParamsOverlay.visible = true
}
function showError(errorMsg) {
__errorMsg = errorMsg
__missingParamsOverlay.visible = true
}
Rectangle {
id: __missingFactOverlay
id: __missingParamsOverlay
anchors.fill: parent
z: 9999
visible: false
......@@ -57,7 +63,7 @@ Rectangle {
QGCLabel {
anchors.fill: parent
wrapMode: Text.WordWrap
text: "Fact(s) missing: " + __missingFacts
text: __errorMsg.length ? __errorMsg : "Paremeters(s) missing: " + __missingParams
}
}
}
......@@ -26,13 +26,19 @@
#include "AutoPilotPluginManager.h"
#include "QGCMessageBox.h"
#include <QQmlEngine>
/// @file
/// @author Don Gagne <don@thegagnes.com>
QGC_LOGGING_CATEGORY(FactPanelControllerLog, "FactPanelControllerLog")
FactPanelController::FactPanelController(void) :
_autopilot(NULL),
_factPanel(NULL)
{
// FIXME: Get rid of these asserts
_uas = UASManager::instance()->getActiveUAS();
Q_ASSERT(_uas);
......@@ -51,48 +57,64 @@ QQuickItem* FactPanelController::factPanel(void)
void FactPanelController::setFactPanel(QQuickItem* panel)
{
// Once we finally have the _factPanel member set send any
// Once we finally have the _factPanel member set, send any
// missing fact notices that were waiting to go out
_factPanel = panel;
foreach (QString missingFact, _delayedMissingFacts) {
_notifyPanelMissingFact(missingFact);
foreach (QString missingParam, _delayedMissingParams) {
_notifyPanelMissingParameter(missingParam);
}
_delayedMissingParams.clear();
}
void FactPanelController::_notifyPanelMissingParameter(const QString& missingParam)
{
if (_factPanel) {
QVariant returnedValue;
QMetaObject::invokeMethod(_factPanel,
"showMissingParameterOverlay",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, missingParam));
}
_delayedMissingFacts.clear();
}
void FactPanelController::_notifyPanelMissingFact(const QString& missingFact)
void FactPanelController::_notifyPanelErrorMsg(const QString& errorMsg)
{
QVariant returnedValue;
if (_factPanel) {
QVariant returnedValue;
QMetaObject::invokeMethod(_factPanel,
"showMissingFactOverlay",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, missingFact));
QMetaObject::invokeMethod(_factPanel,
"showError",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, errorMsg));
}
}
void FactPanelController::_reportMissingFact(const QString& missingFact)
void FactPanelController::_reportMissingParameter(int componentId, const QString& name)
{
qgcApp()->reportMissingFact(missingFact);
qgcApp()->reportMissingParameter(componentId, name);
QString missingParam = QString("%1:%2").arg(componentId).arg(name);
// If missing facts a reported from the constructor of a derived class we
// If missing parameters a reported from the constructor of a derived class we
// will not have access to _factPanel yet. Just record list of missing facts
// in that case instead of notify. Once _factPanel is available they will be
// send out for real.
if (_factPanel) {
_notifyPanelMissingFact(missingFact);
_notifyPanelMissingParameter(missingParam);
} else {
_delayedMissingFacts += missingFact;
_delayedMissingParams += missingParam;
}
}
bool FactPanelController::_allFactsExists(QStringList factList)
bool FactPanelController::_allParametersExists(int componentId, QStringList names)
{
bool noMissingFacts = true;
foreach (QString fact, factList) {
if (!_autopilot->parameterExists(fact)) {
_reportMissingFact(fact);
foreach (QString name, names) {
if (!_autopilot->parameterExists(componentId, name)) {
_reportMissingParameter(componentId, name);
noMissingFacts = false;
}
}
......@@ -103,6 +125,30 @@ bool FactPanelController::_allFactsExists(QStringList factList)
void FactPanelController::_checkForMissingFactPanel(void)
{
if (!_factPanel) {
QGCMessageBox::critical("Incorrect FactPanel Qml implementation", "FactPanelController used without passing in factPanel. This could lead to non-functioning user interface being displayed.");
_showInternalError("Incorrect FactPanel Qml implementation. FactPanelController used without passing in factPanel.");
}
}
Fact* FactPanelController::getParameterFact(int componentId, const QString& name)
{
if (_autopilot->parameterExists(componentId, name)) {
Fact* fact = _autopilot->getParameterFact(componentId, name);
QQmlEngine::setObjectOwnership(fact, QQmlEngine::CppOwnership);
return fact;
} else {
_reportMissingParameter(componentId, name);
return NULL;
}
}
bool FactPanelController::parameterExists(int componentId, const QString& name)
{
return _autopilot->parameterExists(componentId, name);
}
void FactPanelController::_showInternalError(const QString& errorMsg)
{
_notifyPanelErrorMsg(QString("Internal Error: %1").arg(errorMsg));
qCWarning(FactPanelControllerLog) << "Internal Error" << errorMsg;
QGCMessageBox::critical("Internal Error", errorMsg);
}
\ No newline at end of file
......@@ -33,6 +33,9 @@
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
#include "UASManagerInterface.h"
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(FactPanelControllerLog)
/// FactPanelController is used in combination with the FactPanel Qml control for handling
/// missing Facts from C++ code.
......@@ -45,28 +48,33 @@ public:
Q_PROPERTY(QQuickItem* factPanel READ factPanel WRITE setFactPanel)
Q_INVOKABLE Fact* getParameterFact(int componentId, const QString& name);
Q_INVOKABLE bool parameterExists(int componentId, const QString& name);
QQuickItem* factPanel(void);
void setFactPanel(QQuickItem* panel);
protected:
/// Checks for existence of the specified facts
/// @return true: all facts exists, false: facts missing and reported
bool _allFactsExists(QStringList factList);
/// Checks for existence of the specified parameters
/// @return true: all parameters exists, false: parameters missing and reported
bool _allParametersExists(int componentId, QStringList names);
/// Report a missing fact to the FactPanel Qml element
void _reportMissingFact(const QString& missingFact);
/// Report a missing parameter to the FactPanel Qml element
void _reportMissingParameter(int componentId, const QString& name);
UASInterface* _uas;
AutoPilotPlugin* _autopilot;
UASInterface* _uas;
QSharedPointer<AutoPilotPlugin> _autopilot;
private slots:
void _checkForMissingFactPanel(void);
private:
void _notifyPanelMissingFact(const QString& missingFact);
void _notifyPanelMissingParameter(const QString& missingParam);
void _notifyPanelErrorMsg(const QString& errorMsg);
void _showInternalError(const QString& errorMsg);
QQuickItem* _factPanel;
QStringList _delayedMissingFacts;
QStringList _delayedMissingParams;
};
#endif
\ No newline at end of file
......@@ -7,7 +7,7 @@ import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
QGCTextField {
property Fact fact: Fact { }
property Fact fact: null
text: fact.valueString
unitsLabel: fact.units
onEditingFinished: fact.value = text
......
......@@ -28,7 +28,6 @@
#include "UASManager.h"
#include "QGCApplication.h"
#include "VehicleComponent.h"
#include "FactBinder.h"
#include "FactPanelController.h"
#include <QtQml>
......@@ -40,7 +39,8 @@ const char* FactSystem::_factSystemQmlUri = "QGroundControl.FactSystem";
FactSystem::FactSystem(QObject* parent) :
QGCSingleton(parent)
{
qmlRegisterType<FactBinder>(_factSystemQmlUri, 1, 0, "Fact");
qmlRegisterType<Fact>(_factSystemQmlUri, 1, 0, "Fact");
qmlRegisterType<FactPanelController>(_factSystemQmlUri, 1, 0, "FactPanelController");
qmlRegisterUncreatableType<VehicleComponent>(_factSystemQmlUri, 1, 0, "VehicleComponent", "Can only reference, cannot create");
}
......
......@@ -24,21 +24,29 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
FactPanel {
id: panel
FactPanelController { id: controller; factPanel: panel }
Item {
// Use default component id
TextInput {
objectName: "testControl"
Fact { id: fact1; name: "RC_MAP_THROTTLE" }
text: fact1.value
onAccepted: { fact1.value = text; }
text: fact1.value
property Fact fact1: controller.getParameterFact(-1, "RC_MAP_THROTTLE")
onAccepted: fact1.value = text
}
// Use specific component id
TextInput {
objectName: "testControl"
Fact { id: fact2; name: "COMPONENT_51:51" }
text: fact2.value
onAccepted: { fact2.value = text; }
text: fact2.value
property Fact fact2: controller.getParameterFact(51, "COMPONENT_51")
onAccepted: fact2.value = text
}
}
......@@ -64,7 +64,7 @@ void FactSystemTestBase::_init(MAV_AUTOPILOT autopilot)
AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance();
Q_ASSERT(pluginMgr);
_plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas);
_plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas).data();
Q_ASSERT(_plugin);
// Wait for the plugin to be ready
......@@ -129,6 +129,8 @@ void FactSystemTestBase::_qml_test(void)
QVariant qmlValue = control->property("text").toInt();
QCOMPARE(qmlValue.toInt(), 3);
delete widget;
}
/// Test QML getting an updated Fact value
......@@ -143,7 +145,7 @@ void FactSystemTestBase::_qmlUpdate_test(void)
// Change the value
QVariant paramValue = 12;
_plugin->getParameterFact("RC_MAP_THROTTLE")->setValue(paramValue);
_plugin->getParameterFact(FactSystem::defaultComponentId, "RC_MAP_THROTTLE")->setValue(paramValue);
QTest::qWait(500); // Let the signals flow through
......@@ -153,5 +155,7 @@ void FactSystemTestBase::_qmlUpdate_test(void)
QObject* control = rootObject->findChild<QObject*>("testControl");
QVERIFY(control != NULL);
QCOMPARE(control->property("text").toInt(), 12);
delete widget;
}
......@@ -35,6 +35,8 @@
QGC_LOGGING_CATEGORY(ParameterLoaderLog, "ParameterLoaderLog")
Fact ParameterLoader::_defaultFact;
ParameterLoader::ParameterLoader(AutoPilotPlugin* autopilot, UASInterface* uas, QObject* parent) :
QObject(parent),
_autopilot(autopilot),
......@@ -386,13 +388,11 @@ Fact* ParameterLoader::getFact(int componentId, const QString& name)
componentId = _actualComponentId(componentId);
if (!_mapParameterName2Variant.contains(componentId) || !_mapParameterName2Variant[componentId].contains(name)) {
return NULL;
qgcApp()->reportMissingParameter(componentId, name);
return &_defaultFact;
}
Fact* fact = _mapParameterName2Variant[componentId][name].value<Fact*>();
Q_ASSERT(fact);
return fact;
return _mapParameterName2Variant[componentId][name].value<Fact*>();
}
QStringList ParameterLoader::parameterNames(void)
......
......@@ -147,6 +147,8 @@ private:
bool _fullRefresh;
QMutex _dataMutex;
static Fact _defaultFact; ///< Used to return default fact, when parameter not found
};
#endif
\ No newline at end of file
......@@ -185,9 +185,9 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) :
#endif
// Set up timer for delayed missing fact display
_missingFactDelayedDisplayTimer.setSingleShot(true);
_missingFactDelayedDisplayTimer.setInterval(_missingFactDelayedDisplayTimerTimeout);
connect(&_missingFactDelayedDisplayTimer, &QTimer::timeout, this, &QGCApplication::_missingFactsDisplay);
_missingParamsDelayedDisplayTimer.setSingleShot(true);
_missingParamsDelayedDisplayTimer.setInterval(_missingParamsDelayedDisplayTimerTimeout);
connect(&_missingParamsDelayedDisplayTimer, &QTimer::timeout, this, &QGCApplication::_missingParamsDisplay);
// Set application information
if (_runningUnitTests) {
......@@ -675,28 +675,28 @@ void QGCApplication::_loadCurrentStyle(void)
restoreOverrideCursor();
}
void QGCApplication::reportMissingFact(const QString& name)
void QGCApplication::reportMissingParameter(int componentId, const QString& name)
{
_missingFacts += name;
_missingFactDelayedDisplayTimer.start();
_missingParams += QString("%1:%2").arg(componentId).arg(name);
_missingParamsDelayedDisplayTimer.start();
}
/// Called when the delay timer fires to show the missing facts warning
void QGCApplication::_missingFactsDisplay(void)
/// Called when the delay timer fires to show the missing parameters warning
void QGCApplication::_missingParamsDisplay(void)
{
Q_ASSERT(_missingFacts.count());
Q_ASSERT(_missingParams.count());
QString facts;
foreach (QString fact, _missingFacts) {
if (facts.isEmpty()) {
facts += fact;
QString params;
foreach (QString name, _missingParams) {
if (params.isEmpty()) {
params += name;
} else {
facts += QString(", %1").arg(fact);
params += QString(", %1").arg(name);
}
}
_missingFacts.clear();
_missingParams.clear();
QGCMessageBox::critical("Missing Parameters",
QString("Parameters missing from firmware: %1.\n\n"
"You should quit QGroundControl immediately and update your firmware.").arg(facts));
"You should quit QGroundControl immediately and update your firmware.").arg(params));
}
\ No newline at end of file
......@@ -96,9 +96,9 @@ public:
/// Set the current UI style
void setStyle(bool styleIsDark);
/// Used to report a missing Fact. Warning will be displayed to user. Method may be called
/// Used to report a missing Parameter. Warning will be displayed to user. Method may be called
/// multiple times.
void reportMissingFact(const QString& name);
void reportMissingParameter(int componentId, const QString& name);
public slots:
/// You can connect to this slot to show an information message box from a different thread.
......@@ -140,7 +140,7 @@ public:
static QGCApplication* _app; ///< Our own singleton. Should be reference directly by qgcApp
private slots:
void _missingFactsDisplay(void);
void _missingParamsDisplay(void);
private:
void _createSingletons(void);
......@@ -163,9 +163,9 @@ private:
static const char* _lightStyleFile;
bool _styleIsDark; ///< true: dark style, false: light style
static const int _missingFactDelayedDisplayTimerTimeout = 1000; ///< Timeout to wait for next missing fact to come in before display
QTimer _missingFactDelayedDisplayTimer; ///< Timer use to delay missing fact display
QStringList _missingFacts; ///< List of missing facts to be displayed
static const int _missingParamsDelayedDisplayTimerTimeout = 1000; ///< Timeout to wait for next missing fact to come in before display
QTimer _missingParamsDelayedDisplayTimer; ///< Timer use to delay missing fact display
QStringList _missingParams; ///< List of missing facts to be displayed
/// Unit Test have access to creating and destroying singletons
friend class UnitTest;
......
......@@ -43,7 +43,6 @@ QGCView {
property bool fullMode: true
QGCPalette { id: __qgcPal; colorGroupEnabled: true }
ParameterEditorController { id: __controller }
QGCLabel { id: __textMeasure; text: "X"; visible: false }
property Fact __editorDialogFact: Fact { }
......@@ -61,6 +60,8 @@ QGCView {
QGCViewPanel {
id: panel
ParameterEditorController { id: controller; factPanel: panel }
Component {
id: factRowsComponent
......@@ -82,22 +83,16 @@ QGCView {
}
Repeater {
model: __controller.getFactsForGroup(componentId, group)
model: controller.getFactsForGroup(componentId, group)
Column {
property Fact modelFact: controller.getParameterFact(componentId, modelData)
Item {
x: __leftMargin
width: parent.width
height: __textHeight + (ScreenTools.pixelSizeFactor * (9))
Fact {
id: modelFact
Component.onCompleted: {
name = modelData + ":" + componentId
}
}
QGCLabel {
id: nameLabel
width: __textWidth * (__maxParamChars + 1)
......@@ -166,22 +161,22 @@ QGCView {
QGCButton {
text: "Clear RC to Param"
onClicked: __controller.clearRCToParam()
onClicked: controller.clearRCToParam()
}
QGCButton {
text: "Save to file"
visible: fullMode
onClicked: __controller.saveToFile()
onClicked: controller.saveToFile()
}
QGCButton {
text: "Load from file"
visible: fullMode
onClicked: __controller.loadFromFile()
onClicked: controller.loadFromFile()
}
QGCButton {
id: firstButton
text: "Refresh"
onClicked: __controller.refresh()
onClicked: controller.refresh()
}
}
}
......@@ -203,7 +198,7 @@ QGCView {
Column {
Repeater {
model: __controller.componentIds
model: controller.componentIds
Column {
id: componentColumn
......@@ -218,7 +213,7 @@ QGCView {
}
Repeater {
model: __controller.getGroupsForComponent(componentColumn.componentId)
model: controller.getGroupsForComponent(componentColumn.componentId)
Column {
QGCButton {
......@@ -260,8 +255,8 @@ QGCView {
id: factRowsLoader
width: factScrollView.width
property int componentId: __controller.componentIds[0]
property string group: __controller.getGroupsForComponent(__controller.componentIds[0])[0]
property int componentId: controller.componentIds[0]
property string group: controller.getGroupsForComponent(controller.componentIds[0])[0]
sourceComponent: factRowsComponent
}
} // ScrollView - Facts
......@@ -276,6 +271,8 @@ QGCView {
QGCViewDialog {
id: editorDialog
ParameterEditorController { id: controller; factPanel: editorDialog }
property bool fullMode: true
function accept() {
......@@ -364,7 +361,7 @@ QGCView {
anchors.bottom: parent.bottom
visible: __editorDialogFact.defaultValueAvailable
text: "Set RC to Param..."
onClicked: __controller.setRCToParam(__editorDialogFact.name)
onClicked: controller.setRCToParam(__editorDialogFact.name)
}
} // Rectangle - editorDialog
} // Component - Editor Dialog
......
......@@ -33,17 +33,8 @@
#include "MainWindow.h"
/// @Brief Constructs a new ParameterEditorController Widget. This widget is used within the PX4VehicleConfig set of screens.
ParameterEditorController::ParameterEditorController(void) :
_uas(NULL),
_autopilot(NULL)
ParameterEditorController::ParameterEditorController(void)
{
_uas = UASManager::instance()->getActiveUAS();
Q_ASSERT(_uas);
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas);
Q_ASSERT(_autopilot);
Q_ASSERT(_autopilot->pluginReady());
const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap();
foreach (int componentId, groupMap.keys()) {
......@@ -51,6 +42,11 @@ ParameterEditorController::ParameterEditorController(void) :
}
}
ParameterEditorController::~ParameterEditorController()
{
}
QStringList ParameterEditorController::getGroupsForComponent(int componentId)
{
const QMap<int, QMap<QString, QStringList> >& groupMap = _autopilot->getGroupMap();
......
......@@ -32,13 +32,15 @@
#include "AutoPilotPlugin.h"
#include "UASInterface.h"
#include "FactPanelController.h"
class ParameterEditorController : public QObject
class ParameterEditorController : public FactPanelController
{
Q_OBJECT
public:
ParameterEditorController(void);
~ParameterEditorController();
Q_PROPERTY(QStringList componentIds MEMBER _componentIds CONSTANT)
......@@ -54,8 +56,6 @@ public:
QList<QObject*> model(void);
private:
UASInterface* _uas;
AutoPilotPlugin* _autopilot;
QStringList _componentIds;
};
......
......@@ -36,9 +36,14 @@ const double ScreenTools::_largeFontPointSize = 20;
ScreenTools::ScreenTools()
{
connect(MainWindow::instance(), &MainWindow::repaintCanvas, this, &ScreenTools::_updateCanvas);
connect(MainWindow::instance(), &MainWindow::pixelSizeChanged, this, &ScreenTools::_updatePixelSize);
connect(MainWindow::instance(), &MainWindow::fontSizeChanged, this, &ScreenTools::_updateFontSize);
MainWindow* mainWindow = MainWindow::instance();
// Unit tests can run Qml without MainWindow
if (mainWindow) {
connect(mainWindow, &MainWindow::repaintCanvas, this, &ScreenTools::_updateCanvas);
connect(mainWindow, &MainWindow::pixelSizeChanged, this, &ScreenTools::_updatePixelSize);
connect(mainWindow, &MainWindow::fontSizeChanged, this, &ScreenTools::_updateFontSize);
}
}
qreal ScreenTools::adjustFontPointSize(qreal pointSize)
......
......@@ -84,7 +84,7 @@ void SetupView::_setActiveUAS(UASInterface* uas)
_uasCurrent = uas;
if (_uasCurrent) {
_autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent);
_autoPilotPlugin = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uasCurrent).data();
_pluginReadyChanged(_autoPilotPlugin->pluginReady());
connect(_autoPilotPlugin, &AutoPilotPlugin::pluginReadyChanged, this, &SetupView::_pluginReadyChanged);
}
......
......@@ -71,7 +71,7 @@ void SetupViewTest::_clickThrough_test(void)
linkMgr->connectLink(link);
QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through
AutoPilotPlugin* autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS());
AutoPilotPlugin* autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS()).data();
Q_ASSERT(autopilot);
QSignalSpy spyPlugin(autopilot, SIGNAL(pluginReadyChanged(bool)));
......
......@@ -25,8 +25,9 @@ Rectangle {
}
onPluginDisconnected: {
pageLoader.sourceComponent = null
pageLoader.sourceComponent = disconnectedComponent
pageLoader.autopilot = {}
pageLoader.autopilot = null
}
}
......
......@@ -41,13 +41,13 @@ void ViewWidgetController::_activeUasChanged(UASInterface* currentUas)
if (_uas) {
disconnect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged);
_uas = NULL;
_autopilot = NULL;
_autopilot = NULL;
emit pluginDisconnected();
}
if (currentUas) {
_uas = currentUas;
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(currentUas);
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(currentUas).data();
Q_ASSERT(_autopilot);
connect(_autopilot, &AutoPilotPlugin::pluginReadyChanged, this, &ViewWidgetController::_pluginReadyChanged);
......
......@@ -48,9 +48,9 @@ private slots:
void _pluginReadyChanged(bool pluginReady);
private:
AutoPilotPlugin* _autopilot;
UASManagerInterface* _uasManager;
UASInterface* _uas;
AutoPilotPlugin* _autopilot;
UASManagerInterface* _uasManager;
UASInterface* _uas;
};
#endif
\ No newline at end of file
......@@ -151,7 +151,7 @@ void PX4RCCalibrationTest::init(void)
LinkManager::instance()->connectLink(_mockLink);
QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS());
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(UASManager::instance()->getActiveUAS()).data();
Q_ASSERT(_autopilot);
QSignalSpy spyPlugin(_autopilot, SIGNAL(pluginReadyChanged(bool)));
......@@ -412,7 +412,7 @@ void PX4RCCalibrationTest::_fullCalibration_test(void)
switchList << "RC_MAP_MODE_SW" << "RC_MAP_LOITER_SW" << "RC_MAP_RETURN_SW" << "RC_MAP_POSCTL_SW" << "RC_MAP_ACRO_SW";
foreach (QString switchParam, switchList) {
Q_ASSERT(_autopilot->getParameterFact(switchParam)->value().toInt() != channel + 1);
Q_ASSERT(_autopilot->getParameterFact(FactSystem::defaultComponentId, switchParam)->value().toInt() != channel + 1);
}
_rgFunctionChannelMap[function] = channel;
......@@ -424,7 +424,7 @@ void PX4RCCalibrationTest::_fullCalibration_test(void)
// If we aren't mapping this function during calibration, set it to the previous setting
if (!found) {
_rgFunctionChannelMap[function] = _autopilot->getParameterFact(PX4RCCalibration::_rgFunctionInfo[function].parameterName)->value().toInt();
_rgFunctionChannelMap[function] = _autopilot->getParameterFact(FactSystem::defaultComponentId, PX4RCCalibration::_rgFunctionInfo[function].parameterName)->value().toInt();
qCDebug(PX4RCCalibrationTestLog) << "Assigning switch" << function << _rgFunctionChannelMap[function];
if (_rgFunctionChannelMap[function] == 0) {
_rgFunctionChannelMap[function] = -1; // -1 signals no mapping
......@@ -488,8 +488,8 @@ void PX4RCCalibrationTest::_validateParameters(void)
expectedParameterValue = chanIndex + 1; // 1-based parameter value
}
qCDebug(PX4RCCalibrationTestLog) << "Validate" << chanFunction << _autopilot->getParameterFact(PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName)->value().toInt();
QCOMPARE(_autopilot->getParameterFact(PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName)->value().toInt(), expectedParameterValue);
qCDebug(PX4RCCalibrationTestLog) << "Validate" << chanFunction << _autopilot->getParameterFact(FactSystem::defaultComponentId, PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName)->value().toInt();
QCOMPARE(_autopilot->getParameterFact(FactSystem::defaultComponentId, PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName)->value().toInt(), expectedParameterValue);
}
// Validate the channel settings. Note the channels are 1-based in parameter names.
......@@ -503,13 +503,13 @@ void PX4RCCalibrationTest::_validateParameters(void)
int rcTrimExpected = _rgChannelSettingsValidate[chan].rcTrim;
bool rcReversedExpected = _rgChannelSettingsValidate[chan].reversed;
int rcMinActual = _autopilot->getParameterFact(minTpl.arg(oneBasedChannel))->value().toInt(&convertOk);
int rcMinActual = _autopilot->getParameterFact(FactSystem::defaultComponentId, minTpl.arg(oneBasedChannel))->value().toInt(&convertOk);
QCOMPARE(convertOk, true);
int rcMaxActual = _autopilot->getParameterFact(maxTpl.arg(oneBasedChannel))->value().toInt(&convertOk);
int rcMaxActual = _autopilot->getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(oneBasedChannel))->value().toInt(&convertOk);
QCOMPARE(convertOk, true);
int rcTrimActual = _autopilot->getParameterFact(trimTpl.arg(oneBasedChannel))->value().toInt(&convertOk);
int rcTrimActual = _autopilot->getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(oneBasedChannel))->value().toInt(&convertOk);
QCOMPARE(convertOk, true);
float rcReversedFloat = _autopilot->getParameterFact(revTpl.arg(oneBasedChannel))->value().toFloat(&convertOk);
float rcReversedFloat = _autopilot->getParameterFact(FactSystem::defaultComponentId, revTpl.arg(oneBasedChannel))->value().toFloat(&convertOk);
QCOMPARE(convertOk, true);
bool rcReversedActual = (rcReversedFloat == -1.0f);
......@@ -531,6 +531,6 @@ void PX4RCCalibrationTest::_validateParameters(void)
expectedValue = _rgFunctionChannelMap[chanFunction] + 1; // 1-based
}
// qCDebug(PX4RCCalibrationTestLog) << chanFunction << expectedValue << mapParamsSet[PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName].toInt();
QCOMPARE(_autopilot->getParameterFact(PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName)->value().toInt(), expectedValue);
QCOMPARE(_autopilot->getParameterFact(FactSystem::defaultComponentId, PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName)->value().toInt(), expectedValue);
}
}
......@@ -101,13 +101,13 @@ ParamLoader::ParamLoader(QString paramName, UASInterface* uas, QObject* parent)
_paramName(paramName),
_paramReceived(false)
{
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas);
_autopilot = AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_uas).data();
Q_ASSERT(_autopilot);
}
void ParamLoader::load()
{
connect(_autopilot->getParameterFact(_paramName), &Fact::valueChanged, this, &ParamLoader::_parameterUpdated);
connect(_autopilot->getParameterFact(FactSystem::defaultComponentId, _paramName), &Fact::valueChanged, this, &ParamLoader::_parameterUpdated);
// refresh the parameter from onboard to make sure the current value is used
_autopilot->refreshParameter(FactSystem::defaultComponentId, _paramName);
......@@ -117,5 +117,5 @@ void ParamLoader::_parameterUpdated(QVariant value)
{
Q_UNUSED(value);
emit paramLoaded(true, _autopilot->getParameterFact(_paramName)->value().toFloat(), "");
emit paramLoaded(true, _autopilot->getParameterFact(FactSystem::defaultComponentId, _paramName)->value().toFloat(), "");
}
......@@ -707,7 +707,7 @@ void PX4RCCalibration::_resetInternalCalibrationValues(void)
enum rcCalFunctions curFunction = rgFlightModeFunctions[i];
bool ok;
int switchChannel = _autopilot->getParameterFact(_rgFunctionInfo[curFunction].parameterName)->value().toInt(&ok);
int switchChannel = _autopilot->getParameterFact(FactSystem::defaultComponentId, _rgFunctionInfo[curFunction].parameterName)->value().toInt(&ok);
Q_ASSERT(ok);
// Parameter: 1-based channel, 0=not mapped
......@@ -749,16 +749,16 @@ void PX4RCCalibration::_setInternalCalibrationValuesFromParameters(void)
for (int i = 0; i < _chanMax; ++i) {
struct ChannelInfo* info = &_rgChannelInfo[i];
info->rcTrim = _autopilot->getParameterFact(trimTpl.arg(i+1))->value().toInt(&convertOk);
info->rcTrim = _autopilot->getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(i+1))->value().toInt(&convertOk);
Q_ASSERT(convertOk);
info->rcMin = _autopilot->getParameterFact(minTpl.arg(i+1))->value().toInt(&convertOk);
info->rcMin = _autopilot->getParameterFact(FactSystem::defaultComponentId, minTpl.arg(i+1))->value().toInt(&convertOk);
Q_ASSERT(convertOk);
info->rcMax = _autopilot->getParameterFact(maxTpl.arg(i+1))->value().toInt(&convertOk);
info->rcMax = _autopilot->getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(i+1))->value().toInt(&convertOk);
Q_ASSERT(convertOk);
float floatReversed = _autopilot->getParameterFact(revTpl.arg(i+1))->value().toFloat(&convertOk);
float floatReversed = _autopilot->getParameterFact(FactSystem::defaultComponentId, revTpl.arg(i+1))->value().toFloat(&convertOk);
Q_ASSERT(convertOk);
Q_ASSERT(floatReversed == 1.0f || floatReversed == -1.0f);
info->reversed = floatReversed == -1.0f;
......@@ -767,7 +767,7 @@ void PX4RCCalibration::_setInternalCalibrationValuesFromParameters(void)
for (int i=0; i<rcCalFunctionMax; i++) {
int32_t paramChannel;
paramChannel = _autopilot->getParameterFact(_rgFunctionInfo[i].parameterName)->value().toInt(&convertOk);
paramChannel = _autopilot->getParameterFact(FactSystem::defaultComponentId, _rgFunctionInfo[i].parameterName)->value().toInt(&convertOk);
Q_ASSERT(convertOk);
if (paramChannel != 0) {
......@@ -877,10 +877,10 @@ void PX4RCCalibration::_writeCalibration(void)
struct ChannelInfo* info = &_rgChannelInfo[chan];
int oneBasedChannel = chan + 1;
_autopilot->getParameterFact(trimTpl.arg(oneBasedChannel))->setValue((float)info->rcTrim);
_autopilot->getParameterFact(minTpl.arg(oneBasedChannel))->setValue((float)info->rcMin);
_autopilot->getParameterFact(maxTpl.arg(oneBasedChannel))->setValue((float)info->rcMax);
_autopilot->getParameterFact(revTpl.arg(oneBasedChannel))->setValue(info->reversed ? -1.0f : 1.0f);
_autopilot->getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(oneBasedChannel))->setValue((float)info->rcTrim);
_autopilot->getParameterFact(FactSystem::defaultComponentId, minTpl.arg(oneBasedChannel))->setValue((float)info->rcMin);
_autopilot->getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(oneBasedChannel))->setValue((float)info->rcMax);
_autopilot->getParameterFact(FactSystem::defaultComponentId, revTpl.arg(oneBasedChannel))->setValue(info->reversed ? -1.0f : 1.0f);
}
// Write function mapping parameters
......@@ -893,12 +893,12 @@ void PX4RCCalibration::_writeCalibration(void)
// Note that the channel value is 1-based
paramChannel = _rgFunctionChannelMapping[i] + 1;
}
_autopilot->getParameterFact(_rgFunctionInfo[i].parameterName)->setValue(paramChannel);
_autopilot->getParameterFact(FactSystem::defaultComponentId, _rgFunctionInfo[i].parameterName)->setValue(paramChannel);
}
// If the RC_CHAN_COUNT parameter is available write the channel count
if (_autopilot->parameterExists("RC_CHAN_CNT")) {
_autopilot->getParameterFact("RC_CHAN_CNT")->setValue(_chanCount);
if (_autopilot->parameterExists(FactSystem::defaultComponentId, "RC_CHAN_CNT")) {
_autopilot->getParameterFact(FactSystem::defaultComponentId, "RC_CHAN_CNT")->setValue(_chanCount);
}
_stopCalibration();
......
......@@ -256,8 +256,8 @@ private:
RCValueWidget* _rgRCValueMonitorWidget[_chanMax]; ///< Array of radio channel value widgets
QLabel* _rgRCValueMonitorLabel[_chanMax]; ///< Array of radio channel value labels
UASInterface* _uas;
AutoPilotPlugin* _autopilot;
UASInterface* _uas;
QSharedPointer<AutoPilotPlugin> _autopilot;
Ui::PX4RCCalibration* _ui;
......
......@@ -282,7 +282,7 @@ void MainToolBar::_forgetUAS(UASInterface* uas)
if (_mav != NULL && _mav == uas) {
disconnect(UASMessageHandler::instance(), &UASMessageHandler::textMessageCountChanged, this, &MainToolBar::_handleTextMessage);
disconnect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBar::_remoteControlRSSIChanged);
disconnect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue);
disconnect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav).data(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue);
_mav = NULL;
}
}
......@@ -302,7 +302,7 @@ void MainToolBar::_setActiveUAS(UASInterface* active)
{
connect(UASMessageHandler::instance(), &UASMessageHandler::textMessageCountChanged, this, &MainToolBar::_handleTextMessage);
connect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBar::_remoteControlRSSIChanged);
connect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue);
connect(AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(_mav).data(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue);
}
}
......
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