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 | 3344869 | SatId(SatelliteSystem satSys, uint16_t satNum) | |
39 | 3344869 | : satSys(satSys), satNum(satNum) {} | |
40 | |||
41 | /// Default constructor | ||
42 | 548338 | SatId() = default; | |
43 | |||
44 | SatelliteSystem satSys = SatSys_None; ///< Satellite system (GPS, GLONASS, GALILEO, QZSS, BDS, IRNSS, SBAS) | ||
45 | uint16_t satNum = 0; ///< Number of the satellite | ||
46 | |||
47 | /// @brief Equal comparison (needed for unordered_map) | ||
48 | /// @param[in] rhs Right hand side of the operator | ||
49 | /// @return True if the elements are equal | ||
50 |
4/4✓ Branch 1 taken 10914514 times.
✓ Branch 2 taken 25242695 times.
✓ Branch 3 taken 2445157 times.
✓ Branch 4 taken 8469357 times.
|
36149763 | constexpr bool operator==(const SatId& rhs) const { return satSys == rhs.satSys && satNum == rhs.satNum; } |
51 | |||
52 | /// @brief Less than comparison (needed for map) | ||
53 | /// @param[in] rhs Right hand side of the operator | ||
54 | /// @return True if lhs < rhs | ||
55 | 856711 | constexpr bool operator<(const SatId& rhs) const | |
56 | { | ||
57 |
2/2✓ Branch 1 taken 571185 times.
✓ Branch 2 taken 285526 times.
|
856711 | return satSys == rhs.satSys ? satNum < rhs.satNum |
58 | 856711 | : satSys < rhs.satSys; | |
59 | } | ||
60 | |||
61 | /// Checks if the satellite is geostationary | ||
62 | [[nodiscard]] bool isGeo() const; | ||
63 | }; | ||
64 | |||
65 | /// @brief Identifies a satellite signal (satellite frequency and number) | ||
66 | struct SatSigId | ||
67 | { | ||
68 | /// @brief Constructor | ||
69 | /// @param[in] code Signal code | ||
70 | /// @param[in] satNum Number of the satellite | ||
71 | 187431272 | SatSigId(Code code, uint16_t satNum) | |
72 | 187431272 | : code(code), satNum(satNum) {} | |
73 | |||
74 | /// Default constructor | ||
75 | 21400 | SatSigId() = default; | |
76 | |||
77 | Code code = Code::None; ///< Code | ||
78 | uint16_t satNum = 0; ///< Number of the satellite | ||
79 | |||
80 | /// @brief Equal comparison (needed for unordered_map) | ||
81 | /// @param[in] rhs Right hand side of the operator | ||
82 | /// @return True if the elements are equal | ||
83 |
4/4✓ Branch 1 taken 26401165 times.
✓ Branch 2 taken 930472445 times.
✓ Branch 3 taken 4337240 times.
✓ Branch 4 taken 22063925 times.
|
953528605 | bool operator==(const SatSigId& rhs) const { return code == rhs.code && satNum == rhs.satNum; } |
84 | |||
85 | /// @brief Less than comparison (needed for map) | ||
86 | /// @param[in] rhs Right hand side of the operator | ||
87 | /// @return True if lhs < rhs | ||
88 | 158835 | bool operator<(const SatSigId& rhs) const | |
89 | { | ||
90 |
3/6✓ Branch 1 taken 158835 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 158835 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 158835 times.
✗ Branch 8 not taken.
|
158835 | if (toSatId().satSys == rhs.toSatId().satSys) |
91 | { | ||
92 |
2/2✓ Branch 0 taken 35596 times.
✓ Branch 1 taken 123239 times.
|
158835 | if (satNum == rhs.satNum) |
93 | { | ||
94 |
1/2✓ Branch 3 taken 35596 times.
✗ Branch 4 not taken.
|
35596 | return Code::Set(code) < Code::Set(rhs.code); |
95 | } | ||
96 | 123239 | return satNum < rhs.satNum; | |
97 | } | ||
98 | ✗ | return toSatId().satSys < rhs.toSatId().satSys; | |
99 | } | ||
100 | |||
101 | /// @brief Returns a satellite identifier for the satellite signal | ||
102 | 821950 | [[nodiscard]] SatId toSatId() const | |
103 | { | ||
104 |
2/4✓ Branch 1 taken 821950 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 821950 times.
✗ Branch 5 not taken.
|
821950 | return { code.getFrequency().getSatSys(), satNum }; |
105 | } | ||
106 | |||
107 | /// @brief Returns the frequency of the satellite signal | ||
108 | 741173 | [[nodiscard]] Frequency freq() const | |
109 | { | ||
110 | 741173 | return code.getFrequency(); | |
111 | } | ||
112 | }; | ||
113 | |||
114 | /// @brief Less than comparison from string representation | ||
115 | /// @param[in] lhs Left hand side of the operator | ||
116 | /// @param[in] rhs Right hand side of the operator | ||
117 | /// @return True if lhs < rhs | ||
118 | bool lessCompareSatSigId(const std::string& lhs, const std::string& rhs); | ||
119 | |||
120 | /// @brief Converts the provided link into a json object | ||
121 | /// @param[out] j Json object which gets filled with the info | ||
122 | /// @param[in] data Data to convert into json | ||
123 | void to_json(json& j, const SatId& data); | ||
124 | /// @brief Converts the provided json object into a link object | ||
125 | /// @param[in] j Json object with the needed values | ||
126 | /// @param[out] data Object to fill from the json | ||
127 | void from_json(const json& j, SatId& data); | ||
128 | |||
129 | /// @brief Converts the provided link into a json object | ||
130 | /// @param[out] j Json object which gets filled with the info | ||
131 | /// @param[in] data Object to convert into json | ||
132 | void to_json(json& j, const SatSigId& data); | ||
133 | /// @brief Converts the provided json object into a link object | ||
134 | /// @param[in] j Json object with the needed values | ||
135 | /// @param[out] data Object to fill from the json | ||
136 | void from_json(const json& j, SatSigId& data); | ||
137 | |||
138 | /// @brief Shows a ComboBox to select satellites | ||
139 | /// @param[in] label Label to show beside the combo box. This has to be a unique id for ImGui. | ||
140 | /// @param[in, out] satellites Reference to the SatId vector to select | ||
141 | /// @param[in] filterSys Enable/Disable GUI elements according to this filter | ||
142 | /// @param[in] displayOnlyNumber Display only the number, not the system | ||
143 | bool ShowSatelliteSelector(const char* label, std::vector<SatId>& satellites, SatelliteSystem filterSys = SatSys_All, bool displayOnlyNumber = false); | ||
144 | |||
145 | /// @brief Shows a ComboBox to select a single satellite | ||
146 | /// @param[in] label Label to show beside the combo box. This has to be a unique id for ImGui. | ||
147 | /// @param[in, out] satellite Reference to the SatId to select | ||
148 | /// @param[in] filterSys Enable/Disable GUI elements according to this filter | ||
149 | /// @param[in] displayOnlyNumber Display only the number, not the system | ||
150 | bool ShowSatelliteSelector(const char* label, SatId& satellite, SatelliteSystem filterSys = SatSys_All, bool displayOnlyNumber = false); | ||
151 | |||
152 | } // namespace NAV | ||
153 | |||
154 | /// @brief Stream insertion operator overload | ||
155 | /// @param[in, out] os Output stream object to stream the time into | ||
156 | /// @param[in] obj Object to print | ||
157 | /// @return Returns the output stream object in order to chain stream insertions | ||
158 | std::ostream& operator<<(std::ostream& os, const NAV::SatId& obj); | ||
159 | |||
160 | /// @brief Stream insertion operator overload | ||
161 | /// @param[in, out] os Output stream object to stream the time into | ||
162 | /// @param[in] obj Object to print | ||
163 | /// @return Returns the output stream object in order to chain stream insertions | ||
164 | std::ostream& operator<<(std::ostream& os, const NAV::SatSigId& obj); | ||
165 | |||
166 | #ifndef DOXYGEN_IGNORE | ||
167 | |||
168 | /// @brief Formatter for SatId | ||
169 | template<> | ||
170 | struct fmt::formatter<NAV::SatId> | ||
171 | { | ||
172 | /// @brief Parse function to make the struct formattable | ||
173 | /// @param[in] ctx Parser context | ||
174 | /// @return Beginning of the context | ||
175 | 209430 | static constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) | |
176 | { | ||
177 | 209430 | return ctx.begin(); | |
178 | } | ||
179 | |||
180 | /// @brief Defines how to format SatId structs | ||
181 | /// @param[in] satId Struct to format | ||
182 | /// @param[in, out] ctx Format context | ||
183 | /// @return Output iterator | ||
184 | template<typename FormatContext> | ||
185 | 209430 | auto format(const NAV::SatId& satId, FormatContext& ctx) const -> decltype(ctx.out()) | |
186 | { | ||
187 |
1/2✓ Branch 1 taken 209430 times.
✗ Branch 2 not taken.
|
418860 | return fmt::format_to(ctx.out(), "{0}{1:02d}", char(satId.satSys), satId.satNum); |
188 | } | ||
189 | }; | ||
190 | |||
191 | /// @brief Formatter for SatSigId | ||
192 | template<> | ||
193 | struct fmt::formatter<NAV::SatSigId> | ||
194 | { | ||
195 | /// @brief Parse function to make the struct formattable | ||
196 | /// @param[in] ctx Parser context | ||
197 | /// @return Beginning of the context | ||
198 | 546126 | static constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) | |
199 | { | ||
200 | 546126 | return ctx.begin(); | |
201 | } | ||
202 | |||
203 | /// @brief Defines how to format SatSigId structs | ||
204 | /// @param[in] satSigId Struct to format | ||
205 | /// @param[in, out] ctx Format context | ||
206 | /// @return Output iterator | ||
207 | template<typename FormatContext> | ||
208 | 546126 | auto format(const NAV::SatSigId& satSigId, FormatContext& ctx) const | |
209 | { | ||
210 | 1092252 | return fmt::format_to(ctx.out(), "{0}-{1:02d}", satSigId.code, satSigId.satNum); | |
211 | } | ||
212 | }; | ||
213 | |||
214 | #endif | ||
215 | |||
216 | namespace std | ||
217 | { | ||
218 | /// @brief Hash function for SatId (needed for unordered_map) | ||
219 | template<> | ||
220 | struct hash<NAV::SatId> | ||
221 | { | ||
222 | /// @brief Hash function for SatId | ||
223 | /// @param[in] f Satellite identifier | ||
224 | 975809 | std::size_t operator()(const NAV::SatId& f) const | |
225 | { | ||
226 | 975809 | auto hash1 = std::hash<NAV::SatelliteSystem_>{}(NAV::SatelliteSystem_(f.satSys)); | |
227 | 975809 | auto hash2 = static_cast<size_t>(f.satNum); | |
228 | |||
229 | 975809 | return hash1 | (hash2 << 10); | |
230 | } | ||
231 | }; | ||
232 | /// @brief Hash function for SatSigId (needed for unordered_map) | ||
233 | template<> | ||
234 | struct hash<NAV::SatSigId> | ||
235 | { | ||
236 | /// @brief Hash function for SatSigId | ||
237 | /// @param[in] f Satellite signal identifier | ||
238 | 2076571 | std::size_t operator()(const NAV::SatSigId& f) const | |
239 | { | ||
240 | 2076571 | auto hash1 = static_cast<size_t>(f.code.getEnumValue()); | |
241 | 2076571 | auto hash2 = static_cast<size_t>(f.satNum); | |
242 | |||
243 | 2076571 | return hash1 | (hash2 << 8); | |
244 | } | ||
245 | }; | ||
246 | } // namespace std | ||
247 |