Commit 4c989f93 authored by Matej Frančeškin's avatar Matej Frančeškin

Microhard: Added settings panel similar to Taisync

parent 0c5919d3
......@@ -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 {
......
......@@ -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
......
......@@ -201,6 +201,7 @@
<file alias="SyslinkComponent.qml">src/AutoPilotPlugins/Common/SyslinkComponent.qml</file>
<file alias="TcpSettings.qml">src/ui/preferences/TcpSettings.qml</file>
<file alias="TaisyncSettings.qml">src/Taisync/TaisyncSettings.qml</file>
<file alias="MicrohardSettings.qml">src/Microhard/MicrohardSettings.qml</file>
<file alias="test.qml">src/test.qml</file>
<file alias="UdpSettings.qml">src/ui/preferences/UdpSettings.qml</file>
<file alias="ValuePageWidget.qml">src/FlightMap/Widgets/ValuePageWidget.qml</file>
......
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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();
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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 <QTcpServer>
#include <QTcpSocket>
#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;
};
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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 <QSettings>
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<uint32_t>(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<SettingsFact*>(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<uint32_t>(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<uint32_t>(REQ_RTSP_SETTINGS);
_mhSettings->requestRTSPURISettings();
break;
}
if (_reqMask & REQ_IP_SETTINGS) {
_reqMask &= ~static_cast<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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();
}
}
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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 <QTimer>
#include <QTime>
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<uint32_t>(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;
};
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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('{');
}
}
}
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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);
};
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* 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()
}
}
}
}
}
}
}
}
}
......@@ -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;
};
......
......@@ -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)
......
......@@ -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;
......
......@@ -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
}]
......@@ -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)
{
......
......@@ -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)
......
......@@ -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<QmlComponentInfo*>(_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<QmlComponentInfo*>(_p->pMicrohard)));
#endif
#if defined(QGC_AIRMAP_ENABLED)
_p->pAirmap = new QmlComponentInfo(tr("AirMap"),
QUrl::fromUserInput("qrc:/qml/AirmapSettings.qml"),
......
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