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

Merge pull request #1144 from DonLakeFlyer/SafetyComponent

Safety component
parents b1055625 ca2d4a91
......@@ -244,12 +244,14 @@
<file alias="QGroundControl/FactControls/SetupButton.qml">qml/QGroundControl/FactControls/SetupButton.qml</file>
<file alias="QGroundControl/FactControls/FactLabel.qml">qml/QGroundControl/FactControls/FactLabel.qml</file>
<file alias="QGroundControl/FactControls/FactTextField.qml">qml/QGroundControl/FactControls/FactTextField.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">qml/QGroundControl/FactControls/FactCheckBox.qml</file>
<file alias="octo_x.png">files/images/px4/airframes/octo_x.png</file>
<file alias="px4fmu_2.x.png">files/images/px4/boards/px4fmu_2.x.png</file>
<file alias="SetupViewConnected.qml">src/VehicleSetup/SetupViewConnected.qml</file>
<file alias="SetupViewDisconnected.qml">src/VehicleSetup/SetupViewDisconnected.qml</file>
<file alias="SetupPane.qml">src/VehicleSetup/SetupPane.qml</file>
<file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
</qresource>
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
CheckBox {
property Fact fact: Fact { value: 0 }
property variant checkedValue: 1
property variant uncheckedValue: 0
partiallyCheckedEnabled: fact.value != checkedValue && fact.value != uncheckedValue
checkedState: fact.value == checkedValue ? Qt.Checked : (fact.value == uncheckedValue ? Qt.Unchecked : Qt.PartiallyChecked)
text: "Label"
onClicked: {
fact.value = checked ? checkedValue : uncheckedValue
}
style: CheckBoxStyle {
label: Text {
color: palette.windowText
text: control.text
}
}
}
......@@ -9,5 +9,5 @@ Label {
color: palette.windowText
text: fact.value
text: fact.valueString
}
......@@ -5,10 +5,56 @@ import QGroundControl.FactSystem 1.0
TextField {
property Fact fact: Fact { value: 0 }
property bool showUnits: false
QGCPalette { id: palette; colorGroup: enabled ? QGCPalette.Active : QGCPalette.Disabled }
QGCPalette { id: palette; colorGroup: QGCPalette.Active }
text: fact.valueString
textColor: palette.text
text: fact.value
Label {
id: unitsLabelWidthGenerator
text: parent.fact.units
width: contentWidth + ((parent.__contentHeight/3)*2)
visible: false
}
onAccepted: fact.value = text
style: TextFieldStyle {
background: Item {
id: backgroundItem
Rectangle {
anchors.fill: parent
anchors.bottomMargin: -1
color: "#44ffffff"
}
Rectangle {
anchors.fill: parent
border.color: control.activeFocus ? "#47b" : "#999"
color: palette.base
}
Text {
id: unitsLabel
anchors.top: parent.top
anchors.bottom: parent.bottom
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
x: parent.width - width
width: unitsLabelWidthGenerator.width
text: control.fact.units
color: control.textColor
visible: control.showUnits
}
}
padding.right: control.showUnits ? unitsLabelWidthGenerator.width : control.__contentHeight/3
}
onEditingFinished: fact.value = text
}
Module QGroundControl.FactControls
FactLabel 1.0 FactLabel.qml
FactTextField 1.0 FactTextField.qml
\ No newline at end of file
FactTextField 1.0 FactTextField.qml
FactCheckBox 1.0 FactCheckBox.qml
\ No newline at end of file
......@@ -159,6 +159,7 @@
<default>2</default>
<min>0</min>
<max>1000</max>
<unit>timeouts</unit>
</parameter>
<parameter name="NAV_DLL_CHSK" type="INT32">
<short_desc>Skip comms hold wp</short_desc>
......@@ -2041,7 +2042,7 @@
<default>0.5</default>
<min>0</min>
<max>35</max>
<unit>second</unit>
<unit>seconds</unit>
</parameter>
</group>
<group name="mTECS">
......
......@@ -102,55 +102,35 @@ QWidget* SafetyComponent::setupWidget(void) const
const QVariantList& SafetyComponent::summaryItems(void)
{
// FIXME: No summary items yet
#if 0
if (!_summaryItems.count()) {
QString name;
QString state;
// FIXME: Need to pull receiver type from RSSI value
name = "Receiver type:";
state = "n/a";
name = "RTL min alt:";
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" };
name = "RTL home alt:";
QString summary("Chan ");
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
name = "RTL home loiter:";
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
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();
}
} else {
// Why is the parameter missing?
Q_ASSERT(false);
summary += "?";
}
}
name = "Telemetry loss RTL:";
if (!allSticksMapped) {
summary = "Not mapped";
}
name = "Ail, Ele, Rud, Throt:";
state = summary;
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
name = "RC loss RTL:";
item = new VehicleComponentSummaryItem(name, state, this);
_summaryItems.append(QVariant::fromValue(item));
}
#endif
return _summaryItems;
}
......@@ -7,14 +7,92 @@ import QGroundControl.FactControls 1.0
Rectangle {
QGCPalette { id: palette; colorGroup: QGCPalette.Active }
width: 400
width: 600
height: 400
color: palette.window
Column {
Label { text: "Work in Progress"; color: palette.windowText }
Label { text: "Return to Land Altitude"; color: palette.windowText }
FactLabel { fact: autopilot.parameters["RTL_RETURN_ALT"] }
FactTextField { fact: autopilot.parameters["RTL_RETURN_ALT"] }
anchors.fill: parent
spacing: 20
Column {
spacing: 10
Label { text: "Return to Land setup"; color: palette.windowText; font.pointSize: 20 }
Row {
Label { text: "Climb to minimum altitude of "; color: palette.windowText; anchors.baseline: climbField.baseline }
FactTextField { id: climbField; fact: autopilot.parameters["RTL_RETURN_ALT"]; showUnits: true }
}
Row {
Label { text: "When Home is reached, descend to altitude of "; color: palette.windowText; anchors.baseline: descendField.baseline }
FactTextField { id: descendField; fact: autopilot.parameters["RTL_DESCEND_ALT"]; showUnits: true }
}
Row {
CheckBox {
id: homeLoiterCheckbox
property Fact fact: autopilot.parameters["RTL_LAND_DELAY"]
checked: fact.value < 0
text: "Loiter at Home altitude for "
onClicked: {
fact.value = checked ? 60 : -1
}
style: CheckBoxStyle {
label: Text {
color: palette.windowText
text: control.text
}
}
}
FactTextField {
fact: autopilot.parameters["RTL_LAND_DELAY"];
showUnits: true
anchors.baseline: homeLoiterCheckbox.baseline
}
}
}
Column {
spacing: 10
Label { text: "Return to Land Triggers"; color: palette.windowText; font.pointSize: 20 }
Row {
FactCheckBox {
id: telemetryLossCheckbox
fact: autopilot.parameters["COM_DL_LOSS_EN"]
checkedValue: 1
uncheckedValue: 0
text: "Telemetry signal timeout - Return to Land"
anchors.baseline: telemetryLossField.baseline
}
Label { text: " after "; color: palette.windowText; anchors.baseline: telemetryLossField.baseline }
FactTextField {
id: telemetryLossField
fact: autopilot.parameters["NAV_DLL_N"];
showUnits: true
}
}
Row {
Label { text: "RC Transmitter signal loss - Return to Land after "; color: palette.windowText; anchors.baseline: rcLossField.baseline }
FactTextField { id: rcLossField; fact: autopilot.parameters["COM_RC_LOSS_T"]; showUnits: true }
}
}
Text {
width: parent.width
text: "Warning: You have an advanced safety configuration set using the NAV_RCL_OBC parameter. The above settings may not apply.";
visible: autopilot.parameters["NAV_RCL_OBC"].value == 1
color: palette.windowText
wrapMode: Text.Wrap
}
Text {
width: parent.width
text: "Warning: You have an advanced safety configuration set using the NAV_DLL_OBC parameter. The above settings may not apply.";
visible: autopilot.parameters["NAV_DLL_OBC"].value == 1
color: palette.windowText
wrapMode: Text.Wrap
}
}
}
......@@ -48,3 +48,58 @@ void Fact::_containerSetValue(const QVariant& value)
_value = value;
emit valueChanged(_value);
}
QString Fact::name(void) const
{
return _name;
}
QVariant Fact::value(void) const
{
return _value;
}
QString Fact::valueString(void) const
{
return _value.toString();
}
QVariant Fact::defaultValue(void)
{
return _metaData->defaultValue;
}
FactMetaData::ValueType_t Fact::type(void)
{
return _metaData->type;
}
QString Fact::shortDescription(void)
{
return _metaData->shortDescription;
}
QString Fact::longDescription(void)
{
return _metaData->longDescription;
}
QString Fact::units(void)
{
return _metaData->units;
}
QVariant Fact::min(void)
{
return _metaData->min;
}
QVariant Fact::max(void)
{
return _metaData->max;
}
void Fact::setMetaData(FactMetaData* metaData)
{
_metaData = metaData;
}
......@@ -32,6 +32,7 @@
#include <QObject>
#include <QString>
#include <QVariant>
#include <QDebug>
/// @brief A Fact is used to hold a single value within the system.
///
......@@ -44,6 +45,7 @@ class Fact : public QObject
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(QVariant defaultValue READ defaultValue CONSTANT)
Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT)
Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT)
......@@ -60,37 +62,40 @@ public:
// Property system methods
/// Read accessor or name property
QString name(void) const { return _name; }
QString name(void) const;
/// Read accessor for value property
QVariant value(void) const { return _value; }
QVariant value(void) const;
/// Read accessor for valueString property
QString valueString(void) const;
/// Write accessor for value property
void setValue(const QVariant& value);
/// Read accesor for defaultValue property
QVariant defaultValue(void) { return _metaData->defaultValue; }
QVariant defaultValue(void);
/// Read accesor for type property
FactMetaData::ValueType_t type(void) { return _metaData->type; }
FactMetaData::ValueType_t type(void);
/// Read accesor for shortDescription property
QString shortDescription(void) { return _metaData->shortDescription; }
QString shortDescription(void);
/// Read accesor for longDescription property
QString longDescription(void) { return _metaData->longDescription; }
QString longDescription(void);
/// Read accesor for units property
QString units(void) { return _metaData->units; }
QString units(void);
/// Read accesor for min property
QVariant min(void) { return _metaData->min; }
QVariant min(void);
/// Read accesor for max property
QVariant max(void) { return _metaData->max; }
QVariant max(void);
/// Sets the meta data associated with the Fact.
void setMetaData(FactMetaData* metaData) { _metaData = metaData; }
void setMetaData(FactMetaData* metaData);
void _containerSetValue(const QVariant& value);
......
......@@ -82,18 +82,18 @@ void FactLoader::_parameterChanged(int uas, int component, QString parameterName
Q_ASSERT(component == _lastSeenComponent);
}
bool setMetaData = false;
if (!_mapParameterName2Variant.contains(parameterName)) {
qCDebug(FactLoaderLog) << "Adding new fact" << parameterName;
Fact* fact = new Fact(parameterName, this);
setMetaData = true;
_mapParameterName2Variant[parameterName] = QVariant::fromValue(fact);
_mapFact2ParameterName[fact] = parameterName;
// We need to know when the fact changes from QML so that we can send the new value to the parameter manager
connect(fact, &Fact::_containerValueChanged, this, &FactLoader::_valueUpdated);
_addMetaDataToFact(fact);
}
Q_ASSERT(_mapParameterName2Variant.contains(parameterName));
......@@ -103,6 +103,10 @@ void FactLoader::_parameterChanged(int uas, int component, QString parameterName
Fact* fact = _mapParameterName2Variant[parameterName].value<Fact*>();
Q_ASSERT(fact);
fact->_containerSetValue(value);
if (setMetaData) {
_addMetaDataToFact(fact);
}
}
/// Connected to Fact::valueUpdated
......@@ -122,23 +126,26 @@ void FactLoader::_valueUpdated(QVariant value)
case FactMetaData::valueTypeInt8:
case FactMetaData::valueTypeInt16:
case FactMetaData::valueTypeInt32:
typedValue = QVariant(value.value<int>());
typedValue.setValue(QVariant(value.toInt()));
break;
case FactMetaData::valueTypeUint8:
case FactMetaData::valueTypeUint16:
case FactMetaData::valueTypeUint32:
typedValue = QVariant(value.value<uint>());
typedValue.setValue(value.toUInt());
break;
case FactMetaData::valueTypeFloat:
typedValue = QVariant(value.toFloat());
typedValue.setValue(value.toFloat());
break;
case FactMetaData::valueTypeDouble:
typedValue = QVariant(value.toDouble());
typedValue.setValue(value.toDouble());
break;
}
qCDebug(FactLoaderLog) << "Set parameter" << fact->name() << typedValue;
_paramMgr->setParameter(_lastSeenComponent, _mapFact2ParameterName[fact], typedValue);
_paramMgr->sendPendingParameters(true /* persistAfterSend */, false /* forceSend */);
}
......@@ -191,7 +198,7 @@ void FactLoader::_addMetaDataToFact(Fact* fact)
break;
default:
qCWarning(FactLoaderLog) << "Invalid variant type" << fact->value().type();
qWarning() << fact->name() << "Invalid variant type" << fact->value().type();
break;
}
......
......@@ -40,13 +40,18 @@ This file is part of the QGROUNDCONTROL project
IMPLEMENT_QGC_SINGLETON(GAudioOutput, GAudioOutput)
const char* GAudioOutput::_mutedKey = "AudioMuted";
GAudioOutput::GAudioOutput(QObject *parent) :
QGCSingleton(parent),
muted(false),
thread(new QThread()),
worker(new QGCAudioWorker())
{
muted = qgcApp()->runningUnitTests();
QSettings settings;
muted = settings.value(_mutedKey, false).toBool();
muted |= qgcApp()->runningUnitTests();
worker->moveToThread(thread);
connect(this, SIGNAL(textToSpeak(QString,int)), worker, SLOT(say(QString,int)));
......@@ -66,7 +71,12 @@ GAudioOutput::~GAudioOutput()
void GAudioOutput::mute(bool mute)
{
QSettings settings;
muted = mute;
settings.setValue(_mutedKey, mute);
emit mutedChanged(mute);
}
bool GAudioOutput::isMuted()
......
......@@ -110,6 +110,8 @@ protected:
private:
GAudioOutput(QObject *parent = NULL);
~GAudioOutput();
static const char* _mutedKey;
};
#endif // AUDIOOUTPUT_H
......
......@@ -47,7 +47,8 @@ QColor QGCPalette::_window[QGCPalette::_cColorGroups];
QColor QGCPalette::_windowText[QGCPalette::_cColorGroups];
QGCPalette::QGCPalette(QObject* parent) :
QObject(parent)
QObject(parent),
_colorGroup(Active)
{
if (!_paletteLoaded) {
_paletteLoaded = true;
......
......@@ -55,7 +55,7 @@ class QGCPalette : public QObject
public:
enum ColorGroup {
Disabled,
Disabled = 0,
Active,
Inactive
};
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
//import QGroundControl.FactControls 1.0
Item {
id: item1
width: 500
height: 500
Rectangle {
id: innerRect
color: "#d298d2"
z: 1
anchors.rightMargin: 15
anchors.leftMargin: 15
anchors.bottomMargin: 15
anchors.topMargin: 40
anchors.fill: parent
Rectangle {
id: close
x: parent.width - (width / 2)
y: 0 - (height / 2)
width: 30
height: 30
color: "#ffffff"
radius: 15
z: 2
border.color: "#000000"
}
}
Rectangle {
id: outerRect
color: "#ffffff"
opacity: 0.8
anchors.fill: parent
Text {
id: title
x: 237
y: 8
text: qsTr("Setup Pane")
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: 20
}
}
}
......@@ -206,6 +206,8 @@ void MockLink::_loadParams(void)
break;
}
qCDebug(MockLinkLog) << "Loading param" << paramName << paramValue;
_mapParamName2Value[paramName] = paramValue;
_mapParamName2MavParamType[paramName] = static_cast<MAV_PARAM_TYPE>(paramType);
}
......@@ -461,6 +463,8 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg)
Q_ASSERT(paramName.length() <= MAVLINK_MSG_ID_PARAM_VALUE_LEN);
strncpy(paramId, paramName.toLocal8Bit().constData(), MAVLINK_MSG_ID_PARAM_VALUE_LEN);
qCDebug(MockLinkLog) << "Sending msg_param_value" << paramId << paramType;
mavlink_msg_param_value_pack(_vehicleSystemId,
_vehicleComponentId,
&responseMsg, // Outgoing message
......
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