diff --git a/QGCCommon.pri b/QGCCommon.pri
index 9c725866f58567bab31f4db2ed34fb9d78b664c0..5f162ab490d4c70cdaad63d34a13de9073c994bd 100644
--- a/QGCCommon.pri
+++ b/QGCCommon.pri
@@ -22,6 +22,7 @@ linux {
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
linux-clang {
message("Linux clang")
QMAKE_CXXFLAGS += -Qunused-arguments -fcolor-diagnostics
@@ -31,12 +32,14 @@ linux {
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS __rasp_pi2__
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
} else : android-g++ | android-clang {
CONFIG += AndroidBuild MobileBuild
DEFINES += __android__
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_BLUETOOTH
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
target.path = $$DESTDIR
equals(ANDROID_TARGET_ARCH, x86) {
CONFIG += Androidx86Build
@@ -54,6 +57,7 @@ linux {
CONFIG += WindowsBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
} else {
error("Unsupported Windows toolchain, only Visual Studio 2015 is supported")
}
@@ -64,6 +68,7 @@ linux {
CONFIG += x86_64
CONFIG -= x86
DEFINES += QGC_GST_TAISYNC_ENABLED
+ DEFINES += QGC_GST_MICROHARD_ENABLED
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index c0248732bed8dfe9a0102aa45fb867f21aa7f0fc..79b2919a426a33a149905a8258439b6f0361aa6f 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -1148,6 +1148,23 @@ contains (DEFINES, QGC_GST_TAISYNC_ENABLED) {
}
}
+#-------------------------------------------------------------------------------------
+# Microhard
+contains (DEFINES, QGC_GST_MICROHARD_ENABLED) {
+ INCLUDEPATH += \
+ src/Microhard
+
+ HEADERS += \
+ src/Microhard/MicrohardManager.h \
+ src/Microhard/MicrohardHandler.h \
+ src/Microhard/MicrohardSettings.h \
+
+ SOURCES += \
+ src/Microhard/MicrohardManager.cc \
+ src/Microhard/MicrohardHandler.cc \
+ src/Microhard/MicrohardSettings.cc \
+}
+
#-------------------------------------------------------------------------------------
# AirMap
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index b811f360d4917c9f150c198e73a2c3c590b6ad3a..c414f09b7299a3c40e5a25fb95d7fc946ab6bcf5 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -201,6 +201,7 @@
src/AutoPilotPlugins/Common/SyslinkComponent.qml
src/ui/preferences/TcpSettings.qml
src/Taisync/TaisyncSettings.qml
+ src/Microhard/MicrohardSettings.qml
src/test.qml
src/ui/preferences/UdpSettings.qml
src/FlightMap/Widgets/ValuePageWidget.qml
diff --git a/src/Microhard/MicrohardHandler.cc b/src/Microhard/MicrohardHandler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..eed5b6db843e2088e21fd78084c71790323e0833
--- /dev/null
+++ b/src/Microhard/MicrohardHandler.cc
@@ -0,0 +1,107 @@
+/****************************************************************************
+ *
+ * (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 "MicrohardHandler.h"
+#include "SettingsManager.h"
+#include "QGCApplication.h"
+#include "VideoManager.h"
+
+
+QGC_LOGGING_CATEGORY(MicrohardLog, "MicrohardLog")
+QGC_LOGGING_CATEGORY(MicrohardVerbose, "MicrohardVerbose")
+
+//-----------------------------------------------------------------------------
+MicrohardHandler::MicrohardHandler(QObject* parent)
+ : QObject (parent)
+{
+}
+
+//-----------------------------------------------------------------------------
+MicrohardHandler::~MicrohardHandler()
+{
+ close();
+}
+
+//-----------------------------------------------------------------------------
+bool MicrohardHandler::close()
+{
+ bool res = (_tcpSocket || _tcpServer);
+ if(_tcpSocket) {
+ qCDebug(MicrohardLog) << "Close Microhard TCP socket on port" << _tcpSocket->localPort();
+ _tcpSocket->close();
+ _tcpSocket->deleteLater();
+ _tcpSocket = nullptr;
+ }
+ if(_tcpServer) {
+ qCDebug(MicrohardLog) << "Close Microhard TCP server on port" << _tcpServer->serverPort();;
+ _tcpServer->close();
+ _tcpServer->deleteLater();
+ _tcpServer = nullptr;
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardHandler::_start(uint16_t port, QHostAddress addr)
+{
+ close();
+ _serverMode = addr == QHostAddress::AnyIPv4;
+ if(_serverMode) {
+ if(!_tcpServer) {
+ qCDebug(MicrohardLog) << "Listen for Microhard TCP on port" << port;
+ _tcpServer = new QTcpServer(this);
+ QObject::connect(_tcpServer, &QTcpServer::newConnection, this, &MicrohardHandler::_newConnection);
+ _tcpServer->listen(QHostAddress::AnyIPv4, port);
+ }
+ } else {
+ _tcpSocket = new QTcpSocket();
+ QObject::connect(_tcpSocket, &QIODevice::readyRead, this, &MicrohardHandler::_readBytes);
+ qCDebug(MicrohardLog) << "Connecting to" << addr;
+ _tcpSocket->connectToHost(addr, port);
+ if (!_tcpSocket->waitForConnected(1000)) {
+ close();
+ return false;
+ }
+ emit connected();
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardHandler::_newConnection()
+{
+ qCDebug(MicrohardLog) << "New Microhard TCP Connection on port" << _tcpServer->serverPort();
+ if(_tcpSocket) {
+ _tcpSocket->close();
+ _tcpSocket->deleteLater();
+ }
+ _tcpSocket = _tcpServer->nextPendingConnection();
+ if(_tcpSocket) {
+ QObject::connect(_tcpSocket, &QIODevice::readyRead, this, &MicrohardHandler::_readBytes);
+ QObject::connect(_tcpSocket, &QAbstractSocket::disconnected, this, &MicrohardHandler::_socketDisconnected);
+ emit connected();
+ } else {
+ qCWarning(MicrohardLog) << "New Microhard TCP Connection provided no socket";
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardHandler::_socketDisconnected()
+{
+ qCDebug(MicrohardLog) << "Microhard TCP Connection Closed on port" << _tcpSocket->localPort();
+ if(_tcpSocket) {
+ _tcpSocket->close();
+ _tcpSocket->deleteLater();
+ _tcpSocket = nullptr;
+ }
+ emit disconnected();
+}
diff --git a/src/Microhard/MicrohardHandler.h b/src/Microhard/MicrohardHandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b2217eb8453f7fff6d35416b5a9d9b4d0486840
--- /dev/null
+++ b/src/Microhard/MicrohardHandler.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ *
+ * (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.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "QGCLoggingCategory.h"
+
+#include
+#include
+
+#define MICROHARD_SETTINGS_PORT 23
+
+Q_DECLARE_LOGGING_CATEGORY(MicrohardLog)
+Q_DECLARE_LOGGING_CATEGORY(MicrohardVerbose)
+
+class MicrohardHandler : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit MicrohardHandler (QObject* parent = nullptr);
+ ~MicrohardHandler ();
+ virtual bool start () = 0;
+ virtual bool close ();
+ virtual bool isServerRunning () { return (_serverMode && _tcpServer); }
+
+protected:
+ virtual bool _start (uint16_t port, QHostAddress addr = QHostAddress::AnyIPv4);
+
+protected slots:
+ virtual void _newConnection ();
+ virtual void _socketDisconnected ();
+ virtual void _readBytes () = 0;
+
+signals:
+ void connected ();
+ void disconnected ();
+
+protected:
+ bool _serverMode = true;
+ QTcpServer* _tcpServer = nullptr;
+ QTcpSocket* _tcpSocket = nullptr;
+};
diff --git a/src/Microhard/MicrohardManager.cc b/src/Microhard/MicrohardManager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..28e6d8ab5e59b05b0a8ccc85cc3a36b846697acc
--- /dev/null
+++ b/src/Microhard/MicrohardManager.cc
@@ -0,0 +1,531 @@
+/****************************************************************************
+ *
+ * (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 "MicrohardManager.h"
+#include "MicrohardHandler.h"
+#include "SettingsManager.h"
+#include "QGCApplication.h"
+#include "QGCCorePlugin.h"
+#include "VideoManager.h"
+
+#include
+
+static const char *kMICROHARD_GROUP = "Microhard";
+static const char *kRADIO_MODE = "RadioMode";
+static const char *kRADIO_CHANNEL = "RadioChannel";
+static const char *kVIDEO_OUTPUT = "VideoOutput";
+static const char *kVIDEO_MODE = "VideoMode";
+static const char *kVIDEO_RATE = "VideoRate";
+static const char *kLOCAL_IP = "LocalIP";
+static const char *kREMOTE_IP = "RemoteIP";
+static const char *kNET_MASK = "NetMask";
+static const char *kRTSP_URI = "RTSPURI";
+static const char *kRTSP_ACCOUNT = "RTSPAccount";
+static const char *kRTSP_PASSWORD = "RTSPPassword";
+
+//-----------------------------------------------------------------------------
+MicrohardManager::MicrohardManager(QGCApplication* app, QGCToolbox* toolbox)
+ : QGCTool(app, toolbox)
+{
+ connect(&_workTimer, &QTimer::timeout, this, &MicrohardManager::_checkMicrohard);
+ _workTimer.setSingleShot(true);
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ _localIPAddr = settings.value(kLOCAL_IP, QString("192.168.199.33")).toString();
+ _remoteIPAddr = settings.value(kREMOTE_IP, QString("192.168.199.16")).toString();
+ _netMask = settings.value(kNET_MASK, QString("255.255.255.0")).toString();
+ _rtspURI = settings.value(kRTSP_URI, QString("rtsp://192.168.0.2")).toString();
+ _rtspAccount = settings.value(kRTSP_ACCOUNT, QString("admin")).toString();
+ _rtspPassword = settings.value(kRTSP_PASSWORD, QString("12345678")).toString();
+ settings.endGroup();
+}
+
+//-----------------------------------------------------------------------------
+MicrohardManager::~MicrohardManager()
+{
+ _close();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_close()
+{
+ if(_mhSettings) {
+ _mhSettings->close();
+ _mhSettings->deleteLater();
+ _mhSettings = nullptr;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_reset()
+{
+ _close();
+ _isConnected = false;
+ emit connectedChanged();
+ _linkConnected = false;
+ emit linkConnectedChanged();
+ if(!_appSettings) {
+ _appSettings = _toolbox->settingsManager()->appSettings();
+ connect(_appSettings->enableMicrohard(), &Fact::rawValueChanged, this, &MicrohardManager::_setEnabled);
+ connect(_appSettings->enableMicrohardVideo(), &Fact::rawValueChanged, this, &MicrohardManager::_setVideoEnabled);
+ }
+ _setEnabled();
+}
+
+//-----------------------------------------------------------------------------
+FactMetaData*
+MicrohardManager::_createMetadata(const char* name, QStringList enums)
+{
+ FactMetaData* metaData = new FactMetaData(FactMetaData::valueTypeUint32, name, this);
+ QQmlEngine::setObjectOwnership(metaData, QQmlEngine::CppOwnership);
+ metaData->setShortDescription(name);
+ metaData->setLongDescription(name);
+ metaData->setRawDefaultValue(QVariant(0));
+ metaData->setHasControl(true);
+ metaData->setReadOnly(false);
+ for(int i = 0; i < enums.size(); i++) {
+ metaData->addEnumInfo(enums[i], QVariant(i));
+ }
+ metaData->setRawMin(0);
+ metaData->setRawMin(enums.size() - 1);
+ return metaData;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::setToolbox(QGCToolbox* toolbox)
+{
+ QGCTool::setToolbox(toolbox);
+ {
+ //-- Radio Mode
+ QStringList enums;
+ enums.append(tr("Auto"));
+ enums.append(tr("Manual"));
+ FactMetaData* metaData = _createMetadata(kRADIO_MODE, enums);
+ _radioMode = new Fact(kMICROHARD_GROUP, metaData, this);
+ QQmlEngine::setObjectOwnership(_radioMode, QQmlEngine::CppOwnership);
+ _radioModeList.append("auto");
+ _radioModeList.append("manual");
+ connect(_radioMode, &Fact::_containerRawValueChanged, this, &MicrohardManager::_radioSettingsChanged);
+ }
+ {
+ //-- Radio Channel
+ QStringList enums;
+ for(int i = 0; i < 14; i++) {
+ enums.append(QString("ch%1").arg(i));
+ }
+ FactMetaData* metaData = _createMetadata(kRADIO_CHANNEL, enums);
+ _radioChannel = new Fact(kMICROHARD_GROUP, metaData, this);
+ QQmlEngine::setObjectOwnership(_radioChannel, QQmlEngine::CppOwnership);
+ connect(_radioChannel, &Fact::_containerRawValueChanged, this, &MicrohardManager::_radioSettingsChanged);
+ }
+ {
+ //-- Video Output
+ QStringList enums;
+ enums.append(tr("Stream"));
+ enums.append(tr("HDMI Port"));
+ FactMetaData* metaData = _createMetadata(kVIDEO_OUTPUT, enums);
+ _videoOutput = new Fact(kMICROHARD_GROUP, metaData, this);
+ QQmlEngine::setObjectOwnership(_videoOutput, QQmlEngine::CppOwnership);
+ _videoOutputList.append("phone");
+ _videoOutputList.append("hdmi");
+ connect(_videoOutput, &Fact::_containerRawValueChanged, this, &MicrohardManager::_videoSettingsChanged);
+ }
+ {
+ //-- Video Mode
+ QStringList enums;
+ enums.append("H264");
+ enums.append("H265");
+ FactMetaData* metaData = _createMetadata(kVIDEO_MODE, enums);
+ _videoMode = new Fact(kMICROHARD_GROUP, metaData, this);
+ QQmlEngine::setObjectOwnership(_videoMode, QQmlEngine::CppOwnership);
+ connect(_videoMode, &Fact::_containerRawValueChanged, this, &MicrohardManager::_videoSettingsChanged);
+ }
+ {
+ //-- Video Rate
+ QStringList enums;
+ enums.append(tr("Low"));
+ enums.append(tr("Medium"));
+ enums.append(tr("High"));
+ FactMetaData* metaData = _createMetadata(kVIDEO_RATE, enums);
+ _videoRate = new Fact(kMICROHARD_GROUP, metaData, this);
+ QQmlEngine::setObjectOwnership(_videoRate, QQmlEngine::CppOwnership);
+ _videoRateList.append("low");
+ _videoRateList.append("middle");
+ _videoRateList.append("high");
+ connect(_videoRate, &Fact::_containerRawValueChanged, this, &MicrohardManager::_videoSettingsChanged);
+ }
+ //-- Start it all
+ _reset();
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardManager::setRTSPSettings(QString uri, QString account, QString password)
+{
+ if(_mhSettings && _isConnected) {
+ if(_mhSettings->setRTSPSettings(uri, account, password)) {
+ _rtspURI = uri;
+ _rtspAccount = account;
+ _rtspPassword = password;
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ settings.setValue(kRTSP_URI, _rtspURI);
+ settings.setValue(kRTSP_ACCOUNT, _rtspAccount);
+ settings.setValue(kRTSP_PASSWORD, _rtspPassword);
+ settings.endGroup();
+ emit rtspURIChanged();
+ emit rtspAccountChanged();
+ emit rtspPasswordChanged();
+ _needReboot = true;
+ emit needRebootChanged();
+ return true;
+ }
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardManager::setIPSettings(QString localIP_, QString remoteIP_, QString netMask_)
+{
+ bool res = false;
+ if(_localIPAddr != localIP_ || _remoteIPAddr != remoteIP_ || _netMask != netMask_) {
+ //-- If we are connected to the Microhard
+ if(_isConnected) {
+ if(_mhSettings) {
+ //-- Change IP settings
+ res = _mhSettings->setIPSettings(localIP_, remoteIP_, netMask_);
+ if(res) {
+ _needReboot = true;
+ emit needRebootChanged();
+ }
+ }
+ } else {
+ //-- We're not connected. Record the change and restart.
+ _localIPAddr = localIP_;
+ _remoteIPAddr = remoteIP_;
+ _netMask = netMask_;
+ _reset();
+ res = true;
+ }
+ if(res) {
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ settings.setValue(kLOCAL_IP, localIP_);
+ settings.setValue(kREMOTE_IP, remoteIP_);
+ settings.setValue(kNET_MASK, netMask_);
+ settings.endGroup();
+ }
+ } else {
+ //-- Nothing to change
+ res = true;
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_radioSettingsChanged(QVariant)
+{
+ if(_mhSettings && _isConnected) {
+ _workTimer.stop();
+ _mhSettings->setRadioSettings(
+ _radioModeList[_radioMode->rawValue().toInt()],
+ _radioChannel->enumStringValue());
+ _reqMask |= REQ_RADIO_SETTINGS;
+ _workTimer.start(3000);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_videoSettingsChanged(QVariant)
+{
+ if(_mhSettings && _isConnected) {
+ _workTimer.stop();
+ _mhSettings->setVideoSettings(
+ _videoOutputList[_videoOutput->rawValue().toInt()],
+ _videoMode->enumStringValue(),
+ _videoRateList[_videoRate->rawValue().toInt()]);
+ _reqMask |= REQ_VIDEO_SETTINGS;
+ _workTimer.start(500);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_setEnabled()
+{
+ bool enable = _appSettings->enableMicrohard()->rawValue().toBool();
+ if(enable) {
+ if(!_mhSettings) {
+ _mhSettings = new MicrohardSettings(this);
+ connect(_mhSettings, &MicrohardSettings::updateSettings, this, &MicrohardManager::_updateSettings);
+ connect(_mhSettings, &MicrohardSettings::connected, this, &MicrohardManager::_connected);
+ connect(_mhSettings, &MicrohardSettings::disconnected, this, &MicrohardManager::_disconnected);
+ }
+ _reqMask = static_cast(REQ_ALL);
+ _workTimer.start(1000);
+ } else {
+ //-- Stop everything
+ _workTimer.stop();
+ _close();
+ }
+ _enabled = enable;
+ //-- Now handle video support
+ _setVideoEnabled();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_restoreVideoSettings(Fact* setting)
+{
+ SettingsFact* pFact = dynamic_cast(setting);
+ if(pFact) {
+ pFact->setVisible(qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(VideoSettings::settingsGroup, *setting->metaData()));
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_setVideoEnabled()
+{
+ //-- Check both if video is enabled and Microhard support itself is enabled as well.
+ bool enable = _appSettings->enableMicrohardVideo()->rawValue().toBool() && _appSettings->enableMicrohard()->rawValue().toBool();
+ if(enable) {
+ //-- Set it up the way we need it do be.
+ VideoSettings* pVSettings = qgcApp()->toolbox()->settingsManager()->videoSettings();
+ pVSettings->setVisible(false);
+ pVSettings->udpPort()->setRawValue(5600);
+ //-- TODO: this AR must come from somewhere
+ pVSettings->aspectRatio()->setRawValue(1024.0 / 768.0);
+ pVSettings->videoSource()->setRawValue(QString(VideoSettings::videoSourceUDP));
+ } else {
+ //-- Restore video settings.
+ VideoSettings* pVSettings = qgcApp()->toolbox()->settingsManager()->videoSettings();
+ _restoreVideoSettings(pVSettings->videoSource());
+ _restoreVideoSettings(pVSettings->aspectRatio());
+ _restoreVideoSettings(pVSettings->udpPort());
+ pVSettings->setVisible(true);
+ }
+ _enableVideo = enable;
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_connected()
+{
+ qCDebug(MicrohardLog) << "Microhard Settings Connected";
+ _isConnected = true;
+ emit connectedChanged();
+ _needReboot = false;
+ emit needRebootChanged();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_disconnected()
+{
+ qCDebug(MicrohardLog) << "Microhard Settings Disconnected";
+ _isConnected = false;
+ emit connectedChanged();
+ _needReboot = false;
+ emit needRebootChanged();
+ _linkConnected = false;
+ emit linkConnectedChanged();
+ _reset();
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_checkMicrohard()
+{
+ if(_enabled) {
+ if(!_isConnected) {
+ if(_mhSettings) {
+ if(!_mhSettings->isServerRunning()) {
+ _mhSettings->start();
+ }
+ }
+ } else {
+ //qCDebug(MicrohardVerbose) << bin << _reqMask;
+ while(true) {
+ if (_reqMask & REQ_LINK_STATUS) {
+ _mhSettings->requestLinkStatus();
+ break;
+ }
+ if (_reqMask & REQ_DEV_INFO) {
+ _mhSettings->requestDevInfo();
+ break;
+ }
+ if (_reqMask & REQ_FREQ_SCAN) {
+ _reqMask &= ~static_cast(REQ_FREQ_SCAN);
+ _mhSettings->requestFreqScan();
+ break;
+ }
+ if (_reqMask & REQ_VIDEO_SETTINGS) {
+ _mhSettings->requestVideoSettings();
+ break;
+ }
+ if (_reqMask & REQ_RADIO_SETTINGS) {
+ _mhSettings->requestRadioSettings();
+ break;
+ }
+ if (_reqMask & REQ_RTSP_SETTINGS) {
+ _reqMask &= ~static_cast(REQ_RTSP_SETTINGS);
+ _mhSettings->requestRTSPURISettings();
+ break;
+ }
+ if (_reqMask & REQ_IP_SETTINGS) {
+ _reqMask &= ~static_cast(REQ_IP_SETTINGS);
+ _mhSettings->requestIPSettings();
+ break;
+ }
+ //-- Check link status
+ if(_timeoutTimer.elapsed() > 3000) {
+ //-- Give up and restart
+ _disconnected();
+ break;
+ }
+ //-- If it's been too long since we last heard, ping it.
+ if(_timeoutTimer.elapsed() > 1000) {
+ _mhSettings->requestLinkStatus();
+ break;
+ }
+ break;
+ }
+ }
+ _workTimer.start(_isConnected ? 500 : 5000);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardManager::_updateSettings(QByteArray jSonData)
+{
+ _timeoutTimer.start();
+ qCDebug(MicrohardVerbose) << jSonData;
+ QJsonParseError jsonParseError;
+ QJsonDocument doc = QJsonDocument::fromJson(jSonData, &jsonParseError);
+ if (jsonParseError.error != QJsonParseError::NoError) {
+ qWarning() << "Unable to parse Microhard response:" << jsonParseError.errorString() << jsonParseError.offset;
+ return;
+ }
+ QJsonObject jObj = doc.object();
+ //-- Link Status?
+ if(jSonData.contains("\"flight\":")) {
+ _reqMask &= ~static_cast(REQ_LINK_STATUS);
+ bool tlinkConnected = jObj["flight"].toString("") == "online";
+ if(tlinkConnected != _linkConnected) {
+ _linkConnected = tlinkConnected;
+ emit linkConnectedChanged();
+ }
+ QString tlinkVidFormat = jObj["videoformat"].toString(_linkVidFormat);
+ int tdownlinkRSSI = jObj["radiorssi"].toInt(_downlinkRSSI);
+ int tuplinkRSSI = jObj["hdrssi"].toInt(_uplinkRSSI);
+ if(_linkVidFormat != tlinkVidFormat || _downlinkRSSI != tdownlinkRSSI || _uplinkRSSI != tuplinkRSSI) {
+ _linkVidFormat = tlinkVidFormat;
+ _downlinkRSSI = tdownlinkRSSI;
+ _uplinkRSSI = tuplinkRSSI;
+ emit linkChanged();
+ }
+ //-- Device Info?
+ } else if(jSonData.contains("\"firmwareversion\":")) {
+ _reqMask &= ~static_cast(REQ_DEV_INFO);
+ QString tfwVersion = jObj["firmwareversion"].toString(_fwVersion);
+ QString tserialNumber = jObj["sn"].toString(_serialNumber);
+ if(tfwVersion != _fwVersion || tserialNumber != _serialNumber) {
+ _fwVersion = tfwVersion;
+ _serialNumber = tserialNumber;
+ emit infoChanged();
+ }
+ //-- Radio Settings?
+ } else if(jSonData.contains("\"freq\":")) {
+ _reqMask &= ~static_cast(REQ_RADIO_SETTINGS);
+ int idx = _radioModeList.indexOf(jObj["mode"].toString(_radioMode->enumStringValue()));
+ if(idx >= 0) _radioMode->_containerSetRawValue(idx);
+ idx = _radioChannel->valueIndex(jObj["freq"].toString(_radioChannel->enumStringValue()));
+ if(idx < 0) idx = 0;
+ _radioChannel->_containerSetRawValue(idx);
+ //-- Video Settings?
+ } else if(jSonData.contains("\"maxbitrate\":")) {
+ _reqMask &= ~static_cast(REQ_VIDEO_SETTINGS);
+ int idx;
+ idx = _videoMode->valueIndex(jObj["mode"].toString(_videoMode->enumStringValue()));
+ if(idx < 0) idx = 0;
+ _videoMode->_containerSetRawValue(idx);
+ idx = _videoRateList.indexOf(jObj["maxbitrate"].toString(_videoMode->enumStringValue()));
+ if(idx >= 0) _videoRate->_containerSetRawValue(idx);
+ idx = _videoOutputList.indexOf(jObj["decode"].toString(_videoOutput->enumStringValue()));
+ if(idx >= 0) _videoOutput->_containerSetRawValue(idx);
+ //-- IP Address Settings?
+ } else if(jSonData.contains("\"usbEthIp\":")) {
+ QString value;
+ bool changed = false;
+ value = jObj["ipaddr"].toString(_localIPAddr);
+ if(value != _localIPAddr) {
+ _localIPAddr = value;
+ changed = true;
+ emit localIPAddrChanged();
+ }
+ value = jObj["netmask"].toString(_netMask);
+ if(value != _netMask) {
+ _netMask = value;
+ changed = true;
+ emit netMaskChanged();
+ }
+ value = jObj["usbEthIp"].toString(_remoteIPAddr);
+ if(value != _remoteIPAddr) {
+ _remoteIPAddr = value;
+ changed = true;
+ emit remoteIPAddrChanged();
+ }
+ if(changed) {
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ settings.setValue(kLOCAL_IP, _localIPAddr);
+ settings.setValue(kREMOTE_IP, _remoteIPAddr);
+ settings.setValue(kNET_MASK, _netMask);
+ settings.endGroup();
+ }
+ //-- RTSP URI Settings?
+ } else if(jSonData.contains("\"rtspURI\":")) {
+ QString value;
+ bool changed = false;
+ value = jObj["rtspURI"].toString(_rtspURI);
+ if(value != _rtspURI) {
+ _rtspURI = value;
+ changed = true;
+ emit rtspURIChanged();
+ }
+ value = jObj["account"].toString(_rtspAccount);
+ if(value != _rtspAccount) {
+ _rtspAccount = value;
+ changed = true;
+ emit rtspAccountChanged();
+ }
+ value = jObj["passwd"].toString(_rtspPassword);
+ if(value != _rtspPassword) {
+ _rtspPassword = value;
+ changed = true;
+ emit rtspPasswordChanged();
+ }
+ if(changed) {
+ QSettings settings;
+ settings.beginGroup(kMICROHARD_GROUP);
+ settings.setValue(kRTSP_URI, _rtspURI);
+ settings.setValue(kRTSP_ACCOUNT, _rtspAccount);
+ settings.setValue(kRTSP_PASSWORD, _rtspPassword);
+ settings.endGroup();
+ }
+ }
+}
diff --git a/src/Microhard/MicrohardManager.h b/src/Microhard/MicrohardManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..17e19f5dfb710e678e03923ac9c474b78318daf1
--- /dev/null
+++ b/src/Microhard/MicrohardManager.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+ *
+ * (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.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "QGCToolbox.h"
+#include "QGCLoggingCategory.h"
+#include "MicrohardSettings.h"
+#include "Fact.h"
+
+#include
+#include
+
+class AppSettings;
+class QGCApplication;
+
+//-----------------------------------------------------------------------------
+class MicrohardManager : public QGCTool
+{
+ Q_OBJECT
+public:
+
+ Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
+ Q_PROPERTY(bool linkConnected READ linkConnected NOTIFY linkConnectedChanged)
+ Q_PROPERTY(bool needReboot READ needReboot NOTIFY needRebootChanged)
+ Q_PROPERTY(QString linkVidFormat READ linkVidFormat NOTIFY linkChanged)
+ Q_PROPERTY(int uplinkRSSI READ uplinkRSSI NOTIFY linkChanged)
+ Q_PROPERTY(int downlinkRSSI READ downlinkRSSI NOTIFY linkChanged)
+ Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY infoChanged)
+ Q_PROPERTY(QString fwVersion READ fwVersion NOTIFY infoChanged)
+ Q_PROPERTY(Fact* radioMode READ radioMode CONSTANT)
+ Q_PROPERTY(Fact* radioChannel READ radioChannel CONSTANT)
+ Q_PROPERTY(Fact* videoOutput READ videoOutput CONSTANT)
+ Q_PROPERTY(Fact* videoMode READ videoMode CONSTANT)
+ Q_PROPERTY(Fact* videoRate READ videoRate CONSTANT)
+ Q_PROPERTY(QString rtspURI READ rtspURI NOTIFY rtspURIChanged)
+ Q_PROPERTY(QString rtspAccount READ rtspAccount NOTIFY rtspAccountChanged)
+ Q_PROPERTY(QString rtspPassword READ rtspPassword NOTIFY rtspPasswordChanged)
+ Q_PROPERTY(QString localIPAddr READ localIPAddr NOTIFY localIPAddrChanged)
+ Q_PROPERTY(QString remoteIPAddr READ remoteIPAddr NOTIFY remoteIPAddrChanged)
+ Q_PROPERTY(QString netMask READ netMask NOTIFY netMaskChanged)
+
+ Q_INVOKABLE bool setRTSPSettings (QString uri, QString account, QString password);
+ Q_INVOKABLE bool setIPSettings (QString localIP, QString remoteIP, QString netMask);
+
+ explicit MicrohardManager (QGCApplication* app, QGCToolbox* toolbox);
+ ~MicrohardManager () override;
+
+ void setToolbox (QGCToolbox* toolbox) override;
+
+ bool connected () { return _isConnected; }
+ bool linkConnected () { return _linkConnected; }
+ bool needReboot () { return _needReboot; }
+ QString linkVidFormat () { return _linkVidFormat; }
+ int uplinkRSSI () { return _downlinkRSSI; }
+ int downlinkRSSI () { return _uplinkRSSI; }
+ QString serialNumber () { return _serialNumber; }
+ QString fwVersion () { return _fwVersion; }
+ Fact* radioMode () { return _radioMode; }
+ Fact* radioChannel () { return _radioChannel; }
+ Fact* videoOutput () { return _videoOutput; }
+ Fact* videoMode () { return _videoMode; }
+ Fact* videoRate () { return _videoRate; }
+ QString rtspURI () { return _rtspURI; }
+ QString rtspAccount () { return _rtspAccount; }
+ QString rtspPassword () { return _rtspPassword; }
+ QString localIPAddr () { return _localIPAddr; }
+ QString remoteIPAddr () { return _remoteIPAddr; }
+ QString netMask () { return _netMask; }
+
+signals:
+ void linkChanged ();
+ void linkConnectedChanged ();
+ void infoChanged ();
+ void connectedChanged ();
+ void decodeIndexChanged ();
+ void rateIndexChanged ();
+ void rtspURIChanged ();
+ void rtspAccountChanged ();
+ void rtspPasswordChanged ();
+ void localIPAddrChanged ();
+ void remoteIPAddrChanged ();
+ void netMaskChanged ();
+ void needRebootChanged ();
+
+private slots:
+ void _connected ();
+ void _disconnected ();
+ void _checkMicrohard ();
+ void _updateSettings (QByteArray jSonData);
+ void _setEnabled ();
+ void _setVideoEnabled ();
+ void _radioSettingsChanged (QVariant);
+ void _videoSettingsChanged (QVariant);
+
+private:
+ void _close ();
+ void _reset ();
+ void _restoreVideoSettings (Fact* setting);
+ FactMetaData *_createMetadata (const char *name, QStringList enums);
+
+private:
+
+ enum {
+ REQ_LINK_STATUS = 1,
+ REQ_DEV_INFO = 2,
+ REQ_FREQ_SCAN = 4,
+ REQ_VIDEO_SETTINGS = 8,
+ REQ_RADIO_SETTINGS = 16,
+ REQ_RTSP_SETTINGS = 32,
+ REQ_IP_SETTINGS = 64,
+ REQ_ALL = 0xFFFFFFF,
+ };
+
+ uint32_t _reqMask = static_cast(REQ_ALL);
+ bool _running = false;
+ bool _isConnected = false;
+ AppSettings* _appSettings = nullptr;
+ MicrohardSettings* _mhSettings = nullptr;
+ bool _enableVideo = true;
+ bool _enabled = true;
+ bool _linkConnected = false;
+ bool _needReboot = false;
+ QTimer _workTimer;
+ QString _linkVidFormat;
+ int _downlinkRSSI = 0;
+ int _uplinkRSSI = 0;
+ QStringList _decodeList;
+ int _decodeIndex = 0;
+ QStringList _rateList;
+ int _rateIndex = 0;
+ QString _serialNumber;
+ QString _fwVersion;
+ Fact* _radioMode = nullptr;
+ Fact* _radioChannel = nullptr;
+ Fact* _videoOutput = nullptr;
+ Fact* _videoMode = nullptr;
+ Fact* _videoRate = nullptr;
+ QStringList _radioModeList;
+ QStringList _videoOutputList;
+ QStringList _videoRateList;
+ QString _rtspURI;
+ QString _rtspAccount;
+ QString _rtspPassword;
+ QString _localIPAddr;
+ QString _remoteIPAddr;
+ QString _netMask;
+ QTime _timeoutTimer;
+};
diff --git a/src/Microhard/MicrohardSettings.cc b/src/Microhard/MicrohardSettings.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b020a9fbb8deacda67cceb572951bc6410be57d0
--- /dev/null
+++ b/src/Microhard/MicrohardSettings.cc
@@ -0,0 +1,173 @@
+/****************************************************************************
+ *
+ * (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 "MicrohardSettings.h"
+#include "SettingsManager.h"
+#include "QGCApplication.h"
+#include "VideoManager.h"
+
+//-----------------------------------------------------------------------------
+MicrohardSettings::MicrohardSettings(QObject* parent)
+ : MicrohardHandler(parent)
+{
+}
+
+//-----------------------------------------------------------------------------
+bool MicrohardSettings::start()
+{
+ qCDebug(MicrohardLog) << "Start Microhard Settings";
+ return false;
+// return _start(MICROHARD_SETTINGS_PORT, QHostAddress(qgcApp()->toolbox()->microhardManager()->remoteIPAddr()));
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestLinkStatus()
+{
+ return _request("/v1/baseband.json");
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestDevInfo()
+{
+ return _request("/v1/device.json");
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestFreqScan()
+{
+ return _request("/v1/freqscan.json");
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestVideoSettings()
+{
+ return false;
+// return _request(kVideoURI);
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestRadioSettings()
+{
+ return false;
+// return _request(kRadioURI);
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestIPSettings()
+{
+ return false;
+// return _request(kIPAddrURI);
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::requestRTSPURISettings()
+{
+ return false;
+// return _request(kRTSPURI);
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::_request(const QString& request)
+{
+ /*
+ if(_tcpSocket) {
+ QString req = QString(kGetReq).arg(request);
+ //qCDebug(MicrohardVerbose) << "Request" << req;
+ _tcpSocket->write(req.toUtf8());
+ return true;
+ }
+ */
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::_post(const QString& post, const QString &postPayload)
+{
+ /*
+ if(_tcpSocket) {
+ QString req = QString(kPostReq).arg(post).arg(postPayload.size()).arg(postPayload);
+ qCDebug(MicrohardVerbose) << "Post" << req;
+ _tcpSocket->write(req.toUtf8());
+ return true;
+ }
+ */
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::setRadioSettings(const QString& mode, const QString& channel)
+{
+// static const char* kRadioPost = "{\"mode\":\"%1\",\"freq\":\"%2\"}";
+// QString post = QString(kRadioPost).arg(mode).arg(channel);
+ return false;
+// return _post(kRadioURI, post);
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::setVideoSettings(const QString& output, const QString& mode, const QString& rate)
+{
+ return false;
+/*
+ static const char* kVideoPost = "{\"decode\":\"%1\",\"mode\":\"%2\",\"maxbitrate\":\"%3\"}";
+ QString post = QString(kVideoPost).arg(output).arg(mode).arg(rate);
+ return _post(kVideoURI, post);
+ */
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::setRTSPSettings(const QString& uri, const QString& account, const QString& password)
+{
+ return false;
+// static const char* kRTSPPost = "{\"rtspURI\":\"%1\",\"account\":\"%2\",\"passwd\":\"%3\"}";
+// QString post = QString(kRTSPPost).arg(uri).arg(account).arg(password);
+// return _post(kRTSPURI, post);
+}
+
+//-----------------------------------------------------------------------------
+bool
+MicrohardSettings::setIPSettings(const QString& localIP, const QString& remoteIP, const QString& netMask)
+{
+ return false;
+// static const char* kRTSPPost = "{\"ipaddr\":\"%1\",\"netmask\":\"%2\",\"usbEthIp\":\"%3\"}";
+// QString post = QString(kRTSPPost).arg(localIP).arg(netMask).arg(remoteIP);
+// return _post(kIPAddrURI, post);
+}
+
+//-----------------------------------------------------------------------------
+void
+MicrohardSettings::_readBytes()
+{
+ QByteArray bytesIn = _tcpSocket->read(_tcpSocket->bytesAvailable());
+ //-- Go straight to Json payload
+ int idx = bytesIn.indexOf('{');
+ //-- We may receive more than one response within one TCP packet.
+ while(idx >= 0) {
+ bytesIn = bytesIn.mid(idx);
+ idx = bytesIn.indexOf('}');
+ if(idx > 0) {
+ QByteArray data = bytesIn.left(idx + 1);
+ emit updateSettings(data);
+ bytesIn = bytesIn.mid(idx+1);
+ idx = bytesIn.indexOf('{');
+ }
+ }
+}
+
diff --git a/src/Microhard/MicrohardSettings.h b/src/Microhard/MicrohardSettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3866978365b1493576c75520adcc2b053cab509
--- /dev/null
+++ b/src/Microhard/MicrohardSettings.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ *
+ * (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.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include "MicrohardHandler.h"
+
+class MicrohardSettings : public MicrohardHandler
+{
+ Q_OBJECT
+public:
+ explicit MicrohardSettings (QObject* parent = nullptr);
+ bool start () override;
+ bool requestLinkStatus ();
+ bool requestDevInfo ();
+ bool requestFreqScan ();
+ bool requestVideoSettings ();
+ bool requestRadioSettings ();
+ bool requestIPSettings ();
+ bool requestRTSPURISettings ();
+ bool setRadioSettings (const QString& mode, const QString& channel);
+ bool setVideoSettings (const QString& output, const QString& mode, const QString& rate);
+ bool setRTSPSettings (const QString& uri, const QString& account, const QString& password);
+ bool setIPSettings (const QString& localIP, const QString& remoteIP, const QString& netMask);
+
+signals:
+ void updateSettings (QByteArray jSonData);
+
+protected slots:
+ void _readBytes () override;
+
+private:
+ bool _request (const QString& request);
+ bool _post (const QString& post, const QString& postPayload);
+};
diff --git a/src/Microhard/MicrohardSettings.qml b/src/Microhard/MicrohardSettings.qml
new file mode 100644
index 0000000000000000000000000000000000000000..311db2e2135fabfd9737f4fc177d1181d99cd5f4
--- /dev/null
+++ b/src/Microhard/MicrohardSettings.qml
@@ -0,0 +1,543 @@
+/****************************************************************************
+ *
+ * (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 QtGraphicalEffects 1.0
+import QtMultimedia 5.5
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Layouts 1.2
+import QtLocation 5.3
+import QtPositioning 5.3
+
+import QGroundControl 1.0
+import QGroundControl.Controllers 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.FactControls 1.0
+import QGroundControl.FactSystem 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.SettingsManager 1.0
+
+QGCView {
+ id: _qgcView
+ viewPanel: panel
+ color: qgcPal.window
+ anchors.fill: parent
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+
+ property real _labelWidth: ScreenTools.defaultFontPixelWidth * 26
+ property real _valueWidth: ScreenTools.defaultFontPixelWidth * 20
+ property real _panelWidth: _qgcView.width * _internalWidthRatio
+ property Fact _microhardEnabledFact: QGroundControl.settingsManager.appSettings.enableMicrohard
+ property Fact _microhardVideoEnabledFact: QGroundControl.settingsManager.appSettings.enableMicrohardVideo
+ property bool _microhardEnabled: _microhardEnabledFact.rawValue
+
+ readonly property real _internalWidthRatio: 0.8
+
+ QGCPalette { id: qgcPal }
+
+ QGCViewPanel {
+ id: panel
+ anchors.fill: parent
+ QGCFlickable {
+ clip: true
+ anchors.fill: parent
+ contentHeight: settingsColumn.height
+ contentWidth: settingsColumn.width
+ Column {
+ id: settingsColumn
+ width: _qgcView.width
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ QGCLabel {
+ text: qsTr("Reboot ground unit for changes to take effect.")
+ color: qgcPal.colorOrange
+ visible: QGroundControl.microhardManager.needReboot
+ font.family: ScreenTools.demiboldFontFamily
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ //-----------------------------------------------------------------
+ //-- General
+ Item {
+ width: _panelWidth
+ height: generalLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ QGCLabel {
+ id: generalLabel
+ text: qsTr("General")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: generalRow.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Row {
+ id: generalRow
+ spacing: ScreenTools.defaultFontPixelWidth * 4
+ anchors.centerIn: parent
+ Column {
+ spacing: ScreenTools.defaultFontPixelWidth
+ FactCheckBox {
+ text: qsTr("Enable Microhard")
+ fact: _microhardEnabledFact
+ enabled: !QGroundControl.microhardManager.needReboot
+ visible: _microhardEnabledFact.visible
+ }
+ FactCheckBox {
+ text: qsTr("Enable Microhard Video")
+ fact: _microhardVideoEnabledFact
+ visible: _microhardVideoEnabledFact.visible
+ enabled: _microhardEnabled && !QGroundControl.microhardManager.needReboot
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- Connection Status
+ Item {
+ width: _panelWidth
+ height: statusLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled
+ QGCLabel {
+ id: statusLabel
+ text: qsTr("Connection Status")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: statusCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: statusCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Ground Unit:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.connected ? qsTr("Connected") : qsTr("Not Connected")
+ color: QGroundControl.microhardManager.connected ? qgcPal.colorGreen : qgcPal.colorRed
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Air Unit:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.linkConnected ? qsTr("Connected") : qsTr("Not Connected")
+ color: QGroundControl.microhardManager.linkConnected ? qgcPal.colorGreen : qgcPal.colorRed
+ }
+ QGCLabel {
+ text: qsTr("Uplink RSSI:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.linkConnected ? QGroundControl.microhardManager.uplinkRSSI : ""
+ }
+ QGCLabel {
+ text: qsTr("Downlink RSSI:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.linkConnected ? QGroundControl.microhardManager.downlinkRSSI : ""
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- Device Info
+ Item {
+ width: _panelWidth
+ height: devInfoLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled && QGroundControl.microhardManager.connected
+ QGCLabel {
+ id: devInfoLabel
+ text: qsTr("Device Info")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: devInfoCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled && QGroundControl.microhardManager.connected
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: devInfoCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Serial Number:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.connected ? QGroundControl.microhardManager.serialNumber : qsTr("")
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Firmware Version:")
+ }
+ QGCLabel {
+ text: QGroundControl.microhardManager.connected ? QGroundControl.microhardManager.fwVersion : qsTr("")
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- Radio Settings
+ Item {
+ width: _panelWidth
+ height: radioSettingsLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled && QGroundControl.microhardManager.linkConnected
+ QGCLabel {
+ id: radioSettingsLabel
+ text: qsTr("Radio Settings")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: radioSettingsCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled && QGroundControl.microhardManager.linkConnected
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: radioSettingsCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Radio Mode:")
+ Layout.minimumWidth: _labelWidth
+ }
+ FactComboBox {
+ fact: QGroundControl.microhardManager.radioMode
+ indexModel: true
+ enabled: QGroundControl.microhardManager.linkConnected && !QGroundControl.microhardManager.needReboot
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Radio Frequency:")
+ }
+ FactComboBox {
+ fact: QGroundControl.microhardManager.radioChannel
+ indexModel: true
+ enabled: QGroundControl.microhardManager.linkConnected && QGroundControl.microhardManager.radioMode.rawValue > 0 && !QGroundControl.microhardManager.needReboot
+ Layout.minimumWidth: _valueWidth
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- Video Settings
+ Item {
+ width: _panelWidth
+ height: videoSettingsLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled && QGroundControl.microhardManager.linkConnected
+ QGCLabel {
+ id: videoSettingsLabel
+ text: qsTr("Video Settings")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: videoSettingsCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled && QGroundControl.microhardManager.linkConnected
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: videoSettingsCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Video Output:")
+ Layout.minimumWidth: _labelWidth
+ }
+ FactComboBox {
+ fact: QGroundControl.microhardManager.videoOutput
+ indexModel: true
+ enabled: QGroundControl.microhardManager.linkConnected && !QGroundControl.microhardManager.needReboot
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Encoder:")
+ }
+ FactComboBox {
+ fact: QGroundControl.microhardManager.videoMode
+ indexModel: true
+ enabled: QGroundControl.microhardManager.linkConnected && !QGroundControl.microhardManager.needReboot
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Bit Rate:")
+ }
+ FactComboBox {
+ fact: QGroundControl.microhardManager.videoRate
+ indexModel: true
+ enabled: QGroundControl.microhardManager.linkConnected && !QGroundControl.microhardManager.needReboot
+ Layout.minimumWidth: _valueWidth
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- RTSP Settings
+ Item {
+ width: _panelWidth
+ height: rtspSettingsLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled && QGroundControl.microhardManager.connected
+ QGCLabel {
+ id: rtspSettingsLabel
+ text: qsTr("Streaming Settings")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: rtspSettingsCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled && QGroundControl.microhardManager.connected
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: rtspSettingsCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("RTSP URI:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCTextField {
+ id: rtspURI
+ text: QGroundControl.microhardManager.rtspURI
+ enabled: QGroundControl.microhardManager.connected && !QGroundControl.microhardManager.needReboot
+ inputMethodHints: Qt.ImhUrlCharactersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Account:")
+ }
+ QGCTextField {
+ id: rtspAccount
+ text: QGroundControl.microhardManager.rtspAccount
+ enabled: QGroundControl.microhardManager.connected && !QGroundControl.microhardManager.needReboot
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Password:")
+ }
+ QGCTextField {
+ id: rtspPassword
+ text: QGroundControl.microhardManager.rtspPassword
+ enabled: QGroundControl.microhardManager.connected && !QGroundControl.microhardManager.needReboot
+ inputMethodHints: Qt.ImhHiddenText
+ Layout.minimumWidth: _valueWidth
+ }
+ }
+ Item {
+ width: 1
+ height: ScreenTools.defaultFontPixelHeight
+ }
+ QGCButton {
+ function testEnabled() {
+ if(!QGroundControl.microhardManager.connected)
+ return false
+ if(rtspPassword.text === QGroundControl.microhardManager.rtspPassword &&
+ rtspAccount.text === QGroundControl.microhardManager.rtspAccount &&
+ rtspURI.text === QGroundControl.microhardManager.rtspURI)
+ return false
+ if(rtspURI === "")
+ return false
+ return true
+ }
+ enabled: testEnabled() && !QGroundControl.microhardManager.needReboot
+ text: qsTr("Apply")
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: {
+ setRTSPDialog.open()
+ }
+ MessageDialog {
+ id: setRTSPDialog
+ icon: StandardIcon.Warning
+ standardButtons: StandardButton.Yes | StandardButton.No
+ title: qsTr("Set Streaming Settings")
+ text: qsTr("Once changed, you will need to reboot the ground unit for the changes to take effect.\n\nConfirm change?")
+ onYes: {
+ QGroundControl.microhardManager.setRTSPSettings(rtspURI.text, rtspAccount.text, rtspPassword.text)
+ setRTSPDialog.close()
+ }
+ onNo: {
+ setRTSPDialog.close()
+ }
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------
+ //-- IP Settings
+ Item {
+ width: _panelWidth
+ height: ipSettingsLabel.height
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: _microhardEnabled && (!ScreenTools.isiOS && !ScreenTools.isAndroid)
+ QGCLabel {
+ id: ipSettingsLabel
+ text: qsTr("Network Settings")
+ font.family: ScreenTools.demiboldFontFamily
+ }
+ }
+ Rectangle {
+ height: ipSettingsCol.height + (ScreenTools.defaultFontPixelHeight * 2)
+ width: _panelWidth
+ color: qgcPal.windowShade
+ visible: _microhardEnabled && (!ScreenTools.isiOS && !ScreenTools.isAndroid)
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ anchors.horizontalCenter: parent.horizontalCenter
+ Column {
+ id: ipSettingsCol
+ spacing: ScreenTools.defaultFontPixelHeight * 0.5
+ width: parent.width
+ anchors.centerIn: parent
+ GridLayout {
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ anchors.horizontalCenter: parent.horizontalCenter
+ columns: 2
+ QGCLabel {
+ text: qsTr("Local IP Address:")
+ Layout.minimumWidth: _labelWidth
+ }
+ QGCTextField {
+ id: localIP
+ text: QGroundControl.microhardManager.localIPAddr
+ enabled: !QGroundControl.microhardManager.needReboot
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Ground Unit IP Address:")
+ }
+ QGCTextField {
+ id: remoteIP
+ text: QGroundControl.microhardManager.remoteIPAddr
+ enabled: !QGroundControl.microhardManager.needReboot
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ QGCLabel {
+ text: qsTr("Network Mask:")
+ }
+ QGCTextField {
+ id: netMask
+ text: QGroundControl.microhardManager.netMask
+ enabled: !QGroundControl.microhardManager.needReboot
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.minimumWidth: _valueWidth
+ }
+ }
+ Item {
+ width: 1
+ height: ScreenTools.defaultFontPixelHeight
+ }
+ QGCButton {
+ function validateIPaddress(ipaddress) {
+ if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress))
+ return true
+ return false
+ }
+ function testEnabled() {
+ if(localIP.text === QGroundControl.microhardManager.localIPAddr &&
+ remoteIP.text === QGroundControl.microhardManager.remoteIPAddr &&
+ netMask.text === QGroundControl.microhardManager.netMask)
+ return false
+ if(!validateIPaddress(localIP.text)) return false
+ if(!validateIPaddress(remoteIP.text)) return false
+ if(!validateIPaddress(netMask.text)) return false
+ return true
+ }
+ enabled: testEnabled() && !QGroundControl.microhardManager.needReboot
+ text: qsTr("Apply")
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: {
+ setIPDialog.open()
+ }
+ MessageDialog {
+ id: setIPDialog
+ icon: StandardIcon.Warning
+ standardButtons: StandardButton.Yes | StandardButton.No
+ title: qsTr("Set Network Settings")
+ text: qsTr("Once changed, you will need to reboot the ground unit for the changes to take effect. The local IP address must match the one entered (%1).\n\nConfirm change?").arg(localIP.text)
+ onYes: {
+ QGroundControl.microhardManager.setIPSettings(localIP.text, remoteIP.text, netMask.text)
+ setIPDialog.close()
+ }
+ onNo: {
+ setIPDialog.close()
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h
index 8df56423ea3e283c7e153b233a968ef99a94c2e6..eaba4616e89d3c57cf4cac9d5145e4f8970c522b 100644
--- a/src/QGCToolbox.h
+++ b/src/QGCToolbox.h
@@ -36,6 +36,9 @@ class AirspaceManager;
#if defined(QGC_GST_TAISYNC_ENABLED)
class TaisyncManager;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+class MicrohardManager;
+#endif
/// This is used to manage all of our top level services/tools
class QGCToolbox : public QObject {
@@ -67,6 +70,9 @@ public:
#if defined(QGC_GST_TAISYNC_ENABLED)
TaisyncManager* taisyncManager () { return _taisyncManager; }
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ MicrohardManager* microhardManager () { return _microhardManager; }
+#endif
private:
void setChildToolboxes(void);
@@ -96,6 +102,9 @@ private:
AirspaceManager* _airspaceManager = nullptr;
#if defined(QGC_GST_TAISYNC_ENABLED)
TaisyncManager* _taisyncManager = nullptr;
+#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ MicrohardManager* _microhardManager = nullptr;
#endif
friend class QGCApplication;
};
diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc
index b223793fd3501293d02dd2e2289e7656cd8e49f5..fbf84f2f79117e7bb4ce4aa84bd5db93808ea60f 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.cc
+++ b/src/QmlControls/QGroundControlQmlGlobal.cc
@@ -69,6 +69,9 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox)
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager = toolbox->taisyncManager();
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ _microhardManager = toolbox->microhardManager();
+#endif
}
void QGroundControlQmlGlobal::saveGlobalSetting (const QString& key, const QString& value)
diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h
index 26c3631e564200356b488dd0344c509f0fad6995..0a4fb92055a91f58db03959db449f56d1295d3aa 100644
--- a/src/QmlControls/QGroundControlQmlGlobal.h
+++ b/src/QmlControls/QGroundControlQmlGlobal.h
@@ -28,6 +28,11 @@
#else
class TaisyncManager;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+#include "MicrohardManager.h"
+#else
+class MicrohardManager;
+#endif
#ifdef QT_DEBUG
#include "MockLink.h"
@@ -68,6 +73,8 @@ public:
Q_PROPERTY(bool airmapSupported READ airmapSupported CONSTANT)
Q_PROPERTY(TaisyncManager* taisyncManager READ taisyncManager CONSTANT)
Q_PROPERTY(bool taisyncSupported READ taisyncSupported CONSTANT)
+ Q_PROPERTY(MicrohardManager* microhardManager READ microhardManager CONSTANT)
+ Q_PROPERTY(bool microhardSupported READ microhardSupported CONSTANT)
Q_PROPERTY(int supportedFirmwareCount READ supportedFirmwareCount CONSTANT)
Q_PROPERTY(bool px4ProFirmwareSupported READ px4ProFirmwareSupported CONSTANT)
@@ -170,6 +177,13 @@ public:
bool taisyncSupported () { return false; }
#endif
+ MicrohardManager* microhardManager () { return _microhardManager; }
+#if defined(QGC_GST_TAISYNC_ENABLED)
+ bool microhardSupported () { return true; }
+#else
+ bool microhardSupported () { return false; }
+#endif
+
qreal zOrderTopMost () { return 1000; }
qreal zOrderWidgets () { return 100; }
qreal zOrderMapItems () { return 50; }
@@ -230,6 +244,7 @@ private:
FactGroup* _gpsRtkFactGroup = nullptr;
AirspaceManager* _airspaceManager = nullptr;
TaisyncManager* _taisyncManager = nullptr;
+ MicrohardManager* _microhardManager = nullptr;
bool _skipSetupPage = false;
diff --git a/src/Settings/App.SettingsGroup.json b/src/Settings/App.SettingsGroup.json
index 67ef154dcca8ff523e4b7d9289ebcb46ca263397..fd0c89667b21c234a1003a61c3bcee769a1374fb 100644
--- a/src/Settings/App.SettingsGroup.json
+++ b/src/Settings/App.SettingsGroup.json
@@ -221,4 +221,18 @@
"type": "bool",
"defaultValue": true
}
-]
+,
+{
+ "name": "enableMicrohard",
+ "shortDescription": "Enable Microhard Module Support",
+ "longDescription": "Enable Microhard Module Support",
+ "type": "bool",
+ "defaultValue": false
+},
+{
+ "name": "enableMicrohardVideo",
+ "shortDescription": "Enable Microhard Video Support",
+ "longDescription": "Enable Microhard Video Support",
+ "type": "bool",
+ "defaultValue": true
+}]
diff --git a/src/Settings/AppSettings.cc b/src/Settings/AppSettings.cc
index abfdfb4a6196939422ebb0797653fcfc43606112..3d69c86e1537593a4d6121d550a4588cc74d735c 100644
--- a/src/Settings/AppSettings.cc
+++ b/src/Settings/AppSettings.cc
@@ -87,6 +87,8 @@ DECLARE_SETTINGSFACT(AppSettings, followTarget)
DECLARE_SETTINGSFACT(AppSettings, apmStartMavlinkStreams)
DECLARE_SETTINGSFACT(AppSettings, enableTaisync)
DECLARE_SETTINGSFACT(AppSettings, enableTaisyncVideo)
+DECLARE_SETTINGSFACT(AppSettings, enableMicrohard)
+DECLARE_SETTINGSFACT(AppSettings, enableMicrohardVideo)
DECLARE_SETTINGSFACT_NO_FUNC(AppSettings, indoorPalette)
{
diff --git a/src/Settings/AppSettings.h b/src/Settings/AppSettings.h
index 37784b9be964c3a7e81a1363490620405c4bcede..c4e966fa30dfc2b83e0449d24b63a73e2a6faa46 100644
--- a/src/Settings/AppSettings.h
+++ b/src/Settings/AppSettings.h
@@ -45,6 +45,8 @@ public:
DEFINE_SETTINGFACT(followTarget)
DEFINE_SETTINGFACT(enableTaisync)
DEFINE_SETTINGFACT(enableTaisyncVideo)
+ DEFINE_SETTINGFACT(enableMicrohard)
+ DEFINE_SETTINGFACT(enableMicrohardVideo)
// Although this is a global setting it only affects ArduPilot vehicle since PX4 automatically starts the stream from the vehicle side
DEFINE_SETTINGFACT(apmStartMavlinkStreams)
diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc
index eeaa2678d986dc3ea8197af98667e065caf9ad8a..0a1a6dc02b1101aa415102d333792a215b8c6d9c 100644
--- a/src/api/QGCCorePlugin.cc
+++ b/src/api/QGCCorePlugin.cc
@@ -48,6 +48,10 @@ public:
if(pTaisync)
delete pTaisync;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ if(pMicrohard)
+ delete pMicrohard;
+#endif
#if defined(QGC_AIRMAP_ENABLED)
if(pAirmap)
delete pAirmap;
@@ -72,6 +76,9 @@ public:
#if defined(QGC_GST_TAISYNC_ENABLED)
QmlComponentInfo* pTaisync = nullptr;
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ QmlComponentInfo* pMicrohard = nullptr;
+#endif
#if defined(QGC_AIRMAP_ENABLED)
QmlComponentInfo* pAirmap = nullptr;
#endif
@@ -140,6 +147,12 @@ QVariantList &QGCCorePlugin::settingsPages()
QUrl::fromUserInput(""));
_p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pTaisync)));
#endif
+#if defined(QGC_GST_MICROHARD_ENABLED)
+ _p->pMicrohard = new QmlComponentInfo(tr("Microhard"),
+ QUrl::fromUserInput("qrc:/qml/MicrohardSettings.qml"),
+ QUrl::fromUserInput(""));
+ _p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pMicrohard)));
+#endif
#if defined(QGC_AIRMAP_ENABLED)
_p->pAirmap = new QmlComponentInfo(tr("AirMap"),
QUrl::fromUserInput("qrc:/qml/AirmapSettings.qml"),