jump.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /**
  2. * 跳判断相关脚本代码
  3. */
  4. let assign = function (target, ...varArgs) {
  5. if (target == null) {
  6. throw new TypeError('Cannot convert undefined or null to object');
  7. }
  8. if (!varArgs || varArgs.length <= 0) {
  9. return target;
  10. }
  11. // 深度合并对象
  12. function deepAssign(obj1, obj2) {
  13. for (let key in obj2) {
  14. obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
  15. deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key];
  16. }
  17. return obj1;
  18. }
  19. varArgs.forEach(val => {
  20. target = deepAssign(target, val);
  21. });
  22. return target;
  23. };
  24. function Event() {
  25. this.events = {};
  26. }
  27. Event.prototype.addEventListener = function (type, listener) {
  28. this.events[type] = this.events[type] || [];
  29. this.events[type].push(listener);
  30. };
  31. Event.prototype.trigger = function () {
  32. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  33. args[_key] = arguments[_key];
  34. }
  35. var type = args[0];
  36. var params = args.slice(1);
  37. if (!!this.events[type]) {
  38. // console.log("type:",type);
  39. this.events[type].forEach(function (listener) {
  40. try {
  41. listener.apply(null, params);
  42. } catch (e) {
  43. console.error(e);
  44. }
  45. });
  46. }
  47. };
  48. var ActionJump = function ActionJump() {
  49. let jumpOpts = {
  50. //是否上升的标志位
  51. isDirectionUp: false,
  52. //持续上升次数
  53. continueUpCount: 0,
  54. //上一点的持续上升的次数,为了记录波峰的上升次数
  55. continueUpFormerCount: 0,
  56. continueDownCount: 0,
  57. continueDownFormerCount: 0,
  58. //上一点的状态,上升还是下降
  59. lastStatus: false,
  60. //波峰值
  61. peakOfWave: 0,
  62. //波谷值
  63. valleyOfWave: 0,
  64. //检测到极快的波动的次数
  65. timeOfPeakCount: 0,
  66. //开始更新的次数
  67. startCount: 0,
  68. //停止跳
  69. bStopJump: false,
  70. //上次传感器的值
  71. gravityOld: 0,
  72. bUpState: false,
  73. }
  74. this.jumpOpts = jumpOpts;
  75. //其他波峰波谷参数相关数组记录
  76. this.peakOfWaveArray = [];
  77. this.peakOfWaveMaxValue = 0;
  78. this.valleyOfWaveArray = [];
  79. this.valleyOfWaveMinValue = 0;
  80. this.highestCount = 0;
  81. //陀螺仪
  82. this.oriGyroYArray = [];
  83. this.event = new Event();
  84. }
  85. ActionJump.prototype.addEventListener = function (type, listener) {
  86. this.event.addEventListener(type, listener);
  87. };
  88. ActionJump.prototype.updateJump = function () {
  89. let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  90. //使用三个轴的数据,计算重力轴的加速度。最后减去重力的加速度值
  91. //********加速计********
  92. let { lAccX, lAccY, lAccZ } = data.linearAcc;
  93. let { oAccX, oAccY, oAccZ } = data.oriAcc;
  94. let { oGyroX, oGyroY, oGyroZ } = data.oriGyro;
  95. this.detectorNewStep(data.resultant, lAccX, lAccY, lAccZ, oAccX, oAccY, oAccZ, data.runIndex, oGyroX);
  96. };
  97. /*
  98. * 检测步子,并开始计步
  99. * 1.传入数据
  100. * 2.如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
  101. * 3.符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中
  102. * */
  103. ActionJump.prototype.detectorNewStep = function (resultant, linearX, linearY, linearZ, oriX, oriY, oriZ, _runIndex, _oGyroY) {
  104. let bUpdate = true;
  105. let _judgmentValue = oriZ;
  106. if (this.jumpOpts.gravityOld == 0) {
  107. this.jumpOpts.gravityOld = _judgmentValue;
  108. } else {
  109. if (!this.jumpOpts.bStopJump) {
  110. let { bState, bType, value } = this.detectorPeakOfWaveAndValleyOfWave(_judgmentValue, this.jumpOpts.gravityOld);
  111. if (bState) {
  112. this.jumpOpts.bUpState = true;
  113. let _temp = {
  114. type: bType,
  115. oldValue: value,
  116. value: resultant,
  117. lastIndex: _runIndex - 1
  118. };
  119. this.event.trigger('resultant', _temp);
  120. bUpdate = false;
  121. //记录最高点和最低点数组
  122. if (bType == 'peakOfWave') {
  123. this.peakOfWaveArray.push(_temp);
  124. if (value > this.peakOfWaveMaxValue)
  125. this.peakOfWaveMaxValue = value;
  126. } else if (bType == 'valleyOfWave') {
  127. this.valleyOfWaveArray.push(_temp);
  128. if (value < this.valleyOfWaveMinValue)
  129. this.valleyOfWaveMinValue = value;
  130. }
  131. this.highestCount = 0;
  132. //陀螺仪部分
  133. this.oriGyroYArray = [];
  134. this.jumpOpts.startCount = 0;
  135. }
  136. if (this.jumpOpts.bUpState) {
  137. this.oriGyroYArray.push(_oGyroY);
  138. this.jumpOpts.startCount++;
  139. if (this.jumpOpts.startCount >= 15) {
  140. //如果加过一定数量。判断没有触发,重置状态
  141. this.jumpOpts.bUpState = false;
  142. this.resetAll();
  143. this.jumpOpts.startCount = 0;
  144. let allOGyroValue = 0;
  145. for (let i = 0; i < this.oriGyroYArray.length; i++) {
  146. allOGyroValue += this.oriGyroYArray[i];
  147. }
  148. allOGyroValue /= this.oriGyroYArray.length;
  149. //这里相当于处理识别到跳,但是没有判断出什么动作。
  150. this.event.trigger('resultant', {
  151. type: "stateDataOfJump",
  152. currentMaxValue: 0,
  153. oGyroValue: allOGyroValue,
  154. resultant: resultant
  155. });
  156. }
  157. //出现极值后
  158. if (Math.abs(linearZ) < 7 && Math.abs(resultant) < 7) {
  159. this.highestCount++;
  160. if (this.highestCount >= 2) {
  161. //达到最高点,
  162. this.jumpOpts.bStopJump = true;
  163. let _currentMaxValue = 0;
  164. if (Math.abs(this.peakOfWaveMaxValue) > Math.abs(this.valleyOfWaveMinValue)) {
  165. _currentMaxValue = this.peakOfWaveMaxValue;
  166. } else {
  167. _currentMaxValue = this.valleyOfWaveMinValue;
  168. }
  169. let allOGyroValue = 0;
  170. for (let i = 0; i < this.oriGyroYArray.length; i++) {
  171. allOGyroValue += this.oriGyroYArray[i];
  172. }
  173. allOGyroValue /= this.oriGyroYArray.length;
  174. //目前测试预大于100 为旋转跳动
  175. // if (allOGyroValue > 0) {
  176. // console.log('right:', allOGyroValue);
  177. // } else {
  178. // console.log('left:', allOGyroValue);
  179. // }
  180. this.event.trigger('resultant', {
  181. type: "jump",
  182. acc: _currentMaxValue,
  183. value: resultant
  184. });
  185. this.event.trigger('resultant', {
  186. type: "curAngle",
  187. value: _currentMaxValue,
  188. resultant: resultant
  189. });
  190. this.event.trigger('resultant', {
  191. type: "rotate",
  192. value: allOGyroValue,
  193. resultant: resultant
  194. });
  195. //如果_currentMaxValue小于30判断原地跳
  196. // console.log("_currentMaxValue:", _currentMaxValue,allOGyroValue);
  197. //后面通用使用这个类型传输数据
  198. this.event.trigger('resultant', {
  199. type: "stateDataOfJump",
  200. currentMaxValue: _currentMaxValue,
  201. oGyroValue: allOGyroValue,
  202. resultant: resultant
  203. });
  204. // bUpdate = false;
  205. this.jumpOpts.bUpState = false;
  206. this.resetAll();
  207. console.log("this.jumpOpts.startCount111:", this.jumpOpts.startCount);
  208. }
  209. }
  210. }
  211. } else {
  212. this.jumpOpts.timeOfPeakCount++;
  213. if (this.jumpOpts.timeOfPeakCount >= 30) {
  214. this.jumpOpts.timeOfPeakCount = 0;
  215. this.jumpOpts.bStopJump = false;
  216. this.event.trigger('resultant', {
  217. type: "stop"
  218. });
  219. console.log("this.jumpOpts.startCount222:", this.jumpOpts.startCount);
  220. this.resetAll();
  221. }
  222. }
  223. // let result = Math.atan2(averX, averZ) * 180 / (Math.PI);
  224. // result = Math.round(result);
  225. // let curAngle = result > 0 ? result : (360 + result);
  226. // console.log("curAngle:", curAngle);
  227. this.event.trigger('resultant', {
  228. type: "bUpdateDraw",
  229. linearX: linearX,
  230. linearZ: linearZ,
  231. linearY: linearY,
  232. oriX: oriX,
  233. oriY: oriY,
  234. oriZ: oriZ
  235. });
  236. this.jumpOpts.gravityOld = _judgmentValue;
  237. }
  238. }
  239. ActionJump.prototype.detectorPeakOfWaveAndValleyOfWave = function (newValue, oldValue) {
  240. this.jumpOpts.lastStatus = this.jumpOpts.isDirectionUp;
  241. if (newValue >= oldValue) {
  242. this.jumpOpts.continueDownFormerCount = this.jumpOpts.continueDownCount;
  243. this.jumpOpts.continueDownCount = 0;
  244. this.jumpOpts.isDirectionUp = true;
  245. this.jumpOpts.continueUpCount++;
  246. } else {
  247. this.jumpOpts.continueUpFormerCount = this.jumpOpts.continueUpCount;
  248. this.jumpOpts.continueUpCount = 0;
  249. this.jumpOpts.isDirectionUp = false;
  250. this.jumpOpts.continueDownCount++;
  251. }
  252. if (!this.jumpOpts.isDirectionUp && this.jumpOpts.lastStatus && this.jumpOpts.continueUpFormerCount >= 2 && Math.abs(oldValue) >= 5) {
  253. this.jumpOpts.peakOfWave = oldValue;
  254. return { value: oldValue, bType: 'peakOfWave', bState: true };
  255. } else if (!this.jumpOpts.lastStatus && this.jumpOpts.isDirectionUp && this.jumpOpts.continueDownFormerCount >= 2 && Math.abs(oldValue) >= 5) {
  256. this.jumpOpts.valleyOfWave = oldValue;
  257. return { value: oldValue, bType: 'valleyOfWave', bState: true };
  258. } else {
  259. return { value: oldValue, bType: 'None', bState: false };
  260. }
  261. }
  262. //重置对应的参数
  263. ActionJump.prototype.resetAll = function () {
  264. this.peakOfWaveArray = [];
  265. this.peakOfWaveMaxValue = 0;
  266. this.valleyOfWaveArray = [];
  267. this.valleyOfWaveMinValue = 0;
  268. this.highestCount = 0;
  269. this.jumpOpts.continueDownFormerCount = 0;
  270. this.jumpOpts.continueDownCount = 0;
  271. this.jumpOpts.continueUpFormerCount = 0;
  272. this.jumpOpts.continueUpCount = 0;
  273. }
  274. if (typeof module === "object" && typeof module.exports === "object") {
  275. module.exports = ActionJump;
  276. }