在傳感器使用中,我們常常需要對(duì)傳感器數(shù)據(jù)進(jìn)行各種整理,讓應(yīng)用獲得更好的效果,以下介紹幾種常用的簡單處理方法:
- 加權(quán)平滑:平滑和均衡傳感器數(shù)據(jù),減小偶然數(shù)據(jù)突變的影響。
- 抽取突變:去除靜態(tài)和緩慢變化的數(shù)據(jù)背景,強(qiáng)調(diào)瞬間變化。
- 簡單移動(dòng)平均線:保留數(shù)據(jù)流最近的K個(gè)數(shù)據(jù),取平均值。
下面,具體介紹一下這3種處理方法。
加權(quán)平滑,使用算法如下:(新值) = (舊值)*(1 - a) X * a其中a為設(shè)置的權(quán)值,X為最新數(shù)據(jù),程序?qū)崿F(xiàn)如下:
float ALPHA = 0.1f;public void onSensorChanged(SensorEvent event){x = event.values[0];y = event.values[1];z = event.values[2];mLowPassX = lowPass(x,mLowPassX);mLowPassY = lowPass(x,mLowPassY);mLowPassZ = lowPass(x,mLowPassZ);}private float lowPass(float current,float last){return last * (1.0f - ALPHA) current * ALPHA;}抽取突變采用上面加權(quán)平滑的逆算法,實(shí)現(xià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];gravity[2] = ALPHA * gravity[2] (1-ALPHA) * event.values[2];filteredValues[0] = event.values[0] - gravity[0];filteredValues[1] = event.values[1] - gravity[1];filteredValues[2] = event.values[2] - gravity[2];}簡單移動(dòng)平均線,保留傳感器數(shù)據(jù)流中最近的K個(gè)數(shù)據(jù),返回它們的平均值。k表示平均“窗口”的大小,實(shí)現(xiàn)代碼如下:
public class MovingAverage{private float circularBuffer[]; //保存?zhèn)鞲衅髯罱腒個(gè)數(shù)據(jù)private float avg; //返回到傳感器平均值private float sum; //數(shù)值中傳感器數(shù)據(jù)的和private float circularIndex; //傳感器數(shù)據(jù)數(shù)組節(jié)點(diǎn)位置private int count;public MovingAverage(int k){circularBuffer = new float[k];count= 0;circularIndex = 0;avg = 0;sum = 0;}public float getValue(){return arg;}public long getCount(){return count;}private void primeBuffer(float val){for(int i=0;i circularBuffer[i] = val;sum = val;}}private int nextIndex(int curIndex){if(curIndex 1 >= circularBuffer.length){return 0;}return curIndex 1;}public void pushValue(float x){if(0 == count ){primeBuffer(x);}float lastValue = circularBuffer[circularIndex];circularBuffer[circularIndex] = x; //更新窗口中傳感器數(shù)據(jù)sum -= lastValue; //更新窗口中傳感器數(shù)據(jù)和sum = x;avg = sum / circularBuffer.length; //計(jì)算得傳感器平均值circularIndex = nextIndex(circularIndex);}}






