QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GPSDecodedData.cc
Go to the documentation of this file.
1#include "GPSDecodedData.h"
2
3#include <algorithm>
4#include <cmath>
5
6#include "MonotonicClock.h"
7
8namespace GPSDecodedData {
9
10GPSPositionReport position(const GPSDecodedPosition& source, const GPSIntegrityReport& diagnostic, uint64_t nowUs)
11{
12 GPSPositionReport result{.navigation = source.navigation, .integrity = diagnostic};
13 auto& navigation = result.navigation;
14 navigation.fixType = gpsFixQualityFromValue(static_cast<int>(navigation.fixType));
15 if (!source.velocityValid) {
16 navigation.speedMetersPerSecond = NAN;
17 navigation.courseRadians = NAN;
18 }
19 auto& integrity = result.integrity;
20 integrity.jamming.state = GPSIntegrityReport::jammingStateFromValue(static_cast<int>(diagnostic.jamming.state));
21 integrity.spoofing.state = GPSIntegrityReport::spoofingStateFromValue(static_cast<int>(diagnostic.spoofing.state));
22 // Navigation epochs retain their first receipt; diagnostics may arrive before that epoch is published.
23 integrity = integrity.freshAt(nowUs ? nowUs : std::max(navigation.timestampUs, diagnostic.timestampUs));
24 return result;
25}
26
28{
29 if (source.fullSnapshot) {
30 for (auto& [constellation, counts] : _constellations) {
31 counts = {};
32 }
33 }
35 const auto reported =
36 std::span(source.constellations).first(std::min<size_t>(source.count, source.constellations.size()));
37 for (const auto& native : reported) {
38 auto& counts = _constellations[native.constellation];
39 _accept(counts.inView, native.inViewTimestampUs, std::clamp(native.inView, 0, LIMIT), nowUs);
40 _accept(counts.used, native.inUseTimestampUs,
41 native.inUse ? std::optional<int>(std::clamp(*native.inUse, 0, LIMIT)) : std::nullopt, nowUs);
42 }
43 (void) _expire(nowUs);
44 return _report(false);
45}
46
48{
49 _countOnlyUsed = source.usedCount;
50 (void) _expire(nowUs);
51 return _report(true);
52}
53
54std::optional<GPSSatelliteReport> SatelliteCounts::expire(uint64_t nowUs)
55{
56 if (!_expire(nowUs)) {
57 return std::nullopt;
58 }
59 return _report(false);
60}
61
62void SatelliteCounts::_accept(Count& count, uint64_t receivedAtUs, std::optional<int> value, uint64_t nowUs)
63{
64 if (receivedAtUs >= count.receivedAtUs &&
66 count = {receivedAtUs, value};
67 }
68}
69
70bool SatelliteCounts::_expire(uint64_t nowUs)
71{
72 bool expired = false;
73 for (auto& [constellation, counts] : _constellations) {
74 for (Count* count : {&counts.inView, &counts.used}) {
75 if (count->receivedAtUs &&
76 !MonotonicClock::fresh(count->receivedAtUs, nowUs, SatelliteCounts::FRESHNESS_TIMEOUT)) {
77 *count = {};
78 expired = true;
79 }
80 }
81 }
82 return expired;
83}
84
85GPSSatelliteReport SatelliteCounts::_report(bool countOnlyUsed) const
86{
87 GPSSatelliteReport report;
88 int inView = 0;
89 int used = 0;
90 bool usedKnown = true;
91 for (const auto& [constellation, counts] : _constellations) {
92 if (!counts.inView.receivedAtUs) {
93 continue;
94 }
95 report.timestampUs = std::max(report.timestampUs, counts.inView.receivedAtUs);
96 const int visible = counts.inView.value.value_or(0);
97 inView += visible;
98 if (visible == 0) {
99 continue;
100 }
101 if (counts.used.receivedAtUs && counts.used.value) {
102 used += *counts.used.value;
103 } else {
104 usedKnown = false;
105 }
106 }
107 std::optional<int> viewUsed;
108 if (report.timestampUs) {
109 report.inView = inView;
110 if (inView == 0) {
111 viewUsed = 0;
112 } else if (usedKnown) {
113 viewUsed = used;
114 }
115 }
116 report.used = countOnlyUsed || !viewUsed ? _countOnlyUsed : viewUsed;
117 return report;
118}
119} // namespace GPSDecodedData
constexpr GPSFixQuality gpsFixQualityFromValue(int value)
GPSSatelliteReport update(const GPSDecodedSatellites &source, uint64_t nowUs)
std::optional< GPSSatelliteReport > expire(uint64_t nowUs)
static constexpr std::chrono::milliseconds FRESHNESS_TIMEOUT
How GPSDriver adapts decoded events to public reports.
GPSPositionReport position(const GPSDecodedPosition &source, const GPSIntegrityReport &diagnostic, uint64_t nowUs)
constexpr bool fresh(uint64_t timestampUs, uint64_t nowUs, std::chrono::microseconds lifetime)
Whether a receipt is younger than lifetime.
Decoded navigation plus whether the producer accepted its velocity solution.
GPSNavigationValues navigation
std::optional< int > usedCount
static constexpr uint16_t SAT_INFO_MAX_SATELLITES
std::array< Constellation, MAX_CONSTELLATIONS > constellations
static constexpr SpoofingState spoofingStateFromValue(int value)
static constexpr JammingState jammingStateFromValue(int value)
GPSNavigationValues navigation
std::optional< int > used
std::optional< int > inView