footPDR.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #define ZUPT_threshold 0.81
  6. #define SIGMA 0.01
  7. #define SIGMA_V 0.01
  8. #define PI 3.1416
  9. //当地的重力加速度
  10. float g = 9.81;
  11. float dt = 0.01;
  12. float P[81], acc_n[3];
  13. float Temporary_array1[9], Temporary_array2[9];
  14. float K[27], P_prev[81], delta_x[9];
  15. float C[9], C_prev[9];
  16. float vel_n[3], pos_n[3];
  17. float last_pos_n[3];
  18. float pos_offset[3];
  19. int last_num = 0;
  20. int frame_index = 0;
  21. int last_zupt_index = 30;
  22. int output_signal = 0;
  23. int stand_num = 0;
  24. int last_zupt = 0;
  25. float gyr_norm_window[15];
  26. float max_window_val;
  27. float min_window_val;
  28. int last_running = 1;
  29. void invert3x3(float * src, float * dst)
  30. {
  31. float det;
  32. /* Compute adjoint: */
  33. dst[0] = +src[4] * src[8] - src[5] * src[7];
  34. dst[1] = -src[1] * src[8] + src[2] * src[7];
  35. dst[2] = +src[1] * src[5] - src[2] * src[4];
  36. dst[3] = -src[3] * src[8] + src[5] * src[6];
  37. dst[4] = +src[0] * src[8] - src[2] * src[6];
  38. dst[5] = -src[0] * src[5] + src[2] * src[3];
  39. dst[6] = +src[3] * src[7] - src[4] * src[6];
  40. dst[7] = -src[0] * src[7] + src[1] * src[6];
  41. dst[8] = +src[0] * src[4] - src[1] * src[3];
  42. /* Compute determinant: */
  43. det = src[0] * dst[0] + src[1] * dst[3] + src[2] * dst[6];
  44. /* Multiply adjoint with reciprocal of determinant: */
  45. det = 1.0f / det;
  46. dst[0] *= det;
  47. dst[1] *= det;
  48. dst[2] *= det;
  49. dst[3] *= det;
  50. dst[4] *= det;
  51. dst[5] *= det;
  52. dst[6] *= det;
  53. dst[7] *= det;
  54. dst[8] *= det;
  55. }
  56. void multiply3x3(float *a, float *b, float *dst)
  57. {
  58. dst[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
  59. dst[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
  60. dst[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
  61. dst[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6];
  62. dst[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7];
  63. dst[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8];
  64. dst[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6];
  65. dst[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7];
  66. dst[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8];
  67. }
  68. void multiply3x1(float *a, float *b, float *dst)
  69. {
  70. dst[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  71. dst[1] = a[3] * b[0] + a[4] * b[1] + a[5] * b[2];
  72. dst[2] = a[6] * b[0] + a[7] * b[1] + a[8] * b[2];
  73. }
  74. void init_attitude_matrix(float *C, float *acc)
  75. {
  76. float pitch = asin(-acc[0] / g);
  77. float roll = atan2(acc[1], acc[2]);
  78. float pitch_sin = sin(pitch);
  79. float pitch_cos = cos(pitch);
  80. float roll_sin = sin(roll);
  81. float roll_cos = cos(roll);
  82. C[0] = cos(pitch);
  83. C[1] = pitch_sin * roll_sin;
  84. C[2] = pitch_sin * roll_cos;
  85. C[4] = roll_cos;
  86. C[5] = -roll_sin;
  87. C[6] = -pitch_sin;
  88. C[7] = pitch_cos * roll_sin;
  89. C[8] = pitch_cos * roll_cos;
  90. }
  91. void reset_yaw_C(float *C)
  92. {
  93. float pitch = asin(-C[6]);
  94. float roll = atan2(C[7], C[8]);
  95. float pitch_sin = sin(pitch);
  96. float pitch_cos = cos(pitch);
  97. float roll_sin = sin(roll);
  98. float roll_cos = cos(roll);
  99. C[0] = pitch_cos;
  100. C[1] = pitch_sin * roll_sin;
  101. C[2] = pitch_sin * roll_cos;
  102. C[3] = 0.0;
  103. C[4] = roll_cos;
  104. C[5] = -roll_sin;
  105. }
  106. // F * P * F'
  107. void State_covariance_matrix_update(float *P, float *acc_n)
  108. {
  109. // P2 + P3*dt,
  110. P[3] = P[3] + P[6] * dt;
  111. P[4] = P[4] + P[7] * dt;
  112. P[5] = P[5] + P[8] * dt;
  113. P[12] = P[12] + P[15] * dt;
  114. P[13] = P[13] + P[16] * dt;
  115. P[14] = P[14] + P[17] * dt;
  116. P[21] = P[21] + P[24] * dt;
  117. P[22] = P[22] + P[25] * dt;
  118. P[23] = P[23] + P[26] * dt;
  119. //P4 + P7*dt,
  120. P[27] = P[27] + P[54] * dt;
  121. P[28] = P[28] + P[55] * dt;
  122. P[29] = P[29] + P[56] * dt;
  123. P[36] = P[36] + P[63] * dt;
  124. P[37] = P[37] + P[64] * dt;
  125. P[38] = P[38] + P[65] * dt;
  126. P[45] = P[45] + P[72] * dt;
  127. P[46] = P[46] + P[73] * dt;
  128. P[47] = P[47] + P[74] * dt;
  129. // P5 + P8*dt + dt*(P6 + P9*dt)
  130. P[30] = P[30] + P[57] * dt + dt * (P[33] + P[60] * dt);
  131. P[31] = P[31] + P[58] * dt + dt * (P[34] + P[61] * dt);
  132. P[32] = P[32] + P[59] * dt + dt * (P[35] + P[62] * dt);
  133. P[39] = P[39] + P[66] * dt + dt * (P[42] + P[69] * dt);
  134. P[40] = P[40] + P[67] * dt + dt * (P[43] + P[70] * dt);
  135. P[41] = P[41] + P[68] * dt + dt * (P[44] + P[71] * dt);
  136. P[48] = P[48] + P[75] * dt + dt * (P[51] + P[78] * dt);
  137. P[49] = P[49] + P[76] * dt + dt * (P[52] + P[79] * dt);
  138. P[50] = P[50] + P[77] * dt + dt * (P[53] + P[80] * dt);
  139. //P6 + P9*dt + matr*(P4 + P7*dt)
  140. P[33] = P[33] + P[60] * dt + acc_n[2] * dt * P[28] - acc_n[1] * dt * P[29];
  141. P[34] = P[34] + P[61] * dt - acc_n[2] * dt * P[27] + acc_n[0] * dt * P[29];
  142. P[35] = P[35] + P[62] * dt + acc_n[1] * dt * P[27] - acc_n[0] * dt * P[28];
  143. P[42] = P[42] + P[69] * dt + acc_n[2] * dt * P[37] - acc_n[1] * dt * P[38];
  144. P[43] = P[43] + P[70] * dt - acc_n[2] * dt * P[36] + acc_n[0] * dt * P[38];
  145. P[44] = P[44] + P[71] * dt + acc_n[1] * dt * P[36] - acc_n[0] * dt * P[37];
  146. P[51] = P[51] + P[78] * dt + acc_n[2] * dt * P[46] - acc_n[1] * dt * P[47];
  147. P[52] = P[52] + P[79] * dt - acc_n[2] * dt * P[45] + acc_n[0] * dt * P[47];
  148. P[53] = P[53] + P[80] * dt + acc_n[1] * dt * P[45] - acc_n[0] * dt * P[46];
  149. //P7 + P1*matr
  150. P[54] = P[54] + P[9] * acc_n[2] * dt - P[18] * acc_n[1] * dt;
  151. P[55] = P[55] + P[10] * acc_n[2] * dt - P[19] * acc_n[1] * dt;
  152. P[56] = P[56] + P[11] * acc_n[2] * dt - P[20] * acc_n[1] * dt;
  153. P[63] = P[63] - P[0] * acc_n[2] * dt + P[18] * acc_n[0] * dt;
  154. P[64] = P[64] - P[1] * acc_n[2] * dt + P[19] * acc_n[0] * dt;
  155. P[65] = P[65] - P[2] * acc_n[2] * dt + P[20] * acc_n[0] * dt;
  156. P[72] = P[72] + P[0] * acc_n[1] * dt - P[9] * acc_n[0] * dt;
  157. P[73] = P[73] + P[1] * acc_n[1] * dt - P[10] * acc_n[0] * dt;
  158. P[74] = P[74] + P[2] * acc_n[1] * dt - P[11] * acc_n[0] * dt;
  159. //P8 + P2*matr + dt*(P9 + P3*matr),
  160. P[57] = P[57] + dt * P[60] + P[12] * acc_n[2] * dt - P[21] * acc_n[1] * dt;
  161. P[58] = P[58] + dt * P[61] + P[13] * acc_n[2] * dt - P[22] * acc_n[1] * dt;
  162. P[59] = P[59] + dt * P[62] + P[14] * acc_n[2] * dt - P[23] * acc_n[1] * dt;
  163. P[66] = P[66] + dt * P[69] - P[3] * acc_n[2] * dt + P[21] * acc_n[0] * dt;
  164. P[67] = P[67] + dt * P[70] - P[4] * acc_n[2] * dt + P[22] * acc_n[0] * dt;
  165. P[68] = P[68] + dt * P[71] - P[5] * acc_n[2] * dt + P[23] * acc_n[0] * dt;
  166. P[75] = P[75] + dt * P[78] + P[3] * acc_n[1] * dt - P[12] * acc_n[0] * dt;
  167. P[76] = P[76] + dt * P[79] + P[4] * acc_n[1] * dt - P[13] * acc_n[0] * dt;
  168. P[77] = P[77] + dt * P[80] + P[5] * acc_n[1] * dt - P[14] * acc_n[0] * dt;
  169. // P9 + P3*matr + matr*(P7 + P1*matr)
  170. P[60] = P[60] + P[15] * acc_n[2] * dt - P[24] * acc_n[1] * dt + acc_n[2] * dt * P[55] - acc_n[1] * dt * P[56];
  171. P[61] = P[61] + P[16] * acc_n[2] * dt - P[25] * acc_n[1] * dt - acc_n[2] * dt * P[54] + acc_n[0] * dt * P[56];
  172. P[62] = P[62] + P[17] * acc_n[2] * dt - P[26] * acc_n[1] * dt + acc_n[1] * dt * P[54] - acc_n[0] * dt * P[55];
  173. P[69] = P[69] - P[6] * acc_n[2] * dt + P[24] * acc_n[0] * dt + acc_n[2] * dt * P[64] - acc_n[1] * dt * P[65];
  174. P[70] = P[70] - P[7] * acc_n[2] * dt + P[25] * acc_n[0] * dt - acc_n[2] * dt * P[63] + acc_n[0] * dt * P[65];
  175. P[71] = P[71] - P[8] * acc_n[2] * dt + P[26] * acc_n[0] * dt + acc_n[1] * dt * P[63] - acc_n[0] * dt * P[64];
  176. P[78] = P[78] + P[6] * acc_n[1] * dt - P[15] * acc_n[0] * dt + acc_n[2] * dt * P[73] - acc_n[1] * dt * P[74];
  177. P[79] = P[79] + P[7] * acc_n[1] * dt - P[16] * acc_n[0] * dt - acc_n[2] * dt * P[72] + acc_n[0] * dt * P[74];
  178. P[80] = P[80] + P[8] * acc_n[1] * dt - P[17] * acc_n[0] * dt + acc_n[1] * dt * P[72] - acc_n[0] * dt * P[73];
  179. //P3 + P1 * matr
  180. P[6] = P[6] + P[1] * acc_n[2] * dt - P[2] * acc_n[1] * dt;
  181. P[7] = P[7] - P[0] * acc_n[2] * dt + P[2] * acc_n[0] * dt;
  182. P[8] = P[8] + P[0] * acc_n[1] * dt - P[1] * acc_n[0] * dt;
  183. P[15] = P[15] + P[10] * acc_n[2] * dt - P[11] * acc_n[1] * dt;
  184. P[16] = P[16] - P[9] * acc_n[2] * dt + P[11] * acc_n[0] * dt;
  185. P[17] = P[17] + P[9] * acc_n[1] * dt - P[10] * acc_n[0] * dt;
  186. P[24] = P[24] + P[19] * acc_n[2] * dt - P[20] * acc_n[1] * dt;
  187. P[25] = P[25] - P[18] * acc_n[2] * dt + P[20] * acc_n[0] * dt;
  188. P[26] = P[26] + P[18] * acc_n[1] * dt - P[19] * acc_n[0] * dt;
  189. float noise = SIGMA * SIGMA * dt *dt;
  190. for (int i = 0; i < 9; i++)
  191. {
  192. P[i * 9 + i] += noise;
  193. }
  194. }
  195. void Kalfman_gain(float *P, float *Temporary_array, float *Temporary_array1, float *K)
  196. {
  197. Temporary_array[0] = P[60] + SIGMA_V * SIGMA_V;
  198. Temporary_array[1] = P[61];
  199. Temporary_array[2] = P[62];
  200. Temporary_array[3] = P[69];
  201. Temporary_array[4] = P[70] + SIGMA_V * SIGMA_V;
  202. Temporary_array[5] = P[71];
  203. Temporary_array[6] = P[78];
  204. Temporary_array[7] = P[79];
  205. Temporary_array[8] = P[80] + SIGMA_V * SIGMA_V * 0.01;
  206. invert3x3(Temporary_array, Temporary_array1);
  207. memcpy(Temporary_array, Temporary_array1, 9 * sizeof(float));
  208. K[0] = P[6] * Temporary_array[0] + P[7] * Temporary_array[3] + P[8] * Temporary_array[6];
  209. K[1] = P[6] * Temporary_array[1] + P[7] * Temporary_array[4] + P[8] * Temporary_array[7];
  210. K[2] = P[6] * Temporary_array[2] + P[7] * Temporary_array[5] + P[8] * Temporary_array[8];
  211. K[3] = P[15] * Temporary_array[0] + P[16] * Temporary_array[3] + P[17] * Temporary_array[6];
  212. K[4] = P[15] * Temporary_array[1] + P[16] * Temporary_array[4] + P[17] * Temporary_array[7];
  213. K[5] = P[15] * Temporary_array[2] + P[16] * Temporary_array[5] + P[17] * Temporary_array[8];
  214. K[6] = P[24] * Temporary_array[0] + P[25] * Temporary_array[3] + P[26] * Temporary_array[6];
  215. K[7] = P[24] * Temporary_array[1] + P[25] * Temporary_array[4] + P[26] * Temporary_array[7];
  216. K[8] = P[24] * Temporary_array[2] + P[25] * Temporary_array[5] + P[26] * Temporary_array[8];
  217. K[9] = P[33] * Temporary_array[0] + P[34] * Temporary_array[3] + P[35] * Temporary_array[6];
  218. K[10] = P[33] * Temporary_array[1] + P[34] * Temporary_array[4] + P[35] * Temporary_array[7];
  219. K[11] = P[33] * Temporary_array[2] + P[34] * Temporary_array[5] + P[35] * Temporary_array[8];
  220. K[12] = P[42] * Temporary_array[0] + P[43] * Temporary_array[3] + P[44] * Temporary_array[6];
  221. K[13] = P[42] * Temporary_array[1] + P[43] * Temporary_array[4] + P[44] * Temporary_array[7];
  222. K[14] = P[42] * Temporary_array[2] + P[43] * Temporary_array[5] + P[44] * Temporary_array[8];
  223. K[15] = P[51] * Temporary_array[0] + P[52] * Temporary_array[3] + P[53] * Temporary_array[6];
  224. K[16] = P[51] * Temporary_array[1] + P[52] * Temporary_array[4] + P[53] * Temporary_array[7];
  225. K[17] = P[51] * Temporary_array[2] + P[52] * Temporary_array[5] + P[53] * Temporary_array[8];
  226. K[18] = P[60] * Temporary_array[0] + P[61] * Temporary_array[3] + P[62] * Temporary_array[6];
  227. K[19] = P[60] * Temporary_array[1] + P[61] * Temporary_array[4] + P[62] * Temporary_array[7];
  228. K[20] = P[60] * Temporary_array[2] + P[61] * Temporary_array[5] + P[62] * Temporary_array[8];
  229. K[21] = P[69] * Temporary_array[0] + P[70] * Temporary_array[3] + P[71] * Temporary_array[6];
  230. K[22] = P[69] * Temporary_array[1] + P[70] * Temporary_array[4] + P[71] * Temporary_array[7];
  231. K[23] = P[69] * Temporary_array[2] + P[70] * Temporary_array[5] + P[71] * Temporary_array[8];
  232. K[24] = P[78] * Temporary_array[0] + P[79] * Temporary_array[3] + P[80] * Temporary_array[6];
  233. K[25] = P[78] * Temporary_array[1] + P[79] * Temporary_array[4] + P[80] * Temporary_array[7];
  234. K[26] = P[78] * Temporary_array[2] + P[79] * Temporary_array[5] + P[80] * Temporary_array[8];
  235. }
  236. void multiply9x3(float *K, float *vel_n, float* delta_x)
  237. {
  238. int i = 0;
  239. for (i = 0; i < 9; i++)
  240. {
  241. delta_x[i] = K[i * 3] * vel_n[0] + K[i * 3 + 1] * vel_n[1] + K[i * 3 + 2] * vel_n[2];
  242. }
  243. }
  244. void State_covariance_matrix_corr(float *P, float *P_tmp, float *K)
  245. {
  246. int i = 0;
  247. int j = 0;
  248. for (i = 0; i < 9; i++) {
  249. for (j = 0; j < 9; j++) {
  250. P_tmp[i * 9 + j] = P[i * 9 + j] - K[3 * i] * P[54 + j] - K[3 * i + 1] * P[63 + j] - K[3 * i + 2] * P[72 + j];
  251. }
  252. }
  253. memcpy(P, P_tmp, 81 * sizeof(float));
  254. }
  255. void Att_matrix_corr(float *C, float *C_prev, float *Temporary_array, float *Temporary_array1, float *delta_x)
  256. {
  257. Temporary_array[0] = 2.0;
  258. Temporary_array[1] = -delta_x[2];
  259. Temporary_array[2] = delta_x[1];
  260. Temporary_array[3] = delta_x[2];
  261. Temporary_array[4] = 2.0;
  262. Temporary_array[5] = -delta_x[0];
  263. Temporary_array[6] = -delta_x[1];
  264. Temporary_array[7] = delta_x[0];
  265. Temporary_array[8] = 2.0;
  266. invert3x3(Temporary_array, Temporary_array1);
  267. Temporary_array[0] = 2.0;
  268. Temporary_array[1] = delta_x[2];
  269. Temporary_array[2] = -delta_x[1];
  270. Temporary_array[3] = -delta_x[2];
  271. Temporary_array[4] = 2.0;
  272. Temporary_array[5] = delta_x[0];
  273. Temporary_array[6] = delta_x[1];
  274. Temporary_array[7] = -delta_x[0];
  275. Temporary_array[8] = 2.0;
  276. multiply3x3(Temporary_array, Temporary_array1, C_prev);
  277. memcpy(Temporary_array, C_prev, 9 * sizeof(float));
  278. multiply3x3(Temporary_array, C, C_prev);
  279. memcpy(C, C_prev, 9 * sizeof(float));
  280. }
  281. void pos_n_corr(float *pos_n, float *delta_x)
  282. {
  283. pos_n[0] -= delta_x[3];
  284. pos_n[1] -= delta_x[4];
  285. pos_n[2] -= delta_x[5];
  286. }
  287. void vel_n_corr(float *vel_n, float *delta_x)
  288. {
  289. vel_n[0] -= delta_x[6];
  290. vel_n[1] -= delta_x[7];
  291. vel_n[2] -= delta_x[8];
  292. }
  293. void State_covariance_matrix_orthogonalization(float *P)
  294. {
  295. int i = 0;
  296. int j = 0;
  297. float temp;
  298. for (i = 0; i < 9; i++)
  299. for (j = i + 1; j < 9; j++)
  300. {
  301. temp = 0.5f*(P[i * 9 + j] + P[j * 9 + i]);
  302. P[i * 9 + j] = temp;
  303. P[j * 9 + i] = temp;
  304. }
  305. }
  306. void Initialize(float *gyr, float *acc)
  307. {
  308. frame_index = 1;
  309. last_num = 0;
  310. last_zupt_index = 30;
  311. output_signal = 0;
  312. stand_num = 0;
  313. last_zupt = 0;
  314. memset(last_pos_n, 0, 3 * sizeof(float));
  315. memset(pos_offset, 0, 3 * sizeof(float));
  316. memset(gyr_norm_window, 0, 15 * sizeof(float));
  317. memset(P, 0, 81 * sizeof(float));
  318. memset(acc_n, 0, 3 * sizeof(float));
  319. memset(vel_n, 0, 3 * sizeof(float));
  320. memset(pos_n, 0, 3 * sizeof(float));
  321. memset(Temporary_array1, 0, 9 * sizeof(float));
  322. memset(Temporary_array2, 0, 9 * sizeof(float));
  323. memset(K, 0, 27 * sizeof(float));
  324. memset(P_prev, 0, 81 * sizeof(float));
  325. memset(delta_x, 0, 9 * sizeof(float));
  326. memset(C, 0, 9 * sizeof(float));
  327. memset(Temporary_array1, 0, 9 * sizeof(float));
  328. memset(Temporary_array2, 0, 9 * sizeof(float));
  329. init_attitude_matrix(C, acc);
  330. memcpy(C_prev, C, 9 * sizeof(float));
  331. }
  332. void attitude_matrix_update(float *C, float *Temporary_array1, float *Temporary_array2, float *gyr)
  333. {
  334. Temporary_array1[0] = 2.0;
  335. Temporary_array1[1] = dt * gyr[2];
  336. Temporary_array1[2] = -dt * gyr[1];
  337. Temporary_array1[3] = -dt * gyr[2];
  338. Temporary_array1[4] = 2.0;
  339. Temporary_array1[5] = dt * gyr[0];
  340. Temporary_array1[6] = dt * gyr[1];
  341. Temporary_array1[7] = -dt * gyr[0];
  342. Temporary_array1[8] = 2.0;
  343. invert3x3(Temporary_array1, Temporary_array2);
  344. memset(Temporary_array1, 0, 9 * sizeof(float));
  345. Temporary_array1[0] = 2 * C[0] + C[1] * dt * gyr[2] - C[2] * dt * gyr[1];
  346. Temporary_array1[1] = 2 * C[1] - C[0] * dt * gyr[2] + C[2] * dt * gyr[0];
  347. Temporary_array1[2] = 2 * C[2] + C[0] * dt * gyr[1] - C[1] * dt * gyr[0];
  348. Temporary_array1[3] = 2 * C[3] + C[4] * dt * gyr[2] - C[5] * dt * gyr[1];
  349. Temporary_array1[4] = 2 * C[4] - C[3] * dt * gyr[2] + C[5] * dt * gyr[0];
  350. Temporary_array1[5] = 2 * C[5] + C[3] * dt * gyr[1] - C[4] * dt * gyr[0];
  351. Temporary_array1[6] = 2 * C[6] + C[7] * dt * gyr[2] - C[8] * dt * gyr[1];
  352. Temporary_array1[7] = 2 * C[7] - C[6] * dt * gyr[2] + C[8] * dt * gyr[0];
  353. Temporary_array1[8] = 2 * C[8] + C[6] * dt * gyr[1] - C[7] * dt * gyr[0];
  354. multiply3x3(Temporary_array1, Temporary_array2, C);
  355. }
  356. float max_window(float *window)
  357. {
  358. float val = -1.0;
  359. for (int i = 0; i < 15; i++)
  360. {
  361. if (window[i] > val)
  362. val = window[i];
  363. }
  364. return val;
  365. }
  366. float min_window(float *window)
  367. {
  368. float val = 1000.0;
  369. for (int i = 0; i < 15; i++)
  370. {
  371. if (window[i] < val)
  372. val = window[i];
  373. }
  374. return val;
  375. }
  376. unsigned char footPDR(int num, float *gyr, float *acc, float *vel, float *pos)
  377. {
  378. unsigned char movement_e = 0;
  379. for (int i = 0; i < 3; i++)
  380. {
  381. gyr[i] *= (PI / 180);
  382. acc[i] *= g;
  383. }
  384. //需要一个滑动窗口来判断脚步是否在地上
  385. frame_index++;
  386. //下面为惯导解算
  387. if (num == 1)
  388. {
  389. Initialize(gyr, acc);
  390. return movement_e;
  391. }
  392. attitude_matrix_update(C, Temporary_array1, Temporary_array2, gyr);
  393. multiply3x1(C, acc, acc_n);
  394. vel_n[0] = vel_n[0] + acc_n[0] * dt;
  395. vel_n[1] = vel_n[1] + acc_n[1] * dt;
  396. vel_n[2] = vel_n[2] + (acc_n[2] - g) * dt;
  397. pos_n[0] = pos_n[0] + vel_n[0] * dt;
  398. pos_n[1] = pos_n[1] + vel_n[1] * dt;
  399. pos_n[2] = pos_n[2] + vel_n[2] * dt;
  400. //P = F*P*F' + Q;
  401. State_covariance_matrix_update(P, acc_n);
  402. int window_index = (frame_index - 1) % 15;
  403. gyr_norm_window[window_index] = sqrt(gyr[0] * gyr[0] + gyr[1] * gyr[1] + gyr[2] * gyr[2]);
  404. if (frame_index > 15)
  405. {
  406. max_window_val = max_window(gyr_norm_window);
  407. min_window_val = min_window(gyr_norm_window);
  408. }
  409. float sub_window = max_window_val - min_window_val;
  410. pos_offset[0] = pos_n[0] - last_pos_n[0];
  411. pos_offset[1] = pos_n[1] - last_pos_n[1];
  412. pos_offset[2] = pos_n[2] - last_pos_n[2];
  413. //临时值2.0f,后期需要优化
  414. if (((gyr_norm_window[window_index] < 0.6f) && (frame_index > 15) && (sub_window < 0.6f))
  415. || ((gyr_norm_window[window_index] < 2.0f) && ((frame_index - last_zupt_index) > 25) && (frame_index > 15) && (sub_window > 6.0f))
  416. || ((gyr_norm_window[window_index] < 2.0f) && ((frame_index - last_zupt_index) > 50) && (frame_index > 15) && (sub_window > 5.0f)))//这里往后再优化
  417. {
  418. if (last_zupt == 1)
  419. {
  420. //输出信号
  421. output_signal = 1;
  422. stand_num = stand_num + 1;
  423. //K = P*H'/(H*P*H' + R);
  424. Kalfman_gain(P, Temporary_array1, Temporary_array2, K);
  425. //delta_x = K * [vel_n(:,i);];
  426. multiply9x3(K, vel_n, delta_x);
  427. State_covariance_matrix_corr(P, P_prev, K);
  428. Att_matrix_corr(C, C_prev, Temporary_array1, Temporary_array2, delta_x);
  429. pos_n_corr(pos_n, delta_x);
  430. vel_n_corr(vel_n, delta_x);
  431. reset_yaw_C(C);
  432. last_pos_n[0] = pos_n[0];
  433. last_pos_n[1] = pos_n[1];
  434. last_pos_n[2] = pos_n[2];
  435. }
  436. last_zupt = 1;
  437. last_running = frame_index;
  438. }
  439. else
  440. {
  441. if (last_zupt == 1)
  442. {
  443. last_zupt = 0;
  444. last_zupt_index = frame_index - 1;
  445. }
  446. //最先判断左右, 再判断前后,最后再判断起跳,都不符合视作为跑步
  447. if (output_signal == 1 && frame_index - last_zupt_index > 5) //&& pos_offset[2] < -0.001
  448. {
  449. if (pos_offset[1] < -0.25f)
  450. {
  451. movement_e = 4;
  452. output_signal = 0;
  453. }
  454. else if (pos_offset[1] > 0.25f)
  455. {
  456. movement_e = 5;
  457. output_signal = 0;
  458. }
  459. else if (pos_offset[0] < -0.25f)
  460. {
  461. movement_e = 8;
  462. output_signal = 0;
  463. }
  464. else if (pos_offset[2] < -0.25f)
  465. {
  466. movement_e = 7;
  467. output_signal = 0;
  468. }
  469. else if (pos_offset[0] > 0.25f)
  470. {
  471. movement_e = 6;
  472. output_signal = 0;
  473. }
  474. else if (frame_index - last_running > 30)
  475. {
  476. movement_e = 6;
  477. last_running = frame_index;
  478. }
  479. }
  480. }
  481. State_covariance_matrix_orthogonalization(P);
  482. if (output_signal == 1 && stand_num > 100)
  483. {
  484. output_signal = 0;
  485. movement_e = 1;
  486. stand_num = 0;
  487. }
  488. memcpy(vel, vel_n, 3 * sizeof(float));
  489. // memcpy(pos, pos_n, 3 * sizeof(float));
  490. memcpy(pos, pos_offset, 3 * sizeof(float));
  491. return movement_e;
  492. }
  493. //int main()
  494. //{
  495. // FILE *fp = NULL;
  496. // FILE *out = NULL;
  497. // char *line, *record;
  498. // char buffer[1024];
  499. // int num = 0;
  500. // float *gyr = (float *)malloc(3 * sizeof(float));
  501. // float *acc = (float *)malloc(3 * sizeof(float));
  502. // out = fopen("F:\\work\\result.txt", "a+");
  503. // if ((fp = fopen("F:\\work\\LoggedData2_CalInertialAndMag.csv", "r")) != NULL)
  504. // {
  505. // fseek(fp, 170L, SEEK_SET); //定位到第二行,每个英文字符大小为1
  506. // char delims[] = ",";
  507. // char *result = NULL;
  508. // int j = 0;
  509. // while ((line = fgets(buffer, sizeof(buffer), fp)) != NULL)//当没有读取到文件末尾时循环继续
  510. // {
  511. // record = strtok(line, ",");
  512. // while (record != NULL)//读取每一行的数据
  513. // {
  514. // if (strcmp(record, "Ps:") == 0)//当读取到Ps那一行时,不再继续读取
  515. // return 0;
  516. // //printf("%s ", record);//将读取到的每一个数据打印出来
  517. //
  518. // switch (j) {
  519. // case 1:
  520. // gyr[0] = atof(record);
  521. // break;
  522. // case 2:
  523. // gyr[1] = atof(record);
  524. // break;
  525. // case 3:
  526. // gyr[2] = atof(record);
  527. // break;
  528. // case 4:
  529. // acc[0] = atof(record);
  530. // break;
  531. // case 5:
  532. // acc[1] = atof(record);
  533. // break;
  534. // case 6:
  535. // acc[2] = atof(record);
  536. // break;
  537. // default:
  538. // break;
  539. // }
  540. //
  541. // if (j == 6) //只需读取前9列
  542. // break;
  543. // record = strtok(NULL, ",");
  544. // j++;
  545. // }
  546. // if (num > 0)
  547. // {
  548. // //printf("%6.6f %6.6f %6.6f \n", gyr[0], gyr[1], gyr[2]);
  549. // unsigned char movement_e = footPDR(num, gyr, acc, vel_n, pos_n);
  550. // for (int i = 0; i < 3; i++)
  551. // {
  552. // fprintf(out, "%f ", pos_n[i]);
  553. // }
  554. // fprintf(out, "\n ");
  555. //
  556. // switch (movement_e) {
  557. // case 7:
  558. // printf("MOVE_JUMP\n");
  559. // break;
  560. // }
  561. //
  562. // }
  563. // num++;
  564. // j = 0;
  565. //
  566. // }
  567. // fclose(fp);
  568. // fp = NULL;
  569. // }
  570. // /*
  571. // float *gyr = (float *)malloc(3 * sizeof(float));
  572. // float *acc = (float *)malloc(3 * sizeof(float));
  573. // int num;
  574. // float gyr_x, gyr_y, gyr_z, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z;
  575. // while (fscanf(file, "%d%f%f%f%f%f%f%f%f%f", &num, &gyr_x, &gyr_y, &gyr_z, &acc_x, &acc_y, &acc_z, &mag_x, &mag_y, &mag_z)) {
  576. // printf("%d %f %f %f %f %f %f %f %f %f", gyr_x, gyr_y, gyr_z, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z);
  577. //
  578. // }
  579. // fclose(file);
  580. //
  581. // return 0;
  582. // */
  583. //}
  584. /*
  585. int main()
  586. {
  587. float acc_x = 0.0;
  588. float acc_y = 0.1;
  589. float acc_z = 9.75;
  590. float acc[] = { acc_x , acc_y, acc_z };
  591. float gyr_x = 0.01;
  592. float gyr_z = 0.02;
  593. float gyr_y = 0.03;
  594. float gyr[] = { gyr_x , gyr_y, gyr_z };
  595. P = (float *)malloc(81*sizeof(float));
  596. memset(P, 0, 81*sizeof(float));
  597. P_prev = (float *)malloc(81*sizeof(float));
  598. memset(P_prev, 0, 81*sizeof(float));
  599. C = (float *)malloc(9);
  600. float* C_inv = (float *) malloc(9 * sizeof(float));
  601. memset(C_inv, 0, 9 * sizeof(float));
  602. acc_n = (float *) malloc(3 * sizeof(float));
  603. memset(acc_n, 0, 3 * sizeof(float));
  604. vel_n = (float *) malloc(3 * sizeof(float));
  605. memset(vel_n, 0, 3 * sizeof(float));
  606. pos_n = (float *) malloc(3 * sizeof(float));
  607. memset(pos_n, 0, 3 * sizeof(float));
  608. K = (float *)malloc(27 * sizeof(float));
  609. memset(K, 0, 27 * sizeof(float));
  610. Temporary_array1 = (float *)malloc(9 * sizeof(float));
  611. memset(Temporary_array1, 0, 9 * sizeof(float));
  612. Temporary_array2 = (float *)malloc(9 * sizeof(float));
  613. memset(Temporary_array2, 0, 9 * sizeof(float));
  614. delta_x = (float *)malloc(9 * sizeof(float));
  615. memset(delta_x, 0, 9 * sizeof(float));
  616. C_inv[0] = 2.0;
  617. C_inv[1] = dt*gyr_z;
  618. C_inv[2] = -dt*gyr_y;
  619. C_inv[3] = -dt*gyr_z;
  620. C_inv[4] = 2.0;
  621. C_inv[5] = dt*gyr_x;
  622. C_inv[6] = dt*gyr_y;
  623. C_inv[7] = -dt*gyr_x;
  624. C_inv[9] = 2.0;
  625. float* C_res =(float *) malloc(9 * sizeof(float));
  626. memset(C_res, 0, 9 * sizeof(float));
  627. invert3x3(C_inv, C_res);
  628. memset(C_inv, 0, 9 * sizeof(float));
  629. C_inv[0] = 2 * C[0] + C[1] * dt * gyr_z - C[2] * dt * gyr_y;
  630. C_inv[1] = 2 * C[1] - C[0] * dt * gyr_z + C[2] * dt * gyr_x;
  631. C_inv[2] = 2 * C[2] + C[0] * dt * gyr_y - C[1] * dt * gyr_x;
  632. C_inv[3] = 2 * C[3] + C[4] * dt * gyr_z - C[5] * dt * gyr_y;
  633. C_inv[4] = 2 * C[4] - C[3] * dt * gyr_z + C[5] * dt * gyr_x;
  634. C_inv[5] = 2 * C[5] + C[3] * dt * gyr_y - C[4] * dt * gyr_x;
  635. C_inv[6] = 2 * C[6] + C[7] * dt * gyr_z - C[8] * dt * gyr_y;
  636. C_inv[7] = 2 * C[7] - C[6] * dt * gyr_z + C[8] * dt * gyr_x;
  637. C_inv[8] = 2 * C[8] + C[6] * dt * gyr_y - C[7] * dt * gyr_x;
  638. multiply3x3(C_inv, C_res, C);
  639. //C*acc
  640. multiply3x1(C, acc, acc_n);
  641. vel_n[0] = vel_n[0] + acc_n[0] * dt;
  642. vel_n[1] = vel_n[1] + acc_n[1] * dt;
  643. vel_n[2] = vel_n[2] + (acc_n[2] - g) * dt;
  644. pos_n[0] = pos_n[0] + vel_n[0] * dt;
  645. pos_n[1] = pos_n[1] + vel_n[1] * dt;
  646. pos_n[2] = pos_n[2] + vel_n[2] * dt;
  647. float P_copy[] = { 0.0095, -0.0000 , 0.0020, 0.0003, -0.0015, 0.0000 , 0.0002 , - 0.0401, - 0.0011,
  648. -0.0000 ,0.0094 ,-0.0002, 0.0020 ,-0.0000, -0.0005 , 0.0410, -0.0001 ,-0.0051
  649. ,0.0020 , -0.0002 , 0.0830 , 0.0115 , 0.0238 , 0.0006 ,0.0077 , 0.0420 , 0.0000
  650. ,0.0003 , 0.0020 , 0.0115 , 0.6790 , 0.0047 , 0.0009 , 0.1350 , 0.0059 , -0.0015
  651. , -0.0015 , -0.0000 ,0.0238 , 0.0047 , 0.6851 , 0.0012 , 0.0023 , 0.1462 , 0.0006
  652. ,0.0000 , -0.0005 , 0.0006 , 0.0009 , 0.0012 , 0.5172 ,-0.0027 ,-0.0004 , 0.0850
  653. ,0.0002 , 0.0410 , 0.0077 , 0.1350 , 0.0023, -0.0027 , 0.3347 , 0.0040, -0.0270
  654. , -0.0401, -0.0001 , 0.0420 , 0.0059 , 0.1462 , -0.0004 , 0.0040 , 0.3562 , 0.0046
  655. , -0.0011 ,-0.0051 , 0.0000, -0.0015 , 0.0006 , 0.0850 ,-0.0270 , 0.0046 , 0.0384 };
  656. for (int i = 0; i < 81; i++)
  657. {
  658. if (i % 9 == 0)
  659. printf("\n");
  660. printf("%6.8f ", P_copy[i]);
  661. P_copy[i] /= 10000;
  662. }
  663. printf("\n");
  664. Kalfman_gain(P_copy, Temporary_array1, Temporary_array2, K);
  665. for (int i = 0; i < 27; i++)
  666. {
  667. if (i % 3 == 0)
  668. printf("\n");
  669. printf("%6.4f ", K[i]);
  670. }
  671. //inv
  672. return 0;
  673. }
  674. */