QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GPSSettingsBindings.cc
Go to the documentation of this file.
2
3#include <chrono>
4
5#include <QtCore/QSet>
6
7#include "Fact.h"
9#include "NTRIPSettings.h"
10#include "QGCLoggingCategory.h"
11#include "RTKSettings.h"
12
13QGC_LOGGING_CATEGORY(GPSSettingsBindingsLog, "GPS.GPSSettingsBindings")
14
15namespace {
16
17using CorrectionsConfig = GPSCorrectionManager::Configuration;
18using NTRIPConfig = NTRIPManager::Configuration;
19using ReceiverConfig = GPSReceiver::Configuration;
20using PositionConfig = PositionManager::Configuration;
21
23class FactReader
24{
25public:
26 QVariant operator()(Fact* fact)
27 {
28 _facts.append(fact);
29 return fact->rawValue();
30 }
31
32 const QList<Fact*>& facts() const { return _facts; }
33
34private:
35 QList<Fact*> _facts;
36};
37
38CorrectionsConfig correctionsFromSettings(GPSCorrectionSettings* settings, FactReader& read)
39{
40 CorrectionsConfig configuration;
41 const int source = read(settings->correctionSource()).toInt();
43 configuration.source = static_cast<GPSCorrectionSettings::CorrectionSource>(source);
44 } else {
45 qCWarning(GPSSettingsBindingsLog) << "Invalid correction source; using automatic selection";
46 }
47 configuration.udpInput.enabled = read(settings->rtcmUdpInputEnabled()).toBool();
48 configuration.udpInput.port = read(settings->rtcmUdpInputPort()).value<quint16>();
49 configuration.udpOutput.enabled = read(settings->rtcmUdpOutputEnabled()).toBool();
50 configuration.udpOutput.address = read(settings->rtcmUdpOutputAddress()).toString().trimmed();
51 configuration.udpOutput.port = read(settings->rtcmUdpOutputPort()).value<quint16>();
52 return configuration;
53}
54
55NTRIPConfig ntripFromSettings(NTRIPSettings* settings, FactReader& read)
56{
57 NTRIPConfig configuration;
58 configuration.enabled = read(settings->ntripServerConnectEnabled()).toBool();
59 NTRIPConnectionConfig& connection = configuration.connection;
60 connection.host = read(settings->ntripServerHostAddress()).toString();
61 connection.port = read(settings->ntripServerPort()).toInt();
62 connection.username = read(settings->ntripUsername()).toString();
63 connection.password = read(settings->ntripPassword()).toString();
64 connection.mountpoint = read(settings->ntripMountpoint()).toString();
65 connection.useTls = read(settings->ntripUseTls()).toBool();
66 connection.allowSelfSignedCerts = read(settings->ntripAllowSelfSignedCerts()).toBool();
67 connection.pinnedCertificate = read(settings->ntripPinnedCertificate()).toString();
68 configuration.filter.whitelist = read(settings->ntripWhitelist()).toString();
69 configuration.gga.source =
70 static_cast<NTRIPGgaReporter::PositionSource>(read(settings->ntripGgaPositionSource()).toInt());
71 configuration.gga.interval = std::chrono::seconds(read(settings->ntripGgaIntervalSec()).toUInt());
72 return configuration;
73}
74
76GPSBaseStationConfig baseStationFromSettings(RTKSettings* settings, FactReader& read)
77{
78 using Mode = BaseModeDefinition::Mode;
79 const auto mode = static_cast<Mode>(read(settings->useFixedBasePosition()).toInt());
81 .position = {.latitudeDegrees = read(settings->fixedBasePositionLatitude()).toDouble(),
82 .longitudeDegrees = read(settings->fixedBasePositionLongitude()).toDouble(),
83 .altitudeMeters = read(settings->fixedBasePositionAltitude()).toDouble()},
84 .accuracyMeters = read(settings->fixedBasePositionAccuracy()).toFloat()};
86 .accuracyMeters = read(settings->surveyInAccuracyLimit()).toDouble(),
87 .duration = std::chrono::seconds(read(settings->surveyInMinObservationDuration()).value<int64_t>())};
89 .maximumDuration = std::chrono::seconds(read(settings->receiverAveragingDuration()).value<uint32_t>())};
90
91 GPSBaseStationConfig base{.compactObservations = read(settings->compactRtcmCorrections()).toBool()};
92 switch (mode) {
93 case Mode::BaseFixed:
94 base.mode = fixed;
95 break;
96 case Mode::BaseReceiverAveraging:
97 base.mode = averaging;
98 break;
99 case Mode::BaseSurveyIn:
100 base.mode = surveyIn;
101 break;
102 default:
103 qCWarning(GPSSettingsBindingsLog) << "Invalid base mode; using survey-in";
104 base.mode = surveyIn;
105 break;
106 }
107 return base;
108}
109
110ReceiverConfig receiverFromSettings(RTKSettings* settings, FactReader& read)
111{
112 ReceiverConfig configuration;
113 configuration.receiverRole = static_cast<RTKSettings::ReceiverRole>(read(settings->receiverRole()).toInt());
114 configuration.forwardReceiverRtcm = read(settings->forwardReceiverRtcm()).toBool();
115 configuration.baseReceiverManufacturer = read(settings->baseReceiverManufacturers()).toInt();
116 configuration.connectionType = static_cast<RTKSettings::ConnectionType>(read(settings->connectionType()).toInt());
117 configuration.tcpHost = read(settings->tcpHost()).toString();
118 configuration.tcpPort = read(settings->tcpPort()).toUInt();
119 configuration.udpPort = read(settings->udpPort()).toUInt();
120 configuration.serialDevice = read(settings->serialDevice()).toString();
121 configuration.serialBaudRate = read(settings->serialBaudRate()).toUInt();
122 configuration.base = baseStationFromSettings(settings, read);
123 configuration.autoConnect = read(settings->autoConnect()).toBool();
124 return configuration;
125}
126
127PositionConfig positionFromSettings(RTKSettings* settings, FactReader& read)
128{
129 return {.sourceMode = static_cast<PositionManager::SourceMode>(read(settings->gcsPositionSource()).toInt())};
130}
131
133bool redacted(const Fact* fact)
134{
135 static const QSet<QString> names{
136 QString::fromLatin1(NTRIPSettings::ntripPasswordName),
137 QString::fromLatin1(RTKSettings::fixedBasePositionLatitudeName),
138 QString::fromLatin1(RTKSettings::fixedBasePositionLongitudeName),
139 QString::fromLatin1(RTKSettings::fixedBasePositionAltitudeName),
140 };
141 return names.contains(fact->name());
142}
143
144void logSetting(const Fact* fact)
145{
146 const QString value = fact->rawValue().toString();
147 const QString shown =
148 !redacted(fact) ? value : (value.isEmpty() ? QStringLiteral("<empty>") : QStringLiteral("<set>"));
149 qCDebug(GPSSettingsBindingsLog).noquote() << fact->name() << "=" << shown;
150}
151
152template <typename Settings, typename Configuration>
153QList<Fact*> readFacts(Settings* settings, Configuration (*build)(Settings*, FactReader&))
154{
155 FactReader reader;
156 (void) build(settings, reader);
157 return reader.facts();
158}
159
161template <typename Settings, typename Configuration, typename Target>
162void bind(Settings* settings, Configuration (*build)(Settings*, FactReader&), Target* target,
163 void (Target::*setter)(const Configuration&))
164{
165 const auto apply = [settings, build, target, setter]() {
166 FactReader reader;
167 (target->*setter)(build(settings, reader));
168 return reader.facts();
169 };
170 for (Fact* const fact : apply()) {
171 logSetting(fact);
172 QObject::connect(fact, &Fact::rawValueChanged, target, [apply, fact]() {
173 logSetting(fact);
174 (void) apply();
175 });
176 }
177}
178
179} // namespace
180
181QList<Fact*> GPSSettingsBindings::_boundFacts(GPSCorrectionSettings* settings)
182{
183 return readFacts(settings, correctionsFromSettings);
184}
185
186QList<Fact*> GPSSettingsBindings::_boundFacts(NTRIPSettings* settings)
187{
188 return readFacts(settings, ntripFromSettings);
189}
190
191QList<Fact*> GPSSettingsBindings::_boundFacts(RTKSettings* settings)
192{
193 return readFacts(settings, receiverFromSettings) + readFacts(settings, positionFromSettings);
194}
195
197{
198 if (!settings || !corrections) {
199 return;
200 }
201 bind(settings, correctionsFromSettings, corrections, &GPSCorrectionManager::setConfiguration);
202}
203
205{
206 if (!settings || !ntrip) {
207 return;
208 }
209 // Queued: the manager emits these inside its own operation (retrying, trusting a certificate), and storing the
210 // Fact applies a new configuration to it, which must wait until that returns.
211 QObject::connect(
212 ntrip, &NTRIPManager::enableRequested, ntrip,
213 [settings]() { settings->ntripServerConnectEnabled()->setRawValue(true); }, Qt::QueuedConnection);
214 QObject::connect(
216 [settings](const QString& pin) { settings->ntripPinnedCertificate()->setRawValue(pin); }, Qt::QueuedConnection);
217 bind(settings, ntripFromSettings, ntrip, &NTRIPManager::setConfiguration);
218}
219
221{
222 if (!settings || !receiver) {
223 return;
224 }
225 bind(settings, receiverFromSettings, receiver, &GPSReceiver::setConfiguration);
226}
227
229{
230 if (!settings || !positions) {
231 return;
232 }
233 bind(settings, positionFromSettings, positions, &PositionManager::setConfiguration);
234}
constexpr int GPS_CORRECTION_SOURCE_COUNT
#define QGC_LOGGING_CATEGORY(name, categoryStr)
A Fact is used to hold a single value within the system.
Definition Fact.h:15
void rawValueChanged(const QVariant &value)
QString name() const
Definition Fact.h:124
QVariant rawValue() const
Definition Fact.h:87
void setConfiguration(const Configuration &configuration)
Applies the parts that changed; ignored after shutdown().
CorrectionSource
Persisted values of correctionSource. The storage type keeps any saved value a valid enum value.
GPSReceiverConfiguration Configuration
void setConfiguration(const Configuration &configuration)
static void bindReceiver(RTKSettings *settings, GPSReceiver *receiver)
static void bindPosition(RTKSettings *settings, PositionManager *positions)
static void bindCorrections(GPSCorrectionSettings *settings, GPSCorrectionManager *corrections)
Applies the correction settings to corrections now and whenever they change.
static void bindNtrip(NTRIPSettings *settings, NTRIPManager *ntrip)
void setConfiguration(const Configuration &configuration)
void certificatePinChanged(const QString &pin)
The trusted self-signed caster certificate changed, or was forgotten (empty); the settings should sto...
void enableRequested()
Retrying after an error turns the saved connection on.
void setConfiguration(const Configuration &configuration)
Ignored after shutdown().
SourceMode
Values of RTKSettings::gcsPositionSource.
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
QByteArray read(int deviceId, int length, int timeout)
GPSCommandSequence base(QByteArrayView port, const GPSBaseStationConfig &base)
Streams RTCM3 corrections and the PVTGeodetic survey status over port in the mode base selects.
Definition SBFPlan.cc:49
ValsetBatch surveyIn(const GPSBaseStationConfig::SurveyIn &survey)
Definition UBXPlan.cc:166
GPSEllipsoidPosition position
std::chrono::seconds maximumDuration
Maximum receiver-managed time, not a minimum duration or an accuracy guarantee.
Configuration used only by the RTK base-station role.
The correction settings as values; the application's settings binding supplies them.
QString pinnedCertificate
"host:port|sha256-hex" of the self-signed certificate trusted on first use; other endpoints ignore it...
The NTRIP settings as values; the application's settings binding supplies them.