Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
gps_ubx.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
22 
23 #include "modules/gps/gps_ubx.h"
24 #include "modules/core/abi.h"
25 #include "pprzlink/dl_protocol.h"
26 #include "led.h"
27 
28 #ifndef USE_GPS_UBX_RTCM
29 #define USE_GPS_UBX_RTCM 0
30 #endif
31 
32 
33 #if USE_GPS_UBX_RTCM
35 #define RTCM3_PREAMBLE 0xD3
36 #define RTCM3_MSG_1005 0x69
37 #define RTCM3_MSG_1077 0xB1
38 #define RTCM3_MSG_4072 0x72
39 #define RTCM3_MSG_1230 0xE6
40 #define RTCM3_MSG_1087 0xBB
41 #endif
42 
43 #if PRINT_DEBUG_GPS_UBX
44 #define DEBUG_PRINT(...) printf(__VA_ARGS__)
45 #else
46 #define DEBUG_PRINT(...) {}
47 #endif
48 
50 #include "ubx_protocol.h"
51 
52 /* parser status */
53 #define UNINIT 0
54 #define GOT_SYNC1 1
55 #define GOT_SYNC2 2
56 #define GOT_CLASS 3
57 #define GOT_ID 4
58 #define GOT_LEN1 5
59 #define GOT_LEN2 6
60 #define GOT_PAYLOAD 7
61 #define GOT_CHECKSUM1 8
62 
63 #define RXM_RTCM_VERSION 0x02
64 #define NAV_RELPOSNED_VERSION 0x01
65 /* last error type */
66 #define GPS_UBX_ERR_NONE 0
67 #define GPS_UBX_ERR_OVERRUN 1
68 #define GPS_UBX_ERR_MSG_TOO_LONG 2
69 #define GPS_UBX_ERR_CHECKSUM 3
70 #define GPS_UBX_ERR_UNEXPECTED 4
71 #define GPS_UBX_ERR_OUT_OF_SYNC 5
72 
73 #define UTM_HEM_NORTH 0
74 #define UTM_HEM_SOUTH 1
75 
76 struct GpsUbx gps_ubx;
77 
78 #if USE_GPS_UBX_RXM_RAW
79 struct GpsUbxRaw gps_ubx_raw;
80 #endif
81 
82 #if USE_GPS_UBX_RTCM
83 extern struct GpsRelposNED gps_relposned;
84 extern struct RtcmMan rtcm_man;
85 
86 #ifndef INJECT_BUFF_SIZE
87 #define INJECT_BUFF_SIZE 1024 + 6
88 #endif
89 
90 /* RTCM control struct type */
91 struct rtcm_t {
92  uint32_t nbyte;
93  uint32_t len;
94  uint8_t buff[INJECT_BUFF_SIZE];
95 };
96 struct rtcm_t rtcm = { 0 };
97 
98 #endif
99 
100 #ifndef GPS_UBX_BOOTRESET
101 #define GPS_UBX_BOOTRESET 0
102 #endif
103 
104 void gps_ubx_init(void)
105 {
107  gps_ubx.msg_available = false;
108  gps_ubx.error_cnt = 0;
110  gps_ubx.pacc_valid = false;
111 
113 
115 }
116 
117 void gps_ubx_event(void)
118 {
119  struct link_device *dev = &((UBX_GPS_LINK).device);
120 
121  while (dev->char_available(dev->periph)) {
122  gps_ubx_parse(dev->get_byte(dev->periph));
123  if (gps_ubx.msg_available) {
124  gps_ubx_msg();
125  }
126  }
127 
128  if (gps_ubx.reset > 0) {
129  switch (gps_ubx.reset) {
130  case 1 : ubx_send_cfg_rst(&(UBX_GPS_LINK).device, CFG_RST_BBR_Hotstart, CFG_RST_Reset_Controlled); break;
131  case 2 : ubx_send_cfg_rst(&(UBX_GPS_LINK).device, CFG_RST_BBR_Warmstart, CFG_RST_Reset_Controlled); break;
132  case 3 : ubx_send_cfg_rst(&(UBX_GPS_LINK).device, CFG_RST_BBR_Coldstart, CFG_RST_Reset_Controlled); break;
133  default: DEBUG_PRINT("Unknown reset id: %i", gps_ubx.reset); break;
134  }
135  gps_ubx.reset = 0;
136  }
137 }
138 
140 {
142  if (gps_ubx.msg_available) {
143  gps_ubx.error_cnt++;
145  } else {
146  gps_ubx.msg_class = DL_HITL_UBX_class(buf);
147  gps_ubx.msg_id = DL_HITL_UBX_id(buf);
148  uint8_t l = DL_HITL_UBX_ubx_payload_length(buf);
149  uint8_t *ubx_payload = DL_HITL_UBX_ubx_payload(buf);
150  memcpy(gps_ubx.msg_buf, ubx_payload, l);
151  gps_ubx.msg_available = true;
152  }
153 }
154 
155 static void gps_ubx_parse_nav_pvt(void)
156 {
157  uint8_t flags = UBX_NAV_PVT_flags(gps_ubx.msg_buf);
158 
159  // Copy fix information
160  uint8_t gnssFixOK = bit_is_set(flags, 0);
161  uint8_t diffSoln = bit_is_set(flags, 1);
162  uint8_t carrSoln = (flags & 0xC0) >> 6;
163  if (diffSoln && carrSoln == 2) {
164  gps_ubx.state.fix = 5; // rtk
165  } else if(diffSoln && carrSoln == 1) {
166  gps_ubx.state.fix = 4; // dgnss
167  } else if(gnssFixOK) {
168  gps_ubx.state.fix = 3; // 3D
169  } else {
170  gps_ubx.state.fix = 0;
171  }
172 
173  // Copy time information
174  gps_ubx.state.tow = UBX_NAV_PVT_iTOW(gps_ubx.msg_buf);
175  uint16_t year = UBX_NAV_PVT_year(gps_ubx.msg_buf);
176  uint8_t month = UBX_NAV_PVT_month(gps_ubx.msg_buf);
177  uint8_t day = UBX_NAV_PVT_day(gps_ubx.msg_buf);
178  gps_ubx.state.week = gps_week_number(year, month, day);
179  gps_ubx.state.num_sv = UBX_NAV_PVT_numSV(gps_ubx.msg_buf);
180 
181  // Copy LLA position
182  gps_ubx.state.lla_pos.lat = UBX_NAV_PVT_lat(gps_ubx.msg_buf);
183  gps_ubx.state.lla_pos.lon = UBX_NAV_PVT_lon(gps_ubx.msg_buf);
184  gps_ubx.state.lla_pos.alt = UBX_NAV_PVT_height(gps_ubx.msg_buf);
186 
187  // Ublox gives I4 heading in 1e-5 degrees, apparenty from 0 to 360 degrees (not -180 to 180)
188  // I4 max = 2^31 = 214 * 1e5 * 100 < 360 * 1e7: overflow on angles over 214 deg -> casted to -214 deg
189  // solution: First to radians, and then scale to 1e-7 radians
190  // First x 10 for loosing less resolution, then to radians, then multiply x 10 again
191  gps_ubx.state.course = (RadOfDeg(UBX_NAV_PVT_headMot(gps_ubx.msg_buf) * 10)) * 10;
193  gps_ubx.state.cacc = (RadOfDeg(UBX_NAV_PVT_headAcc(gps_ubx.msg_buf) * 10)) * 10;
194 
195  // Copy HMSL and ground speed
196  gps_ubx.state.hmsl = UBX_NAV_PVT_hMSL(gps_ubx.msg_buf);
198  gps_ubx.state.gspeed = UBX_NAV_PVT_gSpeed(gps_ubx.msg_buf) / 10;
199 
200  // Copy NED velocities
201  gps_ubx.state.ned_vel.x = UBX_NAV_PVT_velN(gps_ubx.msg_buf) / 10;
202  gps_ubx.state.ned_vel.y = UBX_NAV_PVT_velE(gps_ubx.msg_buf) / 10;
203  gps_ubx.state.ned_vel.z = UBX_NAV_PVT_velD(gps_ubx.msg_buf) / 10;
205 
206  // Copy accuracy information
207  gps_ubx.state.pdop = UBX_NAV_PVT_pDOP(gps_ubx.msg_buf);
208  gps_ubx.state.hacc = UBX_NAV_PVT_hAcc(gps_ubx.msg_buf) / 10;
209  gps_ubx.state.vacc = UBX_NAV_PVT_vAcc(gps_ubx.msg_buf) / 10;
210  gps_ubx.state.sacc = UBX_NAV_PVT_sAcc(gps_ubx.msg_buf) / 10;
211 
212  if (!gps_ubx.pacc_valid) {
213  // workaround for PVT only
214  gps_ubx.state.pacc = gps_ubx.state.hacc; // report horizontal accuracy
215  }
216 }
217 
218 static void gps_ubx_parse_nav_sol(void)
219 {
220  // Copy time and fix information
221  uint8_t fix = UBX_NAV_SOL_gpsFix(gps_ubx.msg_buf);
222  if ((fix == GPS_FIX_3D && fix > gps_ubx.state.fix) || fix < GPS_FIX_3D) {
223  // update only if fix is better than current or fix not 3D
224  // leaving fix if in GNSS or RTK mode
225  gps_ubx.state.fix = fix;
226  }
227  gps_ubx.state.tow = UBX_NAV_SOL_iTOW(gps_ubx.msg_buf);
228  gps_ubx.state.week = UBX_NAV_SOL_week(gps_ubx.msg_buf);
229  gps_ubx.state.num_sv = UBX_NAV_SOL_numSV(gps_ubx.msg_buf);
230 
231  // Copy ecef position
232  gps_ubx.state.ecef_pos.x = UBX_NAV_SOL_ecefX(gps_ubx.msg_buf);
233  gps_ubx.state.ecef_pos.y = UBX_NAV_SOL_ecefY(gps_ubx.msg_buf);
234  gps_ubx.state.ecef_pos.z = UBX_NAV_SOL_ecefZ(gps_ubx.msg_buf);
236 
237  // Copy ecef velocity
238  gps_ubx.state.ecef_vel.x = UBX_NAV_SOL_ecefVX(gps_ubx.msg_buf);
239  gps_ubx.state.ecef_vel.y = UBX_NAV_SOL_ecefVY(gps_ubx.msg_buf);
240  gps_ubx.state.ecef_vel.z = UBX_NAV_SOL_ecefVZ(gps_ubx.msg_buf);
242 
243  // Copy accuracy measurements
244  gps_ubx.state.pacc = UBX_NAV_SOL_pAcc(gps_ubx.msg_buf);
245  gps_ubx.state.sacc = UBX_NAV_SOL_sAcc(gps_ubx.msg_buf);
246  gps_ubx.state.pdop = UBX_NAV_SOL_pDOP(gps_ubx.msg_buf);
247  gps_ubx.pacc_valid = true;
248 }
249 
250 static void gps_ubx_parse_nav_posecef(void)
251 {
252  gps_ubx.state.tow = UBX_NAV_POSECEF_iTOW(gps_ubx.msg_buf);
253 
254  // Copy ecef position
255  gps_ubx.state.ecef_pos.x = UBX_NAV_POSECEF_ecefX(gps_ubx.msg_buf);
256  gps_ubx.state.ecef_pos.y = UBX_NAV_POSECEF_ecefY(gps_ubx.msg_buf);
257  gps_ubx.state.ecef_pos.z = UBX_NAV_POSECEF_ecefZ(gps_ubx.msg_buf);
259 
260  // Copy accuracy information
261  gps_ubx.state.pacc = UBX_NAV_POSECEF_pAcc(gps_ubx.msg_buf);
262  gps_ubx.pacc_valid = true;
263 }
264 
265 static void gps_ubx_parse_nav_posllh(void)
266 {
267  // Copy LLA position
268  gps_ubx.state.lla_pos.lat = UBX_NAV_POSLLH_lat(gps_ubx.msg_buf);
269  gps_ubx.state.lla_pos.lon = UBX_NAV_POSLLH_lon(gps_ubx.msg_buf);
270  gps_ubx.state.lla_pos.alt = UBX_NAV_POSLLH_height(gps_ubx.msg_buf);
272 
273  // Copy HMSL
274  gps_ubx.state.hmsl = UBX_NAV_POSLLH_hMSL(gps_ubx.msg_buf);
276 
277  // Copy accuracy information
278  gps_ubx.state.hacc = UBX_NAV_POSLLH_hAcc(gps_ubx.msg_buf) / 10;
279  gps_ubx.state.vacc = UBX_NAV_POSLLH_vAcc(gps_ubx.msg_buf) / 10;
280 }
281 
282 static void gps_ubx_parse_nav_posutm(void)
283 {
284  uint8_t hem = UBX_NAV_POSUTM_hem(gps_ubx.msg_buf);
285 
286  // Copy UTM state
287  gps_ubx.state.utm_pos.east = UBX_NAV_POSUTM_east(gps_ubx.msg_buf);
288  gps_ubx.state.utm_pos.north = UBX_NAV_POSUTM_north(gps_ubx.msg_buf);
289  if (hem == UTM_HEM_SOUTH) {
290  gps_ubx.state.utm_pos.north -= 1000000000; /* Subtract false northing: -10000km */
291  }
292  gps_ubx.state.utm_pos.alt = UBX_NAV_POSUTM_alt(gps_ubx.msg_buf) * 10;
293  gps_ubx.state.utm_pos.zone = UBX_NAV_POSUTM_zone(gps_ubx.msg_buf);
295 
296  // Copy HMSL
299 }
300 
301 static void gps_ubx_parse_velecef(void)
302 {
303  gps_ubx.state.tow = UBX_NAV_VELECEF_iTOW(gps_ubx.msg_buf);
304 
305  // Copy ecef velocity
306  gps_ubx.state.ecef_vel.x = UBX_NAV_VELECEF_ecefVX(gps_ubx.msg_buf);
307  gps_ubx.state.ecef_vel.y = UBX_NAV_VELECEF_ecefVY(gps_ubx.msg_buf);
308  gps_ubx.state.ecef_vel.z = UBX_NAV_VELECEF_ecefVZ(gps_ubx.msg_buf);
310 
311  // Copy accuracy measurements
312  gps_ubx.state.sacc = UBX_NAV_VELECEF_sAcc(gps_ubx.msg_buf);
313 }
314 
315 static void gps_ubx_parse_nav_velned(void)
316 {
317  // Copy groundspeed and total 3d speed
318  gps_ubx.state.speed_3d = UBX_NAV_VELNED_speed(gps_ubx.msg_buf);
319  gps_ubx.state.gspeed = UBX_NAV_VELNED_gSpeed(gps_ubx.msg_buf);
320 
321  // Copy NED velocities
322  gps_ubx.state.ned_vel.x = UBX_NAV_VELNED_velN(gps_ubx.msg_buf);
323  gps_ubx.state.ned_vel.y = UBX_NAV_VELNED_velE(gps_ubx.msg_buf);
324  gps_ubx.state.ned_vel.z = UBX_NAV_VELNED_velD(gps_ubx.msg_buf);
326 
327  // Copy course
328  gps_ubx.state.course = (RadOfDeg(UBX_NAV_VELNED_heading(gps_ubx.msg_buf) * 10)) * 10;
329  gps_ubx.state.cacc = (RadOfDeg(UBX_NAV_VELNED_cAcc(gps_ubx.msg_buf) * 10)) * 10;
331 
332  // Copy time of week
333  gps_ubx.state.tow = UBX_NAV_VELNED_iTOW(gps_ubx.msg_buf);
334 }
335 
336 static void gps_ubx_parse_nav_svinfo(void)
337 {
338  // Get the number of channels
339  gps_ubx.state.nb_channels = Min(UBX_NAV_SVINFO_numCh(gps_ubx.msg_buf), GPS_NB_CHANNELS);
340 
341  // Go through all the different channels
342  for (uint8_t i = 0; i < gps_ubx.state.nb_channels; i++) {
343  gps_ubx.state.svinfos[i].svid = UBX_NAV_SVINFO_svid(gps_ubx.msg_buf, i);
344  gps_ubx.state.svinfos[i].flags = UBX_NAV_SVINFO_flags(gps_ubx.msg_buf, i);
345  gps_ubx.state.svinfos[i].qi = UBX_NAV_SVINFO_quality(gps_ubx.msg_buf, i);
346  gps_ubx.state.svinfos[i].cno = UBX_NAV_SVINFO_cno(gps_ubx.msg_buf, i);
347  gps_ubx.state.svinfos[i].elev = UBX_NAV_SVINFO_elev(gps_ubx.msg_buf, i);
348  gps_ubx.state.svinfos[i].azim = UBX_NAV_SVINFO_azim(gps_ubx.msg_buf, i);
349  }
350 }
351 
352 static void gps_ubx_parse_nav_sat(void)
353 {
354  // Get the number of channels(sattelites) and time of week
355  gps_ubx.state.tow = UBX_NAV_SAT_iTOW(gps_ubx.msg_buf);
356  gps_ubx.state.nb_channels = Min(UBX_NAV_SAT_numSvs(gps_ubx.msg_buf), GPS_NB_CHANNELS);
357 
358  // Check the version
359  uint8_t version = UBX_NAV_SAT_version(gps_ubx.msg_buf);
360  if (version != 1) {
361  return;
362  }
363 
364  // Go through all the different channels
365  for (uint8_t i = 0; i < gps_ubx.state.nb_channels; i++) {
366  uint32_t flags = UBX_NAV_SVINFO_flags(gps_ubx.msg_buf, i);
367  gps_ubx.state.svinfos[i].svid = UBX_NAV_SAT_svId(gps_ubx.msg_buf, i);
368  gps_ubx.state.svinfos[i].cno = UBX_NAV_SAT_cno(gps_ubx.msg_buf, i);
369  gps_ubx.state.svinfos[i].elev = UBX_NAV_SAT_elev(gps_ubx.msg_buf, i);
370  gps_ubx.state.svinfos[i].azim = UBX_NAV_SAT_azim(gps_ubx.msg_buf, i);
371  gps_ubx.state.svinfos[i].qi = flags & 0x7;
372  gps_ubx.state.svinfos[i].flags = (flags >> 3) & 0x1;
373  }
374 }
375 
376 static void gps_ubx_parse_nav_status(void)
377 {
378  uint8_t fix = UBX_NAV_STATUS_gpsFix(gps_ubx.msg_buf);
379  if ((fix == GPS_FIX_3D && fix > gps_ubx.state.fix) || fix < GPS_FIX_3D) {
380  // update only if fix is better than current or fix not 3D
381  // leaving fix if in GNSS or RTK mode
382  gps_ubx.state.fix = fix;
383  }
384  gps_ubx.state.tow = UBX_NAV_STATUS_iTOW(gps_ubx.msg_buf);
385  gps_ubx.status_flags = UBX_NAV_STATUS_flags(gps_ubx.msg_buf);
386 }
387 
389 {
390 #if USE_GPS_UBX_RTCM
391  uint8_t version = UBX_NAV_RELPOSNED_version(gps_ubx.msg_buf);
392  if (version <= NAV_RELPOSNED_VERSION) {
393  uint8_t flags = UBX_NAV_RELPOSNED_flags(gps_ubx.msg_buf);
394  uint8_t carrSoln = RTCMgetbitu(&flags, 3, 2);
395  uint8_t relPosValid = RTCMgetbitu(&flags, 5, 1);
396  uint8_t diffSoln = RTCMgetbitu(&flags, 6, 1);
397  uint8_t gnssFixOK = RTCMgetbitu(&flags, 7, 1);
398 
399  /* Only save the latest valid relative position */
400  if (relPosValid) {
401  if (diffSoln && carrSoln == 2) {
402  gps_ubx.state.fix = 5; // rtk
403  } else if(diffSoln && carrSoln == 1) {
404  gps_ubx.state.fix = 4; // dgnss
405  } else if(gnssFixOK) {
406  gps_ubx.state.fix = 3; // 3D
407  } else {
408  gps_ubx.state.fix = 0;
409  }
410 
411  gps_relposned.iTOW = UBX_NAV_RELPOSNED_iTOW(gps_ubx.msg_buf);
412  gps_relposned.refStationId = UBX_NAV_RELPOSNED_refStationId(gps_ubx.msg_buf);
413  gps_relposned.relPosN = UBX_NAV_RELPOSNED_relPosN(gps_ubx.msg_buf);
414  gps_relposned.relPosE = UBX_NAV_RELPOSNED_relPosE(gps_ubx.msg_buf);
415  gps_relposned.relPosD = UBX_NAV_RELPOSNED_relPosD(gps_ubx.msg_buf) ;
416  gps_relposned.relPosHPN = UBX_NAV_RELPOSNED_relPosHPN(gps_ubx.msg_buf);
417  gps_relposned.relPosHPE = UBX_NAV_RELPOSNED_relPosHPE(gps_ubx.msg_buf);
418  gps_relposned.relPosHPD = UBX_NAV_RELPOSNED_relPosHPD(gps_ubx.msg_buf);
419  gps_relposned.accN = UBX_NAV_RELPOSNED_accN(gps_ubx.msg_buf);
420  gps_relposned.accE = UBX_NAV_RELPOSNED_accE(gps_ubx.msg_buf);
421  gps_relposned.accD = UBX_NAV_RELPOSNED_accD(gps_ubx.msg_buf);
422  gps_relposned.carrSoln = carrSoln;
423  gps_relposned.relPosValid = relPosValid;
424  gps_relposned.diffSoln = diffSoln;
425  gps_relposned.gnssFixOK = gnssFixOK;
426  }
427  }
428 #endif
429 }
430 
431 static void gps_ubx_parse_rxm_raw(void)
432 {
433 #if USE_GPS_UBX_RXM_RAW
434  gps_ubx_raw.iTOW = UBX_RXM_RAW_iTOW(gps_ubx.msg_buf);
435  gps_ubx_raw.week = UBX_RXM_RAW_week(gps_ubx.msg_buf);
436  gps_ubx_raw.numSV = UBX_RXM_RAW_numSV(gps_ubx.msg_buf);
437  uint8_t i;
438  uint8_t max_SV = Min(gps_ubx_raw.numSV, GPS_UBX_NB_CHANNELS);
439  for (i = 0; i < max_SV; i++) {
440  gps_ubx_raw.measures[i].cpMes = UBX_RXM_RAW_cpMes(gps_ubx.msg_buf, i);
441  gps_ubx_raw.measures[i].prMes = UBX_RXM_RAW_prMes(gps_ubx.msg_buf, i);
442  gps_ubx_raw.measures[i].doMes = UBX_RXM_RAW_doMes(gps_ubx.msg_buf, i);
443  gps_ubx_raw.measures[i].sv = UBX_RXM_RAW_sv(gps_ubx.msg_buf, i);
444  gps_ubx_raw.measures[i].mesQI = UBX_RXM_RAW_mesQI(gps_ubx.msg_buf, i);
445  gps_ubx_raw.measures[i].cno = UBX_RXM_RAW_cno(gps_ubx.msg_buf, i);
446  gps_ubx_raw.measures[i].lli = UBX_RXM_RAW_lli(gps_ubx.msg_buf, i);
447  }
448 #endif // USE_GPS_UBX_RXM_RAW
449 }
450 
451 static void gps_ubx_parse_rxm_rtcm(void)
452 {
453 #if USE_GPS_UBX_RTCM
454  uint8_t version = UBX_RXM_RTCM_version(gps_ubx.msg_buf);
455  if (version == RXM_RTCM_VERSION) {
456  // uint8_t flags = UBX_RXM_RTCM_flags(gps_ubx.msg_buf);
457  // bool crcFailed = RTCMgetbitu(&flags, 7, 1);
458  // uint16_t refStation = UBX_RXM_RTCM_refStation(gps_ubx.msg_buf);
459  // uint16_t msgType = UBX_RXM_RTCM_msgType(gps_ubx.msg_buf);
460  // DEBUG_PRINT("Message %i from refStation %i processed (CRCfailed: %i)\n", msgType, refStation, crcFailed);
461 
462  rtcm_man.RefStation = UBX_RXM_RTCM_refStation(gps_ubx.msg_buf);
463  rtcm_man.MsgType = UBX_RXM_RTCM_msgType(gps_ubx.msg_buf);
464  uint8_t flags = UBX_RXM_RTCM_flags(gps_ubx.msg_buf);
465  bool crcFailed = RTCMgetbitu(&flags, 7, 1);
466  switch (rtcm_man.MsgType) {
467  case 1005:
468  rtcm_man.Cnt105 += 1;
469  rtcm_man.Crc105 += crcFailed;
470  break;
471  case 1077:
472  rtcm_man.Cnt177 += 1;
473  rtcm_man.Crc177 += crcFailed;;
474  break;
475  case 1087:
476  rtcm_man.Cnt187 += 1;
477  rtcm_man.Crc187 += crcFailed;;
478  break;
479  default:
480  break;
481  }
482  } else {
483  DEBUG_PRINT("Unknown RXM_RTCM version: %i\n", version);
484  }
485 #endif // USE_GPS_UBX_RTCM
486 }
487 
489 {
490 
491  if (gps_ubx.msg_class == UBX_NAV_ID) {
492  switch (gps_ubx.msg_id) {
493  case UBX_NAV_POSECEF_ID:
495  break;
496  case UBX_NAV_POSLLH_ID:
498  break;
499  case UBX_NAV_STATUS_ID:
501  break;
502  case UBX_NAV_SOL_ID:
504  break;
505  case UBX_NAV_PVT_ID:
507  break;
508  case UBX_NAV_POSUTM_ID:
510  break;
511  case UBX_NAV_VELECEF_ID:
513  break;
514  case UBX_NAV_VELNED_ID:
516  break;
517  case UBX_NAV_SVINFO_ID:
519  break;
520  case UBX_NAV_SAT_ID:
522  break;
523  case UBX_NAV_RELPOSNED_ID:
525  break;
526  default:
527  break;
528  }
529  }
530  else if (gps_ubx.msg_class == UBX_RXM_ID) {
531  switch (gps_ubx.msg_id) {
532  case UBX_RXM_RAW_ID:
534  break;
535  case UBX_RXM_RTCM_ID:
537  break;
538  default:
539  break;
540  }
541  }
542 
543 }
544 
545 #if LOG_RAW_GPS
547 #endif
548 
549 /* UBX parsing */
551 {
552 #if LOG_RAW_GPS
553  sdLogWriteByte(pprzLogFile, c);
554 #endif
555  if (gps_ubx.status < GOT_PAYLOAD) {
556  gps_ubx.ck_a += c;
558  }
559  switch (gps_ubx.status) {
560  case UNINIT:
561  if (c == UBX_SYNC1) {
562  gps_ubx.status++;
563  }
564  break;
565  case GOT_SYNC1:
566  if (c != UBX_SYNC2) {
568  goto error;
569  }
570  gps_ubx.ck_a = 0;
571  gps_ubx.ck_b = 0;
572  gps_ubx.status++;
573  break;
574  case GOT_SYNC2:
575  if (gps_ubx.msg_available) {
576  /* Previous message has not yet been parsed: discard this one */
578  goto error;
579  }
580  gps_ubx.msg_class = c;
581  gps_ubx.status++;
582  break;
583  case GOT_CLASS:
584  gps_ubx.msg_id = c;
585  gps_ubx.status++;
586  break;
587  case GOT_ID:
588  gps_ubx.len = c;
589  gps_ubx.status++;
590  break;
591  case GOT_LEN1:
592  gps_ubx.len |= (c << 8);
595  goto error;
596  }
597  gps_ubx.msg_idx = 0;
598  gps_ubx.status++;
599  break;
600  case GOT_LEN2:
602  gps_ubx.msg_idx++;
603  if (gps_ubx.msg_idx >= gps_ubx.len) {
604  gps_ubx.status++;
605  }
606  break;
607  case GOT_PAYLOAD:
608  if (c != gps_ubx.ck_a) {
610  goto error;
611  }
612  gps_ubx.status++;
613  break;
614  case GOT_CHECKSUM1:
615  if (c != gps_ubx.ck_b) {
617  goto error;
618  }
619  gps_ubx.msg_available = true;
620  goto restart;
621  break;
622  default:
624  goto error;
625  }
626  return;
627 error:
628  gps_ubx.error_cnt++;
629 restart:
631  return;
632 }
633 
634 static void ubx_send_1byte(struct link_device *dev, uint8_t byte)
635 {
636  dev->put_byte(dev->periph, 0, byte);
639 }
640 
641 void ubx_header(struct link_device *dev, uint8_t nav_id, uint8_t msg_id, uint16_t len)
642 {
643  dev->put_byte(dev->periph, 0, UBX_SYNC1);
644  dev->put_byte(dev->periph, 0, UBX_SYNC2);
645  gps_ubx.send_ck_a = 0;
646  gps_ubx.send_ck_b = 0;
647  ubx_send_1byte(dev, nav_id);
648  ubx_send_1byte(dev, msg_id);
649  ubx_send_1byte(dev, (uint8_t)(len & 0xFF));
650  ubx_send_1byte(dev, (uint8_t)(len >> 8));
651 }
652 
653 void ubx_trailer(struct link_device *dev)
654 {
655  dev->put_byte(dev->periph, 0, gps_ubx.send_ck_a);
656  dev->put_byte(dev->periph, 0, gps_ubx.send_ck_b);
657  dev->send_message(dev->periph, 0);
658 }
659 
660 void ubx_send_bytes(struct link_device *dev, uint8_t len, uint8_t *bytes)
661 {
662  int i;
663  for (i = 0; i < len; i++) {
664  ubx_send_1byte(dev, bytes[i]);
665  }
666 }
667 
668 void ubx_send_cfg_rst(struct link_device *dev, uint16_t bbr , uint8_t reset_mode)
669 {
670 #ifdef UBX_GPS_LINK
671  UbxSend_CFG_RST(dev, bbr, reset_mode, 0x00);
672 #endif /* else less harmful for HITL */
673 }
674 
675 #ifndef GPS_UBX_UCENTER
676 #define gps_ubx_ucenter_event() {}
677 #else
679 #endif
680 
681 void gps_ubx_msg(void)
682 {
683  // current timestamp
684  uint32_t now_ts = get_sys_time_usec();
685 
690  if (gps_ubx.msg_class == UBX_NAV_ID &&
691  (gps_ubx.msg_id == UBX_NAV_VELNED_ID ||
692  gps_ubx.msg_id == UBX_NAV_PVT_ID ||
693  (gps_ubx.msg_id == UBX_NAV_SOL_ID &&
695  if (gps_ubx.state.fix >= GPS_FIX_3D) {
698 #ifdef GPS_LED
699  LED_ON(GPS_LED);
700  } else {
701  LED_TOGGLE(GPS_LED);
702  }
703 #else
704  }
705 #endif
706  AbiSendMsgGPS(GPS_UBX_ID, now_ts, &gps_ubx.state);
707  }
708  gps_ubx.msg_available = false;
709 }
710 
711 /*
712  * Write bytes to the ublox UART connection
713  * This is a wrapper functions used in the librtcm library
714  */
715 void gps_ublox_write(struct link_device *dev, uint8_t *buff, uint32_t n);
716 void gps_ublox_write(struct link_device *dev, uint8_t *buff, uint32_t n)
717 {
718  uint32_t i = 0;
719  for (i = 0; i < n; i++) {
720  dev->put_byte(dev->periph, 0, buff[i]);
721  }
722  dev->send_message(dev->periph, 0);
723  return;
724 }
725 
729 #if USE_GPS_UBX_RTCM
730 void gps_inject_data(uint8_t packet_id, uint8_t length, uint8_t *data)
731 {
732  uint8_t i;
733 
734  // nothing to do
735  if (length == 0) {
736  return;
737  }
738 
739 #ifdef GPS_UBX_UCENTER
740  // not ready
741  if (gps_ubx_ucenter_get_status() != 0) {
742  return;
743  }
744 #endif
745 
746  // go through buffer
747  for (i = 0; i < length; i++) {
748  if (rtcm.nbyte == 0) {
749  // wait for frame start byte
750  if (data[i] == RTCM3_PREAMBLE) {
751  rtcm.buff[rtcm.nbyte++] = data[i];
752  }
753  } else {
754  // fill buffer
755  if (rtcm.nbyte < INJECT_BUFF_SIZE) {
756  rtcm.buff[rtcm.nbyte++] = data[i];
757  if (rtcm.nbyte == 3) {
758  // extract length
759  rtcm.len = RTCMgetbitu(rtcm.buff, 14, 10) + 3;
760  } else {
761  // wait complete frame
762  if (rtcm.nbyte == rtcm.len + 3) {
763  // check CRC
764  unsigned int crc1 = crc24q(rtcm.buff, rtcm.len);
765  unsigned int crc2 = RTCMgetbitu(rtcm.buff, rtcm.len * 8, 24);
766 
767  if (crc1 == crc2) {
768  // write to GPS
769  gps_ublox_write(&(UBX_GPS_LINK).device, rtcm.buff, rtcm.len + 3);
770  switch (packet_id) {
771  case RTCM3_MSG_1005 : break;
772  case RTCM3_MSG_1077 : break;
773  case RTCM3_MSG_1087 : break;
774  case RTCM3_MSG_4072 : break;
775  case RTCM3_MSG_1230 : break;
776  default: DEBUG_PRINT("Unknown type: %i", packet_id); break;
777  }
778  } else {
779  DEBUG_PRINT("Skipping message %i (CRC failed) - %d", packet_id, rtcm.buff[0]);
780  unsigned int j;
781  for (j = 1; j < rtcm.len; j++) {
782  DEBUG_PRINT(",%d", rtcm.buff[j]);
783  }
784  DEBUG_PRINT("\n");
785  }
786 
787  // reset index
788  rtcm.nbyte = 0;
789  }
790  }
791  } else {
792  // reset index
793  rtcm.nbyte = 0;
794  }
795  }
796  }
797 }
798 
799 #endif
unsigned int RTCMgetbitu(unsigned char *buff, int pos, int lenb)
Definition: CRC24Q.h:54
unsigned int crc24q(const unsigned char *buff, int len)
Definition: CRC24Q.h:44
Main include for ABI (AirBorneInterface).
#define GPS_UBX_ID
#define LED_ON(i)
Definition: led_hw.h:51
#define LED_TOGGLE(i)
Definition: led_hw.h:53
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:71
#define Min(x, y)
Definition: esc_dshot.c:109
uint16_t gps_week_number(uint16_t year, uint8_t month, uint8_t day)
Number of weeks since navigation epoch (6 January 1980)
Definition: gps.c:641
void WEAK gps_inject_data(uint8_t packet_id, uint8_t length, uint8_t *data)
Default parser for GPS injected data.
Definition: gps.c:410
struct RtcmMan rtcm_man
Definition: gps.c:72
struct GpsRelposNED gps_relposned
Definition: gps.c:71
int16_t azim
azimuth in deg
Definition: gps.h:81
uint32_t tow
GPS time of week in ms.
Definition: gps.h:107
uint32_t Cnt105
Definition: gps.h:148
uint8_t qi
quality bitfield (GPS receiver specific)
Definition: gps.h:78
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:92
uint32_t Cnt187
Definition: gps.h:150
uint16_t refStationId
Definition: gps.h:129
uint32_t iTOW
Definition: gps.h:128
int8_t elev
elevation in deg
Definition: gps.h:80
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:90
uint32_t Crc177
Definition: gps.h:152
uint32_t sacc
speed accuracy in cm/s
Definition: gps.h:101
struct UtmCoor_i utm_pos
position in UTM (north,east: cm; alt: mm over MSL)
Definition: gps.h:91
uint32_t cacc
course accuracy in rad*1e7
Definition: gps.h:102
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition: gps.h:97
uint8_t gnssFixOK
Definition: gps.h:142
uint32_t accD
Definition: gps.h:138
uint32_t Crc187
Definition: gps.h:153
#define GPS_VALID_VEL_ECEF_BIT
Definition: gps.h:49
#define GPS_VALID_VEL_NED_BIT
Definition: gps.h:50
uint8_t cno
Carrier to Noise Ratio (Signal Strength) in dbHz.
Definition: gps.h:79
uint32_t accE
Definition: gps.h:137
struct EcefCoor_i ecef_pos
position in ECEF in cm
Definition: gps.h:89
uint32_t hacc
horizontal accuracy in cm
Definition: gps.h:99
#define GPS_VALID_POS_LLA_BIT
Definition: gps.h:47
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:112
int32_t relPosN
Definition: gps.h:130
struct EcefCoor_i ecef_vel
speed ECEF in cm/s
Definition: gps.h:93
#define GPS_NB_CHANNELS
Definition: gps.h:55
uint32_t Crc105
Definition: gps.h:151
uint16_t RefStation
Definition: gps.h:146
uint16_t pdop
position dilution of precision scaled by 100
Definition: gps.h:103
uint8_t diffSoln
Definition: gps.h:141
#define GPS_VALID_POS_ECEF_BIT
Definition: gps.h:46
#define GPS_VALID_HMSL_BIT
Definition: gps.h:51
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:94
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition: gps.h:115
uint8_t svid
Satellite ID.
Definition: gps.h:76
int8_t relPosHPN
Definition: gps.h:133
uint32_t Cnt177
Definition: gps.h:149
uint8_t nb_channels
Number of scanned satellites.
Definition: gps.h:109
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:113
uint32_t pacc
position accuracy in cm
Definition: gps.h:98
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:95
uint8_t valid_fields
bitfield indicating valid fields (GPS_VALID_x_BIT)
Definition: gps.h:86
uint8_t comp_id
id of current gps
Definition: gps.h:87
uint8_t carrSoln
Definition: gps.h:139
uint32_t vacc
vertical accuracy in cm
Definition: gps.h:100
uint8_t relPosValid
Definition: gps.h:140
int32_t relPosE
Definition: gps.h:131
int32_t relPosD
Definition: gps.h:132
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:42
uint16_t speed_3d
norm of 3d speed in cm/s
Definition: gps.h:96
int8_t relPosHPD
Definition: gps.h:135
uint32_t accN
Definition: gps.h:136
struct SVinfo svinfos[GPS_NB_CHANNELS]
holds information from the Space Vehicles (Satellites)
Definition: gps.h:110
uint8_t flags
bitfield with GPS receiver specific flags
Definition: gps.h:77
#define GPS_VALID_COURSE_BIT
Definition: gps.h:52
uint32_t last_msg_ticks
cpu time ticks at last received GPS message
Definition: gps.h:114
int8_t relPosHPE
Definition: gps.h:134
#define GPS_VALID_POS_UTM_BIT
Definition: gps.h:48
uint16_t MsgType
Definition: gps.h:147
uint8_t num_sv
number of sat in fix
Definition: gps.h:104
uint16_t week
GPS week.
Definition: gps.h:106
uint8_t fix
status of fix
Definition: gps.h:105
data structures for GPS with RTK capabilities
Definition: gps.h:127
Definition: gps.h:145
#define GOT_CLASS
Definition: gps_ubx.c:56
void ubx_trailer(struct link_device *dev)
Definition: gps_ubx.c:653
void gps_ubx_parse_HITL_UBX(uint8_t *buf)
Definition: gps_ubx.c:139
void ubx_header(struct link_device *dev, uint8_t nav_id, uint8_t msg_id, uint16_t len)
Definition: gps_ubx.c:641
#define GPS_UBX_ERR_UNEXPECTED
Definition: gps_ubx.c:70
struct GpsUbx gps_ubx
Definition: gps_ubx.c:76
#define GPS_UBX_ERR_OVERRUN
Definition: gps_ubx.c:67
#define UTM_HEM_SOUTH
Definition: gps_ubx.c:74
#define GPS_UBX_BOOTRESET
Definition: gps_ubx.c:101
void gps_ubx_parse(uint8_t c)
Definition: gps_ubx.c:550
static void gps_ubx_parse_nav_svinfo(void)
Definition: gps_ubx.c:336
static void gps_ubx_parse_nav_sat(void)
Definition: gps_ubx.c:352
void gps_ubx_read_message(void)
Definition: gps_ubx.c:488
#define GOT_SYNC2
Definition: gps_ubx.c:55
#define NAV_RELPOSNED_VERSION
Definition: gps_ubx.c:64
static void ubx_send_1byte(struct link_device *dev, uint8_t byte)
Definition: gps_ubx.c:634
#define GPS_UBX_ERR_NONE
Definition: gps_ubx.c:66
void ubx_send_cfg_rst(struct link_device *dev, uint16_t bbr, uint8_t reset_mode)
Definition: gps_ubx.c:668
#define GOT_LEN1
Definition: gps_ubx.c:58
void gps_ublox_write(struct link_device *dev, uint8_t *buff, uint32_t n)
Definition: gps_ubx.c:716
static void gps_ubx_parse_nav_posecef(void)
Definition: gps_ubx.c:250
#define GPS_UBX_ERR_MSG_TOO_LONG
Definition: gps_ubx.c:68
#define GOT_PAYLOAD
Definition: gps_ubx.c:60
#define GOT_SYNC1
Definition: gps_ubx.c:54
#define UNINIT
Includes macros generated from ubx.xml.
Definition: gps_ubx.c:53
#define GOT_CHECKSUM1
Definition: gps_ubx.c:61
#define RXM_RTCM_VERSION
Definition: gps_ubx.c:63
void gps_ubx_event(void)
Definition: gps_ubx.c:117
static void gps_ubx_parse_nav_pvt(void)
Definition: gps_ubx.c:155
#define GOT_ID
Definition: gps_ubx.c:57
#define DEBUG_PRINT(...)
Definition: gps_ubx.c:46
#define GPS_UBX_ERR_CHECKSUM
Definition: gps_ubx.c:69
static void gps_ubx_parse_nav_status(void)
Definition: gps_ubx.c:376
static void gps_ubx_parse_nav_sol(void)
Definition: gps_ubx.c:218
static void gps_ubx_parse_velecef(void)
Definition: gps_ubx.c:301
#define gps_ubx_ucenter_event()
Definition: gps_ubx.c:676
void gps_ubx_init(void)
Definition: gps_ubx.c:104
void gps_ubx_msg(void)
Definition: gps_ubx.c:681
static void gps_ubx_parse_nav_velned(void)
Definition: gps_ubx.c:315
static void gps_ubx_parse_nav_relposned(void)
Definition: gps_ubx.c:388
static void gps_ubx_parse_rxm_raw(void)
Definition: gps_ubx.c:431
static void gps_ubx_parse_nav_posutm(void)
Definition: gps_ubx.c:282
void ubx_send_bytes(struct link_device *dev, uint8_t len, uint8_t *bytes)
Definition: gps_ubx.c:660
static void gps_ubx_parse_nav_posllh(void)
Definition: gps_ubx.c:265
#define GOT_LEN2
Definition: gps_ubx.c:59
static void gps_ubx_parse_rxm_rtcm(void)
Definition: gps_ubx.c:451
#define GPS_UBX_ERR_OUT_OF_SYNC
Definition: gps_ubx.c:71
UBX protocol specific code.
#define CFG_RST_BBR_Coldstart
Definition: gps_ubx.h:126
uint16_t len
Definition: gps_ubx.h:62
uint8_t ck_b
Definition: gps_ubx.h:64
struct GpsState state
Definition: gps_ubx.h:74
#define GPS_UBX_NB_CHANNELS
Definition: gps_ubx.h:52
uint8_t status_flags
Definition: gps_ubx.h:70
uint8_t status
Definition: gps_ubx.h:61
uint8_t reset
Definition: gps_ubx.h:68
#define CFG_RST_Reset_Controlled
Definition: gps_ubx.h:119
#define CFG_RST_BBR_Hotstart
Definition: gps_ubx.h:124
uint8_t msg_class
Definition: gps_ubx.h:59
#define CFG_RST_BBR_Warmstart
Definition: gps_ubx.h:125
uint8_t msg_buf[GPS_UBX_MAX_PAYLOAD]
Definition: gps_ubx.h:57
uint8_t error_cnt
Definition: gps_ubx.h:66
bool pacc_valid
Definition: gps_ubx.h:72
uint8_t send_ck_b
Definition: gps_ubx.h:65
uint8_t send_ck_a
Definition: gps_ubx.h:65
uint8_t msg_id
Definition: gps_ubx.h:58
uint8_t error_last
Definition: gps_ubx.h:67
#define GPS_UBX_MAX_PAYLOAD
Definition: gps_ubx.h:54
bool msg_available
Definition: gps_ubx.h:56
uint8_t ck_a
Definition: gps_ubx.h:64
uint16_t msg_idx
Definition: gps_ubx.h:63
Definition: gps_ubx.h:55
int gps_ubx_ucenter_get_status(void)
Configure Ublox GPS.
int32_t lat
in degrees*1e7
int32_t alt
in millimeters (above WGS84 reference ellipsoid or above MSL)
int32_t alt
in millimeters above WGS84 reference ellipsoid
int32_t z
Down.
int32_t z
in centimeters
uint8_t zone
UTM zone number.
int32_t x
in centimeters
int32_t y
East.
int32_t east
in centimeters
int32_t y
in centimeters
int32_t lon
in degrees*1e7
int32_t x
North.
int32_t north
in centimeters
uint8_t buff[25]
Buffer used for general comunication over SPI (in buffer)
arch independent LED (Light Emitting Diodes) API
#define byte
#define RTCM3_MSG_1005
Definition: rtcm3.h:20
#define RTCM3_MSG_1077
Definition: rtcm3.h:22
#define RTCM3_MSG_4072
Definition: rtcm3.h:21
#define RTCM3_MSG_1230
Definition: rtcm3.h:24
#define RTCM3_MSG_1087
Definition: rtcm3.h:23
#define RTCM3_PREAMBLE
Definition: rtcm3.h:19
FileDes pprzLogFile
Definition: sdlog_chibios.c:86
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98