Advertisement
Guest User

Untitled

a guest
Apr 21st, 2015
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.61 KB | None | 0 0
  1. #include "OrientationFusion.h"
  2. #include "time/SystemTime.h"
  3.  
  4. using namespace Sensors;
  5.  
  6. #define matrix_set(matrix, row, column, value) \
  7. matrix->data[row][column] = value
  8.  
  9. #define matrix_set_symmetric(matrix, row, column, value) \
  10. matrix->data[row][column] = value; \
  11. matrix->data[column][row] = value
  12.  
  13. #define matrix_get(matrix, row, column) \
  14. matrix->data[row][column]
  15.  
  16.  
  17. #ifndef FIXMATRIX_MAX_SIZE
  18. #error FIXMATRIX_MAX_SIZE must be defined and greater or equal to the number of states, inputs and measurements.
  19. #endif
  20.  
  21. OrientationFusion::OrientationFusion()
  22. {
  23. #if (FIXMATRIX_MAX_SIZE < States) || (FIXMATRIX_MAX_SIZE < Inputs) || (FIXMATRIX_MAX_SIZE < Measurements)
  24. #error FIXMATRIX_MAX_SIZE must be greater or equal to the number of states, inputs and measurements.
  25. #endif
  26.  
  27. /************************************************************************/
  28. /* initialize the filter structures */
  29. /************************************************************************/
  30. kalman_filter_initialize_uc(&kf, States);
  31. kalman_observation_initialize(&kfm, States, Measurements);
  32.  
  33. /************************************************************************/
  34. /* set initial state */
  35. /************************************************************************/
  36. mf16 *x = kalman_get_state_vector_uc(&kf);
  37.  
  38. x->data[0][0] = 0; // theta
  39. x->data[1][0] = 0; // omega
  40. x->data[2][0] = 0; // alpha
  41.  
  42. /************************************************************************/
  43. /* set covariance */
  44. /************************************************************************/
  45. mf16 *P = kalman_get_system_covariance_uc(&kf);
  46. matrix_set_symmetric(P, 0, 0, F16(.029792 * .029792)); // var(v)
  47. matrix_set_symmetric(P, 0, 1, 0); // cov(v,a)
  48. matrix_set_symmetric(P, 0, 2, 0); // cov(v,j)
  49.  
  50. matrix_set_symmetric(P, 1, 1, F16(.00857434 * .00857434)); // var(a)
  51. matrix_set_symmetric(P, 1, 2, 0); // cov(a,j)
  52.  
  53. matrix_set_symmetric(P, 2, 2, F16(.0085743 * .0085743)); // var(j)
  54.  
  55. /************************************************************************/
  56. /* system process noise */
  57. /************************************************************************/
  58. mf16 *Q = kalman_get_system_process_noise_uc(&kf);
  59. matrix_set_symmetric(Q, 0, 0, F16(.029792 * .029792)); // var(v)
  60. matrix_set_symmetric(Q, 0, 1, 0); // cov(v,a)
  61. matrix_set_symmetric(Q, 0, 2, 0); // cov(v,j)
  62.  
  63. matrix_set_symmetric(Q, 1, 1, F16(.129792 * .129792)); // var(a)
  64. matrix_set_symmetric(Q, 1, 2, 0); // cov(a,j)
  65.  
  66. matrix_set_symmetric(Q, 2, 2, F16(.0085743 * .0085743)); // var(j)
  67.  
  68. /************************************************************************/
  69. /* set measurement transformation */
  70. /************************************************************************/
  71. mf16 *H = kalman_get_observation_transformation(&kfm);
  72.  
  73. matrix_set(H, 0, 0, fix16_one); // z = 1*theta
  74. matrix_set(H, 0, 1, 0); // + 0*omega
  75. matrix_set(H, 0, 2, 0); // + 0*alpha
  76. matrix_set(H, 1, 0, 0); // z = 0*theta
  77. matrix_set(H, 1, 1, fix16_one); // + 1*omega
  78. matrix_set(H, 1, 2, 0); // + 0*alpha
  79.  
  80. /************************************************************************/
  81. /* set process noise */
  82. /************************************************************************/
  83. mf16 *R = kalman_get_observation_process_noise(&kfm);
  84.  
  85. matrix_set(R, 0, 0, F16(3*0.129792*0.129792)); // var(theta)
  86. matrix_set(R, 1, 1, F16(0.0085743*0.0085743)); // var(omega)
  87. }
  88.  
  89. void OrientationFusion::SetStateTransition(milliseconds_t time)
  90. {
  91. mf16 *A = kalman_get_state_transition_uc(&kf);
  92.  
  93. // set time constant
  94. const fix16_t T = fix16_div(fix16_from_int(time.value), fix16_from_int(1000));
  95. const fix16_t Tsquare = fix16_sq(T);
  96.  
  97. // helper
  98. const fix16_t fix16_half = fix16_from_float(0.5);
  99.  
  100. // transition of x to v
  101. matrix_set(A, 0, 0, fix16_one); // 1
  102. matrix_set(A, 0, 1, T); // T
  103. matrix_set(A, 0, 2, fix16_mul(fix16_half, Tsquare)); // 0.5 * T^2
  104.  
  105. // transition of x to a
  106. matrix_set(A, 1, 0, 0); // 0
  107. matrix_set(A, 1, 1, fix16_one); // 1
  108. matrix_set(A, 1, 2, T); // T
  109.  
  110. // transition of x to j
  111. matrix_set(A, 2, 0, 0); // 0
  112. matrix_set(A, 2, 1, 0); // 0
  113. matrix_set(A, 2, 2, fix16_one); // 1
  114. }
  115.  
  116. milliseconds_t OrientationFusion::Predict(Fix16 u_omega)
  117. {
  118. const auto now = SystemTime::get()->NowMs();
  119. const auto difference = (now - _previousRun);
  120. _previousRun = now;
  121.  
  122. SetStateTransition(difference);
  123. kalman_predict_uc(&kf);
  124.  
  125. return difference;
  126. }
  127.  
  128.  
  129. void OrientationFusion::Update(milliseconds_t dt, Fix16 z_heading, Fix16 z_odometry)
  130. {
  131. /* update */
  132. mf16 *z = kalman_get_observation_vector(&kfm);
  133. matrix_set(z, 0, 0, z_heading);
  134. matrix_set(z, 1, 0, z_odometry);
  135.  
  136. /* correct */
  137. kalman_correct_uc(&kf, &kfm);
  138.  
  139. mf16 *P = kalman_get_system_covariance_uc(&kf);
  140. matrix_set_symmetric(P, 0, 1, 0);
  141. matrix_set_symmetric(P, 0, 2, 0);
  142. matrix_set_symmetric(P, 1, 2, 0);
  143.  
  144. if (kf.x.data[1][0] == 0xFFFFFFFF80000000 || kf.x.data[1][0] == 0x80000000)
  145. {
  146. kf.x.data[0][0] = 0;
  147. kf.P.data[0][0] = Fix16::OneThousand;
  148.  
  149. kf.x.data[1][0] = 0;
  150. kf.P.data[1][1] = Fix16::OneThousand;
  151.  
  152. kf.x.data[2][0] = 0;
  153. kf.P.data[2][2] = Fix16::OneThousand;
  154. }
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement