忽略SensorEventListener(指南针应用程序)的小更改

时间:2015-04-04 13:25:26

标签: java android compass sensormanager

我正在创建一个用于测试目的的指南针应用程序,它工作正常,箭头图像指向北极,但它变化太大,即使设备不是,也会在几毫秒左右左右进行非常小的移动移动。

我的问题是如何忽略这些微小变化?谢谢

public class Compass implements SensorEventListener {
private static final String TAG = "Compass";

private SensorManager sensorManager;
private Sensor gsensor;
private Sensor msensor;
private float[] mGravity = new float[3];
private float[] mGeomagnetic = new float[3];
private float azimuth = 0f;
private float currectAzimuth = 0;

// compass arrow to rotate
public ImageView arrowView = null;

public Compass(Context context) {
    sensorManager = (SensorManager) context
            .getSystemService(Context.SENSOR_SERVICE);
    gsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    msensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}

public void start() {
    sensorManager.registerListener(this, gsensor,
            SensorManager.SENSOR_DELAY_GAME);
    sensorManager.registerListener(this, msensor,
            SensorManager.SENSOR_DELAY_GAME);
}

public void stop() {
    sensorManager.unregisterListener(this);
}

private void adjustArrow() {
    if (arrowView == null) {
        Log.i(TAG, "arrow view is not set");
        return;
    }

    Log.i(TAG, "will set rotation from " + currectAzimuth + " to "
            + azimuth);

    Animation an = new RotateAnimation(-currectAzimuth, -azimuth,
            Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
            0.5f);
    currectAzimuth = azimuth;

    an.setDuration(500);
    an.setRepeatCount(0);
    an.setFillAfter(true);

    arrowView.startAnimation(an);
}

@Override
public void onSensorChanged(SensorEvent event) {
    final float alpha = 0.97f;

    synchronized (this) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

            mGravity[0] = alpha * mGravity[0] + (1 - alpha)
                    * event.values[0];
            mGravity[1] = alpha * mGravity[1] + (1 - alpha)
                    * event.values[1];
            mGravity[2] = alpha * mGravity[2] + (1 - alpha)
                    * event.values[2];

            // mGravity = event.values;

            // Log.e(TAG, Float.toString(mGravity[0]));
        }

        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            // mGeomagnetic = event.values;

            mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
                    * event.values[0];
            mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
                    * event.values[1];
            mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
                    * event.values[2];
            // Log.e(TAG, Float.toString(event.values[0]));

        }

        float R[] = new float[9];
        float I[] = new float[9];
        boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
                mGeomagnetic);
        if (success) {
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);
            // Log.d(TAG, "azimuth (rad): " + azimuth);
            azimuth = (float) Math.toDegrees(orientation[0]); // orientation
            azimuth = (azimuth + 360) % 360;
            // Log.d(TAG, "azimuth (deg): " + azimuth);
            adjustArrow();
        }
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

1 个答案:

答案 0 :(得分:0)

加速度计非常敏感。

onSensorChanged即使在最轻微的移动中也会被传感器type_accelerometer触发。

检查event.values [0],event.values [1]和event.values [2]值(设置一个超出指南针响应的阈值),其本质上是x,y和z co-纵坐标加速度矢量值。

您也可以在加速度计上使用滤镜。

这是一个低切滤镜:

public void onSensorChanged(SensorEvent se) {
  float x = se.values[0];
  float y = se.values[1];
  float z = se.values[2];
  mAccelLast = mAccelCurrent;
  mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
  float delta = mAccelCurrent - mAccelLast;
  mAccel = mAccel * 0.9f + delta; // perform low-cut filter
} 

然后:

if(mAccel>12||status)
  {
    //move compass : 
        float orientation[] = new float[3];
        SensorManager.getOrientation(R, orientation);
        // Log.d(TAG, "azimuth (rad): " + azimuth); 
        azimuth = (float) Math.toDegrees(orientation[0]); // orientation
        azimuth = (azimuth + 360) % 360;
        // Log.d(TAG, "azimuth (deg): " + azimuth); 
        adjustArrow(); 
  }