Skip to content

Commit

Permalink
PositionManager: Convert to Singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Nov 9, 2024
1 parent 0b4bfa2 commit 4bddc9e
Show file tree
Hide file tree
Showing 18 changed files with 171 additions and 161 deletions.
1 change: 1 addition & 0 deletions src/Comms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ target_link_libraries(Comms
Qt6::Test
AirLink
MockLink
PositionManager
Settings
Vehicle
PUBLIC
Expand Down
4 changes: 2 additions & 2 deletions src/Comms/LinkManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ void LinkManager::_addSerialAutoConnectLink()
qCDebug(LinkManagerLog) << "Changing port for UDP NMEA stream";
_nmeaSocket->close();
_nmeaSocket->bind(QHostAddress::AnyIPv4, _autoConnectSettings->nmeaUdpPort()->rawValue().toUInt());
_toolbox->qgcPositionManager()->setNmeaSourceDevice(_nmeaSocket);
QGCPositionManager::instance()->setNmeaSourceDevice(_nmeaSocket);
}
if (_nmeaPort) {
_nmeaPort->close();
Expand Down Expand Up @@ -809,7 +809,7 @@ void LinkManager::_addSerialAutoConnectLink()
newPort->setBaudRate(static_cast<qint32>(_nmeaBaud));
qCDebug(LinkManagerLog) << "Configuring nmea baudrate" << _nmeaBaud;
// This will stop polling old device if previously set
_toolbox->qgcPositionManager()->setNmeaSourceDevice(newPort);
QGCPositionManager::instance()->setNmeaSourceDevice(newPort);
if (_nmeaPort) {
delete _nmeaPort;
}
Expand Down
4 changes: 2 additions & 2 deletions src/FollowMe/FollowMe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void FollowMe::_settingsChanged(QVariant value)
void FollowMe::_enableFollowSend()
{
if (!_gcsMotionReportTimer->isActive()) {
_gcsMotionReportTimer->setInterval(qMin(qgcApp()->toolbox()->qgcPositionManager()->updateInterval(), kMotionUpdateInterval));
_gcsMotionReportTimer->setInterval(qMin(QGCPositionManager::instance()->updateInterval(), kMotionUpdateInterval));
_gcsMotionReportTimer->start();
}
}
Expand All @@ -94,7 +94,7 @@ void FollowMe::_disableFollowSend()

void FollowMe::_sendGCSMotionReport()
{
const QGeoPositionInfo geoPositionInfo = qgcApp()->toolbox()->qgcPositionManager()->geoPositionInfo();
const QGeoPositionInfo geoPositionInfo = QGCPositionManager::instance()->geoPositionInfo();
const QGeoCoordinate gcsCoordinate = geoPositionInfo.coordinate();

if (!geoPositionInfo.isValid()) {
Expand Down
3 changes: 2 additions & 1 deletion src/PositionManager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
find_package(Qt6 REQUIRED COMPONENTS Core Qml Positioning)
find_package(Qt6 REQUIRED COMPONENTS Core Qml Positioning QmlIntegration)

qt_add_library(PositionManager STATIC
PositionManager.cpp
Expand All @@ -17,6 +17,7 @@ target_link_libraries(PositionManager
PUBLIC
Qt6::Core
Qt6::Positioning
Qt6::QmlIntegration
QGC
)

Expand Down
158 changes: 82 additions & 76 deletions src/PositionManager/PositionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
#include "SimulatedPosition.h"
#include <DeviceInfo.h>
#include <QGCLoggingCategory.h>
#include "DeviceInfo.h"
#include "QGCLoggingCategory.h"

#include <QtCore/qapplicationstatic.h>
#include <QtCore/QPermissions>
#include <QtPositioning/QGeoPositionInfoSource>
#include <QtPositioning/private/qgeopositioninfosource_p.h>
Expand All @@ -22,27 +23,46 @@

QGC_LOGGING_CATEGORY(QGCPositionManagerLog, "qgc.positionmanager.positionmanager")

QGCPositionManager::QGCPositionManager(QGCApplication *app, QGCToolbox *toolbox)
: QGCTool(app, toolbox)
Q_APPLICATION_STATIC(QGCPositionManager, _positionManager);

QGCPositionManager::QGCPositionManager(QObject *parent)
: QObject(parent)
{
// qCDebug(QGCPositionManagerLog) << Q_FUNC_INFO << this;

(void) qmlRegisterUncreatableType<QGCPositionManager>("QGroundControl.QGCPositionManager", 1, 0, "QGCPositionManager", "Reference only");
}

QGCPositionManager::~QGCPositionManager()
{
// qCDebug(QGCPositionManagerLog) << Q_FUNC_INFO << this;
}

QGCPositionManager *QGCPositionManager::instance()
{
return _positionManager();
}

void QGCPositionManager::init()
{
if (qgcApp()->runningUnitTests()) {
_simulatedSource = new SimulatedPosition(this);
_setPositionSource(QGCPositionSource::Simulated);
} else {
_checkPermission();
}
}

void QGCPositionManager::_setupPositionSources()
{
m_defaultSource = _toolbox->corePlugin()->createPositionSource(this);
if (m_defaultSource) {
m_usingPluginSource = true;
_defaultSource = qgcApp()->toolbox()->corePlugin()->createPositionSource(this);
if (_defaultSource) {
_usingPluginSource = true;
} else {
qCDebug(QGCPositionManagerLog) << Q_FUNC_INFO << QGeoPositionInfoSource::availableSources();

m_defaultSource = QGeoPositionInfoSource::createDefaultSource(this);
if (!m_defaultSource) {
_defaultSource = QGeoPositionInfoSource::createDefaultSource(this);
if (!_defaultSource) {
qCWarning(QGCPositionManagerLog) << Q_FUNC_INFO << "No default source available";
return;
}
Expand All @@ -65,84 +85,70 @@ void QGCPositionManager::_checkPermission()
QLocationPermission locationPermission;
locationPermission.setAccuracy(QLocationPermission::Precise);

const Qt::PermissionStatus permissionStatus = _app->checkPermission(locationPermission);
const Qt::PermissionStatus permissionStatus = qgcApp()->checkPermission(locationPermission);
if (permissionStatus == Qt::PermissionStatus::Undetermined) {
_app->requestPermission(locationPermission, this, [this](const QPermission &permission) {
qgcApp()->requestPermission(locationPermission, this, [this](const QPermission &permission) {
_handlePermissionStatus(permission.status());
});
} else {
_handlePermissionStatus(permissionStatus);
}
}

void QGCPositionManager::setToolbox(QGCToolbox *toolbox)
{
QGCTool::setToolbox(toolbox);

(void) qmlRegisterUncreatableType<QGCPositionManager>("QGroundControl.QGCPositionManager", 1, 0, "QGCPositionManager", "Reference only");

if (_app->runningUnitTests()) {
m_simulatedSource = new SimulatedPosition(this);
_setPositionSource(QGCPositionSource::Simulated);
} else {
_checkPermission();
}
}

void QGCPositionManager::setNmeaSourceDevice(QIODevice *device)
{
if (m_nmeaSource) {
m_nmeaSource->stopUpdates();
(void) disconnect(m_nmeaSource);
if (_nmeaSource) {
_nmeaSource->stopUpdates();
(void) disconnect(_nmeaSource);

if (m_currentSource == m_nmeaSource) {
m_currentSource = nullptr;
if (_currentSource == _nmeaSource) {
_currentSource = nullptr;
}

delete m_nmeaSource;
m_nmeaSource = nullptr;
delete _nmeaSource;
_nmeaSource = nullptr;
}

m_nmeaSource = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode, this);
m_nmeaSource->setDevice(device);
m_nmeaSource->setUserEquivalentRangeError(5.1);
_nmeaSource = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode, this);
_nmeaSource->setDevice(device);
_nmeaSource->setUserEquivalentRangeError(5.1);
_setPositionSource(QGCPositionManager::NmeaGPS);
}

void QGCPositionManager::_positionUpdated(const QGeoPositionInfo &update)
{
m_geoPositionInfo = update;
_geoPositionInfo = update;

QGeoCoordinate newGCSPosition(m_gcsPosition);
QGeoCoordinate newGCSPosition(_gcsPosition);

if (update.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) {
if ((qAbs(update.coordinate().latitude()) > 0.001) && (qAbs(update.coordinate().longitude()) > 0.001)) {
m_gcsPositionHorizontalAccuracy = update.attribute(QGeoPositionInfo::HorizontalAccuracy);
if (m_gcsPositionHorizontalAccuracy <= s_minHorizonalAccuracyMeters) {
_gcsPositionHorizontalAccuracy = update.attribute(QGeoPositionInfo::HorizontalAccuracy);
if (_gcsPositionHorizontalAccuracy <= kMinHorizonalAccuracyMeters) {
newGCSPosition.setLatitude(update.coordinate().latitude());
newGCSPosition.setLongitude(update.coordinate().longitude());
}
emit gcsPositionHorizontalAccuracyChanged(m_gcsPositionHorizontalAccuracy);
emit gcsPositionHorizontalAccuracyChanged(_gcsPositionHorizontalAccuracy);
}
}

if (update.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) {
m_gcsPositionVerticalAccuracy = update.attribute(QGeoPositionInfo::VerticalAccuracy);
if (m_gcsPositionVerticalAccuracy <= s_minVerticalAccuracyMeters) {
_gcsPositionVerticalAccuracy = update.attribute(QGeoPositionInfo::VerticalAccuracy);
if (_gcsPositionVerticalAccuracy <= kMinVerticalAccuracyMeters) {
newGCSPosition.setAltitude(update.coordinate().altitude());
}
}

m_gcsPositionAccuracy = sqrt(pow(m_gcsPositionHorizontalAccuracy, 2) + pow(m_gcsPositionVerticalAccuracy, 2));
_gcsPositionAccuracy = sqrt(pow(_gcsPositionHorizontalAccuracy, 2) + pow(_gcsPositionVerticalAccuracy, 2));

_setGCSPosition(newGCSPosition);

if (update.hasAttribute(QGeoPositionInfo::DirectionAccuracy)) {
m_gcsDirectionAccuracy = update.attribute(QGeoPositionInfo::DirectionAccuracy);
if (m_gcsDirectionAccuracy <= s_minDirectionAccuracyDegrees) {
_gcsDirectionAccuracy = update.attribute(QGeoPositionInfo::DirectionAccuracy);
if (_gcsDirectionAccuracy <= kMinDirectionAccuracyDegrees) {
_setGCSHeading(update.attribute(QGeoPositionInfo::Direction));
}
} else if (m_usingPluginSource) {
} else if (_usingPluginSource) {
_setGCSHeading(update.attribute(QGeoPositionInfo::Direction));
}

Expand All @@ -151,69 +157,69 @@ void QGCPositionManager::_positionUpdated(const QGeoPositionInfo &update)

void QGCPositionManager::_setGCSHeading(qreal newGCSHeading)
{
if (newGCSHeading != m_gcsHeading) {
m_gcsHeading = newGCSHeading;
emit gcsHeadingChanged(m_gcsHeading);
if (newGCSHeading != _gcsHeading) {
_gcsHeading = newGCSHeading;
emit gcsHeadingChanged(_gcsHeading);
}
}

void QGCPositionManager::_setGCSPosition(const QGeoCoordinate& newGCSPosition)
{
if (newGCSPosition != m_gcsPosition) {
m_gcsPosition = newGCSPosition;
emit gcsPositionChanged(m_gcsPosition);
if (newGCSPosition != _gcsPosition) {
_gcsPosition = newGCSPosition;
emit gcsPositionChanged(_gcsPosition);
}
}

void QGCPositionManager::_setPositionSource(QGCPositionSource source)
{
if (m_currentSource != nullptr) {
m_currentSource->stopUpdates();
(void) disconnect(m_currentSource);

m_geoPositionInfo = QGeoPositionInfo();
m_gcsPosition = QGeoCoordinate();
m_gcsHeading = qQNaN();
m_gcsPositionHorizontalAccuracy = std::numeric_limits<qreal>::infinity();

emit gcsPositionChanged(m_gcsPosition);
emit gcsHeadingChanged(m_gcsHeading);
emit positionInfoUpdated(m_geoPositionInfo);
emit gcsPositionHorizontalAccuracyChanged(m_gcsPositionHorizontalAccuracy);
if (_currentSource != nullptr) {
_currentSource->stopUpdates();
(void) disconnect(_currentSource);

_geoPositionInfo = QGeoPositionInfo();
_gcsPosition = QGeoCoordinate();
_gcsHeading = qQNaN();
_gcsPositionHorizontalAccuracy = std::numeric_limits<qreal>::infinity();

emit gcsPositionChanged(_gcsPosition);
emit gcsHeadingChanged(_gcsHeading);
emit positionInfoUpdated(_geoPositionInfo);
emit gcsPositionHorizontalAccuracyChanged(_gcsPositionHorizontalAccuracy);
}

switch (source) {
case QGCPositionManager::Log:
break;
case QGCPositionManager::Simulated:
m_currentSource = m_simulatedSource;
_currentSource = _simulatedSource;
break;
case QGCPositionManager::NmeaGPS:
m_currentSource = m_nmeaSource;
_currentSource = _nmeaSource;
break;
case QGCPositionManager::InternalGPS:
m_currentSource = m_defaultSource;
_currentSource = _defaultSource;
break;
case QGCPositionManager::ExternalGPS:
break;
default:
m_currentSource = m_defaultSource;
_currentSource = _defaultSource;
break;
}

if (m_currentSource != nullptr) {
m_currentSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
m_updateInterval = m_currentSource->minimumUpdateInterval();
if (_currentSource != nullptr) {
_currentSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
_updateInterval = _currentSource->minimumUpdateInterval();
#if !defined(Q_OS_DARWIN) && !defined(Q_OS_IOS)
m_currentSource->setUpdateInterval(m_updateInterval);
_currentSource->setUpdateInterval(_updateInterval);
#endif
(void) connect(m_currentSource, &QGeoPositionInfoSource::positionUpdated, this, &QGCPositionManager::_positionUpdated);
(void) connect(m_currentSource, &QGeoPositionInfoSource::errorOccurred, this, [](QGeoPositionInfoSource::Error positioningError) {
(void) connect(_currentSource, &QGeoPositionInfoSource::positionUpdated, this, &QGCPositionManager::_positionUpdated);
(void) connect(_currentSource, &QGeoPositionInfoSource::errorOccurred, this, [](QGeoPositionInfoSource::Error positioningError) {
qCWarning(QGCPositionManagerLog) << Q_FUNC_INFO << positioningError;
});

// (void) connect(QGCCompass::instance(), &QGCCompass::positionUpdated, this, &QGCPositionManager::_positionUpdated);

m_currentSource->startUpdates();
_currentSource->startUpdates();
}
}
Loading

0 comments on commit 4bddc9e

Please sign in to comment.