我在做Android的使用指南针和加速计传感器显示旋转我的设备和倾斜程度我自己的应用程序。我初始化所有的监听器和对象,我需要(我也跟着一些教程),现在我能赶上度,我想。问题是,该传感器返回的措施是不准确的。我的意思是,即使我尝试从传感器回合度我抓到值,它们振荡的 - / + 7(或8)第二度之数,即使我留在草地远离干扰源。我想有一个准确的衡量度,像一个方法,圆我从传感器免费获赠价值。
浮法[]弹匣= NULL;
浮动[] ACCELS = NULL;
浮动[] R =新的浮动[matrix_size]
浮动[] OUTR =新的浮动[matrix_size]
浮动[] I =新的浮动[matrix_size]
浮动[]值= NULL;
私人无效startSensor(){
sensorMan.registerListener(这一点,sensorMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_UI);
sensorMan.registerListener(这一点,sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_UI);
}
@覆盖
公共无效onSensorChanged(SensorEvent事件){
如果(event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE){
返回;
}
开关(event.sensor.getType()){
案例Sensor.TYPE_MAGNETIC_FIELD:
弹匣= event.values.clone();
打破;
案例Sensor.TYPE_ACCELEROMETER:
ACCELS = event.values.clone();
打破;
}
如果(弹匣= NULL和放大器;!&安培;!ACCELS = NULL){
SensorManager.getRotationMatrix(R,I,ACCELS,弹匣);
//正确的,如果屏幕处于横向
SensorManager.remapCoordinateSystem(R,SensorManager.AXIS_X,
SensorManager.AXIS_Z,OUTR);
SensorManager.getOrientation(OUTR,价值观);
方位角=(浮点)Math.round((Math.toDegrees(值[0]))* 7)/ 7;
方位角=(方位角+ 360)%360;
//这里是倾向。现在的问题是一样的带指南针
//inclination=-Math.round((float)(值[1] *(360 /(2 * Math.PI))));
//其他code更新我的看法
//方位我有度值。它不断地变化
//即使我的目标仍然是相同的方向
}
}
解决方案
在这里看到我的回答:Help从传感器平滑数据
我将它们传递给 SensorManager.getRotationMatrix之前先运行此过滤器在两个加速计和magetometer事件值()
。我认为这个算法有没有让大阵历史价值的优势,就在之前的低通输出数组。
该算法是从这个Wikipedia条目来源: http://en.wikipedia.org /维基/低pass_filter#Algorithmic_implementation
i made my own application in Android that use compass and accelerometer sensors to display the degrees of rotation and inclination of my device. I initialized all the listener and objects i needed (i followed some tutorials), and now i can catch the degrees as i wished. The problem is that the measures that sensors return aren't accurate. I mean even if i try to round the values of degrees i catch from the sensor, they oscillate between -/+ 7 (or 8) degrees every fraction of a second, even if i stay in a grass field away from any disturbing source. What i want to have is a accurate measure of the degrees, something like a method to round the values i recieve from the sensors.
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
}
}
解决方案
See my answer here: Help smoothing data from a sensor
I run this filter on both the accelerometer and magetometer event values before passing them to SensorManager.getRotationMatrix()
. I think this algorithm has the advantage of not having to keep a large array of historic values, just the prior low-pass output array.
The algorithm was derived from this Wikipedia entry: http://en.wikipedia.org/wiki/Low-pass_filter#Algorithmic_implementation