安卓學習之路---計步器算法

關於網上找的一個算法的自己的一點理解

package cn.edu.hit.run.service;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;

/**
 * 這是一個實現了信號監聽的記步的類
 * 這是從谷歌找來的一個記步的算法,看不太懂
 *
 */
public class StepDetector implements SensorEventListener {

    public static int CURRENT_SETP = 0;//當前的步數
    public static float SENSITIVITY = 5; // SENSITIVITY靈敏度
    private float mLastValues[] = new float[3 * 2];
    private float mScale[] = new float[2];
    private float mYOffset;
    private static long end = 0;
    private static long start = 0;
    /**
     * 最後加速度方向
     */
    private float mLastDirections[] = new float[3 * 2];
    private float mLastExtremes[][] = { new float[3 * 2], new float[3 * 2] };
    private float mLastDiff[] = new float[3 * 2];
    private int mLastMatch = -1;

    /**
     * 傳入上下文的構造函數
     * 
     * @param context
     */
    public StepDetector(Context context) {
        super();
        int h = 480;
        mYOffset = h * 0.5f;//240
        mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));//這個數值計算出來大概是-6.12
        mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));//這個數值計算出來是-2
    }

    //當傳感器檢測到的數值發生變化時就會調用這個方法
    //通過一定的邏輯來判斷是否走了一步,如果走了,CURRENT_SETP就加1
    public void onSensorChanged(SensorEvent event) {
        Sensor sensor = event.sensor;
        synchronized (this) {
            if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {//如果是加速度傳感器

                float vSum = 0;
                for (int i = 0; i < 3; i++) {
                    final float v = mYOffset + event.values[i] * mScale[1];//240加x(y、z)方向上的加速度乘以2
                    vSum += v;//累和
                }
                int k = 0;
                float v = vSum / 3;
                //把v和 mLastValues[k]比較,如果v大,則directions得1,
                //否則(即v比 mLastValues[k])小,則再把v和mLastValues[k]比較,如果v比較小,則directions得-1
                //否則(即v和mLastValues[k]相等),directions得0
                //即判斷當期的速度波形的方向,是上升的還是下降的
                float direction = (v > mLastValues[k] ? 1
                        : (v < mLastValues[k] ? -1 : 0));
                if (direction == -mLastDirections[k]) {//如果方向發生了改變
                    // Direction changed
                    int extType = (direction > 0 ? 0 : 1); // minumum or
                                                            // maximum?    
                    //Direction 大於0時到達波谷,否則爲波峯
                    mLastExtremes[extType][k] = mLastValues[k];//把上次的v賦值爲最近一次的極值,即波峯或波谷的值
                    float diff = Math.abs(mLastExtremes[extType][k]
                            - mLastExtremes[1 - extType][k]);//波峯波谷做差

                    if (diff > SENSITIVITY) {
                        boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3);//是否和之前的一樣大
                        boolean isPreviousLargeEnough = mLastDiff[k] > (diff / 3);//之前的差值是否一樣大
                        boolean isNotContra = (mLastMatch != 1 - extType);//不懂?

                        if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough
                                && isNotContra) {
                            end = System.currentTimeMillis();//時間判斷,ps:end-start本來是500,被我修改成了1000,以便觀察效果
                            if (end - start > 500) {// 此時判斷爲走了一步
                                Log.i(end - start+"",end - start+"aa"+diff);
                                CURRENT_SETP++;
                                mLastMatch = extType;
                                start = end;
                            }
                        } else {
                            mLastMatch = -1;//由於時間因素,當前數值的變化並不承認,也就是沒有匹配上
                        }
                    }
                    mLastDiff[k] = diff;//把當前的波峯波谷間的差值存下來,便於下次繼續判斷
                }
                mLastDirections[k] = direction;//存下當前波形的方向
                mLastValues[k] = v;//存下當前的加速度值
            }
        }
    }
    //當傳感器的精度發生變化時就會調用這個方法,在這裏沒有用
    public void onAccuracyChanged(Sensor arg0, int arg1) {

    }

}

【轉載】智能手機計步器算法的實現

計步器

基於安卓的計步器實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章