Paparazzi UAS  v5.17_devel-15-geeac31e
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ahrs_madgwick_wrapper.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Gautier Hattenberger <gautier.hattenberger@enac.fr>
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 "subsystems/ahrs.h"
29 #include "subsystems/abi.h"
30 #include "mcu_periph/sys_time.h"
31 #include "message_pragmas.h"
32 #include "state.h"
33 
34 #ifndef AHRS_MADGWICK_OUTPUT_ENABLED
35 #define AHRS_MADGWICK_OUTPUT_ENABLED TRUE
36 #endif
37 PRINT_CONFIG_VAR(AHRS_MADGWICK_OUTPUT_ENABLED)
38 
39 
44 
45 static void compute_body_orientation_and_rates(void);
46 
47 #if PERIODIC_TELEMETRY
49 
50 static void send_att(struct transport_tx *trans, struct link_device *dev)
51 {
52  /* compute eulers in int (IMU frame) */
53  struct FloatEulers ltp_to_imu_euler;
54  float_eulers_of_quat(&ltp_to_imu_euler, &ahrs_madgwick.quat);
55  struct Int32Eulers eulers_imu;
56  EULERS_BFP_OF_REAL(eulers_imu, ltp_to_imu_euler);
57 
58  /* compute Eulers in int (body frame) */
59  struct FloatQuat ltp_to_body_quat;
60  struct FloatQuat *body_to_imu_quat = orientationGetQuat_f(&ahrs_madgwick.body_to_imu);
61  float_quat_comp_inv(&ltp_to_body_quat, &ahrs_madgwick.quat, body_to_imu_quat);
62  struct FloatEulers ltp_to_body_euler;
63  float_eulers_of_quat(&ltp_to_body_euler, &ltp_to_body_quat);
64  struct Int32Eulers eulers_body;
65  EULERS_BFP_OF_REAL(eulers_body, ltp_to_body_euler);
66 
67  pprz_msg_send_AHRS_EULER_INT(trans, dev, AC_ID,
68  &eulers_imu.phi,
69  &eulers_imu.theta,
70  &eulers_imu.psi,
71  &eulers_body.phi,
72  &eulers_body.theta,
73  &eulers_body.psi,
75 }
76 
77 static void send_filter_status(struct transport_tx *trans, struct link_device *dev)
78 {
79  uint8_t mde = 3;
80  uint16_t val = 0;
81  if (!ahrs_madgwick.is_aligned) { mde = 2; }
83  /* set lost if no new gyro measurements for 50ms */
84  if (t_diff > 50000) { mde = 5; }
85  pprz_msg_send_STATE_FILTER_STATUS(trans, dev, AC_ID, &ahrs_madgwick_id, &mde, &val);
86 }
87 #endif
88 
89 
90 /*
91  * ABI bindings
92  */
94 #ifndef AHRS_MADGWICK_IMU_ID
95 #define AHRS_MADGWICK_IMU_ID ABI_BROADCAST
96 #endif
97 PRINT_CONFIG_VAR(AHRS_MADGWICK_IMU_ID)
98 
99 
100 #ifndef AHRS_MADGWICK_MAG_ID
101 #define AHRS_MADGWICK_MAG_ID AHRS_MADGWICK_IMU_ID
102 #endif
103 PRINT_CONFIG_VAR(AHRS_MADGWICK_MAG_ID)
104 
109 
115 static void gyro_cb(uint8_t sender_id __attribute__((unused)),
116  uint32_t stamp, struct Int32Rates *gyro)
117 {
118  struct FloatRates gyro_f;
119  RATES_FLOAT_OF_BFP(gyro_f, *gyro);
120 
121 #if USE_AUTO_AHRS_FREQ || !defined(AHRS_PROPAGATE_FREQUENCY)
122  PRINT_CONFIG_MSG("Calculating dt for AHRS Madgwick propagation.")
123  /* timestamp in usec when last callback was received */
124  static uint32_t last_stamp = 0;
125 
126  if (last_stamp > 0 && ahrs_madgwick.is_aligned) {
127  float dt = (float)(stamp - last_stamp) * 1e-6;
128  ahrs_madgwick_propagate(&gyro_f, dt);
130  }
131  last_stamp = stamp;
132 #else
133  PRINT_CONFIG_MSG("Using fixed AHRS_PROPAGATE_FREQUENCY for AHRS Madgwick propagation.")
134  PRINT_CONFIG_VAR(AHRS_PROPAGATE_FREQUENCY)
135  const float dt = 1. / (AHRS_PROPAGATE_FREQUENCY);
137  ahrs_madgwick_propagate(&gyro_f, dt);
139  }
140 #endif
141 
142  ahrs_madgwick_last_stamp = stamp;
143 }
144 
145 static void accel_cb(uint8_t sender_id __attribute__((unused)),
146  uint32_t stamp __attribute__((unused)),
147  struct Int32Vect3 *accel)
148 {
150  struct FloatVect3 accel_f;
151  ACCELS_FLOAT_OF_BFP(accel_f, *accel);
152  ahrs_madgwick_update_accel(&accel_f);
153  }
154 }
155 
156 static void aligner_cb(uint8_t __attribute__((unused)) sender_id,
157  uint32_t stamp __attribute__((unused)),
158  struct Int32Rates *lp_gyro, struct Int32Vect3 *lp_accel,
159  struct Int32Vect3 *lp_mag __attribute__((unused)))
160 {
161  if (!ahrs_madgwick.is_aligned) {
162  /* convert to float */
163  struct FloatRates gyro_f;
164  RATES_FLOAT_OF_BFP(gyro_f, *lp_gyro);
165  struct FloatVect3 accel_f;
166  ACCELS_FLOAT_OF_BFP(accel_f, *lp_accel);
167  ahrs_madgwick_align(&gyro_f, &accel_f);
169  }
170 }
171 
172 static void body_to_imu_cb(uint8_t sender_id __attribute__((unused)),
173  struct FloatQuat *q_b2i_f)
174 {
176 }
177 
178 static bool ahrs_madgwick_enable_output(bool enable)
179 {
180  ahrs_madgwick_output_enabled = enable;
182 }
183 
188 {
189  if (ahrs_madgwick_output_enabled) {
190  /* Compute LTP to BODY quaternion */
191  struct FloatQuat ltp_to_body_quat;
192  struct FloatQuat *body_to_imu_quat = orientationGetQuat_f(&ahrs_madgwick.body_to_imu);
193  float_quat_comp_inv(&ltp_to_body_quat, &ahrs_madgwick.quat, body_to_imu_quat);
194  /* Set state */
195  stateSetNedToBodyQuat_f(&ltp_to_body_quat);
196 
197  /* compute body rates */
199  }
200 }
201 
202 
204 {
205  ahrs_madgwick_output_enabled = AHRS_MADGWICK_OUTPUT_ENABLED;
208 
209  /*
210  * Subscribe to scaled IMU measurements and attach callbacks
211  */
212  AbiBindMsgIMU_GYRO_INT32(AHRS_MADGWICK_IMU_ID, &gyro_ev, gyro_cb);
213  AbiBindMsgIMU_ACCEL_INT32(AHRS_MADGWICK_IMU_ID, &accel_ev, accel_cb);
214  AbiBindMsgIMU_LOWPASSED(AHRS_MADGWICK_IMU_ID, &aligner_ev, aligner_cb);
215  AbiBindMsgBODY_TO_IMU_QUAT(AHRS_MADGWICK_IMU_ID, &body_to_imu_ev, body_to_imu_cb);
216 
217 #if PERIODIC_TELEMETRY
218  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_AHRS_EULER_INT, send_att);
219  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_STATE_FILTER_STATUS, send_filter_status);
220 #endif
221 }
222 
static bool ahrs_madgwick_output_enabled
if TRUE with push the estimation results to the state interface
#define AHRS_MADGWICK_IMU_ID
IMU (gyro, accel)
int32_t psi
in rad with INT32_ANGLE_FRAC
Event structure to store callbacks in a linked list.
Definition: abi_common.h:65
static abi_event gyro_ev
unsigned short uint16_t
Definition: types.h:16
void float_quat_comp_inv(struct FloatQuat *a2b, struct FloatQuat *a2c, struct FloatQuat *b2c)
Composition (multiplication) of two quaternions.
void ahrs_madgwick_align(struct FloatRates *lp_gyro, struct FloatVect3 *lp_accel)
Definition: ahrs_madgwick.c:59
angular rates
void ahrs_madgwick_propagate(struct FloatRates *gyro, float dt)
Definition: ahrs_madgwick.c:69
Dispatcher to register actual AHRS implementations.
void ahrs_madgwick_update_accel(struct FloatVect3 *accel)
#define AHRS_PROPAGATE_FREQUENCY
Definition: hf_float.c:55
#define EULERS_BFP_OF_REAL(_ei, _ef)
Definition: pprz_algebra.h:715
Periodic telemetry system header (includes downlink utility and generated code).
static abi_event accel_ev
int32_t theta
in rad with INT32_ANGLE_FRAC
#define AHRS_MADGWICK_MAG_ID
magnetometer
static void gyro_cb(uint8_t sender_id, uint32_t stamp, struct Int32Rates *gyro)
Call ahrs_madgwick_propagate on new gyro measurements.
Main include for ABI (AirBorneInterface).
static abi_event aligner_ev
static void stateSetNedToBodyQuat_f(struct FloatQuat *ned_to_body_quat)
Set vehicle body attitude from quaternion (float).
Definition: state.h:1093
struct AhrsMadgwick ahrs_madgwick
Definition: ahrs_madgwick.c:39
#define AHRS_MADGWICK_OUTPUT_ENABLED
bool is_aligned
aligned flag
Definition: ahrs_madgwick.h:45
static void send_filter_status(struct transport_tx *trans, struct link_device *dev)
struct FloatQuat quat
Estimated attitude (quaternion)
Definition: ahrs_madgwick.h:39
euler angles
Roation quaternion.
#define RATES_FLOAT_OF_BFP(_rf, _ri)
Definition: pprz_algebra.h:759
void ahrs_register_impl(AhrsEnableOutput enable)
Register an AHRS implementation.
Definition: ahrs.c:62
static void body_to_imu_cb(uint8_t sender_id, struct FloatQuat *q_b2i_f)
Architecture independent timing functions.
struct FloatRates rates
Measured gyro rates.
Definition: ahrs_madgwick.h:40
static void send_att(struct transport_tx *trans, struct link_device *dev)
static uint8_t ahrs_madgwick_id
static void compute_body_orientation_and_rates(void)
Compute body orientation and rates from imu orientation and rates.
euler angles
uint16_t val[TCOUPLE_NB]
unsigned long uint32_t
Definition: types.h:18
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
void ahrs_madgwick_register(void)
void ahrs_madgwick_set_body_to_imu_quat(struct FloatQuat *q_b2i)
Paparazzi specific wrapper to run Madgwick ahrs filter.
#define ACCELS_FLOAT_OF_BFP(_ef, _ei)
Definition: pprz_algebra.h:795
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
#define AHRS_COMP_ID_MADGWICK
Definition: ahrs.h:45
int32_t phi
in rad with INT32_ANGLE_FRAC
unsigned char uint8_t
Definition: types.h:14
API to get/set the generic vehicle states.
static void accel_cb(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *accel)
static uint32_t ahrs_madgwick_last_stamp
last gyro msg timestamp
static abi_event body_to_imu_ev
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:68
static void stateSetBodyRates_f(struct FloatRates *body_rate)
Set vehicle body angular rate (float).
Definition: state.h:1181
void float_eulers_of_quat(struct FloatEulers *e, struct FloatQuat *q)
euler rotation 'ZYX'
void ahrs_madgwick_init(void)
Definition: ahrs_madgwick.c:50
static void aligner_cb(uint8_t sender_id, uint32_t stamp, struct Int32Rates *lp_gyro, struct Int32Vect3 *lp_accel, struct Int32Vect3 *lp_mag)
static bool ahrs_madgwick_enable_output(bool enable)
angular rates
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:46
static struct FloatQuat * orientationGetQuat_f(struct OrientationReps *orientation)
Get vehicle body attitude quaternion (float).
struct OrientationReps body_to_imu
body_to_imu rotation
Definition: ahrs_madgwick.h:43