Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
ins_ekf2.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Freek van Tienen <freek.v.tienen@gmail.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, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
29 #include "modules/ins/ins_ekf2.h"
30 #include "modules/nav/waypoints.h"
31 #include "modules/core/abi.h"
32 #include "stabilization/stabilization_attitude.h"
33 #include "generated/airframe.h"
34 #include "generated/flight_plan.h"
35 #include "EKF/ekf.h"
36 #include "math/pprz_isa.h"
38 #include "mcu_periph/sys_time.h"
39 #include "autopilot.h"
40 
42 #if defined SITL && USE_NPS
43 #include "nps_autopilot.h"
44 #include <stdio.h>
45 #endif
46 
48 #ifndef USE_INS_NAV_INIT
49 #define USE_INS_NAV_INIT TRUE
50 #endif
51 
53 #ifndef INS_EKF2_MAX_REL_LENGTH_ERROR
54 #define INS_EKF2_MAX_REL_LENGTH_ERROR 0.2 // Factor which gets multiplied by the reference distance
55 #endif
56 
58 #if INS_EKF2_OPTITRACK
59 #ifndef INS_EKF2_FUSION_MODE
60 #define INS_EKF2_FUSION_MODE (MASK_USE_EVPOS | MASK_USE_EVVEL | MASK_USE_EVYAW)
61 #endif
62 #ifndef INS_EKF2_VDIST_SENSOR_TYPE
63 #define INS_EKF2_VDIST_SENSOR_TYPE VDIST_SENSOR_EV
64 #endif
65 #endif
66 
68 #ifndef INS_EKF2_FUSION_MODE
69 #define INS_EKF2_FUSION_MODE (MASK_USE_GPS)
70 #endif
72 
73 
74 #ifndef INS_EKF2_VDIST_SENSOR_TYPE
75 #define INS_EKF2_VDIST_SENSOR_TYPE VDIST_SENSOR_BARO
76 #endif
78 
79 
80 #ifndef INS_EKF2_GPS_CHECK_MASK
81 #define INS_EKF2_GPS_CHECK_MASK 21 // (MASK_GPS_NSATS | MASK_GPS_HACC | MASK_GPS_SACC)
82 #endif
84 
85 
86 #ifndef INS_EKF2_SONAR_MIN_RANGE
87 #define INS_EKF2_SONAR_MIN_RANGE 0.001
88 #endif
90 
91 
92 #ifndef INS_EKF2_SONAR_MAX_RANGE
93 #define INS_EKF2_SONAR_MAX_RANGE 4
94 #endif
96 
97 
98 #ifndef INS_EKF2_RANGE_MAIN_AGL
99 #define INS_EKF2_RANGE_MAIN_AGL 1
100 #endif
102 
103 
104 #ifndef INS_EKF2_BARO_ID
105 #if USE_BARO_BOARD
106 #define INS_EKF2_BARO_ID BARO_BOARD_SENDER_ID
107 #else
108 #define INS_EKF2_BARO_ID ABI_BROADCAST
109 #endif
110 #endif
112 
113 
114 #ifndef INS_EKF2_TEMPERATURE_ID
115 #define INS_EKF2_TEMPERATURE_ID ABI_BROADCAST
116 #endif
118 
119 
120 #ifndef INS_EKF2_AGL_ID
121 #define INS_EKF2_AGL_ID ABI_BROADCAST
122 #endif
124 
125 /* default Gyro to use in INS */
126 #ifndef INS_EKF2_GYRO_ID
127 #define INS_EKF2_GYRO_ID ABI_BROADCAST
128 #endif
130 
131 /* default Accelerometer to use in INS */
132 #ifndef INS_EKF2_ACCEL_ID
133 #define INS_EKF2_ACCEL_ID ABI_BROADCAST
134 #endif
136 
137 /* default Magnetometer to use in INS */
138 #ifndef INS_EKF2_MAG_ID
139 #define INS_EKF2_MAG_ID ABI_BROADCAST
140 #endif
142 
143 /* default GPS to use in INS */
144 #ifndef INS_EKF2_GPS_ID
145 #define INS_EKF2_GPS_ID GPS_MULTI_ID
146 #endif
148 
149 /* default RELPOS to use for heading in INS */
150 #ifndef INS_EKF2_RELPOS_ID
151 #define INS_EKF2_RELPOS_ID ABI_BROADCAST
152 #endif
154 
155 /* default Optical Flow to use in INS */
156 #ifndef INS_EKF2_OF_ID
157 #define INS_EKF2_OF_ID ABI_BROADCAST
158 #endif
160 
161 /* IMU X offset from CoG position in meters */
162 #ifndef INS_EKF2_IMU_POS_X
163 #define INS_EKF2_IMU_POS_X 0
164 #endif
166 
167 /* IMU Y offset from CoG position in meters */
168 #ifndef INS_EKF2_IMU_POS_Y
169 #define INS_EKF2_IMU_POS_Y 0
170 #endif
172 
173 /* IMU Z offset from CoG position in meters */
174 #ifndef INS_EKF2_IMU_POS_Z
175 #define INS_EKF2_IMU_POS_Z 0
176 #endif
178 
179 /* GPS X offset from CoG position in meters */
180 #ifndef INS_EKF2_GPS_POS_X
181 #define INS_EKF2_GPS_POS_X 0
182 #endif
184 
185 /* GPS Y offset from CoG position in meters */
186 #ifndef INS_EKF2_GPS_POS_Y
187 #define INS_EKF2_GPS_POS_Y 0
188 #endif
190 
191 /* GPS Z offset from CoG position in meters */
192 #ifndef INS_EKF2_GPS_POS_Z
193 #define INS_EKF2_GPS_POS_Z 0
194 #endif
196 
197 /* Default flow/radar message delay (in ms) */
198 #ifndef INS_EKF2_FLOW_SENSOR_DELAY
199 #define INS_EKF2_FLOW_SENSOR_DELAY 15
200 #endif
201 PRINT_CONFIG_VAR(INS_FLOW_SENSOR_DELAY)
202 
203 /* Default minimum accepted quality (1 to 255) */
204 #ifndef INS_EKF2_MIN_FLOW_QUALITY
205 #define INS_EKF2_MIN_FLOW_QUALITY 100
206 #endif
208 
209 /* Max flow rate that the sensor can measure (rad/sec) */
210 #ifndef INS_EKF2_MAX_FLOW_RATE
211 #define INS_EKF2_MAX_FLOW_RATE 200
212 #endif
214 
215 /* Flow sensor X offset from CoG position in meters */
216 #ifndef INS_EKF2_FLOW_POS_X
217 #define INS_EKF2_FLOW_POS_X 0
218 #endif
220 
221 /* Flow sensor Y offset from CoG position in meters */
222 #ifndef INS_EKF2_FLOW_POS_Y
223 #define INS_EKF2_FLOW_POS_Y 0
224 #endif
226 
227 /* Flow sensor Z offset from CoG position in meters */
228 #ifndef INS_EKF2_FLOW_POS_Z
229 #define INS_EKF2_FLOW_POS_Z 0
230 #endif
232 
233 /* Flow sensor noise in rad/sec */
234 #ifndef INS_EKF2_FLOW_NOISE
235 #define INS_EKF2_FLOW_NOISE 0.03
236 #endif
238 
239 /* Flow sensor noise at qmin in rad/sec */
240 #ifndef INS_EKF2_FLOW_NOISE_QMIN
241 #define INS_EKF2_FLOW_NOISE_QMIN 0.05
242 #endif
244 
245 /* Flow sensor innovation gate */
246 #ifndef INS_EKF2_FLOW_INNOV_GATE
247 #define INS_EKF2_FLOW_INNOV_GATE 4
248 #endif
250 
251 /* External vision position noise (m) */
252 #ifndef INS_EKF2_EVP_NOISE
253 #define INS_EKF2_EVP_NOISE 0.02f
254 #endif
256 
257 /* External vision velocity noise (m/s) */
258 #ifndef INS_EKF2_EVV_NOISE
259 #define INS_EKF2_EVV_NOISE 0.1f
260 #endif
262 
263 /* External vision angle noise (rad) */
264 #ifndef INS_EKF2_EVA_NOISE
265 #define INS_EKF2_EVA_NOISE 0.05f
266 #endif
268 
269 /* GPS measurement noise for horizontal velocity (m/s) */
270 #ifndef INS_EKF2_GPS_V_NOISE
271 #define INS_EKF2_GPS_V_NOISE 0.3f
272 #endif
274 
275 /* GPS measurement position noise (m) */
276 #ifndef INS_EKF2_GPS_P_NOISE
277 #define INS_EKF2_GPS_P_NOISE 0.5f
278 #endif
280 
281 /* Barometric measurement noise for altitude (m) */
282 #ifndef INS_EKF2_BARO_NOISE
283 #define INS_EKF2_BARO_NOISE 3.5f
284 #endif
286 
287 /* Maximum allowed distance error for the RTK relative heading measurement (m) */
288 #ifndef INS_EKF2_RELHEADING_ERR
289 #define INS_EKF2_RELHEADING_ERR 0.2
290 #endif
291 
292 #ifdef INS_EXT_VISION_ROTATION
293 struct FloatQuat ins_ext_vision_rot;
294 #endif
295 
296 /* All registered ABI events */
307 
308 /* All ABI callbacks */
309 static void baro_cb(uint8_t sender_id, uint32_t stamp, float pressure);
310 static void temperature_cb(uint8_t sender_id, float temp);
311 static void agl_cb(uint8_t sender_id, uint32_t stamp, float distance);
312 static void gyro_int_cb(uint8_t sender_id, uint32_t stamp, struct FloatRates *delta_gyro, uint16_t dt);
313 static void accel_int_cb(uint8_t sender_id, uint32_t stamp, struct FloatVect3 *delta_accel, uint16_t dt);
314 static void mag_cb(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *mag);
315 static void gps_cb(uint8_t sender_id, uint32_t stamp, struct GpsState *gps_s);
316 static void relpos_cb(uint8_t sender_id, uint32_t stamp, struct RelPosNED *relpos);
317 static void optical_flow_cb(uint8_t sender_id, uint32_t stamp, int32_t flow_x, int32_t flow_y, int32_t flow_der_x, int32_t flow_der_y, float quality, float size_divergence);
318 static void reset_cb(uint8_t sender_id, uint8_t flag);
319 
320 /* Static local functions */
321 static void ins_ekf2_publish_attitude(uint32_t stamp);
322 
323 /* Static local variables */
324 static Ekf ekf;
326 struct ekf2_t ekf2;
327 static struct extVisionSample sample_ev;
328 #if PERIODIC_TELEMETRY
330 
331 static void send_ins(struct transport_tx *trans, struct link_device *dev)
332 {
333  struct NedCoor_i pos, speed, accel;
334 
335  // Get it from the EKF
336  const Vector3f pos_f{ekf.getPosition()};
337  const Vector3f speed_f{ekf.getVelocity()};
338  const Vector3f accel_f{ekf.getVelocityDerivative()};
339 
340  // Convert to integer
341  pos.x = POS_BFP_OF_REAL(pos_f(0));
342  pos.y = POS_BFP_OF_REAL(pos_f(1));
343  pos.z = POS_BFP_OF_REAL(pos_f(2));
344  speed.x = SPEED_BFP_OF_REAL(speed_f(0));
345  speed.y = SPEED_BFP_OF_REAL(speed_f(1));
346  speed.z = SPEED_BFP_OF_REAL(speed_f(2));
347  accel.x = ACCEL_BFP_OF_REAL(accel_f(0));
348  accel.y = ACCEL_BFP_OF_REAL(accel_f(1));
349  accel.z = ACCEL_BFP_OF_REAL(accel_f(2));
350 
351  // Send the message
352  pprz_msg_send_INS(trans, dev, AC_ID,
353  &pos.x, &pos.y, &pos.z,
354  &speed.x, &speed.y, &speed.z,
355  &accel.x, &accel.y, &accel.z);
356 }
357 
358 static void send_ins_z(struct transport_tx *trans, struct link_device *dev)
359 {
360  float baro_z = 0.0f;
361  int32_t pos_z, speed_z, accel_z;
362 
363  // Get it from the EKF
364  const Vector3f pos_f{ekf.getPosition()};
365  const Vector3f speed_f{ekf.getVelocity()};
366  const Vector3f accel_f{ekf.getVelocityDerivative()};
367 
368  // Convert to integer
369  pos_z = POS_BFP_OF_REAL(pos_f(2));
370  speed_z = SPEED_BFP_OF_REAL(speed_f(2));
371  accel_z = ACCEL_BFP_OF_REAL(accel_f(2));
372 
373  // Send the message
374  pprz_msg_send_INS_Z(trans, dev, AC_ID,
375  &baro_z, &pos_z, &speed_z, &accel_z);
376 }
377 
378 static void send_ins_ref(struct transport_tx *trans, struct link_device *dev)
379 {
380  float qfe = 101325.0; //TODO: this is qnh not qfe?
381  if (ekf2.ltp_stamp > 0)
382  pprz_msg_send_INS_REF(trans, dev, AC_ID,
385  &ekf2.ltp_def.hmsl, &qfe);
386 }
387 
388 static void send_ins_ekf2(struct transport_tx *trans, struct link_device *dev)
389 {
390  uint16_t gps_check_status, soln_status;
391  uint16_t filter_fault_status = ekf.fault_status().value; // FIXME: 32bit instead of 16bit
392  uint32_t control_mode = ekf.control_status().value;
393  ekf.get_gps_check_status(&gps_check_status);
394  ekf.get_ekf_soln_status(&soln_status);
395 
396  uint16_t innov_test_status;
397  float mag, vel, pos, hgt, tas, hagl, flow, beta, mag_decl;
398  uint8_t terrain_valid, dead_reckoning;
399  ekf.get_innovation_test_status(innov_test_status, mag, vel, pos, hgt, tas, hagl, beta);
400  //ekf.get_flow_innov(&flow);
401  ekf.get_mag_decl_deg(&mag_decl);
402 
403  if (ekf.isTerrainEstimateValid()) {
404  terrain_valid = 1;
405  } else {
406  terrain_valid = 0;
407  }
408 
409  if (ekf.inertial_dead_reckoning()) {
410  dead_reckoning = 1;
411  } else {
412  dead_reckoning = 0;
413  }
414 
415  pprz_msg_send_INS_EKF2(trans, dev, AC_ID,
416  &control_mode, &filter_fault_status, &gps_check_status, &soln_status,
417  &innov_test_status, &mag, &vel, &pos, &hgt, &tas, &hagl, &flow, &beta,
418  &mag_decl, &terrain_valid, &dead_reckoning);
419 }
420 
421 static void send_ins_ekf2_ext(struct transport_tx *trans, struct link_device *dev)
422 {
423  float gps_drift[3];
424  Vector3f vibe = ekf.getImuVibrationMetrics();
425  bool gps_blocked;
426  uint8_t gps_blocked_b;
427  ekf.get_gps_drift_metrics(gps_drift, &gps_blocked);
428  gps_blocked_b = gps_blocked;
429 
430  pprz_msg_send_INS_EKF2_EXT(trans, dev, AC_ID,
431  &gps_drift[0], &gps_drift[1], &gps_drift[2], &gps_blocked_b,
432  &vibe(0), &vibe(1), &vibe(2));
433 }
434 
435 static void send_filter_status(struct transport_tx *trans, struct link_device *dev)
436 {
437  uint8_t ahrs_ekf2_id = AHRS_COMP_ID_EKF2;
438  filter_control_status_u control_mode = ekf.control_status();
439  uint32_t filter_fault_status = ekf.fault_status().value;
440  uint16_t filter_fault_status_16 = filter_fault_status; //FIXME
441  uint8_t mde = 0;
442 
443  // Check the alignment and if GPS is fused
444  if (control_mode.flags.tilt_align && control_mode.flags.yaw_align && (control_mode.flags.gps || control_mode.flags.ev_pos)) {
445  mde = 3;
446  } else if (control_mode.flags.tilt_align && control_mode.flags.yaw_align) {
447  mde = 4;
448  } else {
449  mde = 2;
450  }
451 
452  // Check if there is a covariance error
453  if (filter_fault_status) {
454  mde = 6;
455  }
456 
457  pprz_msg_send_STATE_FILTER_STATUS(trans, dev, AC_ID, &ahrs_ekf2_id, &mde, &filter_fault_status_16);
458 }
459 
460 static void send_wind_info_ret(struct transport_tx *trans, struct link_device *dev)
461 {
462  float tas;
463  Vector2f wind = ekf.getWindVelocity();
464  uint8_t flags = 0x5;
465  float f_zero = 0;
466 
467  ekf.get_true_airspeed(&tas);
468 
469  pprz_msg_send_WIND_INFO_RET(trans, dev, AC_ID, &flags, &wind(1), &wind(0), &f_zero, &tas);
470 }
471 
472 static void send_ahrs_bias(struct transport_tx *trans, struct link_device *dev)
473 {
474  Vector3f accel_bias = ekf.getAccelBias();
475  Vector3f gyro_bias = ekf.getGyroBias();
476  Vector3f mag_bias = ekf.getMagBias();
477 
478  pprz_msg_send_AHRS_BIAS(trans, dev, AC_ID, &accel_bias(0), &accel_bias(1), &accel_bias(2),
479  &gyro_bias(0), &gyro_bias(1), &gyro_bias(2), &mag_bias(0), &mag_bias(1), &mag_bias(2));
480 }
481 
482 static void send_ahrs_quat(struct transport_tx *trans, struct link_device *dev)
483 {
484  struct Int32Quat ltp_to_body_quat;
485  const Quatf att_q{ekf.calculate_quaternion()};
486  ltp_to_body_quat.qi = QUAT1_BFP_OF_REAL(att_q(0));
487  ltp_to_body_quat.qx = QUAT1_BFP_OF_REAL(att_q(1));
488  ltp_to_body_quat.qy = QUAT1_BFP_OF_REAL(att_q(2));
489  ltp_to_body_quat.qz = QUAT1_BFP_OF_REAL(att_q(3));
490  struct Int32Quat *quat = stateGetNedToBodyQuat_i();
491  float foo = 0.f;
492  uint8_t ahrs_id = 1; // generic
493  pprz_msg_send_AHRS_QUAT_INT(trans, dev, AC_ID,
494  &foo,
495  &ltp_to_body_quat.qi,
496  &ltp_to_body_quat.qx,
497  &ltp_to_body_quat.qy,
498  &ltp_to_body_quat.qz,
499  &(quat->qi),
500  &(quat->qx),
501  &(quat->qy),
502  &(quat->qz),
503  &ahrs_id);
504 }
505 
506 
507 static void send_external_pose_down(struct transport_tx *trans, struct link_device *dev)
508 {
509  if(sample_ev.time_us == 0){
510  return;
511  }
512  float sample_temp_ev[11];
513  sample_temp_ev[0] = (float) sample_ev.time_us;
514  sample_temp_ev[1] = sample_ev.pos(0) ;
515  sample_temp_ev[2] = sample_ev.pos(1) ;
516  sample_temp_ev[3] = sample_ev.pos(2) ;
517  sample_temp_ev[4] = sample_ev.vel(0) ;
518  sample_temp_ev[5] = sample_ev.vel(1) ;
519  sample_temp_ev[6] = sample_ev.vel(2) ;
520  sample_temp_ev[7] = sample_ev.quat(0);
521  sample_temp_ev[8] = sample_ev.quat(1);
522  sample_temp_ev[9] = sample_ev.quat(2);
523  sample_temp_ev[10] = sample_ev.quat(3);
524  pprz_msg_send_EXTERNAL_POSE_DOWN(trans, dev, AC_ID,
525  &sample_temp_ev[0],
526  &sample_temp_ev[1],
527  &sample_temp_ev[2],
528  &sample_temp_ev[3],
529  &sample_temp_ev[4],
530  &sample_temp_ev[5],
531  &sample_temp_ev[6],
532  &sample_temp_ev[7],
533  &sample_temp_ev[8],
534  &sample_temp_ev[9],
535  &sample_temp_ev[10] );
536 }
537 #endif
538 
539 /* Initialize the EKF */
540 void ins_ekf2_init(void)
541 {
542  /* Get the ekf parameters */
543  ekf_params = ekf.getParamHandle();
544  ekf_params->fusion_mode = INS_EKF2_FUSION_MODE;
545  ekf_params->vdist_sensor_type = INS_EKF2_VDIST_SENSOR_TYPE;
546  ekf_params->gps_check_mask = INS_EKF2_GPS_CHECK_MASK;
547 
548  /* Set specific noise levels */
549  ekf_params->accel_bias_p_noise = 3.0e-3f;
550  ekf_params->gps_vel_noise = INS_EKF2_GPS_V_NOISE;
551  ekf_params->gps_pos_noise = INS_EKF2_GPS_P_NOISE;
552  ekf_params->baro_noise = INS_EKF2_BARO_NOISE;
553 
554  /* Set optical flow parameters */
555  ekf_params->flow_qual_min = INS_EKF2_MIN_FLOW_QUALITY;
556  ekf_params->flow_delay_ms = INS_EKF2_FLOW_SENSOR_DELAY;
557  ekf_params->range_delay_ms = INS_EKF2_FLOW_SENSOR_DELAY;
558  ekf_params->flow_noise = INS_EKF2_FLOW_NOISE;
559  ekf_params->flow_noise_qual_min = INS_EKF2_FLOW_NOISE_QMIN;
560  ekf_params->flow_innov_gate = INS_EKF2_FLOW_INNOV_GATE;
561 
562  /* Set the IMU position relative from the CoG in xyz (m) */
563  ekf_params->imu_pos_body = {
567  };
568 
569  /* Set the GPS position relative from the CoG in xyz (m) */
570  ekf_params->gps_pos_body = {
574  };
575 
576  /* Set flow sensor offset from CoG position in xyz (m) */
577  ekf_params->flow_pos_body = {
581  };
582 
583  /* Set range as default AGL measurement if possible */
584  ekf_params->range_aid = INS_EKF2_RANGE_MAIN_AGL;
585 
586  /* Initialize struct */
587  ekf2.ltp_stamp = 0;
588  ekf2.flow_stamp = 0;
589  ekf2.gyro_valid = false;
590  ekf2.accel_valid = false;
591  ekf2.got_imu_data = false;
593  ekf2.temp = 20.0f; // Default temperature of 20 degrees celcius
594  ekf2.qnh = 1013.25f; // Default atmosphere
595 
596  /* Initialize the range sensor limits */
597  ekf.set_rangefinder_limits(INS_EKF2_SONAR_MIN_RANGE, INS_EKF2_SONAR_MAX_RANGE);
598 
599  /* Initialize the flow sensor limits */
601 
602  // Don't send external vision data by default
603  sample_ev.time_us = 0;
604 
605  /* Initialize the origin from flight plan */
606 #if USE_INS_NAV_INIT
607  if(ekf.setEkfGlobalOrigin(NAV_LAT0*1e-7, NAV_LON0*1e-7, (NAV_ALT0)*1e-3)) // EKF2 works HMSL
608  {
609  struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */
610  llh_nav0.lat = NAV_LAT0;
611  llh_nav0.lon = NAV_LON0;
612  /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */
613  llh_nav0.alt = NAV_ALT0 + NAV_MSL0; // in millimeters above WGS84 reference ellipsoid
614 
615  ltp_def_from_lla_i(&ekf2.ltp_def, &llh_nav0);
616  ekf2.ltp_def.hmsl = NAV_ALT0;
617  stateSetLocalOrigin_i(MODULE_INS_EKF2_ID, &ekf2.ltp_def);
618 
619  /* update local ENU coordinates of global waypoints */
621 
622  ekf2.ltp_stamp = 1;
623  }
624 #endif
625 
626 #if PERIODIC_TELEMETRY
632  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_STATE_FILTER_STATUS, send_filter_status);
635  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_AHRS_QUAT_INT, send_ahrs_quat);
636  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_EXTERNAL_POSE_DOWN, send_external_pose_down);
637 #endif
638 
639  /*
640  * Subscribe to scaled IMU measurements and attach callbacks
641  */
642  AbiBindMsgBARO_ABS(INS_EKF2_BARO_ID, &baro_ev, baro_cb);
643  AbiBindMsgTEMPERATURE(INS_EKF2_TEMPERATURE_ID, &temperature_ev, temperature_cb);
644  AbiBindMsgAGL(INS_EKF2_AGL_ID, &agl_ev, agl_cb);
645  AbiBindMsgIMU_GYRO_INT(INS_EKF2_GYRO_ID, &gyro_int_ev, gyro_int_cb);
646  AbiBindMsgIMU_ACCEL_INT(INS_EKF2_ACCEL_ID, &accel_int_ev, accel_int_cb);
647  AbiBindMsgIMU_MAG(INS_EKF2_MAG_ID, &mag_ev, mag_cb);
648  AbiBindMsgGPS(INS_EKF2_GPS_ID, &gps_ev, gps_cb);
649  AbiBindMsgRELPOS(INS_EKF2_RELPOS_ID, &relpos_ev, relpos_cb);
650  AbiBindMsgOPTICAL_FLOW(INS_EKF2_OF_ID, &optical_flow_ev, optical_flow_cb);
651  AbiBindMsgINS_RESET(ABI_BROADCAST, &reset_ev, reset_cb);
652 }
653 
654 static void reset_ref(void)
655 {
656 #if USE_GPS
657  if (GpsFixValid()) {
658  struct LlaCoor_i lla_pos = lla_int_from_gps(&gps);
659  if (ekf.setEkfGlobalOrigin(lla_pos.lat*1e-7, lla_pos.lon*1e-7, gps.hmsl*1e-3)) {
660  ltp_def_from_lla_i(&ekf2.ltp_def, &lla_pos);
662  stateSetLocalOrigin_i(MODULE_INS_EKF2_ID, &ekf2.ltp_def);
663  }
664  }
665 #endif
666 }
667 
668 static void reset_vertical_ref(void)
669 {
670 #if USE_GPS
671  if (GpsFixValid()) {
672  struct LlaCoor_i lla_pos = lla_int_from_gps(&gps);
673  struct LlaCoor_i lla = {
675  .lon = stateGetLlaOrigin_i().lon,
676  .alt = lla_pos.alt
677  };
678  if (ekf.setEkfGlobalOrigin(lla.lat*1e-7, lla.lon*1e-7, gps.hmsl*1e-3)) {
681  stateSetLocalOrigin_i(MODULE_INS_EKF2_ID, &ekf2.ltp_def);
682  }
683  }
684 #endif
685 }
686 
687 static void reset_cb(uint8_t sender_id UNUSED, uint8_t flag)
688 {
689  switch (flag) {
690  case INS_RESET_REF:
691  reset_ref();
692  break;
695  break;
696  default:
697  // unsupported cases
698  break;
699  }
700 }
701 /* Update the INS state */
702 void ins_ekf2_update(void)
703 {
704  /* Set EKF settings */
705  ekf.set_in_air_status(autopilot_in_flight());
706 
707  /* Update the EKF */
708  if (ekf2.got_imu_data) {
709  // Update the EKF but ignore the response and also copy the faster intermediate filter
710  ekf.update();
711  filter_control_status_u control_status = ekf.control_status();
712 
713  // Only publish position after successful alignment
714  if (control_status.flags.tilt_align) {
715  /* Get the position */
716  const Vector3f pos_f{ekf.getPosition()};
717  struct NedCoor_f pos;
718  pos.x = pos_f(0);
719  pos.y = pos_f(1);
720  pos.z = pos_f(2);
721 
722  // Publish to the state
723  stateSetPositionNed_f(MODULE_INS_EKF2_ID, &pos);
724 
725  /* Get the velocity in NED frame */
726  const Vector3f vel_f{ekf.getVelocity()};
727  struct NedCoor_f speed;
728  speed.x = vel_f(0);
729  speed.y = vel_f(1);
730  speed.z = vel_f(2);
731 
732  // Publish to state
733  stateSetSpeedNed_f(MODULE_INS_EKF2_ID, &speed);
734 
735  /* Get the accelerations in NED frame */
736  const Vector3f vel_deriv_f{ekf.getVelocityDerivative()};
737  struct NedCoor_f accel;
738  accel.x = vel_deriv_f(0);
739  accel.y = vel_deriv_f(1);
740  accel.z = vel_deriv_f(2);
741 
742  // Publish to state
743  stateSetAccelNed_f(MODULE_INS_EKF2_ID, &accel);
744 
745  /* Get local origin */
746  // Position of local NED origin in GPS / WGS84 frame
747  double ekf_origin_lat, ekf_origin_lon;
748  float ref_alt;
749  struct LlaCoor_i lla_ref;
750  uint64_t origin_time;
751 
752  // Only update the origin when the state estimator has updated the origin
753  bool ekf_origin_valid = ekf.getEkfGlobalOrigin(origin_time, ekf_origin_lat, ekf_origin_lon, ref_alt);
754  if (ekf_origin_valid && (origin_time > ekf2.ltp_stamp)) {
755  lla_ref.lat = ekf_origin_lat * 1e7; // WGS-84 lat
756  lla_ref.lon = ekf_origin_lon * 1e7; // WGS-84 lon
757  lla_ref.alt = ref_alt * 1e3 + wgs84_ellipsoid_to_geoid_i(lla_ref.lat, lla_ref.lon); // in millimeters above WGS84 reference ellipsoid (ref_alt is in HMSL)
758  ltp_def_from_lla_i(&ekf2.ltp_def, &lla_ref);
759  ekf2.ltp_def.hmsl = ref_alt * 1e3;
760  stateSetLocalOrigin_i(MODULE_INS_EKF2_ID, &ekf2.ltp_def);
761 
762  /* update local ENU coordinates of global waypoints */
764 
765  ekf2.ltp_stamp = origin_time;
766  }
767  }
768  }
769 
770 #if defined SITL && USE_NPS
771  if (nps_bypass_ins) {
773  }
774 #endif
775 
776  ekf2.got_imu_data = false;
777 }
778 
780 {
781  ekf_params->mag_fusion_type = ekf2.mag_fusion_type = unk;
782 }
783 
785 {
786  if (mode) {
787  ekf_params->fusion_mode = ekf2.fusion_mode = (MASK_USE_OF | MASK_USE_GPSYAW);
788  } else {
790  }
791 }
792 
794  if (DL_EXTERNAL_POSE_ac_id(buf) != AC_ID) { return; } // not for this aircraft
795 
796  sample_ev.time_us = get_sys_time_usec(); //FIXME
797  sample_ev.pos(0) = DL_EXTERNAL_POSE_enu_y(buf);
798  sample_ev.pos(1) = DL_EXTERNAL_POSE_enu_x(buf);
799  sample_ev.pos(2) = -DL_EXTERNAL_POSE_enu_z(buf);
800  sample_ev.vel(0) = DL_EXTERNAL_POSE_enu_yd(buf);
801  sample_ev.vel(1) = DL_EXTERNAL_POSE_enu_xd(buf);
802  sample_ev.vel(2) = -DL_EXTERNAL_POSE_enu_zd(buf);
803  sample_ev.quat(0) = DL_EXTERNAL_POSE_body_qi(buf);
804  sample_ev.quat(1) = DL_EXTERNAL_POSE_body_qy(buf);
805  sample_ev.quat(2) = DL_EXTERNAL_POSE_body_qx(buf);
806  sample_ev.quat(3) = -DL_EXTERNAL_POSE_body_qz(buf);
807 
808 #ifdef INS_EXT_VISION_ROTATION
809  // Rotate the quaternion
810  struct FloatQuat body_q = {sample_ev.quat(0), sample_ev.quat(1), sample_ev.quat(2), sample_ev.quat(3)};
811  struct FloatQuat rot_q;
812  float_quat_comp(&rot_q, &body_q, &ins_ext_vision_rot);
813  sample_ev.quat(0) = rot_q.qi;
814  sample_ev.quat(1) = rot_q.qx;
815  sample_ev.quat(2) = rot_q.qy;
816  sample_ev.quat(3) = rot_q.qz;
817 #endif
818 
819  sample_ev.posVar.setAll(INS_EKF2_EVP_NOISE);
820  sample_ev.velCov = matrix::eye<float, 3>() * INS_EKF2_EVV_NOISE;
821  sample_ev.angVar = INS_EKF2_EVA_NOISE;
822  sample_ev.vel_frame = velocity_frame_t::LOCAL_FRAME_FRD;
823 
824  ekf.setExtVisionData(sample_ev);
825 }
826 
827 void ins_ekf2_parse_EXTERNAL_POSE_SMALL(uint8_t __attribute__((unused)) *buf) {
828 
829 }
830 
835 {
836  imuSample imu_sample = {};
837  imu_sample.time_us = stamp;
838  imu_sample.delta_ang_dt = ekf2.gyro_dt * 1.e-6f;
839  imu_sample.delta_ang = Vector3f{ekf2.delta_gyro.p, ekf2.delta_gyro.q, ekf2.delta_gyro.r};
840  imu_sample.delta_vel_dt = ekf2.accel_dt * 1.e-6f;
841  imu_sample.delta_vel = Vector3f{ekf2.delta_accel.x, ekf2.delta_accel.y, ekf2.delta_accel.z};
842  ekf.setIMUData(imu_sample);
843 
844  if (ekf.attitude_valid()) {
845  // Calculate the quaternion
846  struct FloatQuat ltp_to_body_quat;
847  const Quatf att_q{ekf.calculate_quaternion()};
848  ltp_to_body_quat.qi = att_q(0);
849  ltp_to_body_quat.qx = att_q(1);
850  ltp_to_body_quat.qy = att_q(2);
851  ltp_to_body_quat.qz = att_q(3);
852 
853  // Publish it to the state
854  stateSetNedToBodyQuat_f(MODULE_INS_EKF2_ID, &ltp_to_body_quat);
855 
856  /* Check the quaternion reset state */
857  float delta_q_reset[4];
858  uint8_t quat_reset_counter;
859  ekf.get_quat_reset(delta_q_reset, &quat_reset_counter);
860 
861 #ifndef NO_RESET_UPDATE_SETPOINT_HEADING
862  // FIXME is this hard reset of control setpoint really needed ? is it the right place ?
863  if (ekf2.quat_reset_counter < quat_reset_counter) {
864  float psi = matrix::Eulerf(matrix::Quatf(delta_q_reset)).psi();
865  guidance_h.sp.heading += psi;
866  guidance_h.rc_sp.heading += psi;
867  nav.heading += psi;
868  //guidance_h_read_rc(autopilot_in_flight());
870  ekf2.quat_reset_counter = quat_reset_counter;
871  }
872 #endif
873 
874  /* Get in-run gyro bias */
875  struct FloatRates body_rates;
876  Vector3f gyro_bias{ekf.getGyroBias()};
877  body_rates.p = (ekf2.delta_gyro.p / (ekf2.gyro_dt * 1.e-6f)) - gyro_bias(0);
878  body_rates.q = (ekf2.delta_gyro.q / (ekf2.gyro_dt * 1.e-6f)) - gyro_bias(1);
879  body_rates.r = (ekf2.delta_gyro.r / (ekf2.gyro_dt * 1.e-6f)) - gyro_bias(2);
880 
881  // Publish it to the state
882  stateSetBodyRates_f(MODULE_INS_EKF2_ID, &body_rates);
883 
884  /* Get the in-run acceleration bias */
885  struct Int32Vect3 accel;
886  Vector3f accel_bias{ekf.getAccelBias()};
887  accel.x = ACCEL_BFP_OF_REAL((ekf2.delta_accel.x / (ekf2.accel_dt * 1e-6f)) - accel_bias(0));
888  accel.y = ACCEL_BFP_OF_REAL((ekf2.delta_accel.y / (ekf2.accel_dt * 1e-6f)) - accel_bias(1));
889  accel.z = ACCEL_BFP_OF_REAL((ekf2.delta_accel.z / (ekf2.accel_dt * 1e-6f)) - accel_bias(2));
890 
891  // Publish it to the state
892  stateSetAccelBody_i(MODULE_INS_EKF2_ID, &accel);
893  }
894 
895  ekf2.gyro_valid = false;
896  ekf2.accel_valid = false;
897  ekf2.got_imu_data = true;
898 }
899 
900 /* Update INS based on Baro information */
901 static void baro_cb(uint8_t __attribute__((unused)) sender_id, uint32_t stamp, float pressure)
902 {
903  baroSample sample;
904  sample.time_us = stamp;
905 
906  // Calculate the air density
907  float rho = pprz_isa_density_of_pressure(pressure, ekf2.temp);
908  ekf.set_air_density(rho);
909 
910  // Calculate the height above mean sea level based on pressure
911  sample.hgt = pprz_isa_height_of_pressure_full(pressure, ekf2.qnh * 100.0f);
912  ekf.setBaroData(sample);
913 }
914 
915 /* Save the latest temperature measurement for air density calculations */
916 static void temperature_cb(uint8_t __attribute__((unused)) sender_id, float temp)
917 {
918  ekf2.temp = temp;
919 }
920 
921 /* Update INS based on AGL information */
922 static void agl_cb(uint8_t __attribute__((unused)) sender_id, uint32_t stamp, float distance)
923 {
924  rangeSample sample;
925  sample.time_us = stamp;
926  sample.rng = distance;
927  sample.quality = -1;
928 
929  ekf.setRangeData(sample);
930 }
931 
932 /* Update INS based on Gyro information */
933 static void gyro_int_cb(uint8_t __attribute__((unused)) sender_id,
934  uint32_t stamp, struct FloatRates *delta_gyro, uint16_t dt)
935 {
936  // Copy and save the gyro data
937  RATES_COPY(ekf2.delta_gyro, *delta_gyro);
938  ekf2.gyro_dt = dt;
939  ekf2.gyro_valid = true;
940 
941  /* When Gyro and accelerometer are valid enter it into the EKF */
942  if (ekf2.gyro_valid && ekf2.accel_valid) {
944  }
945 }
946 
947 /* Update INS based on Accelerometer information */
948 static void accel_int_cb(uint8_t sender_id __attribute__((unused)),
949  uint32_t stamp, struct FloatVect3 *delta_accel, uint16_t dt)
950 {
951  // Copy and save the gyro data
952  VECT3_COPY(ekf2.delta_accel, *delta_accel);
953  ekf2.accel_dt = dt;
954  ekf2.accel_valid = true;
955 
956  /* When Gyro and accelerometer are valid enter it into the EKF */
957  if (ekf2.gyro_valid && ekf2.accel_valid) {
959  }
960 }
961 
962 /* Update INS based on Magnetometer information */
963 static void mag_cb(uint8_t __attribute__((unused)) sender_id,
964  uint32_t stamp,
965  struct Int32Vect3 *mag)
966 {
967  struct FloatVect3 mag_gauss;
968  magSample sample;
969  sample.time_us = stamp;
970 
971  // Convert Magnetometer information to float and to radius 0.2f
972  MAGS_FLOAT_OF_BFP(mag_gauss, *mag);
973  mag_gauss.x *= 0.4f;
974  mag_gauss.y *= 0.4f;
975  mag_gauss.z *= 0.4f;
976 
977  // Publish information to the EKF
978  sample.mag(0) = mag_gauss.x;
979  sample.mag(1) = mag_gauss.y;
980  sample.mag(2) = mag_gauss.z;
981 
982  ekf.setMagData(sample);
983  ekf2.got_imu_data = true;
984 }
985 
986 /* Update INS based on GPS information */
987 static void gps_cb(uint8_t sender_id __attribute__((unused)),
988  uint32_t stamp,
989  struct GpsState *gps_s)
990 {
991  gps_message gps_msg = {};
992  gps_msg.time_usec = stamp;
993  struct LlaCoor_i lla_pos = lla_int_from_gps(gps_s);
994  gps_msg.lat = lla_pos.lat;
995  gps_msg.lon = lla_pos.lon;
996  gps_msg.alt = gps_s->hmsl; // EKF2 works with HMSL
997 #if INS_EKF2_GPS_COURSE_YAW
998  gps_msg.yaw = wrap_pi((float)gps_s->course / 1e7);
999  gps_msg.yaw_offset = 0;
1000 #elif defined(INS_EKF2_GPS_YAW_OFFSET)
1001  if(ekf2.rel_heading_valid) {
1002  gps_msg.yaw = wrap_pi(ekf2.rel_heading - RadOfDeg(INS_EKF2_GPS_YAW_OFFSET));
1003  ekf2.rel_heading_valid = false;
1004  } else {
1005  gps_msg.yaw = NAN;
1006  }
1007 
1008  // Offset also needs to be substracted from the heading (this is for roll/pitch angle limits)
1009  gps_msg.yaw_offset = RadOfDeg(INS_EKF2_GPS_YAW_OFFSET);
1010 #else
1011  gps_msg.yaw = NAN;
1012  gps_msg.yaw_offset = NAN;
1013 #endif
1014  gps_msg.fix_type = gps_s->fix;
1015  gps_msg.eph = gps_s->hacc / 100.0;
1016  gps_msg.epv = gps_s->vacc / 100.0;
1017  gps_msg.sacc = gps_s->sacc / 100.0;
1018  gps_msg.vel_m_s = gps_s->gspeed / 100.0;
1019  struct NedCoor_f ned_vel = ned_vel_float_from_gps(gps_s);
1020  gps_msg.vel_ned(0) = ned_vel.x;
1021  gps_msg.vel_ned(1) = ned_vel.y;
1022  gps_msg.vel_ned(2) = ned_vel.z;
1023  gps_msg.vel_ned_valid = bit_is_set(gps_s->valid_fields, GPS_VALID_VEL_NED_BIT);
1024  gps_msg.nsats = gps_s->num_sv;
1025  gps_msg.pdop = gps_s->pdop;
1026 
1027  ekf.setGpsData(gps_msg);
1028 }
1029 
1030 /* Update the local relative position information */
1031 static void relpos_cb(uint8_t sender_id __attribute__((unused)), uint32_t stamp __attribute__((unused)), struct RelPosNED *relpos)
1032 {
1033  // Verify if we received a valid heading
1034  if(
1035 #ifdef INS_EKF2_RELHEADING_REF_ID
1036  relpos->reference_id != INS_EKF2_RELHEADING_REF_ID ||
1037 #endif
1038 #ifdef INS_EKF2_RELHEADING_DISTANCE
1039  fabs(relpos->distance - INS_EKF2_RELHEADING_DISTANCE) > INS_EKF2_RELHEADING_ERR ||
1040 #endif
1041  !ISFINITE(relpos->heading)
1042  ) {
1043  return;
1044  }
1045 
1046  ekf2.rel_heading = relpos->heading;
1047  ekf2.rel_heading_valid = true;
1048 }
1049 
1050 /* Update INS based on Optical Flow information */
1051 static void optical_flow_cb(uint8_t sender_id __attribute__((unused)),
1052  uint32_t stamp,
1053  int32_t flow_x,
1054  int32_t flow_y,
1055  int32_t flow_der_x __attribute__((unused)),
1056  int32_t flow_der_y __attribute__((unused)),
1057  float quality,
1058  float size_divergence __attribute__((unused)))
1059 {
1060  flowSample sample;
1061  sample.time_us = stamp;
1062 
1063  // Wait for two measurements in order to integrate
1064  if (ekf2.flow_stamp <= 0) {
1065  ekf2.flow_stamp = stamp;
1066  return;
1067  }
1068 
1069  // Calculate the timestamp
1070  sample.dt = (stamp - ekf2.flow_stamp);
1071  ekf2.flow_stamp = stamp;
1072 
1073  /* Build integrated flow and gyro messages for filter
1074  NOTE: pure rotations should result in same flow_x and
1075  gyro_roll and same flow_y and gyro_pitch */
1076  Vector2f flowdata;
1077  flowdata(0) = RadOfDeg(flow_y) * (1e-6 *
1078  sample.dt); // INTEGRATED FLOW AROUND Y AXIS (RIGHT -X, LEFT +X)
1079  flowdata(1) = - RadOfDeg(flow_x) * (1e-6 *
1080  sample.dt); // INTEGRATED FLOW AROUND X AXIS (FORWARD +Y, BACKWARD -Y)
1081 
1082  sample.quality = quality; // quality indicator between 0 and 255
1083  sample.flow_xy_rad =
1084  flowdata; // measured delta angle of the image about the X and Y body axes (rad), RH rotaton is positive
1085  sample.gyro_xyz = Vector3f{NAN, NAN, NAN}; // measured delta angle of the inertial frame about the body axes obtained from rate gyro measurements (rad), RH rotation is positive
1086 
1087  // Update the optical flow data based on the callback
1088  ekf.setOpticalFlowData(sample);
1089 }
Main include for ABI (AirBorneInterface).
#define ABI_BROADCAST
Broadcast address.
Definition: abi_common.h:58
Event structure to store callbacks in a linked list.
Definition: abi_common.h:67
#define AHRS_COMP_ID_EKF2
Definition: ahrs.h:47
bool autopilot_in_flight(void)
get in_flight flag
Definition: autopilot.c:340
Core autopilot interface common to all firmwares.
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:71
uint8_t last_wp UNUSED
static const float pos_z[]
struct NedCoor_f ned_vel_float_from_gps(struct GpsState *gps_s)
Get GPS ned velocity (float) Converted on the fly if not available.
Definition: gps.c:544
struct GpsState gps
global GPS state
Definition: gps.c:74
struct LlaCoor_i lla_int_from_gps(struct GpsState *gps_s)
Get GPS lla (integer) Converted on the fly if not available.
Definition: gps.c:464
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:94
float heading
Relative heading to the reference station in radians.
Definition: gps.h:134
uint32_t sacc
speed accuracy in cm/s
Definition: gps.h:103
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition: gps.h:99
#define GPS_VALID_VEL_NED_BIT
Definition: gps.h:52
uint32_t hacc
horizontal accuracy in cm
Definition: gps.h:101
double distance
Relative distance to the reference station in meters.
Definition: gps.h:133
uint16_t pdop
position dilution of precision scaled by 100
Definition: gps.h:105
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:97
uint8_t valid_fields
bitfield indicating valid fields (GPS_VALID_x_BIT)
Definition: gps.h:88
uint32_t vacc
vertical accuracy in cm
Definition: gps.h:102
#define GpsFixValid()
Definition: gps.h:168
uint16_t reference_id
Reference station identification.
Definition: gps.h:129
uint8_t num_sv
number of sat in fix
Definition: gps.h:106
uint8_t fix
status of fix
Definition: gps.h:107
data structure for GPS information
Definition: gps.h:87
Definition: gps.h:128
float q
in rad/s
float p
in rad/s
float r
in rad/s
void float_quat_comp(struct FloatQuat *a2c, struct FloatQuat *a2b, struct FloatQuat *b2c)
Composition (multiplication) of two quaternions.
Roation quaternion.
angular rates
#define MAGS_FLOAT_OF_BFP(_ef, _ei)
Definition: pprz_algebra.h:807
#define RATES_COPY(_a, _b)
Definition: pprz_algebra.h:337
#define VECT3_COPY(_a, _b)
Definition: pprz_algebra.h:140
#define QUAT1_BFP_OF_REAL(_qf)
#define ACCEL_BFP_OF_REAL(_af)
#define POS_BFP_OF_REAL(_af)
#define SPEED_BFP_OF_REAL(_af)
Rotation quaternion.
int32_t lat
in degrees*1e7
int32_t hmsl
Height above mean sea level in mm.
int32_t alt
in millimeters above WGS84 reference ellipsoid
int32_t z
Down.
int32_t z
in centimeters
struct LlaCoor_i lla
Reference point in lla.
int32_t x
in centimeters
int32_t y
East.
struct EcefCoor_i ecef
Reference point in ecef.
int32_t y
in centimeters
int32_t lon
in degrees*1e7
int32_t x
North.
void ltp_def_from_lla_i(struct LtpDef_i *def, struct LlaCoor_i *lla)
vector in Latitude, Longitude and Altitude
vector in North East Down coordinates
static int32_t wgs84_ellipsoid_to_geoid_i(int32_t lat, int32_t lon)
Get WGS84 ellipsoid/geoid separation.
static float pprz_isa_density_of_pressure(float pressure, float temp)
Get the air density (rho) from a given pressure and temperature.
Definition: pprz_isa.h:193
static float pprz_isa_height_of_pressure_full(float pressure, float ref_p)
Get relative altitude from pressure (using full equation).
Definition: pprz_isa.h:146
static void stateSetAccelNed_f(uint16_t id, struct NedCoor_f *ned_accel)
Set acceleration in NED coordinates (float).
Definition: state.h:1147
static void stateSetAccelBody_i(uint16_t id, struct Int32Vect3 *body_accel)
Set acceleration in Body coordinates (int).
Definition: state.h:1167
static struct Int32Quat * stateGetNedToBodyQuat_i(void)
Get vehicle body attitude quaternion (int).
Definition: state.h:1276
static void stateSetNedToBodyQuat_f(uint16_t id, struct FloatQuat *ned_to_body_quat)
Set vehicle body attitude from quaternion (float).
Definition: state.h:1253
static void stateSetPositionNed_f(uint16_t id, struct NedCoor_f *ned_pos)
Set position from local NED coordinates (float).
Definition: state.h:718
static void stateSetLocalOrigin_i(uint16_t id, struct LtpDef_i *ltp_def)
Set the local (flat earth) coordinate frame origin (int).
Definition: state.h:519
struct LlaCoor_i stateGetLlaOrigin_i(void)
Get the LLA position of the frame origin (int)
Definition: state.c:124
static void stateSetBodyRates_f(uint16_t id, struct FloatRates *body_rate)
Set vehicle body angular rate (float).
Definition: state.h:1346
static void stateSetSpeedNed_f(uint16_t id, struct NedCoor_f *ned_speed)
Set ground speed in local NED coordinates (float).
Definition: state.h:947
#define INS_RESET_VERTICAL_REF
Definition: ins.h:37
#define INS_RESET_REF
flags for INS reset
Definition: ins.h:36
static void reset_vertical_ref(void)
Definition: ins_ekf2.cpp:668
static void relpos_cb(uint8_t sender_id, uint32_t stamp, struct RelPosNED *relpos)
Definition: ins_ekf2.cpp:1031
static abi_event optical_flow_ev
Definition: ins_ekf2.cpp:305
static void gps_cb(uint8_t sender_id, uint32_t stamp, struct GpsState *gps_s)
Definition: ins_ekf2.cpp:987
#define INS_EKF2_EVV_NOISE
Definition: ins_ekf2.cpp:259
void ins_ekf2_update(void)
Definition: ins_ekf2.cpp:702
#define INS_EKF2_IMU_POS_Z
Definition: ins_ekf2.cpp:175
#define INS_EKF2_GPS_ID
Definition: ins_ekf2.cpp:145
static void reset_cb(uint8_t sender_id, uint8_t flag)
Definition: ins_ekf2.cpp:687
static void send_ins(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:331
#define INS_EKF2_GPS_POS_Y
Definition: ins_ekf2.cpp:187
static void send_ins_ekf2(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:388
void ins_ekf2_remove_gps(int32_t mode)
Definition: ins_ekf2.cpp:784
static void send_ins_ekf2_ext(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:421
static abi_event temperature_ev
Definition: ins_ekf2.cpp:298
static void optical_flow_cb(uint8_t sender_id, uint32_t stamp, int32_t flow_x, int32_t flow_y, int32_t flow_der_x, int32_t flow_der_y, float quality, float size_divergence)
Definition: ins_ekf2.cpp:1051
#define INS_EKF2_TEMPERATURE_ID
default temperature sensor to use in INS
Definition: ins_ekf2.cpp:115
#define INS_EKF2_RELHEADING_ERR
Definition: ins_ekf2.cpp:289
#define INS_EKF2_VDIST_SENSOR_TYPE
The EKF2 primary vertical distance sensor type.
Definition: ins_ekf2.cpp:75
static abi_event mag_ev
Definition: ins_ekf2.cpp:302
static void reset_ref(void)
Definition: ins_ekf2.cpp:654
#define INS_EKF2_RELPOS_ID
Definition: ins_ekf2.cpp:151
static void mag_cb(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *mag)
Definition: ins_ekf2.cpp:963
static void accel_int_cb(uint8_t sender_id, uint32_t stamp, struct FloatVect3 *delta_accel, uint16_t dt)
Definition: ins_ekf2.cpp:948
#define INS_EKF2_FUSION_MODE
Special configuration for Optitrack.
Definition: ins_ekf2.cpp:69
static abi_event reset_ev
Definition: ins_ekf2.cpp:306
#define INS_EKF2_GPS_CHECK_MASK
The EKF2 GPS checks before initialization.
Definition: ins_ekf2.cpp:81
#define INS_EKF2_RANGE_MAIN_AGL
If enabled uses radar sensor as primary AGL source, if possible.
Definition: ins_ekf2.cpp:99
#define INS_EKF2_MAX_FLOW_RATE
Definition: ins_ekf2.cpp:211
#define INS_EKF2_GPS_POS_Z
Definition: ins_ekf2.cpp:193
static abi_event gyro_int_ev
Definition: ins_ekf2.cpp:300
static abi_event relpos_ev
Definition: ins_ekf2.cpp:304
#define INS_EKF2_EVA_NOISE
Definition: ins_ekf2.cpp:265
#define INS_EKF2_BARO_NOISE
Definition: ins_ekf2.cpp:283
#define INS_EKF2_ACCEL_ID
Definition: ins_ekf2.cpp:133
#define INS_EKF2_GYRO_ID
Definition: ins_ekf2.cpp:127
static void send_ins_ref(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:378
static void temperature_cb(uint8_t sender_id, float temp)
Definition: ins_ekf2.cpp:916
#define INS_EKF2_FLOW_POS_Y
Definition: ins_ekf2.cpp:223
static void agl_cb(uint8_t sender_id, uint32_t stamp, float distance)
Definition: ins_ekf2.cpp:922
static void send_ins_z(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:358
static abi_event baro_ev
Definition: ins_ekf2.cpp:297
static parameters * ekf_params
The EKF parameters.
Definition: ins_ekf2.cpp:325
void ins_ekf2_init(void)
Definition: ins_ekf2.cpp:540
static void send_filter_status(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:435
#define INS_EKF2_FLOW_INNOV_GATE
Definition: ins_ekf2.cpp:247
#define INS_EKF2_FLOW_NOISE
Definition: ins_ekf2.cpp:235
#define INS_EKF2_EVP_NOISE
Definition: ins_ekf2.cpp:253
static void baro_cb(uint8_t sender_id, uint32_t stamp, float pressure)
Definition: ins_ekf2.cpp:901
void ins_ekf2_change_param(int32_t unk)
Definition: ins_ekf2.cpp:779
static void send_wind_info_ret(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:460
#define INS_EKF2_MIN_FLOW_QUALITY
Definition: ins_ekf2.cpp:205
#define INS_EKF2_GPS_V_NOISE
Definition: ins_ekf2.cpp:271
static Ekf ekf
EKF class itself.
Definition: ins_ekf2.cpp:324
struct ekf2_t ekf2
Local EKF2 status structure.
Definition: ins_ekf2.cpp:326
#define INS_EKF2_FLOW_SENSOR_DELAY
Definition: ins_ekf2.cpp:199
void ins_ekf2_parse_EXTERNAL_POSE(uint8_t *buf)
Definition: ins_ekf2.cpp:793
void ins_ekf2_parse_EXTERNAL_POSE_SMALL(uint8_t *buf)
Definition: ins_ekf2.cpp:827
#define INS_EKF2_MAG_ID
Definition: ins_ekf2.cpp:139
#define INS_EKF2_IMU_POS_X
Definition: ins_ekf2.cpp:163
#define INS_EKF2_GPS_P_NOISE
Definition: ins_ekf2.cpp:277
static void send_ahrs_quat(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:482
#define INS_EKF2_AGL_ID
default AGL sensor to use in INS
Definition: ins_ekf2.cpp:121
#define INS_EKF2_OF_ID
Definition: ins_ekf2.cpp:157
static void ins_ekf2_publish_attitude(uint32_t stamp)
Publish the attitude and get the new state Directly called after a succeslfull gyro+accel reading.
Definition: ins_ekf2.cpp:834
static void gyro_int_cb(uint8_t sender_id, uint32_t stamp, struct FloatRates *delta_gyro, uint16_t dt)
Definition: ins_ekf2.cpp:933
#define INS_EKF2_SONAR_MIN_RANGE
Default AGL sensor minimum range.
Definition: ins_ekf2.cpp:87
#define INS_EKF2_FLOW_NOISE_QMIN
Definition: ins_ekf2.cpp:241
#define INS_EKF2_IMU_POS_Y
Definition: ins_ekf2.cpp:169
static abi_event accel_int_ev
Definition: ins_ekf2.cpp:301
#define INS_EKF2_FLOW_POS_Z
Definition: ins_ekf2.cpp:229
static struct extVisionSample sample_ev
External vision sample.
Definition: ins_ekf2.cpp:327
#define INS_EKF2_BARO_ID
default barometer to use in INS
Definition: ins_ekf2.cpp:108
static void send_external_pose_down(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:507
#define INS_EKF2_SONAR_MAX_RANGE
Default AGL sensor maximum range.
Definition: ins_ekf2.cpp:93
#define INS_EKF2_GPS_POS_X
Definition: ins_ekf2.cpp:181
#define INS_EKF2_FLOW_POS_X
Definition: ins_ekf2.cpp:217
static abi_event gps_ev
Definition: ins_ekf2.cpp:303
static abi_event agl_ev
Definition: ins_ekf2.cpp:299
static void send_ahrs_bias(struct transport_tx *trans, struct link_device *dev)
Definition: ins_ekf2.cpp:472
INS based in the EKF2 of PX4.
int32_t mag_fusion_type
Definition: ins_ekf2.h:58
bool accel_valid
If we received a acceleration measurement.
Definition: ins_ekf2.h:46
bool rel_heading_valid
If we received a valid relative heading.
Definition: ins_ekf2.h:49
bool got_imu_data
If we received valid IMU data (any sensor)
Definition: ins_ekf2.h:56
int32_t fusion_mode
Definition: ins_ekf2.h:59
bool gyro_valid
If we received a gyroscope measurement.
Definition: ins_ekf2.h:45
uint32_t accel_dt
Accelerometer delta timestamp between abi messages (us)
Definition: ins_ekf2.h:44
uint32_t gyro_dt
Gyroscope delta timestamp between abi messages (us)
Definition: ins_ekf2.h:43
struct LtpDef_i ltp_def
Latest LTP definition from the quat_reset_counter EKF2.
Definition: ins_ekf2.h:55
uint32_t flow_stamp
Optic flow last abi message timestamp.
Definition: ins_ekf2.h:47
float rel_heading
Relative heading from RTK gps (rad)
Definition: ins_ekf2.h:48
float temp
Latest temperature measurement in degrees celcius.
Definition: ins_ekf2.h:51
struct FloatVect3 delta_accel
Last accelerometer measurements.
Definition: ins_ekf2.h:42
uint64_t ltp_stamp
Last LTP change timestamp from the EKF2.
Definition: ins_ekf2.h:54
float qnh
QNH value in hPa.
Definition: ins_ekf2.h:52
uint8_t quat_reset_counter
Amount of quaternion resets from the EKF2.
Definition: ins_ekf2.h:53
struct FloatRates delta_gyro
Last gyroscope measurements.
Definition: ins_ekf2.h:41
float parameters[20]
Definition: ins_flow.c:235
uint16_t foo
Definition: main_demo5.c:58
void waypoints_localize_all(void)
update local ENU coordinates of global waypoints
Definition: waypoints.c:357
bool nps_bypass_ins
void sim_overwrite_ins(void)
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
float z
in meters
float x
in meters
float y
in meters
vector in North East Down coordinates Units: meters
WGS-84 Geoid Heights.
Paparazzi atmospheric pressure conversion utilities.
struct HorizontalGuidance guidance_h
Definition: guidance_h.c:45
struct HorizontalGuidanceRCInput rc_sp
remote control setpoint
Definition: guidance_h.h:110
struct HorizontalGuidanceSetpoint sp
setpoints
Definition: guidance_h.h:108
struct RotorcraftNavigation nav
Definition: navigation.c:51
float heading
heading setpoint (in radians)
Definition: navigation.h:133
void stabilization_attitude_enter(void)
Attitude control enter function.
static uint8_t mode
mode holds the current sonar mode mode = 0 used at high altitude, uses 16 wave patterns mode = 1 used...
Definition: sonar_bebop.c:65
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
Architecture independent timing functions.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
int int32_t
Typedef defining 32 bit int type.
Definition: vl53l1_types.h:83
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned long long uint64_t
Definition: vl53l1_types.h:72
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98