imu.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // 周涛 2023-02-08
  2. // 基于传感器参数计算位移
  3. #include "../../includes/includes.h"
  4. // 定义模块所需的全局变量
  5. static IMU_INIT_PARAM_T gImu_stInitParam = {0}; // 模块初始化参数
  6. uint8 *pgImu_byAccDataList = NULL; // 加速度数据队列(存储js模块注入的加速度)
  7. static flt32 gImu_afAccDataList[IMU_ACC_LIST_LEN] = {0}; // 加速度点列表
  8. static uint8 gImu_byGenerateIndex = 0; // 生产索引
  9. static uint8 gImu_byConsumeIndex = 0; // 消费索引
  10. static uint8 gImu_byRunFlag = 0; // 系统正常运行标识符,0:初始化,1:正常运行
  11. // 模块初始化
  12. void imu_init()
  13. {
  14. pgImu_byAccDataList = (uint8 *)malloc(IMU_ACC_LIST_SIZE); // 申请一片内存,用于存储js注入的加速度数据队列
  15. gImu_byRunFlag = 0; // 初始化状态
  16. memset(&gImu_stInitParam, 0, sizeof(IMU_INIT_PARAM_T));
  17. memset(&gImu_afAccDataList, 0, sizeof(flt32) * IMU_ACC_LIST_LEN);
  18. // 加速度噪声
  19. gImu_stInitParam.fNoiseX = -0.0047304;
  20. gImu_stInitParam.fNoiseY = 0.047326; // 0.057326
  21. gImu_stInitParam.fNoiseZ = -0.015313; //-0.984687
  22. // 选峰参数
  23. gImu_stInitParam.dwPeakPeakDistance = 35; // 35; // 峰间距
  24. gImu_stInitParam.dwPeakValueThres = 102; // 峰值门限
  25. printf("imu init ok \n");
  26. return;
  27. }
  28. // 释放内存
  29. void imu_free_memory()
  30. {
  31. if (!pgImu_byAccDataList)
  32. {
  33. free(pgImu_byAccDataList);
  34. pgImu_byAccDataList = NULL;
  35. }
  36. }
  37. // 查询加速度存储地址(exchange模块使用)
  38. int32 *imu_get_acc_address_exchange()
  39. {
  40. return (int32 *)pgImu_byAccDataList;
  41. }
  42. // 保存加速度(exchange模块使用)
  43. void imu_save_acc_list_exchange()
  44. {
  45. uint32 dwAccListLen = 0;
  46. // 获得数队列长度
  47. memcpy(&dwAccListLen, (uint32 *)pgImu_byAccDataList, 4);
  48. imu_save_acc_xyz(dwAccListLen);
  49. memset(pgImu_byAccDataList, 0, IMU_ACC_LIST_SIZE); // 清空数据缓存
  50. }
  51. // 保存加速度
  52. // fAccX:X轴加速度
  53. // fAccY:Y轴加速度
  54. // fAccZ:Z轴加速度
  55. // dwTimestamp:时间戳
  56. void imu_save_acc_xyz(uint32 dwAccListLen)
  57. {
  58. IMU_ACC_DATA_T *pstAccData = NULL;
  59. flt32 fAccX = 0;
  60. flt32 fAccY = 0;
  61. flt32 fAccZ = 0;
  62. flt32 fAccTotal = 0; // 三轴加速度之和
  63. // 加速度队列
  64. pstAccData = (IMU_ACC_DATA_T *)(pgImu_byAccDataList + 4);
  65. for (uint32 i = 0; i < dwAccListLen; i++)
  66. {
  67. fAccX = pstAccData->fAccX - gImu_stInitParam.fNoiseX;
  68. fAccY = pstAccData->fAccY - gImu_stInitParam.fNoiseY;
  69. fAccZ = pstAccData->fAccZ - gImu_stInitParam.fNoiseZ;
  70. fAccTotal = fAccX * fAccX + fAccY * fAccY + fAccZ * fAccZ;
  71. fAccTotal = sqrt(fAccTotal); // 合加速度
  72. gImu_afAccDataList[gImu_byGenerateIndex] = fAccTotal;
  73. pstAccData++;
  74. // 生产索引加1
  75. gImu_byGenerateIndex++;
  76. }
  77. // 运行标识符置位
  78. if (!gImu_byRunFlag)
  79. {
  80. if (gImu_byGenerateIndex > 60)
  81. {
  82. gImu_byRunFlag = 1;
  83. }
  84. }
  85. return;
  86. }
  87. // 计算位移(定位模块使用)
  88. // 返回值,0:失败,1:成功,静止,50:成功,移动
  89. uint32 imu_cal_distance_lct()
  90. {
  91. uint8 byMoveFlag = 0;
  92. if (!gImu_byRunFlag)
  93. {
  94. return 0;
  95. }
  96. // 计算位移
  97. byMoveFlag = imu_cal_distance();
  98. return byMoveFlag;
  99. }
  100. // 计算位移
  101. // 返回值,0:失败,1:成功,静止,50:成功,移动
  102. uint32 imu_cal_distance()
  103. {
  104. uint8 byResult = 0;
  105. flt32 afAccDataList[IMU_ACC_LIST_ONE_SECOND_LEN] = {0}; // 有效加速度点队列(1秒)
  106. uint8 byAccDataListLen = 0; // 有效加速度点队列长度
  107. uint8 byMoveFlag = 0;
  108. // 系统处于初始化阶段
  109. if (!gImu_byRunFlag)
  110. {
  111. return 0;
  112. }
  113. memset(afAccDataList, 0, sizeof(flt32) * IMU_ACC_LIST_ONE_SECOND_LEN);
  114. // 选择加速度
  115. byResult = imu_select_acc_xyz(afAccDataList, &byAccDataListLen);
  116. if (!byResult || byAccDataListLen <= 0)
  117. {
  118. return 0;
  119. }
  120. // 判断加速度是否超过移动门限值
  121. byResult = imu_check_max_acc(afAccDataList, byAccDataListLen, &byMoveFlag);
  122. if (!byResult)
  123. {
  124. return 0;
  125. }
  126. // 检查移动标识
  127. if (byMoveFlag)
  128. {
  129. return 50; // 成功,但移动
  130. }
  131. return 1; // 成功,但静止
  132. }
  133. // 选择加速度点集
  134. // pfValidAccDataList:有效加速度队列,返回参数
  135. // pfValidAccDataListLen:有效加速度队列长度,返回参数
  136. uint8 imu_select_acc_xyz(flt32 *pfValidAccDataList, uint8 *pfValidAccDataListLen)
  137. {
  138. flt32 *pfData = gImu_afAccDataList; // 加速度数据队列
  139. uint8 byCounter = 0; // 有效加速度计数器
  140. // 容错处理
  141. if (pfValidAccDataList == NULL || pfValidAccDataListLen == NULL)
  142. {
  143. return 0;
  144. }
  145. // 遍历队列,选择当前窗口内的加速度(全部)
  146. while (gImu_byConsumeIndex != gImu_byGenerateIndex)
  147. {
  148. pfValidAccDataList[byCounter] = pfData[gImu_byConsumeIndex];
  149. byCounter++;
  150. if (byCounter >= IMU_ACC_LIST_ONE_SECOND_LEN)
  151. {
  152. gImu_byConsumeIndex++;
  153. break;
  154. }
  155. gImu_byConsumeIndex++;
  156. }
  157. *pfValidAccDataListLen = byCounter;
  158. return 1;
  159. }
  160. // 检查加最大速度是否超过门限值
  161. // pfAccDataList:加速度队列
  162. // byListLen:加速度队列长度
  163. // pbyMoveFlag:移动标识符,1:移动,0:不移动
  164. uint8 imu_check_max_acc(flt32 *pfAccDataList, uint8 byListLen, uint8 *pbyMoveFlag)
  165. {
  166. flt32 fMaxValue = FLT_MIN;
  167. flt32 fThres = (flt32)gImu_stInitParam.dwPeakValueThres / 100; // 峰值门限
  168. if (pfAccDataList == NULL || byListLen <= 0 || pbyMoveFlag == NULL)
  169. {
  170. return 0;
  171. }
  172. // 查找加速度最大值
  173. for (uint8 i = 0; i < byListLen; i++)
  174. {
  175. if (pfAccDataList[i] > fMaxValue)
  176. {
  177. fMaxValue = pfAccDataList[i];
  178. }
  179. }
  180. // 判断加速度是否超过门限
  181. if (fMaxValue > fThres)
  182. {
  183. *pbyMoveFlag = 1; // 有移动
  184. }
  185. else
  186. {
  187. *pbyMoveFlag = 0; // 静止
  188. }
  189. return 1;
  190. }