QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GPSReceiverFactGroup.cc
Go to the documentation of this file.
2
3#include <cmath>
4#include <limits>
5#include <utility>
6
7#include "GPSReceiverConfig.h"
8
9GPSReceiverFactGroup::GPSReceiverFactGroup(QObject* parent)
10 : FactGroup(1000, QStringLiteral(":/json/GPS/GPSReceiverFact.json"), parent)
11{
12 _addFact(&_currentDurationFact);
13 _addFact(&_currentAccuracyFact);
14 _addFact(&_validFact);
15 _addFact(&_activeFact);
16 _addFact(&_numSatellitesFact);
17 _addFact(&_numSatellitesUsedFact);
18 _addFact(&_fixTypeFact);
19 _addFact(&_jammingStateFact);
20 _addFact(&_spoofingStateFact);
21 _addFact(&_antennaStateFact);
22
23 for (Fact* fact : {&_jammingStateFact, &_spoofingStateFact, &_antennaStateFact}) {
24 connect(fact, &Fact::rawValueChanged, this, &GPSReceiverFactGroup::_updateReceiverWarning);
25 }
26 _reset();
27}
28
29void GPSReceiverFactGroup::_update(Fact& fact, const QVariant& value)
30{
31 // Unavailable values stay NaN; rewriting NaN would report a change, as NaN never equals itself.
32 if (!std::isnan(value.toDouble()) || !std::isnan(fact.rawValue().toDouble())) {
33 fact.setRawValue(value);
34 }
35}
36
37void GPSReceiverFactGroup::_restoreDefaults(std::initializer_list<Fact*> facts)
38{
39 for (Fact* fact : facts) {
40 _update(*fact, fact->rawDefaultValue());
41 }
42}
43
44void GPSReceiverFactGroup::_setSurvey(const GPSSurveyReport& report)
45{
46 const double accuracy = report.meanAccuracyMeters.value_or(qQNaN());
47 _update(_currentDurationFact, static_cast<qint64>(report.duration.count()));
48 _update(_currentAccuracyFact, accuracy);
49 _update(_validFact, report.valid);
50 _update(_activeFact, report.active);
51 if (report.active) {
52 _setCurrentBasePositionSaved(false);
53 }
54 std::optional<GPSBaseStationConfig::Fixed> base;
55 if (report.valid && std::isfinite(accuracy) && accuracy >= 0 && accuracy <= (std::numeric_limits<float>::max)()) {
56 const GPSBaseStationConfig::Fixed fixed{.position = report.position,
57 .accuracyMeters = static_cast<float>(accuracy)};
59 base = fixed;
60 }
61 }
62 _setCurrentBasePosition(base);
63}
64
65void GPSReceiverFactGroup::_setSatellites(int inView, int used)
66{
67 _update(_numSatellitesFact, inView);
68 _update(_numSatellitesUsedFact, used);
69}
70
71void GPSReceiverFactGroup::_setSolution(GPSFixQuality fixType, const GPSIntegrityReport& integrity)
72{
73 _update(_fixTypeFact, static_cast<int>(fixType));
74 _update(_jammingStateFact, static_cast<int>(integrity.jamming.state));
75 _update(_spoofingStateFact, static_cast<int>(integrity.spoofing.state));
76 _update(_antennaStateFact, static_cast<int>(integrity.antenna.state));
77}
78
79void GPSReceiverFactGroup::_clearSolution()
80{
81 _restoreDefaults({&_numSatellitesFact, &_numSatellitesUsedFact, &_fixTypeFact, &_jammingStateFact,
82 &_spoofingStateFact, &_antennaStateFact});
83}
84
85void GPSReceiverFactGroup::_reset()
86{
87 _restoreDefaults({&_currentDurationFact, &_currentAccuracyFact, &_validFact, &_activeFact, &_numSatellitesFact,
88 &_numSatellitesUsedFact, &_fixTypeFact, &_jammingStateFact, &_spoofingStateFact,
89 &_antennaStateFact});
90 _setCurrentBasePosition(std::nullopt);
92}
93
94void GPSReceiverFactGroup::_updateReceiverWarning()
95{
96 using JammingState = GPSIntegrityReport::JammingState;
97 using SpoofingState = GPSIntegrityReport::SpoofingState;
98 using AntennaState = GPSIntegrityReport::AntennaState;
99 const int jamming = _jammingStateFact.rawValue().toInt();
100 const int spoofing = _spoofingStateFact.rawValue().toInt();
101 const int antenna = _antennaStateFact.rawValue().toInt();
102 const bool warning =
103 jamming == static_cast<int>(JammingState::Warning) || jamming == static_cast<int>(JammingState::Critical) ||
104 spoofing == static_cast<int>(SpoofingState::Indicated) ||
105 spoofing == static_cast<int>(SpoofingState::Multiple) || antenna == static_cast<int>(AntennaState::Open) ||
106 antenna == static_cast<int>(AntennaState::Short);
107 if (std::exchange(_receiverWarning, warning) != warning) {
109 }
110}
111
112void GPSReceiverFactGroup::_setCurrentBasePosition(const std::optional<GPSBaseStationConfig::Fixed>& base)
113{
114 const bool couldSave = canSaveCurrentBasePosition();
115 _currentBasePosition = base;
116 if (!base) {
117 _setCurrentBasePositionSaved(false);
118 }
119 if (canSaveCurrentBasePosition() != couldSave) {
121 }
122}
123
124void GPSReceiverFactGroup::_setCurrentBasePositionSaved(bool saved)
125{
126 if (std::exchange(_currentBasePositionSaved, saved) != saved) {
128 }
129}
GPSReceiverConfigError gpsValidateBaseStationConfig(const GPSBaseStationConfig &config)
Check the selected base mode against the existing receiver wire-unit limits.
Used to group Facts together into an object hierarachy.
Definition FactGroup.h:16
void _setTelemetryAvailable(bool telemetryAvailable)
Definition FactGroup.cc:175
A Fact is used to hold a single value within the system.
Definition Fact.h:15
QVariant rawDefaultValue() const
Definition Fact.cc:494
void rawValueChanged(const QVariant &value)
void setRawValue(const QVariant &value)
Definition Fact.cc:135
QVariant rawValue() const
Definition Fact.h:87
bool canSaveCurrentBasePosition() const
void currentBasePositionChanged()
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
GPSEllipsoidPosition position
AntennaState
Ordered by severity, so the worst of several reports is the greatest.
GPSEllipsoidPosition position
std::optional< double > meanAccuracyMeters
std::chrono::seconds duration