INSTINCT Code Coverage Report


Directory: src/
File: Navigation/GNSS/Core/SatelliteIdentifier.hpp
Date: 2025-11-25 23:34:18
Exec Total Coverage
Lines: 43 43 100.0%
Functions: 18 18 100.0%
Branches: 31 48 64.6%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 /// @file SatelliteIdentifier.hpp
10 /// @brief Structs identifying a unique satellite
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2022-04-29
13
14 #pragma once
15
16 #include <cstdint>
17 #include <string>
18 #include <vector>
19 #include <nlohmann/json.hpp>
20 using json = nlohmann::json; ///< json namespace
21 #include <fmt/format.h>
22
23 #include "SatelliteSystem.hpp"
24 #include "Frequency.hpp"
25 #include "Code.hpp"
26
27 #include "util/Container/STL.hpp"
28
29 namespace NAV
30 {
31
32 /// @brief Identifies a satellite (satellite system and number)
33 struct SatId
34 {
35 /// @brief Constructor
36 /// @param[in] satSys Satellite system
37 /// @param[in] satNum Number of the satellite
38 11521503 SatId(SatelliteSystem satSys, uint16_t satNum)
39 11521503 : satSys(satSys), satNum(satNum) {}
40
41 /// Default constructor
42 571742 SatId() = default;
43
44 /// @brief Constructor from String representation
45 /// @param[in] str SatId as string
46 364 explicit SatId(const std::string& str)
47
2/4
✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 364 times.
✗ Branch 6 not taken.
364 : satSys(SatelliteSystem::fromChar(str.substr(0, 1).front())),
48
2/4
✓ Branch 1 taken 364 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 364 times.
✗ Branch 5 not taken.
364 satNum(static_cast<uint16_t>(std::stoul(str.substr(1)))) {}
49
50 SatelliteSystem satSys = SatSys_None; ///< Satellite system (GPS, GLONASS, GALILEO, QZSS, BDS, IRNSS, SBAS)
51 uint16_t satNum = 0; ///< Number of the satellite
52
53 /// @brief Equal comparison (needed for unordered_map)
54 /// @param[in] rhs Right hand side of the operator
55 /// @return True if the elements are equal
56
4/4
✓ Branch 1 taken 15952485 times.
✓ Branch 2 taken 32575256 times.
✓ Branch 3 taken 4247293 times.
✓ Branch 4 taken 11705192 times.
48510418 constexpr bool operator==(const SatId& rhs) const { return satSys == rhs.satSys && satNum == rhs.satNum; }
57
58 /// @brief Less than comparison (needed for map)
59 /// @param[in] rhs Right hand side of the operator
60 /// @return True if lhs < rhs
61 856711 constexpr bool operator<(const SatId& rhs) const
62 {
63
2/2
✓ Branch 1 taken 571185 times.
✓ Branch 2 taken 285526 times.
856711 return satSys == rhs.satSys ? satNum < rhs.satNum
64 856711 : satSys < rhs.satSys;
65 }
66
67 /// Checks if the satellite is geostationary
68 [[nodiscard]] bool isGeo() const;
69 };
70
71 /// @brief Identifies a satellite signal (satellite frequency and number)
72 struct SatSigId
73 {
74 /// @brief Constructor
75 /// @param[in] code Signal code
76 /// @param[in] satNum Number of the satellite
77 228226844 SatSigId(Code code, uint16_t satNum)
78 228226844 : code(code), satNum(satNum) {}
79
80 /// Default constructor
81 177785 SatSigId() = default;
82
83 /// @brief Constructor from String representation
84 /// @param[in] str SatSigId as string
85 14 explicit SatSigId(const std::string& str)
86
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 : code(str.substr(0, 3)),
87
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 satNum(static_cast<uint16_t>(std::stoul(str.substr(4)))) {}
88
89 Code code = Code::None; ///< Code
90 uint16_t satNum = 0; ///< Number of the satellite
91
92 /// @brief Equal comparison (needed for unordered_map)
93 /// @param[in] rhs Right hand side of the operator
94 /// @return True if the elements are equal
95
4/4
✓ Branch 1 taken 39993731 times.
✓ Branch 2 taken 1130468956 times.
✓ Branch 3 taken 10870519 times.
✓ Branch 4 taken 29123212 times.
1165162925 bool operator==(const SatSigId& rhs) const { return code == rhs.code && satNum == rhs.satNum; }
96
97 /// @brief Less than comparison (needed for map)
98 /// @param[in] rhs Right hand side of the operator
99 /// @return True if lhs < rhs
100 2234096 bool operator<(const SatSigId& rhs) const
101 {
102
4/6
✓ Branch 1 taken 2234096 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2234096 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1876524 times.
✓ Branch 8 taken 357572 times.
2234096 if (toSatId().satSys == rhs.toSatId().satSys)
103 {
104
2/2
✓ Branch 0 taken 582330 times.
✓ Branch 1 taken 1294194 times.
1876524 if (satNum == rhs.satNum)
105 {
106
1/2
✓ Branch 3 taken 582330 times.
✗ Branch 4 not taken.
582330 return Code::Set(code) < Code::Set(rhs.code);
107 }
108 1294194 return satNum < rhs.satNum;
109 }
110
2/4
✓ Branch 1 taken 357572 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 357572 times.
✗ Branch 5 not taken.
357572 return toSatId().satSys < rhs.toSatId().satSys;
111 }
112
113 /// @brief Returns a satellite identifier for the satellite signal
114 8316426 [[nodiscard]] SatId toSatId() const
115 {
116
2/4
✓ Branch 1 taken 8316194 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8316239 times.
✗ Branch 5 not taken.
8316426 return { code.getFrequency().getSatSys(), satNum };
117 }
118
119 /// @brief Returns the frequency of the satellite signal
120 2367538 [[nodiscard]] Frequency freq() const
121 {
122 2367538 return code.getFrequency();
123 }
124 };
125
126 /// @brief Less than comparison from string representation
127 /// @param[in] lhs Left hand side of the operator
128 /// @param[in] rhs Right hand side of the operator
129 /// @return True if lhs < rhs
130 bool lessCompareSatSigId(const std::string& lhs, const std::string& rhs);
131
132 /// @brief Converts the provided link into a json object
133 /// @param[out] j Json object which gets filled with the info
134 /// @param[in] data Data to convert into json
135 void to_json(json& j, const SatId& data);
136 /// @brief Converts the provided json object into a link object
137 /// @param[in] j Json object with the needed values
138 /// @param[out] data Object to fill from the json
139 void from_json(const json& j, SatId& data);
140
141 /// @brief Converts the provided link into a json object
142 /// @param[out] j Json object which gets filled with the info
143 /// @param[in] data Object to convert into json
144 void to_json(json& j, const SatSigId& data);
145 /// @brief Converts the provided json object into a link object
146 /// @param[in] j Json object with the needed values
147 /// @param[out] data Object to fill from the json
148 void from_json(const json& j, SatSigId& data);
149
150 /// @brief Shows a ComboBox to select satellites
151 /// @param[in] label Label to show beside the combo box. This has to be a unique id for ImGui.
152 /// @param[in, out] satellites Reference to the SatId vector to select
153 /// @param[in] filterSys Enable/Disable GUI elements according to this filter
154 /// @param[in] displayOnlyNumber Display only the number, not the system
155 bool ShowSatelliteSelector(const char* label, std::vector<SatId>& satellites, SatelliteSystem filterSys = SatSys_All, bool displayOnlyNumber = false);
156
157 /// @brief Shows a ComboBox to select a single satellite
158 /// @param[in] label Label to show beside the combo box. This has to be a unique id for ImGui.
159 /// @param[in, out] satellite Reference to the SatId to select
160 /// @param[in] filterSys Enable/Disable GUI elements according to this filter
161 /// @param[in] displayOnlyNumber Display only the number, not the system
162 bool ShowSatelliteSelector(const char* label, SatId& satellite, SatelliteSystem filterSys = SatSys_All, bool displayOnlyNumber = false);
163
164 } // namespace NAV
165
166 /// @brief Stream insertion operator overload
167 /// @param[in, out] os Output stream object to stream the time into
168 /// @param[in] obj Object to print
169 /// @return Returns the output stream object in order to chain stream insertions
170 std::ostream& operator<<(std::ostream& os, const NAV::SatId& obj);
171
172 /// @brief Stream insertion operator overload
173 /// @param[in, out] os Output stream object to stream the time into
174 /// @param[in] obj Object to print
175 /// @return Returns the output stream object in order to chain stream insertions
176 std::ostream& operator<<(std::ostream& os, const NAV::SatSigId& obj);
177
178 #ifndef DOXYGEN_IGNORE
179
180 /// @brief Formatter for SatId
181 template<>
182 struct fmt::formatter<NAV::SatId>
183 {
184 /// @brief Parse function to make the struct formattable
185 /// @param[in] ctx Parser context
186 /// @return Beginning of the context
187 220433 static constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin())
188 {
189 220433 return ctx.begin();
190 }
191
192 /// @brief Defines how to format SatId structs
193 /// @param[in] satId Struct to format
194 /// @param[in, out] ctx Format context
195 /// @return Output iterator
196 template<typename FormatContext>
197 220433 auto format(const NAV::SatId& satId, FormatContext& ctx) const -> decltype(ctx.out())
198 {
199
2/4
✓ Branch 1 taken 220433 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 220433 times.
✗ Branch 5 not taken.
440866 return fmt::format_to(ctx.out(), "{0}{1:02d}", char(satId.satSys), satId.satNum);
200 }
201 };
202
203 /// @brief Formatter for SatSigId
204 template<>
205 struct fmt::formatter<NAV::SatSigId>
206 {
207 /// @brief Parse function to make the struct formattable
208 /// @param[in] ctx Parser context
209 /// @return Beginning of the context
210 672503 static constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin())
211 {
212 672503 return ctx.begin();
213 }
214
215 /// @brief Defines how to format SatSigId structs
216 /// @param[in] satSigId Struct to format
217 /// @param[in, out] ctx Format context
218 /// @return Output iterator
219 template<typename FormatContext>
220 672503 auto format(const NAV::SatSigId& satSigId, FormatContext& ctx) const
221 {
222 1345006 return fmt::format_to(ctx.out(), "{0}-{1:02d}", satSigId.code, satSigId.satNum);
223 }
224 };
225
226 #endif
227
228 namespace std
229 {
230 /// @brief Hash function for SatId (needed for unordered_map)
231 template<>
232 struct hash<NAV::SatId>
233 {
234 /// @brief Hash function for SatId
235 /// @param[in] f Satellite identifier
236 2556254 std::size_t operator()(const NAV::SatId& f) const
237 {
238 2556254 auto hash1 = std::hash<NAV::SatelliteSystem_>{}(NAV::SatelliteSystem_(f.satSys));
239 2556245 auto hash2 = static_cast<size_t>(f.satNum);
240
241 2556245 return hash1 | (hash2 << 10);
242 }
243 };
244 /// @brief Hash function for SatSigId (needed for unordered_map)
245 template<>
246 struct hash<NAV::SatSigId>
247 {
248 /// @brief Hash function for SatSigId
249 /// @param[in] f Satellite signal identifier
250 11223764 std::size_t operator()(const NAV::SatSigId& f) const
251 {
252 11223764 auto hash1 = static_cast<size_t>(f.code.getEnumValue());
253 11222643 auto hash2 = static_cast<size_t>(f.satNum);
254
255 11222643 return hash1 | (hash2 << 8);
256 }
257 };
258 } // namespace std
259