Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
gps_uavcan.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025 Fabien-B <fabien-b@github.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, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
28#include "uavcan/uavcan.h"
29#include "core/abi.h"
30#include "uavcan.equipment.gnss.Fix2.h"
31#include "gps.h"
35#include "std.h"
36
37
38
39#define SECS_IN_WEEK (7*24*3600000)
40
42
44 // current timestamp
46
49 return; // decode error
50 }
51
52 struct GpsState state;
53
54 // id of current gps
55#if GPS_UAVCAN_USE_NODE_ID
56 state.comp_id = transfer->source_node_id;
57#else
58 state.comp_id = GPS_UAVCAN_ID;
59#endif
60
61 // cpu time ticks at last received GPS message
62 state.last_msg_ticks = sys_time.nb_sec_rem;
63 // cpu time in sec at last received GPS message
64 state.last_msg_time = sys_time.nb_sec;
65
66 // status of fix
67 switch (msg.status)
68 {
70 state.fix = GPS_FIX_NONE;
71 break;
73 state.fix = GPS_FIX_NONE;
74 break;
76 state.fix = GPS_FIX_2D;
77 break;
80 state.fix = GPS_FIX_DGPS;
81 } else if(msg.mode == UAVCAN_EQUIPMENT_GNSS_FIX2_MODE_RTK) {
82 state.fix = GPS_FIX_RTK;
83 } else if(msg.mode == UAVCAN_EQUIPMENT_GNSS_FIX2_MODE_PPP) {
84 state.fix = GPS_FIX_3D; // TODO add PPP mode to paparazzi ?
85 } else {
86 state.fix = GPS_FIX_3D;
87 }
88 // cpu time ticks at last valid 3D fix
89 state.last_3dfix_ticks = sys_time.nb_sec_rem;
90 // cpu time in sec at last valid 3D fix
91 state.last_3dfix_time = sys_time.nb_sec;
92 break;
93 default:
94 return; // unknown value
95 }
96
97
98 if(msg.ecef_position_velocity.len > 0) {
99 // position in ECEF in cm
100 state.ecef_pos.x = msg.ecef_position_velocity.data[0].position_xyz_mm[0] / 10;
101 state.ecef_pos.y = msg.ecef_position_velocity.data[0].position_xyz_mm[1] / 10;
102 state.ecef_pos.z = msg.ecef_position_velocity.data[0].position_xyz_mm[2] / 10;
103 SetBit(state.valid_fields, GPS_VALID_POS_ECEF_BIT);
104
105 // speed ECEF in cm/s
106 state.ecef_vel.x = msg.ecef_position_velocity.data[0].velocity_xyz[0] * 100;
107 state.ecef_vel.y = msg.ecef_position_velocity.data[0].velocity_xyz[1] * 100;
108 state.ecef_vel.z = msg.ecef_position_velocity.data[0].velocity_xyz[2] * 100;
109 SetBit(state.valid_fields, GPS_VALID_VEL_ECEF_BIT);
110
111 // TODO handle msg.ecef_position_velocity.data[0].covariance
112 }
113
114 // position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
115 state.lla_pos.lat = msg.latitude_deg_1e8 / 10;
116 state.lla_pos.lon = msg.longitude_deg_1e8 / 10;
117 state.lla_pos.alt = msg.height_ellipsoid_mm;
118 SetBit(state.valid_fields, GPS_VALID_POS_LLA_BIT);
119
120 // utm_pos ignored.
121
122 // height above mean sea level (MSL) in mm
123 state.hmsl = msg.height_msl_mm;
124 SetBit(state.valid_fields, GPS_VALID_HMSL_BIT);
125
126 // speed NED in cm/s
127 state.ned_vel.x = msg.ned_velocity[0] * 100;
128 state.ned_vel.y = msg.ned_velocity[1] * 100;
129 state.ned_vel.z = msg.ned_velocity[2] * 100;
130 SetBit(state.valid_fields, GPS_VALID_VEL_NED_BIT);
131
132 // norm of 2d ground speed in cm/s
133 state.gspeed = VECT2_NORM2(state.ned_vel);
134 // norm of 3d speed in cm/s
135 state.speed_3d = VECT3_NORM2(state.ned_vel);
136 // GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
137 float course = atan2f(state.ned_vel.y, state.ned_vel.x);
139 state.course = course * 1e7;
140 SetBit(state.valid_fields, GPS_VALID_COURSE_BIT);
141
142 // cacc ignored (course accuracy in rad*1e7)
143
144 if (msg.covariance.len == 6) {
145 // horizontal accuracy in cm
146 if (!isnan(msg.covariance.data[0])) {
147 state.hacc = sqrtf(msg.covariance.data[0]) * 100;
148 }
149 // vertical accuracy in cm
150 if (!isnan(msg.covariance.data[2])) {
151 state.vacc = sqrtf(msg.covariance.data[2]) * 100;
152 }
153 // position accuracy in cm
154 if(!isnan(msg.covariance.data[0]) && !isnan(msg.covariance.data[2])) {
155 state.pacc = sqrtf(SQUARE(state.hacc) + SQUARE(state.vacc));
156 }
157 // speed accuracy in cm/s
158 if (!isnan(msg.covariance.data[3]) &&
159 !isnan(msg.covariance.data[4]) &&
160 !isnan(msg.covariance.data[5])) {
161 state.sacc = sqrtf((msg.covariance.data[3] + msg.covariance.data[4] + msg.covariance.data[5])/3) * 100;
162 }
163 } else if(msg.covariance.len != 0){
164 // TODO handle the other cases ?
165 }
166
167 // position dilution of precision scaled by 100
168 state.pdop = msg.pdop * 100;
169 // number of sat in fix
170 state.num_sv = msg.sats_used;
171
172 // GPS week
173 // GPS time of week in ms
174 const uint32_t unixToGpsEpoch = 315964800; // Unix timestamp of the GPS epoch 1980-01-06 00:00:00 UTC
175 uint64_t gnss_ts_msec = msg.gnss_timestamp.usec / 1000 - unixToGpsEpoch*1000;
176 switch (msg.gnss_time_standard)
177 {
179 break;
181 gnss_ts_msec -= 19000;
182 break;
184 gnss_ts_msec += (msg.num_leap_seconds*1000 - 9000);
185 break;
187 // good
188 break;
189 default:
190 break;
191 }
192
195
196
197 // Number of scanned satellites
198 // cannot get SVinfo from GPS
199 state.nb_channels = 0;
200
201 AbiSendMsgGPS(state.comp_id, now_ts, &state);
202}
203
204
212
Main include for ABI (AirBorneInterface).
#define GPS_UAVCAN_ID
static int16_t course[3]
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Main uavcan event structure for registering/calling callbacks.
Definition uavcan.h:76
Device independent GPS code (interface)
#define GPS_FIX_DGPS
DGPS fix.
Definition gps.h:45
#define GPS_VALID_VEL_ECEF_BIT
Definition gps.h:51
#define GPS_VALID_VEL_NED_BIT
Definition gps.h:52
#define GPS_VALID_POS_LLA_BIT
Definition gps.h:49
#define GPS_FIX_NONE
No GPS fix.
Definition gps.h:42
#define GPS_VALID_POS_ECEF_BIT
Definition gps.h:48
#define GPS_VALID_HMSL_BIT
Definition gps.h:53
#define GPS_FIX_2D
2D GPS fix
Definition gps.h:43
#define GPS_FIX_3D
3D GPS fix
Definition gps.h:44
#define GPS_FIX_RTK
RTK GPS fix.
Definition gps.h:46
#define GPS_VALID_COURSE_BIT
Definition gps.h:54
data structure for GPS information
Definition gps.h:90
static void gps_uavcan_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
Definition gps_uavcan.c:43
static uavcan_event gps_uavcan_ev
Definition gps_uavcan.c:41
#define SECS_IN_WEEK
Definition gps_uavcan.c:39
void gps_uavcan_init(void)
Definition gps_uavcan.c:205
#define SQUARE(_a)
#define VECT3_NORM2(_v)
#define VECT2_NORM2(_v)
struct State state
Definition state.c:36
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
uint16_t foo
Definition main_demo5.c:58
Paparazzi double-precision floating point math for geodetic calculations.
Paparazzi floating point math for geodetic calculations.
Paparazzi fixed point math for geodetic calculations.
#define NormCourseRad(x)
Normalize a rad angle between 0 and 2*PI.
Definition navigation.h:156
uavcan interface structure
Definition uavcan.h:46
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
void uavcan_bind(uint16_t data_type_id, uint64_t data_type_signature, uavcan_event *ev, uavcan_callback cb)
Bind to a receiving message from uavcan.
Definition uavcan.c:250
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned long long uint64_t
int transfer(const Mat *from, const image_t *to)