Commit 558b23f8 authored by Don Gagne's avatar Don Gagne

AutoPilot plugin restructuring for better QML support

- properties now hand off of main “autopilot” object in qml
- Added support for summary items through qml
parent b82bfe84
import QtQuick 2.2
import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
TextInput {
property Fact fact
text: fact.value
font.family: "Helvetica"
font.pointSize: 24
color: "red"
focus: true
onAccepted: { fact.value = text; }
}
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Button {
text: "Button"
property bool setupComplete: false
property var summaryModel: ListModel {
ListElement { name: "Row 1"; state: "State 1" }
ListElement { name: "Row 2"; state: "State 2" }
ListElement { name: "Row 3"; state: "State 3" }
}
style: ButtonStyle {
id: buttonStyle
background: Rectangle {
id: innerRect
readonly property real titleHeight: 30
//property alias summaryModel: summaryList.model
border.color: "#888"
radius: 10
color: control.activeFocus ? "#47b" : "white"
opacity: control.hovered || control.activeFocus ? 1 : 0.75
Behavior on opacity {NumberAnimation{ duration: 100 }}
Text {
id: titleBar
width: parent.width
height: parent.titleHeight
verticalAlignment: TextEdit.AlignVCenter
horizontalAlignment: TextEdit.AlignHCenter
text: control.text
font.pixelSize: 12
Rectangle {
id: setupIndicator
property bool setupComplete: true
readonly property real indicatorRadius: 6
x: parent.width - (indicatorRadius * 2) - 5
y: (parent.height - (indicatorRadius * 2)) / 2
width: indicatorRadius * 2
height: indicatorRadius * 2
radius: indicatorRadius
color: control.setupComplete ? "green" : "red"
}
}
Rectangle {
width: parent.width
height: parent.height - parent.titleHeight
y: parent.titleHeight
border.color: "#888"
gradient: Gradient {
GradientStop { position: 0; color: "#ffffff" }
GradientStop { position: 1; color: "#000000" }
}
ListView {
id: summaryList
anchors.fill: parent
model: control.summaryModel
delegate: Row {
Text { text: modelData.name }
Text { text: modelData.state }
}
}
}
}
label: Item {}
}
}
/*
Rectangle {
readonly property real titleHeight: 30
property alias title: titleBar.text
property alias setupComplete: setupIndicator.setupComplete
//property alias summaryModel: summaryList.model
border.color: "#888"
radius: 10
gradient: Gradient {
GradientStop { position: 0 ; color: "#cccccc" }
GradientStop { position: 1 ; color: "#aaa" }
}
Text {
id: titleBar
width: parent.width
height: parent.titleHeight
verticalAlignment: TextEdit.AlignVCenter
horizontalAlignment: TextEdit.AlignHCenter
text: qsTr("TITLE")
font.pixelSize: 12
Rectangle {
id: setupIndicator
property bool setupComplete: true
readonly property real indicatorRadius: 6
x: parent.width - (indicatorRadius * 2) - 5
y: (parent.height - (indicatorRadius * 2)) / 2
width: indicatorRadius * 2
height: indicatorRadius * 2
radius: indicatorRadius
color: setupComplete ? "green" : "red"
}
}
Rectangle {
width: parent.width
height: parent.height - parent.titleHeight
y: parent.titleHeight
border.color: "#888"
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
}
GradientStop {
position: 1
color: "#000000"
}
}
ListView {
id: summaryList
anchors.fill: parent
model: ListModel {
ListElement { name: "Row 1"; state: "State 1" }
ListElement { name: "Row 2"; state: "State 2" }
ListElement { name: "Row 3"; state: "State 3" }
}
delegate: Row { Text { text: modelData.name } Text { text: modelData.state } }
}
}
}
*/
\ No newline at end of file
Module QGroundControl.FactControls
FactTextInput 1.0 FactTextInput.qml
\ No newline at end of file
SetupButton 1.0 SetupButton.qml
\ No newline at end of file
......@@ -48,18 +48,14 @@ class AutoPilotPlugin : public QObject
Q_OBJECT
public:
/// @brief Returns the list of VehicleComponent objects associated with the AutoPilot.
virtual QList<VehicleComponent*> getVehicleComponents(void) const = 0;
Q_PROPERTY(QVariantMap parameters READ parameters CONSTANT)
Q_PROPERTY(QVariantList components READ components CONSTANT)
Q_PROPERTY(QUrl setupBackgroundImage READ setupBackgroundImage CONSTANT)
/// Returns the parameter facts for the specified UAS.
///
/// Key is parameter name. Get Fact object like this: _mapParameterName2Variant["RC_MAP_THROTTLE"].value<Fact*>().
/// You should not request parameter facts until the plugin reports that it is ready.
virtual const QVariantMap& parameterFacts(void) const = 0;
/// Adds the FactSystem properties to the Qml context. You should not call
/// this method until the plugin reports that it is ready.
virtual void addFactsToQmlContext(QQmlContext* context) const = 0;
// Property accessors
virtual const QVariantList& components(void) = 0;
virtual const QVariantMap& parameters(void) = 0;
virtual QUrl setupBackgroundImage(void) = 0;
/// Returns true if the plugin is ready for use
virtual bool pluginIsReady(void) const = 0;
......@@ -72,8 +68,9 @@ signals:
void pluginReady(void);
protected:
// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
/// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
};
#endif
......@@ -32,12 +32,6 @@ GenericAutoPilotPlugin::GenericAutoPilotPlugin(UASInterface* uas, QObject* paren
Q_UNUSED(uas);
}
QList<VehicleComponent*> GenericAutoPilotPlugin::getVehicleComponents(void) const
{
// Generic autopilot has no configurable components
return QList<VehicleComponent*>();
}
QList<AutoPilotPluginManager::FullMode_t> GenericAutoPilotPlugin::getModes(void)
{
AutoPilotPluginManager::FullMode_t fullMode;
......@@ -83,13 +77,20 @@ QString GenericAutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t cust
return mode;
}
void GenericAutoPilotPlugin::addFactsToQmlContext(QQmlContext* context) const
void GenericAutoPilotPlugin::clearStaticData(void)
{
Q_UNUSED(context);
// No Static data yet
}
const QVariantList& GenericAutoPilotPlugin::components(void)
{
static QVariantList staticList;
Q_ASSERT_X(false, "Not yet implemented", "");
return staticList;
}
const QVariantMap& GenericAutoPilotPlugin::parameterFacts(void) const
const QVariantMap& GenericAutoPilotPlugin::parameters(void)
{
static QVariantMap staticMap;
......@@ -97,7 +98,10 @@ const QVariantMap& GenericAutoPilotPlugin::parameterFacts(void) const
return staticMap;
}
void GenericAutoPilotPlugin::clearStaticData(void)
QUrl GenericAutoPilotPlugin::setupBackgroundImage(void)
{
// No Static data yet
static QUrl url;
Q_ASSERT_X(false, "Not yet implemented", "");
return url;
}
......@@ -40,14 +40,16 @@ public:
GenericAutoPilotPlugin(UASInterface* uas, QObject* parent = NULL);
// Overrides from AutoPilotPlugin
virtual QList<VehicleComponent*> getVehicleComponents(void) const ;
virtual void addFactsToQmlContext(QQmlContext* context) const;
virtual const QVariantMap& parameterFacts(void) const;
virtual bool pluginIsReady(void) const { return true; }
virtual QUrl setupBackgroundImage(void);
virtual const QVariantList& components(void);
virtual const QVariantMap& parameters(void);
static QList<AutoPilotPluginManager::FullMode_t> getModes(void);
static QString getShortModeText(uint8_t baseMode, uint32_t customMode);
static void clearStaticData(void);
protected:
};
#endif
......@@ -26,6 +26,7 @@
#include "AirframeComponent.h"
#include "QGCPX4AirframeConfig.h"
#include "VehicleComponentSummaryItem.h"
/// @brief Parameters which signal a change in setupComplete state
static const char* triggerParams[] = { "SYS_AUTOSTART", NULL };
......@@ -161,56 +162,65 @@ QWidget* AirframeComponent::setupWidget(void) const
return new QGCPX4AirframeConfig;
}
QList<QStringList> AirframeComponent::summaryItems(void) const
const QVariantList& AirframeComponent::summaryItems(void)
{
QVariant value;
QStringList row;
QList<QStringList> items;
// Fill the items on first reference
// FIXME: These items are not live
row << "System ID:";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_SYS_ID", value)) {
if (value.toInt() == 0) {
row << "Setup required";
if (!_summaryItems.count()) {
QString name;
QString state;
QVariant value;
name = "System ID:";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_SYS_ID", value)) {
if (value.toInt() == 0) {
state = "Setup required";
} else {
state = value.toString();
}
} else {
row << value.toString();
// Why is the parameter missing?
Q_ASSERT(false);
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
}
items << row;
row.clear();
row << "Airframe:";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "SYS_AUTOSTART", value)) {
if (value.toInt() == 0) {
row << "Setup required";
VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
name = "Airframe:";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "SYS_AUTOSTART", value)) {
if (value.toInt() == 0) {
state = "Setup required";
} else {
state = value.toString();
}
} else {
row << value.toString();
// Why is the parameter missing?
Q_ASSERT(false);
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
}
items << row;
row.clear();
row << "Type:";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_TYPE", value)) {
int index = value.toInt();
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
if (index < 0 || index >= (int)cMavTypes) {
row << "Unknown";
name = "Type:";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_TYPE", value)) {
int index = value.toInt();
if (index < 0 || index >= (int)cMavTypes) {
state = "Unknown";
} else {
state = mavTypeInfo[index].description;
}
} else {
row << mavTypeInfo[index].description;
// Why is the parameter missing?
Q_ASSERT(false);
state = "Unknown";
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
row << "Unknown";
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
}
items << row;
return items;
return _summaryItems;
}
......@@ -49,10 +49,11 @@ public:
virtual QString setupStateDescription(void) const;
virtual QWidget* setupWidget(void) const;
virtual QStringList paramFilterList(void) const;
virtual QList<QStringList> summaryItems(void) const;
virtual const QVariantList& summaryItems(void);
private:
const QString _name;
const QString _name;
QVariantList _summaryItems;
};
#endif
......@@ -6,27 +6,28 @@
<rect>
<x>0</x>
<y>0</y>
<width>831</width>
<height>1286</height>
<width>642</width>
<height>645</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>642</width>
<height>645</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_8">
<property name="font">
<font>
<pointsize>22</pointsize>
</font>
</property>
<property name="text">
<string>This implementation is a work in progress. Visuals are meant to be functional only. Active display of switch positions is not yet implemented. If this entire screen is disabled, you must do a Radio Calibration before settings Flight Modes.</string>
</property>
......@@ -205,19 +206,6 @@
</attribute>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
......
......@@ -26,6 +26,7 @@
#include "FlightModesComponent.h"
#include "FlightModeConfig.h"
#include "VehicleComponentSummaryItem.h"
/// @brief Parameters which signal a change in setupComplete state
static const char* triggerParams[] = { "RC_MAP_MODE_SW", NULL };
......@@ -116,41 +117,44 @@ QWidget* FlightModesComponent::setupWidget(void) const
return new FlightModeConfig();
}
QList<QStringList> FlightModesComponent::summaryItems(void) const
const QVariantList& FlightModesComponent::summaryItems(void)
{
QList<QStringList> items;
// Create summary items for each mode switch
for (size_t i=0; i<cSwitchList; i++) {
QVariant value;
QStringList row;
row << switchList[i].name;
if (!_summaryItems.count()) {
// Create summary items for each mode switch
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), switchList[i].param, value)) {
int chan = value.toInt();
for (size_t i=0; i<cSwitchList; i++) {
QString name;
QString state;
QVariant value;
name = switchList[i].name;
if (chan == 0) {
// Switch is not mapped
if (i == 0) {
// Mode switch is required
Q_ASSERT(strcmp(switchList[0].param, "RC_MAP_MODE_SW") == 0);
row << "Setup required";
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), switchList[i].param, value)) {
int chan = value.toInt();
if (chan == 0) {
// Switch is not mapped
if (i == 0) {
// Mode switch is required
Q_ASSERT(strcmp(switchList[0].param, "RC_MAP_MODE_SW") == 0);
state = "Setup required";
} else {
state = "None";
}
} else {
row << "None";
state = tr("Chan %1").arg(chan);
}
} else {
row << tr("Chan %1").arg(chan);
// Why is the parameter missing?
Q_ASSERT(false);
state = "Unknown";
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
row << "Unknown";
VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
}
items << row;
}
return items;
return _summaryItems;
}
......@@ -49,10 +49,11 @@ public:
virtual QString setupStateDescription(void) const;
virtual QWidget* setupWidget(void) const;
virtual QStringList paramFilterList(void) const;
virtual QList<QStringList> summaryItems(void) const;
virtual const QVariantList& summaryItems(void);
private:
const QString _name;
const QString _name;
QVariantList _summaryItems;
};
#endif
......@@ -86,33 +86,6 @@ PX4AutoPilotPlugin::~PX4AutoPilotPlugin()
PX4ParameterFacts::deleteParameterFactMetaData();
}
QList<VehicleComponent*> PX4AutoPilotPlugin::getVehicleComponents(void) const
{
Q_ASSERT(_uas);
QList<VehicleComponent*> components;
VehicleComponent* component;
component = new AirframeComponent(_uas);
Q_CHECK_PTR(component);
components.append(component);
component = new RadioComponent(_uas);
Q_CHECK_PTR(component);
components.append(component);
component = new FlightModesComponent(_uas);
Q_CHECK_PTR(component);
components.append(component);
component = new SensorsComponent(_uas);
Q_CHECK_PTR(component);
components.append(component);
return components;
}
QList<AutoPilotPluginManager::FullMode_t> PX4AutoPilotPlugin::getModes(void)
{
union px4_custom_mode px4_cm;
......@@ -206,15 +179,6 @@ QString PX4AutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t customMo
return mode;
}
void PX4AutoPilotPlugin::addFactsToQmlContext(QQmlContext* context) const
{
Q_ASSERT(context);
Q_ASSERT(_parameterFacts->factsAreReady());
context->setContextProperty("parameters", _parameterFacts->factMap());
}
void PX4AutoPilotPlugin::clearStaticData(void)
{
PX4ParameterFacts::clearStaticData();
......@@ -224,3 +188,40 @@ bool PX4AutoPilotPlugin::pluginIsReady(void) const
{
return _parameterFacts->factsAreReady();
}
const QVariantList& PX4AutoPilotPlugin::components(void)
{
if (_components.count() == 0) {
VehicleComponent* component;
Q_ASSERT(_uas);
component = new AirframeComponent(_uas);
Q_CHECK_PTR(component);
_components.append(QVariant::fromValue(component));
component = new RadioComponent(_uas);
Q_CHECK_PTR(component);
_components.append(QVariant::fromValue(component));
component = new FlightModesComponent(_uas);
Q_CHECK_PTR(component);
_components.append(QVariant::fromValue(component));
component = new SensorsComponent(_uas);
Q_CHECK_PTR(component);
_components.append(QVariant::fromValue(component));
}
return _components;
}
const QVariantMap& PX4AutoPilotPlugin::parameters(void)
{
return _parameterFacts->factMap();
}
QUrl PX4AutoPilotPlugin::setupBackgroundImage(void)
{
return QUrl::fromUserInput("qrc:/qml/px4fmu_2.x.png");
}
......@@ -29,6 +29,8 @@
#include "UASInterface.h"
#include "PX4ParameterFacts.h"
#include <QImage>
/// @file
/// @brief This is the PX4 specific implementation of the AutoPilot class.
/// @author Don Gagne <don@thegagnes.com>
......@@ -42,10 +44,10 @@ public:
~PX4AutoPilotPlugin();
// Overrides from AutoPilotPlugin
virtual QList<VehicleComponent*> getVehicleComponents(void) const ;
virtual void addFactsToQmlContext(QQmlContext* context) const;
virtual const QVariantMap& parameterFacts(void) const { return _parameterFacts->factMap(); }
virtual bool pluginIsReady(void) const;
virtual const QVariantList& components(void);
virtual const QVariantMap& parameters(void);
virtual QUrl setupBackgroundImage(void);
static QList<AutoPilotPluginManager::FullMode_t> getModes(void);
static QString getShortModeText(uint8_t baseMode, uint32_t customMode);
......@@ -55,6 +57,7 @@ private:
UASInterface* _uas;
PX4ParameterFacts* _parameterFacts;
bool _pluginReady;
QVariantList _components;
};
#endif
......@@ -26,6 +26,7 @@
#include "RadioComponent.h"
#include "PX4RCCalibration.h"
#include "VehicleComponentSummaryItem.h"
/// @brief Parameters which signal a change in setupComplete state
static const char* triggerParams[] = { "RC_MAP_MODE_SW", NULL };
......@@ -100,48 +101,54 @@ QWidget* RadioComponent::setupWidget(void) const
return new PX4RCCalibration;
}
QList<QStringList> RadioComponent::summaryItems(void) const
const QVariantList& RadioComponent::summaryItems(void)
{
QList<QStringList> items;
QStringList row;
// FIXME: Need to pull receiver type from RSSI value
row << "Receiver type:" << "n/a";
items << row;
static const char* stickParams[] = { "RC_MAP_ROLL", "RC_MAP_PITCH", "RC_MAP_YAW", "RC_MAP_THROTTLE" };
QString summary("Chan ");
bool allSticksMapped = true;
for (size_t i=0; i<sizeof(stickParams)/sizeof(stickParams[0]); i++) {
QVariant value;
if (!_summaryItems.count()) {
QString name;
QString state;
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), stickParams[i], value)) {
if (value.toInt() == 0) {
allSticksMapped = false;
break;
} else {
if (i != 0) {
summary += ",";
// FIXME: Need to pull receiver type from RSSI value
name = "Receiver type:";
state = "n/a";
VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
static const char* stickParams[] = { "RC_MAP_ROLL", "RC_MAP_PITCH", "RC_MAP_YAW", "RC_MAP_THROTTLE" };
QString summary("Chan ");
bool allSticksMapped = true;
for (size_t i=0; i<sizeof(stickParams)/sizeof(stickParams[0]); i++) {
QVariant value;
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), stickParams[i], value)) {
if (value.toInt() == 0) {
allSticksMapped = false;
break;
} else {
if (i != 0) {
summary += ",";
}
summary += value.toString();
}
summary += value.toString();
} else {
// Why is the parameter missing?
Q_ASSERT(false);
summary += "?";
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
summary += "?";
}
}
if (!allSticksMapped) {
summary = "Not mapped";
}
if (!allSticksMapped) {
summary = "Not mapped";
}
row.clear();
row << "Ail, Ele, Rud, Throt:" << summary;
items << row;
name = "Ail, Ele, Rud, Throt:";
state = summary;
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
}
return items;
return _summaryItems;
}
......@@ -50,10 +50,11 @@ public:
virtual QString setupStateDescription(void) const;
virtual QWidget* setupWidget(void) const;
virtual QStringList paramFilterList(void) const;
virtual QList<QStringList> summaryItems(void) const;
virtual const QVariantList& summaryItems(void);
private:
const QString _name;
const QString _name;
QVariantList _summaryItems;
};
#endif
......@@ -26,6 +26,7 @@
#include "SensorsComponent.h"
#include "QGCPX4SensorCalibration.h"
#include "VehicleComponentSummaryItem.h"
// These two list must be kept in sync
......@@ -116,106 +117,108 @@ QWidget* SensorsComponent::setupWidget(void) const
return new QGCPX4SensorCalibration;
}
QList<QStringList> SensorsComponent::summaryItems(void) const
const QVariantList& SensorsComponent::summaryItems(void)
{
QList<QStringList> items;
// Summary item for each Sensor
int i = 0;
while (triggerParams[i] != NULL) {
QVariant value;
QStringList row;
if (!_summaryItems.count()) {
QString name;
QString state;
row << tr("%1:").arg(triggerSensors[i]);
// Summary item for each Sensor
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), triggerParams[i], value)) {
if (value.toFloat() == 0.0f) {
row << "Setup required";
int i = 0;
while (triggerParams[i] != NULL) {
QVariant value;
name = tr("%1:").arg(triggerSensors[i]);
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), triggerParams[i], value)) {
if (value.toFloat() == 0.0f) {
state = "Setup required";
} else {
state = "Ready";
}
} else {
row << "Ready";
// Why is the parameter missing?
Q_ASSERT(false);
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
i++;
}
items << row;
i++;
}
// Summary item for each orientation param
static const char* orientationSensors[] = { "Autopilot orientation:", "Compass orientation:" };
static const char* orientationParams[] = { "SENS_BOARD_ROT", "SENS_EXT_MAG_ROT" };
static const size_t cOrientationSensors = sizeof(orientationSensors)/sizeof(orientationSensors[0]);
static const char* orientationValues[] = {
"Line of flight",
"Yaw:45",
"Yaw:90",
"Yaw:135",
"Yaw:180",
"Yaw:225",
"Yaw:270",
"Yaw:315",
"Roll:180",
"Roll:180 Yaw:45",
"Roll:180 Yaw:90",
"Roll:180 Yaw:135",
"Pitch:180",
"Roll:180 Yaw:225",
"Roll:180 Yaw:270",
"Roll:180 Yaw:315",
"Roll:90",
"Roll:90 Yaw:45",
"Roll:90 Yaw:90",
"Roll:90 Yaw:135",
"Roll:270",
"Roll:270 Yaw:45",
"Roll:270 Yaw:90",
"Roll:270 Yaw:135",
"Pitch:90",
"Pitch:270",
"Pitch:180",
"Pitch:180 Yaw:90",
"Pitch:180 Yaw:270",
"Roll:90 Pitch:90",
"Roll:180 Pitch:90",
"Roll:270 Pitch:90",
"Roll:90 Pitch:180",
"Roll:270 Pitch:180",
"Roll:90 Pitch:270",
"Roll:180 Pitch:270",
"Roll:270 Pitch:270",
"Roll:90 Pitch:180 Yaw:90",
"Roll:90 Yaw:270"
};
static const size_t cOrientationValues = sizeof(orientationValues)/sizeof(orientationValues[0]);
for (size_t i=0; i<cOrientationSensors; i++) {
QVariant value;
QStringList row;
// Summary item for each orientation param
row.clear();
static const char* orientationSensors[] = { "Autopilot orientation:", "Compass orientation:" };
static const char* orientationParams[] = { "SENS_BOARD_ROT", "SENS_EXT_MAG_ROT" };
static const size_t cOrientationSensors = sizeof(orientationSensors)/sizeof(orientationSensors[0]);
row << orientationSensors[i];
static const char* orientationValues[] = {
"Line of flight",
"Yaw:45",
"Yaw:90",
"Yaw:135",
"Yaw:180",
"Yaw:225",
"Yaw:270",
"Yaw:315",
"Roll:180",
"Roll:180 Yaw:45",
"Roll:180 Yaw:90",
"Roll:180 Yaw:135",
"Pitch:180",
"Roll:180 Yaw:225",
"Roll:180 Yaw:270",
"Roll:180 Yaw:315",
"Roll:90",
"Roll:90 Yaw:45",
"Roll:90 Yaw:90",
"Roll:90 Yaw:135",
"Roll:270",
"Roll:270 Yaw:45",
"Roll:270 Yaw:90",
"Roll:270 Yaw:135",
"Pitch:90",
"Pitch:270",
"Pitch:180",
"Pitch:180 Yaw:90",
"Pitch:180 Yaw:270",
"Roll:90 Pitch:90",
"Roll:180 Pitch:90",
"Roll:270 Pitch:90",
"Roll:90 Pitch:180",
"Roll:270 Pitch:180",
"Roll:90 Pitch:270",
"Roll:180 Pitch:270",
"Roll:270 Pitch:270",
"Roll:90 Pitch:180 Yaw:90",
"Roll:90 Yaw:270"
};
static const size_t cOrientationValues = sizeof(orientationValues)/sizeof(orientationValues[0]);
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), orientationParams[i], value)) {
int index = value.toInt();
if (index < 0 || index >= (int)cOrientationValues) {
row << "Setup required";
for (size_t i=0; i<cOrientationSensors; i++) {
QVariant value;
name = orientationSensors[i];
if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), orientationParams[i], value)) {
int index = value.toInt();
if (index < 0 || index >= (int)cOrientationValues) {
state = "Setup required";
} else {
state = orientationValues[index];
}
} else {
row << orientationValues[index];
// Why is the parameter missing?
Q_ASSERT(false);
state = "Unknown";
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
row << "Unknown";
VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
}
items << row;
}
return items;
return _summaryItems;
}
......@@ -49,10 +49,11 @@ public:
virtual QString setupStateDescription(void) const;
virtual QWidget* setupWidget(void) const;
virtual QStringList paramFilterList(void) const;
virtual QList<QStringList> summaryItems(void) const;
virtual const QVariantList& summaryItems(void);
private:
const QString _name;
const QString _name;
QVariantList _summaryItems;
};
#endif
......@@ -27,6 +27,7 @@
#include "FactSystem.h"
#include "UASManager.h"
#include "QGCApplication.h"
#include "VehicleComponent.h"
#include <QtQml>
......@@ -39,6 +40,10 @@ FactSystem::FactSystem(QObject* parent) :
{
qmlRegisterType<Fact>(_factSystemQmlUri, 1, 0, "Fact");
qmlRegisterType<FactValidator>(_factSystemQmlUri, 1, 0, "FactValidator");
// FIXME: Where should this go? Also creation string
qmlRegisterUncreatableType<VehicleComponent>(_factSystemQmlUri, 1, 0, "VehicleComponent", "Can only reference VehicleComponent");
qmlRegisterUncreatableType<VehicleComponent>(_factSystemQmlUri, 1, 0, "VehicleComponentSummaryItem", "Can only reference VehicleComponentSummaryItem");
}
FactSystem::~FactSystem()
......
......@@ -90,13 +90,7 @@ void FactSystemTest::_parameter_test(void)
{
// Get the parameter facts from the AutoPilot
AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance();
Q_ASSERT(pluginMgr);
AutoPilotPlugin* plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas);
Q_ASSERT(plugin);
const QVariantMap& parameterFacts = plugin->parameterFacts();
const QVariantMap& parameterFacts = _plugin->parameters();
// Compare the value in the Parameter Manager with the value from the FactSystem
......@@ -116,6 +110,8 @@ void FactSystemTest::_qml_test(void)
{
QGCQuickWidget* widget = new QGCQuickWidget;
widget->setAutoPilot(_plugin);
widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml"));
QQuickItem* rootObject = widget->rootObject();
......@@ -134,13 +130,7 @@ void FactSystemTest::_paramMgrSignal_test(void)
{
// Get the parameter Fact from the AutoPilot
AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance();
Q_ASSERT(pluginMgr);
AutoPilotPlugin* plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas);
Q_ASSERT(plugin);
const QVariantMap& parameterFacts = plugin->parameterFacts();
const QVariantMap& parameterFacts = _plugin->parameters();
Fact* fact = parameterFacts["RC_MAP_THROTTLE"].value<Fact*>();
QVERIFY(fact != NULL);
......@@ -170,6 +160,8 @@ void FactSystemTest::_qmlUpdate_test(void)
{
QGCQuickWidget* widget = new QGCQuickWidget;
widget->setAutoPilot(_plugin);
widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml"));
// Change the value using param manager
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
import QGroundControlFactControls 1.0
Item {
TextInput {
objectName: "testControl"
text: parameters["RC_MAP_THROTTLE"].value
text: autopilot.parameters["RC_MAP_THROTTLE"].value
font.family: "Helvetica"
font.pointSize: 24
color: "red"
focus: true
onAccepted: { parameters["RC_MAP_THROTTLE"].value = text; }
onAccepted: { autopilot.parameters["RC_MAP_THROTTLE"].value = text; }
}
}
\ No newline at end of file
......@@ -22,7 +22,6 @@
======================================================================*/
#include "QGCQuickWidget.h"
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include <QQmlContext>
......@@ -37,13 +36,10 @@
QGCQuickWidget::QGCQuickWidget(QWidget* parent) :
QQuickWidget(parent)
{
UASManagerInterface* uasMgr = UASManager::instance();
Q_ASSERT(uasMgr);
UASInterface* uas = uasMgr->getActiveUAS();
Q_ASSERT(uas);
rootContext()->engine()->addImportPath("qrc:/qml");
AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(uas)->addFactsToQmlContext(rootContext());
}
void QGCQuickWidget::setAutoPilot(AutoPilotPlugin* autoPilot)
{
rootContext()->setContextProperty("autopilot", autoPilot);
}
......@@ -26,7 +26,7 @@
#include <QQuickWidget>
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
/// @file
/// @brief Subclass of QQuickWidget which injects Facts and the Pallete object into
......@@ -39,7 +39,9 @@ class QGCQuickWidget : public QQuickWidget {
public:
QGCQuickWidget(QWidget* parent = NULL);
/// Sets the UAS into the widget which in turn will load facts into the context
void setAutoPilot(AutoPilotPlugin* autoPilot);
};
#endif
......@@ -38,3 +38,20 @@ VehicleComponent::~VehicleComponent()
{
}
void VehicleComponent::addSummaryQmlComponent(QQmlContext* context, QQuickItem* parent)
{
Q_ASSERT(context);
// FIXME: We own this object now, need to delete somewhere
QQmlComponent component(context->engine(), QUrl::fromUserInput("qrc:/qml/VehicleComponentSummaryButton.qml"));
if (component.status() == QQmlComponent::Error) {
qDebug() << component.errors();
Q_ASSERT(false);
}
QQuickItem* item = qobject_cast<QQuickItem*>(component.create(context));
Q_ASSERT(item);
item->setParentItem(parent);
item->setProperty("vehicleComponent", QVariant::fromValue(this));
}
......@@ -25,6 +25,8 @@
#define VEHICLECOMPONENT_H
#include <QObject>
#include <QQmlContext>
#include <QQuickItem>
#include "UASInterface.h"
......@@ -37,6 +39,7 @@
class VehicleComponent : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT)
Q_PROPERTY(bool requiresSetup READ requiresSetup CONSTANT)
......@@ -44,6 +47,7 @@ class VehicleComponent : public QObject
Q_PROPERTY(QString setupStateDescription READ setupStateDescription STORED false)
Q_PROPERTY(QString icon READ icon CONSTANT)
Q_PROPERTY(QWidget* setupWidget READ setupWidget STORED false)
Q_PROPERTY(QVariantList summaryItems READ summaryItems CONSTANT);
public:
VehicleComponent(UASInterface* uas, QObject* parent = NULL);
......@@ -57,7 +61,9 @@ public:
virtual QString setupStateDescription(void) const = 0;
virtual QWidget* setupWidget(void) const = 0;
virtual QStringList paramFilterList(void) const = 0;
virtual QList<QStringList> summaryItems(void) const = 0;
virtual const QVariantList& summaryItems(void) = 0;
virtual void addSummaryQmlComponent(QQmlContext* context, QQuickItem* parent);
signals:
void setupCompleteChanged(void);
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QGroundControlFactControls 1.0
SetupButton {
width: 300
height: 200
title: vehicleComponent.name
}
/*=====================================================================
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 "VehicleComponentSummaryItem.h"
VehicleComponentSummaryItem::VehicleComponentSummaryItem(const QString& name, const QString& state, QObject* parent) :
QObject(parent),
_name(name),
_state(state)
{
}
/*=====================================================================
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 VehicleComponentSummaryItem_H
#define VehicleComponentSummaryItem_H
#include <QObject>
#include <QQmlContext>
#include <QQuickItem>
#include "UASInterface.h"
/// @file
/// @brief Vehicle Component class. A vehicle component is an object which
/// abstracts the physical portion of a vehicle into a set of
/// configurable values and user interface.
/// @author Don Gagne <don@thegagnes.com>
class VehicleComponentSummaryItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString state READ state CONSTANT)
public:
VehicleComponentSummaryItem(const QString& name, const QString& state, QObject* parent = NULL);
QString name(void) const { return _name; }
QString state(void) const { return _state; }
protected:
QString _name;
QString _state;
};
#endif
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
//import QGroundControl.FactControls 1.0
Row {
width: 200
Text { id: firstCol; text: "Col 1" }
Text { horizontalAlignment: Text.AlignRight; width: parent.width - firstCol.contentWidth; text: "Col 2" }
}
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