Paparazzi UAS  v5.15_devel-99-g2ff7410
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
gps.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2011 The Paparazzi Team
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 
40 #include "subsystems/abi.h"
41 #include "subsystems/gps.h"
42 #include "led.h"
43 #include "subsystems/settings.h"
44 #include "generated/settings.h"
46 #include "math/pprz_geodetic.h"
47 
48 #ifndef PRIMARY_GPS
49 #error "PRIMARY_GPS not set!"
50 #else
51 PRINT_CONFIG_VAR(PRIMARY_GPS)
52 #endif
53 
54 #ifdef SECONDARY_GPS
55 PRINT_CONFIG_VAR(SECONDARY_GPS)
56 #endif
57 
58 #ifdef GPS_POWER_GPIO
59 #include "mcu_periph/gpio.h"
60 
61 #ifndef GPS_POWER_GPIO_ON
62 #define GPS_POWER_GPIO_ON gpio_set
63 #endif
64 #endif
65 
66 #define MSEC_PER_WEEK (1000*60*60*24*7)
67 #define TIME_TO_SWITCH 5000 //ten s in ms
68 
69 struct GpsState gps;
70 
74 
75 #ifdef SECONDARY_GPS
76 static uint8_t current_gps_id = GpsId(PRIMARY_GPS);
77 #endif
78 
80 
81 
82 #if PERIODIC_TELEMETRY
84 
85 static void send_svinfo_id(struct transport_tx *trans, struct link_device *dev,
86  uint8_t svid)
87 {
88  if (svid < GPS_NB_CHANNELS) {
89  pprz_msg_send_SVINFO(trans, dev, AC_ID, &svid,
90  &gps.svinfos[svid].svid, &gps.svinfos[svid].flags,
91  &gps.svinfos[svid].qi, &gps.svinfos[svid].cno,
92  &gps.svinfos[svid].elev, &gps.svinfos[svid].azim);
93  }
94 }
95 
97 static void send_svinfo(struct transport_tx *trans, struct link_device *dev)
98 {
99  static uint8_t i = 0;
100  if (i == gps.nb_channels) { i = 0; }
101  send_svinfo_id(trans, dev, i);
102  i++;
103 }
104 
109 static inline void send_svinfo_available(struct transport_tx *trans, struct link_device *dev)
110 {
111  static uint8_t i = 0;
112  static uint8_t last_cnos[GPS_NB_CHANNELS];
113  if (i >= gps.nb_channels) { i = 0; }
114  // send SVINFO for all satellites while no GPS fix,
115  // after 3D fix, send avialable sats if they were updated
116  if (gps.fix < GPS_FIX_3D) {
117  send_svinfo_id(trans, dev, i);
118  } else if (gps.svinfos[i].cno != last_cnos[i]) {
119  send_svinfo_id(trans, dev, i);
120  last_cnos[i] = gps.svinfos[i].cno;
121  }
122  i++;
123 }
124 
125 static void send_gps(struct transport_tx *trans, struct link_device *dev)
126 {
127  uint8_t zero = 0;
128  int16_t climb = -gps.ned_vel.z;
129  int16_t course = (DegOfRad(gps.course) / ((int32_t)1e6));
130  struct UtmCoor_i utm = utm_int_from_gps(&gps, 0);
131 #if PPRZLINK_DEFAULT_VER == 2 && GPS_POS_BROADCAST
132  // broadcast GPS message
133  struct pprzlink_msg msg;
134  msg.trans = trans;
135  msg.dev = dev;
136  msg.sender_id = AC_ID;
137  msg.receiver_id = PPRZLINK_MSG_BROADCAST;
138  msg.component_id = 0;
139  pprzlink_msg_send_GPS(&msg,
140 #else
141  pprz_msg_send_GPS(trans, dev, AC_ID,
142 #endif
143  &gps.fix,
144  &utm.east, &utm.north,
145  &course, &gps.hmsl, &gps.gspeed, &climb,
146  &gps.week, &gps.tow, &utm.zone, &zero);
147  // send SVINFO for available satellites that have new data
148  send_svinfo_available(trans, dev);
149 }
150 
151 static void send_gps_rtk(struct transport_tx *trans, struct link_device *dev)
152 {
153  pprz_msg_send_GPS_RTK(trans, dev, AC_ID,
163 }
164 
165 static void send_gps_rxmrtcm(struct transport_tx *trans, struct link_device *dev)
166 {
167  pprz_msg_send_GPS_RXMRTCM(trans, dev, AC_ID,
168  &rtcm_man.Cnt105,
169  &rtcm_man.Cnt177,
170  &rtcm_man.Cnt187,
171  &rtcm_man.Crc105,
172  &rtcm_man.Crc177,
173  &rtcm_man.Crc187);
174 }
175 
176 static void send_gps_int(struct transport_tx *trans, struct link_device *dev)
177 {
178 #if PPRZLINK_DEFAULT_VER == 2 && GPS_POS_BROADCAST
179  // broadcast GPS message
180  struct pprzlink_msg msg;
181  msg.trans = trans;
182  msg.dev = dev;
183  msg.sender_id = AC_ID;
184  msg.receiver_id = PPRZLINK_MSG_BROADCAST;
185  msg.component_id = 0;
186  pprzlink_msg_send_GPS_INT(&msg,
187 #else
188  pprz_msg_send_GPS_INT(trans, dev, AC_ID,
189 #endif
192  &gps.hmsl,
194  &gps.pacc, &gps.sacc,
195  &gps.tow,
196  &gps.pdop,
197  &gps.num_sv,
198  &gps.fix,
199  &gps.comp_id);
200  // send SVINFO for available satellites that have new data
201  send_svinfo_available(trans, dev);
202 }
203 
204 static void send_gps_lla(struct transport_tx *trans, struct link_device *dev)
205 {
206  uint8_t err = 0;
207  int16_t climb = -gps.ned_vel.z;
208  int16_t course = (DegOfRad(gps.course) / ((int32_t)1e6));
209 #if PPRZLINK_DEFAULT_VER == 2 && GPS_POS_BROADCAST
210  // broadcast GPS message
211  struct pprzlink_msg msg;
212  msg.trans = trans;
213  msg.dev = dev;
214  msg.sender_id = AC_ID;
215  msg.receiver_id = PPRZLINK_MSG_BROADCAST;
216  msg.component_id = 0;
217  pprzlink_msg_send_GPS_LLA(&msg,
218 #else
219  pprz_msg_send_GPS_LLA(trans, dev, AC_ID,
220 #endif
222  &gps.hmsl, &course, &gps.gspeed, &climb,
223  &gps.week, &gps.tow,
224  &gps.fix, &err);
225 }
226 
227 static void send_gps_sol(struct transport_tx *trans, struct link_device *dev)
228 {
229  pprz_msg_send_GPS_SOL(trans, dev, AC_ID, &gps.pacc, &gps.sacc, &gps.pdop, &gps.num_sv);
230 }
231 #endif
232 
233 
234 #ifdef SECONDARY_GPS
235 static uint8_t gps_multi_switch(struct GpsState *gps_s) {
236  static uint32_t time_since_last_gps_switch = 0;
237 
238  if (multi_gps_mode == GPS_MODE_PRIMARY){
239  return GpsId(PRIMARY_GPS);
240  } else if (multi_gps_mode == GPS_MODE_SECONDARY){
241  return GpsId(SECONDARY_GPS);
242  } else{
243  if (gps_s->fix > gps.fix){
244  return gps_s->comp_id;
245  } else if (gps.fix > gps_s->fix){
246  return gps.comp_id;
247  } else{
248  if (get_sys_time_msec() - time_since_last_gps_switch > TIME_TO_SWITCH) {
249  if (gps_s->num_sv > gps.num_sv) {
250  current_gps_id = gps_s->comp_id;
251  time_since_last_gps_switch = get_sys_time_msec();
252  } else if (gps.num_sv > gps_s->num_sv) {
253  current_gps_id = gps.comp_id;
254  time_since_last_gps_switch = get_sys_time_msec();
255  }
256  }
257  }
258  }
259  return current_gps_id;
260 }
261 #endif /*SECONDARY_GPS*/
262 
263 
264 void gps_periodic_check(struct GpsState *gps_s)
265 {
266  if (sys_time.nb_sec - gps_s->last_msg_time > GPS_TIMEOUT) {
267  gps_s->fix = GPS_FIX_NONE;
268  }
269 
270 #ifdef SECONDARY_GPS
271  current_gps_id = gps_multi_switch(gps_s);
272  if (gps_s->comp_id == current_gps_id) {
273  gps = *gps_s;
274  }
275 #else
276  gps = *gps_s;
277 #endif
278 }
279 
280 
282 static void gps_cb(uint8_t sender_id,
283  uint32_t stamp __attribute__((unused)),
284  struct GpsState *gps_s)
285 {
286  /* ignore callback from own AbiSendMsgGPS */
287  if (sender_id == GPS_MULTI_ID) {
288  return;
289  }
290  uint32_t now_ts = get_sys_time_usec();
291 #ifdef SECONDARY_GPS
292  current_gps_id = gps_multi_switch(gps_s);
293  if (gps_s->comp_id == current_gps_id) {
294  gps = *gps_s;
295  AbiSendMsgGPS(GPS_MULTI_ID, now_ts, gps_s);
296  }
297 #else
298  gps = *gps_s;
299  AbiSendMsgGPS(GPS_MULTI_ID, now_ts, gps_s);
300 #endif
301  if (gps.tow != gps_time_sync.t0_tow)
302  {
305  }
306 }
307 
308 
309 void gps_init(void)
310 {
311  multi_gps_mode = MULTI_GPS_MODE;
312 
313  gps.valid_fields = 0;
314  gps.fix = GPS_FIX_NONE;
315  gps.week = 0;
316  gps.tow = 0;
317  gps.cacc = 0;
318  gps.hacc = 0;
319  gps.vacc = 0;
320 
321  gps.last_3dfix_ticks = 0;
322  gps.last_3dfix_time = 0;
323  gps.last_msg_ticks = 0;
324  gps.last_msg_time = 0;
325 
326 #ifdef GPS_POWER_GPIO
328  GPS_POWER_GPIO_ON(GPS_POWER_GPIO);
329 #endif
330 #ifdef GPS_LED
331  LED_OFF(GPS_LED);
332 #endif
333 
334  AbiBindMsgGPS(ABI_BROADCAST, &gps_ev, gps_cb);
335 
336 #if PERIODIC_TELEMETRY
344 #endif
345 
346  // Initializing counter variables to count the number of Rtcm msgs in the input stream(for each msg type)
347  rtcm_man.Cnt105 = 0;
348  rtcm_man.Cnt177 = 0;
349  rtcm_man.Cnt187 = 0;
350  // Initializing counter variables to count the number of messages that failed Crc Check
351  rtcm_man.Crc105 = 0;
352  rtcm_man.Crc177 = 0;
353  rtcm_man.Crc187 = 0;
354 }
355 
357 {
358  uint32_t clock_delta;
359  uint32_t time_delta;
360  uint32_t itow_now;
361 
362  if (sys_ticks < gps_time_sync.t0_ticks) {
363  clock_delta = (0xFFFFFFFF - sys_ticks) + gps_time_sync.t0_ticks + 1;
364  } else {
365  clock_delta = sys_ticks - gps_time_sync.t0_ticks;
366  }
367 
368  time_delta = msec_of_sys_time_ticks(clock_delta);
369 
370  itow_now = gps_time_sync.t0_tow + time_delta;
371  if (itow_now > MSEC_PER_WEEK) {
372  itow_now %= MSEC_PER_WEEK;
373  }
374 
375  return itow_now;
376 }
377 
381 void WEAK gps_inject_data(uint8_t packet_id __attribute__((unused)), uint8_t length __attribute__((unused)), uint8_t *data __attribute__((unused))){
382 
383 }
384 
388 #include "state.h"
390 {
391  struct UtmCoor_f utm = {.east = 0., .north=0., .alt=0., .zone=zone};
392 
393  if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_UTM_BIT)) {
394  /* A real UTM position is available, use the correct zone */
395  UTM_FLOAT_OF_BFP(utm, gps_s->utm_pos);
396  } else if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_LLA_BIT))
397  {
398  /* Recompute UTM coordinates in this zone */
399  struct UtmCoor_i utm_i;
400  utm_i.zone = zone;
401  utm_of_lla_i(&utm_i, &gps_s->lla_pos);
402  UTM_FLOAT_OF_BFP(utm, utm_i);
403 
404  /* set utm.alt in hsml */
405  if (bit_is_set(gps_s->valid_fields, GPS_VALID_HMSL_BIT)) {
406  utm.alt = gps_s->hmsl/1000.;
407  } else {
408  utm.alt = wgs84_ellipsoid_to_geoid_i(gps_s->lla_pos.lat, gps_s->lla_pos.lon)/1000.;
409  }
410  }
411 
412  return utm;
413 }
414 
416 {
417  struct UtmCoor_i utm = {.east = 0, .north=0, .alt=0, .zone=zone};
418 
419  if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_UTM_BIT)) {
420  // A real UTM position is available, use the correct zone
421  UTM_COPY(utm, gps_s->utm_pos);
422  }
423  else if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_LLA_BIT)){
424  /* Recompute UTM coordinates in zone */
425  utm_of_lla_i(&utm, &gps_s->lla_pos);
426 
427  /* set utm.alt in hsml */
428  if (bit_is_set(gps_s->valid_fields, GPS_VALID_HMSL_BIT)) {
429  utm.alt = gps_s->hmsl;
430  } else {
431  utm.alt = wgs84_ellipsoid_to_geoid_i(gps_s->lla_pos.lat, gps_s->lla_pos.lon);
432  }
433  }
434 
435  return utm;
436 }
uint8_t qi
quality bitfield (GPS receiver specific)
Definition: gps.h:80
static void send_gps_int(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:176
Event structure to store callbacks in a linked list.
Definition: abi_common.h:65
int32_t z
in centimeters
uint32_t t0_tow
GPS time of week in ms from last message.
Definition: gps.h:123
int32_t north
in centimeters
struct SVinfo svinfos[GPS_NB_CHANNELS]
holds information from the Space Vehicles (Satellites)
Definition: gps.h:112
int16_t azim
azimuth in deg
Definition: gps.h:83
float east
in meters
uint32_t pacc
position accuracy in cm
Definition: gps.h:100
float alt
in meters (above WGS84 reference ellipsoid or above MSL)
static void send_svinfo_id(struct transport_tx *trans, struct link_device *dev, uint8_t svid)
Definition: gps.c:85
uint8_t nb_channels
Number of scanned satellites.
Definition: gps.h:111
uint32_t Cnt187
Definition: gps.h:152
uint32_t t0_ticks
hw clock ticks when GPS message is received
Definition: gps.h:125
Periodic telemetry system header (includes downlink utility and generated code).
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
Definition: sys_time_arch.c:78
uint8_t valid_fields
bitfield indicating valid fields (GPS_VALID_x_BIT)
Definition: gps.h:88
int32_t y
in centimeters
#define LED_OFF(i)
Definition: led_hw.h:52
uint8_t carrSoln
Definition: gps.h:141
uint32_t hacc
horizontal accuracy in cm
Definition: gps.h:101
uint16_t week
GPS week.
Definition: gps.h:108
Some architecture independent helper functions for GPIOs.
#define GPS_NB_CHANNELS
Definition: gps.h:57
#define TIME_TO_SWITCH
Definition: gps.c:67
int32_t relPosE
Definition: gps.h:133
static uint32_t msec_of_sys_time_ticks(uint32_t ticks)
Definition: sys_time.h:158
#define GpsId(_x)
Definition: gps.h:71
Main include for ABI (AirBorneInterface).
uint32_t vacc
vertical accuracy in cm
Definition: gps.h:102
struct RtcmMan rtcm_man
Definition: gps.c:73
static void send_gps_sol(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:227
static void send_gps(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:125
#define UTM_FLOAT_OF_BFP(_o, _i)
position in UTM coordinates Units: meters
int32_t east
in centimeters
int8_t relPosHPD
Definition: gps.h:137
#define MSEC_PER_WEEK
Definition: gps.c:66
uint8_t svid
Satellite ID.
Definition: gps.h:78
volatile uint32_t nb_tick
SYS_TIME_TICKS since startup.
Definition: sys_time.h:74
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:39
int32_t z
Down.
void gpio_setup_output(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as outputs.
Definition: gpio_arch.c:33
uint8_t diffSoln
Definition: gps.h:143
uint32_t Crc187
Definition: gps.h:155
#define PRIMARY_GPS
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:114
int8_t elev
elevation in deg
Definition: gps.h:82
int32_t alt
in millimeters above WGS84 reference ellipsoid
WGS-84 Geoid Heights.
uint32_t accN
Definition: gps.h:138
uint32_t sacc
speed accuracy in cm/s
Definition: gps.h:103
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition: gps.h:117
uint32_t cacc
course accuracy in rad*1e7
Definition: gps.h:104
uint8_t zone
UTM zone number.
struct UtmCoor_i utm_int_from_gps(struct GpsState *gps_s, uint8_t zone)
Convenience function to get utm position in int from GPS structure.
Definition: gps.c:415
static void send_svinfo_available(struct transport_tx *trans, struct link_device *dev)
send SVINFO message if updated.
Definition: gps.c:109
static abi_event gps_ev
Definition: gps.c:281
int8_t relPosHPE
Definition: gps.h:136
uint32_t Crc105
Definition: gps.h:153
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:94
void WEAK gps_inject_data(uint8_t packet_id, uint8_t length, uint8_t *data)
Default parser for GPS injected data.
Definition: gps.c:381
uint8_t cno
Carrier to Noise Ratio (Signal Strength) in dbHz.
Definition: gps.h:81
data structure for GPS information
Definition: gps.h:87
static void send_gps_lla(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:204
uint32_t tow
GPS time of week in ms.
Definition: gps.h:109
uint32_t Cnt177
Definition: gps.h:151
#define GPS_FIX_NONE
No GPS fix.
Definition: gps.h:37
Device independent GPS code (interface)
uint16_t pdop
position dilution of precision scaled by 100
Definition: gps.h:105
static void send_gps_rxmrtcm(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:165
Definition: gps.h:147
uint8_t multi_gps_mode
Definition: gps.c:79
unsigned long uint32_t
Definition: types.h:18
struct EcefCoor_i ecef_pos
position in ECEF in cm
Definition: gps.h:91
signed short int16_t
Definition: types.h:17
#define GPS_MODE_PRIMARY
Definition: gps.h:61
#define GPS_VALID_HMSL_BIT
Definition: gps.h:53
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
int32_t lon
in degrees*1e7
uint32_t iTOW
Definition: gps.h:130
void utm_of_lla_i(struct UtmCoor_i *utm, struct LlaCoor_i *lla)
Convert a LLA to UTM.
int32_t relPosD
Definition: gps.h:134
uint8_t zone
UTM zone number.
int32_t relPosN
Definition: gps.h:132
signed long int32_t
Definition: types.h:19
uint8_t relPosValid
Definition: gps.h:142
struct GpsRelposNED gps_relposned
Definition: gps.c:72
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:73
static void send_gps_rtk(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:151
static void gps_cb(uint8_t sender_id, uint32_t stamp, struct GpsState *gps_s)
Definition: gps.c:282
int8_t relPosHPN
Definition: gps.h:135
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:115
int32_t alt
in millimeters (above WGS84 reference ellipsoid or above MSL)
uint32_t accE
Definition: gps.h:139
Paparazzi generic macros for geodetic calculations.
unsigned char uint8_t
Definition: types.h:14
static void send_svinfo(struct transport_tx *trans, struct link_device *dev)
send SVINFO message (regardless of state)
Definition: gps.c:97
struct UtmCoor_f utm_float_from_gps(struct GpsState *gps_s, uint8_t zone)
Convenience functions to get utm position from GPS state.
Definition: gps.c:389
API to get/set the generic vehicle states.
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition: gps.h:99
Persistent settings interface.
uint8_t comp_id
id of current gps
Definition: gps.h:89
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
#define GPS_MULTI_ID
#define GPS_MODE_SECONDARY
Definition: gps.h:62
static int16_t course[3]
Definition: airspeed_uADC.c:57
data structures for GPS with RTK capabilities
Definition: gps.h:129
uint32_t accD
Definition: gps.h:140
uint8_t flags
bitfield with GPS receiver specific flags
Definition: gps.h:79
struct GpsTimeSync gps_time_sync
Definition: gps.c:71
#define MULTI_GPS_MODE
Definition: gps.h:65
uint32_t last_msg_ticks
cpu time ticks at last received GPS message
Definition: gps.h:116
#define GPS_VALID_POS_LLA_BIT
Definition: gps.h:49
uint32_t gps_tow_from_sys_ticks(uint32_t sys_ticks)
Convert time in sys_time ticks to GPS time of week.
Definition: gps.c:356
uint8_t num_sv
number of sat in fix
Definition: gps.h:106
uint8_t gnssFixOK
Definition: gps.h:144
arch independent LED (Light Emitting Diodes) API
int32_t x
in centimeters
#define ABI_BROADCAST
Broadcast address.
Definition: abi_common.h:56
uint32_t Cnt105
Definition: gps.h:150
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:97
struct EcefCoor_i ecef_vel
speed ECEF in cm/s
Definition: gps.h:95
data structure for GPS time sync
Definition: gps.h:122
uint32_t Crc177
Definition: gps.h:154
#define GPS_TIMEOUT
GPS timeout in seconds.
Definition: gps.h:176
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:92
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:68
int32_t lat
in degrees*1e7
uint8_t fix
status of fix
Definition: gps.h:107
#define GPS_VALID_POS_UTM_BIT
Definition: gps.h:50
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:96
struct GpsState gps
global GPS state
Definition: gps.c:69
void gps_init(void)
initialize the global GPS state
Definition: gps.c:309
uint16_t refStationId
Definition: gps.h:131
static int32_t wgs84_ellipsoid_to_geoid_i(int32_t lat, int32_t lon)
Get WGS84 ellipsoid/geoid separation.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:46
void gps_periodic_check(struct GpsState *gps_s)
Periodic GPS check.
Definition: gps.c:264
position in UTM coordinates
#define UTM_COPY(_u1, _u2)
Definition: pprz_geodetic.h:71