press_down_detect.c 14 KB

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