QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
PositionManager.h
Go to the documentation of this file.
1#pragma once
2
3#include <chrono>
4#include <functional>
5#include <limits>
6#include <memory>
7#include <optional>
8
9#include <QtCore/QObject>
10#include <QtCore/QPointer>
11#include <QtPositioning/QGeoCoordinate>
12#include <QtPositioning/QGeoPositionInfoSource>
13#include <QtQmlIntegration/QtQmlIntegration>
14
15#include "GPSSourceHealth.h"
16#include "ScheduledTask.h"
17
20using GPSPositionSourceRegistration = std::shared_ptr<const void>;
21
26class PositionManager : public QObject
27{
28 Q_OBJECT
29 QML_ELEMENT
30 QML_UNCREATABLE("Created by QGroundControl")
31
32 Q_PROPERTY(QString selectedSourceName READ selectedSourceName NOTIFY selectionChanged FINAL)
33 Q_PROPERTY(QString sourceStatusText READ sourceStatusText NOTIFY selectionChanged FINAL)
34 Q_PROPERTY(QGeoCoordinate gcsPosition READ gcsPosition NOTIFY gcsPositionChanged FINAL)
35 Q_PROPERTY(qreal gcsHeading READ gcsHeading NOTIFY gcsHeadingChanged FINAL)
38
39 friend class PositionManagerTest;
40
41public:
43 enum class SourceMode
44 {
45 Automatic = 0,
46 ReceiverOnly = 1,
47 InternalOnly = 2,
48 };
49 Q_ENUM(SourceMode)
50
51 enum class SelectedSource
52 {
53 None,
56 };
57 Q_ENUM(SelectedSource)
58
70 Q_ENUM(SourceStatus)
71
72
73 using SourceFactory = std::function<QGeoPositionInfoSource*(QObject* parent)>;
74
76 {
78 bool operator==(const Configuration&) const = default;
79 };
80
81 static constexpr std::chrono::milliseconds RECOVERY_DELAY{5000};
82
83 explicit PositionManager(QObject* parent = nullptr, RuntimeScheduler* scheduler = nullptr);
84 ~PositionManager() override;
85
87 void setConfiguration(const Configuration& configuration);
88
89 const Configuration& configuration() const { return _configuration; }
90
94
95 void init();
97 void shutdown();
98
99 SelectedSource selectedSource() const { return _selectedSource; }
100
101 QString selectedSourceName() const;
102
103 SourceStatus sourceStatus() const { return _sourceStatus; }
104
105 QString sourceStatusText() const;
106
110 void setInternalPositionSource(QGeoPositionInfoSource* source, SourceStatus status, bool custom = false,
112
115 GPSPositionSourceRegistration registerReceiver(GPSSourceHealth* producer, quint64 sessionId = 0);
116
117 QGeoCoordinate gcsPosition() const { return _published.position; }
118
119 qreal gcsHeading() const { return _published.heading; }
120
121 qreal gcsPositionHorizontalAccuracy() const { return _published.horizontalAccuracy; }
122
123 std::optional<GPSObservation> acceptedObservation(
125 std::optional<std::chrono::milliseconds> maximumAge = std::nullopt) const;
126
127 QGeoPositionInfoSource::Error gcsPositioningError() const { return _gcsPositioningError; }
128
129signals:
131 void gcsPositionChanged(QGeoCoordinate gcsPosition);
134
135private:
136 struct Publication
137 {
138 QGeoCoordinate position;
139 qreal heading = qQNaN();
140 qreal horizontalAccuracy = std::numeric_limits<qreal>::infinity();
141 };
142
143 void _setInternalPositionStatus(SourceStatus status);
145 GPSSourceHealth* _sourceHealth(SelectedSource kind) const;
146 void _setReceiver(GPSSourceHealth* producer, quint64 sessionId);
147 void _retireReceiver(quint64 token);
148 void _releaseDevice();
149 void _setDeviceActive(bool active);
150 void _devicePositionUpdated(const QGeoPositionInfo& position);
151 void _deviceErrorOccurred(QGeoPositionInfoSource::Error error);
152 void _bindingChanged(SelectedSource kind);
154 void _update(SelectedSource reporter = SelectedSource::None);
155 SelectedSource _choose();
156 void _republish();
157 void _updateStatus();
158 void _emitChanges();
159 void _setPositioningError(QGeoPositionInfoSource::Error error);
160 std::optional<GPSObservation> _accepted(
162 std::optional<std::chrono::milliseconds> maximumAge = std::nullopt) const;
163 void _setupPositionSources();
164 void _handlePermissionStatus(Qt::PermissionStatus permissionStatus);
165 void _checkPermission();
166
167 RuntimeScheduler* const _scheduler;
168 ScheduledTask _recoveryTask;
169 std::optional<qint64> _receiverUsableSinceMs;
170
171 QPointer<GPSSourceHealth> _receiver;
172 quint64 _receiverSession = 0;
173 quint64 _receiverToken = 0;
174
175 QPointer<QGeoPositionInfoSource> _device;
176 GPSSourceHealth* const _deviceHealth;
177 bool _deviceActive = false;
178 bool _usingPluginSource = false;
179 GPSAltitudeDatum _deviceAltitudeDatum = GPSAltitudeDatum::Unknown;
180 SourceStatus _platformStatus = SourceStatus::NoSource;
181
182 Configuration _configuration;
184 QPointer<GPSSourceHealth> _currentHealth;
185 bool _reselect = false;
186 quint64 _selectionRevision = 0;
187 bool _authorized = false;
188
189 SelectedSource _selectedSource = SelectedSource::None;
190 SourceStatus _sourceStatus = SourceStatus::NoSource;
191 QGeoPositionInfoSource::Error _gcsPositioningError = QGeoPositionInfoSource::NoError;
192 Publication _published;
193
194 struct Notified
195 {
203
204 Publication publication;
205 } _notified;
206
207 SourceFactory _platformSourceFactory;
208 bool _shutdown = false;
209};
GPSAltitudeDatum
std::shared_ptr< const void > GPSPositionSourceRegistration
Error error
Session health is independent of transport readiness and RTK survey-in validity.
void setInternalPositionSource(QGeoPositionInfoSource *source, SourceStatus status, bool custom=false, GPSAltitudeDatum altitudeDatum=GPSAltitudeDatum::Unknown)
QString sourceStatusText() const
qreal gcsPositionHorizontalAccuracy() const
qreal gcsHeading() const
~PositionManager() override
void gcsPositionChanged(QGeoCoordinate gcsPosition)
void gcsPositionHorizontalAccuracyChanged(qreal gcsPositionHorizontalAccuracy)
void shutdown()
Releases the position sources and ignores later configuration; init() does not restart them.
std::optional< GPSObservation > acceptedObservation(GPSObservation::PositionUse use=GPSObservation::PositionUse::GroundStation, std::optional< std::chrono::milliseconds > maximumAge=std::nullopt) const
void selectionChanged()
void setConfiguration(const Configuration &configuration)
Ignored after shutdown().
SourceStatus sourceStatus() const
SelectedSource selectedSource() const
static constexpr std::chrono::milliseconds RECOVERY_DELAY
SourceMode
Values of RTKSettings::gcsPositionSource.
friend class PositionManagerTest
void gcsHeadingChanged(qreal gcsHeading)
GPSPositionSourceRegistration registerReceiver(GPSSourceHealth *producer, quint64 sessionId=0)
std::function< QGeoPositionInfoSource *(QObject *parent)> SourceFactory
Creates a position source parented to parent, or returns null.
QGeoPositionInfoSource::Error gcsPositioningError() const
QGeoCoordinate gcsPosition() const
const Configuration & configuration() const
void setPlatformSourceFactory(SourceFactory factory)
QString selectedSourceName() const
bool operator==(const Configuration &) const =default
bool operator==(const Selection &) const =default