Commit 7955dc3a authored by Don Gagne's avatar Don Gagne

Merge pull request #1281 from DonLakeFlyer/SensorConfig

Sensor config in Qml
parents 73f716be 76065a63
......@@ -337,8 +337,6 @@ FORMS += \
src/ui/configuration/terminalconsole.ui \
src/ui/configuration/SerialSettingsDialog.ui \
src/ui/px4_configuration/QGCPX4AirframeConfig.ui \
src/ui/px4_configuration/QGCPX4MulticopterConfig.ui \
src/ui/px4_configuration/QGCPX4SensorCalibration.ui \
src/ui/px4_configuration/PX4RCCalibration.ui \
src/ui/QGCUASFileView.ui \
src/QGCQmlWidgetHolder.ui \
......@@ -472,8 +470,6 @@ HEADERS += \
src/ui/QGCPendingParamWidget.h \
src/ui/px4_configuration/QGCPX4AirframeConfig.h \
src/ui/QGCBaseParamWidget.h \
src/ui/px4_configuration/QGCPX4MulticopterConfig.h \
src/ui/px4_configuration/QGCPX4SensorCalibration.h \
src/ui/px4_configuration/PX4RCCalibration.h \
src/ui/px4_configuration/RCValueWidget.h \
src/uas/UASManagerInterface.h \
......@@ -617,8 +613,6 @@ SOURCES += \
src/ui/QGCPendingParamWidget.cc \
src/ui/px4_configuration/QGCPX4AirframeConfig.cc \
src/ui/QGCBaseParamWidget.cc \
src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \
src/ui/px4_configuration/QGCPX4SensorCalibration.cc \
src/ui/px4_configuration/PX4RCCalibration.cc \
src/ui/px4_configuration/RCValueWidget.cc \
src/uas/QGCUASFileManager.cc \
......@@ -743,6 +737,7 @@ HEADERS+= \
src/AutoPilotPlugins/PX4/FlightModeConfig.h \
src/AutoPilotPlugins/PX4/AirframeComponent.h \
src/AutoPilotPlugins/PX4/SensorsComponent.h \
src/AutoPilotPlugins/PX4/SensorsComponentController.h \
src/AutoPilotPlugins/PX4/SafetyComponent.h \
src/AutoPilotPlugins/PX4/PX4ParameterFacts.h \
......@@ -754,6 +749,7 @@ SOURCES += \
src/VehicleSetup/PX4Bootloader.cc \
src/VehicleSetup/PX4FirmwareUpgradeThread.cc \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \
src/AutoPilotPlugins/AutoPilotPlugin.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/Generic/GenericParameterFacts.cc \
src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc \
......@@ -763,6 +759,7 @@ SOURCES += \
src/AutoPilotPlugins/PX4/FlightModeConfig.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \
src/AutoPilotPlugins/PX4/SensorsComponent.cc \
src/AutoPilotPlugins/PX4/SensorsComponentController.cc \
src/AutoPilotPlugins/PX4/SafetyComponent.cc \
src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc \
......
......@@ -245,9 +245,11 @@
<file alias="QGroundControl/FactControls/FactLabel.qml">src/FactSystem/FactControls/FactLabel.qml</file>
<file alias="QGroundControl/FactControls/FactTextField.qml">src/FactSystem/FactControls/FactTextField.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">src/FactSystem/FactControls/FactCheckBox.qml</file>
<file alias="QGroundControl/FactControls/FactComboBox.qml">src/FactSystem/FactControls/FactComboBox.qml</file>
<file alias="QGroundControl/Controls/qmldir">src/QmlControls/qmldir</file>
<file alias="QGroundControl/Controls/SubMenuButton.qml">src/QmlControls/SubMenuButton.qml</file>
<file alias="QGroundControl/Controls/IndicatorButton.qml">src/QmlControls/IndicatorButton.qml</file>
<file alias="QGroundControl/Controls/QGCButton.qml">src/QmlControls/QGCButton.qml</file>
<file alias="QGroundControl/Controls/QGCRadioButton.qml">src/QmlControls/QGCRadioButton.qml</file>
<file alias="QGroundControl/Controls/QGCCheckBox.qml">src/QmlControls/QGCCheckBox.qml</file>
......@@ -266,6 +268,7 @@
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
<file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file>
<file alias="SafetyComponentSummary.qml">src/AutoPilotPlugins/PX4/SafetyComponentSummary.qml</file>
<file alias="SensorsComponentSummary.qml">src/AutoPilotPlugins/PX4/SensorsComponentSummary.qml</file>
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 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 "AutoPilotPlugin.h"
AutoPilotPlugin::AutoPilotPlugin(UASInterface* uas, QObject* parent) :
QObject(parent),
_uas(uas)
{
Q_ASSERT(_uas);
}
void AutoPilotPlugin::refreshAllParameters(void)
{
Q_ASSERT(_uas);
QGCUASParamManagerInterface* paramMgr = _uas->getParamManager();
Q_ASSERT(paramMgr);
paramMgr->requestParameterList();
}
void AutoPilotPlugin::refreshParameter(const QString& param)
{
Q_ASSERT(_uas);
QGCUASParamManagerInterface* paramMgr = _uas->getParamManager();
Q_ASSERT(paramMgr);
QList<int> compIdList = paramMgr->getComponentForParam(param);
Q_ASSERT(compIdList.count() > 0);
paramMgr->requestParameterUpdate(compIdList[0], param);
}
void AutoPilotPlugin::refreshParametersPrefix(const QString& paramPrefix)
{
foreach(QVariant varFact, parameters()) {
Fact* fact = qvariant_cast<Fact*>(varFact);
Q_ASSERT(fact);
if (fact->name().startsWith(paramPrefix)) {
refreshParameter(fact->name());
}
}
}
......@@ -48,10 +48,21 @@ class AutoPilotPlugin : public QObject
Q_OBJECT
public:
AutoPilotPlugin(UASInterface* uas, QObject* parent);
Q_PROPERTY(QVariantMap parameters READ parameters CONSTANT)
Q_PROPERTY(QVariantList components READ components CONSTANT)
Q_PROPERTY(QUrl setupBackgroundImage READ setupBackgroundImage CONSTANT)
/// Re-request the full set of parameters from the autopilot
Q_INVOKABLE void refreshAllParameters(void);
/// Request a refresh on the specific parameter
Q_INVOKABLE void refreshParameter(const QString& param);
// Request a refresh on all parameters that begin with the specified prefix
Q_INVOKABLE void refreshParametersPrefix(const QString& paramPrefix);
// Property accessors
virtual const QVariantList& components(void) = 0;
virtual const QVariantMap& parameters(void) = 0;
......@@ -63,6 +74,8 @@ public:
/// FIXME: Kind of hacky
static void clearStaticData(void);
UASInterface* uas(void) { return _uas; }
signals:
/// Signalled when plugin is ready for use
void pluginReady(void);
......@@ -71,6 +84,7 @@ protected:
/// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
UASInterface* _uas;
};
#endif
......@@ -27,9 +27,9 @@
#include "GenericAutoPilotPlugin.h"
GenericAutoPilotPlugin::GenericAutoPilotPlugin(UASInterface* uas, QObject* parent) :
AutoPilotPlugin(parent)
AutoPilotPlugin(uas, parent)
{
Q_UNUSED(uas);
Q_ASSERT(uas);
_parameterFacts = new GenericParameterFacts(uas, this);
Q_CHECK_PTR(_parameterFacts);
......
......@@ -26,6 +26,8 @@
#include "UASManager.h"
#include "QGCUASParamManagerInterface.h"
#include "PX4ParameterFacts.h"
#include "SensorsComponentController.h"
#include "QGCMessageBox.h"
/// @file
/// @brief This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_PX4 type.
......@@ -61,21 +63,21 @@ union px4_custom_mode {
};
PX4AutoPilotPlugin::PX4AutoPilotPlugin(UASInterface* uas, QObject* parent) :
AutoPilotPlugin(parent),
_uas(uas),
AutoPilotPlugin(uas, parent),
_parameterFacts(NULL),
_airframeComponent(NULL),
_radioComponent(NULL),
_flightModesComponent(NULL),
_sensorsComponent(NULL),
_safetyComponent(NULL)
_safetyComponent(NULL),
_incorrectParameterVersion(false)
{
Q_ASSERT(uas);
_parameterFacts = new PX4ParameterFacts(uas, this);
Q_CHECK_PTR(_parameterFacts);
connect(_parameterFacts, &PX4ParameterFacts::factsReady, this, &PX4AutoPilotPlugin::pluginReady);
connect(_parameterFacts, &PX4ParameterFacts::factsReady, this, &PX4AutoPilotPlugin::_checkForIncorrectParameterVersion);
PX4ParameterFacts::loadParameterFactMetaData();
}
......@@ -191,7 +193,7 @@ bool PX4AutoPilotPlugin::pluginIsReady(void) const
const QVariantList& PX4AutoPilotPlugin::components(void)
{
if (_components.count() == 0) {
if (_components.count() == 0 && !_incorrectParameterVersion) {
Q_ASSERT(_uas);
_airframeComponent = new AirframeComponent(_uas, this);
......@@ -227,3 +229,13 @@ QUrl PX4AutoPilotPlugin::setupBackgroundImage(void)
{
return QUrl::fromUserInput("qrc:/qml/px4fmu_2.x.png");
}
void PX4AutoPilotPlugin::_checkForIncorrectParameterVersion(void)
{
if (parameters().contains("SENS_GYRO_XOFF")) {
_incorrectParameterVersion = true;
QGCMessageBox::warning(tr("Setup"), tr("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."));
}
emit pluginReady();
}
......@@ -65,8 +65,10 @@ public:
SensorsComponent* sensorsComponent(void) { return _sensorsComponent; }
SafetyComponent* safetyComponent(void) { return _safetyComponent; }
private slots:
void _checkForIncorrectParameterVersion(void);
private:
UASInterface* _uas;
PX4ParameterFacts* _parameterFacts;
QVariantList _components;
AirframeComponent* _airframeComponent;
......@@ -74,6 +76,7 @@ private:
FlightModesComponent* _flightModesComponent;
SensorsComponent* _sensorsComponent;
SafetyComponent* _safetyComponent;
bool _incorrectParameterVersion; ///< true: parameter version incorrect, setup not allowed
};
#endif
......@@ -25,25 +25,21 @@
/// @author Don Gagne <don@thegagnes.com>
#include "SensorsComponent.h"
#include "QGCPX4SensorCalibration.h"
#include "PX4AutoPilotPlugin.h"
#include "QGCQmlWidgetHolder.h"
#include "SensorsComponentController.h"
// These two list must be kept in sync
/// @brief Parameters which signal a change in setupComplete state
static const char* triggerParamsV1[] = { "SENS_MAG_XOFF", "SENS_GYRO_XOFF", "SENS_ACC_XOFF", NULL };
static const char* triggerParamsV2[] = { "CAL_MAG0_ID", "CAL_GYRO0_ID", "CAL_ACC0_ID", NULL };
static const char* triggerParamsV1FixedWing[] = { "SENS_MAG_XOFF", "SENS_GYRO_XOFF", "SENS_ACC_XOFF", "SENS_DPRES_OFF", NULL };
static const char* triggerParamsV2FixedWing[] = { "CAL_MAG0_ID", "CAL_GYRO0_ID", "CAL_ACC0_ID", "SENS_DPRES_OFF", NULL };
static const char* triggerParams[] = { "CAL_MAG0_ID", "CAL_GYRO0_ID", "CAL_ACC0_ID", NULL };
static const char* triggerParamsFixedWing[] = { "CAL_MAG0_ID", "CAL_GYRO0_ID", "CAL_ACC0_ID", "SENS_DPRES_OFF", NULL };
SensorsComponent::SensorsComponent(UASInterface* uas, AutoPilotPlugin* autopilot, QObject* parent) :
PX4Component(uas, autopilot, parent),
_name(tr("Sensors"))
{
// Determine what set of parameters are available. This is a temporary hack for now. Will need real parameter
// mapping in the future.
QVariant value;
_paramsV1 = _paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "SENS_MAG_XOFF", value);
}
QString SensorsComponent::name(void) const
......@@ -104,29 +100,31 @@ QString SensorsComponent::setupStateDescription(void) const
const char** SensorsComponent::setupCompleteChangedTriggerList(void) const
{
if (_uas->getSystemType() == MAV_TYPE_FIXED_WING) {
return _paramsV1 ? triggerParamsV1FixedWing : triggerParamsV2FixedWing;
} else {
return _paramsV1 ? triggerParamsV1 : triggerParamsV2;
}
return _uas->getSystemType() == MAV_TYPE_FIXED_WING ? triggerParamsFixedWing : triggerParams;
}
QStringList SensorsComponent::paramFilterList(void) const
{
QStringList list;
if (_paramsV1) {
list << "SENS_*";
} else {
list << "CAL_*";
}
list << "SENS_*" << "CAL_*";
return list;
}
QWidget* SensorsComponent::setupWidget(void) const
{
return new QGCPX4SensorCalibration;
QGCQmlWidgetHolder* holder = new QGCQmlWidgetHolder();
Q_CHECK_PTR(holder);
holder->setAutoPilot(_autopilot);
SensorsComponentController* controller = new SensorsComponentController(_autopilot, holder);
holder->setContextPropertyObject("controller", controller);
holder->setSource(QUrl::fromUserInput("qrc:/qml/SensorsComponent.qml"));
return holder;
}
QUrl SensorsComponent::summaryQmlSource(void) const
......
......@@ -55,7 +55,6 @@ public:
private:
const QString _name;
QVariantList _summaryItems;
bool _paramsV1;
};
#endif
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
Rectangle {
property QGCPalette qgcPal: QGCPalette { colorGroupEnabled: true }
readonly property int rotationColumnWidth: 200
readonly property var rotations: [
"ROTATION_NONE",
"ROTATION_YAW_45",
"ROTATION_YAW_90",
"ROTATION_YAW_135",
"ROTATION_YAW_180",
"ROTATION_YAW_225",
"ROTATION_YAW_270",
"ROTATION_YAW_315",
"ROTATION_ROLL_180",
"ROTATION_ROLL_180_YAW_45",
"ROTATION_ROLL_180_YAW_90",
"ROTATION_ROLL_180_YAW_135",
"ROTATION_PITCH_180",
"ROTATION_ROLL_180_YAW_225",
"ROTATION_ROLL_180_YAW_270",
"ROTATION_ROLL_180_YAW_315",
"ROTATION_ROLL_90",
"ROTATION_ROLL_90_YAW_45",
"ROTATION_ROLL_90_YAW_90",
"ROTATION_ROLL_90_YAW_135",
"ROTATION_ROLL_270",
"ROTATION_ROLL_270_YAW_45",
"ROTATION_ROLL_270_YAW_90",
"ROTATION_ROLL_270_YAW_135",
"ROTATION_PITCH_90",
"ROTATION_PITCH_270",
"ROTATION_ROLL_270_YAW_270"
]
width: 600
height: 600
color: qgcPal.window
// We use this bogus loader just so we can get an onLoaded signal to hook to in order to
// finish controller initialization.
Component {
id: loadSignal;
Item { }
}
Loader {
sourceComponent: loadSignal
onLoaded: controller.statusLog = statusTextArea
}
Column {
anchors.fill: parent
QGCLabel {
text: "SENSORS CONFIG"
font.pointSize: 20
}
Item { height: 20; width: 10 } // spacer
Item {
readonly property int calibrationAreaHeight: 300
width: parent.width
height: calibrationAreaHeight
TextArea {
id: statusTextArea
width: parent.width - rotationColumnWidth
height: parent.height
readOnly: true
frameVisible: false
text: qsTr("Sensor config is a work in progress which currently supports textual instructions only. Updated visuals coming soon.")
style: TextAreaStyle {
textColor: qgcPal.text
backgroundColor: qgcPal.windowShade
}
}
Column {
// Compass rotation parameter < 0 indicates either internal compass, or no compass. So in
// both those cases we do not show a rotation combo.
property bool showCompass0: autopilot.parameters["CAL_MAG0_ROT"].value >= 0
property bool showCompass1: autopilot.parameters["CAL_MAG1_ROT"].value >= 0
property bool showCompass2: autopilot.parameters["CAL_MAG2_ROT"].value >= 0
x: parent.width - rotationColumnWidth
QGCLabel { text: "Autpilot Orientation" }
FactComboBox {
width: rotationColumnWidth;
model: rotations
fact: autopilot.parameters["SENS_BOARD_ROT"]
}
// Compass 0 rotation
Component {
id: compass0ComponentLabel
QGCLabel { text: "Compass Orientation" }
}
Component {
id: compass0ComponentCombo
FactComboBox {
width: rotationColumnWidth
model: rotations
fact: autopilot.parameters["CAL_MAG0_ROT"]
}
}
Loader { sourceComponent: parent.showCompass0 ? compass0ComponentLabel : null }
Loader { sourceComponent: parent.showCompass0 ? compass0ComponentCombo : null }
// Compass 1 rotation
Component {
id: compass1ComponentLabel
QGCLabel { text: "Compass 1 Orientation" }
}
Component {
id: compass1ComponentCombo
FactComboBox {
width: rotationColumnWidth
model: rotations
fact: autopilot.parameters["CAL_MAG1_ROT"]
}
}
Loader { sourceComponent: parent.showCompass1 ? compass1ComponentLabel : null }
Loader { sourceComponent: parent.showCompass1 ? compass1ComponentCombo : null }
// Compass 2 rotation
Component {
id: compass2ComponentLabel
QGCLabel { text: "Compass 2 Orientation" }
}
Component {
id: compass2ComponentCombo
FactComboBox {
width: rotationColumnWidth
model: rotations
fact: autopilot.parameters["CAL_MAG2_ROT"]
}
}
Loader { sourceComponent: parent.showCompass2 ? compass2ComponentLabel : null }
Loader { sourceComponent: parent.showCompass2 ? compass2ComponentCombo : null }
}
}
Item { height: 20; width: 10 } // spacer
Row {
readonly property int buttonWidth: 120
spacing: 20
QGCLabel { text: "Calibrate:"; anchors.baseline: firstButton.baseline }
IndicatorButton {
id: firstButton
width: parent.buttonWidth
text: "Compass"
indicatorGreen: autopilot.parameters["CAL_MAG0_ID"].value != 0
onClicked: controller.calibrateCompass()
}
IndicatorButton {
width: parent.buttonWidth
text: "Gyroscope"
indicatorGreen: autopilot.parameters["CAL_GYRO0_ID"].value != 0
onClicked: controller.calibrateGyro()
}
IndicatorButton {
width: parent.buttonWidth
text: "Acceleromter"
indicatorGreen: autopilot.parameters["CAL_ACC0_ID"].value != 0
onClicked: controller.calibrateAccel()
}
IndicatorButton {
width: parent.buttonWidth
text: "Airspeed"
visible: controller.fixedWing
indicatorGreen: autopilot.parameters["SENS_DPRES_OFF"].value != 0
onClicked: controller.calibrateAirspeed()
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 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 "SensorsComponentController.h"
#include "QGCMAVLink.h"
#include "UASManager.h"
#include <QVariant>
#include <QQmlProperty>
SensorsComponentController::SensorsComponentController(AutoPilotPlugin* autopilot, QObject* parent) :
QObject(parent),
_autopilot(autopilot)
{
Q_ASSERT(autopilot);
}
/// Appends the specified text to the status log area in the ui
void SensorsComponentController::_appendStatusLog(const QString& text)
{
Q_ASSERT(_statusLog);
QVariant returnedValue;
QVariant varText = text;
QMetaObject::invokeMethod(_statusLog,
"append",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, varText));
}
void SensorsComponentController::calibrateGyro(void)
{
_beginTextLogging();
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
uas->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
}
void SensorsComponentController::calibrateCompass(void)
{
_beginTextLogging();
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
uas->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
}
void SensorsComponentController::calibrateAccel(void)
{
_beginTextLogging();
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
uas->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0);
}
void SensorsComponentController::calibrateAirspeed(void)
{
_beginTextLogging();
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
uas->executeCommand(MAV_CMD_PREFLIGHT_CALIBRATION, 1, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0);
}
void SensorsComponentController::_beginTextLogging(void)
{
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
connect(uas, &UASInterface::textMessageReceived, this, &SensorsComponentController::_handleUASTextMessage);
}
void SensorsComponentController::_handleUASTextMessage(int uasId, int compId, int severity, QString text)
{
Q_UNUSED(compId);
Q_UNUSED(severity);
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
if (uasId != uas->getUASID()) {
return;
}
QStringList ignorePrefixList;
ignorePrefixList << "[cmd]" << "[mavlink pm]" << "[ekf check]";
foreach (QString ignorePrefix, ignorePrefixList) {
if (text.startsWith(ignorePrefix)) {
return;
}
}
_appendStatusLog(text);
if (text.endsWith(" calibration: done") || text.endsWith(" calibration: failed")) {
_refreshParams();
}
}
void SensorsComponentController::_refreshParams(void)
{
#if 0
// FIXME: Not sure if firmware issue yet
_autopilot->refreshParametersPrefix("CAL_");
_autopilot->refreshParametersPrefix("SENS_");
#else
// Sending too many parameter requests like above doesn't seem to work. So for now,
// ask for everything back
_autopilot->refreshAllParameters();
#endif
}
bool SensorsComponentController::fixedWing(void)
{
UASInterface* uas = _autopilot->uas();
Q_ASSERT(uas);
return uas->getSystemType() == MAV_TYPE_FIXED_WING;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 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 SENSORSCOMPONENTCONTROLLER_H
#define SENSORSCOMPONENTCONTROLLER_H
#include <QObject>
#include <QQuickItem>
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
/// Sensors Component MVC Controller for SensorsComponent.qml.
class SensorsComponentController : public QObject
{
Q_OBJECT
public:
SensorsComponentController(AutoPilotPlugin* autopilot, QObject* parent = NULL);
Q_PROPERTY(bool fixedWing READ fixedWing CONSTANT)
/// TextArea for log output
Q_PROPERTY(QQuickItem* statusLog MEMBER _statusLog)
Q_INVOKABLE void calibrateCompass(void);
Q_INVOKABLE void calibrateGyro(void);
Q_INVOKABLE void calibrateAccel(void);
Q_INVOKABLE void calibrateAirspeed(void);
bool fixedWing(void);
signals:
void bogusNotify(void);
private slots:
void _handleUASTextMessage(int uasId, int compId, int severity, QString text);
private:
void _beginTextLogging(void);
void _appendStatusLog(const QString& text);
void _refreshParams(void);
QQuickItem* _statusLog; ///< Status log TextArea Qml control
AutoPilotPlugin* _autopilot;
};
#endif
......@@ -20,8 +20,7 @@ Column {
QGCLabel {
horizontalAlignment: Text.AlignRight;
width: parent.width - compass.contentWidth;
property bool setupRequiredValue: autopilot.parameters["SENS_MAG_XOFF"] ? autopilot.parameters["SENS_MAG_XOFF"].value : autopilot.parameters["CAL_MAG0_ID"].value
text: setupRequiredValue == 0 ? "Setup required" : "Ready"
text: autopilot.parameters["CAL_MAG0_ID"].value == 0 ? "Setup required" : "Ready"
}
}
......@@ -32,8 +31,7 @@ Column {
QGCLabel {
horizontalAlignment: Text.AlignRight;
width: parent.width - gyro.contentWidth;
property bool setupRequiredValue: autopilot.parameters["SENS_GYRO_XOFF"] ? autopilot.parameters["SENS_GYRO_XOFF"].value : autopilot.parameters["CAL_GYRO0_ID"].value
text: setupRequiredValue == 0 ? "Setup required" : "Ready"
text: autopilot.parameters["CAL_GYRO0_ID"].value == 0 ? "Setup required" : "Ready"
}
}
......@@ -44,8 +42,7 @@ Column {
QGCLabel {
horizontalAlignment: Text.AlignRight;
width: parent.width - accel.contentWidth;
property bool setupRequiredValue: autopilot.parameters["SENS_ACC_XOFF"] ? autopilot.parameters["SENS_ACC_XOFF"].value : autopilot.parameters["CAL_ACC0_ID"].value
text: setupRequiredValue == 0 ? "Setup required" : "Ready"
text: autopilot.parameters["CAL_ACC0_ID"].value == 0 ? "Setup required" : "Ready"
}
}
}
......@@ -20,8 +20,7 @@ Column {
QGCLabel {
horizontalAlignment: Text.AlignRight;
width: parent.width - compass.contentWidth;
property bool setupRequiredValue: autopilot.parameters["SENS_MAG_XOFF"] ? autopilot.parameters["SENS_MAG_XOFF"].value : autopilot.parameters["CAL_MAG0_ID"].value
text: setupRequiredValue == 0 ? "Setup required" : "Ready"
text: autopilot.parameters["CAL_MAG0_ID"].value == 0 ? "Setup required" : "Ready"
}
}
......@@ -32,8 +31,7 @@ Column {
QGCLabel {
horizontalAlignment: Text.AlignRight;
width: parent.width - gyro.contentWidth;
property bool setupRequiredValue: autopilot.parameters["SENS_GYRO_XOFF"] ? autopilot.parameters["SENS_GYRO_XOFF"].value : autopilot.parameters["CAL_GYRO0_ID"].value
text: setupRequiredValue == 0 ? "Setup required" : "Ready"
text: autopilot.parameters["CAL_GYRO0_ID"].value == 0 ? "Setup required" : "Ready"
}
}
......@@ -44,8 +42,7 @@ Column {
QGCLabel {
horizontalAlignment: Text.AlignRight;
width: parent.width - accel.contentWidth;
property bool setupRequiredValue: autopilot.parameters["SENS_ACC_XOFF"] ? autopilot.parameters["SENS_ACC_XOFF"].value : autopilot.parameters["CAL_ACC0_ID"].value
text: setupRequiredValue == 0 ? "Setup required" : "Ready"
text: autopilot.parameters["CAL_ACC0_ID"].value == 0 ? "Setup required" : "Ready"
}
}
......
......@@ -28,12 +28,13 @@
#include <QtQml>
Fact::Fact(QString name, QObject* parent) :
Fact::Fact(QString name, FactMetaData::ValueType_t type, QObject* parent) :
QObject(parent),
_name(name),
_type(type),
_metaData(NULL)
{
_value = "";
_value = 0;
}
void Fact::setValue(const QVariant& value)
......@@ -72,8 +73,7 @@ QVariant Fact::defaultValue(void)
FactMetaData::ValueType_t Fact::type(void)
{
Q_ASSERT(_metaData);
return _metaData->type;
return _type;
}
QString Fact::shortDescription(void)
......
......@@ -57,7 +57,7 @@ class Fact : public QObject
Q_ENUMS(FactMetaData::ValueType_t)
public:
Fact(QString name = "", QObject* parent = NULL);
Fact(QString name = "", FactMetaData::ValueType_t type = FactMetaData::valueTypeInt32, QObject* parent = NULL);
// Property system methods
......@@ -111,9 +111,10 @@ signals:
void _containerValueChanged(QVariant& value);
private:
QString _name; ///< Fact name
QVariant _value; ///< Fact value
FactMetaData* _metaData; ///< FactMetaData object for Fact
QString _name;
QVariant _value;
FactMetaData::ValueType_t _type;
FactMetaData* _metaData;
};
#endif
\ No newline at end of file
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
QGCComboBox {
property Fact fact: Fact { value: 0 }
currentIndex: fact.value
onActivated: fact.value = index
}
Module QGroundControl.FactControls
FactLabel 1.0 FactLabel.qml
FactTextField 1.0 FactTextField.qml
FactCheckBox 1.0 FactCheckBox.qml
FactComboBox 1.0 FactComboBox.qml
\ No newline at end of file
......@@ -51,9 +51,8 @@ FactLoader::FactLoader(UASInterface* uas, QObject* parent) :
// We need to know when the param mgr is done sending the initial set of paramters
connect(_paramMgr, SIGNAL(parameterListUpToDate()), this, SLOT(_paramMgrParameterListUpToDate()));
// We track parameters changes to keep Facts up to date. UASInterface::parameterChanged has multiple overrides so we need to
// use SIGNAL/SLOT style connect
connect(uas, SIGNAL(parameterChanged(int, int, QString, QVariant)), this, SLOT(_parameterChanged(int, int, QString, QVariant)));
// We track parameters changes to keep Facts up to date.
connect(uas, &UASInterface::parameterUpdate, this, &FactLoader::_parameterUpdate);
}
FactLoader::~FactLoader()
......@@ -65,10 +64,8 @@ FactLoader::~FactLoader()
_mapFact2ParameterName.clear();
}
/// Connected to QGCUASParmManager::parameterChanged
///
/// When a new parameter is seen it is added to the system. If the parameter is already known it is updated.
void FactLoader::_parameterChanged(int uas, int component, QString parameterName, QVariant value)
/// Called whenever a parameter is updated or first seen.
void FactLoader::_parameterUpdate(int uas, int component, QString parameterName, int mavType, QVariant value)
{
// Is this for our uas?
if (uas != _uasId) {
......@@ -86,7 +83,39 @@ void FactLoader::_parameterChanged(int uas, int component, QString parameterName
if (!_mapParameterName2Variant.contains(parameterName)) {
qCDebug(FactLoaderLog) << "Adding new fact" << parameterName;
Fact* fact = new Fact(parameterName, this);
FactMetaData::ValueType_t factType;
switch (mavType) {
case MAV_PARAM_TYPE_UINT8:
factType = FactMetaData::valueTypeUint8;
break;
case MAV_PARAM_TYPE_INT8:
factType = FactMetaData::valueTypeUint8;
break;
case MAV_PARAM_TYPE_UINT16:
factType = FactMetaData::valueTypeUint16;
break;
case MAV_PARAM_TYPE_INT16:
factType = FactMetaData::valueTypeInt16;
break;
case MAV_PARAM_TYPE_UINT32:
factType = FactMetaData::valueTypeUint32;
break;
case MAV_PARAM_TYPE_INT32:
factType = FactMetaData::valueTypeInt32;
break;
case MAV_PARAM_TYPE_REAL32:
factType = FactMetaData::valueTypeFloat;
break;
case MAV_PARAM_TYPE_REAL64:
factType = FactMetaData::valueTypeDouble;
break;
default:
factType = FactMetaData::valueTypeInt32;
qCritical() << "Unsupported fact type" << mavType;
break;
}
Fact* fact = new Fact(parameterName, factType, this);
setMetaData = true;
_mapParameterName2Variant[parameterName] = QVariant::fromValue(fact);
......@@ -169,39 +198,6 @@ void FactLoader::_paramMgrParameterListUpToDate(void)
void FactLoader::_addMetaDataToFact(Fact* fact)
{
// Create generic meta data based on value variant type
FactMetaData::ValueType_t factType = FactMetaData::valueTypeInt32; // init to in32 to silence compiler warning
switch ((QMetaType::Type)fact->value().type()) {
case QMetaType::Int:
factType = FactMetaData::valueTypeInt32;
break;
case QMetaType::UInt:
factType = FactMetaData::valueTypeUint32;
break;
case QMetaType::Double:
factType = FactMetaData::valueTypeDouble;
case QMetaType::Short:
factType = FactMetaData::valueTypeInt16;
break;
case QMetaType::UShort:
factType = FactMetaData::valueTypeUint16;
break;
case QMetaType::Float:
factType = FactMetaData::valueTypeFloat;
break;
default:
qWarning() << fact->name() << "Invalid variant type" << fact->value().type();
break;
}
FactMetaData* metaData = new FactMetaData(this);
metaData->initFromTypeOnly(factType);
metaData->initFromTypeOnly(fact->type());
}
......@@ -72,7 +72,7 @@ protected:
virtual void _addMetaDataToFact(Fact* fact);
private slots:
void _parameterChanged(int uas, int component, QString parameterName, QVariant value);
void _parameterUpdate(int uas, int component, QString parameterName, int mavType, QVariant value);
void _valueUpdated(QVariant value);
void _paramMgrParameterListUpToDate(void);
......
......@@ -37,6 +37,4 @@ FactMetaData::FactMetaData(QObject* parent) :
void FactMetaData::initFromTypeOnly(ValueType_t initType)
{
type = initType;
// FIXME: NYI
}
......@@ -40,10 +40,15 @@ QGCQmlWidgetHolder::~QGCQmlWidgetHolder()
void QGCQmlWidgetHolder::setAutoPilot(AutoPilotPlugin* autoPilot)
{
_ui.qmlWidget->rootContext()->setContextProperty("autopilot", autoPilot);
setContextPropertyObject("autopilot", autoPilot);
}
bool QGCQmlWidgetHolder::setSource(const QUrl& qmlUrl)
{
return _ui.qmlWidget->setSource(qmlUrl);
}
void QGCQmlWidgetHolder::setContextPropertyObject(const QString& name, QObject* object)
{
_ui.qmlWidget->rootContext()->setContextProperty(name, object);
}
......@@ -53,6 +53,8 @@ public:
/// @return true: source loaded, false: source not loaded, errors occured
bool setSource(const QUrl& qmlUrl);
void setContextPropertyObject(const QString& name, QObject* object);
private:
Ui::QGCQmlWidgetHolder _ui;
};
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
// An IndicatorButton works just like q QGCButton with the additional support or a red/green
// indicator on the right edge.
QGCButton {
property bool indicatorGreen: false
Rectangle {
readonly property real indicatorRadius: 4
x: parent.width - (indicatorRadius * 2) - 5
y: (parent.height - (indicatorRadius * 2)) / 2
width: indicatorRadius * 2
height: indicatorRadius * 2
radius: indicatorRadius
color: indicatorGreen ? "#00d932" : "red"
}
}
Module QGroundControl.Controls
SubMenuButton 1.0 SubMenuButton.qml
QGCLabel 1.0 QGCLabel.qml
QGCButton 1.0 QGCButton.qml
QGCRadioButton 1.0 QGCRadioButton.qml
......@@ -7,3 +7,7 @@ QGCCheckBox 1.0 QGCCheckBox.qml
QGCTextField 1.0 QGCTextField.qml
QGCComboBox 1.0 QGCComboBox.qml
QGCColoredImage 1.0 QGCColoredImage.qml
SubMenuButton 1.0 SubMenuButton.qml
IndicatorButton 1.0 IndicatorButton.qml
This diff is collapsed.
......@@ -2414,6 +2414,7 @@ void UAS::processParamValueMsg(mavlink_message_t& msg, const QString& paramName,
parameters.value(compId)->insert(paramName, paramValue);
emit parameterChanged(uasId, compId, paramName, paramValue);
emit parameterUpdate(uasId, compId, paramName, rawValue.param_type, paramValue);
emit parameterChanged(uasId, compId, rawValue.param_count, rawValue.param_index, paramName, paramValue);
}
......
......@@ -507,6 +507,7 @@ signals:
void autoModeChanged(bool autoMode);
void parameterChanged(int uas, int component, QString parameterName, QVariant value);
void parameterChanged(int uas, int component, int parameterCount, int parameterId, QString parameterName, QVariant value);
void parameterUpdate(int uas, int component, QString parameterName, int type, QVariant value);
void patternDetected(int uasId, QString patternPath, float confidence, bool detected);
void letterDetected(int uasId, QString letter, float confidence, bool detected);
/**
......
......@@ -285,6 +285,7 @@ void UASParameterCommsMgr::requestParameterUpdate(int compId, const QString& par
{
if (mav) {
mav->requestParameter(compId, paramName);
qCDebug(UASParameterCommsMgrLog) << "Requested update for" << compId << paramName;
//TODO track these read requests with a paramName but no param ID : use index in getOnboardParamsForComponent?
//ensure we keep track of every single read request
}
......
#include "QGCPX4MulticopterConfig.h"
#include "ui_QGCPX4MulticopterConfig.h"
QGCPX4MulticopterConfig::QGCPX4MulticopterConfig(QWidget *parent) :
QWidget(parent),
ui(new Ui::QGCPX4MulticopterConfig)
{
ui->setupUi(this);
}
QGCPX4MulticopterConfig::~QGCPX4MulticopterConfig()
{
delete ui;
}
#ifndef QGCPX4MULTICOPTERCONFIG_H
#define QGCPX4MULTICOPTERCONFIG_H
#include <QWidget>
namespace Ui {
class QGCPX4MulticopterConfig;
}
class QGCPX4MulticopterConfig : public QWidget
{
Q_OBJECT
public:
explicit QGCPX4MulticopterConfig(QWidget *parent = 0);
~QGCPX4MulticopterConfig();
private:
Ui::QGCPX4MulticopterConfig *ui;
};
#endif // QGCPX4MULTICOPTERCONFIG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCPX4MulticopterConfig</class>
<widget class="QWidget" name="QGCPX4MulticopterConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
<height>449</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QSlider" name="horizontalSlider">
<property name="geometry">
<rect>
<x>130</x>
<y>150</y>
<width>341</width>
<height>22</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QSlider" name="horizontalSlider_2">
<property name="geometry">
<rect>
<x>130</x>
<y>400</y>
<width>351</width>
<height>22</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>160</y>
<width>62</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>510</x>
<y>160</y>
<width>62</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>40</x>
<y>400</y>
<width>62</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>520</x>
<y>400</y>
<width>62</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>30</x>
<y>10</y>
<width>62</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>30</x>
<y>200</y>
<width>62</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
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