Paparazzi UAS  v5.14.0_stable-0-g3f680d1
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 /* expand GpsId(PRIMARY_GPS) to e.g. GPS_UBX_ID */
59 #define __GpsId(_x) _x ## _ID
60 #define _GpsId(_x) __GpsId(_x)
61 #define GpsId(_x) _GpsId(_x)
62 
63 
64 #ifdef GPS_POWER_GPIO
65 #include "mcu_periph/gpio.h"
66 
67 #ifndef GPS_POWER_GPIO_ON
68 #define GPS_POWER_GPIO_ON gpio_set
69 #endif
70 #endif
71 
72 #define MSEC_PER_WEEK (1000*60*60*24*7)
73 #define TIME_TO_SWITCH 5000 //ten s in ms
74 
75 struct GpsState gps;
76 
80 
81 #ifdef SECONDARY_GPS
82 static uint8_t current_gps_id = GpsId(PRIMARY_GPS);
83 #endif
84 
86 
87 
88 #if PERIODIC_TELEMETRY
90 
91 static void send_svinfo_id(struct transport_tx *trans, struct link_device *dev,
92  uint8_t svid)
93 {
94  if (svid < GPS_NB_CHANNELS) {
95  pprz_msg_send_SVINFO(trans, dev, AC_ID, &svid,
96  &gps.svinfos[svid].svid, &gps.svinfos[svid].flags,
97  &gps.svinfos[svid].qi, &gps.svinfos[svid].cno,
98  &gps.svinfos[svid].elev, &gps.svinfos[svid].azim);
99  }
100 }
101 
103 static void send_svinfo(struct transport_tx *trans, struct link_device *dev)
104 {
105  static uint8_t i = 0;
106  if (i == gps.nb_channels) { i = 0; }
107  send_svinfo_id(trans, dev, i);
108  i++;
109 }
110 
115 static inline void send_svinfo_available(struct transport_tx *trans, struct link_device *dev)
116 {
117  static uint8_t i = 0;
118  static uint8_t last_cnos[GPS_NB_CHANNELS];
119  if (i >= gps.nb_channels) { i = 0; }
120  // send SVINFO for all satellites while no GPS fix,
121  // after 3D fix, send avialable sats if they were updated
122  if (gps.fix < GPS_FIX_3D) {
123  send_svinfo_id(trans, dev, i);
124  } else if (gps.svinfos[i].cno != last_cnos[i]) {
125  send_svinfo_id(trans, dev, i);
126  last_cnos[i] = gps.svinfos[i].cno;
127  }
128  i++;
129 }
130 
131 static void send_gps(struct transport_tx *trans, struct link_device *dev)
132 {
133  uint8_t zero = 0;
134  int16_t climb = -gps.ned_vel.z;
135  int16_t course = (DegOfRad(gps.course) / ((int32_t)1e6));
136  struct UtmCoor_i utm = utm_int_from_gps(&gps, 0);
137 #if PPRZLINK_DEFAULT_VER == 2 && GPS_POS_BROADCAST
138  // broadcast GPS message
139  struct pprzlink_msg msg;
140  msg.trans = trans;
141  msg.dev = dev;
142  msg.sender_id = AC_ID;
143  msg.receiver_id = PPRZLINK_MSG_BROADCAST;
144  msg.component_id = 0;
145  pprzlink_msg_send_GPS(&msg,
146 #else
147  pprz_msg_send_GPS(trans, dev, AC_ID,
148 #endif
149  &gps.fix,
150  &utm.east, &utm.north,
151  &course, &gps.hmsl, &gps.gspeed, &climb,
152  &gps.week, &gps.tow, &utm.zone, &zero);
153  // send SVINFO for available satellites that have new data
154  send_svinfo_available(trans, dev);
155 }
156 
157 static void send_gps_rtk(struct transport_tx *trans, struct link_device *dev)
158 {
159  pprz_msg_send_GPS_RTK(trans, dev, AC_ID,
169 }
170 
171 static void send_gps_rxmrtcm(struct transport_tx *trans, struct link_device *dev)
172 {
173  pprz_msg_send_GPS_RXMRTCM(trans, dev, AC_ID,
174  &rtcm_man.Cnt105,
175  &rtcm_man.Cnt177,
176  &rtcm_man.Cnt187,
177  &rtcm_man.Crc105,
178  &rtcm_man.Crc177,
179  &rtcm_man.Crc187);
180 }
181 
182 static void send_gps_int(struct transport_tx *trans, struct link_device *dev)
183 {
184 #if PPRZLINK_DEFAULT_VER == 2 && GPS_POS_BROADCAST
185  // broadcast GPS message
186  struct pprzlink_msg msg;
187  msg.trans = trans;
188  msg.dev = dev;
189  msg.sender_id = AC_ID;
190  msg.receiver_id = PPRZLINK_MSG_BROADCAST;
191  msg.component_id = 0;
192  pprzlink_msg_send_GPS_INT(&msg,
193 #else
194  pprz_msg_send_GPS_INT(trans, dev, AC_ID,
195 #endif
198  &gps.hmsl,
200  &gps.pacc, &gps.sacc,
201  &gps.tow,
202  &gps.pdop,
203  &gps.num_sv,
204  &gps.fix,
205  &gps.comp_id);
206  // send SVINFO for available satellites that have new data
207  send_svinfo_available(trans, dev);
208 }
209 
210 static void send_gps_lla(struct transport_tx *trans, struct link_device *dev)
211 {
212  uint8_t err = 0;
213  int16_t climb = -gps.ned_vel.z;
214  int16_t course = (DegOfRad(gps.course) / ((int32_t)1e6));
215 #if PPRZLINK_DEFAULT_VER == 2 && GPS_POS_BROADCAST
216  // broadcast GPS message
217  struct pprzlink_msg msg;
218  msg.trans = trans;
219  msg.dev = dev;
220  msg.sender_id = AC_ID;
221  msg.receiver_id = PPRZLINK_MSG_BROADCAST;
222  msg.component_id = 0;
223  pprzlink_msg_send_GPS_LLA(&msg,
224 #else
225  pprz_msg_send_GPS_LLA(trans, dev, AC_ID,
226 #endif
228  &gps.hmsl, &course, &gps.gspeed, &climb,
229  &gps.week, &gps.tow,
230  &gps.fix, &err);
231 }
232 
233 static void send_gps_sol(struct transport_tx *trans, struct link_device *dev)
234 {
235  pprz_msg_send_GPS_SOL(trans, dev, AC_ID, &gps.pacc, &gps.sacc, &gps.pdop, &gps.num_sv);
236 }
237 #endif
238 
239 
240 #ifdef SECONDARY_GPS
241 static uint8_t gps_multi_switch(struct GpsState *gps_s) {
242  static uint32_t time_since_last_gps_switch = 0;
243 
244  if (multi_gps_mode == GPS_MODE_PRIMARY){
245  return GpsId(PRIMARY_GPS);
246  } else if (multi_gps_mode == GPS_MODE_SECONDARY){
247  return GpsId(SECONDARY_GPS);
248  } else{
249  if (gps_s->fix > gps.fix){
250  return gps_s->comp_id;
251  } else if (gps.fix > gps_s->fix){
252  return gps.comp_id;
253  } else{
254  if (get_sys_time_msec() - time_since_last_gps_switch > TIME_TO_SWITCH) {
255  if (gps_s->num_sv > gps.num_sv) {
256  current_gps_id = gps_s->comp_id;
257  time_since_last_gps_switch = get_sys_time_msec();
258  } else if (gps.num_sv > gps_s->num_sv) {
259  current_gps_id = gps.comp_id;
260  time_since_last_gps_switch = get_sys_time_msec();
261  }
262  }
263  }
264  }
265  return current_gps_id;
266 }
267 #endif /*SECONDARY_GPS*/
268 
269 
270 void gps_periodic_check(struct GpsState *gps_s)
271 {
272  if (sys_time.nb_sec - gps_s->last_msg_time > GPS_TIMEOUT) {
273  gps_s->fix = GPS_FIX_NONE;
274  }
275 
276 #ifdef SECONDARY_GPS
277  current_gps_id = gps_multi_switch(gps_s);
278  if (gps_s->comp_id == current_gps_id) {
279  gps = *gps_s;
280  }
281 #else
282  gps = *gps_s;
283 #endif
284 }
285 
286 
288 static void gps_cb(uint8_t sender_id,
289  uint32_t stamp __attribute__((unused)),
290  struct GpsState *gps_s)
291 {
292  /* ignore callback from own AbiSendMsgGPS */
293  if (sender_id == GPS_MULTI_ID) {
294  return;
295  }
296  uint32_t now_ts = get_sys_time_usec();
297 #ifdef SECONDARY_GPS
298  current_gps_id = gps_multi_switch(gps_s);
299  if (gps_s->comp_id == current_gps_id) {
300  gps = *gps_s;
301  AbiSendMsgGPS(GPS_MULTI_ID, now_ts, gps_s);
302  }
303 #else
304  gps = *gps_s;
305  AbiSendMsgGPS(GPS_MULTI_ID, now_ts, gps_s);
306 #endif
307  if (gps.tow != gps_time_sync.t0_tow)
308  {
311  }
312 }
313 
314 
315 void gps_init(void)
316 {
317  multi_gps_mode = MULTI_GPS_MODE;
318 
319  gps.valid_fields = 0;
320  gps.fix = GPS_FIX_NONE;
321  gps.week = 0;
322  gps.tow = 0;
323  gps.cacc = 0;
324 
325  gps.last_3dfix_ticks = 0;
326  gps.last_3dfix_time = 0;
327  gps.last_msg_ticks = 0;
328  gps.last_msg_time = 0;
329 
330 #ifdef GPS_POWER_GPIO
332  GPS_POWER_GPIO_ON(GPS_POWER_GPIO);
333 #endif
334 #ifdef GPS_LED
335  LED_OFF(GPS_LED);
336 #endif
337 
338  AbiBindMsgGPS(ABI_BROADCAST, &gps_ev, gps_cb);
339 
340 #if PERIODIC_TELEMETRY
348 #endif
349 
350  // Initializing counter variables to count the number of Rtcm msgs in the input stream(for each msg type)
351  rtcm_man.Cnt105 = 0;
352  rtcm_man.Cnt177 = 0;
353  rtcm_man.Cnt187 = 0;
354  // Initializing counter variables to count the number of messages that failed Crc Check
355  rtcm_man.Crc105 = 0;
356  rtcm_man.Crc177 = 0;
357  rtcm_man.Crc187 = 0;
358 }
359 
361 {
362  uint32_t clock_delta;
363  uint32_t time_delta;
364  uint32_t itow_now;
365 
366  if (sys_ticks < gps_time_sync.t0_ticks) {
367  clock_delta = (0xFFFFFFFF - sys_ticks) + gps_time_sync.t0_ticks + 1;
368  } else {
369  clock_delta = sys_ticks - gps_time_sync.t0_ticks;
370  }
371 
372  time_delta = msec_of_sys_time_ticks(clock_delta);
373 
374  itow_now = gps_time_sync.t0_tow + time_delta;
375  if (itow_now > MSEC_PER_WEEK) {
376  itow_now %= MSEC_PER_WEEK;
377  }
378 
379  return itow_now;
380 }
381 
385 void WEAK gps_inject_data(uint8_t packet_id __attribute__((unused)), uint8_t length __attribute__((unused)), uint8_t *data __attribute__((unused))){
386 
387 }
388 
392 #include "state.h"
394 {
395  struct UtmCoor_f utm = {.east = 0., .north=0., .alt=0., .zone=zone};
396 
397  if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_UTM_BIT)) {
398  /* A real UTM position is available, use the correct zone */
399  UTM_FLOAT_OF_BFP(utm, gps_s->utm_pos);
400  } else if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_LLA_BIT))
401  {
402  /* Recompute UTM coordinates in this zone */
403  struct UtmCoor_i utm_i;
404  utm_i.zone = zone;
405  utm_of_lla_i(&utm_i, &gps_s->lla_pos);
406  UTM_FLOAT_OF_BFP(utm, utm_i);
407 
408  /* set utm.alt in hsml */
409  if (bit_is_set(gps_s->valid_fields, GPS_VALID_HMSL_BIT)) {
410  utm.alt = gps_s->hmsl/1000.;
411  } else {
412  utm.alt = wgs84_ellipsoid_to_geoid_i(gps_s->lla_pos.lat, gps_s->lla_pos.lon)/1000.;
413  }
414  }
415 
416  return utm;
417 }
418 
420 {
421  struct UtmCoor_i utm = {.east = 0, .north=0, .alt=0, .zone=zone};
422 
423  if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_UTM_BIT)) {
424  // A real UTM position is available, use the correct zone
425  UTM_COPY(utm, gps_s->utm_pos);
426  }
427  else if (bit_is_set(gps_s->valid_fields, GPS_VALID_POS_LLA_BIT)){
428  /* Recompute UTM coordinates in zone */
429  utm_of_lla_i(&utm, &gps_s->lla_pos);
430 
431  /* set utm.alt in hsml */
432  if (bit_is_set(gps_s->valid_fields, GPS_VALID_HMSL_BIT)) {
433  utm.alt = gps_s->hmsl;
434  } else {
435  utm.alt = wgs84_ellipsoid_to_geoid_i(gps_s->lla_pos.lat, gps_s->lla_pos.lon);
436  }
437  }
438 
439  return utm;
440 }
uint8_t qi
quality bitfield (GPS receiver specific)
Definition: gps.h:74
static void send_gps_int(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:182
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:115
int32_t north
in centimeters
struct SVinfo svinfos[GPS_NB_CHANNELS]
holds information from the Space Vehicles (Satellites)
Definition: gps.h:104
int16_t azim
azimuth in deg
Definition: gps.h:77
float east
in meters
uint32_t pacc
position accuracy in cm
Definition: gps.h:94
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:91
uint8_t nb_channels
Number of scanned satellites.
Definition: gps.h:103
uint32_t Cnt187
Definition: gps.h:144
uint32_t t0_ticks
hw clock ticks when GPS message is received
Definition: gps.h:117
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:82
int32_t y
in centimeters
#define LED_OFF(i)
Definition: led_hw.h:51
uint8_t carrSoln
Definition: gps.h:133
uint16_t week
GPS week.
Definition: gps.h:100
Some architecture independent helper functions for GPIOs.
#define GPS_NB_CHANNELS
Definition: gps.h:57
#define TIME_TO_SWITCH
Definition: gps.c:73
int32_t relPosE
Definition: gps.h:125
static uint32_t msec_of_sys_time_ticks(uint32_t ticks)
Definition: sys_time.h:158
Main include for ABI (AirBorneInterface).
struct RtcmMan rtcm_man
Definition: gps.c:79
static void send_gps_sol(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:233
static void send_gps(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:131
#define UTM_FLOAT_OF_BFP(_o, _i)
position in UTM coordinates Units: meters
int32_t east
in centimeters
int8_t relPosHPD
Definition: gps.h:129
#define MSEC_PER_WEEK
Definition: gps.c:72
uint8_t svid
Satellite ID.
Definition: gps.h:72
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:135
uint32_t Crc187
Definition: gps.h:147
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:106
int8_t elev
elevation in deg
Definition: gps.h:76
int32_t alt
in millimeters above WGS84 reference ellipsoid
WGS-84 Geoid Heights.
uint32_t accN
Definition: gps.h:130
uint32_t sacc
speed accuracy in cm/s
Definition: gps.h:95
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition: gps.h:109
uint32_t cacc
course accuracy in rad*1e7
Definition: gps.h:96
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:419
static void send_svinfo_available(struct transport_tx *trans, struct link_device *dev)
send SVINFO message if updated.
Definition: gps.c:115
static abi_event gps_ev
Definition: gps.c:287
int8_t relPosHPE
Definition: gps.h:128
uint32_t Crc105
Definition: gps.h:145
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:88
void WEAK gps_inject_data(uint8_t packet_id, uint8_t length, uint8_t *data)
Default parser for GPS injected data.
Definition: gps.c:385
uint8_t cno
Carrier to Noise Ratio (Signal Strength) in dbHz.
Definition: gps.h:75
data structure for GPS information
Definition: gps.h:81
static void send_gps_lla(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:210
uint32_t tow
GPS time of week in ms.
Definition: gps.h:101
uint32_t Cnt177
Definition: gps.h:143
#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:97
static void send_gps_rxmrtcm(struct transport_tx *trans, struct link_device *dev)
Definition: gps.c:171
Definition: gps.h:139
uint8_t multi_gps_mode
Definition: gps.c:85
unsigned long uint32_t
Definition: types.h:18
struct EcefCoor_i ecef_pos
position in ECEF in cm
Definition: gps.h:85
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:122
void utm_of_lla_i(struct UtmCoor_i *utm, struct LlaCoor_i *lla)
Convert a LLA to UTM.
int32_t relPosD
Definition: gps.h:126
uint8_t zone
UTM zone number.
int32_t relPosN
Definition: gps.h:124
signed long int32_t
Definition: types.h:19
uint8_t relPosValid
Definition: gps.h:134
struct GpsRelposNED gps_relposned
Definition: gps.c:78
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:157
static void gps_cb(uint8_t sender_id, uint32_t stamp, struct GpsState *gps_s)
Definition: gps.c:288
int8_t relPosHPN
Definition: gps.h:127
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:107
int32_t alt
in millimeters (above WGS84 reference ellipsoid or above MSL)
uint32_t accE
Definition: gps.h:131
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:103
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:393
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:93
Persistent settings interface.
uint8_t comp_id
id of current gps
Definition: gps.h:83
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:121
uint32_t accD
Definition: gps.h:132
uint8_t flags
bitfield with GPS receiver specific flags
Definition: gps.h:73
struct GpsTimeSync gps_time_sync
Definition: gps.c:77
#define MULTI_GPS_MODE
Definition: gps.h:65
uint32_t last_msg_ticks
cpu time ticks at last received GPS message
Definition: gps.h:108
#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:360
uint8_t num_sv
number of sat in fix
Definition: gps.h:98
uint8_t gnssFixOK
Definition: gps.h:136
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:142
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:91
struct EcefCoor_i ecef_vel
speed ECEF in cm/s
Definition: gps.h:89
data structure for GPS time sync
Definition: gps.h:114
uint32_t Crc177
Definition: gps.h:146
#define GPS_TIMEOUT
GPS timeout in seconds.
Definition: gps.h:168
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:86
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:99
#define GPS_VALID_POS_UTM_BIT
Definition: gps.h:50
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:90
struct GpsState gps
global GPS state
Definition: gps.c:75
void gps_init(void)
initialize the global GPS state
Definition: gps.c:315
uint16_t refStationId
Definition: gps.h:123
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
#define GpsId(_x)
Definition: gps.c:61
void gps_periodic_check(struct GpsState *gps_s)
Periodic GPS check.
Definition: gps.c:270
position in UTM coordinates
#define UTM_COPY(_u1, _u2)
Definition: pprz_geodetic.h:66