QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GPSReceiverConfig.cc
Go to the documentation of this file.
1#include "GPSReceiverConfig.h"
2
3#include <cmath>
4#include <limits>
5
6#include <QtCore/QCoreApplication>
7
8#include "GPSProtocolMath.h"
10
12{
13 if (const auto* averaging = std::get_if<GPSBaseStationConfig::ReceiverAveraging>(&config.mode)) {
14 if (averaging->maximumDuration < std::chrono::seconds{1} ||
15 averaging->maximumDuration > std::chrono::hours{1}) {
17 }
19 }
20 if (const auto* fixed = std::get_if<GPSBaseStationConfig::Fixed>(&config.mode)) {
21 const auto& position = fixed->position;
22 const double altitudeCm = position.altitudeMeters * 100.0;
23 if (!std::isfinite(position.latitudeDegrees) || std::abs(position.latitudeDegrees) > 90.0 ||
24 !std::isfinite(position.longitudeDegrees) || std::abs(position.longitudeDegrees) > 180.0 ||
25 !std::isfinite(altitudeCm) || altitudeCm < (std::numeric_limits<int32_t>::min)() ||
26 altitudeCm > (std::numeric_limits<int32_t>::max)() ||
27 !GPSProtocolMath::tenthMillimeters(fixed->accuracyMeters)) {
29 }
30 } else {
31 const auto& survey = std::get<GPSBaseStationConfig::SurveyIn>(config.mode);
32 const auto accuracyUnits = GPSProtocolMath::tenthMillimeters(survey.accuracyMeters);
33 if (!accuracyUnits || *accuracyUnits < 1 || survey.duration < std::chrono::seconds{1} ||
34 survey.duration > std::chrono::seconds((std::numeric_limits<uint32_t>::max)())) {
36 }
37 }
39}
40
41namespace {
42
44GPSReceiverConfigError validateOptions(const GPSReceiverConfig& config, const GPSReceiverCapabilities& capabilities,
45 bool passive)
46{
47 if (config.allowPersistentChanges && !capabilities.persistentConfiguration) {
49 }
50 if (!passive) {
51 if ((std::holds_alternative<GPSBaseStationConfig::ReceiverAveraging>(config.base.mode) &&
52 !capabilities.receiverAveraging) ||
53 (std::holds_alternative<GPSBaseStationConfig::SurveyIn>(config.base.mode) && !capabilities.surveyIn)) {
55 }
56 if (config.base.compactObservations && !capabilities.compactObservations) {
58 }
61 return error;
62 }
63 }
64 if (passive && config.base != GPSBaseStationConfig{}) {
66 }
67 if (!gpsValidBaudRate(config.baudRate, passive)) {
69 }
71}
72
73} // namespace
74
76{
77 const GPSReceiverCapabilities capabilities = gpsReceiverCapabilities(type);
78 if (!capabilities.recognized) {
80 }
81 return validateOptions(config, capabilities, type == GPSType::passive);
82}
83
85{
86 switch (error) {
88 return {};
90 return QCoreApplication::translate("GPSReceiverConfig", "Unsupported GPS receiver type");
92 return QCoreApplication::translate("GPSReceiverConfig", "Enter a valid fixed base position and accuracy");
94 return QCoreApplication::translate("GPSReceiverConfig", "Enter a valid survey-in accuracy and duration");
96 return QCoreApplication::translate("GPSReceiverConfig",
97 "This receiver does not support the selected base mode");
99 return QCoreApplication::translate("GPSReceiverConfig",
100 "Enter a receiver averaging duration between 1 and 3600 seconds");
102 return QCoreApplication::translate(
103 "GPSReceiverConfig", "Select a valid serial baud rate; passive input requires an explicit rate");
105 return QCoreApplication::translate("GPSReceiverConfig",
106 "This driver does not support persistent receiver configuration");
108 return QCoreApplication::translate("GPSReceiverConfig",
109 "This receiver cannot send compact (MSM4) RTCM corrections");
110 }
111 return QCoreApplication::translate("GPSReceiverConfig", "Invalid GPS receiver configuration");
112}
113
118
120{
121 const GPSReceiverCapabilities capabilities = gpsReceiverCapabilities(detected);
122 config.allowPersistentChanges = config.allowPersistentChanges && capabilities.persistentConfiguration;
123 const bool fallback = config.base.compactObservations && !capabilities.compactObservations;
124 if (fallback) {
125 config.base.compactObservations = false;
126 }
127 if (compactFallback) {
128 *compactFallback = fallback;
129 }
130 return config;
131}
132
134{
137 return {};
138 }
139 const QString name = gpsReceiverName(detected);
140 const QString receiver = name.isEmpty() ? QCoreApplication::translate("GPSReceiverConfig", "unknown") : name;
142 const QString mode = std::holds_alternative<GPSBaseStationConfig::ReceiverAveraging>(config.base.mode)
143 ? QCoreApplication::translate("GPSReceiverConfig", "receiver-managed averaging")
144 : std::holds_alternative<GPSBaseStationConfig::SurveyIn>(config.base.mode)
145 ? QCoreApplication::translate("GPSReceiverConfig", "survey-in")
146 : QCoreApplication::translate("GPSReceiverConfig", "a fixed base position");
147 //: %1 is a receiver manufacturer, such as Septentrio; %2 is a base mode, such as survey-in
148 return QCoreApplication::translate("GPSReceiverConfig", "Detected %1 receiver does not support %2")
149 .arg(receiver, mode);
150 }
151 //: %1 is a receiver manufacturer; %2 explains the unsupported request
152 return QCoreApplication::translate("GPSReceiverConfig", "Detected %1 receiver: %2")
153 .arg(receiver, gpsReceiverConfigErrorText(error));
154}
GPSReceiverConfig gpsReceiverConfigForDetected(GPSType detected, GPSReceiverConfig config, bool *compactFallback)
GPSReceiverConfigError gpsValidateBaseStationConfig(const GPSBaseStationConfig &config)
Check the selected base mode against the existing receiver wire-unit limits.
GPSReceiverConfigError gpsValidateReceiverConfig(GPSType type, const GPSReceiverConfig &config)
Precedence: recognized receiver, persistent permission, base mode, baud rate.
QString gpsDetectedReceiverConfigError(GPSType detected, const GPSReceiverConfig &config)
QString gpsReceiverConfigErrorText(GPSReceiverConfigError error)
Translated diagnostic; empty for GPSReceiverConfigError::None.
QString gpsReceiverConfigError(GPSType type, const GPSReceiverConfig &config)
An empty diagnostic means the receiver supports the role and all supplied settings.
GPSReceiverConfigError
constexpr bool gpsValidBaudRate(uint32_t baudRate, bool passive)
GPSReceiverCapabilities gpsReceiverCapabilities(GPSType type)
What type supports, for either role; unknown receiver families support nothing.
QString gpsReceiverName(GPSType type)
The name of type's receiver family as shown to users; empty when no descriptor exists.
Config config
Error error
std::optional< uint32_t > tenthMillimeters(double meters)
meters in 0.1 mm, truncated toward zero. Empty when not finite, negative or beyond a 32-bit unsigned ...
Configuration used only by the RTK base-station role.
Software request support, not a guarantee for every physical receiver model or firmware.