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
ins_alt_float.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2012 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 
28 
29 #include "subsystems/abi.h"
30 #include "state.h"
31 
32 #include <inttypes.h>
33 #include <math.h>
34 
35 #include "state.h"
36 #include "mcu_periph/sys_time.h"
37 #include "subsystems/gps.h"
39 
40 #include "generated/airframe.h"
41 #include "generated/modules.h"
42 
43 #ifdef DEBUG_ALT_KALMAN
44 #include "mcu_periph/uart.h"
46 #endif
47 
48 #if defined ALT_KALMAN || defined ALT_KALMAN_ENABLED
49 #warning Please remove the obsolete ALT_KALMAN and ALT_KALMAN_ENABLED defines from your airframe file.
50 #endif
51 
52 
54 
55 #if USE_BAROMETER
57 #include "math/pprz_isa.h"
58 
59 PRINT_CONFIG_MSG("USE_BAROMETER is TRUE: Using baro for altitude estimation.")
60 
61 // Baro event on ABI
62 #ifndef INS_BARO_ID
63 #if USE_BARO_BOARD
64 #define INS_BARO_ID BARO_BOARD_SENDER_ID
65 #else
66 #define INS_BARO_ID ABI_BROADCAST
67 #endif
68 #endif
69 PRINT_CONFIG_VAR(INS_BARO_ID)
71 static void baro_cb(uint8_t sender_id, float pressure);
72 #endif /* USE_BAROMETER */
73 
78 #ifndef INS_ALT_IMU_ID
79 #define INS_ALT_IMU_ID ABI_BROADCAST
80 #endif
81 
82 static void alt_kalman_reset(void);
83 static void alt_kalman_init(void);
84 static void alt_kalman(float z_meas, float dt);
85 
86 void ins_alt_float_update_gps(struct GpsState *gps_s);
87 
89 {
90 
93 
94  stateSetPositionUtm_f(&utm0);
95 
96  // set initial body to imu to 0
97  struct Int32Eulers b2i0 = { 0, 0, 0 };
99 
100  alt_kalman_init();
101 
102 #if USE_BAROMETER
103  ins_altf.qfe = 0.0f;
105  ins_altf.baro_alt = 0.0f;
106 #endif
108 
109  // why do we have this here?
110  alt_kalman(0.0f, 0.1);
111 }
112 
115 {
116  struct UtmCoor_f utm;
117 #ifdef GPS_USE_LATLONG
118  /* Recompute UTM coordinates in this zone */
119  struct LlaCoor_f lla;
121  utm.zone = (gps.lla_pos.lon / 1e7 + 180) / 6 + 1;
122  utm_of_lla_f(&utm, &lla);
123 #else
124  utm.zone = gps.utm_pos.zone;
125  utm.east = gps.utm_pos.east / 100.0f;
126  utm.north = gps.utm_pos.north / 100.0f;
127 #endif
128  // ground_alt
129  utm.alt = gps.hmsl / 1000.0f;
130 
131  // reset state UTM ref
133 
134  // reset filter flag
136 }
137 
139 {
140  struct UtmCoor_f utm = state.utm_origin_f;
141  // ground_alt
142  utm.alt = gps.hmsl / 1000.0f;
143  // reset state UTM ref
145  // reset filter flag
147 }
148 
149 #if USE_BAROMETER
150 void ins_alt_float_update_baro(float pressure)
151 {
152  // timestamp in usec when last callback was received
153  static uint32_t last_ts = 0;
154  // current timestamp
155  uint32_t now_ts = get_sys_time_usec();
156  // dt between this and last callback in seconds
157  float dt = (float)(now_ts - last_ts) / 1e6;
158  last_ts = now_ts;
159 
160  // bound dt (assume baro freq 1Hz-500Hz
161  Bound(dt, 0.002, 1.0)
162 
163  if (!ins_altf.baro_initialized) {
164  ins_altf.qfe = pressure;
166  }
167  if (ins_altf.reset_alt_ref) {
170  ins_altf.alt_dot = 0.0f;
171  ins_altf.qfe = pressure;
173  } else { /* not realigning, so normal update with baro measurement */
175  /* run the filter */
177  /* set new altitude, just copy old horizontal position */
178  struct UtmCoor_f utm;
180  utm.alt = ins_altf.alt;
181  stateSetPositionUtm_f(&utm);
182  struct NedCoor_f ned_vel;
183  ned_vel = *stateGetSpeedNed_f();
184  ned_vel.z = -ins_altf.alt_dot;
185  stateSetSpeedNed_f(&ned_vel);
186  }
187 }
188 #else
189 void ins_alt_float_update_baro(float pressure __attribute__((unused)))
190 {
191 }
192 #endif
193 
194 
196 {
197 #if USE_GPS
198  struct UtmCoor_f utm;
199  utm.east = gps_s->utm_pos.east / 100.0f;
200  utm.north = gps_s->utm_pos.north / 100.0f;
201  utm.zone = nav_utm_zone0;
202 
203 #if !USE_BAROMETER
204 #ifdef GPS_DT
205  const float dt = GPS_DT;
206 #else
207  // timestamp in usec when last callback was received
208  static uint32_t last_ts = 0;
209  // current timestamp
210  uint32_t now_ts = get_sys_time_usec();
211  // dt between this and last callback in seconds
212  float dt = (float)(now_ts - last_ts) / 1e6;
213  last_ts = now_ts;
214 
215  // bound dt (assume GPS freq between 0.5Hz and 50Hz)
216  Bound(dt, 0.02, 2)
217 #endif
218 
219  float falt = gps_s->hmsl / 1000.0f;
220  if (ins_altf.reset_alt_ref) {
222  ins_altf.alt = falt;
223  ins_altf.alt_dot = 0.0f;
225  } else {
226  alt_kalman(falt, dt);
227  ins_altf.alt_dot = -gps_s->ned_vel.z / 100.0f;
228  }
229 #endif
230  utm.alt = ins_altf.alt;
231  // set position
232  stateSetPositionUtm_f(&utm);
233 
234  struct NedCoor_f ned_vel = {
235  gps_s->ned_vel.x / 100.0f,
236  gps_s->ned_vel.y / 100.0f,
238  };
239  // set velocity
240  stateSetSpeedNed_f(&ned_vel);
241 
242 #endif
243 }
244 
245 
246 #define GPS_SIGMA2 1.
247 #define GPS_R 2.
248 
249 static float p[2][2];
250 
251 static void alt_kalman_reset(void)
252 {
253  p[0][0] = 1.0f;
254  p[0][1] = 0.0f;
255  p[1][0] = 0.0f;
256  p[1][1] = 1.0f;
257 }
258 
259 static void alt_kalman_init(void)
260 {
262 }
263 
264 static void alt_kalman(float z_meas, float dt)
265 {
266  float R = GPS_R;
267  float SIGMA2 = GPS_SIGMA2;
268 
269 #if USE_BAROMETER
270 #ifdef SITL
271  R = 0.5;
272  SIGMA2 = 0.1;
273 #elif USE_BARO_MS5534A
274  if (alt_baro_enabled) {
275  R = baro_MS5534A_r;
276  SIGMA2 = baro_MS5534A_sigma2;
277  }
278 #elif USE_BARO_ETS
279  if (baro_ets_enabled) {
280  R = baro_ets_r;
281  SIGMA2 = baro_ets_sigma2;
282  }
283 #elif USE_BARO_MS5611
284  if (baro_ms5611_enabled) {
285  R = baro_ms5611_r;
286  SIGMA2 = baro_ms5611_sigma2;
287  }
288 #elif USE_BARO_AMSYS
289  if (baro_amsys_enabled) {
290  R = baro_amsys_r;
291  SIGMA2 = baro_amsys_sigma2;
292  }
293 #elif USE_BARO_BMP
294  if (baro_bmp_enabled) {
295  R = baro_bmp_r;
296  SIGMA2 = baro_bmp_sigma2;
297  }
298 #endif
299 #endif // USE_BAROMETER
300 
301  float q[2][2];
302  q[0][0] = dt * dt * dt * dt / 4.;
303  q[0][1] = dt * dt * dt / 2.;
304  q[1][0] = dt * dt * dt / 2.;
305  q[1][1] = dt * dt;
306 
307 
308  /* predict */
309  ins_altf.alt += ins_altf.alt_dot * dt;
310  p[0][0] = p[0][0] + p[1][0] * dt + dt * (p[0][1] + p[1][1] * dt) + SIGMA2 * q[0][0];
311  p[0][1] = p[0][1] + p[1][1] * dt + SIGMA2 * q[0][1];
312  p[1][0] = p[1][0] + p[1][1] * dt + SIGMA2 * q[1][0];
313  p[1][1] = p[1][1] + SIGMA2 * q[1][1];
314 
315  /* error estimate */
316  float e = p[0][0] + R;
317 
318  if (fabs(e) > 1e-5) {
319  float k_0 = p[0][0] / e;
320  float k_1 = p[1][0] / e;
321  e = z_meas - ins_altf.alt;
322 
323  /* correction */
324  ins_altf.alt += k_0 * e;
325  ins_altf.alt_dot += k_1 * e;
326 
327  p[1][0] = -p[0][0] * k_1 + p[1][0];
328  p[1][1] = -p[0][1] * k_1 + p[1][1];
329  p[0][0] = p[0][0] * (1 - k_0);
330  p[0][1] = p[0][1] * (1 - k_0);
331  }
332 
333 #ifdef DEBUG_ALT_KALMAN
334  DOWNLINK_SEND_ALT_KALMAN(DefaultChannel, DefaultDevice, &(p[0][0]), &(p[0][1]), &(p[1][0]), &(p[1][1]));
335 #endif
336 }
337 
338 #if USE_BAROMETER
339 static void baro_cb(uint8_t __attribute__((unused)) sender_id, float pressure)
340 {
341  ins_alt_float_update_baro(pressure);
342 }
343 #endif
344 
345 static void gps_cb(uint8_t sender_id __attribute__((unused)),
346  uint32_t stamp __attribute__((unused)),
347  struct GpsState *gps_s)
348 {
350 }
351 
352 static void accel_cb(uint8_t sender_id __attribute__((unused)),
353  uint32_t stamp __attribute__((unused)),
354  struct Int32Vect3 *accel)
355 {
356  // untilt accel and remove gravity
357  struct Int32Vect3 accel_body, accel_ned;
358  struct Int32RMat *body_to_imu_rmat = orientationGetRMat_i(&body_to_imu);
359  int32_rmat_transp_vmult(&accel_body, body_to_imu_rmat, accel);
360  struct Int32RMat *ned_to_body_rmat = stateGetNedToBodyRMat_i();
361  int32_rmat_transp_vmult(&accel_ned, ned_to_body_rmat, &accel_body);
362  accel_ned.z += ACCEL_BFP_OF_REAL(9.81);
363  stateSetAccelNed_i((struct NedCoor_i *)&accel_ned);
364 }
365 
366 static void body_to_imu_cb(uint8_t sender_id __attribute__((unused)),
367  struct FloatQuat *q_b2i_f)
368 {
370 }
371 
373 {
375 
376 #if USE_BAROMETER
377  // Bind to BARO_ABS message
378  AbiBindMsgBARO_ABS(INS_BARO_ID, &baro_ev, baro_cb);
379 #endif
380  AbiBindMsgGPS(ABI_BROADCAST, &gps_ev, gps_cb);
381  AbiBindMsgIMU_ACCEL_INT32(INS_ALT_IMU_ID, &accel_ev, accel_cb);
382  AbiBindMsgBODY_TO_IMU_QUAT(INS_ALT_IMU_ID, &body_to_imu_ev, body_to_imu_cb);
383 }
Event structure to store callbacks in a linked list.
Definition: abi_common.h:65
bool_t baro_ms5611_enabled
bool_t baro_initialized
Definition: ins_alt_float.h:46
bool_t reset_alt_ref
flag to request reset of altitude reference to current alt
Definition: ins_alt_float.h:41
int32_t north
in centimeters
void ins_reset_local_origin(void)
Reset the geographic reference to the current GPS fix.
static void orientationSetQuat_f(struct OrientationReps *orientation, struct FloatQuat *quat)
Set vehicle body attitude from quaternion (float).
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
float baro_ms5611_sigma2
#define INS_BARO_ID
Definition: ins_alt_float.c:66
static struct Int32RMat * orientationGetRMat_i(struct OrientationReps *orientation)
Get vehicle body attitude rotation matrix (int).
float east
in meters
Common barometric sensor implementation.
float north
in meters
static abi_event accel_ev
Definition: ins_alt_float.c:75
static void baro_cb(uint8_t sender_id, float pressure)
float alt
in meters above WGS84 reference ellipsoid
static abi_event body_to_imu_ev
Definition: ins_alt_float.c:76
float ground_alt
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition: common_nav.c:40
static void gps_cb(uint8_t sender_id, uint32_t stamp, struct GpsState *gps_s)
static struct Int32RMat * stateGetNedToBodyRMat_i(void)
Get vehicle body attitude rotation matrix (int).
Definition: state.h:1090
static void accel_cb(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *accel)
float baro_MS5534A_r
Definition: baro_MS5534A.c:47
abi_event baro_ev
Definition: ins_alt_float.c:70
Main include for ABI (AirBorneInterface).
#define GPS_R
uint8_t nav_utm_zone0
Definition: common_nav.c:44
static void alt_kalman_init(void)
position in UTM coordinates Units: meters
int32_t east
in centimeters
float alt
estimated altitude above MSL in meters
Definition: ins_alt_float.h:38
float baro_ets_r
Definition: baro_ets.c:108
void ins_altf_register(void)
void ins_alt_float_update_baro(float pressure)
Ins implementation state (altitude, float)
Definition: ins_alt_float.h:37
static void body_to_imu_cb(uint8_t sender_id, struct FloatQuat *q_b2i_f)
int32_t z
Down.
struct UtmCoor_i utm_pos
position in UTM (north,east: cm; alt: mm over ellipsoid)
Definition: gps.h:70
bool_t baro_bmp_enabled
Definition: baro_bmp.c:54
#define FALSE
Definition: std.h:5
static uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.h:39
Roation quaternion.
float baro_amsys_r
Definition: baro_amsys.c:78
int32_t y
East.
static void stateSetPositionUtm_f(struct UtmCoor_f *utm_pos)
Set position from UTM coordinates (float).
Definition: state.h:565
static void stateSetAccelNed_i(struct NedCoor_i *ned_accel)
Set acceleration in NED coordinates (int).
Definition: state.h:957
uint8_t zone
UTM zone number.
vector in Latitude, Longitude and Altitude
static void stateSetSpeedNed_f(struct NedCoor_f *ned_speed)
Set ground speed in local NED coordinates (float).
Definition: state.h:792
static void orientationSetEulers_i(struct OrientationReps *orientation, struct Int32Eulers *eulers)
Set vehicle body attitude from euler angles (int).
static void alt_kalman(float z_meas, float dt)
#define TRUE
Definition: std.h:4
bool_t alt_baro_enabled
Definition: baro_MS5534A.c:45
struct InsAltFloat ins_altf
Definition: ins_alt_float.c:53
int32_t hmsl
height above mean sea level in mm
Definition: gps.h:71
int32_t nav_utm_north0
Definition: common_nav.c:43
vector in North East Down coordinates Units: meters
void ins_alt_float_update_gps(struct GpsState *gps_s)
static struct NedCoor_f * stateGetSpeedNed_f(void)
Get ground speed in local NED coordinates (float).
Definition: state.h:885
Architecture independent timing functions.
data structure for GPS information
Definition: gps.h:67
void ins_alt_float_init(void)
Definition: ins_alt_float.c:88
#define INS_ALT_IMU_ID
Definition: ins_alt_float.c:79
euler angles
Device independent GPS code (interface)
Paparazzi atmospheric pressure conversion utilities.
int32_t x
North.
unsigned long uint32_t
Definition: types.h:18
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
int32_t lon
in degrees*1e7
float baro_bmp_sigma2
Definition: baro_bmp.c:56
static abi_event gps_ev
Definition: ins_alt_float.c:74
float baro_bmp_r
Definition: baro_bmp.c:55
uint8_t zone
UTM zone number.
float baro_amsys_sigma2
Definition: baro_amsys.c:79
float baro_MS5534A_sigma2
Definition: baro_MS5534A.c:48
struct UtmCoor_f utm_origin_f
Definition of the origin of Utm coordinate system.
Definition: state.h:228
bool_t baro_amsys_enabled
Definition: baro_amsys.c:77
bool_t baro_ets_enabled
Definition: baro_ets.c:107
#define GPS_SIGMA2
static struct UtmCoor_f * stateGetPositionUtm_f(void)
Get position in UTM coordinates (float).
Definition: state.h:675
unsigned char uint8_t
Definition: types.h:14
float baro_alt
Definition: ins_alt_float.h:45
API to get/set the generic vehicle states.
float baro_ets_sigma2
Definition: baro_ets.c:109
vector in North East Down coordinates
int32_t nav_utm_east0
Definition: common_nav.c:42
void int32_rmat_transp_vmult(struct Int32Vect3 *vb, struct Int32RMat *m_b2a, struct Int32Vect3 *va)
rotate 3D vector by transposed rotation matrix.
float alt_dot
estimated vertical speed in m/s (positive-up)
Definition: ins_alt_float.h:39
#define ABI_BROADCAST
Broadcast address.
Definition: abi_common.h:56
static float p[2][2]
rotation matrix
static struct OrientationReps body_to_imu
Definition: ins_alt_float.c:77
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:69
Filters altitude and climb rate for fixedwings.
static float pprz_isa_height_of_pressure(float pressure, float ref_p)
Get relative altitude from pressure (using simplified equation).
Definition: pprz_isa.h:95
#define ACCEL_BFP_OF_REAL(_af)
static void alt_kalman_reset(void)
void ins_register_impl(InsInit init)
Definition: ins.c:53
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:73
void ins_reset_altitude_ref(void)
INS altitude reference reset.
static void stateSetLocalUtmOrigin_f(struct UtmCoor_f *utm_def)
Set the local (flat earth) coordinate frame origin from UTM (float).
Definition: state.h:460
struct GpsState gps
global GPS state
Definition: gps.c:41
#define LLA_FLOAT_OF_BFP(_o, _i)
struct State state
Definition: state.c:36
void utm_of_lla_f(struct UtmCoor_f *utm, struct LlaCoor_f *lla)
float baro_ms5611_r
#define UTM_COPY(_u1, _u2)
Definition: pprz_geodetic.h:66