Skip to content

Commit f48990c

Browse files
committed
调整计步算法
1 parent b0a0ec9 commit f48990c

File tree

2 files changed

+180
-37
lines changed

2 files changed

+180
-37
lines changed

app/src/main/java/com/base/basepedo/service/StepDcretor.java

Lines changed: 168 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,40 @@
1212
import java.util.TimerTask;
1313

1414
public class StepDcretor implements SensorEventListener {
15+
//存放三轴数据
16+
float[] oriValues = new float[3];
17+
final int valueNum = 4;
18+
//用于存放计算阈值的波峰波谷差值
19+
float[] tempValue = new float[valueNum];
20+
int tempCount = 0;
21+
//是否上升的标志位
22+
boolean isDirectionUp = false;
23+
//持续上升次数
24+
int continueUpCount = 0;
25+
//上一点的持续上升的次数,为了记录波峰的上升次数
26+
int continueUpFormerCount = 0;
27+
//上一点的状态,上升还是下降
28+
boolean lastStatus = false;
29+
//波峰值
30+
float peakOfWave = 0;
31+
//波谷值
32+
float valleyOfWave = 0;
33+
//此次波峰的时间
34+
long timeOfThisPeak = 0;
35+
//上次波峰的时间
36+
long timeOfLastPeak = 0;
37+
//当前的时间
38+
long timeOfNow = 0;
39+
//当前传感器的值
40+
float gravityNew = 0;
41+
//上次传感器的值
42+
float gravityOld = 0;
43+
//动态阈值需要动态的数据,这个值用于这些动态数据的阈值
44+
final float initialValue = (float) 1.8;
45+
//初始阈值
46+
float ThreadValue = (float) 2.0;
47+
48+
1549
float avg_v = 0;
1650
float min_v = 0;
1751
float max_v = 0;
@@ -65,15 +99,10 @@ public void onSensorChanged(SensorEvent event) {
6599
synchronized (this) {
66100
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
67101
calc_step(event);
68-
69102
}
70103
}
71104
}
72105

