我在Android中制作了自己的应用程序,使用指南针和加速计传感器来显示设备的旋转度和倾斜度。我初始化了我需要的所有监听器和对象(我遵循了一些教程),现在我可以按照自己的意愿捕获学位。问题是传感器返回的措施不准确。我的意思是,即使我试图将传感器捕获的度数值四舍五入,它们也会在每秒几分钟内在 - / + 7(或8)度之间振荡,即使我留在草地上远离任何干扰源。我想要的是一个精确的度数度量,类似于我从传感器接收的值的方法。
float[] mags = null;
float[] accels = null;
float[] R = new float[matrix_size];
float[] outR = new float[matrix_size];
float[] I = new float[matrix_size];
float[] values = null;
private void startSensor() {
sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
switch (event.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD:
mags = event.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER:
accels = event.values.clone();
break;
}
if (mags != null && accels != null) {
SensorManager.getRotationMatrix(R, I, accels, mags);
// Correct if screen is in Landscape
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X,
SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, values);
azimuth = (float) Math.round((Math.toDegrees(values[0]))*7)/7;
azimuth = ( azimuth + 360)%360;
//here is inclination. The problem is just the same with compass
//inclination=-Math.round((float) (values[1]*(360/(2*Math.PI))));
//other code to update my view
//in azimuth i have the degree value. It changes continuously
//even if i aim still the same direction
}
}
答案 0 :(得分:1)
请在此处查看我的回答:Smoothing data from a sensor
我在加速度计和magetometer事件值上运行此过滤器,然后将它们传递给SensorManager.getRotationMatrix()
。我认为这种算法的优点是不需要保留大量的历史值,只需要保留先前的低通输出数组。
该算法源自此维基百科条目:http://en.wikipedia.org/wiki/Low-pass_filter#Algorithmic_implementation
答案 1 :(得分:0)
你所看到的是真实的东西 - 大多数手机上的方向传感器只能给你一个粗略的罗盘标题。
如果你想平滑显示的值,那么它会给你一些似乎没有随机改变的东西我建议在Java上用这个方向结果实现http://en.wikipedia.org/wiki/Moving_average或其他平滑滤波器。
为获得最高性能,您可以使用NDK编写过滤器并使用Boost Accumulators库:http://www.boost.org/doc/libs/1_46_1/doc/html/accumulators.html
答案 2 :(得分:0)
我是从这里使用卡尔曼滤波器做到的: Greg Czerniak's Website
我将数据发送到udp端口并使用python在PC上平滑它。 但我想你可以在那里找到java / android的卡尔曼滤波器实现。