/** * 跳判断相关脚本代码 */ function Event() { this.events = {}; } Event.prototype.addEventListener = function (type, listener) { this.events[type] = this.events[type] || []; this.events[type].push(listener); }; Event.prototype.trigger = function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var type = args[0]; var params = args.slice(1); if (!!this.events[type]) { // console.log("type:",type); this.events[type].forEach(function (listener) { try { listener.apply(null, params); } catch (e) { console.error(e); } }); } }; /** * 公共部分计算参数 * 已时间为条件执行 */ var jumpOpts = { //是否上升的标志位 isDirectionUp: false, //持续上升次数 continueUpCount: 0, //上一点的持续上升的次数,为了记录波峰的上升次数 continueUpFormerCount: 0, continueDownCount: 0, continueDownFormerCount: 0, //上一点的状态,上升还是下降 lastStatus: false, //波峰值 peakOfWave: 0, //波谷值 valleyOfWave: 0, //检测到极快的波动的次数 timeOfPeakCount: 0, //开始添加 bUpdateTimeOfPeakCount: false, //开始更新的次数 startCount: 0, //停止跳 bStopJump: false, //上次传感器的值 gravityOld: 0, bUpState: false, //开始时间 startTime: 0, endTime: 0, startResultant: 0 } var ActionJump = function ActionJump() { this.jumpOpts = jumpOpts; this.peakOfWaveMaxValue = 0; this.peakOfWaveMaxValueCount = 0; this.valleyOfWaveMinValue = 0; this.valleyOfWaveMinValueCount = 0; this.highestCount = 0; //记录当前传入的数据 this.dataArray = []; //获取一个判断数组的数据,比如触发点前后取一定帧数 //记录波形的个数,可重复添加 this.tempDataArray = []; //记录一个加速计数组 this.oriAccArray = []; //陀螺仪 this.oriGyroYArray = []; this.event = new Event(); this.frameCapacity = 10; this.frame = []; this.frameLength = 5; this.frameOffset = 0; for (var i = 0; i < this.frameCapacity; ++i) { var o = new Object(); o.maxValue = 0; o.gyroValue = 0; o.resultant = 0; o.index = -1; o.acc = null; o.gyro = null; this.frame.push(o); } this.frameLog = []; this.LastMS = 0; this.LastTime = 0; this.xA = 0; this.yA = 0; this.zA = 0; } ActionJump.prototype.addEventListener = function (type, listener) { this.event.addEventListener(type, listener); }; /** * 更新数据 */ ActionJump.prototype.updateJump = function () { let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; //使用三个轴的数据,计算重力轴的加速度。最后减去重力的加速度值 /** * 纠正后使用的轴向 * box["acc"] = { ax: -ay, ay: -ax, az: az }; box["gyro"] = { gx: -gy, gy: -gx, gz: gz }; */ //********加速计******** // let { // lAccX, // lAccY, // lAccZ // } = data.linearAcc; // let { // oAccX, // oAccY, // oAccZ // } = data.oriAcc; // let { // oGyroX, // oGyroY, // oGyroZ // } = data.oriGyro; // let { // bYAxis // } = data; // //oGyroX 在用的过程中方向相反,所以添加负号 // let _tempAxisData = bYAxis ? -oGyroX : oGyroY; //新设备直接使用oGyroY // this.detectorNewStep(data.resultant, lAccX, lAccY, lAccZ, oAccX, oAccY, oAccZ, data.runIndex, _tempAxisData); // oAccZ // this.detectorNewStep(data.resultant, -lAccY, -lAccX, -lAccZ, -oAccY, -oAccX, -oAccZ, data.runIndex, // _tempAxisData); //********传感器数值******** let { ax, ay, az } = data.acc; let { gx, gy, gz } = data.gyro; let { min, s, ms } = data; let msGap = ms - this.LastMS; if (msGap < 0) { msGap += 1000; } this.LastMS = ms; let _ax = data.acc.ax * 10; let _ay = data.acc.ay * 10; let _az = data.acc.az * 10; //低通滤波分离重力 let curTime = new Date().getTime(); let alpha = 1000 / (1000 + msGap); // 0.8; this.LastTime = curTime; this.xA = alpha * this.xA + (1 - alpha) * _ax; this.yA = alpha * this.yA + (1 - alpha) * _ay; this.zA = alpha * this.zA + (1 - alpha) * _az; //高通滤波获取线性速度 let linear_acceleration_x = _ax - this.xA; let linear_acceleration_y = _ay - this.yA; let linear_acceleration_z = _az - this.zA; let _temp = { oriAcc: { oAccX: _ax, oAccY: _ay, oAccZ: _az }, linearAcc: { lAccX: linear_acceleration_x, lAccY: linear_acceleration_y, lAccZ: linear_acceleration_z }, gravityAcc: { gravityX: this.xA, gravityY: this.yA, gravityZ: this.zA }, bLimitRebound: false, resultant: Math.sqrt(_ax * _ax + _ay * _ay + _az * _az), runIndex: data.BLEAccIndex, //陀螺仪 oriGyro: { oGyroX: gx, oGyroY: gy, oGyroZ: gz }, bYAxis: data.isY }; this.detectorNewStep(_temp); }; /* *计算跳逻辑 */ // ActionJump.prototype.detectorNewStep = function(resultant, linearX, linearY, linearZ, oriX, oriY, oriZ, _runIndex, // _oGyroY) ActionJump.prototype.detectorNewStep = function (data) { /** * 把數據返回 */ this.event.trigger('resultant', { type: "bUpdateDraw", data: data }); let { oAccX, oAccY, oAccZ } = data.oriAcc; let { oGyroX, oGyroY, oGyroZ } = data.oriGyro; let resultant = data.resultant; //合加速度 // 记录500个点 // 如果超过了,去除第一个点,加入最后一个元素 if (this.dataArray.length <= 500) { this.dataArray.push(data); } else { this.dataArray.shift(); this.dataArray.push(data); } //判断resultant 一个阀值,简单的检测跳的动作触发幅度 let limitResultant = 20; if (resultant > limitResultant && !this.jumpOpts.bUpState) { let currTime = new Date().getTime(); //当前时间 // 清空触发的数值 this.tempDataArray = []; let diffTime = currTime - this.jumpOpts.endTime; //当前时间减最初时间,得到当前时间差 if (Math.abs(diffTime) < 100) { //前一帧到后一帧的间隔忽略 150 / 6 约25帧落地波动 return; } this.jumpOpts.bUpState = true; //第一次触发的时间。记录开始时间 this.jumpOpts.startTime = new Date().getTime(); this.event.trigger('resultant', { type: "log", logType: 'normal', data: "开始时间:" + this.jumpOpts.startTime + ",resultant:" + resultant }); //取触发前一定帧数 let len = this.dataArray.length; let total = 5;//取倒数5帧 if (len != 0) { let newArr = []; //长度超过 let limit = len - total; if (limit > 0) { for (let i = len; i > limit; i--) { newArr.push(this.dataArray[i - 1]); } this.tempDataArray.push(newArr); } else { //直接添加数据 this.tempDataArray.push(this.dataArray.slice()); } } console.log("start bUpState"); } if (this.jumpOpts.bUpState) { //取一个时间段为截取时间,计算时间段里面的数据 let currTime = new Date().getTime(); //当前时间 let diffTime = currTime - this.jumpOpts.startTime; //当前时间减最初时间,得到当前时间差 if (diffTime > 400) { // console.log("diffTime:", diffTime); //计算已出发的数据 // console.log(this.tempDataArray); for (let i = 0; i < this.tempDataArray.length; i++) { // 计算数据 this.resetAll(); let _frameMaxValue = 0, _frameMinValue = 0, _frameGyroValue = 0, _frameGyroMinValue = 0; for (let j = 0; j < this.tempDataArray[i].length; j++) { let _data = this.tempDataArray[i][j]; if (j < 30) { //取前面30帧判断 let _judgmentValue = _data.linearAcc.lAccZ //_data.oriAcc.oAccZ; //判断左右方向用z if (_judgmentValue > 1) { _frameMaxValue += _judgmentValue; if (_judgmentValue > this.peakOfWaveMaxValue) { this.peakOfWaveMaxValue += _judgmentValue; this.peakOfWaveMaxValueCount++; } } else if (_judgmentValue < -1) { _frameMinValue += _judgmentValue; if (_judgmentValue < this.valleyOfWaveMinValue) { this.valleyOfWaveMinValue += _judgmentValue; this.valleyOfWaveMinValueCount++; } } if (_data.oriGyro.oGyroY > 5) { _frameGyroValue += _data.oriGyro.oGyroY; } else if (_data.oriGyro.oGyroY < -5) { _frameGyroMinValue += _data.oriGyro.oGyroY; } } } //后面通用使用这个类型传输数据 this.event.trigger('resultant', { type: "stateDataOfJump", currentMaxValue: _frameMaxValue, currentMinValue: _frameMinValue, peakOfWaveMaxValue: this.peakOfWaveMaxValue, valleyOfWaveMinValue: this.valleyOfWaveMinValue, oGyroValue: _frameGyroValue, oGyroMinValue: _frameGyroMinValue, // resultant: resultant, tempIndex: i, //触发了多少次 // name: "highestCountEnd" }); this.event.trigger('resultant', { type: "stop", tempDataArray: this.tempDataArray }); } this.jumpOpts.bUpState = false; this.jumpOpts.endTime = new Date().getTime(); console.log("end bUpState"); } else { //还在计算时间区间内,记录各帧的数据 for (let i = 0; i < this.tempDataArray.length; i++) { let _dataArray = this.tempDataArray[i]; _dataArray.push(data); } } } } ActionJump.prototype.setEndUpdate = function () { for (let i = 0; i < this.tempDataArray.length; i++) { // 计算数据 this.resetAll(); let _frameMaxValue = 0, _frameMinValue = 0, _frameGyroValue = 0; for (let j = 0; j < this.tempDataArray[i].length; j++) { let _data = this.tempDataArray[i][j]; let _judgmentValue = _data.oriAcc.oAccZ; //判断左右方向用z if (_judgmentValue > 1) { _frameMaxValue += _judgmentValue; if (_judgmentValue > this.peakOfWaveMaxValue) { this.peakOfWaveMaxValue += _judgmentValue; this.peakOfWaveMaxValueCount++; } } else if (_judgmentValue < -1) { _frameMinValue += _judgmentValue; if (_judgmentValue < this.valleyOfWaveMinValue) { this.valleyOfWaveMinValue += _judgmentValue; this.valleyOfWaveMinValueCount++; } } if (Math.abs(_data.oriGyro.oGyroY) > 5) { // this.oriGyroYArray.push(_oGyroY); _frameGyroValue += _data.oriGyro.oGyroY; } } //后面通用使用这个类型传输数据 this.event.trigger('resultant', { type: "stateDataOfJump", currentMaxValue: _frameMaxValue, currentMinValue: _frameMinValue, peakOfWaveMaxValue: this.peakOfWaveMaxValue, valleyOfWaveMinValue: this.valleyOfWaveMinValue, oGyroValue: _frameGyroValue, // resultant: resultant, tempIndex: i, //触发了多少次 // name: "highestCountEnd" }); this.event.trigger('resultant', { type: "stop", arrayData: this.dataArray }); } this.jumpOpts.bUpState = false; // 清空触发的数值 this.tempDataArray = []; this.jumpOpts.endTime = new Date().getTime(); console.log("end bUpState"); } ActionJump.prototype.setBUpState = function (value) { this.jumpOpts.bUpState = value; } //重置对应的参数 ActionJump.prototype.resetAll = function () { console.log("resetAll"); this.peakOfWaveMaxValue = 0; this.peakOfWaveMaxValueCount = 0; this.valleyOfWaveMinValue = 0; this.valleyOfWaveMinValueCount = 0; } /** * 日志 * @param {Object} data * @param {Object} logType */ ActionJump.prototype.sendLog = function (data, logType) { this.event.trigger('resultant', { type: "log", logType: logType, data: data }); } if (typeof module === "object" && typeof module.exports === "object") { module.exports = ActionJump; }