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_datalink.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Freek van Tienen
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 
30 #include "generated/flight_plan.h" // reference lla NAV_XXX0
31 
32 #include "subsystems/gps.h"
33 #include "subsystems/abi.h"
35 
37 
39 
42 {
44  gps_datalink.pdop = 0;
45  gps_datalink.sacc = 0;
46  gps_datalink.pacc = 0;
47  gps_datalink.cacc = 0;
48 
50 
51  struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */
52  llh_nav0.lat = NAV_LAT0;
53  llh_nav0.lon = NAV_LON0;
54  /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */
55  llh_nav0.alt = NAV_ALT0 + NAV_MSL0;
56 
57  ltp_def_from_lla_i(&ltp_def, &llh_nav0);
58 }
59 
60 // Parse the REMOTE_GPS_SMALL datalink packet
61 static void parse_gps_datalink_small(int16_t heading, uint32_t pos_xyz, uint32_t speed_xyz, uint32_t tow)
62 {
63  struct EnuCoor_i enu_pos, enu_speed;
64 
65  // Position in ENU coordinates
66  enu_pos.x = (int32_t)((pos_xyz >> 21) & 0x7FF); // bits 31-21 x position in cm
67  if (enu_pos.x & 0x400) {
68  enu_pos.x |= 0xFFFFF800; // sign extend for twos complements
69  }
70  enu_pos.y = (int32_t)((pos_xyz >> 10) & 0x7FF); // bits 20-10 y position in cm
71  if (enu_pos.y & 0x400) {
72  enu_pos.y |= 0xFFFFF800; // sign extend for twos complements
73  }
74  enu_pos.z = (int32_t)(pos_xyz & 0x3FF); // bits 9-0 z position in cm
75 
76  // Convert the ENU coordinates to ECEF
79 
82 
83  enu_speed.x = (int32_t)((speed_xyz >> 21) & 0x7FF); // bits 31-21 speed x in cm/s
84  if (enu_speed.x & 0x400) {
85  enu_speed.x |= 0xFFFFF800; // sign extend for twos complements
86  }
87  enu_speed.y = (int32_t)((speed_xyz >> 10) & 0x7FF); // bits 20-10 speed y in cm/s
88  if (enu_speed.y & 0x400) {
89  enu_speed.y |= 0xFFFFF800; // sign extend for twos complements
90  }
91  enu_speed.z = (int32_t)((speed_xyz) & 0x3FF); // bits 9-0 speed z in cm/s
92  if (enu_speed.z & 0x200) {
93  enu_speed.z |= 0xFFFFFC00; // sign extend for twos complements
94  }
95 
98 
101 
104 
105  gps_datalink.hmsl = ltp_def.hmsl + enu_pos.z * 10;
107 
108  gps_datalink.course = ((int32_t)heading) * 1e3;
110 
111  gps_datalink.num_sv = 7;
112  gps_datalink.tow = tow;
113  gps_datalink.fix = GPS_FIX_3D; // set 3D fix to true
114 
115  // set gps msg time
118 
121 
122  // publish new GPS data
123  uint32_t now_ts = get_sys_time_usec();
124  AbiSendMsgGPS(GPS_DATALINK_ID, now_ts, &gps_datalink);
125 }
126 
128 static void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t ecef_z,
129  int32_t lat, int32_t lon, int32_t alt, int32_t hmsl,
130  int32_t ecef_xd, int32_t ecef_yd, int32_t ecef_zd,
131  uint32_t tow, int32_t course)
132 {
133  gps_datalink.lla_pos.lat = lat;
134  gps_datalink.lla_pos.lon = lon;
135  gps_datalink.lla_pos.alt = alt;
137 
138  gps_datalink.hmsl = hmsl;
140 
141  gps_datalink.ecef_pos.x = ecef_x;
142  gps_datalink.ecef_pos.y = ecef_y;
143  gps_datalink.ecef_pos.z = ecef_z;
145 
146  gps_datalink.ecef_vel.x = ecef_xd;
147  gps_datalink.ecef_vel.y = ecef_yd;
148  gps_datalink.ecef_vel.z = ecef_zd;
150 
153 
156 
159 
160  gps_datalink.num_sv = numsv;
161  gps_datalink.tow = tow;
163 
164  // set gps msg time
167 
170 
171  // publish new GPS data
172  uint32_t now_ts = get_sys_time_usec();
173  AbiSendMsgGPS(GPS_DATALINK_ID, now_ts, &gps_datalink);
174 }
175 
177 static void parse_gps_datalink_local(float enu_x, float enu_y, float enu_z,
178  float enu_xd, float enu_yd, float enu_zd,
179  uint32_t tow, float course)
180 {
181 
182  struct EnuCoor_i enu_pos, enu_speed;
183 
184  // Position in ENU coordinates
185  enu_pos.x = (int32_t)CM_OF_M(enu_x);
186  enu_pos.y = (int32_t)CM_OF_M(enu_y);
187  enu_pos.z = (int32_t)CM_OF_M(enu_z);
188 
189  // Convert the ENU coordinates to ECEF
192 
195 
196  enu_speed.x = (int32_t)CM_OF_M(enu_xd);
197  enu_speed.y = (int32_t)CM_OF_M(enu_yd);
198  enu_speed.z = (int32_t)CM_OF_M(enu_zd);
199 
202 
205 
208 
209  gps_datalink.hmsl = ltp_def.hmsl + enu_pos.z * 10;
211 
212  gps_datalink.course = (int32_t)(RadOfDeg(course)*1e7);
214 
215  gps_datalink.num_sv = 7;
216  gps_datalink.tow = tow;
217  gps_datalink.fix = GPS_FIX_3D; // set 3D fix to true
218 
219  // set gps msg time
222 
225 
226  // publish new GPS data
227  uint32_t now_ts = get_sys_time_usec();
228  AbiSendMsgGPS(GPS_DATALINK_ID, now_ts, &gps_datalink);
229 }
230 
232 {
233  if (DL_REMOTE_GPS_ac_id(dl_buffer) != AC_ID) { return; } // not for this aircraft
234 
235  parse_gps_datalink(DL_REMOTE_GPS_numsv(dl_buffer),
236  DL_REMOTE_GPS_ecef_x(dl_buffer),
237  DL_REMOTE_GPS_ecef_y(dl_buffer),
238  DL_REMOTE_GPS_ecef_z(dl_buffer),
239  DL_REMOTE_GPS_lat(dl_buffer),
240  DL_REMOTE_GPS_lon(dl_buffer),
241  DL_REMOTE_GPS_alt(dl_buffer),
242  DL_REMOTE_GPS_hmsl(dl_buffer),
243  DL_REMOTE_GPS_ecef_xd(dl_buffer),
244  DL_REMOTE_GPS_ecef_yd(dl_buffer),
245  DL_REMOTE_GPS_ecef_zd(dl_buffer),
246  DL_REMOTE_GPS_tow(dl_buffer),
247  DL_REMOTE_GPS_course(dl_buffer));
248 }
249 
251 {
252  if (DL_REMOTE_GPS_SMALL_ac_id(dl_buffer) != AC_ID) { return; } // not for this aircraft
253 
254  parse_gps_datalink_small(DL_REMOTE_GPS_SMALL_heading(dl_buffer),
255  DL_REMOTE_GPS_SMALL_pos_xyz(dl_buffer),
256  DL_REMOTE_GPS_SMALL_speed_xyz(dl_buffer),
257  DL_REMOTE_GPS_SMALL_tow(dl_buffer));
258 }
259 
261 {
262  if (DL_REMOTE_GPS_LOCAL_ac_id(dl_buffer) != AC_ID) { return; } // not for this aircraft
263 
264  parse_gps_datalink_local(DL_REMOTE_GPS_LOCAL_enu_x(dl_buffer),
265  DL_REMOTE_GPS_LOCAL_enu_y(dl_buffer),
266  DL_REMOTE_GPS_LOCAL_enu_z(dl_buffer),
267  DL_REMOTE_GPS_LOCAL_enu_xd(dl_buffer),
268  DL_REMOTE_GPS_LOCAL_enu_yd(dl_buffer),
269  DL_REMOTE_GPS_LOCAL_enu_zd(dl_buffer),
270  DL_REMOTE_GPS_LOCAL_tow(dl_buffer),
271  DL_REMOTE_GPS_LOCAL_course(dl_buffer));
272 }
int32_t z
in centimeters
uint32_t pacc
position accuracy in cm
Definition: gps.h:94
definition of the local (flat earth) coordinate system
int32_t y
North.
int32_t x
East.
#define GPS_VALID_VEL_NED_BIT
Definition: gps.h:52
void ecef_of_enu_point_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Convert a point in local ENU to ECEF.
uint8_t valid_fields
bitfield indicating valid fields (GPS_VALID_x_BIT)
Definition: gps.h:82
int32_t y
in centimeters
#define CM_OF_M(_m)
Main include for ABI (AirBorneInterface).
vector in Latitude, Longitude and Altitude
uint16_t speed_3d
norm of 3d speed in cm/s
Definition: gps.h:92
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:39
void ltp_def_from_lla_i(struct LtpDef_i *def, struct LlaCoor_i *lla)
void ned_of_ecef_vect_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Rotate a vector from ECEF to NED.
int32_t hmsl
Height above mean sea level in mm.
#define FLOAT_VECT3_NORM(_v)
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:106
int32_t alt
in millimeters above WGS84 reference ellipsoid
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
#define GPS_VALID_COURSE_BIT
Definition: gps.h:54
#define FLOAT_VECT2_NORM(_v)
static float heading
Definition: ahrs_infrared.c:45
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:88
data structure for GPS information
Definition: gps.h:81
uint32_t tow
GPS time of week in ms.
Definition: gps.h:101
#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
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_VALID_HMSL_BIT
Definition: gps.h:53
int32_t lon
in degrees*1e7
int32_t z
Up.
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
signed long int32_t
Definition: types.h:19
#define VECT3_NED_OF_ENU(_o, _i)
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:107
vector in East North Up coordinates
unsigned char uint8_t
Definition: types.h:14
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition: gps.h:93
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
static int16_t course[3]
Definition: airspeed_uADC.c:57
#define GPS_VALID_POS_ECEF_BIT
Definition: gps.h:48
uint8_t dl_buffer[MSG_SIZE]
Definition: main_demo5.c:64
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
uint8_t num_sv
number of sat in fix
Definition: gps.h:98
int32_t x
in centimeters
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
#define GPS_VALID_VEL_ECEF_BIT
Definition: gps.h:51
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:86
void lla_of_ecef_i(struct LlaCoor_i *out, struct EcefCoor_i *in)
Convert a ECEF to LLA.
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
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:90
#define GPS_DATALINK_ID
void ecef_of_enu_vect_i(struct EcefCoor_i *ecef, struct LtpDef_i *def, struct EnuCoor_i *enu)
Rotate a vector from ENU to ECEF.