/sw/in_progress/inertial/C/ahrs_quat_ukf.c

https://bitbucket.org/tamasszabo/paparazzi_mavlink · C · 123 lines · 90 code · 14 blank · 19 comment · 2 complexity · d50a2e506bf6a209ddf61f609f8a3d03 MD5 · raw file

  1. #include "ahrs_data.h"
  2. #include "ahrs_display.h"
  3. #include "ahrs_utils.h"
  4. #include "ukf.h"
  5. #define UPDATE_PHI 0
  6. #define UPDATE_THETA 1
  7. #define UPDATE_PSI 2
  8. #define UPDATE_NB 3
  9. static struct ahrs_data* ad;
  10. static int ahrs_state;
  11. void linear_filter(double *x1, double *x0, double *u) {
  12. /*
  13. * quat_dot = Wxq(pqr) * quat
  14. * bias_dot = 0
  15. *
  16. * Wxq is the quaternion omega matrix:
  17. *
  18. * [ 0, -p, -q, -r ]
  19. * 1/2 * [ p, 0, r, -q ]
  20. * [ q, -r, 0, p ]
  21. * [ r, q, -p, 0 ]
  22. */
  23. double p = u[0] - x0[4];
  24. double q = u[1] - x0[5];
  25. double r = u[2] - x0[6];
  26. double q0_dot = -p*x0[1] -q*x0[2] -r*x0[3];
  27. double q1_dot = p*x0[0] +r*x0[2] -q*x0[3];
  28. double q2_dot = q*x0[0] -r*x0[1] +p*x0[3];
  29. double q3_dot = r*x0[0] +q*x0[1] -p*x0[2];
  30. x1[0] = x0[0] + q0_dot * ad->dt;
  31. x1[1] = x0[1] + q1_dot * ad->dt;
  32. x1[2] = x0[2] + q2_dot * ad->dt;
  33. x1[3] = x0[3] + q3_dot * ad->dt;
  34. x1[4] = x0[4];
  35. x1[5] = x0[5];
  36. x1[6] = x0[6];
  37. norm_quat(x1);
  38. }
  39. void linear_measure(double *y, double *x) {
  40. double eulers[3];
  41. eulers_of_quat(eulers, x);
  42. y[0] = eulers[ahrs_state];
  43. }
  44. void run_ukf(void) {
  45. /* initial state covariance matrix */
  46. double P[7*7] = {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  47. 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  48. 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
  49. 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
  50. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  51. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  52. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
  53. /* model noise covariance matrix */
  54. double Q[7*7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  55. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  56. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  57. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  58. 0.0, 0.0, 0.0, 0.0, 0.008, 0.0, 0.0,
  59. 0.0, 0.0, 0.0, 0.0, 0.0, 0.008, 0.0,
  60. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.008 };
  61. /* measurement noise covariance matrix */
  62. double R[1]={0.3};
  63. /* state [q0, q1, q2, q3, bp, bq, br] */
  64. double X[7];
  65. /* measure */
  66. double Y[1];
  67. /* command */
  68. double U[3] = {0.0, 0.0, 0.0};
  69. ukf_filter filter;
  70. filter = ukf_filter_new(7, 1, Q, R, linear_filter, linear_measure);
  71. ahrs_init(ad, 150, X);
  72. ukf_filter_reset(filter, X, P);
  73. ukf_filter_compute_weights(filter, 1.1, 0.0, 2.0);
  74. int iter;
  75. for (iter=0; iter < ad->nb_samples; iter++) {
  76. U[0] = ad->gyro_p[iter];// - X[4];
  77. U[1] = ad->gyro_q[iter];// - X[5];
  78. U[2] = ad->gyro_r[iter];// - X[6];
  79. ahrs_state = iter%3;
  80. switch (ahrs_state) {
  81. case UPDATE_PHI:
  82. Y[0] = phi_of_accel(ad->accel_x[iter], ad->accel_y[iter], ad->accel_z[iter]);
  83. break;
  84. case UPDATE_THETA:
  85. Y[0] = theta_of_accel(ad->accel_x[iter], ad->accel_y[iter], ad->accel_z[iter]);
  86. break;
  87. case UPDATE_PSI: {
  88. double eulers[3];
  89. eulers_of_quat(eulers, X);
  90. Y[0] = psi_of_mag(eulers[0], eulers[1], ad->mag_x[iter], ad->mag_y[iter], ad->mag_z[iter]);
  91. break;
  92. }
  93. }
  94. ukf_filter_update(filter, Y, U);
  95. ukf_filter_get_state(filter, X, P);
  96. ahrs_data_save_state(ad, iter, X, P);
  97. }
  98. ukf_filter_delete(filter);
  99. }
  100. int main(int argc, char** argv) {
  101. gtk_init(&argc, &argv);
  102. //ad = ahrs_data_read_log("../data/log_ahrs_bug");
  103. ad = ahrs_data_read_log("../data/log_ahrs_roll");
  104. // ad = ahrs_data_read_log("../data/log_ahrs_yaw_pitched");
  105. run_ukf();
  106. ahrs_display(ad);
  107. gtk_main();
  108. return 0;
  109. }