From d4e6eca76c5f207fb12a6146d240911ca68e9d97 Mon Sep 17 00:00:00 2001 From: Dennis Shtatnov Date: Sun, 11 Dec 2016 10:15:48 -0500 Subject: [PATCH] Component for configuring CF2 Radio --- qgroundcontrol.pro | 4 + qgroundcontrol.qrc | 1 + .../Common/SyslinkComponent.cc | 64 ++++++++ .../Common/SyslinkComponent.h | 40 +++++ .../Common/SyslinkComponent.qml | 152 ++++++++++++++++++ .../Common/SyslinkComponentController.cc | 137 ++++++++++++++++ .../Common/SyslinkComponentController.h | 66 ++++++++ .../PX4/PX4AutoPilotPlugin.cc | 7 + src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h | 4 +- src/QGCApplication.cc | 2 + 10 files changed, 475 insertions(+), 2 deletions(-) create mode 100644 src/AutoPilotPlugins/Common/SyslinkComponent.cc create mode 100644 src/AutoPilotPlugins/Common/SyslinkComponent.h create mode 100644 src/AutoPilotPlugins/Common/SyslinkComponent.qml create mode 100644 src/AutoPilotPlugins/Common/SyslinkComponentController.cc create mode 100644 src/AutoPilotPlugins/Common/SyslinkComponentController.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 82cf18446..9b2c5cffc 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -806,6 +806,8 @@ HEADERS+= \ src/AutoPilotPlugins/Common/MixersComponent.h \ src/AutoPilotPlugins/Common/MotorComponent.h \ src/AutoPilotPlugins/Common/RadioComponentController.h \ + src/AutoPilotPlugins/Common/SyslinkComponent.h \ + src/AutoPilotPlugins/Common/SyslinkComponentController.h \ src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \ src/FirmwarePlugin/CameraMetaData.h \ src/FirmwarePlugin/FirmwarePlugin.h \ @@ -829,6 +831,8 @@ SOURCES += \ src/AutoPilotPlugins/Common/MixersComponent.cc \ src/AutoPilotPlugins/Common/MotorComponent.cc \ src/AutoPilotPlugins/Common/RadioComponentController.cc \ + src/AutoPilotPlugins/Common/SyslinkComponent.cc \ + src/AutoPilotPlugins/Common/SyslinkComponentController.cc \ src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \ src/FirmwarePlugin/CameraMetaData.cc \ src/FirmwarePlugin/FirmwarePlugin.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 13452d1fc..098ec02e2 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -24,6 +24,7 @@ src/ui/preferences/DebugWindow.qml src/AutoPilotPlugins/Common/ESP8266Component.qml src/AutoPilotPlugins/Common/ESP8266ComponentSummary.qml + src/AutoPilotPlugins/Common/SyslinkComponent.qml src/VehicleSetup/FirmwareUpgrade.qml src/FlightDisplay/FlightDisplayViewDummy.qml src/FlightDisplay/FlightDisplayViewUVC.qml diff --git a/src/AutoPilotPlugins/Common/SyslinkComponent.cc b/src/AutoPilotPlugins/Common/SyslinkComponent.cc new file mode 100644 index 000000000..ea1e28e37 --- /dev/null +++ b/src/AutoPilotPlugins/Common/SyslinkComponent.cc @@ -0,0 +1,64 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + + +#include "SyslinkComponent.h" +#include "AutoPilotPlugin.h" + +SyslinkComponent::SyslinkComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) + : VehicleComponent(vehicle, autopilot, parent) + , _name(tr("Syslink")) +{ + +} + +QString SyslinkComponent::name(void) const +{ + return _name; +} + +QString SyslinkComponent::description(void) const +{ + return tr("The Syslink Component is used to setup the radio connection on Crazyflies."); +} + +QString SyslinkComponent::iconResource(void) const +{ + return "/qmlimages/wifi.svg"; +} + +bool SyslinkComponent::requiresSetup(void) const +{ + return false; +} + +bool SyslinkComponent::setupComplete(void) const +{ + return true; +} + +QStringList SyslinkComponent::setupCompleteChangedTriggerList(void) const +{ + return QStringList(); +} + +QUrl SyslinkComponent::setupSource(void) const +{ + return QUrl::fromUserInput("qrc:/qml/SyslinkComponent.qml"); +} + +QUrl SyslinkComponent::summaryQmlSource(void) const +{ + return QUrl(); +} + +QString SyslinkComponent::prerequisiteSetup(void) const +{ + return QString(); +} diff --git a/src/AutoPilotPlugins/Common/SyslinkComponent.h b/src/AutoPilotPlugins/Common/SyslinkComponent.h new file mode 100644 index 000000000..8569b1abe --- /dev/null +++ b/src/AutoPilotPlugins/Common/SyslinkComponent.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + + +#ifndef SyslinkComponent_H +#define SyslinkComponent_H + +#include "VehicleComponent.h" + +class SyslinkComponent : public VehicleComponent +{ + Q_OBJECT +public: + SyslinkComponent (Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL); + + // Virtuals from VehicleComponent + QStringList setupCompleteChangedTriggerList() const; + + // Virtuals from VehicleComponent + QString name () const; + QString description () const; + QString iconResource () const; + bool requiresSetup () const; + bool setupComplete () const; + QUrl setupSource () const; + QUrl summaryQmlSource () const; + QString prerequisiteSetup () const; + +private: + const QString _name; + QVariantList _summaryItems; +}; + +#endif diff --git a/src/AutoPilotPlugins/Common/SyslinkComponent.qml b/src/AutoPilotPlugins/Common/SyslinkComponent.qml new file mode 100644 index 000000000..66fbb8c78 --- /dev/null +++ b/src/AutoPilotPlugins/Common/SyslinkComponent.qml @@ -0,0 +1,152 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + + +import QtQuick 2.5 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.2 + +import QGroundControl 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controllers 1.0 + +QGCView { + id: qgcView + viewPanel: panel + + QGCPalette { id: palette; colorGroupEnabled: panel.enabled } + + property real _margins: ScreenTools.defaultFontPixelHeight + property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 16 + property real _labelWidth: ScreenTools.defaultFontPixelWidth * 18 + + SyslinkComponentController { + id: controller + factPanel: panel + } + + QGCViewPanel { + id: panel + anchors.fill: parent + + Flickable { + clip: true + anchors.fill: parent + contentHeight: mainCol.height + flickableDirection: Flickable.VerticalFlick + Column { + id: mainCol + spacing: _margins + anchors.horizontalCenter: parent.horizontalCenter + Item { width: 1; height: _margins * 0.5; } + + Rectangle { + color: palette.windowShade + height: settingsRow.height + _margins * 2 + Row { + id: settingsRow + spacing: _margins * 4 + anchors.centerIn: parent + Column { + spacing: _margins * 0.5 + anchors.verticalCenter: parent.verticalCenter + Row { + QGCLabel { + text: qsTr("NRF Radio Settings") + font.family: ScreenTools.demiboldFontFamily + } + } + Row { + QGCLabel { + text: qsTr("Channel") + width: _labelWidth + anchors.baseline: channelField.baseline + } + QGCTextField { + id: channelField + width: _editFieldWidth + text: controller.radioChannel + validator: IntValidator {bottom: 0; top: 125;} + inputMethodHints: Qt.ImhDigitsOnly + onEditingFinished: { + controller.radioChannel = text + } + } + } + Row { + anchors.right: parent.right + QGCLabel { + wrapMode: Text.WordWrap + text: qsTr("Channel can be between 0 and 125") + } + + } + Row { + QGCLabel { + text: qsTr("Address") + width: _labelWidth + anchors.baseline: addressField.baseline + } + QGCTextField { + id: addressField + width: _editFieldWidth + text: controller.radioAddress + maximumLength: 10 + validator: RegExpValidator { regExp: /^[0-9A-Fa-f]*$/ } + onEditingFinished: { + controller.radioAddress = text + } + } + } + Row { + anchors.right: parent.right + QGCLabel { + wrapMode: Text.WordWrap + text: qsTr("Address in hex. Default E7E7E7E7E7") + } + + } + Row { + QGCLabel { + text: qsTr("Data Rate") + width: _labelWidth + anchors.baseline: rateField.baseline + } + QGCComboBox { + id: rateField + width: _editFieldWidth + model: controller.radioRates + currentIndex: controller.radioRate + onActivated: { + controller.radioRate = index + } + } + } + Row { + spacing: _margins + anchors.horizontalCenter: parent.horizontalCenter + QGCButton { + text: qsTr("Restore Defaults") + width: _editFieldWidth + onClicked: { + controller.resetDefaults() + } + } + } + } + } + } + + } + } + } +} diff --git a/src/AutoPilotPlugins/Common/SyslinkComponentController.cc b/src/AutoPilotPlugins/Common/SyslinkComponentController.cc new file mode 100644 index 000000000..63145c074 --- /dev/null +++ b/src/AutoPilotPlugins/Common/SyslinkComponentController.cc @@ -0,0 +1,137 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "SyslinkComponentController.h" +#include "QGCApplication.h" +#include "UAS.h" +#include "ParameterManager.h" + +#include +#include + +QGC_LOGGING_CATEGORY(SyslinkComponentControllerLog, "SyslinkComponentControllerLog") + +//----------------------------------------------------------------------------- +SyslinkComponentController::SyslinkComponentController() +{ + _dataRates.append("750Kb/s"); + _dataRates.append("1Mb/s"); + _dataRates.append("2Mb/s"); + + Fact* chan = getParameterFact(_vehicle->id(), "SLNK_RADIO_CHAN"); + connect(chan, &Fact::valueChanged, this, &SyslinkComponentController::_channelChanged); + Fact* rate = getParameterFact(_vehicle->id(), "SLNK_RADIO_RATE"); + connect(rate, &Fact::valueChanged, this, &SyslinkComponentController::_rateChanged); + Fact* addr1 = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR1"); + connect(addr1, &Fact::valueChanged, this, &SyslinkComponentController::_addressChanged); + Fact* addr2 = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR2"); + connect(addr2, &Fact::valueChanged, this, &SyslinkComponentController::_addressChanged); +} + +//----------------------------------------------------------------------------- +SyslinkComponentController::~SyslinkComponentController() +{ + +} + +//----------------------------------------------------------------------------- +int +SyslinkComponentController::radioChannel() +{ + return getParameterFact(_vehicle->id(), "SLNK_RADIO_CHAN")->rawValue().toUInt(); +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::setRadioChannel(int num) +{ + Fact* f = getParameterFact(_vehicle->id(), "SLNK_RADIO_CHAN"); + f->setRawValue(QVariant(num)); +} + +//----------------------------------------------------------------------------- +QString +SyslinkComponentController::radioAddress() +{ + uint32_t val_uh = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR1")->rawValue().toUInt(); + uint32_t val_lh = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR2")->rawValue().toUInt(); + uint64_t val = (((uint64_t) val_uh) << 32) | ((uint64_t) val_lh); + + return QString().number(val, 16); +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::setRadioAddress(QString str) +{ + Fact *uh = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR1"); + Fact *lh = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR2"); + + uint64_t val = str.toULongLong(0, 16); + + uint32_t val_uh = val >> 32; + uint32_t val_lh = val & 0xFFFFFFFF; + + uh->setRawValue(QVariant(val_uh)); + lh->setRawValue(QVariant(val_lh)); +} + +//----------------------------------------------------------------------------- +int +SyslinkComponentController::radioRate() +{ + return getParameterFact(_vehicle->id(), "SLNK_RADIO_RATE")->rawValue().toInt(); +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::setRadioRate(int idx) +{ + if(idx >= 0 && idx <= 2 && idx != radioRate()) { + Fact* r = getParameterFact(_vehicle->id(), "SLNK_RADIO_RATE"); + r->setRawValue(idx); + } +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::resetDefaults() +{ + Fact* chan = getParameterFact(_vehicle->id(), "SLNK_RADIO_CHAN"); + Fact* rate = getParameterFact(_vehicle->id(), "SLNK_RADIO_RATE"); + Fact* addr1 = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR1"); + Fact* addr2 = getParameterFact(_vehicle->id(), "SLNK_RADIO_ADDR2"); + + chan->setRawValue(chan->rawDefaultValue()); + rate->setRawValue(rate->rawDefaultValue()); + addr1->setRawValue(addr1->rawDefaultValue()); + addr2->setRawValue(addr2->rawDefaultValue()); +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::_channelChanged(QVariant) +{ + emit radioChannelChanged(); +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::_addressChanged(QVariant) +{ + emit radioAddressChanged(); +} + +//----------------------------------------------------------------------------- +void +SyslinkComponentController::_rateChanged(QVariant) +{ + emit radioRateChanged(); +} + diff --git a/src/AutoPilotPlugins/Common/SyslinkComponentController.h b/src/AutoPilotPlugins/Common/SyslinkComponentController.h new file mode 100644 index 000000000..b8180a0b7 --- /dev/null +++ b/src/AutoPilotPlugins/Common/SyslinkComponentController.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * + * (c) 2009-2016 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#ifndef SyslinkComponentController_H +#define SyslinkComponentController_H + +#include "FactPanelController.h" +#include "UASInterface.h" +#include "QGCLoggingCategory.h" +#include "AutoPilotPlugin.h" + +Q_DECLARE_LOGGING_CATEGORY(SyslinkComponentControllerLog) + +namespace Ui { + class SyslinkComponentController; +} + +class SyslinkComponentController : public FactPanelController +{ + Q_OBJECT + +public: + SyslinkComponentController (); + ~SyslinkComponentController (); + + Q_PROPERTY(int radioChannel READ radioChannel WRITE setRadioChannel NOTIFY radioChannelChanged) + Q_PROPERTY(QString radioAddress READ radioAddress WRITE setRadioAddress NOTIFY radioAddressChanged) + Q_PROPERTY(int radioRate READ radioRate WRITE setRadioRate NOTIFY radioRateChanged) + Q_PROPERTY(QStringList radioRates READ radioRates CONSTANT) + Q_PROPERTY(Vehicle* vehicle READ vehicle CONSTANT) + + Q_INVOKABLE void resetDefaults(); + + int radioChannel (); + QString radioAddress (); + int radioRate (); + QStringList radioRates () { return _dataRates; } + Vehicle* vehicle () { return _vehicle; } + + void setRadioChannel (int num); + void setRadioAddress (QString str); + void setRadioRate (int idx); + + +signals: + void radioChannelChanged (); + void radioAddressChanged (); + void radioRateChanged (); + +private slots: + void _channelChanged (QVariant value); + void _addressChanged (QVariant value); + void _rateChanged (QVariant value); + +private: + QStringList _dataRates; + +}; + +#endif // SyslinkComponentController_H diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc index 7fef798bc..1b1dd0a8f 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc @@ -40,6 +40,7 @@ PX4AutoPilotPlugin::PX4AutoPilotPlugin(Vehicle* vehicle, QObject* parent) , _motorComponent(NULL) , _tuningComponent(NULL) , _mixersComponent(NULL) + , _syslinkComponent(NULL) { if (!vehicle) { qWarning() << "Internal error"; @@ -122,6 +123,12 @@ const QVariantList& PX4AutoPilotPlugin::vehicleComponents(void) } else { qWarning() << "Call to vehicleCompenents prior to parametersReady"; } + + if(_vehicle->parameterManager()->parameterExists(_vehicle->id(), "SLNK_RADIO_CHAN")) { + _syslinkComponent = new SyslinkComponent(_vehicle, this); + _syslinkComponent->setupTriggerSignals(); + _components.append(QVariant::fromValue((VehicleComponent*)_syslinkComponent)); + } } else { qWarning() << "Internal error"; } diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h index ee85d9775..f886176e6 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h @@ -24,6 +24,7 @@ #include "MotorComponent.h" #include "PX4TuningComponent.h" #include "MixersComponent.h" +#include "SyslinkComponent.h" #include "Vehicle.h" #include @@ -44,7 +45,6 @@ public: const QVariantList& vehicleComponents(void) override; void parametersReadyPreChecks(void) override; QString prerequisiteSetup(VehicleComponent* component) const override; - protected: bool _incorrectParameterVersion; ///< true: parameter version incorrect, setup not allowed PX4AirframeLoader* _airframeFacts; @@ -59,7 +59,7 @@ protected: MotorComponent* _motorComponent; PX4TuningComponent* _tuningComponent; MixersComponent* _mixersComponent; - + SyslinkComponent* _syslinkComponent; private: QVariantList _components; }; diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 7bbdfd009..d5a66d367 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -51,6 +51,7 @@ #include "ScreenToolsController.h" #include "QFileDialogController.h" #include "RCChannelMonitorController.h" +#include "SyslinkComponentController.h" #include "AutoPilotPlugin.h" #include "VehicleComponent.h" #include "FirmwarePluginManager.h" @@ -390,6 +391,7 @@ void QGCApplication::_initCommon(void) qmlRegisterType ("QGroundControl.Controllers", 1, 0, "RCChannelMonitorController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "JoystickConfigController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "LogDownloadController"); + qmlRegisterType ("QGroundControl.Controllers", 1, 0, "SyslinkComponentController"); #ifndef __mobile__ qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ViewWidgetController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "CustomCommandWidgetController"); -- 2.22.0