QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GPSReceiver.h
Go to the documentation of this file.
1#pragma once
2
3#include <chrono>
4#include <functional>
5#include <memory>
6#include <optional>
7
8#include <QtCore/QHash>
9#include <QtCore/QList>
10#include <QtCore/QObject>
11#include <QtCore/QPointer>
12#include <QtCore/QString>
13#include <QtQmlIntegration/QtQmlIntegration>
14
15#include "GPSObservation.h"
18#include "GPSReceiverReports.h"
19#include "ScheduledTask.h"
20
25class GPSSourceHealth;
26class PositionManager;
29
32{
37#ifndef QGC_NO_SERIAL_LINK
41#endif
42};
43
46{
47 Q_GADGET
48 QML_VALUE_TYPE(gpsSerialPortEntry)
49 QML_STRUCTURED_VALUE
50 Q_PROPERTY(QString value MEMBER value FINAL)
51 Q_PROPERTY(QString label MEMBER label FINAL)
52
53public:
55 QString value;
57 QString label;
58
59 bool operator==(const GPSSerialPortEntry&) const = default;
60};
61
66class GPSReceiver : public QObject, private GPSReceiverConnector
67{
68 Q_OBJECT
69 QML_ELEMENT
70 QML_UNCREATABLE("Managed by GPSManager")
71 Q_MOC_INCLUDE("GPSReceiverFactGroup.h")
72
73 Q_PROPERTY(GPSReceiverFactGroup* facts READ facts CONSTANT FINAL)
74 Q_PROPERTY(QList<GPSSerialPortEntry> serialPortEntries READ serialPortEntries NOTIFY serialPortEntriesChanged FINAL)
75 Q_PROPERTY(QList<int> serialBaudRates READ serialBaudRates CONSTANT FINAL)
76 Q_PROPERTY(bool hasReceiver READ hasReceiver NOTIFY receiverChanged FINAL)
77 Q_PROPERTY(bool serialSupported READ serialSupported CONSTANT FINAL)
78 Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged FINAL)
79 Q_PROPERTY(int activeBaseMode READ activeBaseMode NOTIFY receiverChanged FINAL)
80 Q_PROPERTY(QString activeEndpoint READ activeEndpoint NOTIFY receiverChanged FINAL)
81 Q_PROPERTY(QString receiverIdentity READ receiverIdentity NOTIFY receiverChanged FINAL)
82 Q_PROPERTY(QString detectedReceiver READ detectedReceiver NOTIFY receiverChanged FINAL)
83 Q_PROPERTY(bool reconnecting READ reconnecting NOTIFY receiverChanged FINAL)
87 Q_PROPERTY(bool forwardingCorrections READ forwardingCorrections NOTIFY receiverChanged FINAL)
93 Q_PROPERTY(bool connectionSupported READ connectionSupported NOTIFY configurationChanged FINAL)
95 Q_PROPERTY(QString summaryLabel READ summaryLabel NOTIFY summaryLabelChanged FINAL)
97 Q_PROPERTY(QString statusText READ statusText NOTIFY statusTextChanged FINAL)
99 Q_PROPERTY(bool baseModeSupported READ baseModeSupported NOTIFY configurationChanged FINAL)
101 Q_PROPERTY(bool canConnect READ canConnect NOTIFY configurationChanged FINAL)
102
103 friend class GPSReceiverTest;
106
107public:
110
112 static constexpr std::chrono::seconds POLL_INTERVAL{1};
114 static constexpr std::chrono::seconds OUTPUT_OVERFLOW_WARNING_DURATION{30};
116 static constexpr std::chrono::seconds SHUTDOWN_TIMEOUT{2};
117
119
120 explicit GPSReceiver(QObject* parent = nullptr, RuntimeScheduler* scheduler = nullptr,
121 const Dependencies& dependencies = {});
122 ~GPSReceiver();
123
126 void setWorkerFactory(WorkerFactory factory);
127
128 const Configuration& configuration() const { return _configuration; }
129
132 QList<GPSSerialPortEntry> serialPortEntries() const { return _serialPortEntries; }
133
135 static QList<int> serialBaudRates();
136
138 std::optional<GPSObservation> acceptedPositionObservation(GPSObservation::PositionUse use) const;
141 Q_INVOKABLE bool connectReceiver();
143 Q_INVOKABLE void disconnectReceiver();
145 void startConnectionPolling(std::function<bool()> suspended = {});
147 void tick();
150 void shutdown();
151
153 GPSReceiverFactGroup* facts() const { return _facts; }
154
155 bool hasReceiver() const override;
156
157 bool serialSupported() const
158 {
159#ifdef QGC_NO_SERIAL_LINK
160 return false;
161#else
162 return true;
163#endif
164 }
165
167 QString errorMessage() const;
168
169 int activeBaseMode() const;
170
172 QString activeEndpoint() const;
173
174 QString receiverIdentity() const;
175
178 QString detectedReceiver() const;
179
180 QString summaryLabel() const { return _summaryLabel; }
181
182 QString statusText() const { return _statusText; }
183
185 bool reconnecting() const;
186
188 Q_INVOKABLE GPSReceiverPresentation capabilitiesFor(int role, int manufacturer) const;
189
192
194
195 bool forwardingCorrections() const;
196
197 bool persistentChangesAllowed() const { return _persistentChangesAllowed; }
198
200 void setPersistentChangesAllowed(bool allowed);
201
203
205 bool connectionSupported() const;
206
207 bool baseModeSupported() const;
208
209 bool canConnect() const;
210
211signals:
219
220private slots:
221 void _onSatelliteInfoUpdated(const GPSSatelliteReport& msg);
222 void _onPositionUpdated(const GPSPositionReport& report);
223 void _onGPSConnect();
224 void _onReceiverDetected();
225 void _onInputProblem(GPSInputProblem problem);
226 void _onGPSSurveyReport(const GPSSurveyReport& status);
227
228private:
230 struct ReceiverState
231 {
232 bool hasReceiver = false;
233 int baseMode = -1;
234 QString endpoint;
235 QString identity;
236 QString detected;
237 bool reconnecting = false;
238 GPSReceiverPresentation presentation;
240 bool forwardingCorrections = false;
241 bool operator==(const ReceiverState&) const = default;
242 };
243
245 struct Notified
246 {
247 quint64 configurationRevision = 0;
248 bool persistentChangesAllowed = false;
249 QString errorMessage;
250 ReceiverState receiver;
251 };
252
253 int _activeManufacturer() const;
254
255 void setConnectionError(const QString& message) override { _setError(message); }
256
257 void endConnection(bool clearError) override;
258 bool connectTcp(const QString& host, quint16 port, GPSType type, bool allowPersistentChanges) override;
259 bool connectUdp(quint16 port, GPSType type) override;
260#ifndef QGC_NO_SERIAL_LINK
261 bool connectSerial(const QString& device, GPSType type, uint32_t baudRate, bool allowPersistentChanges,
262 GPSSerialClaim claim) override;
263 bool serialPortAvailable(const QString& device) const override;
264 QStringList rtkReceiverPorts() const override;
265 GPSSerialClaim claimSerialPort(const QString& device) override;
267 void _onSerialPortsEnumerated(const QStringList& devices);
268 void _updateSerialPortEntries();
269#endif
270
271 bool _connectReceiver(GPSType type, GPSReceiverWorker::TransportFactory transportFactory,
272 const QString& sourceInstance, uint32_t baudRate, bool allowPersistentChanges,
273 const QString& serialDevice = {}, const QString& endpoint = {});
274 void _endSession(GPSConnectionError error, const QString& detail, bool portRemoved);
276 void _retireSession();
278 void _joinRetiredWorkers();
279
280 void _setError(const QString& message = {}) { _errorMessage = message; }
281
283 void _updateOutputOverflow(uint64_t receiptUs);
284 void _setPersistentChangesAllowed(bool allowed);
285 void _resetStatus();
286 void _updateLabels();
288 void _clearStaleSolution();
289 ReceiverState _receiverState() const;
291 void _emitChanges();
292
293 Configuration _configuration;
294 GPSReceiverSession* _session = nullptr;
296 QList<QPointer<GPSReceiverWorker>> _retiredWorkers;
297 const QPointer<GPSCorrectionManager> _correctionManager;
298 const QPointer<PositionManager> _positionManager;
299 RuntimeScheduler* const _scheduler;
300 GPSSourceHealth* const _positionHealth;
301 ScheduledTask _outputOverflowTask;
302 ScheduledTask _pollTask;
303 quint64 _sessionCount = 0;
304 QString _errorMessage;
305 QString _summaryLabel;
306 QString _statusText;
307 QString _outputOverflowWarning;
308 uint64_t _outputOverflowUs = 0;
309 std::unique_ptr<GPSReceiverConnectionPolicy> _connection;
310 GPSReceiverFactGroup* _facts = nullptr;
311 WorkerFactory _workerFactory;
312 quint64 _configurationRevision = 0;
313 Notified _notified;
314 bool _destroying = false;
315 bool _persistentChangesAllowed = false;
316 QList<GPSSerialPortEntry> _serialPortEntries;
317#ifndef QGC_NO_SERIAL_LINK
318 const QPointer<SerialPortManager> _serialPorts;
321 QHash<QString, std::weak_ptr<const SerialPortManager::Reservation>> _serialClaims;
322 std::function<std::unique_ptr<GPSTransport>(const QString&, GPSCancelToken)> _serialTransportFactory;
323#endif
324};
std::function< GPSReceiverWorker *(GPSReceiverWorker::TransportFactory, GPSType, const GPSReceiverConfig &, QObject *)> GPSReceiverWorkerFactory
Creates a receiver session's worker; tests inject scripted workers.
SerialPortManager::ReservationPtr GPSSerialClaim
Holds a serial device for one receiver session until the last copy is released.
Error error
std::function< std::unique_ptr< GPSTransport >(GPSCancelToken)> TransportFactory
Consumed on the worker thread, so transport construction, I/O and destruction share that thread.
void summaryLabelChanged()
friend class GPSReceiverConnectionPolicyTest
static constexpr std::chrono::seconds POLL_INTERVAL
How often connection polling ticks the receiver.
void startConnectionPolling(std::function< bool()> suspended={})
Runs tick() every POLL_INTERVAL until shutdown(), skipping ticks while suspended returns true.
RTKSettings::ConnectionType effectiveConnectionType() const
QString detectedReceiver() const
bool persistentChangesAllowed() const
friend class GPSReceiverSettingsBindingTest
static QList< int > serialBaudRates()
The application's serial rates that a receiver accepts as an explicit rate; empty without serial link...
const Configuration & configuration() const
void receiverChanged()
RTKSettings::ReceiverRole activeRole() const
bool connectionSupported() const
UDP only receives, so a receiver QGroundControl configures needs serial or TCP.
QString statusText() const
QString activeEndpoint() const
Serial device or TCP host:port of the active receiver.
void configurationChanged()
Q_INVOKABLE GPSReceiverPresentation capabilitiesFor(int role, int manufacturer) const
Editable settings for a role; configured bases also depend on the manufacturer.
bool hasReceiver() const override
void persistentChangesAllowedChanged()
void serialPortEntriesChanged()
bool forwardingCorrections() const
friend class GPSReceiverTest
The active receiver's RTCM output is a correction source.
GPSReceiverWorkerFactory WorkerFactory
void shutdown()
QList< GPSSerialPortEntry > serialPortEntries() const
static constexpr std::chrono::seconds SHUTDOWN_TIMEOUT
How long shutdown() waits for the workers of retired sessions.
int activeBaseMode() const
GPSReceiverFactGroup * facts() const
The receiver's reported state; with no receiver, every Fact is at its metadata default.
bool reconnecting() const
The saved receiver is being connected automatically, at startup or after its connection was lost.
void setWorkerFactory(WorkerFactory factory)
Inject before connecting; an empty factory restores the real worker.
GPSReceiverPresentation activePresentation() const
Presentation capabilities of the connected receiver family.
QString summaryLabel() const
void statusTextChanged()
void errorMessageChanged()
static constexpr std::chrono::seconds OUTPUT_OVERFLOW_WARNING_DURATION
How long the warning about output the receiver dropped stays after the last report of it.
std::optional< GPSObservation > acceptedPositionObservation(GPSObservation::PositionUse use) const
Latest receiver solution that passes the consumer's gates; empty without a fresh fix.
QString errorMessage() const
The connection or input problem, else a recent report that the receiver dropped output.
GPSReceiverConfiguration Configuration
void setConfiguration(const Configuration &configuration)
bool serialSupported() const
Q_INVOKABLE bool connectReceiver()
void tick()
One step of automatic connection: connections due, reconnections, and USB discovery.
bool baseModeSupported() const
void setPersistentChangesAllowed(bool allowed)
Granting permission only lasts until the configuration changes, a session starts or ends,...
bool canConnect() const
Q_INVOKABLE void disconnectReceiver()
Disconnects and pauses automatic connection until the user connects again.
QString receiverIdentity() const
Session health is independent of transport readiness and RTK survey-in validity.
ConnectionType
Persisted values of connectionType. The storage type keeps any saved value a valid enum value.
Definition RTKSettings.h:44
ReceiverRole
Persisted values of receiverRole. The storage type keeps any saved value a valid enum value.
Definition RTKSettings.h:36
Shared serial inventory and exclusive claims. Called on the application thread.
GPSInputProblem
Why a receiver that stays connected while silent reports no position.
The receiver configuration the application's settings binding supplies as values.
RTKSettings::ConnectionType effectiveConnectionType() const
The connection this configuration uses; builds without serial links connect a serial selection over T...
Services a GPSReceiver uses, which must outlive it.
Definition GPSReceiver.h:32
SerialPortManager * serialPorts
Definition GPSReceiver.h:40
GPSCorrectionManager * corrections
Receives a forwarding receiver's RTCM output as the local correction source.
Definition GPSReceiver.h:34
PositionManager * positions
Ready receivers publish their solution here as the GCS "RTK receiver" position source.
Definition GPSReceiver.h:36
A serial device the receiver settings offer.
Definition GPSReceiver.h:46
QString value
The system location, which the device setting stores.
Definition GPSReceiver.h:55
QString label
What the picker shows.
Definition GPSReceiver.h:57
bool operator==(const GPSSerialPortEntry &) const =default