73-
74-
75-
76-
77106
public void onAccuracyChanged(Sensor arg0, int arg1) {
78107

79108
}
@@ -143,12 +172,12 @@ void avg_check_v(float v) {
143172
acc_count++;
144173
//求移动平均线
145174
//50ms 1 second 20 , 3 sec60;
146-
if (acc_count < 64) {
175+
if (acc_count < 34) {
147176
//avg_v=((acc_count-1)*avg_v+v)/acc_count;
148177
avg_v = avg_v + (v - avg_v) / acc_count;
149178
} else {
150179
//avg_v=(avg_v*99+v)/100;
151-
avg_v = avg_v * 63 / 64 + v / 64;
180+
avg_v = avg_v * 33 / 34 + v / 34;
152181
}
153182

154183
if (v > avg_v) {
@@ -178,27 +207,25 @@ void avg_check_v(float v) {
178207
if (up_c == 2 && (max_v - min_v) > 2) {
179208
//
180209
long cur_time = System.currentTimeMillis();
181-
if (cur_time - pre_time > 250) {
210+
if (cur_time - pre_time >= 500
211+
) {
182212
pre_time = cur_time;
183213
preStep();
184-
// StepDcretor.CURRENT_SETP++;
185-
// //记步,通知ui
186-
// if (onSensorChangeListener != null) {
187-
// onSensorChangeListener.onChange();
188-
// }
189-
Log.e("xfblog","CURRENT_SETP:"+CURRENT_SETP);
214+
Log.e("xfblog", "CURRENT_SETP:" + CURRENT_SETP);
190215
} else {
191216
up_c = 1;
192217
}
193218
}
194219
}
195220

196-
synchronized private void calc_step(SensorEvent arg0) {
197-
float v = (float) Math.sqrt(arg0.values[0] * arg0.values[0] + arg0.values[1] * arg0.values[1] + arg0.values[2] * arg0.values[2]);
198-
avg_check_v(v);
221+
synchronized private void calc_step(SensorEvent event) {
222+
average = (float) Math.sqrt(Math.pow(event.values[0], 2)
223+
+ Math.pow(event.values[1], 2) + Math.pow(event.values[2], 2));
224+
// avg_check_v(average);
225+
DetectorNewStep(average);
199226
}
200227

201-
private void preStep(){
228+
private void preStep() {
202229
if (CountTimeState == 0) {
203230
// 开启计时器
204231
time = new TimeCount(duration, 700);
@@ -216,9 +243,7 @@ private void preStep(){
216243
}
217244
}
218245

219-
220-
221-
private void oldCalStep(SensorEvent event){
246+
private void oldCalStep(SensorEvent event) {
222247
// 用低通滤波器分离出重力加速度
223248
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
224249
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
@@ -229,12 +254,12 @@ private void oldCalStep(SensorEvent event){
229254

230255
// if (average <= verminValue) {
231256
if (average <= minValue) {
232-
Log.v("xfblog","低");
257+
Log.v("xfblog", "低");
233258
perCalTime = System.currentTimeMillis();
234259
}
235260
// } else if (average >= vermaxValue) {
236261
else if (average >= maxValue) {
237-
Log.v("xfblog","高");
262+
Log.v("xfblog", "高");
238263
float betweentime = System.currentTimeMillis()
239264
- perCalTime;
240265
if (betweentime >= minTime && betweentime < maxTime) {
@@ -275,9 +300,128 @@ else if (CountTimeState == 3) {
275300
}
276301

277302

278-
279303
}
280304
}
281305
// }
282306
}
307+
308+
309+
/*
310+
* 检测步子,并开始计步
311+
* 1.传入sersor中的数据
312+
* 2.如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
313+
* 3.符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中
314+
* */
315+
public void DetectorNewStep(float values) {
316+
if (gravityOld == 0) {
317+
gravityOld = values;
318+
} else {
319+
if (DetectorPeak(values, gravityOld)) {
320+
timeOfLastPeak = timeOfThisPeak;
321+
timeOfNow = System.currentTimeMillis();
322+
if (timeOfNow - timeOfLastPeak >= 250
323+
&& (peakOfWave - valleyOfWave >= ThreadValue) && timeOfNow - timeOfLastPeak <= 2000) {
324+
timeOfThisPeak = timeOfNow;
325+
/*
326+
* 更新界面的处理,不涉及到算法
327+
* 一般在通知更新界面之前,增加下面处理,为了处理无效运动:
328+
* 1.连续记录10才开始计步
329+
* 2.例如记录的9步用户停住超过3秒,则前面的记录失效,下次从头开始
330+
* 3.连续记录了9步用户还在运动,之前的数据才有效
331+
* */
332+
StepDcretor.CURRENT_SETP++;
333+
if (onSensorChangeListener != null) {
334+
onSensorChangeListener.onChange();
335+
}
336+
}
337+
if (timeOfNow - timeOfLastPeak >= 250
338+
&& (peakOfWave - valleyOfWave >= initialValue)) {
339+
timeOfThisPeak = timeOfNow;
340+
ThreadValue = Peak_Valley_Thread(peakOfWave - valleyOfWave);
341+
}
342+
}
343+
}
344+
gravityOld = values;
345+
}
346+
347+
/*
348+
* 检测波峰
349+
* 以下四个条件判断为波峰:
350+
* 1.目前点为下降的趋势:isDirectionUp为false
351+
* 2.之前的点为上升的趋势:lastStatus为true
352+
* 3.到波峰为止,持续上升大于等于2次
353+
* 4.波峰值大于20
354+
* 记录波谷值
355+
* 1.观察波形图,可以发现在出现步子的地方,波谷的下一个就是波峰,有比较明显的特征以及差值
356+
* 2.所以要记录每次的波谷值,为了和下次的波峰做对比
357+
* */
358+
public boolean DetectorPeak(float newValue, float oldValue) {
359+
lastStatus = isDirectionUp;
360+
if (newValue >= oldValue) {
361+
isDirectionUp = true;
362+
continueUpCount++;
363+
} else {
364+
continueUpFormerCount = continueUpCount;
365+
continueUpCount = 0;
366+
isDirectionUp = false;
367+
}
368+
369+
if (!isDirectionUp && lastStatus
370+
&& (continueUpFormerCount >= 2 || oldValue >= 15)) {
371+
peakOfWave = oldValue;
372+
return true;
373+
} else if (!lastStatus && isDirectionUp) {
374+
valleyOfWave = oldValue;
375+
return false;
376+
} else {
377+
return false;
378+
}
379+
}
380+
381+
/*
382+
* 阈值的计算
383+
* 1.通过波峰波谷的差值计算阈值
384+
* 2.记录4个值,存入tempValue[]数组中
385+
* 3.在将数组传入函数averageValue中计算阈值
386+
* */
387+
public float Peak_Valley_Thread(float value) {
388+
float tempThread = ThreadValue;
389+
if (tempCount < valueNum) {
390+
tempValue[tempCount] = value;
391+
tempCount++;
392+
} else {
393+
tempThread = averageValue(tempValue, valueNum);
394+
for (int i = 1; i < valueNum; i++) {
395+
tempValue[i - 1] = tempValue[i];
396+
}
397+
tempValue[valueNum - 1] = value;
398+
}
399+
return tempThread;
400+
401+
}
402+
403+
/*
404+
* 梯度化阈值
405+
* 1.计算数组的均值
406+
* 2.通过均值将阈值梯度化在一个范围里
407+
* */
408+
public float averageValue(float value[], int n) {
409+
float ave = 0;
410+
for (int i = 0; i < n; i++) {
411+
ave += value[i];
412+
}
413+
ave = ave / valueNum;
414+
if (ave >= 8)
415+
ave = (float) 4.3;
416+
else if (ave >= 7 && ave < 8)
417+
ave = (float) 3.3;
418+
else if (ave >= 4 && ave < 7)
419+
ave = (float) 2.3;
420+
else if (ave >= 3 && ave < 4)
421+
ave = (float) 2.0;
422+
else {
423+
ave = (float) 1.3;
424+
}
425+
return ave;
426+
}
283427
}

app/src/main/java/com/base/basepedo/service/StepService.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -222,33 +222,32 @@ private void startStepDetector() {
222222
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
223223
// sensorManager.unregisterListener(stepDetector);
224224
sensorManager.registerListener(stepDetector, sensor,
225-
SensorManager.SENSOR_DELAY_GAME);
225+
SensorManager.SENSOR_DELAY_UI);
226226
stepDetector
227227
.setOnSensorChangeListener(new StepDcretor.OnSensorChangeListener() {
228228

229229
@Override
230230
public void onChange() {
231-
updateNotification("今日步数:" + StepDcretor.CURRENT_SETP + " 步");
231+
updateNotification("今日步数:" + StepDcretor.CURRENT_SETP +","+i+ " 步");
232232
}
233233
});
234234
}
235235

236236
//android4.4以后可以使用计步传感器
237-
// sensorManager = (SensorManager) this
238-
// .getSystemService(SENSOR_SERVICE);
239-
// Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
240-
// if (countSensor != null) {
241-
// sensorManager.registerListener(StepService.this, countSensor, SensorManager.SENSOR_DELAY_UI);
242-
// } else {
243-
// Looper.prepare();
244-
// Toast.makeText(this, "Count sensor not available!", Toast.LENGTH_LONG).show();
245-
// }
237+
sensorManager = (SensorManager) this
238+
.getSystemService(SENSOR_SERVICE);
239+
Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
240+
if (countSensor != null) {
241+
sensorManager.registerListener(StepService.this, countSensor, SensorManager.SENSOR_DELAY_UI);
242+
} else {
243+
Log.v("xf","Count sensor not available!");
244+
}
246245
}
247246

248247
@Override
249248
public void onSensorChanged(SensorEvent event) {
250-
StepDcretor.CURRENT_SETP++;
251-
updateNotification("今日步数:" + StepDcretor.CURRENT_SETP + " 步");
249+
i++;
250+
// updateNotification("今日步数:" + i + " 步");
252251
}
253252

254253
@Override

0 commit comments

Comments
 (0)