press_down_detect.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. #include "press_down_detect.h"
  2. #define down_thresh 2000
  3. #define BIG_WINDOW_SIZE 20
  4. int back_jump_stage = 0;
  5. int cancel_down = 0;
  6. int virus_flag = 0;
  7. float real_front_min_left = 50000;
  8. float real_front_min_right = 50000;
  9. void dual_foot_detect_up_trend(uint16_t* left_mag_up_min, uint16_t*left_up_count, uint16_t* left_mag_window,
  10. uint16_t* right_mag_up_min, uint16_t*right_up_count , uint16_t* right_mag_window, int window_size, int RESET_SIGNAL, int up_thesh)
  11. {
  12. uint16_t left_max_val = left_mag_window[window_size - 1];
  13. uint16_t left_min_val = left_mag_window[window_size - 1];
  14. int16_t left_max_index = window_size - 1;
  15. int16_t left_min_index = window_size - 1;
  16. uint16_t right_max_val = right_mag_window[window_size - 1];
  17. uint16_t right_min_val = right_mag_window[window_size - 1];
  18. int16_t right_max_index = window_size - 1;
  19. int16_t right_min_index = window_size - 1;
  20. for (int i = window_size -1; i > 1; i--)
  21. {
  22. if (left_mag_window[i] >= left_mag_window[i - 1] + up_thesh && left_mag_window[i] < left_mag_window[i - 1] + 1000
  23. && right_mag_window[i] >= right_mag_window[i - 1] + up_thesh && right_mag_window[i] < right_mag_window[i - 1] + 1000)
  24. {
  25. if (left_max_val < left_mag_window[i])
  26. {
  27. left_max_val = left_mag_window[i];
  28. left_max_index = i;
  29. }
  30. if (left_min_val > left_mag_window[i])
  31. {
  32. left_min_val = left_mag_window[i];
  33. left_min_index = i;
  34. }
  35. if (right_max_val < right_mag_window[i])
  36. {
  37. right_max_val = right_mag_window[i];
  38. right_max_index = i;
  39. }
  40. if (right_min_val > right_mag_window[i])
  41. {
  42. right_min_val = right_mag_window[i];
  43. right_min_index = i;
  44. }
  45. }
  46. else
  47. {
  48. break;
  49. }
  50. }
  51. if ((left_max_val - left_min_val > 100 && left_max_index > left_min_index && left_max_val - left_mag_window[window_size - 1] < 100) &&
  52. (right_max_val - right_min_val > 100 && right_max_index > right_min_index && right_max_val - right_mag_window[window_size - 1] < 100)
  53. &&((RESET_SIGNAL && right_mag_window[window_size - 1] < right_mag_window[window_size - 2] + 1000
  54. && left_mag_window[window_size - 1] < left_mag_window[window_size - 2] + 1000)
  55. || !RESET_SIGNAL))
  56. {
  57. if (*left_up_count > 0)
  58. {
  59. *left_up_count = *left_up_count + 1;
  60. if (left_min_val < *left_mag_up_min)
  61. {
  62. *left_mag_up_min = left_min_val;
  63. }
  64. }
  65. else
  66. {
  67. int index = left_min_index > right_min_index ? left_min_index : right_min_index;
  68. *left_mag_up_min = left_mag_window[index];
  69. for (int i = 0; i <= index; i++)
  70. {
  71. left_mag_window[i] = left_mag_window[index];
  72. }
  73. *left_up_count = window_size - index;
  74. }
  75. if (*right_up_count > 0)
  76. {
  77. *right_up_count = *right_up_count + 1;
  78. if (right_min_val < *right_mag_up_min)
  79. {
  80. *right_mag_up_min = right_min_val;
  81. }
  82. }
  83. else
  84. {
  85. int index = left_min_index > right_min_index ? left_min_index : right_min_index;
  86. *right_mag_up_min = right_mag_window[index];
  87. for (int i = 0; i <= index; i++)
  88. {
  89. right_mag_window[i] = right_mag_window[index];
  90. }
  91. *right_up_count = window_size - index;
  92. }
  93. }
  94. else
  95. {
  96. *left_mag_up_min = 40000;
  97. *right_mag_up_min = 40000;
  98. *left_up_count = 0;
  99. *right_up_count = 0;
  100. //重置窗口数据
  101. //if (RESET_SIGNAL &&((right_mag_window[window_size - 1] > right_mag_window[window_size - 2] + 1000)
  102. // || (left_mag_window[window_size - 1] > left_mag_window[window_size - 2] + 1000)))
  103. ///*if (RESET_SIGNAL && ((right_mag_window[window_size - 1] > right_mag_window[window_size - 2] + 1000)
  104. // || (left_mag_window[window_size - 1] > left_mag_window[window_size - 2] + 1000)))*/
  105. //{
  106. // memset(right_mag_window, right_mag_window[window_size - 1], window_size * sizeof(uint16_t));
  107. // memset(left_mag_window, left_mag_window[window_size - 1], window_size * sizeof(uint16_t));
  108. //}
  109. }
  110. }
  111. int avoid_down_during_change_road(float* left_mag_window, float* right_mag_window, int window_size)
  112. {
  113. float left_max_val = left_mag_window[0];
  114. float left_min_val = left_mag_window[0];
  115. int left_max_index = 0;
  116. int left_min_index = 0;
  117. float right_max_val = right_mag_window[0];
  118. float right_min_val = right_mag_window[0];
  119. int right_max_index = 0;
  120. int right_min_index = 0;
  121. for (int i = 1; i < window_size; i++)
  122. {
  123. if (left_max_val < left_mag_window[i])
  124. {
  125. left_max_val = left_mag_window[i];
  126. left_max_index = i;
  127. }
  128. if (left_min_val > left_mag_window[i])
  129. {
  130. left_min_val = left_mag_window[i];
  131. left_min_index = i;
  132. }
  133. if (right_max_val < right_mag_window[i])
  134. {
  135. right_max_val = right_mag_window[i];
  136. right_max_index = i;
  137. }
  138. if (right_min_val > right_mag_window[i])
  139. {
  140. right_min_val = right_mag_window[i];
  141. right_min_index = i;
  142. }
  143. }
  144. if (left_max_index > left_min_index && right_max_index < right_min_index
  145. && left_max_val - left_min_val > 2000 && right_max_val - right_min_val > 2000)
  146. {
  147. return 1;
  148. }
  149. if (left_max_index < left_min_index && right_max_index > right_min_index
  150. && left_max_val - left_min_val > 2000 && right_max_val - right_min_val > 2000)
  151. {
  152. return 1;
  153. }
  154. return 0;
  155. }
  156. int avoid_down_during_change_road_by_acc(int16_t* left_acc_window, int16_t* right_acc_window, int window_size, int threshold)
  157. {
  158. int16_t left_max_val = left_acc_window[window_size - 1];
  159. int16_t left_min_val = left_acc_window[window_size - 1];
  160. int16_t right_max_val = right_acc_window[window_size - 1];
  161. int16_t right_min_val = right_acc_window[window_size - 1];
  162. for (int i = BIG_WINDOW_SIZE - 1; i >= BIG_WINDOW_SIZE - window_size; i--)
  163. {
  164. if (left_max_val < left_acc_window[i])
  165. {
  166. left_max_val = left_acc_window[i];
  167. }
  168. if (left_min_val > left_acc_window[i])
  169. {
  170. left_min_val = left_acc_window[i];
  171. }
  172. if (right_max_val < right_acc_window[i])
  173. {
  174. right_max_val = right_acc_window[i];
  175. }
  176. if (right_min_val > right_acc_window[i])
  177. {
  178. right_min_val = right_acc_window[i];
  179. }
  180. }
  181. //if (left_max_val > left_min_val + 0.3f || right_max_val > right_min_val + 0.3f)
  182. if (left_max_val > left_min_val + threshold || right_max_val > right_min_val + threshold) // 0.1
  183. {
  184. return 1;
  185. }
  186. return 0;
  187. }
  188. int press_down_detect_new(int index, uint16_t front_mag_left, uint16_t back_mag_left,
  189. uint16_t front_mag_right, uint16_t back_mag_right, int16_t left_zupt, int16_t right_zupt,
  190. int16_t left_acc_x, int16_t left_acc_y, int16_t left_acc_z,
  191. int16_t right_acc_x, int16_t right_acc_y, int16_t right_acc_z,
  192. int16_t* front_down, int16_t* back_down)
  193. {
  194. static uint16_t front_mag_left_big_buff[BIG_WINDOW_SIZE];
  195. static uint16_t front_mag_right_big_buff[BIG_WINDOW_SIZE];
  196. static uint16_t back_mag_left_big_buff[BIG_WINDOW_SIZE];
  197. static uint16_t back_mag_right_big_buff[BIG_WINDOW_SIZE];
  198. static int16_t left_acc_z_big_buff[BIG_WINDOW_SIZE];
  199. static int16_t right_acc_z_big_buff[BIG_WINDOW_SIZE];
  200. static uint16_t left_front_up_min = 40000;
  201. static uint16_t left_back_up_min = 40000;
  202. static uint16_t right_front_up_min = 40000;
  203. static uint16_t right_back_up_min = 40000;
  204. static uint16_t left_front_up_count = 0;
  205. static uint16_t right_front_up_count = 0;
  206. static uint16_t left_back_up_count = 0;
  207. static uint16_t right_back_up_count = 0;
  208. memcpy(front_mag_left_big_buff, front_mag_left_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));
  209. memcpy(front_mag_right_big_buff, front_mag_right_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));
  210. memcpy(back_mag_left_big_buff, back_mag_left_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));
  211. memcpy(back_mag_right_big_buff, back_mag_right_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(uint16_t));
  212. memcpy(left_acc_z_big_buff, left_acc_z_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(int16_t));
  213. memcpy(right_acc_z_big_buff, right_acc_z_big_buff + 1, (BIG_WINDOW_SIZE - 1) * sizeof(int16_t));
  214. front_mag_left_big_buff[(BIG_WINDOW_SIZE - 1)] = front_mag_left;
  215. front_mag_right_big_buff[(BIG_WINDOW_SIZE - 1)] = front_mag_right;
  216. back_mag_left_big_buff[(BIG_WINDOW_SIZE - 1)] = back_mag_left;
  217. back_mag_right_big_buff[(BIG_WINDOW_SIZE - 1)] = back_mag_right;
  218. left_acc_z_big_buff[(BIG_WINDOW_SIZE - 1)] = left_acc_z;
  219. right_acc_z_big_buff[(BIG_WINDOW_SIZE - 1)] = right_acc_z;
  220. dual_foot_detect_up_trend(&left_front_up_min, &left_front_up_count, front_mag_left_big_buff,
  221. &right_front_up_min, &right_front_up_count, front_mag_right_big_buff, BIG_WINDOW_SIZE, 1, -50);
  222. dual_foot_detect_up_trend(&left_back_up_min, &left_back_up_count, back_mag_left_big_buff,
  223. &right_back_up_min, &right_back_up_count, back_mag_right_big_buff, BIG_WINDOW_SIZE, 0, -100);
  224. //if (front_mag_left - left_front_up_min > 2000 && front_mag_right - right_front_up_min > 2000)
  225. if (front_mag_left - left_front_up_min > 2000 && front_mag_right - right_front_up_min > 2000
  226. && front_mag_left_big_buff[BIG_WINDOW_SIZE - 1] > front_mag_left_big_buff[BIG_WINDOW_SIZE - 2]
  227. && front_mag_right_big_buff[BIG_WINDOW_SIZE - 1] > front_mag_right_big_buff[BIG_WINDOW_SIZE - 2]
  228. && left_front_up_count < 30 && right_front_up_count < 30)
  229. {
  230. *front_down = 1;
  231. //printf( "left_front_up_count: %d , right_front_up_count : %d \n" , left_front_up_count , right_front_up_count);
  232. }
  233. //if (back_mag_left - left_back_up_min > 3000 && back_mag_right - right_back_up_min > 3000)
  234. if (((back_mag_left - left_back_up_min > 2000 && back_mag_right - right_back_up_min > 2000 && left_back_up_min > 8000 && right_back_up_min > 8000)
  235. || (back_mag_left - left_back_up_min > 3000 && back_mag_right - right_back_up_min > 3000))
  236. && back_mag_left_big_buff[BIG_WINDOW_SIZE - 1] > back_mag_left_big_buff[BIG_WINDOW_SIZE - 2]
  237. && back_mag_right_big_buff[BIG_WINDOW_SIZE - 1] > back_mag_right_big_buff[BIG_WINDOW_SIZE - 2])
  238. {
  239. *back_down = 1;
  240. //printf("left_front_up_count: %d , right_front_up_count : %d \n", left_front_up_count , right_front_up_count);
  241. }
  242. if (avoid_down_during_change_road_by_acc(left_acc_z_big_buff, right_acc_z_big_buff, BIG_WINDOW_SIZE/2, 250))
  243. {
  244. if (*front_down == 1)
  245. {
  246. //printf("delete front_down when change road \n");
  247. }
  248. if (*back_down == 1)
  249. {
  250. //printf("delete back_down when change road \n");
  251. }
  252. *front_down = 0;
  253. *back_down = 0;
  254. }
  255. // if (!avoid_down_during_change_road_by_acc(left_acc_z_big_buff, right_acc_z_big_buff, BIG_WINDOW_SIZE/2, 100))
  256. // {
  257. // /*if (front_mag_left - left_front_up_min > 500 && front_mag_right - right_front_up_min > 500)
  258. // {
  259. // *front_down = 1;
  260. // }*/
  261. // if (back_mag_left - left_back_up_min > 1000 && back_mag_right - right_back_up_min > 1000)
  262. // {
  263. // *back_down = 1;
  264. // }
  265. // }
  266. return 0;
  267. }
  268. short pos_jump_detect(int* h_pos, int* s_pos, int left_zupt, int right_zupt)
  269. {
  270. static int last_h_z;
  271. static int last_s_z;
  272. static int left_up;
  273. static int right_up;
  274. static int left_up_count;
  275. static int right_up_count;
  276. static int left_zupt_count;
  277. static int right_zupt_count;
  278. if (left_zupt)
  279. {
  280. left_zupt_count = 10;
  281. }
  282. else
  283. {
  284. left_zupt_count--;
  285. }
  286. if (right_zupt)
  287. {
  288. right_zupt_count = 10;
  289. }
  290. else
  291. {
  292. right_zupt_count--;
  293. }
  294. if (h_pos[2] - last_h_z > 0 && h_pos[2] > 0)
  295. {
  296. left_up = 1;
  297. }
  298. else if ((h_pos[2] - last_h_z < 0) || h_pos[2] <= 0)
  299. {
  300. left_up = -1;
  301. }
  302. if (left_up == 1)
  303. {
  304. left_up_count++;
  305. }
  306. else
  307. {
  308. left_up_count = 0;
  309. }
  310. if (s_pos[2] - last_s_z > 0 && s_pos[2] > 0)
  311. {
  312. right_up = 1;
  313. }
  314. else if ((s_pos[2] - last_s_z < 0) || s_pos[2] <= 0)
  315. {
  316. right_up = -1;
  317. }
  318. if (right_up == 1)
  319. {
  320. right_up_count++;
  321. }
  322. else
  323. {
  324. right_up_count = 0;
  325. }
  326. last_h_z = h_pos[2];
  327. last_s_z = s_pos[2];
  328. if (left_up == 1 && right_up == 1 && right_up_count < 15 && left_up_count < 15
  329. && right_zupt_count > 0 && left_zupt_count > 0 &&
  330. ((right_up_count > 2 && left_up_count > 2) ||
  331. (right_up_count > 0 && left_up_count > 0 && h_pos[2] > 15 && s_pos[2] > 15)))
  332. {
  333. return 1;
  334. }
  335. return 0;
  336. }
  337. //由于仅靠IMU来探测触底了,高度估计得不太对,所以用加速度来算起跳动作
  338. void max_min_window(float* data, int length, float* max_val, int* max_index, float* min_val, int* min_index)
  339. {
  340. *max_val = data[0];
  341. *max_index = 0;
  342. *min_val = data[0];
  343. *min_index = 0;
  344. for (int i = 0; i < length; i++)
  345. {
  346. if (*max_val < data[i])
  347. {
  348. *max_val = data[i];
  349. *max_index = i;
  350. }
  351. if (*min_val > data[i])
  352. {
  353. *min_val = data[i];
  354. *min_index = i;
  355. }
  356. }
  357. }
  358. int avoid_error_jump_by_press(float* mag_window, int window_size)
  359. {
  360. float min_val = mag_window[0];
  361. float max_val = mag_window[0];
  362. int max_index = 0;
  363. for (int i = 0; i < window_size; i++)
  364. {
  365. if (min_val > mag_window[0])
  366. {
  367. min_val = mag_window[0];
  368. }
  369. if (max_val < mag_window[0])
  370. {
  371. max_val = mag_window[0];
  372. max_index = i;
  373. }
  374. }
  375. if (max_val - min_val > 2000.f && max_index == window_size - 1)
  376. {
  377. return 1;
  378. }
  379. return 0;
  380. }
  381. short press_jump_detect(float left_acc_z, float right_acc_z, int left_zupt, int right_zupt, int left_front_press, int right_front_press)
  382. {
  383. static float right_data_z_buff[10];
  384. static float left_data_z_buff[10];
  385. static float left_front_mag_buff[10];
  386. static float right_front_mag_buff[10];
  387. static int press_wait;
  388. static int acc_wait;
  389. /*
  390. * 存储数据
  391. */
  392. memcpy(right_data_z_buff, right_data_z_buff + 1, 9 * sizeof(float));
  393. memcpy(left_data_z_buff, left_data_z_buff + 1, 9 * sizeof(float));
  394. right_data_z_buff[9] = right_acc_z;
  395. left_data_z_buff[9] = left_acc_z;
  396. memcpy(left_front_mag_buff, left_front_mag_buff + 1, 9 * sizeof(float));
  397. memcpy(right_front_mag_buff, right_front_mag_buff + 1, 9 * sizeof(float));
  398. left_front_mag_buff[9] = left_front_press;
  399. right_front_mag_buff[9] = right_front_press;
  400. float max_val_right_mag, min_val_right_mag, max_val_left_mag, min_val_left_mag;
  401. int max_index_right_mag, min_index_right_mag, max_index_left_mag, min_index_left_mag;
  402. max_min_window(right_front_mag_buff, 10, &max_val_right_mag, &max_index_right_mag, &min_val_right_mag, &min_index_right_mag);
  403. max_min_window(left_front_mag_buff, 10, &max_val_left_mag, &max_index_left_mag, &min_val_left_mag, &min_index_left_mag);
  404. if (max_val_right_mag > right_front_press + 3000.f && max_val_left_mag > left_front_press + 3000.f)
  405. {
  406. int start_index = max_index_left_mag > max_index_right_mag ? max_index_left_mag : max_index_right_mag;
  407. int down_flag = 1;
  408. // 遍历双脚持续下降的所用
  409. for (int i = start_index + 1; i < 10; i++)
  410. {
  411. if (right_front_mag_buff[i - 1] - right_front_mag_buff[i] < 100.f)
  412. {
  413. down_flag = 0;
  414. break;
  415. }
  416. if (left_front_mag_buff[i - 1] - left_front_mag_buff[i] < 100.f)
  417. {
  418. down_flag = 0;
  419. break;
  420. }
  421. }
  422. if (down_flag == 1)
  423. {
  424. press_wait = 10;
  425. }
  426. }
  427. /*
  428. * 加速变化估计
  429. */
  430. float max_val_right, min_val_right, max_val_left, min_val_left;
  431. int max_index_right, min_index_right, max_index_left, min_index_left;
  432. max_min_window(right_data_z_buff, 10, &max_val_right, &max_index_right, &min_val_right, &min_index_right);
  433. max_min_window(left_data_z_buff, 10, &max_val_left, &max_index_left, &min_val_left, &min_index_left);
  434. /*
  435. * 1.0f的阈值轻轻跳就可以达到了,现在改为1.3f的阈值
  436. */
  437. int jump = 0;
  438. if (max_index_right < min_index_right && max_index_left < min_index_left
  439. && max_val_right - min_val_right > 0.8f && max_val_left - min_val_left > 0.8f
  440. && (left_zupt == 0 && right_zupt == 0))
  441. {
  442. acc_wait = 10;
  443. }
  444. if ( acc_wait > 0 && press_wait > 0)
  445. {
  446. jump = 1;
  447. }
  448. if (acc_wait > 0)
  449. {
  450. acc_wait--;
  451. }
  452. if (press_wait > 0)
  453. {
  454. press_wait--;
  455. }
  456. //if (avoid_error_jump_by_press(left_front_mag_buff, 10))
  457. //{
  458. // jump = 0;
  459. //}
  460. //if (avoid_error_jump_by_press(right_front_mag_buff, 10))
  461. //{
  462. // jump = 0;
  463. //}
  464. return jump;
  465. }
  466. int att_jump_detect(float left_pitch, float right_pitch, int left_zupt, int right_zupt)
  467. {
  468. static int num;
  469. static float left_pitch_window[8];
  470. static float right_pitch_window[8];
  471. //用俯仰角判断好了, 现在的IMU方向 下标1为俯仰角
  472. memcpy(left_pitch_window, left_pitch_window + 1, 7 * sizeof(float));
  473. memcpy(right_pitch_window, right_pitch_window + 1, 7 * sizeof(float));
  474. left_pitch_window[7] = left_pitch;
  475. right_pitch_window[7] = right_pitch;
  476. num++;
  477. if (num < 8)
  478. {
  479. return 0;
  480. }
  481. else
  482. {
  483. num = 8;
  484. }
  485. //要求起跳要同步
  486. static int zupt_count = 0;
  487. if (left_zupt && right_zupt)
  488. {
  489. zupt_count = 21;
  490. }
  491. if (zupt_count > 0)
  492. {
  493. zupt_count--;
  494. }
  495. for (int i = 7; i > 1; i--)
  496. {
  497. if ((left_pitch_window[i] > left_pitch_window[i - 1] || left_pitch_window[i] > left_pitch_window[i - 2])
  498. && (right_pitch_window[i] > right_pitch_window[i - 1] || right_pitch_window[i] > right_pitch_window[i - 2]))
  499. {
  500. if ((left_pitch > left_pitch_window[i - 1] + 0.1f || left_pitch > left_pitch_window[i - 2] + 0.1f)
  501. && (right_pitch > right_pitch_window[i - 1] + 0.1f || right_pitch > right_pitch_window[i - 2] + 0.1f)
  502. && zupt_count > 0)
  503. {
  504. return 1;
  505. }
  506. }
  507. else
  508. {
  509. return 0;
  510. }
  511. }
  512. return 0;
  513. }