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 VectorNavTypes.hpp | ||
10 | /// @brief Type Definitions for VectorNav messages | ||
11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
12 | /// @date 2021-07-01 | ||
13 | |||
14 | #pragma once | ||
15 | |||
16 | // VectorNav library includes <winsock2.h>, but <boost/asio.hpp> needs to be included before (even though not used in this file) | ||
17 | // https://stackoverflow.com/questions/9750344/boostasio-winsock-and-winsock-2-compatibility-issue | ||
18 | #ifdef _WIN32 | ||
19 | // Set the proper SDK version before including boost/Asio | ||
20 | #include <SDKDDKVer.h> | ||
21 | // Note boost/ASIO includes Windows.h. | ||
22 | #include <boost/asio.hpp> | ||
23 | #endif //_WIN32 | ||
24 | |||
25 | #include <cstdint> | ||
26 | #include <vector> | ||
27 | #include <iostream> | ||
28 | #include <fmt/format.h> | ||
29 | #include <fmt/ostream.h> | ||
30 | #include <vn/vector.h> | ||
31 | #include <vn/matrix.h> | ||
32 | #include <vn/types.h> | ||
33 | |||
34 | #include "Navigation/GNSS/Core/Code.hpp" | ||
35 | #include "Navigation/GNSS/Core/SatelliteIdentifier.hpp" | ||
36 | #include "Navigation/GNSS/Core/SatelliteSystem.hpp" | ||
37 | |||
38 | namespace NAV::vendor::vectornav | ||
39 | { | ||
40 | /// @brief The VPE status bitfield | ||
41 | /// | ||
42 | /// Bit | Name | Description | ||
43 | /// 0 | timeOk | GpsTow is valid. | ||
44 | /// 1 | dateOk | TimeGps and GpsWeek are valid. | ||
45 | /// 2 | utcTimeValid | UTC time is valid. | ||
46 | class TimeStatus | ||
47 | { | ||
48 | public: | ||
49 | /// Constructor | ||
50 | /// @param[in] status Status to set | ||
51 | explicit TimeStatus(uint8_t status) : _status(status) {} | ||
52 | |||
53 | /// @brief Assignment operator | ||
54 | /// @param[in] status Status to set | ||
55 | 57147 | TimeStatus& operator=(const uint8_t& status) | |
56 | { | ||
57 | 57147 | _status = status; | |
58 | 57147 | return *this; | |
59 | } | ||
60 | |||
61 | /// @brief Default constructor | ||
62 | TimeStatus() = default; | ||
63 | |||
64 | /// @brief Returns a reference to the status | ||
65 | 426 | [[nodiscard]] constexpr uint8_t& status() | |
66 | { | ||
67 | 426 | return _status; | |
68 | } | ||
69 | |||
70 | /// GpsTow is valid | ||
71 | 29088 | [[nodiscard]] constexpr uint8_t timeOk() const | |
72 | { | ||
73 | 29088 | return ((_status & (1U << 0U)) >> 0U); | |
74 | } | ||
75 | /// TimeGps and GpsWeek are valid. | ||
76 | 29088 | [[nodiscard]] constexpr uint8_t dateOk() const | |
77 | { | ||
78 | 29088 | return ((_status & (1U << 1U)) >> 1U); // NOLINT | |
79 | } | ||
80 | /// UTC time is valid. | ||
81 | 704 | [[nodiscard]] constexpr uint8_t utcTimeValid() const | |
82 | { | ||
83 | 704 | return ((_status & (1U << 2U)) >> 2U); // NOLINT | |
84 | } | ||
85 | |||
86 | private: | ||
87 | /// The storage field | ||
88 | uint8_t _status; | ||
89 | }; | ||
90 | |||
91 | /// @brief Storage class for UTC Time | ||
92 | struct UTC | ||
93 | { | ||
94 | int8_t year{}; ///< The year is given as a signed byte year offset from the year 2000. For example the year 2013 would be given as year 13. | ||
95 | uint8_t month{}; ///< Months | ||
96 | uint8_t day{}; ///< Days | ||
97 | uint8_t hour{}; ///< Hours | ||
98 | uint8_t min{}; ///< Minutes | ||
99 | uint8_t sec{}; ///< Seconds | ||
100 | uint16_t ms{}; ///< Milliseconds | ||
101 | }; | ||
102 | |||
103 | /// @brief GNSS fix. | ||
104 | enum GnssFix : uint8_t | ||
105 | { | ||
106 | GnssFix_NoFix, ///< No fix | ||
107 | GnssFix_TimeOnly, ///< Time only | ||
108 | GnssFix_2D, ///< 2D | ||
109 | GnssFix_3D, ///< 3D | ||
110 | GnssFix_SBAS, ///< SBAS | ||
111 | GnssFix_RTK_Float, ///< RTK Float (only GNSS1) | ||
112 | GnssFix_RTK_Fixed ///< RTK Fixed (only GNSS1) | ||
113 | }; | ||
114 | |||
115 | /// @brief Flags for valid GPS TOW, week number and UTC and current leap seconds. | ||
116 | struct TimeInfo | ||
117 | { | ||
118 | /// Fields: timeOk | dateOk | utcTimeValid | resv | resv | resv | resv | resv | ||
119 | /// Bit Offset: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
120 | /// | ||
121 | /// Name | Description | ||
122 | /// ------------ | ---------------------------------- | ||
123 | /// timeOk | 1 - GpsTow is valid. | ||
124 | /// dateOk | 1 - TimeGps and GpsWeek are valid. | ||
125 | /// utcTimeValid | 1 - UTC time is valid. | ||
126 | /// resv | Reserved for future use. | ||
127 | TimeStatus status{}; | ||
128 | /// @brief Amount of leap seconds | ||
129 | int8_t leapSeconds{}; | ||
130 | }; | ||
131 | |||
132 | /// @brief Dilution of precision | ||
133 | struct DOP | ||
134 | { | ||
135 | float gDop{}; ///< Geometric DOP | ||
136 | float pDop{}; ///< Positional DOP (Overall 3D position precision) | ||
137 | float tDop{}; ///< Time DOP (time precision) | ||
138 | float vDop{}; ///< Vertical DOP (vertical position precision) | ||
139 | float hDop{}; ///< Horizontal DOP (2D position precision) | ||
140 | float nDop{}; ///< North DOP | ||
141 | float eDop{}; ///< East DOP | ||
142 | }; | ||
143 | |||
144 | /// @brief Satellite Constellation | ||
145 | enum class SatSys : uint8_t | ||
146 | { | ||
147 | GPS = 0, ///< GPS | ||
148 | SBAS = 1, ///< SBAS | ||
149 | Galileo = 2, ///< Galileo | ||
150 | BeiDou = 3, ///< BeiDou | ||
151 | IMES = 4, ///< IMES | ||
152 | QZSS = 5, ///< QZSS | ||
153 | GLONASS = 6, ///< GLONASS | ||
154 | }; | ||
155 | |||
156 | /// @brief Converts the VectorNav satellite system to the INSTINCT representation | ||
157 | /// @param[in] sys VectorNav satellite system | ||
158 | SatelliteSystem toSatelliteSystem(SatSys sys); | ||
159 | |||
160 | /// @brief Converts the INSTINCT satellite system to the VectorNav representation | ||
161 | /// @param[in] sys INSTINCT satellite system | ||
162 | SatSys fromSatelliteSystem(SatelliteSystem sys); | ||
163 | |||
164 | /// @brief Stream insertion operator overload | ||
165 | /// @param[in, out] os Output stream where data gets printed to | ||
166 | /// @param[in] satSys Satellite Constellation | ||
167 | /// @return Output stream object | ||
168 | std::ostream& operator<<(std::ostream& os, const SatSys& satSys); | ||
169 | |||
170 | /// @brief Information and measurements pertaining to each GNSS satellite in view. | ||
171 | /// | ||
172 | /// The size of this packet will vary depending upon the number of satellites in view. To parse this packet you | ||
173 | /// will first need to read the number of satellites (numSats) in the beginning of the packet to determine the | ||
174 | /// packets overall length. The total length of the packet payload will be 2 + N*8 bytes where N is the number of | ||
175 | /// satellites (numSats). | ||
176 | struct SatInfo | ||
177 | { | ||
178 | /// @brief Information for a certain satellite | ||
179 | struct SatInfoElement | ||
180 | { | ||
181 | /// @brief Tracking info flags | ||
182 | enum class Flags : uint8_t | ||
183 | { | ||
184 | None = 0, ///< No flag set | ||
185 | Healthy = 1 << 0, ///< Healthy | ||
186 | Almanac = 1 << 1, ///< Almanac | ||
187 | Ephemeris = 1 << 2, ///< Ephemeris | ||
188 | DifferentialCorrection = 1 << 3, ///< Differential Correction | ||
189 | UsedForNavigation = 1 << 4, ///< Used for Navigation | ||
190 | AzimuthElevationValid = 1 << 5, ///< Azimuth / Elevation Valid | ||
191 | UsedForRTK = 1 << 6, ///< Used for RTK | ||
192 | }; | ||
193 | |||
194 | /// @brief Binary or-operator | ||
195 | /// @param[in] lhs Left-hand side | ||
196 | /// @param[in] rhs Right-hand side | ||
197 | /// @return Binary or-ed result | ||
198 | 2292906 | friend Flags operator|(Flags lhs, Flags rhs) | |
199 | { | ||
200 | 2292906 | return Flags(int(lhs) | int(rhs)); | |
201 | } | ||
202 | |||
203 | /// @brief Quality Indicator | ||
204 | enum class QualityIndicator : uint8_t | ||
205 | { | ||
206 | NoSignal = 0, ///< No signal | ||
207 | SearchingSignal = 1, ///< Searching signal | ||
208 | SignalAcquired = 2, ///< Signal acquired | ||
209 | SignalDetectedButUnstable = 3, ///< Signal detected but unstable | ||
210 | CodeLockedAndTimeSynchronized = 4, ///< Code locked and time synchronized | ||
211 | CodeAndCarrierLockedAndTimeSynchronized1 = 5, ///< Code and carrier locked and time synchronized | ||
212 | CodeAndCarrierLockedAndTimeSynchronized2 = 6, ///< Code and carrier locked and time synchronized | ||
213 | CodeAndCarrierLockedAndTimeSynchronized3 = 7, ///< Code and carrier locked and time synchronized | ||
214 | }; | ||
215 | |||
216 | /// @brief Default Constructor | ||
217 | 2267 | SatInfoElement() = default; | |
218 | |||
219 | /// @brief Constructor | ||
220 | /// @param[in] sys GNSS constellation indicator | ||
221 | /// @param[in] svId Space vehicle Id | ||
222 | /// @param[in] flags Tracking info flags | ||
223 | /// @param[in] cno Carrier-to-noise density ratio (signal strength) [dB-Hz] | ||
224 | /// @param[in] qi Quality Indicator | ||
225 | /// @param[in] el Elevation in degrees | ||
226 | /// @param[in] az Azimuth angle in degrees | ||
227 | 69549 | SatInfoElement(uint8_t sys, uint8_t svId, uint8_t flags, uint8_t cno, uint8_t qi, int8_t el, int16_t az) | |
228 | 69549 | : sys(static_cast<SatSys>(sys)), svId(svId), flags(static_cast<Flags>(flags)), cno(cno), qi(static_cast<QualityIndicator>(qi)), el(el), az(az) {} | |
229 | |||
230 | /// @brief Constructor | ||
231 | /// @param[in] sys GNSS constellation indicator | ||
232 | /// @param[in] svId Space vehicle Id | ||
233 | /// @param[in] healthy Healthy | ||
234 | /// @param[in] almanac Almanac | ||
235 | /// @param[in] ephemeris Ephemeris | ||
236 | /// @param[in] differentialCorrection Differential Correction | ||
237 | /// @param[in] usedForNavigation Used for Navigation | ||
238 | /// @param[in] azimuthElevationValid Azimuth / Elevation Valid | ||
239 | /// @param[in] usedForRTK Used for RTK | ||
240 | /// @param[in] cno Carrier-to-noise density ratio (signal strength) [dB-Hz] | ||
241 | /// @param[in] qi Quality Indicator | ||
242 | /// @param[in] el Elevation in degrees | ||
243 | /// @param[in] az Azimuth angle in degrees | ||
244 | 382025 | SatInfoElement(uint8_t sys, uint8_t svId, | |
245 | uint8_t healthy, uint8_t almanac, uint8_t ephemeris, uint8_t differentialCorrection, uint8_t usedForNavigation, uint8_t azimuthElevationValid, uint8_t usedForRTK, | ||
246 | uint8_t cno, uint8_t qi, int8_t el, int16_t az) | ||
247 |
14/14✓ Branch 0 taken 66375 times.
✓ Branch 1 taken 315650 times.
✓ Branch 2 taken 295295 times.
✓ Branch 3 taken 86730 times.
✓ Branch 4 taken 212400 times.
✓ Branch 5 taken 169625 times.
✓ Branch 6 taken 7965 times.
✓ Branch 7 taken 374060 times.
✓ Branch 8 taken 238360 times.
✓ Branch 9 taken 143665 times.
✓ Branch 10 taken 2950 times.
✓ Branch 11 taken 379075 times.
✓ Branch 12 taken 225970 times.
✓ Branch 13 taken 156055 times.
|
382025 | : sys(static_cast<SatSys>(sys)), svId(svId), flags((healthy ? Flags::Healthy : Flags::None) | (almanac ? Flags::Almanac : Flags::None) | (ephemeris ? Flags::Ephemeris : Flags::None) | (differentialCorrection ? Flags::DifferentialCorrection : Flags::None) | (usedForNavigation ? Flags::UsedForNavigation : Flags::None) | (azimuthElevationValid ? Flags::AzimuthElevationValid : Flags::None) | (usedForRTK ? Flags::UsedForRTK : Flags::None)), cno(cno), qi(static_cast<QualityIndicator>(qi)), el(el), az(az) {} |
248 | |||
249 | SatSys sys{}; ///< GNSS constellation indicator | ||
250 | uint8_t svId{}; ///< Space vehicle Id | ||
251 | Flags flags{}; ///< Tracking info flags | ||
252 | uint8_t cno{}; ///< Carrier-to-noise density ratio (signal strength) [dB-Hz] | ||
253 | QualityIndicator qi{}; ///< Quality Indicator | ||
254 | int8_t el{}; ///< Elevation in degrees | ||
255 | int16_t az{}; ///< Azimuth angle in degrees | ||
256 | }; | ||
257 | |||
258 | /// @brief Number of measurements to follow. | ||
259 | uint8_t numSats{}; | ||
260 | /// @brief SatInfo container | ||
261 | std::vector<SatInfoElement> satellites; | ||
262 | }; | ||
263 | |||
264 | /// @brief Allows combining flags of the SatInfo::SatInfoElement::Flags enum. | ||
265 | /// | ||
266 | /// @param[in] lhs Left-hand side enum value. | ||
267 | /// @param[in] rhs Right-hand side enum value. | ||
268 | /// @return The binary ANDed value. | ||
269 | ✗ | constexpr SatInfo::SatInfoElement::Flags operator&(SatInfo::SatInfoElement::Flags lhs, SatInfo::SatInfoElement::Flags rhs) | |
270 | { | ||
271 | ✗ | return SatInfo::SatInfoElement::Flags(int(lhs) & int(rhs)); | |
272 | } | ||
273 | |||
274 | /// @brief Raw measurements pertaining to each GNSS satellite in view. | ||
275 | struct RawMeas | ||
276 | { | ||
277 | /// @brief Raw measurements for a certain satellite | ||
278 | struct SatRawElement | ||
279 | { | ||
280 | /// @brief Tracking info flags | ||
281 | enum class Flags : uint16_t | ||
282 | { | ||
283 | None = 0, ///< No flag set | ||
284 | Searching = 1 << 0, ///< Searching | ||
285 | Tracking = 1 << 1, ///< Tracking | ||
286 | TimeValid = 1 << 2, ///< Time Valid | ||
287 | CodeLock = 1 << 3, ///< Code Lock | ||
288 | PhaseLock = 1 << 4, ///< Phase Lock | ||
289 | PhaseHalfAmbiguity = 1 << 5, ///< Phase Half Ambiguity | ||
290 | PhaseHalfSub = 1 << 6, ///< Phase Half Sub | ||
291 | PhaseSlip = 1 << 7, ///< Phase Slip | ||
292 | PseudorangeSmoothed = 1 << 8, ///< Pseudorange Smoothed | ||
293 | }; | ||
294 | |||
295 | /// @brief Binary or-operator | ||
296 | /// @param[in] lhs Left-hand side | ||
297 | /// @param[in] rhs Right-hand side | ||
298 | /// @return Binary or-ed result | ||
299 | 2827904 | friend Flags operator|(Flags lhs, Flags rhs) | |
300 | { | ||
301 | 2827904 | return Flags(int(lhs) | int(rhs)); | |
302 | } | ||
303 | |||
304 | /// @brief Channel Indicator | ||
305 | enum class Chan : uint8_t | ||
306 | { | ||
307 | P_Code = 0, ///< P-code (GPS,GLO) | ||
308 | CA_Code = 1, ///< C/A-code (GPS,GLO,SBAS,QZSS), C chan (GAL) | ||
309 | SemiCodeless = 2, ///< semi-codeless (GPS) | ||
310 | Y_Code = 3, ///< Y-code (GPS) | ||
311 | M_Code = 4, ///< M-code (GPS) | ||
312 | Codeless = 5, ///< codeless (GPS) | ||
313 | A_Chan = 6, ///< A chan (GAL) | ||
314 | B_Chan = 7, ///< B chan (GAL) | ||
315 | I_Chan = 8, ///< I chan (GPS,GAL,QZSS,BDS) | ||
316 | Q_Chan = 9, ///< Q chan (GPS,GAL,QZSS,BDS) | ||
317 | M_Chan = 10, ///< M chan (L2CGPS, L2CQZSS), D chan (GPS,QZSS) | ||
318 | L_Chan = 11, ///< L chan (L2CGPS, L2CQZSS), P chan (GPS,QZSS) | ||
319 | BC_Chan = 12, ///< B+C chan (GAL), I+Q chan (GPS,GAL,QZSS,BDS), M+L chan (GPS,QZSS), D+P chan (GPS,QZSS) | ||
320 | Z_Tracking = 13, ///< based on Z-tracking (GPS) | ||
321 | ABC = 14, ///< A+B+C (GAL) | ||
322 | }; | ||
323 | |||
324 | /// @brief Stream insertion operator overload | ||
325 | /// @param[in, out] os Output stream where data gets printed to | ||
326 | /// @param[in] chan Channel indicator | ||
327 | /// @return Output stream object | ||
328 | ✗ | friend std::ostream& operator<<(std::ostream& os, const Chan& chan) | |
329 | { | ||
330 | ✗ | switch (chan) | |
331 | { | ||
332 | ✗ | case Chan::P_Code: | |
333 | ✗ | os << "P-Code"; | |
334 | ✗ | break; | |
335 | ✗ | case Chan::CA_Code: | |
336 | ✗ | os << "C/A-Code or C-Chan"; | |
337 | ✗ | break; | |
338 | ✗ | case Chan::SemiCodeless: | |
339 | ✗ | os << "Semi-codeless"; | |
340 | ✗ | break; | |
341 | ✗ | case Chan::Y_Code: | |
342 | ✗ | os << "Y-Code"; | |
343 | ✗ | break; | |
344 | ✗ | case Chan::M_Code: | |
345 | ✗ | os << "M-Code"; | |
346 | ✗ | break; | |
347 | ✗ | case Chan::Codeless: | |
348 | ✗ | os << "Codeless"; | |
349 | ✗ | break; | |
350 | ✗ | case Chan::A_Chan: | |
351 | ✗ | os << "A Chan"; | |
352 | ✗ | break; | |
353 | ✗ | case Chan::B_Chan: | |
354 | ✗ | os << "B Chan"; | |
355 | ✗ | break; | |
356 | ✗ | case Chan::I_Chan: | |
357 | ✗ | os << "I Chan"; | |
358 | ✗ | break; | |
359 | ✗ | case Chan::Q_Chan: | |
360 | ✗ | os << "Q Chan"; | |
361 | ✗ | break; | |
362 | ✗ | case Chan::M_Chan: | |
363 | ✗ | os << "M Chan or D Chan"; | |
364 | ✗ | break; | |
365 | ✗ | case Chan::L_Chan: | |
366 | ✗ | os << "L Chan or P Chan"; | |
367 | ✗ | break; | |
368 | ✗ | case Chan::BC_Chan: | |
369 | ✗ | os << "B+C Chan, I+Q Chan, M+L Chan or D+P Chan"; | |
370 | ✗ | break; | |
371 | ✗ | case Chan::Z_Tracking: | |
372 | ✗ | os << "based on Z-tracking"; | |
373 | ✗ | break; | |
374 | ✗ | case Chan::ABC: | |
375 | ✗ | os << "A+B+C"; | |
376 | ✗ | break; | |
377 | } | ||
378 | ✗ | return os; | |
379 | } | ||
380 | |||
381 | /// @brief Frequency indicator | ||
382 | enum class Freq : uint8_t | ||
383 | { | ||
384 | RxChannel = 0, ///< Rx Channel | ||
385 | L1 = 1, ///< L1(GPS,QZSS,SBAS), G1(GLO), E2-L1-E1(GAL), B1(BDS) | ||
386 | L2 = 2, ///< L2(GPS,QZSS), G2(GLO) | ||
387 | L5 = 3, ///< L5(GPS,QZSS,SBAS), E5a(GAL) | ||
388 | E6 = 4, ///< E6(GAL), LEX(QZSS), B3(BDS) | ||
389 | E5b = 5, ///< E5b(GAL), B2(BDS) | ||
390 | E5a = 6, ///< E5a+b(GAL) | ||
391 | }; | ||
392 | |||
393 | /// @brief Gets the satellite signal identifier | ||
394 | 7 | [[nodiscard]] SatSigId toSatSigId() const | |
395 | { | ||
396 | 7 | return { toCode(), svId }; | |
397 | } | ||
398 | |||
399 | /// @brief Converts the sys, freq and chan into a GNSS code | ||
400 | [[nodiscard]] Code toCode() const; | ||
401 | |||
402 | /// @brief Stream insertion operator overload | ||
403 | /// @param[in, out] os Output stream where data gets printed to | ||
404 | /// @param[in] freq Frequency indicator | ||
405 | /// @return Output stream object | ||
406 | ✗ | friend std::ostream& operator<<(std::ostream& os, const Freq& freq) | |
407 | { | ||
408 | ✗ | switch (freq) | |
409 | { | ||
410 | ✗ | case Freq::RxChannel: | |
411 | ✗ | os << "Rx Channel"; | |
412 | ✗ | break; | |
413 | ✗ | case Freq::L1: | |
414 | ✗ | os << "L1, G1, E2-L1-E1 or B1"; | |
415 | ✗ | break; | |
416 | ✗ | case Freq::L2: | |
417 | ✗ | os << "L2 or G2"; | |
418 | ✗ | break; | |
419 | ✗ | case Freq::L5: | |
420 | ✗ | os << "L5 or E5a"; | |
421 | ✗ | break; | |
422 | ✗ | case Freq::E6: | |
423 | ✗ | os << "E6, LEX or B3"; | |
424 | ✗ | break; | |
425 | ✗ | case Freq::E5b: | |
426 | ✗ | os << "E5b or B2"; | |
427 | ✗ | break; | |
428 | ✗ | case Freq::E5a: | |
429 | ✗ | os << "E5a+b"; | |
430 | ✗ | break; | |
431 | } | ||
432 | ✗ | return os; | |
433 | } | ||
434 | |||
435 | /// @brief Default Constructor | ||
436 | 1198 | SatRawElement() = default; | |
437 | |||
438 | /// @brief Constructor | ||
439 | /// @param[in] sys GNSS constellation indicator | ||
440 | /// @param[in] svId Space vehicle Id | ||
441 | /// @param[in] freq Frequency indicator | ||
442 | /// @param[in] chan Channel Indicator | ||
443 | /// @param[in] slot Slot Id | ||
444 | /// @param[in] cno Carrier-to-noise density ratio (signal strength) [dB-Hz] | ||
445 | /// @param[in] flags Tracking info flags | ||
446 | /// @param[in] pr Pseudorange measurement in meters | ||
447 | /// @param[in] cp Carrier phase measurement in cycles | ||
448 | /// @param[in] dp Doppler measurement in Hz. Positive sign for approaching satellites | ||
449 | 110796 | SatRawElement(uint8_t sys, uint8_t svId, uint8_t freq, uint8_t chan, int8_t slot, uint8_t cno, uint16_t flags, double pr, double cp, float dp) | |
450 | 110796 | : sys(static_cast<SatSys>(sys)), svId(svId), freq(static_cast<Freq>(freq)), chan(static_cast<Chan>(chan)), slot(slot), cno(cno), flags(static_cast<Flags>(flags)), pr(pr), cp(cp), dp(dp) {} | |
451 | |||
452 | /// @brief Constructor | ||
453 | /// @param[in] sys GNSS constellation indicator | ||
454 | /// @param[in] svId Space vehicle Id | ||
455 | /// @param[in] freq Frequency indicator | ||
456 | /// @param[in] chan Channel Indicator | ||
457 | /// @param[in] slot Slot Id | ||
458 | /// @param[in] cno Carrier-to-noise density ratio (signal strength) [dB-Hz] | ||
459 | /// @param[in] searching Searching | ||
460 | /// @param[in] tracking Tracking | ||
461 | /// @param[in] timeValid Time Valid | ||
462 | /// @param[in] codeLock Code Lock | ||
463 | /// @param[in] phaseLock Phase Lock | ||
464 | /// @param[in] phaseHalfAmbiguity Phase Half Ambiguity | ||
465 | /// @param[in] phaseHalfSub Phase Half Sub | ||
466 | /// @param[in] phaseSlip Phase Slip | ||
467 | /// @param[in] pseudorangeSmoothed Pseudorange Smoothed | ||
468 | /// @param[in] pr Pseudorange measurement in meters | ||
469 | /// @param[in] cp Carrier phase measurement in cycles | ||
470 | /// @param[in] dp Doppler measurement in Hz. Positive sign for approaching satellites | ||
471 | 353410 | SatRawElement(uint8_t sys, uint8_t svId, uint8_t freq, uint8_t chan, int8_t slot, uint8_t cno, | |
472 | uint8_t searching, uint8_t tracking, uint8_t timeValid, uint8_t codeLock, uint8_t phaseLock, uint8_t phaseHalfAmbiguity, uint8_t phaseHalfSub, uint8_t phaseSlip, uint8_t pseudorangeSmoothed, | ||
473 | double pr, double cp, double dp) | ||
474 |
11/18✗ Branch 0 not taken.
✓ Branch 1 taken 353410 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 353410 times.
✓ Branch 4 taken 89680 times.
✓ Branch 5 taken 263730 times.
✓ Branch 6 taken 5310 times.
✓ Branch 7 taken 348100 times.
✓ Branch 8 taken 353410 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 353410 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 353410 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 353410 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 353410 times.
|
353410 | : sys(static_cast<SatSys>(sys)), svId(svId), freq(static_cast<Freq>(freq)), chan(static_cast<Chan>(chan)), slot(slot), cno(cno), flags((searching ? Flags::Searching : Flags::None) | (tracking ? Flags::Tracking : Flags::None) | (timeValid ? Flags::TimeValid : Flags::None) | (codeLock ? Flags::CodeLock : Flags::None) | (phaseLock ? Flags::PhaseLock : Flags::None) | (phaseHalfAmbiguity ? Flags::PhaseHalfAmbiguity : Flags::None) | (phaseHalfSub ? Flags::PhaseHalfSub : Flags::None) | (phaseSlip ? Flags::PhaseSlip : Flags::None) | (pseudorangeSmoothed ? Flags::PseudorangeSmoothed : Flags::None)), pr(pr), cp(cp), dp(static_cast<float>(dp)) {} |
475 | |||
476 | SatSys sys{}; ///< GNSS constellation indicator | ||
477 | uint8_t svId{}; ///< Space vehicle Id | ||
478 | Freq freq{}; ///< Frequency indicator | ||
479 | Chan chan{}; ///< Channel Indicator | ||
480 | int8_t slot{}; ///< Slot Id | ||
481 | uint8_t cno{}; ///< Carrier-to-noise density ratio (signal strength) [dB-Hz] | ||
482 | Flags flags{}; ///< Tracking info flags | ||
483 | double pr{}; ///< Pseudorange measurement in meters | ||
484 | double cp{}; ///< Carrier phase measurement in cycles | ||
485 | float dp{}; ///< Doppler measurement in Hz. Positive sign for approaching satellites | ||
486 | }; | ||
487 | |||
488 | /// @brief Time of week in seconds | ||
489 | double tow{}; | ||
490 | /// @brief GPS week number | ||
491 | uint16_t week{}; | ||
492 | /// @brief Number of measurements to follow | ||
493 | uint8_t numSats{}; | ||
494 | /// @brief SatRaw container | ||
495 | std::vector<SatRawElement> satellites; | ||
496 | }; | ||
497 | |||
498 | /// @brief Allows combining flags of the RawMeas::SatRawElement::Flags enum. | ||
499 | /// | ||
500 | /// @param[in] lhs Left-hand side enum value. | ||
501 | /// @param[in] rhs Right-hand side enum value. | ||
502 | /// @return The binary ANDed value. | ||
503 | ✗ | constexpr RawMeas::SatRawElement::Flags operator&(RawMeas::SatRawElement::Flags lhs, RawMeas::SatRawElement::Flags rhs) | |
504 | { | ||
505 | ✗ | return RawMeas::SatRawElement::Flags(int(lhs) & int(rhs)); | |
506 | } | ||
507 | |||
508 | /// @brief The VPE status bitfield | ||
509 | /// | ||
510 | /// Bit | Name | Description | ||
511 | /// 0+1 | AttitudeQuality | Provides an indication of the quality of the attitude solution. 0 - Excellent, 1 - Good, 2 - Bad, 3 - Not tracking | ||
512 | /// 2 | GyroSaturation | At least one gyro axis is currently saturated. | ||
513 | /// 3 | GyroSaturationRecovery | Filter is in the process of recovering from a gyro saturation event. | ||
514 | /// 4+5 | MagDisturbance | A magnetic DC disturbance has been detected. 0 - No magnetic disturbance. 1 to 3 - Magnetic disturbance is present. | ||
515 | /// 6 | MagSaturation | At least one magnetometer axis is currently saturated. | ||
516 | /// 7+8 | AccDisturbance | A strong acceleration disturbance has been detected. 0 - No acceleration disturbance. 1 to 3 - Acceleration disturbance has been detected. | ||
517 | /// 9 | AccSaturation | At least one accelerometer axis is currently saturated. | ||
518 | /// 11 | KnownMagDisturbance | A known magnetic disturbance has been reported by the user and the magnetometer is currently tuned out. | ||
519 | /// 12 | KnownAccelDisturbance | A known acceleration disturbance has been reported by the user and the accelerometer is currently tuned out. | ||
520 | class VpeStatus | ||
521 | { | ||
522 | public: | ||
523 | /// Constructor | ||
524 | /// @param[in] status Status to set | ||
525 | explicit VpeStatus(uint16_t status) : _status(status) {} | ||
526 | |||
527 | /// @brief Assignment operator | ||
528 | /// @param[in] status Status to set | ||
529 | ✗ | VpeStatus& operator=(const uint16_t& status) | |
530 | { | ||
531 | ✗ | _status = status; | |
532 | ✗ | return *this; | |
533 | } | ||
534 | |||
535 | /// @brief Default constructor | ||
536 | VpeStatus() = default; | ||
537 | |||
538 | /// @brief Returns a reference to the status | ||
539 | ✗ | [[nodiscard]] constexpr uint16_t& status() | |
540 | { | ||
541 | ✗ | return _status; | |
542 | } | ||
543 | |||
544 | /// Extract the attitude quality from the vpe status | ||
545 | ✗ | [[nodiscard]] constexpr uint8_t attitudeQuality() const | |
546 | { | ||
547 | ✗ | return ((_status & (1U << 0U | 1U << 1U)) >> 0U); | |
548 | } | ||
549 | /// Extract the gyro saturation from the vpe status | ||
550 | ✗ | [[nodiscard]] constexpr uint8_t gyroSaturation() const | |
551 | { | ||
552 | ✗ | return ((_status & (1U << 2U)) >> 2U); // NOLINT | |
553 | } | ||
554 | /// Extract the gyro saturation recovery from the vpe status | ||
555 | ✗ | [[nodiscard]] constexpr uint8_t gyroSaturationRecovery() const | |
556 | { | ||
557 | ✗ | return ((_status & (1U << 3U)) >> 3U); // NOLINT | |
558 | } | ||
559 | /// Extract the magnetic disturbance from the vpe status | ||
560 | ✗ | [[nodiscard]] constexpr uint8_t magDisturbance() const | |
561 | { | ||
562 | ✗ | return ((_status & (1U << 4U | 1U << 5U)) >> 4U); // NOLINT | |
563 | } | ||
564 | /// Extract the magnetic saturation from the vpe status | ||
565 | ✗ | [[nodiscard]] constexpr uint8_t magSaturation() const | |
566 | { | ||
567 | ✗ | return ((_status & (1U << 6U)) >> 6U); // NOLINT | |
568 | } | ||
569 | /// Extract the acceleration disturbance from the vpe status | ||
570 | ✗ | [[nodiscard]] constexpr uint8_t accDisturbance() const | |
571 | { | ||
572 | ✗ | return ((_status & (1U << 7U | 1U << 8U)) >> 7U); // NOLINT | |
573 | } | ||
574 | /// Extract the acceleration saturation from the vpe status | ||
575 | ✗ | [[nodiscard]] constexpr uint8_t accSaturation() const | |
576 | { | ||
577 | ✗ | return ((_status & (1U << 9U)) >> 9U); // NOLINT | |
578 | } | ||
579 | /// Extract the known magnetic disturbance from the vpe status | ||
580 | ✗ | [[nodiscard]] constexpr uint8_t knownMagDisturbance() const | |
581 | { | ||
582 | ✗ | return ((_status & (1U << 11U)) >> 11U); // NOLINT | |
583 | } | ||
584 | /// Extract the known acceleration disturbance from the vpe status | ||
585 | ✗ | [[nodiscard]] constexpr uint8_t knownAccelDisturbance() const | |
586 | { | ||
587 | ✗ | return ((_status & (1U << 12U)) >> 12U); // NOLINT | |
588 | } | ||
589 | |||
590 | private: | ||
591 | /// The storage field | ||
592 | uint16_t _status; | ||
593 | }; | ||
594 | |||
595 | /// @brief The INS status bitfield | ||
596 | /// | ||
597 | /// Bit | Name | Description | ||
598 | /// 0+1 | Mode | Indicates the current mode of the INS filter. | ||
599 | /// | 0 = Not tracking. GNSS Compass is initializing. Output heading is based on magnetometer measurements. | ||
600 | /// | 1 = Aligning. | ||
601 | /// | INS Filter is dynamically aligning. | ||
602 | /// | For a stationary startup: GNSS Compass has initialized and INS Filter is | ||
603 | /// | aligning from the magnetic heading to the GNSS Compass heading. | ||
604 | /// | For a dynamic startup: INS Filter has initialized and is dynamically aligning to | ||
605 | /// | True North heading. | ||
606 | /// | In operation, if the INS Filter drops from INS Mode 2 back down to 1, the | ||
607 | /// | attitude uncertainty has increased above 2 degrees. | ||
608 | /// | 2 = Tracking. The INS Filter is tracking and operating within specification. | ||
609 | /// | 3 = Loss of GNSS. A GNSS outage has lasted more than 45 seconds. The INS Filter will | ||
610 | /// | no longer update the position and velocity outputs, but the attitude remains valid. | ||
611 | /// 2 | GpsFix | Indicates whether the GNSS has a proper fix. | ||
612 | /// 4 | IMU Error | High if IMU communication error is detected. | ||
613 | /// 5 | Mag/Pres Error | High if Magnetometer or Pressure sensor error is detected. | ||
614 | /// 6 | GNSS Error | High if GNSS communication error is detected, | ||
615 | /// 8 | GpsHeadingIns | In stationary operation, if set the INS Filter has fully aligned to the GNSS Compass solution. | ||
616 | /// | In dynamic operation, the GNSS Compass solution is currently aiding the INS Filter heading solution. | ||
617 | /// 9 | GpsCompass | Indicates if the GNSS compass is operational and reporting a heading solution. | ||
618 | class InsStatus | ||
619 | { | ||
620 | public: | ||
621 | /// @brief Indicates the current mode of the INS filter. | ||
622 | enum class Mode : uint8_t | ||
623 | { | ||
624 | /// @brief Not tracking. | ||
625 | /// | ||
626 | /// GNSS Compass is initializing. Output heading is based on magnetometer measurements. | ||
627 | NotTracking = 0, | ||
628 | /// @brief INS Filter is dynamically aligning. | ||
629 | /// | ||
630 | /// For a stationary startup: GNSS Compass has initialized and INS Filter is | ||
631 | /// aligning from the magnetic heading to the GNSS Compass heading. | ||
632 | /// For a dynamic startup: INS Filter has initialized and is dynamically aligning to | ||
633 | /// True North heading. | ||
634 | /// In operation, if the INS Filter drops from INS Mode 2 back down to 1, the | ||
635 | /// attitude uncertainty has increased above 2 degrees. | ||
636 | Aligning = 1, | ||
637 | /// @brief Tracking. | ||
638 | /// | ||
639 | /// The INS Filter is tracking and operating within specification. | ||
640 | Tracking = 2, | ||
641 | /// @brief Loss of GNSS. | ||
642 | /// | ||
643 | /// A GNSS outage has lasted more than 45 seconds. The INS Filter will | ||
644 | /// no longer update the position and velocity outputs, but the attitude remains valid. | ||
645 | LossOfGNSS = 3, | ||
646 | }; | ||
647 | |||
648 | /// Constructor | ||
649 | /// @param[in] status Status to set | ||
650 | explicit InsStatus(uint16_t status) : _status(status) {} | ||
651 | |||
652 | /// @brief Assignment operator | ||
653 | /// @param[in] status Status to set | ||
654 | ✗ | InsStatus& operator=(const uint16_t& status) | |
655 | { | ||
656 | ✗ | _status = status; | |
657 | ✗ | return *this; | |
658 | } | ||
659 | |||
660 | /// @brief Default constructor | ||
661 | InsStatus() = default; | ||
662 | |||
663 | /// @brief Returns a reference to the status | ||
664 | 2800 | [[nodiscard]] constexpr uint16_t& status() | |
665 | { | ||
666 | 2800 | return _status; | |
667 | } | ||
668 | |||
669 | /// Extract the current mode of the INS filter from the ins status | ||
670 | 5369 | [[nodiscard]] constexpr Mode mode() const | |
671 | { | ||
672 | 5369 | return static_cast<Mode>((_status & (1U << 0U | 1U << 1U)) >> 0U); | |
673 | } | ||
674 | /// Extract the GPS Fix from the ins status | ||
675 | 153 | [[nodiscard]] constexpr bool gpsFix() const | |
676 | { | ||
677 | 153 | return ((_status & (1U << 2U)) >> 2U); // NOLINT | |
678 | } | ||
679 | /// Extract the IMU Error from the ins status | ||
680 | 153 | [[nodiscard]] constexpr bool errorIMU() const | |
681 | { | ||
682 | 153 | return ((_status & (1U << 4U)) >> 4U); // NOLINT | |
683 | } | ||
684 | /// Extract the Mag/Pres Error from the ins status | ||
685 | 153 | [[nodiscard]] constexpr bool errorMagPres() const | |
686 | { | ||
687 | 153 | return ((_status & (1U << 5U)) >> 5U); // NOLINT | |
688 | } | ||
689 | /// Extract the GNSS Error from the ins status | ||
690 | 153 | [[nodiscard]] constexpr bool errorGnss() const | |
691 | { | ||
692 | 153 | return ((_status & (1U << 6U)) >> 6U); // NOLINT | |
693 | } | ||
694 | /// Extract the GPS Heading INS from the ins status | ||
695 | 153 | [[nodiscard]] constexpr bool gpsHeadingIns() const | |
696 | { | ||
697 | 153 | return ((_status & (1U << 8U)) >> 8U); // NOLINT | |
698 | } | ||
699 | /// Extract the GPS Compass from the ins status | ||
700 | 153 | [[nodiscard]] constexpr bool gpsCompass() const | |
701 | { | ||
702 | 153 | return ((_status & (1U << 9U)) >> 9U); // NOLINT | |
703 | } | ||
704 | |||
705 | private: | ||
706 | /// The storage field | ||
707 | uint16_t _status; | ||
708 | }; | ||
709 | |||
710 | } // namespace NAV::vendor::vectornav | ||
711 | |||
712 | #ifndef DOXYGEN_IGNORE | ||
713 | |||
714 | template<> | ||
715 | struct fmt::formatter<vn::protocol::uart::ErrorDetectionMode> : ostream_formatter | ||
716 | {}; | ||
717 | template<> | ||
718 | struct fmt::formatter<vn::protocol::uart::AsciiAsync> : ostream_formatter | ||
719 | {}; | ||
720 | template<> | ||
721 | struct fmt::formatter<vn::protocol::uart::AsyncMode> : ostream_formatter | ||
722 | {}; | ||
723 | template<> | ||
724 | struct fmt::formatter<vn::protocol::uart::BinaryGroup> : ostream_formatter | ||
725 | {}; | ||
726 | template<> | ||
727 | struct fmt::formatter<vn::protocol::uart::CommonGroup> : ostream_formatter | ||
728 | {}; | ||
729 | template<> | ||
730 | struct fmt::formatter<vn::protocol::uart::TimeGroup> : ostream_formatter | ||
731 | {}; | ||
732 | template<> | ||
733 | struct fmt::formatter<vn::protocol::uart::ImuGroup> : ostream_formatter | ||
734 | {}; | ||
735 | template<> | ||
736 | struct fmt::formatter<vn::protocol::uart::GpsGroup> : ostream_formatter | ||
737 | {}; | ||
738 | template<> | ||
739 | struct fmt::formatter<vn::protocol::uart::AttitudeGroup> : ostream_formatter | ||
740 | {}; | ||
741 | template<> | ||
742 | struct fmt::formatter<vn::protocol::uart::InsGroup> : ostream_formatter | ||
743 | {}; | ||
744 | template<> | ||
745 | struct fmt::formatter<vn::protocol::uart::SensorError> : ostream_formatter | ||
746 | {}; | ||
747 | template<> | ||
748 | struct fmt::formatter<vn::protocol::uart::BootloaderError> : ostream_formatter | ||
749 | {}; | ||
750 | template<> | ||
751 | struct fmt::formatter<vn::protocol::uart::SyncInMode> : ostream_formatter | ||
752 | {}; | ||
753 | template<> | ||
754 | struct fmt::formatter<vn::protocol::uart::SyncInEdge> : ostream_formatter | ||
755 | {}; | ||
756 | template<> | ||
757 | struct fmt::formatter<vn::protocol::uart::SyncOutMode> : ostream_formatter | ||
758 | {}; | ||
759 | template<> | ||
760 | struct fmt::formatter<vn::protocol::uart::SyncOutPolarity> : ostream_formatter | ||
761 | {}; | ||
762 | template<> | ||
763 | struct fmt::formatter<vn::protocol::uart::CountMode> : ostream_formatter | ||
764 | {}; | ||
765 | template<> | ||
766 | struct fmt::formatter<vn::protocol::uart::StatusMode> : ostream_formatter | ||
767 | {}; | ||
768 | template<> | ||
769 | struct fmt::formatter<vn::protocol::uart::ChecksumMode> : ostream_formatter | ||
770 | {}; | ||
771 | template<> | ||
772 | struct fmt::formatter<vn::protocol::uart::ErrorMode> : ostream_formatter | ||
773 | {}; | ||
774 | template<> | ||
775 | struct fmt::formatter<vn::protocol::uart::FilterMode> : ostream_formatter | ||
776 | {}; | ||
777 | template<> | ||
778 | struct fmt::formatter<vn::protocol::uart::IntegrationFrame> : ostream_formatter | ||
779 | {}; | ||
780 | template<> | ||
781 | struct fmt::formatter<vn::protocol::uart::CompensationMode> : ostream_formatter | ||
782 | {}; | ||
783 | template<> | ||
784 | struct fmt::formatter<vn::protocol::uart::AccCompensationMode> : ostream_formatter | ||
785 | {}; | ||
786 | template<> | ||
787 | struct fmt::formatter<vn::protocol::uart::EarthRateCorrection> : ostream_formatter | ||
788 | {}; | ||
789 | template<> | ||
790 | struct fmt::formatter<vn::protocol::uart::GpsFix> : ostream_formatter | ||
791 | {}; | ||
792 | template<> | ||
793 | struct fmt::formatter<vn::protocol::uart::GpsMode> : ostream_formatter | ||
794 | {}; | ||
795 | template<> | ||
796 | struct fmt::formatter<vn::protocol::uart::PpsSource> : ostream_formatter | ||
797 | {}; | ||
798 | template<> | ||
799 | struct fmt::formatter<vn::protocol::uart::GpsRate> : ostream_formatter | ||
800 | {}; | ||
801 | template<> | ||
802 | struct fmt::formatter<vn::protocol::uart::AntPower> : ostream_formatter | ||
803 | {}; | ||
804 | template<> | ||
805 | struct fmt::formatter<vn::protocol::uart::VpeEnable> : ostream_formatter | ||
806 | {}; | ||
807 | template<> | ||
808 | struct fmt::formatter<vn::protocol::uart::HeadingMode> : ostream_formatter | ||
809 | {}; | ||
810 | template<> | ||
811 | struct fmt::formatter<vn::protocol::uart::VpeMode> : ostream_formatter | ||
812 | {}; | ||
813 | template<> | ||
814 | struct fmt::formatter<vn::protocol::uart::Scenario> : ostream_formatter | ||
815 | {}; | ||
816 | template<> | ||
817 | struct fmt::formatter<vn::protocol::uart::HsiMode> : ostream_formatter | ||
818 | {}; | ||
819 | template<> | ||
820 | struct fmt::formatter<vn::protocol::uart::HsiOutput> : ostream_formatter | ||
821 | {}; | ||
822 | template<> | ||
823 | struct fmt::formatter<vn::protocol::uart::VelocityCompensationMode> : ostream_formatter | ||
824 | {}; | ||
825 | template<> | ||
826 | struct fmt::formatter<vn::protocol::uart::MagneticMode> : ostream_formatter | ||
827 | {}; | ||
828 | template<> | ||
829 | struct fmt::formatter<vn::protocol::uart::ExternalSensorMode> : ostream_formatter | ||
830 | {}; | ||
831 | template<> | ||
832 | struct fmt::formatter<vn::protocol::uart::FoamInit> : ostream_formatter | ||
833 | {}; | ||
834 | template<> | ||
835 | struct fmt::formatter<vn::protocol::uart::SensSat> : ostream_formatter | ||
836 | {}; | ||
837 | template<> | ||
838 | struct fmt::formatter<vn::protocol::uart::InsStatus> : ostream_formatter | ||
839 | {}; | ||
840 | |||
841 | template<> | ||
842 | struct fmt::formatter<NAV::vendor::vectornav::SatSys> : ostream_formatter | ||
843 | {}; | ||
844 | template<> | ||
845 | struct fmt::formatter<NAV::vendor::vectornav::RawMeas::SatRawElement::Chan> : ostream_formatter | ||
846 | {}; | ||
847 | template<> | ||
848 | struct fmt::formatter<NAV::vendor::vectornav::RawMeas::SatRawElement::Freq> : ostream_formatter | ||
849 | {}; | ||
850 | |||
851 | template<size_t tdim, typename T> | ||
852 | struct fmt::formatter<vn::math::vec<tdim, T>> : ostream_formatter | ||
853 | {}; | ||
854 | |||
855 | template<size_t m, size_t n, typename T> | ||
856 | struct fmt::formatter<vn::math::mat<m, n, T>> : ostream_formatter | ||
857 | {}; | ||
858 | |||
859 | #endif | ||
860 |