|
在传感器使用中,我们常常需要对传感器数据进行各种整理,让应用获得更好的效果,以下介绍几种常用的简单处理方法: - D; t0 j+ l2 J 1.加权平滑:平滑和均衡传感器数据,减小偶然数据突变的影响;& c5 T/ I; i! I6 j 2.抽取突变:去除静态和缓慢变化的数据背景,强调瞬间变化;* k A/ _0 V1 X1 M3 Q7 F 3.简单移动平均线:保留数据流最近的K个数据,取平均值;/ B% a3 E$ g; u# l ) v4 ]& s6 h0 {7 x6 N6 l$ } 01 加权平滑( ?* e7 ?2 N0 ^1 T5 H3 ]7 X, ~ 使用算法如下: (新值) = (旧值)*(1 - a) + X * a其中a为设置的权值,X为最新数据,程序实现如下:/ o; F& K- G1 _0 g float ALPHA = 0.1f; public void onSensorChanged(SensorEvent event){9 [9 k `& H5 d x = event.values[0]; y = event.values[1]; z = event.values[2]; mLowPassX = lowPass(x,mLowPassX); mLowPassY = lowPass(x,mLowPassY);6 X& E1 x& ]" M' a' l8 A4 } mLowPassZ = lowPass(x,mLowPassZ); } private float lowPass(float current,float last){ return last * (1.0f - ALPHA) + current * ALPHA;7 m& X/ l9 l |3 r+ G9 M m } 02; V) k% b8 J4 ^8 ]* B 抽取突变采用上面加权平滑的逆算法* m3 B0 [$ ?: j ; [, {4 K, l& }1 C, s$ e 实现代码如下:" l0 i" w% S$ ^# G9 @3 n public void onSensorChanged(SensorEvent event){ final float ALPHA = 0.8;gravity[0] = ALPHA * gravity[0] + (1-ALPHA) * event.values[0]; gravity[1] = ALPHA * gravity[1] + (1-ALPHA) * event.values[1];9 G9 ]' [0 Y! k7 u9 D gravity[2] = ALPHA * gravity[2] + (1-ALPHA) * event.values[2];filteredValues[0] = event.values[0] - gravity[0]; filteredValues[1] = event.values[1] - gravity[1];4 J' J2 O+ c, _ filteredValues[2] = event.values[2] - gravity[2];8 Y8 P8 d7 T! T+ p9 Z% c$ B, F }1 a* ^# d9 R- ~' { 03 简单移动平均线 保留传感器数据流中最近的K个数据,返回它们的平均值。k表示平均“窗口”的大小;. H" v. @( l# S6 @; I0 P9 P 实现代码如下:( c; @: }6 \0 d& ~3 w5 s" [ public class MovingAverage{; @+ x/ F7 Q7 n5 B9 x! v5 [ private float circularBuffer[]; //保存传感器最近的K个数据4 o9 D/ V3 F! S' g1 t# y private float avg; //返回到传感器平均值9 d/ b$ p4 {$ b3 B1 v1 ^( y- B0 |$ B private float sum; //数值中传感器数据的和 d; F: E( B$ i private float circularIndex; //传感器数据数组节点位置2 E# C/ u$ F9 ? private int count;public MovingAverage(int k){; F, ~# \. I- c. }' y1 Z5 z circularBuffer = new float[k];$ l% o: r( C3 f( i count= 0; circularIndex = 0; avg = 0;2 n* v; O. p" B sum = 0;4 y9 S& i2 \; f$ B4 A }8 z% W& q' a7 M/ `! r U public float getValue(){! k( ~. c: C2 s W return arg;' E4 X M, q) ^% Q: S4 T7 [# X9 u& k } public long getCount(){# ~* y2 d4 d4 p return count;$ }' e( p3 X6 H. t }( A7 u. \' x4 m5 Y( |( E/ H8 E private void primeBuffer(float val){ for(int i=0;i<circularbuffer.length;++i){' ~) V1 o7 p0 v9 M circularBuffer = val; sum += val; }& P: S5 H' ^0 H9 _ } private int nextIndex(int curIndex){, {& P3 p9 E; M. B! M) V! q4 S if(curIndex + 1 >= circularBuffer.length){( m ~3 U1 }' l8 O0 |! d* Y4 y return 0; }- Q, Q; H5 S" X r7 ^- x: s return curIndex + 1; }9 g0 y* `! O k0 ~/ ^; } public void pushValue(float x){ if(0 == count++){9 G& N+ Z/ R' ]& v2 N, B1 P+ a primeBuffer(x); } float lastValue = circularBuffer[circularIndex];( U# P* g- P) ^; t( S3 _ circularBuffer[circularIndex] = x; //更新窗口中传感器数据 sum -= lastValue; //更新窗口中传感器数据和: a; E3 o" x& t7 z! ?8 \" l sum += x;0 ]5 ?8 F) P# x+ Q3 |. ?: m! y avg = sum / circularBuffer.length; //计算得传感器平均值 circularIndex = nextIndex(circularIndex); } } 2 N" v4 o5 R: y' E$ }- G" ?, ? |
微信公众号
手机版