QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
UBXMessageSchema.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstdint>
5#include <cstdlib>
6#include <limits>
7#include <span>
8#include <tuple>
9
10#include "GPSProtocolMath.h"
11#include "UBX/UBXFrame.h"
12#include "WireFields.h"
13
16namespace UBX {
17
19{
20 static constexpr MessageId ID = Msg::NAV_HPPOSLLH;
21 int8_t flags;
22 int32_t lon;
23 int32_t lat;
24 int32_t height;
25 int32_t hMSL;
26 int8_t lonHp;
27 int8_t latHp;
28 int8_t heightHp;
29 int8_t hMSLHp;
30 uint32_t hAcc;
31 uint32_t vAcc;
32};
33
34struct NavDop
35{
36 static constexpr MessageId ID = Msg::NAV_DOP;
37 uint16_t vDOP;
38 uint16_t hDOP;
39};
40
41struct NavPvt
42{
43 static constexpr MessageId ID = Msg::NAV_PVT;
44 uint16_t year;
45 uint8_t month;
46 uint8_t day;
47 uint8_t hour;
48 uint8_t min;
49 uint8_t sec;
50 uint8_t valid;
51 int32_t nano;
52 uint8_t fixType;
53 uint8_t flags;
54 uint8_t numSV;
55 int32_t lon;
56 int32_t lat;
57 int32_t height;
58 int32_t hMSL;
59 uint32_t hAcc;
60 uint32_t vAcc;
61 int32_t gSpeed;
62 int32_t headMot;
63};
64
66{
67 static constexpr MessageId ID = Msg::NAV_STATUS;
68 uint8_t flags2;
69};
70
71struct NavSvin
72{
73 static constexpr MessageId ID = Msg::NAV_SVIN;
74 uint32_t dur;
75 int32_t meanX;
76 int32_t meanY;
77 int32_t meanZ;
78 int8_t meanXHP;
79 int8_t meanYHP;
80 int8_t meanZHP;
81 uint32_t meanAcc;
82 uint8_t valid;
83 uint8_t active;
84};
85
86struct NavSat
87{
88 uint8_t numSvs;
89};
90
92{
93 uint8_t gnssId;
94 uint32_t flags;
95};
96
98{
99 uint8_t numCh;
100};
101
103{
104 uint8_t flags;
105};
106
108struct MonHw
109{
110 static constexpr MessageId ID = Msg::MON_HW;
111 uint8_t aStatus;
112 uint8_t flags;
113};
114
116{
117 uint8_t flags;
118 uint8_t antStatus;
119};
120
122struct MonRf
123{
124 static constexpr MessageId ID = Msg::MON_RF;
126};
127
129struct SecSig
130{
131 static constexpr MessageId ID = Msg::SEC_SIG;
132 uint8_t version;
133 uint8_t flags;
134 uint8_t jamFlags;
135};
136
137struct MonVer
138{
139 uint8_t swVersion[30];
140 uint8_t hwVersion[10];
141};
142
144{
145 uint8_t extension[30];
146};
147
149struct Ack
150{
151 static constexpr MessageId ID = Msg::ACK_ACK;
152 uint16_t msg;
153};
154
155struct CfgPrt
156{
157 uint8_t portID = 0;
158 uint32_t mode = 0;
159 uint32_t baudRate = 0;
160 uint16_t inProtoMask = 0;
161 uint16_t outProtoMask = 0;
162};
163
165{
166 uint16_t measRate = 0;
167 uint16_t navRate = 0;
168 uint16_t timeRef = 0;
169};
170
172{
173 uint16_t mask = 0;
174 uint8_t dynModel = 0;
175 uint8_t fixMode = 0;
176};
177
178struct CfgMsg
179{
180 uint16_t msg = 0;
181 uint8_t rate = 0;
182};
183
186{
187 static constexpr MessageId ID = Msg::CFG_MSG;
188 uint16_t msg;
189 uint8_t rates[6];
190};
191
193{
194 uint16_t flags = 0;
195 int32_t ecefXOrLat = 0;
196 int32_t ecefYOrLon = 0;
197 int32_t ecefZOrAlt = 0;
198 int8_t ecefXOrLatHP = 0;
199 int8_t ecefYOrLonHP = 0;
200 int8_t ecefZOrAltHP = 0;
201 uint32_t fixedPosAcc = 0;
202 uint32_t svinMinDur = 0;
203 uint32_t svinAccLimit = 0;
204};
205
206} // namespace UBX
207
208namespace Wire {
209template <>
210struct Layout<UBX::NavHpposllh>
211{
213 static constexpr size_t SIZE = 36;
218};
219
220template <>
221struct Layout<UBX::NavDop>
222{
223 using T = UBX::NavDop;
224 static constexpr size_t SIZE = 18;
225 static constexpr auto FIELDS = std::tuple{Field<&T::vDOP, 10>{}, Field<&T::hDOP, 12>{}};
226};
227
228template <>
240
241template <>
242struct Layout<UBX::NavStatus>
243{
245 static constexpr size_t SIZE = 16;
246 static constexpr auto FIELDS = std::tuple{Field<&T::flags2, 7>{}};
247};
248
249template <>
250struct Layout<UBX::NavSvin>
251{
253 static constexpr size_t SIZE = 40;
258};
259
260template <>
261struct Layout<UBX::NavSat>
262{
263 using T = UBX::NavSat;
264 static constexpr size_t SIZE = 8;
265 static constexpr auto FIELDS = std::tuple{Field<&T::numSvs, 5>{}};
266};
267
268template <>
269struct Layout<UBX::NavSatSatellite>
270{
272 static constexpr size_t SIZE = 12;
273 static constexpr auto FIELDS = std::tuple{Field<&T::gnssId, 0>{}, Field<&T::flags, 8>{}};
274};
275
276template <>
277struct Layout<UBX::NavSvinfo>
278{
280 static constexpr size_t SIZE = 8;
281 static constexpr auto FIELDS = std::tuple{Field<&T::numCh, 4>{}};
282};
283
284template <>
285struct Layout<UBX::NavSvinfoChannel>
286{
288 static constexpr size_t SIZE = 12;
289 static constexpr auto FIELDS = std::tuple{Field<&T::flags, 2>{}};
290};
291
292template <>
293struct Layout<UBX::MonHw>
294{
295 using T = UBX::MonHw;
296 static constexpr size_t SIZE = 60;
297 static constexpr auto FIELDS = std::tuple{Field<&T::aStatus, 20>{}, Field<&T::flags, 22>{}};
298};
299
300template <>
301struct Layout<UBX::MonRfBlock>
302{
304 static constexpr size_t SIZE = 24;
305 static constexpr auto FIELDS = std::tuple{Field<&T::flags, 1>{}, Field<&T::antStatus, 2>{}};
306};
307
308template <>
309struct Layout<UBX::MonRf>
310{
311 using T = UBX::MonRf;
312 static constexpr size_t SIZE = 28;
313 static constexpr auto FIELDS = std::tuple{Field<&T::block, 4>{}};
314};
315
316template <>
317struct Layout<UBX::SecSig>
318{
319 using T = UBX::SecSig;
320 static constexpr size_t SIZE = 5;
321 static constexpr auto FIELDS = std::tuple{Field<&T::version, 0>{}, Field<&T::flags, 1>{}, Field<&T::jamFlags, 4>{}};
322};
323
324template <>
325struct Layout<UBX::MonVer>
326{
327 using T = UBX::MonVer;
328 static constexpr size_t SIZE = 40;
329 static constexpr auto FIELDS = std::tuple{Field<&T::swVersion, 0>{}, Field<&T::hwVersion, 30>{}};
330};
331
332template <>
333struct Layout<UBX::MonVerExtension>
334{
336 static constexpr size_t SIZE = 30;
337 static constexpr auto FIELDS = std::tuple{Field<&T::extension, 0>{}};
338};
339
340template <>
341struct Layout<UBX::Ack>
342{
343 using T = UBX::Ack;
344 static constexpr size_t SIZE = 2;
345 static constexpr auto FIELDS = std::tuple{Field<&T::msg, 0>{}};
346};
347
348template <>
349struct Layout<UBX::CfgPrt>
350{
351 using T = UBX::CfgPrt;
352 static constexpr size_t SIZE = 20;
355};
356
357template <>
358struct Layout<UBX::CfgRate>
359{
361 static constexpr size_t SIZE = 6;
362 static constexpr auto FIELDS =
364};
365
366template <>
367struct Layout<UBX::CfgNav5>
368{
370 static constexpr size_t SIZE = 36;
371 static constexpr auto FIELDS = std::tuple{Field<&T::mask, 0>{}, Field<&T::dynModel, 2>{}, Field<&T::fixMode, 3>{}};
372};
373
374template <>
375struct Layout<UBX::CfgMsg>
376{
377 using T = UBX::CfgMsg;
378 static constexpr size_t SIZE = 3;
379 static constexpr auto FIELDS = std::tuple{Field<&T::msg, 0>{}, Field<&T::rate, 2>{}};
380};
381
382template <>
383struct Layout<UBX::CfgMsgRates>
384{
386 static constexpr size_t SIZE = 8;
387 static constexpr auto FIELDS = std::tuple{Field<&T::msg, 0>{}, Field<&T::rates, 2>{}};
388};
389
390template <>
401} // namespace Wire
402
403namespace UBX {
404template <Wire::Record T>
405inline constexpr size_t WIRE_SIZE = Wire::SIZE<T>;
406
407inline constexpr size_t MAX_CONTROL_PAYLOAD_SIZE = 328;
408inline constexpr float DOP_PER_UNIT = 0.01f;
409
412[[nodiscard]] inline double coordinateDegrees(int32_t value, int64_t limitDegrees)
413{
414 return std::llabs(value) <= limitDegrees * 10'000'000 ? GPSProtocolMath::degreesFromE7(value)
415 : std::numeric_limits<double>::quiet_NaN();
416}
417
418[[nodiscard]] inline double latitudeDegrees(int32_t value)
419{
420 return coordinateDegrees(value, 90);
421}
422
423[[nodiscard]] inline double longitudeDegrees(int32_t value)
424{
425 return coordinateDegrees(value, 180);
426}
427
431{
432 uint16_t message;
433 size_t minimum;
434 size_t maximum;
435 size_t stride;
437};
438
439template <typename T>
440[[nodiscard]] constexpr MessageSchema fixedSchema(int towOffset = -1)
441{
442 return {T::ID.value(), WIRE_SIZE<T>, WIRE_SIZE<T>, 1, towOffset};
443}
444
445template <typename Header, typename Block>
446[[nodiscard]] constexpr MessageSchema repeatedSchema(MessageId message, size_t maximumBlocks)
447{
448 return {message.value(), WIRE_SIZE<Header>, WIRE_SIZE<Header> + WIRE_SIZE<Block> * maximumBlocks, WIRE_SIZE<Block>,
449 -1};
450}
451
452inline constexpr std::array MESSAGE_SCHEMAS = {
453 MessageSchema{Msg::NAV_PVT.value(), 84, WIRE_SIZE<NavPvt>, 8, 0},
454 fixedSchema<NavHpposllh>(4),
455 fixedSchema<NavStatus>(),
456 fixedSchema<NavDop>(0),
457 fixedSchema<NavSvin>(),
458 MessageSchema{Msg::NAV_EOE.value(), 4, 4, 1, 0},
459 repeatedSchema<NavSat, NavSatSatellite>(Msg::NAV_SAT, 255),
460 repeatedSchema<NavSvinfo, NavSvinfoChannel>(Msg::NAV_SVINFO, 255),
461 MessageSchema{Msg::MON_VER.value(), WIRE_SIZE<MonVer>, 4090, WIRE_SIZE<MonVerExtension>, -1},
462 fixedSchema<MonHw>(),
463 repeatedSchema<MonRf, MonRfBlock>(Msg::MON_RF, 254),
464 MessageSchema{Msg::SEC_SIG.value(), 4, 4096, 1, -1},
465 fixedSchema<Ack>(),
466 MessageSchema{Msg::ACK_NAK.value(), WIRE_SIZE<Ack>, WIRE_SIZE<Ack>, 1, -1},
468 fixedSchema<CfgMsgRates>(),
469 MessageSchema{Msg::CFG_TMODE3.value(), WIRE_SIZE<CfgTmode3>, WIRE_SIZE<CfgTmode3>, 1, -1},
470};
471
472[[nodiscard]] constexpr const MessageSchema* messageSchema(uint16_t message)
473{
474 for (const auto& schema : MESSAGE_SCHEMAS) {
475 if (schema.message == message) {
476 return &schema;
477 }
478 }
479 return nullptr;
480}
481
483[[nodiscard]] inline bool validPayload(uint16_t message, std::span<const uint8_t> payload, const MessageSchema* schema)
484{
485 if (!schema) {
486 return true;
487 }
488 if (payload.size() < schema->minimum || payload.size() > schema->maximum ||
489 (payload.size() - schema->minimum) % schema->stride != 0) {
490 return false;
491 }
492 switch (message) {
493 case Msg::NAV_SAT.value():
494 return payload.size() == schema->minimum + schema->stride * size_t(payload[5]) && payload[4] == 1;
495 case Msg::NAV_SVINFO.value():
496 return payload.size() == schema->minimum + schema->stride * size_t(payload[4]);
497 case Msg::MON_RF.value():
498 return payload[0] == 0 && payload[1] > 0 &&
499 payload.size() == schema->minimum + schema->stride * (size_t(payload[1]) - 1);
500 case Msg::SEC_SIG.value():
501 return payload[0] == 1
502 ? payload.size() >= 5
503 : (payload[0] == 2 || payload[0] == 3) && payload.size() == 4 + 4 * size_t(payload[3]);
504 default:
505 return true;
506 }
507}
508} // namespace UBX
constexpr double degreesFromE7(int32_t value)
Degrees of a coordinate in 1e-7 degree units, as u-blox and MAVLink send them.
constexpr MessageId NAV_SVIN
Definition UBXFrame.h:51
constexpr MessageId ACK_NAK
Definition UBXFrame.h:59
constexpr MessageId MON_HW
Definition UBXFrame.h:69
constexpr MessageId MON_RF
Definition UBXFrame.h:70
constexpr MessageId SEC_SIG
Definition UBXFrame.h:71
constexpr MessageId NAV_EOE
Definition UBXFrame.h:52
constexpr MessageId ACK_ACK
Definition UBXFrame.h:60
constexpr MessageId NAV_STATUS
Definition UBXFrame.h:44
constexpr MessageId NAV_DOP
Definition UBXFrame.h:45
constexpr MessageId CFG_VALGET
Definition UBXFrame.h:67
constexpr MessageId NAV_SAT
Definition UBXFrame.h:50
constexpr MessageId MON_VER
Definition UBXFrame.h:68
constexpr MessageId NAV_SVINFO
Definition UBXFrame.h:49
constexpr MessageId CFG_MSG
Definition UBXFrame.h:62
constexpr MessageId CFG_TMODE3
Definition UBXFrame.h:65
constexpr MessageId NAV_HPPOSLLH
Definition UBXFrame.h:47
constexpr MessageId NAV_PVT
Definition UBXFrame.h:46
u-blox receivers over UBX: CFG-VALSET configuration from protocol 27, CFG-MSG and CFG-TMODE3 before i...
constexpr const MessageSchema * messageSchema(uint16_t message)
bool validPayload(uint16_t message, std::span< const uint8_t > payload, const MessageSchema *schema)
constexpr size_t WIRE_SIZE
double longitudeDegrees(int32_t value)
constexpr MessageSchema repeatedSchema(MessageId message, size_t maximumBlocks)
double latitudeDegrees(int32_t value)
constexpr std::array MESSAGE_SCHEMAS
constexpr size_t MAX_CONTROL_PAYLOAD_SIZE
double coordinateDegrees(int32_t value, int64_t limitDegrees)
constexpr MessageSchema fixedSchema(int towOffset=-1)
constexpr float DOP_PER_UNIT
constexpr std::size_t SIZE
Definition WireFields.h:28
ACK-ACK and ACK-NAK.
static constexpr MessageId ID
A CFG-MSG poll reply: the message's output rate on each I/O port.
static constexpr MessageId ID
uint16_t outProtoMask
uint16_t inProtoMask
uint16_t timeRef
0 UTC, 1 GPS time
uint16_t measRate
ms
uint16_t navRate
measurement cycles
uint16_t flags
mode in bits 7..0, lla in bit 8
constexpr uint16_t value() const
Definition UBXFrame.h:27
MON-HW of u-blox 7 and later; protocol 27 deprecates it for MON-RF.
uint8_t flags
jammingState in bits 3..2
static constexpr MessageId ID
uint8_t flags
jammingState in bits 1..0
MON-RF with its first RF block; F9P reports two blocks and X20 three.
MonRfBlock block
static constexpr MessageId ID
uint8_t swVersion[30]
uint8_t hwVersion[10]
static constexpr MessageId ID
uint16_t hDOP
0.01
uint16_t vDOP
0.01
static constexpr MessageId ID
int8_t hMSLHp
0.1 mm
int32_t lon
1e-7 deg
uint32_t vAcc
0.1 mm
int32_t hMSL
mm above mean sea level
int8_t heightHp
0.1 mm
int8_t flags
invalidLlh
int8_t latHp
1e-9 deg
int32_t height
mm above the ellipsoid
int32_t lat
1e-7 deg
int8_t lonHp
1e-9 deg
uint32_t hAcc
0.1 mm
uint8_t valid
validDate, validTime, fullyResolved
int32_t headMot
1e-5 deg
int32_t gSpeed
mm/s
static constexpr MessageId ID
uint8_t flags
gnssFixOK, diffSoln, carrSoln in bits 7..6
uint32_t flags
svUsed in bit 3
uint8_t flags2
spoofDetState in bits 4..3
static constexpr MessageId ID
static constexpr MessageId ID
int8_t meanXHP
0.1 mm
uint32_t meanAcc
0.1 mm
uint8_t flags
svUsed in bit 0
SEC-SIG header: v2 and v3 flags, or v1 jamFlags; the per-band groups that follow are not read.
static constexpr MessageId ID