Paparazzi UAS  v5.8.2_stable-0-g6260b7c
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 "subsystems/gps.h"
31 #include "subsystems/abi.h"
32 
33 // #include <stdio.h>
34 
35 #if GPS_USE_DATALINK_SMALL
36 #ifndef GPS_LOCAL_ECEF_ORIGIN_X
37 #error Local x coordinate in ECEF of the remote GPS required
38 #endif
39 
40 #ifndef GPS_LOCAL_ECEF_ORIGIN_Y
41 #error Local y coordinate in ECEF of the remote GPS required
42 #endif
43 
44 #ifndef GPS_LOCAL_ECEF_ORIGIN_Z
45 #error Local z coordinate in ECEF of the remote GPS required
46 #endif
47 
48 struct EcefCoor_i tracking_ecef;
49 
50 struct LtpDef_i tracking_ltp;
51 
52 struct EnuCoor_i enu_pos, enu_speed;
53 
54 struct EcefCoor_i ecef_pos, ecef_vel;
55 
56 struct LlaCoor_i lla_pos;
57 #endif
58 
59 bool_t gps_available;
60 
62 void gps_impl_init(void)
63 {
66  gps.gspeed = 700; // To enable course setting
67  gps.cacc = 0; // To enable course setting
68 
69 #if GPS_USE_DATALINK_SMALL
70  tracking_ecef.x = GPS_LOCAL_ECEF_ORIGIN_X;
71  tracking_ecef.y = GPS_LOCAL_ECEF_ORIGIN_Y;
72  tracking_ecef.z = GPS_LOCAL_ECEF_ORIGIN_Z;
73 
74  ltp_def_from_ecef_i(&tracking_ltp, &tracking_ecef);
75 #endif
76 }
77 
78 #ifdef GPS_USE_DATALINK_SMALL
79 // Parse the REMOTE_GPS_SMALL datalink packet
80 void parse_gps_datalink_small(uint8_t num_sv, uint32_t pos_xyz, uint32_t speed_xy)
81 {
82 
83  // Position in ENU coordinates
84  enu_pos.x = (int32_t)((pos_xyz >> 22) & 0x3FF); // bits 31-22 x position in cm
85  if (enu_pos.x & 0x200) {
86  enu_pos.x |= 0xFFFFFC00; // fix for twos complements
87  }
88  enu_pos.y = (int32_t)((pos_xyz >> 12) & 0x3FF); // bits 21-12 y position in cm
89  if (enu_pos.y & 0x200) {
90  enu_pos.y |= 0xFFFFFC00; // fix for twos complements
91  }
92  enu_pos.z = (int32_t)(pos_xyz >> 2 & 0x3FF); // bits 11-2 z position in cm
93  // bits 1 and 0 are free
94 
95  // printf("ENU Pos: %u (%d, %d, %d)\n", pos_xyz, enu_pos.x, enu_pos.y, enu_pos.z);
96 
97  // Convert the ENU coordinates to ECEF
98  ecef_of_enu_point_i(&ecef_pos, &tracking_ltp, &enu_pos);
99  gps.ecef_pos = ecef_pos;
100 
101  lla_of_ecef_i(&lla_pos, &ecef_pos);
102  gps.lla_pos = lla_pos;
103 
104  enu_speed.x = (int32_t)((speed_xy >> 22) & 0x3FF); // bits 31-22 speed x in cm/s
105  if (enu_speed.x & 0x200) {
106  enu_speed.x |= 0xFFFFFC00; // fix for twos complements
107  }
108  enu_speed.y = (int32_t)((speed_xy >> 12) & 0x3FF); // bits 21-12 speed y in cm/s
109  if (enu_speed.y & 0x200) {
110  enu_speed.y |= 0xFFFFFC00; // fix for twos complements
111  }
112  enu_speed.z = 0;
113 
114  // printf("ENU Speed: %u (%d, %d, %d)\n", speed_xy, enu_speed.x, enu_speed.y, enu_speed.z);
115 
116  ecef_of_enu_vect_i(&gps.ecef_vel , &tracking_ltp , &enu_speed);
117 
118  gps.hmsl = tracking_ltp.hmsl + enu_pos.z * 10; // TODO: try to compensate for the loss in accuracy
119 
120  gps.course = (int32_t)((speed_xy >> 2) & 0x3FF); // bits 11-2 heading in rad*1e2
121  if (gps.course & 0x200) {
122  gps.course |= 0xFFFFFC00; // fix for twos complements
123  }
124 
125  // printf("Heading: %d\n", gps.course);
126 
127  gps.course *= 1e5;
128  gps.num_sv = num_sv;
129  gps.tow = 0; // set time-of-weak to 0
130  gps.fix = GPS_FIX_3D; // set 3D fix to true
131  gps_available = TRUE; // set GPS available to true
132 
133 #if GPS_USE_LATLONG
134  // Computes from (lat, long) in the referenced UTM zone
135  struct LlaCoor_f lla_f;
137  struct UtmCoor_f utm_f;
139  // convert to utm
141  // copy results of utm conversion
142  gps.utm_pos.east = utm_f.east * 100;
143  gps.utm_pos.north = utm_f.north * 100;
146 #endif
147 
148  // publish new GPS data
149  uint32_t now_ts = get_sys_time_usec();
152  if (gps.fix == GPS_FIX_3D) {
155  }
156  AbiSendMsgGPS(GPS_DATALINK_ID, now_ts, &gps);
157 }
158 #endif
159 
161 void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t ecef_z, int32_t lat, int32_t lon,
162  int32_t alt,
163  int32_t hmsl, int32_t ecef_xd, int32_t ecef_yd, int32_t ecef_zd, uint32_t tow, int32_t course)
164 {
165  gps.lla_pos.lat = lat;
166  gps.lla_pos.lon = lon;
167  gps.lla_pos.alt = alt;
168  gps.hmsl = hmsl;
169 
170  gps.ecef_pos.x = ecef_x;
171  gps.ecef_pos.y = ecef_y;
172  gps.ecef_pos.z = ecef_z;
173 
174  gps.ecef_vel.x = ecef_xd;
175  gps.ecef_vel.y = ecef_yd;
176  gps.ecef_vel.z = ecef_zd;
177 
178  gps.course = course;
179  gps.num_sv = numsv;
180  gps.tow = tow;
181  gps.fix = GPS_FIX_3D;
183 
184 #if GPS_USE_LATLONG
185  // Computes from (lat, long) in the referenced UTM zone
186  struct LlaCoor_f lla_f;
187  LLA_FLOAT_OF_BFP(lla_f, gps.lla_pos);
188  struct UtmCoor_f utm_f;
189  utm_f.zone = nav_utm_zone0;
190  // convert to utm
191  utm_of_lla_f(&utm_f, &lla_f);
192  // copy results of utm conversion
193  gps.utm_pos.east = utm_f.east * 100;
194  gps.utm_pos.north = utm_f.north * 100;
197 #endif
198 
199  // publish new GPS data
200  uint32_t now_ts = get_sys_time_usec();
203  if (gps.fix == GPS_FIX_3D) {
206  }
207  AbiSendMsgGPS(GPS_DATALINK_ID, now_ts, &gps);
208 }
209 
int32_t z
in centimeters
int32_t north
in centimeters
float east
in meters
definition of the local (flat earth) coordinate system
float north
in meters
float alt
in meters above WGS84 reference ellipsoid
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.
vector in EarthCenteredEarthFixed coordinates
int32_t y
in centimeters
Main include for ABI (AirBorneInterface).
uint8_t nav_utm_zone0
Definition: common_nav.c:44
position in UTM coordinates Units: meters
int32_t east
in centimeters
vector in Latitude, Longitude and Altitude
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:43
struct UtmCoor_i utm_pos
position in UTM (north,east: cm; alt: mm over ellipsoid)
Definition: gps.h:70
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:89
#define FALSE
Definition: std.h:5
int32_t alt
in millimeters above WGS84 reference ellipsoid
static uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.h:39
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition: gps.h:92
uint32_t cacc
course accuracy in rad*1e7
Definition: gps.h:79
uint8_t zone
UTM zone number.
vector in Latitude, Longitude and Altitude
#define TRUE
Definition: std.h:4
struct LlaCoor_f lla_f
Definition: ins_xsens700.c:159
int32_t hmsl
height above mean sea level in mm
Definition: gps.h:71
uint32_t tow
GPS time of week in ms.
Definition: gps.h:84
#define GPS_FIX_NONE
No GPS fix.
Definition: gps.h:41
Device independent GPS code (interface)
unsigned long uint32_t
Definition: types.h:18
struct EcefCoor_i ecef_pos
position in ECEF in cm
Definition: gps.h:68
int32_t lon
in degrees*1e7
uint8_t zone
UTM zone number.
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:70
struct UtmCoor_f utm_f
Definition: ins_xsens700.c:160
signed long int32_t
Definition: types.h:19
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:90
int32_t alt
in millimeters above WGS84 reference ellipsoid
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:76
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:69
uint32_t last_msg_ticks
cpu time ticks at last received GPS message
Definition: gps.h:91
uint8_t num_sv
number of sat in fix
Definition: gps.h:81
int32_t x
in centimeters
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:74
struct EcefCoor_i ecef_vel
speed ECEF in cm/s
Definition: gps.h:72
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:69
void lla_of_ecef_i(struct LlaCoor_i *out, struct EcefCoor_i *in)
int32_t lat
in degrees*1e7
uint8_t fix
status of fix
Definition: gps.h:82
struct GpsState gps
global GPS state
Definition: gps.c:41
#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.
#define LLA_FLOAT_OF_BFP(_o, _i)
void ltp_def_from_ecef_i(struct LtpDef_i *def, struct EcefCoor_i *ecef)
void utm_of_lla_f(struct UtmCoor_f *utm, struct LlaCoor_f *lla)