detect_step_by_mag.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. #include "detect_step_by_mag.h"
  2. #include "math.h"
  3. #include "stdlib.h"
  4. #include "nrf_delay.h"
  5. uint16_t mag_sqrt =0;
  6. //static int16_t ShoeTouchFlag=1;
  7. int16_t Get_ShoeTouchFlag(void)
  8. {
  9. return ShoeTouchFlag;
  10. }
  11. //static int16_t Rcounter=0;
  12. int16_t Get_Rcounter(void)
  13. {
  14. return Rcounter;
  15. }
  16. static int16_t Tcounter=0;
  17. int16_t Get_Tcounter(void)
  18. {
  19. return Tcounter;
  20. }
  21. //static int16_t FKEY=0;
  22. //static int16_t BKEY=0;
  23. int16_t Get_FKEY(void)
  24. {
  25. return FKEY;
  26. }
  27. int16_t Get_BKEY(void)
  28. {
  29. return BKEY;
  30. }
  31. static int RealFrontLiftPoint;
  32. static int RealBackLiftPoint;
  33. int32_t Get_RealFrontLiftPoint(void)
  34. {
  35. return RealFrontLiftPoint;
  36. }
  37. int32_t Get_RealBackLiftPoint(void)
  38. {
  39. return RealBackLiftPoint;
  40. }
  41. uint8_t RealTimeStep(int16_t front[3], int16_t back[3], int16_t acc[3])
  42. {
  43. //static int FrontLiftPoint;
  44. //static int FrontDropPoint;
  45. //static int BackLiftPoint;
  46. //static int BackDropPoint;
  47. static int32_t SD;
  48. //static int16_t Rcounter;
  49. int32_t mag_temp_front[3];
  50. int32_t mag_temp_back[3];
  51. static int16_t accZ_buf[4];
  52. //static uint8_t acc_index = 0;
  53. static int mag_buf_front[3];
  54. static int mag_buf_back[3];
  55. //static uint8_t mag_index_front = 0;
  56. //static uint8_t mag_index_back = 0;
  57. int32_t mag_sqrt_front =0;
  58. int32_t mag_sqrt_back =0;
  59. //static int calculate_flag = 0;
  60. int16_t step=0;
  61. float MV;
  62. float D;
  63. //static int16_t Ucounter=0;//离地计时器
  64. //SEGGER_RTT_printf(0,"Enter RealTimeStep!\n");
  65. Tcounter++;
  66. for(int i = 0; i < 3; i ++)
  67. {
  68. mag_temp_front[i] = (int32_t) (front[i]);
  69. }
  70. mag_sqrt_front = abs(mag_temp_front[2]);
  71. for(int i = 0; i < 3; i ++)
  72. {
  73. mag_temp_back[i] = (int32_t) (back[i]);
  74. }
  75. mag_sqrt_back = abs(mag_temp_back[2]);
  76. /*读入磁力计数据*/
  77. if(mag_index_front >= 3)
  78. {
  79. mag_buf_front[0] = mag_buf_front[1];
  80. mag_buf_front[1] = mag_buf_front[2];
  81. mag_index_front = 2;
  82. calculate_flag = 1;
  83. }
  84. mag_buf_front[mag_index_front++] = mag_sqrt_front;//前脚掌数据
  85. if(mag_index_back >= 3)
  86. {
  87. mag_buf_back[0] = mag_buf_back[1];
  88. mag_buf_back[1] = mag_buf_back[2];
  89. mag_index_back = 2;
  90. calculate_flag = 1;
  91. }
  92. mag_buf_back[mag_index_back++] = mag_sqrt_back;//后脚掌数据
  93. /*读入xyZ轴加速度数据*/
  94. if(acc_index >= 3)
  95. {
  96. accZ_buf[0] = accZ_buf[1];
  97. accZ_buf[1] = accZ_buf[2];
  98. acc_index = 2;
  99. calculate_flag = 1;
  100. }
  101. accZ_buf[acc_index++] = -acc[2];
  102. if(calculate_flag==1)
  103. {
  104. SEGGER_RTT_printf(0,"mag_front3==:%d...\n",mag_buf_front[2]);
  105. SEGGER_RTT_printf(0,"mag_back3==:%d...\n",mag_buf_back[2]);
  106. SEGGER_RTT_printf(0,"FrontLiftPoint==:%d...\n",FrontLiftPoint);
  107. SEGGER_RTT_printf(0,"BackLiftPoint==:%d...\n",BackLiftPoint);
  108. /*不断更新前后脚掌磁力计的上升起始点或下降起始点*/
  109. if(mag_buf_front[2] - mag_buf_front[1]>=0)
  110. {
  111. if(FKEY==0)
  112. {
  113. FrontDropPoint = mag_buf_front[2];
  114. }
  115. else
  116. {
  117. if(mag_buf_front[2]>FrontDropPoint)
  118. {
  119. FrontDropPoint = mag_buf_front[2];
  120. }
  121. }
  122. }
  123. else
  124. {
  125. if(FKEY==0)//FKEY为前脚波形状态变量,1代表波形进行中,0代表波形结束。该语句意思是前脚掌磁力计不处于波形进行阶段时,如常更新上升起点。
  126. {
  127. FrontLiftPoint = mag_buf_front[2];
  128. }
  129. else
  130. {
  131. ;//当波形进行中,不改变初始上升起点,有助于过滤杂波。
  132. }
  133. }
  134. if(mag_buf_back[2] - mag_buf_back[1]>=0)
  135. {
  136. if(BKEY==0)
  137. {
  138. BackDropPoint = mag_buf_back[2];
  139. }
  140. else
  141. {
  142. if(mag_buf_back[2]>BackDropPoint)
  143. {
  144. BackDropPoint = mag_buf_back[2];
  145. }
  146. }
  147. }
  148. else
  149. {
  150. if(BKEY==0)//BKEY为后脚波形状态变量,1代表波形进行中,0代表波形结束。该语句意思是后脚掌磁力计不处于波形进行阶段时,如常更新上升起点
  151. {
  152. BackLiftPoint = mag_buf_back[2];
  153. }
  154. else
  155. {
  156. ;
  157. }
  158. }
  159. /*判断前后脚掌的状态*/
  160. if(mag_buf_front[2] - FrontLiftPoint>2200)
  161. {
  162. FKEY = 1;
  163. if(mag_buf_front[2] - FrontLiftPoint>FrontLiftDistance)
  164. {
  165. FrontLiftDistance = mag_buf_front[2] - FrontLiftPoint;
  166. }
  167. }
  168. if(mag_buf_back[2] - BackLiftPoint>2200)
  169. {
  170. BKEY = 1;
  171. if(mag_buf_back[2] - BackLiftPoint>BackLiftDistance)
  172. {
  173. BackLiftDistance = mag_buf_back[2] - BackLiftPoint;
  174. }
  175. }
  176. /*判断是否满足FKEY=0和BKEY=0,即是否满足一个升降波形*/
  177. if((mag_buf_front[2] - FrontLiftPoint<=1500)||(FrontDropPoint-mag_buf_front[2]>0.45*FrontLiftDistance)) //当磁力计回降到小于上升起点+1000的数值时,FKEY归零,预示前脚波形结束。
  178. //if(mag_buf_front[2] - FrontLiftPoint<=1500)
  179. {
  180. FKEY=0;
  181. FrontLiftDistance = 2200;
  182. }
  183. if((mag_buf_back[2] - BackLiftPoint<=1500)||(BackDropPoint-mag_buf_back[2]>0.45*BackLiftDistance))//当磁力计回降到小于上升起点+1000的数值时,BKEY归零,预示后脚波形结束。
  184. //if(mag_buf_back[2] - BackLiftPoint<=1500)
  185. {
  186. BKEY=0;
  187. BackLiftDistance = 2200;
  188. }
  189. /*跳出死循环*/
  190. if(FrontLiftPoint==0) //当磁力计回降到小于上升起点+1000的数值时,FKEY归零,预示前脚波形结束。
  191. {
  192. FKEY=0;
  193. }
  194. if(BackLiftPoint==0)//当磁力计回降到小于上升起点+1000的数值时,BKEY归零,预示后脚波形结束。
  195. {
  196. BKEY=0;
  197. }
  198. /*判断鞋子触地或离地*/
  199. if(ShoeTouchFlag==0)
  200. {
  201. if(Ucounter<300)
  202. {
  203. Ucounter++;
  204. }
  205. Rcounter=0;
  206. if(((FKEY==1)||(BKEY==1))&&(Ucounter>=6))
  207. {
  208. step=1;
  209. ShoeTouchFlag=1;
  210. SEGGER_RTT_printf(0,"You have one step!\n");
  211. }
  212. else
  213. {
  214. step=0;
  215. ShoeTouchFlag=0;
  216. }
  217. }
  218. else
  219. {
  220. step = 0;
  221. if(Rcounter<300)
  222. {
  223. Rcounter++;
  224. }
  225. Ucounter=0;
  226. if((Rcounter>=6)&&(FKEY==0)&&((abs(accZ_buf[0]-2000)>250)||(abs(accZ_buf[1]-2000)>250)||(abs(accZ_buf[2]-2000)>250))&&(BKEY==0))
  227. {
  228. ShoeTouchFlag=0;
  229. }
  230. else
  231. {
  232. ShoeTouchFlag=1;
  233. }
  234. }
  235. SEGGER_RTT_printf(0,"Rcounter==:%d...\n",Rcounter);
  236. /*计算加速度的方差*/
  237. /*
  238. MV = (accZ_buf[0]+accZ_buf[1]+accZ_buf[2])/3;
  239. D=0;
  240. for(int i = 0; i < 3; i ++)
  241. {
  242. D = D + (accZ_buf[i]-MV)*(accZ_buf[i]-MV);
  243. }
  244. D = D*0.33333333;
  245. SD = sqrt((float)D);
  246. */
  247. }
  248. else
  249. {
  250. step=0;
  251. FrontLiftPoint = mag_buf_front[2];
  252. FrontDropPoint = mag_buf_front[2];
  253. BackLiftPoint = mag_buf_back[2];
  254. BackDropPoint = mag_buf_back[2];
  255. SEGGER_RTT_printf(0,"Just Enter The Game! FrontLiftPoint==:%d...\n",FrontLiftPoint);
  256. SEGGER_RTT_printf(0,"Just Enter The Game! BackLiftPoint==:%d...\n",BackLiftPoint);
  257. }
  258. RealFrontLiftPoint = FrontLiftPoint;
  259. RealBackLiftPoint = BackLiftPoint;
  260. return step;
  261. }
  262. void ClearRealTimeStep()
  263. {
  264. FrontLiftPoint=30000;
  265. FrontDropPoint=30000;
  266. BackLiftPoint=30000;
  267. BackDropPoint=30000;
  268. calculate_flag=0;
  269. Ucounter=0;
  270. ShoeTouchFlag=1;
  271. Rcounter=0;
  272. FKEY=0;
  273. BKEY=0;
  274. acc_index = 0;
  275. mag_index_front = 0;
  276. mag_index_back = 0;
  277. FrontLiftDistance = 2200;
  278. BackLiftDistance = 2200;
  279. Lock = 0;
  280. }
  281. uint8_t detect_step_by_mag(int16_t *mag, int16_t acc_z)
  282. {
  283. static uint8_t up_flag = 0;
  284. int32_t mag_temp[3];
  285. static int16_t accZ_buf[3];
  286. static uint8_t acc_index = 0;
  287. //static uint16_t mag_buf[3];
  288. static int mag_buf[3];
  289. static uint8_t mag_index = 0;
  290. int step;
  291. int calculate_flag = 0;
  292. static int16_t FrontLiftPoint;
  293. static int16_t FrontDropPoint;
  294. static int16_t FrontTouchFlag=0;
  295. static int16_t PreFrontTouchFlag=0;
  296. float MV;
  297. float D;
  298. static int32_t SD;
  299. static int16_t counter=0;
  300. /*
  301. static float K;
  302. static float L;
  303. static float a=0;
  304. static float v=0;
  305. static float s=0;
  306. K = 9.8*0.0001*0.0005;//单位分别为厘米和毫秒
  307. */
  308. //SEGGER_RTT_printf(0,"mag_sqrt==:%d...\n",1000);
  309. for(int i = 0; i < 3; i ++)
  310. {
  311. mag_temp[i] = (int32_t) (mag[i]);
  312. }
  313. //mag_sqrt = (uint16_t)(sqrt((float) (mag_temp[0] * mag_temp[0] + mag_temp[1] * mag_temp[1] + mag_temp[2] * mag_temp[2])));
  314. mag_sqrt = abs(mag_temp[2]);
  315. // SEGGER_RTT_printf(0,"mag_sqrt:%d...\n",mag_sqrt);
  316. /*读入磁力计数据*/
  317. if(mag_index >= 3)
  318. {
  319. mag_buf[0] = mag_buf[1];
  320. mag_buf[1] = mag_buf[2];
  321. mag_index = 2;
  322. calculate_flag = 1;
  323. }
  324. mag_buf[mag_index++] = mag_sqrt;
  325. /*读入xyZ轴加速度数据*/
  326. if(acc_index >= 3)
  327. {
  328. accZ_buf[0] = accZ_buf[1];
  329. accZ_buf[1] = accZ_buf[2];
  330. acc_index = 2;
  331. }
  332. accZ_buf[acc_index++] = -acc_z;
  333. /*开始计算*/
  334. if (calculate_flag == 1)
  335. {
  336. //static uint32_t time =0;
  337. /*
  338. if(TIME_GetTicks() - time >=1000){
  339. time = TIME_GetTicks();
  340. SEGGER_RTT_printf(0,"mag_front3==:%d...\n",mag_buf[2]);
  341. SEGGER_RTT_printf(0,"mag_front2==:%d...\n",mag_buf[1]);
  342. SEGGER_RTT_printf(0,"mag_front1==:%d...\n",mag_buf[0]);
  343. SEGGER_RTT_printf(0,"acc3==:%d...\n",accZ_buf[2]);
  344. SEGGER_RTT_printf(0,"acc2==:%d...\n",accZ_buf[1]);
  345. SEGGER_RTT_printf(0,"acc1==:%d...\n",accZ_buf[0]);
  346. SEGGER_RTT_printf(0,"f_mx=%d,f_my=%d,f_mz=%d,acc_z:%d\r\n",mag[0],mag[1],mag[2],acc_z);
  347. }
  348. */
  349. if(mag_buf[1] - mag_buf[0]>=0)
  350. {
  351. FrontDropPoint = mag_buf[1];
  352. }
  353. else
  354. {
  355. FrontLiftPoint = mag_buf[1];
  356. }
  357. /*判断前后脚掌的状态*/
  358. if(mag_buf[1] - FrontLiftPoint>2000)
  359. {
  360. FrontTouchFlag = 2;
  361. }
  362. else if(mag_buf[1] - FrontDropPoint<-1000)
  363. {
  364. FrontTouchFlag = 0;
  365. }
  366. else if((abs(mag_buf[1]-mag_buf[0])<500)&&(abs(mag_buf[1]-mag_buf[2])<500))
  367. {
  368. FrontTouchFlag = 1;
  369. }
  370. /*计算步数*/
  371. if (up_flag == 0)
  372. {
  373. if(((FrontTouchFlag==2)&&(PreFrontTouchFlag!=2))&&(SD>60))
  374. {
  375. step = 1;
  376. up_flag = 1;
  377. counter=0;
  378. //a=0;
  379. //v=0;
  380. //s=0;
  381. /*
  382. SEGGER_RTT_printf(0,"step==%d\n",step);
  383. SEGGER_RTT_printf(0,"mag_front3==:%d...\n",mag_buf[2]);
  384. SEGGER_RTT_printf(0,"mag_front2==:%d...\n",mag_buf[1]);
  385. SEGGER_RTT_printf(0,"mag_front1==:%d...\n",mag_buf[0]);
  386. SEGGER_RTT_printf(0,"acc3==:%d...\n",accZ_buf[2]);
  387. SEGGER_RTT_printf(0,"acc2==:%d...\n",accZ_buf[1]);
  388. SEGGER_RTT_printf(0,"acc1==:%d...\n",accZ_buf[0]);
  389. SEGGER_RTT_printf(0,"FrontLiftPoint==:%d...\n",FrontLiftPoint);
  390. SEGGER_RTT_printf(0,"FrontDropPoint==:%d...\n",FrontDropPoint);
  391. SEGGER_RTT_printf(0,"SD==:%d...\n",SD);
  392. */
  393. // static char string[50];
  394. // sprintf(string,"1 min=%f,mag_buf=%d\n",min,mag_buf[2]);
  395. // SEGGER_RTT_printf(0,"%s",string);
  396. // SEGGER_RTT_printf(0,"step==%d\n",step);
  397. // nrf_delay_ms(1000);
  398. // while(1);
  399. }
  400. else
  401. {
  402. step = 0;
  403. up_flag = 0;
  404. // nrf_delay_ms(1000);
  405. // NVIC_SystemReset();
  406. }
  407. }
  408. else
  409. {
  410. step = 0;
  411. counter++;
  412. //a = (accZ_buf[2]-L)*K;
  413. //v = v + a*10;
  414. //s = s + v*10;
  415. if((FrontTouchFlag!=2)&&(((accZ_buf[0]<1800)&&(accZ_buf[1]<1800)&&(accZ_buf[2]<1800))||((accZ_buf[0]>2500)&&(accZ_buf[1]>2500)&&(accZ_buf[2]>2500)))&&(counter>=12))
  416. {
  417. up_flag=0;
  418. }
  419. }
  420. MV = (accZ_buf[0]+accZ_buf[1]+accZ_buf[2])/3;
  421. D=0;
  422. for(int i = 0; i < 3; i ++)
  423. {
  424. D = D + (accZ_buf[i]-MV)*(accZ_buf[i]-MV);
  425. }
  426. D = D/3;
  427. SD = sqrt((float)D);
  428. PreFrontTouchFlag = FrontTouchFlag;
  429. /*
  430. static char string[100];
  431. sprintf(string,"=====>time consuming:%02f us\r\n",(float)a);
  432. SEGGER_RTT_printf(0,"%s",string);
  433. SEGGER_RTT_printf(0,"acc3==:%d...\n",accZ_buf[2]);
  434. sprintf(string,"=====>time consuming:%02f us\r\n",(float)v);
  435. SEGGER_RTT_printf(0,"%s",string);
  436. */
  437. }
  438. else
  439. {
  440. step = 0;
  441. }
  442. return step;
  443. }