gpt4 book ai didi

java - 忽略 SensorEventListener( compass 应用程序)的微小变化

转载 作者:太空宇宙 更新时间:2023-11-04 13:59:32 24 4
gpt4 key购买 nike

我正在创建一个用于测试目的的 compass 应用程序,它工作得很好,箭头图像指向北极,但它变化太大,即使设备没有移动,也会在几毫秒内左右做出非常小的移动。

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

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) {
}

最佳答案

加速度计非常灵敏。

即使是最轻微的移动,传感器 type_accelerometer 也会触发 onSensorChanged。

检查 event.values[0]、event.values[1] 和 event.values[2] 值(设置一个阈值,超过该阈值 compass 就会响应),这些值本质上是 x、y 和 z 坐标加速度 vector 值。

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

这是一个低切滤波器:

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();
}

关于java - 忽略 SensorEventListener( compass 应用程序)的微小变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29446967/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com