Advertisement
Guest User

Untitled

a guest
Oct 27th, 2013
1,818
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.57 KB | None | 0 0
  1. void MARGfilter::UpdateFilter(float w_x, float w_y, float w_z, float a_x, float a_y, float a_z, float m_x, float m_y, float m_z)
  2. {
  3. // local system variables
  4. float norm; // vector norm
  5. float SEqDot_omega_1, SEqDot_omega_2, SEqDot_omega_3, SEqDot_omega_4; // quaternion rate from gyroscopes elements
  6. float f_1, f_2, f_3, f_4, f_5, f_6; // objective function elements
  7. float J_11or24, J_12or23, J_13or22, J_14or21, J_32, J_33, // objective function Jacobian elements
  8. J_41, J_42, J_43, J_44, J_51, J_52, J_53, J_54, J_61, J_62, J_63, J_64; //
  9. float SEqHatDot_1, SEqHatDot_2, SEqHatDot_3, SEqHatDot_4; // estimated direction of the gyroscope error
  10. float w_err_x, w_err_y, w_err_z; // estimated direction of the gyroscope error (angular)
  11. float h_x, h_y, h_z; // computed flux in the earth frame
  12. // axulirary variables to avoid reapeated calcualtions
  13. float halfSEq_1 = 0.5 * SEq_1;
  14. float halfSEq_2 = 0.5 * SEq_2;
  15. float halfSEq_3 = 0.5 * SEq_3;
  16. float halfSEq_4 = 0.5 * SEq_4;
  17. float twoSEq_1 = 2.0 * SEq_1;
  18. float twoSEq_2 = 2.0 * SEq_2;
  19. float twoSEq_3 = 2.0 * SEq_3;
  20. float twoSEq_4 = 2.0 * SEq_4;
  21. float twob_x = 2.0 * b_x;
  22. float twob_z = 2.0 * b_z;
  23. float twob_xSEq_1 = 2.0 * b_x * SEq_1;
  24. float twob_xSEq_2 = 2.0 * b_x * SEq_2;
  25. float twob_xSEq_3 = 2.0 * b_x * SEq_3;
  26. float twob_xSEq_4 = 2.0 * b_x * SEq_4;
  27. float twob_zSEq_1 = 2.0 * b_z * SEq_1;
  28. float twob_zSEq_2 = 2.0* b_z * SEq_2;
  29. float twob_zSEq_3 = 2.0 * b_z * SEq_3;
  30. float twob_zSEq_4 = 2.0 * b_z * SEq_4;
  31. float SEq_1SEq_2;
  32. float SEq_1SEq_3 = SEq_1 * SEq_3;
  33. float SEq_1SEq_4;
  34. float SEq_2SEq_3;
  35. float SEq_2SEq_4 = SEq_2 * SEq_4;
  36. float SEq_3SEq_4;
  37. // normalise the accelerometer measurement
  38. norm = sqrt(a_x * a_x + a_y * a_y + a_z * a_z);
  39. a_x /= norm;
  40. a_y /= norm;
  41. a_z /= norm;
  42. // normalise the magnetometer measurement
  43. norm = sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
  44. m_x /= norm;
  45. m_y /= norm;
  46. m_z /= norm;
  47. float twom_x = 2.0 * m_x;
  48. float twom_y = 2.0 * m_y;
  49. float twom_z = 2.0 * m_z;
  50. // compute the objective function and Jacobian
  51. f_1 = twoSEq_2 * SEq_4 - twoSEq_1 * SEq_3 - a_x;
  52. f_2 = twoSEq_1 * SEq_2 + twoSEq_3 * SEq_4 - a_y;
  53. f_3 = 1.0 - twoSEq_2 * SEq_2 - twoSEq_3 * SEq_3 - a_z;
  54. f_4 = twob_x * (0.5 - SEq_3 * SEq_3 - SEq_4 * SEq_4) + twob_z * (SEq_2SEq_4 - SEq_1SEq_3) - m_x;
  55. f_5 = twob_x * (SEq_2 * SEq_3 - SEq_1 * SEq_4) + twob_z * (SEq_1 * SEq_2 + SEq_3 * SEq_4) - m_y;
  56. f_6 = twob_x * (SEq_1SEq_3 + SEq_2SEq_4) + twob_z * (0.5 - SEq_2 * SEq_2 - SEq_3 * SEq_3) - m_z;
  57. J_11or24 = twoSEq_3; // J_11 negated in matrix multiplication
  58. J_12or23 = 2.0 * SEq_4;
  59. J_13or22 = twoSEq_1; // J_12 negated in matrix multiplication
  60. J_14or21 = twoSEq_2;
  61. J_32 = 2.0 * J_14or21; // negated in matrix multiplication
  62. J_33 = 2.0 * J_11or24; // negated in matrix multiplication
  63. J_41 = twob_zSEq_3; // negated in matrix multiplication
  64. J_42 = twob_zSEq_4;
  65. J_43 = 2.0 * twob_xSEq_3 + twob_zSEq_1; // negated in matrix multiplication
  66. J_44 = 2.0 * twob_xSEq_4 - twob_zSEq_2; // negated in matrix multiplication
  67. J_51 = twob_xSEq_4 - twob_zSEq_2; // negated in matrix multiplication
  68. J_52 = twob_xSEq_3 + twob_zSEq_1;
  69. J_53 = twob_xSEq_2 + twob_zSEq_4;
  70. J_54 = twob_xSEq_1 - twob_zSEq_3; // negated in matrix multiplication
  71. J_61 = twob_xSEq_3;
  72. J_62 = twob_xSEq_4 - 2.0 * twob_zSEq_2;
  73. J_63 = twob_xSEq_1 - 2.0 * twob_zSEq_3;
  74. J_64 = twob_xSEq_2;
  75. // compute the gradient (matrix multiplication)
  76. SEqHatDot_1 = J_14or21 * f_2 - J_11or24 * f_1 - J_41 * f_4 - J_51 * f_5 + J_61 * f_6;
  77. SEqHatDot_2 = J_12or23 * f_1 + J_13or22 * f_2 - J_32 * f_3 + J_42 * f_4 + J_52 * f_5 + J_62 * f_6;
  78. SEqHatDot_3 = J_12or23 * f_2 - J_33 * f_3 - J_13or22 * f_1 - J_43 * f_4 + J_53 * f_5 + J_63 * f_6;
  79. SEqHatDot_4 = J_14or21 * f_1 + J_11or24 * f_2 - J_44 * f_4 - J_54 * f_5 + J_64 * f_6;
  80. // normalise the gradient to estimate direction of the gyroscope error
  81. norm = sqrt(SEqHatDot_1 * SEqHatDot_1 + SEqHatDot_2 * SEqHatDot_2 + SEqHatDot_3 * SEqHatDot_3 + SEqHatDot_4 * SEqHatDot_4);
  82. SEqHatDot_1 = SEqHatDot_1 / norm;
  83. SEqHatDot_2 = SEqHatDot_2 / norm;
  84. SEqHatDot_3 = SEqHatDot_3 / norm;
  85. SEqHatDot_4 = SEqHatDot_4 / norm;
  86. // compute angular estimated direction of the gyroscope error
  87. w_err_x = twoSEq_1 * SEqHatDot_2 - twoSEq_2 * SEqHatDot_1 - twoSEq_3 * SEqHatDot_4 + twoSEq_4 * SEqHatDot_3;
  88. w_err_y = twoSEq_1 * SEqHatDot_3 + twoSEq_2 * SEqHatDot_4 - twoSEq_3 * SEqHatDot_1 - twoSEq_4 * SEqHatDot_2;
  89. w_err_z = twoSEq_1 * SEqHatDot_4 - twoSEq_2 * SEqHatDot_3 + twoSEq_3 * SEqHatDot_2 - twoSEq_4 * SEqHatDot_1;
  90. // compute and remove the gyroscope baises
  91. w_bx += w_err_x * deltat * zeta;
  92. w_by += w_err_y * deltat * zeta;
  93. w_bz += w_err_z * deltat * zeta;
  94. w_x -= w_bx;
  95. w_y -= w_by;
  96. w_z -= w_bz;
  97. // compute the quaternion rate measured by gyroscopes
  98. SEqDot_omega_1 = -halfSEq_2 * w_x - halfSEq_3 * w_y - halfSEq_4 * w_z;
  99. SEqDot_omega_2 = halfSEq_1 * w_x + halfSEq_3 * w_z - halfSEq_4 * w_y;
  100. SEqDot_omega_3 = halfSEq_1 * w_y - halfSEq_2 * w_z + halfSEq_4 * w_x;
  101. SEqDot_omega_4 = halfSEq_1 * w_z + halfSEq_2 * w_y - halfSEq_3 * w_x;
  102. // compute then integrate the estimated quaternion rate
  103. SEq_1 += (SEqDot_omega_1 - (beta * SEqHatDot_1)) * deltat;
  104. SEq_2 += (SEqDot_omega_2 - (beta * SEqHatDot_2)) * deltat;
  105. SEq_3 += (SEqDot_omega_3 - (beta * SEqHatDot_3)) * deltat;
  106. SEq_4 += (SEqDot_omega_4 - (beta * SEqHatDot_4)) * deltat;
  107. // normalise quaternion
  108. norm = sqrt(SEq_1 * SEq_1 + SEq_2 * SEq_2 + SEq_3 * SEq_3 + SEq_4 * SEq_4);
  109. SEq_1 /= norm;
  110. SEq_2 /= norm;
  111. SEq_3 /= norm;
  112. SEq_4 /= norm;
  113. // compute flux in the earth frame
  114. SEq_1SEq_2 = SEq_1 * SEq_2; // recompute axulirary variables
  115. SEq_1SEq_3 = SEq_1 * SEq_3;
  116. SEq_1SEq_4 = SEq_1 * SEq_4;
  117. SEq_3SEq_4 = SEq_3 * SEq_4;
  118. SEq_2SEq_3 = SEq_2 * SEq_3;
  119. SEq_2SEq_4 = SEq_2 * SEq_4;
  120. h_x = twom_x * (0.5 - SEq_3 * SEq_3 - SEq_4 * SEq_4) + twom_y * (SEq_2SEq_3 - SEq_1SEq_4) + twom_z * (SEq_2SEq_4 + SEq_1SEq_3);
  121. h_y = twom_x * (SEq_2SEq_3 + SEq_1SEq_4) + twom_y * (0.5 - SEq_2 * SEq_2 - SEq_4 * SEq_4) + twom_z * (SEq_3SEq_4 - SEq_1SEq_2);
  122. h_z = twom_x * (SEq_2SEq_4 - SEq_1SEq_3) + twom_y * (SEq_3SEq_4 + SEq_1SEq_2) + twom_z * (0.5 - SEq_2 * SEq_2 - SEq_3 * SEq_3);
  123. // normalise the flux vector to have only components in the x and z
  124. b_x = sqrt((h_x * h_x) + (h_y * h_y));
  125. b_z = h_z;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement