jump-0.3.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /**
  2. * 跳判断相关脚本代码
  3. */
  4. function Event() {
  5. this.events = {};
  6. }
  7. Event.prototype.addEventListener = function (type, listener) {
  8. this.events[type] = this.events[type] || [];
  9. this.events[type].push(listener);
  10. };
  11. Event.prototype.trigger = function () {
  12. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  13. args[_key] = arguments[_key];
  14. }
  15. var type = args[0];
  16. var params = args.slice(1);
  17. if (!!this.events[type]) {
  18. // console.log("type:",type);
  19. this.events[type].forEach(function (listener) {
  20. try {
  21. listener.apply(null, params);
  22. } catch (e) {
  23. console.error(e);
  24. }
  25. });
  26. }
  27. };
  28. /**
  29. * 公共部分计算参数
  30. * 已时间为条件执行
  31. */
  32. var jumpOpts = {
  33. //是否上升的标志位
  34. isDirectionUp: false,
  35. //持续上升次数
  36. continueUpCount: 0,
  37. //上一点的持续上升的次数,为了记录波峰的上升次数
  38. continueUpFormerCount: 0,
  39. continueDownCount: 0,
  40. continueDownFormerCount: 0,
  41. //上一点的状态,上升还是下降
  42. lastStatus: false,
  43. //波峰值
  44. peakOfWave: 0,
  45. //波谷值
  46. valleyOfWave: 0,
  47. //检测到极快的波动的次数
  48. timeOfPeakCount: 0,
  49. //开始添加
  50. bUpdateTimeOfPeakCount: false,
  51. //开始更新的次数
  52. startCount: 0,
  53. //停止跳
  54. bStopJump: false,
  55. //上次传感器的值
  56. gravityOld: 0,
  57. bUpState: false,
  58. //开始时间
  59. startTime: 0,
  60. endTime: 0,
  61. startResultant: 0
  62. }
  63. var ActionJump = function ActionJump() {
  64. this.jumpOpts = jumpOpts;
  65. this.peakOfWaveMaxValue = 0;
  66. this.peakOfWaveMaxValueCount = 0;
  67. this.valleyOfWaveMinValue = 0;
  68. this.valleyOfWaveMinValueCount = 0;
  69. this.highestCount = 0;
  70. //记录当前传入的数据
  71. this.dataArray = [];
  72. //获取一个判断数组的数据,比如触发点前后取一定帧数
  73. //记录波形的个数,可重复添加
  74. this.tempDataArray = [];
  75. //记录一个加速计数组
  76. this.oriAccArray = [];
  77. //陀螺仪
  78. this.oriGyroYArray = [];
  79. this.event = new Event();
  80. this.frameCapacity = 10;
  81. this.frame = [];
  82. this.frameLength = 5;
  83. this.frameOffset = 0;
  84. for (var i = 0; i < this.frameCapacity; ++i) {
  85. var o = new Object();
  86. o.maxValue = 0;
  87. o.gyroValue = 0;
  88. o.resultant = 0;
  89. o.index = -1;
  90. o.acc = null;
  91. o.gyro = null;
  92. this.frame.push(o);
  93. }
  94. this.frameLog = [];
  95. this.LastMS = 0;
  96. this.LastTime = 0;
  97. this.xA = 0;
  98. this.yA = 0;
  99. this.zA = 0;
  100. }
  101. ActionJump.prototype.addEventListener = function (type, listener) {
  102. this.event.addEventListener(type, listener);
  103. };
  104. /**
  105. * 更新数据
  106. */
  107. ActionJump.prototype.updateJump = function () {
  108. let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  109. //使用三个轴的数据,计算重力轴的加速度。最后减去重力的加速度值
  110. /**
  111. * 纠正后使用的轴向
  112. * box["acc"] = {
  113. ax: -ay,
  114. ay: -ax,
  115. az: az
  116. };
  117. box["gyro"] = {
  118. gx: -gy,
  119. gy: -gx,
  120. gz: gz
  121. };
  122. */
  123. //********加速计********
  124. // let {
  125. // lAccX,
  126. // lAccY,
  127. // lAccZ
  128. // } = data.linearAcc;
  129. // let {
  130. // oAccX,
  131. // oAccY,
  132. // oAccZ
  133. // } = data.oriAcc;
  134. // let {
  135. // oGyroX,
  136. // oGyroY,
  137. // oGyroZ
  138. // } = data.oriGyro;
  139. // let {
  140. // bYAxis
  141. // } = data;
  142. // //oGyroX 在用的过程中方向相反,所以添加负号
  143. // let _tempAxisData = bYAxis ? -oGyroX : oGyroY; //新设备直接使用oGyroY
  144. // this.detectorNewStep(data.resultant, lAccX, lAccY, lAccZ, oAccX, oAccY, oAccZ, data.runIndex, _tempAxisData);
  145. // oAccZ
  146. // this.detectorNewStep(data.resultant, -lAccY, -lAccX, -lAccZ, -oAccY, -oAccX, -oAccZ, data.runIndex,
  147. // _tempAxisData);
  148. //********传感器数值********
  149. let { ax, ay, az } = data.acc;
  150. let { gx, gy, gz } = data.gyro;
  151. let { min, s, ms } = data;
  152. let msGap = ms - this.LastMS;
  153. if (msGap < 0) {
  154. msGap += 1000;
  155. }
  156. this.LastMS = ms;
  157. let _ax = data.acc.ax * 10;
  158. let _ay = data.acc.ay * 10;
  159. let _az = data.acc.az * 10;
  160. //低通滤波分离重力
  161. let curTime = new Date().getTime();
  162. let alpha = 1000 / (1000 + msGap); // 0.8;
  163. this.LastTime = curTime;
  164. this.xA = alpha * this.xA + (1 - alpha) * _ax;
  165. this.yA = alpha * this.yA + (1 - alpha) * _ay;
  166. this.zA = alpha * this.zA + (1 - alpha) * _az;
  167. //高通滤波获取线性速度
  168. let linear_acceleration_x = _ax - this.xA;
  169. let linear_acceleration_y = _ay - this.yA;
  170. let linear_acceleration_z = _az - this.zA;
  171. let _temp = {
  172. oriAcc: {
  173. oAccX: _ax,
  174. oAccY: _ay,
  175. oAccZ: _az
  176. },
  177. linearAcc: {
  178. lAccX: linear_acceleration_x,
  179. lAccY: linear_acceleration_y,
  180. lAccZ: linear_acceleration_z
  181. },
  182. gravityAcc: {
  183. gravityX: this.xA,
  184. gravityY: this.yA,
  185. gravityZ: this.zA
  186. },
  187. bLimitRebound: false,
  188. resultant: Math.sqrt(_ax * _ax
  189. + _ay * _ay + _az * _az),
  190. runIndex: data.BLEAccIndex,
  191. //陀螺仪
  192. oriGyro: {
  193. oGyroX: gx,
  194. oGyroY: gy,
  195. oGyroZ: gz
  196. },
  197. bYAxis: data.isY
  198. };
  199. this.detectorNewStep(_temp);
  200. };
  201. /*
  202. *计算跳逻辑
  203. */
  204. // ActionJump.prototype.detectorNewStep = function(resultant, linearX, linearY, linearZ, oriX, oriY, oriZ, _runIndex,
  205. // _oGyroY)
  206. ActionJump.prototype.detectorNewStep = function (data) {
  207. /**
  208. * 把數據返回
  209. */
  210. this.event.trigger('resultant', {
  211. type: "bUpdateDraw",
  212. data: data
  213. });
  214. let {
  215. oAccX,
  216. oAccY,
  217. oAccZ
  218. } = data.oriAcc;
  219. let {
  220. oGyroX,
  221. oGyroY,
  222. oGyroZ
  223. } = data.oriGyro;
  224. let resultant = data.resultant; //合加速度
  225. // 记录500个点
  226. // 如果超过了,去除第一个点,加入最后一个元素
  227. if (this.dataArray.length <= 500) {
  228. this.dataArray.push(data);
  229. } else {
  230. this.dataArray.shift();
  231. this.dataArray.push(data);
  232. }
  233. //判断resultant 一个阀值,简单的检测跳的动作触发幅度
  234. let limitResultant = 20;
  235. if (resultant > limitResultant && !this.jumpOpts.bUpState) {
  236. let currTime = new Date().getTime(); //当前时间
  237. // 清空触发的数值
  238. this.tempDataArray = [];
  239. let diffTime = currTime - this.jumpOpts.endTime; //当前时间减最初时间,得到当前时间差
  240. if (Math.abs(diffTime) < 100) {
  241. //前一帧到后一帧的间隔忽略 150 / 6 约25帧落地波动
  242. return;
  243. }
  244. this.jumpOpts.bUpState = true;
  245. //第一次触发的时间。记录开始时间
  246. this.jumpOpts.startTime = new Date().getTime();
  247. this.event.trigger('resultant', {
  248. type: "log",
  249. logType: 'normal',
  250. data: "开始时间:" + this.jumpOpts.startTime + ",resultant:" + resultant
  251. });
  252. //取触发前一定帧数
  253. let len = this.dataArray.length;
  254. let total = 5;//取倒数5帧
  255. if (len != 0) {
  256. let newArr = [];
  257. //长度超过
  258. let limit = len - total;
  259. if (limit > 0) {
  260. for (let i = len; i > limit; i--) {
  261. newArr.push(this.dataArray[i - 1]);
  262. }
  263. this.tempDataArray.push(newArr);
  264. } else {
  265. //直接添加数据
  266. this.tempDataArray.push(this.dataArray.slice());
  267. }
  268. }
  269. console.log("start bUpState");
  270. }
  271. if (this.jumpOpts.bUpState) {
  272. //取一个时间段为截取时间,计算时间段里面的数据
  273. let currTime = new Date().getTime(); //当前时间
  274. let diffTime = currTime - this.jumpOpts.startTime; //当前时间减最初时间,得到当前时间差
  275. if (diffTime > 400) {
  276. // console.log("diffTime:", diffTime);
  277. //计算已出发的数据
  278. // console.log(this.tempDataArray);
  279. for (let i = 0; i < this.tempDataArray.length; i++) {
  280. // 计算数据
  281. this.resetAll();
  282. let _frameMaxValue = 0,
  283. _frameMinValue = 0,
  284. _frameGyroValue = 0,
  285. _frameGyroMinValue = 0;
  286. for (let j = 0; j < this.tempDataArray[i].length; j++) {
  287. let _data = this.tempDataArray[i][j];
  288. if (j < 30) { //取前面30帧判断
  289. let _judgmentValue = _data.linearAcc.lAccZ //_data.oriAcc.oAccZ; //判断左右方向用z
  290. if (_judgmentValue > 1) {
  291. _frameMaxValue += _judgmentValue;
  292. if (_judgmentValue > this.peakOfWaveMaxValue) {
  293. this.peakOfWaveMaxValue += _judgmentValue;
  294. this.peakOfWaveMaxValueCount++;
  295. }
  296. } else if (_judgmentValue < -1) {
  297. _frameMinValue += _judgmentValue;
  298. if (_judgmentValue < this.valleyOfWaveMinValue) {
  299. this.valleyOfWaveMinValue += _judgmentValue;
  300. this.valleyOfWaveMinValueCount++;
  301. }
  302. }
  303. if (_data.oriGyro.oGyroY > 5) {
  304. _frameGyroValue += _data.oriGyro.oGyroY;
  305. } else if (_data.oriGyro.oGyroY < -5) {
  306. _frameGyroMinValue += _data.oriGyro.oGyroY;
  307. }
  308. }
  309. }
  310. //后面通用使用这个类型传输数据
  311. this.event.trigger('resultant', {
  312. type: "stateDataOfJump",
  313. currentMaxValue: _frameMaxValue,
  314. currentMinValue: _frameMinValue,
  315. peakOfWaveMaxValue: this.peakOfWaveMaxValue,
  316. valleyOfWaveMinValue: this.valleyOfWaveMinValue,
  317. oGyroValue: _frameGyroValue,
  318. oGyroMinValue: _frameGyroMinValue,
  319. // resultant: resultant,
  320. tempIndex: i, //触发了多少次
  321. // name: "highestCountEnd"
  322. });
  323. this.event.trigger('resultant', {
  324. type: "stop",
  325. tempDataArray: this.tempDataArray
  326. });
  327. }
  328. this.jumpOpts.bUpState = false;
  329. this.jumpOpts.endTime = new Date().getTime();
  330. console.log("end bUpState");
  331. } else {
  332. //还在计算时间区间内,记录各帧的数据
  333. for (let i = 0; i < this.tempDataArray.length; i++) {
  334. let _dataArray = this.tempDataArray[i];
  335. _dataArray.push(data);
  336. }
  337. }
  338. }
  339. }
  340. ActionJump.prototype.setEndUpdate = function () {
  341. for (let i = 0; i < this.tempDataArray.length; i++) {
  342. // 计算数据
  343. this.resetAll();
  344. let _frameMaxValue = 0,
  345. _frameMinValue = 0,
  346. _frameGyroValue = 0;
  347. for (let j = 0; j < this.tempDataArray[i].length; j++) {
  348. let _data = this.tempDataArray[i][j];
  349. let _judgmentValue = _data.oriAcc.oAccZ; //判断左右方向用z
  350. if (_judgmentValue > 1) {
  351. _frameMaxValue += _judgmentValue;
  352. if (_judgmentValue > this.peakOfWaveMaxValue) {
  353. this.peakOfWaveMaxValue += _judgmentValue;
  354. this.peakOfWaveMaxValueCount++;
  355. }
  356. } else if (_judgmentValue < -1) {
  357. _frameMinValue += _judgmentValue;
  358. if (_judgmentValue < this.valleyOfWaveMinValue) {
  359. this.valleyOfWaveMinValue += _judgmentValue;
  360. this.valleyOfWaveMinValueCount++;
  361. }
  362. }
  363. if (Math.abs(_data.oriGyro.oGyroY) > 5) {
  364. // this.oriGyroYArray.push(_oGyroY);
  365. _frameGyroValue += _data.oriGyro.oGyroY;
  366. }
  367. }
  368. //后面通用使用这个类型传输数据
  369. this.event.trigger('resultant', {
  370. type: "stateDataOfJump",
  371. currentMaxValue: _frameMaxValue,
  372. currentMinValue: _frameMinValue,
  373. peakOfWaveMaxValue: this.peakOfWaveMaxValue,
  374. valleyOfWaveMinValue: this.valleyOfWaveMinValue,
  375. oGyroValue: _frameGyroValue,
  376. // resultant: resultant,
  377. tempIndex: i, //触发了多少次
  378. // name: "highestCountEnd"
  379. });
  380. this.event.trigger('resultant', {
  381. type: "stop",
  382. arrayData: this.dataArray
  383. });
  384. }
  385. this.jumpOpts.bUpState = false;
  386. // 清空触发的数值
  387. this.tempDataArray = [];
  388. this.jumpOpts.endTime = new Date().getTime();
  389. console.log("end bUpState");
  390. }
  391. ActionJump.prototype.setBUpState = function (value) {
  392. this.jumpOpts.bUpState = value;
  393. }
  394. //重置对应的参数
  395. ActionJump.prototype.resetAll = function () {
  396. console.log("resetAll");
  397. this.peakOfWaveMaxValue = 0;
  398. this.peakOfWaveMaxValueCount = 0;
  399. this.valleyOfWaveMinValue = 0;
  400. this.valleyOfWaveMinValueCount = 0;
  401. }
  402. /**
  403. * 日志
  404. * @param {Object} data
  405. * @param {Object} logType
  406. */
  407. ActionJump.prototype.sendLog = function (data, logType) {
  408. this.event.trigger('resultant', {
  409. type: "log",
  410. logType: logType,
  411. data: data
  412. });
  413. }
  414. if (typeof module === "object" && typeof module.exports === "object") {
  415. module.exports = ActionJump;
  416. }