PageRenderTime 74ms CodeModel.GetById 45ms RepoModel.GetById 0ms app.codeStats 0ms

/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.c

https://github.com/AshuLara/lisa
C | 282 lines | 167 code | 68 blank | 47 comment | 0 complexity | 2778e0cefa8cf2261604797b94d85bd6 MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 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. #include "subsystems/ahrs.h"
  22. #include "subsystems/ahrs/ahrs_float_cmpl_rmat.h"
  23. #include "subsystems/ahrs/ahrs_float_utils.h"
  24. #include "subsystems/ahrs/ahrs_aligner.h"
  25. #include "subsystems/imu.h"
  26. #include "math/pprz_algebra_float.h"
  27. #include "math/pprz_algebra_int.h"
  28. #include "math/pprz_simple_matrix.h"
  29. #include "generated/airframe.h"
  30. #include "../../test/pprz_algebra_print.h"
  31. void ahrs_update_mag_full(void);
  32. void ahrs_update_mag_2d(void);
  33. void ahrs_update_mag_2d_dumb(void);
  34. static inline void compute_imu_quat_and_euler_from_rmat(void);
  35. static inline void compute_imu_rmat_and_euler_from_quat(void);
  36. static inline void compute_body_orientation_and_rates(void);
  37. struct AhrsFloatCmplRmat ahrs_impl;
  38. void ahrs_init(void) {
  39. ahrs_float.status = AHRS_UNINIT;
  40. /* Initialises IMU alignement */
  41. struct FloatEulers body_to_imu_euler =
  42. {IMU_BODY_TO_IMU_PHI, IMU_BODY_TO_IMU_THETA, IMU_BODY_TO_IMU_PSI};
  43. FLOAT_QUAT_OF_EULERS(ahrs_impl.body_to_imu_quat, body_to_imu_euler);
  44. FLOAT_RMAT_OF_EULERS(ahrs_impl.body_to_imu_rmat, body_to_imu_euler);
  45. /* Set ltp_to_body to zero */
  46. FLOAT_QUAT_ZERO(ahrs_float.ltp_to_body_quat);
  47. FLOAT_EULERS_ZERO(ahrs_float.ltp_to_body_euler);
  48. FLOAT_RMAT_ZERO(ahrs_float.ltp_to_body_rmat);
  49. FLOAT_RATES_ZERO(ahrs_float.body_rate);
  50. /* Set ltp_to_imu so that body is zero */
  51. QUAT_COPY(ahrs_float.ltp_to_imu_quat, ahrs_impl.body_to_imu_quat);
  52. RMAT_COPY(ahrs_float.ltp_to_imu_rmat, ahrs_impl.body_to_imu_rmat);
  53. EULERS_COPY(ahrs_float.ltp_to_imu_euler, body_to_imu_euler);
  54. FLOAT_RATES_ZERO(ahrs_float.imu_rate);
  55. }
  56. void ahrs_align(void) {
  57. /* Compute an initial orientation using euler angles */
  58. ahrs_float_get_euler_from_accel_mag(&ahrs_float.ltp_to_imu_euler, &ahrs_aligner.lp_accel, &ahrs_aligner.lp_mag);
  59. /* Convert initial orientation in quaternion and rotation matrice representations. */
  60. FLOAT_QUAT_OF_EULERS(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_euler);
  61. FLOAT_RMAT_OF_QUAT(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_quat);
  62. /* Compute initial body orientation */
  63. compute_body_orientation_and_rates();
  64. /* used averaged gyro as initial value for bias */
  65. struct Int32Rates bias0;
  66. RATES_COPY(bias0, ahrs_aligner.lp_gyro);
  67. RATES_FLOAT_OF_BFP(ahrs_impl.gyro_bias, bias0);
  68. ahrs.status = AHRS_RUNNING;
  69. }
  70. void ahrs_propagate(void) {
  71. /* converts gyro to floating point */
  72. struct FloatRates gyro_float;
  73. RATES_FLOAT_OF_BFP(gyro_float, imu.gyro_prev);
  74. /* unbias measurement */
  75. RATES_SUB(gyro_float, ahrs_impl.gyro_bias);
  76. #ifdef AHRS_PROPAGATE_LOW_PASS_RATES
  77. const float alpha = 0.1;
  78. FLOAT_RATES_LIN_CMB(ahrs_float.imu_rate, ahrs_float.imu_rate, (1.-alpha), gyro_float, alpha);
  79. #else
  80. RATES_COPY(ahrs_float.imu_rate,gyro_float);
  81. #endif
  82. /* add correction */
  83. struct FloatRates omega;
  84. RATES_SUM(omega, gyro_float, ahrs_impl.rate_correction);
  85. /* and zeros it */
  86. FLOAT_RATES_ZERO(ahrs_impl.rate_correction);
  87. const float dt = 1./AHRS_PROPAGATE_FREQUENCY;
  88. #ifdef AHRS_PROPAGATE_RMAT
  89. FLOAT_RMAT_INTEGRATE_FI(ahrs_float.ltp_to_imu_rmat, omega, dt );
  90. float_rmat_reorthogonalize(&ahrs_float.ltp_to_imu_rmat);
  91. compute_imu_quat_and_euler_from_rmat();
  92. #endif
  93. #ifdef AHRS_PROPAGATE_QUAT
  94. FLOAT_QUAT_INTEGRATE(ahrs_float.ltp_to_imu_quat, omega, dt);
  95. FLOAT_QUAT_NORMALIZE(ahrs_float.ltp_to_imu_quat);
  96. compute_imu_rmat_and_euler_from_quat();
  97. #endif
  98. compute_body_orientation_and_rates();
  99. }
  100. void ahrs_update_accel(void) {
  101. struct FloatVect3 accel_float;
  102. ACCELS_FLOAT_OF_BFP(accel_float, imu.accel);
  103. #ifdef AHRS_GRAVITY_UPDATE_COORDINATED_TURN
  104. float v = FLOAT_VECT3_NORM(ahrs_impl.est_ltp_speed);
  105. accel_float.y -= v * ahrs_float.imu_rate.r;
  106. accel_float.z -= -v * ahrs_float.imu_rate.q;
  107. #endif
  108. struct FloatVect3 c2 = { RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 0,2),
  109. RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 1,2),
  110. RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 2,2)};
  111. struct FloatVect3 residual;
  112. FLOAT_VECT3_CROSS_PRODUCT(residual, accel_float, c2);
  113. #ifdef AHRS_GRAVITY_UPDATE_NORM_HEURISTIC
  114. /* heuristic on acceleration norm */
  115. const float acc_norm = FLOAT_VECT3_NORM(accel_float);
  116. const float weight = Chop(1.-6*fabs((9.81-acc_norm)/9.81), 0., 1.);
  117. #else
  118. const float weight = 1.;
  119. #endif
  120. /* compute correction */
  121. const float gravity_rate_update_gain = -5e-2; // -5e-2
  122. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual, weight*gravity_rate_update_gain);
  123. #if 1
  124. const float gravity_bias_update_gain = 1e-5; // -5e-6
  125. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual, weight*gravity_bias_update_gain);
  126. #else
  127. const float alpha = 5e-4;
  128. FLOAT_RATES_SCALE(ahrs_impl.gyro_bias, 1.-alpha);
  129. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual, alpha);
  130. #endif
  131. /* FIXME: saturate bias */
  132. }
  133. void ahrs_update_mag(void) {
  134. #ifdef AHRS_MAG_UPDATE_YAW_ONLY
  135. ahrs_update_mag_2d();
  136. // ahrs_update_mag_2d_dumb();
  137. #else
  138. ahrs_update_mag_full();
  139. #endif
  140. }
  141. void ahrs_update_mag_full(void) {
  142. const struct FloatVect3 expected_ltp = {AHRS_H_X, AHRS_H_Y, AHRS_H_Z};
  143. struct FloatVect3 expected_imu;
  144. FLOAT_RMAT_VECT3_MUL(expected_imu, ahrs_float.ltp_to_imu_rmat, expected_ltp);
  145. struct FloatVect3 measured_imu;
  146. MAGS_FLOAT_OF_BFP(measured_imu, imu.mag);
  147. struct FloatVect3 residual_imu;
  148. FLOAT_VECT3_CROSS_PRODUCT(residual_imu, measured_imu, expected_imu);
  149. // DISPLAY_FLOAT_VECT3("# expected", expected_imu);
  150. // DISPLAY_FLOAT_VECT3("# measured", measured_imu);
  151. // DISPLAY_FLOAT_VECT3("# residual", residual);
  152. const float mag_rate_update_gain = 2.5;
  153. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual_imu, mag_rate_update_gain);
  154. const float mag_bias_update_gain = -2.5e-3;
  155. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual_imu, mag_bias_update_gain);
  156. }
  157. void ahrs_update_mag_2d(void) {
  158. const struct FloatVect2 expected_ltp = {AHRS_H_X, AHRS_H_Y};
  159. struct FloatVect3 measured_imu;
  160. MAGS_FLOAT_OF_BFP(measured_imu, imu.mag);
  161. struct FloatVect3 measured_ltp;
  162. FLOAT_RMAT_VECT3_TRANSP_MUL(measured_ltp, ahrs_float.ltp_to_imu_rmat, measured_imu);
  163. const struct FloatVect3 residual_ltp =
  164. { 0,
  165. 0,
  166. measured_ltp.x * expected_ltp.y - measured_ltp.y * expected_ltp.x };
  167. // printf("res : %f\n", residual_ltp.z);
  168. struct FloatVect3 residual_imu;
  169. FLOAT_RMAT_VECT3_MUL(residual_imu, ahrs_float.ltp_to_imu_rmat, residual_ltp);
  170. const float mag_rate_update_gain = 2.5;
  171. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual_imu, mag_rate_update_gain);
  172. const float mag_bias_update_gain = -2.5e-3;
  173. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual_imu, mag_bias_update_gain);
  174. }
  175. void ahrs_update_mag_full_2d_dumb(void) {
  176. /* project mag on local tangeant plane */
  177. struct FloatVect3 magf;
  178. MAGS_FLOAT_OF_BFP(magf, imu.mag);
  179. const float cphi = cosf(ahrs_float.ltp_to_imu_euler.phi);
  180. const float sphi = sinf(ahrs_float.ltp_to_imu_euler.phi);
  181. const float ctheta = cosf(ahrs_float.ltp_to_imu_euler.theta);
  182. const float stheta = sinf(ahrs_float.ltp_to_imu_euler.theta);
  183. const float mn = ctheta * magf.x + sphi*stheta*magf.y + cphi*stheta*magf.z;
  184. const float me = 0. * magf.x + cphi *magf.y - sphi *magf.z;
  185. const float res_norm = -RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 0,0)*me + RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 1,0)*mn;
  186. struct FloatVect3* r2 = (struct FloatVect3*)(&RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 2,0));
  187. const float mag_rate_update_gain = 2.5;
  188. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, (*r2), (mag_rate_update_gain*res_norm));
  189. const float mag_bias_update_gain = -2.5e-4;
  190. FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, (*r2), (mag_bias_update_gain*res_norm));
  191. }
  192. /*
  193. * Compute ltp to imu rotation in euler angles and quaternion representations
  194. * from the rotation matrice representation
  195. */
  196. static inline void compute_imu_quat_and_euler_from_rmat(void) {
  197. FLOAT_QUAT_OF_RMAT(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_rmat);
  198. FLOAT_EULERS_OF_RMAT(ahrs_float.ltp_to_imu_euler, ahrs_float.ltp_to_imu_rmat);
  199. }
  200. static inline void compute_imu_rmat_and_euler_from_quat(void) {
  201. FLOAT_RMAT_OF_QUAT(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_quat);
  202. FLOAT_EULERS_OF_RMAT(ahrs_float.ltp_to_imu_euler, ahrs_float.ltp_to_imu_rmat);
  203. }
  204. /*
  205. * Compute body orientation and rates from imu orientation and rates
  206. */
  207. static inline void compute_body_orientation_and_rates(void) {
  208. FLOAT_QUAT_COMP_INV(ahrs_float.ltp_to_body_quat,
  209. ahrs_float.ltp_to_imu_quat, ahrs_impl.body_to_imu_quat);
  210. FLOAT_RMAT_COMP_INV(ahrs_float.ltp_to_body_rmat,
  211. ahrs_float.ltp_to_imu_rmat, ahrs_impl.body_to_imu_rmat);
  212. FLOAT_EULERS_OF_RMAT(ahrs_float.ltp_to_body_euler, ahrs_float.ltp_to_body_rmat);
  213. FLOAT_RMAT_TRANSP_RATEMULT(ahrs_float.body_rate, ahrs_impl.body_to_imu_rmat, ahrs_float.imu_rate);
  214. }