QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
UBXPlan.cc
Go to the documentation of this file.
1#include "UBX/UBXPlan.h"
2
3#include <algorithm>
4
5#include "GPSProtocolMath.h"
6
7namespace UBX::Plan {
8namespace {
9
11struct Observations
12{
13 std::array<MsgOutKey, 4> keys;
14 std::array<MessageId, 4> messages;
15};
16
24
25constexpr uint32_t LEGACY_PORT_MODE_8N1 = 0x08d0;
26constexpr uint16_t LEGACY_PROTOCOL_UBX = 1 << 0;
27constexpr uint16_t LEGACY_PROTOCOL_NMEA = 1 << 1;
28constexpr uint16_t LEGACY_PROTOCOL_RTCM3 = 1 << 5;
29
31uint32_t accuracyWireUnits(double accuracyMeters)
32{
33 return GPSProtocolMath::tenthMillimeters(accuracyMeters).value_or(0);
34}
35
38struct FixedPositionWire
39{
40 int32_t latitude;
41 int8_t latitudeHp;
42 int32_t longitude;
44 int32_t height;
45 int8_t heightHp;
46};
47
48FixedPositionWire fixedPositionWire(const GPSEllipsoidPosition& position)
49{
50 const auto latitude = static_cast<int64_t>(position.latitudeDegrees * 1e9);
51 const auto longitude = static_cast<int64_t>(position.longitudeDegrees * 1e9);
52 const auto height = static_cast<int64_t>(position.altitudeMeters * 1e4);
53 return {static_cast<int32_t>(latitude / 100), static_cast<int8_t>(latitude % 100),
54 static_cast<int32_t>(longitude / 100), static_cast<int8_t>(longitude % 100),
55 static_cast<int32_t>(height / 100), static_cast<int8_t>(height % 100)};
56}
57
58} // namespace
59
71
72ValsetBatch uart1Baudrate(uint32_t baudrate)
73{
74 return {.policy = NakPolicy::Tolerate, .items = {{Cfg::UART1_BAUDRATE, baudrate}}};
75}
76
77std::vector<ValsetBatch> portsAndNavigation(const ReceiverProfile& profile)
78{
79 return {
80 // UBX on USB, and RTCM3 output on both ports. USB keeps NMEA output, which the base ignores, so NMEA consumers
81 // work after the session; UART1 gets none, as it typically feeds a correction radio.
82 {.items = {{Cfg::UART1INPROT_RTCM3X, 0},
90 // SPARTN input (PointPerfect) is off; receivers without SPARTN reject it.
91 {.policy = NakPolicy::Tolerate, .items = {{Cfg::UART1INPROT_SPARTN, 0}, {Cfg::USBINPROT_SPARTN, 0}}},
92 {.items = {{Cfg::NAVSPG_FIXMODE, 3}, // auto 2D/3D
93 {Cfg::NAVSPG_UTCSTANDARD, 3}, // USNO, derived from GPS time
96 {Cfg::RATE_NAV, 1},
97 {Cfg::RATE_TIMEREF, 0}}}, // UTC
98 // Odometer off. The F20 platform (ZED-X20P HPG 2.10+) has no CFG-ODO.
99 {.policy = NakPolicy::Tolerate,
100 .items = {{Cfg::ODO_USE_ODO, 0}, {Cfg::ODO_USE_COG, 0}, {Cfg::ODO_OUTLPVEL, 0}, {Cfg::ODO_OUTLPCOG, 0}}},
101 // RTK fixed mode, on RTK receivers only.
102 {.policy = NakPolicy::Tolerate, .items = {{Cfg::NAVHPG_DGNSSMODE, 3}}},
103 };
104}
105
110
112{
113 return {.policy = NakPolicy::Warn,
114 .warning = "Jamming monitor not supported by this receiver",
115 .items = {{Cfg::ITFM_ENABLE, 1}}};
116}
117
118std::vector<ValsetBatch> messageOutput(const ReceiverProfile& profile)
119{
120 return {
121 // The key is only in app note UBX-21038688, so it has a batch of its own.
122 {.included = profile.l5HealthOverride,
123 .policy = NakPolicy::Warn,
124 .warning = "GPS L5 health override not supported by this receiver",
125 .items = {{Cfg::SIGNAL_HEALTH_L5, 1}}},
126 {.items = {{Cfg::MSGOUT_UBX_NAV_PVT, 1},
133 // Older firmware has no NAV-EOE; epochs then end at their bounded deadline.
134 {.policy = NakPolicy::Tolerate, .items = {{Cfg::MSGOUT_UBX_NAV_EOE, 1}}},
135 // SEC-SIG jammingState (F9 HPG 1.51, X20); MON-RF jammingState stays 0 on that firmware.
136 {.policy = NakPolicy::Tolerate, .items = {{Cfg::MSGOUT_UBX_SEC_SIG, 1}}},
137 // Unused output that u-center or other firmware can leave enabled in non-volatile layers.
138 {.policy = NakPolicy::Warn,
139 .warning = "Could not disable unused messages",
143 };
144}
145
147{
148 return {.policy = NakPolicy::Tolerate,
150 {MSM7.keys[0], NO_OUTPUT},
151 {MSM7.keys[1], NO_OUTPUT},
153 {MSM7.keys[2], NO_OUTPUT},
154 {MSM7.keys[3], NO_OUTPUT},
155 {MSM4.keys[0], NO_OUTPUT},
156 {MSM4.keys[1], NO_OUTPUT},
157 {MSM4.keys[2], NO_OUTPUT},
158 {MSM4.keys[3], NO_OUTPUT}}};
159}
160
162{
163 return {.items = {{Cfg::TMODE_MODE, 0}}};
164}
165
167{
168 return {.items = {{Cfg::TMODE_MODE, 1},
169 {Cfg::TMODE_SVIN_MIN_DUR, static_cast<uint32_t>(survey.duration.count())},
170 {Cfg::TMODE_SVIN_ACC_LIMIT, accuracyWireUnits(survey.accuracyMeters)},
172}
173
175{
176 const auto position = fixedPositionWire(fixed.position);
177 return {.items = {{Cfg::TMODE_MODE, 2},
178 {Cfg::TMODE_POS_TYPE, 1}, // latitude, longitude and height
179 {Cfg::TMODE_LAT, position.latitude},
180 {Cfg::TMODE_LAT_HP, position.latitudeHp},
181 {Cfg::TMODE_LON, position.longitude},
182 {Cfg::TMODE_LON_HP, position.longitudeHp},
183 {Cfg::TMODE_HEIGHT, position.height},
184 {Cfg::TMODE_HEIGHT_HP, position.heightHp},
185 {Cfg::TMODE_FIXED_POS_ACC, accuracyWireUnits(fixed.accuracyMeters)}}};
186}
187
188ValsetBatch rtcmOutput(bool compactObservations)
189{
190 const auto& on = compactObservations ? MSM4 : MSM7;
191 const auto& off = compactObservations ? MSM7 : MSM4;
192 return {.policy = NakPolicy::Tolerate,
194 {Cfg::MSGOUT_RTCM_3X_TYPE1005, 1}, // stationary reference station position
195 {on.keys[0], 1},
196 {on.keys[1], 1},
197 {Cfg::MSGOUT_RTCM_3X_TYPE1230, 1}, // GLONASS code-phase biases
198 {on.keys[2], 1},
199 {on.keys[3], 1},
200 {off.keys[0], NO_OUTPUT},
201 {off.keys[1], NO_OUTPUT},
202 {off.keys[2], NO_OUTPUT},
203 {off.keys[3], NO_OUTPUT},
206}
207
209{
210 return {.policy = NakPolicy::WriteOnly, .items = {{key, NO_OUTPUT}}};
211}
212
213std::array<uint8_t, 2 * WIRE_SIZE<CfgPrt>> legacyPorts(uint32_t baudrate)
214{
215 std::array<uint8_t, 2 * WIRE_SIZE<CfgPrt>> payload{};
216 auto next = payload.begin();
217 for (const uint16_t id : {LEGACY_PORT_UART1, LEGACY_PORT_USB}) {
218 const uint16_t nmea = id == LEGACY_PORT_USB ? LEGACY_PROTOCOL_NMEA : 0;
219 const auto port = Wire::encode(
220 CfgPrt{.portID = static_cast<uint8_t>(id),
221 .mode = LEGACY_PORT_MODE_8N1,
222 .baudRate = baudrate,
223 .inProtoMask = LEGACY_PROTOCOL_UBX,
224 .outProtoMask = static_cast<uint16_t>(LEGACY_PROTOCOL_UBX | nmea | LEGACY_PROTOCOL_RTCM3)});
225 next = std::copy(port.begin(), port.end(), next);
226 }
227 return payload;
228}
229
230std::array<MessageRate, 5> legacyMessageOutput()
231{
232 return {{{Msg::NAV_PVT, 1}, {Msg::NAV_STATUS, 1}, {Msg::NAV_DOP, 1}, {Msg::NAV_SVINFO, 5}, {Msg::MON_HW, 1}}};
233}
234
235std::array<MessageRate, 10> legacyDisableRTCMOutput()
236{
237 return {{{Msg::RTCM3_1005, NO_OUTPUT},
239 {MSM7.messages[0], NO_OUTPUT},
240 {MSM7.messages[1], NO_OUTPUT},
241 {MSM7.messages[2], NO_OUTPUT},
242 {MSM7.messages[3], NO_OUTPUT},
243 {MSM4.messages[0], NO_OUTPUT},
244 {MSM4.messages[1], NO_OUTPUT},
245 {MSM4.messages[2], NO_OUTPUT},
246 {MSM4.messages[3], NO_OUTPUT}}};
247}
248
249std::array<MessageRate, 2> legacyBaseStatus()
250{
252}
253
254std::array<RTCMOutput, 6> legacyRTCMOutput(bool compactObservations)
255{
256 const auto& observations = compactObservations ? MSM4 : MSM7;
257 return {{{{Msg::RTCM3_1005, 5}, RTCMContent::StationPosition}, // the station position can be sent at a lower rate
258 {{observations.messages[0], 1}, RTCMContent::Observations},
259 {{observations.messages[1], 1}, RTCMContent::Observations},
261 {{observations.messages[2], 1}, RTCMContent::Observations},
262 {{observations.messages[3], 1}, RTCMContent::Observations}}};
263}
264
266{
267 return {.flags = 1,
268 .svinMinDur = static_cast<uint32_t>(survey.duration.count()),
269 .svinAccLimit = accuracyWireUnits(survey.accuracyMeters)};
270}
271
273{
274 const auto position = fixedPositionWire(fixed.position);
275 return {.flags = 2 | (1 << 8), // fixed mode, latitude/longitude/height
276 .ecefXOrLat = position.latitude,
277 .ecefYOrLon = position.longitude,
278 .ecefZOrAlt = position.height,
279 .ecefXOrLatHP = position.latitudeHp,
280 .ecefYOrLonHP = position.longitudeHp,
281 .ecefZOrAltHP = position.heightHp,
282 .fixedPosAcc = accuracyWireUnits(fixed.accuracyMeters)};
283}
284
285} // namespace UBX::Plan
int8_t latitudeHp
Definition UBXPlan.cc:41
int8_t longitudeHp
Definition UBXPlan.cc:43
std::array< MsgOutKey, 4 > keys
Definition UBXPlan.cc:13
int32_t height
Definition UBXPlan.cc:44
std::array< MessageId, 4 > messages
Definition UBXPlan.cc:14
int8_t heightHp
Definition UBXPlan.cc:45
int32_t latitude
Definition UBXPlan.cc:40
int32_t longitude
Definition UBXPlan.cc:42
GPSPositionReport position(const GPSDecodedPosition &source, const GPSIntegrityReport &diagnostic, uint64_t nowUs)
std::optional< uint32_t > tenthMillimeters(double meters)
meters in 0.1 mm, truncated toward zero. Empty when not finite, negative or beyond a 32-bit unsigned ...
constexpr MsgOutKey MSGOUT_UBX_NAV_PVT
constexpr auto TMODE_LON_HP
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1005
constexpr auto USBINPROT_SPARTN
constexpr auto USBOUTPROT_UBX
constexpr auto TMODE_SVIN_MIN_DUR
constexpr auto TMODE_FIXED_POS_ACC
constexpr MsgOutKey MSGOUT_UBX_RXM_SFRBX
constexpr auto ITFM_ENABLE
constexpr auto USBINPROT_NMEA
constexpr MsgOutKey MSGOUT_UBX_NAV_SVIN
constexpr auto ODO_OUTLPCOG
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1097
constexpr auto TMODE_HEIGHT
constexpr auto UART1OUTPROT_NMEA
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1094
constexpr auto USBINPROT_UBX
constexpr auto UART1_BAUDRATE
constexpr auto NAVSPG_UTCSTANDARD
constexpr auto TMODE_HEIGHT_HP
constexpr auto SEC_JAMDET_SENSITIVITY_HI
constexpr MsgOutKey MSGOUT_UBX_NAV_RELPOSNED
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1087
constexpr auto RATE_NAV
constexpr MsgOutKey MSGOUT_UBX_RXM_RAWX
constexpr auto UART1_PARITY
constexpr auto TMODE_POS_TYPE
constexpr auto UART1_STOPBITS
constexpr auto TMODE_MODE
constexpr auto TMODE_SVIN_ACC_LIMIT
constexpr auto UART1INPROT_SPARTN
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1084
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1077
constexpr auto USBINPROT_RTCM3X
constexpr auto SIGNAL_HEALTH_L5
constexpr auto UART1OUTPROT_RTCM3X
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1124
constexpr MsgOutKey MSGOUT_UBX_NAV_STATUS
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1230
constexpr auto TMODE_LON
constexpr MsgOutKey MSGOUT_UBX_NAV_DOP
constexpr auto UART1INPROT_RTCM3X
constexpr auto NAVHPG_DGNSSMODE
constexpr auto USBOUTPROT_NMEA
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1127
constexpr MsgOutKey MSGOUT_UBX_NAV_EOE
constexpr MsgOutKey MSGOUT_RTCM_3X_TYPE1074
constexpr auto NAVSPG_FIXMODE
constexpr auto UART1OUTPROT_UBX
constexpr MsgOutKey MSGOUT_UBX_MON_RF
constexpr auto ODO_USE_COG
constexpr auto NAVSPG_DYNMODEL
constexpr auto UART1INPROT_UBX
constexpr auto TMODE_LAT
constexpr auto UART1_DATABITS
constexpr auto UART1INPROT_NMEA
constexpr auto ODO_USE_ODO
constexpr auto TMODE_LAT_HP
constexpr MsgOutKey MSGOUT_UBX_NAV_TIMEGPS
constexpr auto USBOUTPROT_RTCM3X
constexpr MsgOutKey MSGOUT_UBX_NAV_SAT
constexpr auto RATE_TIMEREF
constexpr MsgOutKey MSGOUT_UBX_SEC_SIG
constexpr auto RATE_MEAS
constexpr MsgOutKey MSGOUT_UBX_NAV_HPPOSLLH
constexpr auto ODO_OUTLPVEL
constexpr MessageId NAV_SVIN
Definition UBXFrame.h:51
constexpr MessageId RTCM3_1074
Definition UBXFrame.h:73
constexpr MessageId MON_HW
Definition UBXFrame.h:69
constexpr MessageId RTCM3_1124
Definition UBXFrame.h:79
constexpr MessageId RTCM3_1077
Definition UBXFrame.h:74
constexpr MessageId RTCM3_1127
Definition UBXFrame.h:80
constexpr MessageId NAV_STATUS
Definition UBXFrame.h:44
constexpr MessageId NAV_DOP
Definition UBXFrame.h:45
constexpr MessageId RTCM3_1097
Definition UBXFrame.h:78
constexpr MessageId RTCM3_1230
Definition UBXFrame.h:81
constexpr MessageId RTCM3_1087
Definition UBXFrame.h:76
constexpr MessageId NAV_SVINFO
Definition UBXFrame.h:49
constexpr MessageId RTCM3_1005
Definition UBXFrame.h:72
constexpr MessageId RTCM3_1084
Definition UBXFrame.h:75
constexpr MessageId NAV_PVT
Definition UBXFrame.h:46
constexpr MessageId RTCM3_1094
Definition UBXFrame.h:77
ValsetBatch rtcmOutput(bool compactObservations)
Base output at 1 Hz: station position, observations in the selected MSM format and GLONASS biases.
Definition UBXPlan.cc:188
constexpr uint8_t NO_OUTPUT
Definition UBXPlan.h:131
ValsetBatch fixedBase(const GPSBaseStationConfig::Fixed &fixed)
Definition UBXPlan.cc:174
ValsetBatch jammingDetection()
Probes CFG-SEC-JAMDET, which F9 HPG 1.50+, F9 L1L5 and X20 have instead of CFG-ITFM.
Definition UBXPlan.cc:106
std::array< MessageRate, 5 > legacyMessageOutput()
NAV-PVT, status, satellite and MON-HW (antenna and jamming) rates during the survey.
Definition UBXPlan.cc:230
ValsetBatch disableRTCMOutput()
Stops RTCM output, including observations a previous session left in the other MSM format.
Definition UBXPlan.cc:146
constexpr uint8_t SURVEY_SATELLITE_RATE
NAV-SAT every tenth survey epoch.
Definition UBXPlan.h:135
ValsetBatch interferenceMonitor()
Enables the interference monitor of firmware without CFG-SEC-JAMDET.
Definition UBXPlan.cc:111
constexpr uint16_t BASE_MEASUREMENT_PERIOD_MS
RTCM output only needs 1 Hz; the survey keeps the faster navigation rate because it converges faster.
Definition UBXPlan.h:141
constexpr std::chrono::milliseconds PORT_TIMEOUT
Definition UBXPlan.h:115
constexpr uint8_t BASE_SATELLITE_INFO_RATE
Definition UBXPlan.h:138
ValsetBatch uart1Baudrate(uint32_t baudrate)
Definition UBXPlan.cc:72
constexpr uint16_t LEGACY_PORT_UART1
Definition UBXPlan.h:229
std::vector< ValsetBatch > portsAndNavigation(const ReceiverProfile &profile)
Protocol 27+ configuration before jamming detection: ports, navigation, odometer and RTK.
Definition UBXPlan.cc:77
std::array< MessageRate, 10 > legacyDisableRTCMOutput()
Written without waiting for acknowledgements.
Definition UBXPlan.cc:235
CfgTmode3 legacySurveyIn(const GPSBaseStationConfig::SurveyIn &survey)
Definition UBXPlan.cc:265
@ WriteOnly
Required, but written without awaiting the reply.
@ Warn
Optional, but worth a warning.
@ Tolerate
Optional: firmware without these keys rejects them, or the configuration flow decides.
std::vector< ValsetBatch > messageOutput(const ReceiverProfile &profile)
Protocol 27+ configuration after jamming detection: message output and receiver-specific extras.
Definition UBXPlan.cc:118
ValsetBatch uart1Protocols()
Protocol 27+ port setup at the detected baud rate: UBX only on UART1, 8N1.
Definition UBXPlan.cc:60
std::array< uint8_t, 2 *WIRE_SIZE< CfgPrt > > legacyPorts(uint32_t baudrate)
Definition UBXPlan.cc:213
std::array< RTCMOutput, 6 > legacyRTCMOutput(bool compactObservations)
Definition UBXPlan.cc:254
ValsetBatch disableTimeMode()
Definition UBXPlan.cc:161
CfgTmode3 legacyFixedBase(const GPSBaseStationConfig::Fixed &fixed)
Definition UBXPlan.cc:272
ValsetBatch surveyIn(const GPSBaseStationConfig::SurveyIn &survey)
Definition UBXPlan.cc:166
constexpr uint16_t LEGACY_PORT_USB
Definition UBXPlan.h:230
constexpr uint8_t SURVEY_STATUS_RATE
Definition UBXPlan.h:139
ValsetBatch disableMessage(MsgOutKey key)
Disables unexpected output; the reply is not awaited.
Definition UBXPlan.cc:208
std::array< MessageRate, 2 > legacyBaseStatus()
Survey status and satellite rates for the 1 Hz base; rejections are ignored.
Definition UBXPlan.cc:249
constexpr uint8_t STATIONARY_DYNAMIC_MODEL
Base stations always use the stationary navigation model.
Definition UBXPlan.h:133
constexpr std::array< uint8_t, SIZE< T > > encode(const T &value)
Definition WireFields.h:136
GPSEllipsoidPosition position
WGS84 geodetic position with ellipsoid height, not mean-sea-level altitude.
uint16_t flags
mode in bits 7..0, lla in bit 8
A CFG-MSGOUT output rate key family, named by its I2C key.
std::chrono::milliseconds timeout
Definition UBXPlan.h:182
std::vector< ValsetItem > items
Definition UBXPlan.h:184
uint16_t measurementPeriodMs
Definition UBXPlan.h:46
bool l5HealthOverride
GPS L5 is broadcast unhealthy while pre-operational; L1/L5 receivers take the L1 health flag instead.
Definition UBXPlan.h:43