我无法获得良好的方向传感器读数。传感器读数似乎不可靠,因此我针对两个免费的传感器测试应用程序(Sensor Tester (Dicotomica)和Sensor Monitoring (R's Software))测试了我的代码。我发现虽然我的读数通常与传感器测试应用程序一致,但有时方位角/偏航角和滚动的值相差高达 40 度,尽管俯仰读数大多一致。这两个免费应用程序似乎总是相互一致。
我将我的代码放入一个很小的 Android 活动中并得到了同样的不一致。代码如下:
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private float[] AccelerometerValues;
private float[] MagneticFieldValues;
private float[] RotationMatrix;
private long nextRefreshTime; // used to ensure dump to LogCat occurs no more than 4 times a second
private DecimalFormat df; // used for dumping sensors to LogCat
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager)getSystemService(android.content.Context.SENSOR_SERVICE);
Sensor SensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, SensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
Sensor SensorMagField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, SensorMagField, SensorManager.SENSOR_DELAY_UI);
AccelerometerValues = new float[3];
MagneticFieldValues = new float[3];
RotationMatrix = new float[9];
nextRefreshTime = 0;
df = new DecimalFormat("#.00");
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
System.arraycopy(event.values, 0, AccelerometerValues, 0, AccelerometerValues.length);
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
System.arraycopy(event.values, 0, MagneticFieldValues, 0, MagneticFieldValues.length);
if (AccelerometerValues != null && MagneticFieldValues != null) {
if(SensorManager.getRotationMatrix(RotationMatrix, null, AccelerometerValues, MagneticFieldValues)) {
float[] OrientationValues = new float[3];
SensorManager.getOrientation(RotationMatrix, OrientationValues);
// chance conventions to match sample apps
if (OrientationValues[0] < 0) OrientationValues[0] += 2*(float)Math.PI;
OrientationValues[2] *= -1;
// dump to logcat 4 times a second
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis > nextRefreshTime) {
nextRefreshTime = currentTimeMillis+250;
Log.i("Sensors", // arrange output so that numbers line up in columns :-)
"(" + AngleToStr(OrientationValues[0]) + "," + AngleToStr(OrientationValues[1]) + "," + AngleToStr(OrientationValues[2])
+ ") ("+FloatToStr(AccelerometerValues[0]) + "," + FloatToStr(AccelerometerValues[1]) + "," + FloatToStr(AccelerometerValues[2])
+ ") ("+FloatToStr(MagneticFieldValues[0]) + "," + FloatToStr(MagneticFieldValues[1]) + "," + FloatToStr(MagneticFieldValues[2])+")");
}
}
}
}
private String AngleToStr(double AngleInRadians) {
String Str = " "+Integer.toString((int)Math.toDegrees(AngleInRadians));
return Str.substring(Str.length() - 3);
}
private String FloatToStr(float flt) {
String Str = " "+df.format(flt);
return Str.substring(Str.length() - 6);
}
@Override
protected void onDestroy() {
super.onDestroy();
mSensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) { }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
我正在使用运行 Jelly Bean 4.1.1 的 Galaxy Note 2。谁能告诉我我做错了什么?
2013 年 3 月 24 日更新:更多信息。(1) 我在清单中禁用了纵向和横向之间的切换,因此 getWindowManager().getDefaultDisplay().getRotation() 始终为零。因此,我认为 remapCoordSystem 在这里没有帮助,因为那是用于切换轴,而我看到的错误并不是大错误,它们更加微妙。(2)我检查了精度灵敏度,当两个传感器都声称具有高精度时,就会出现不一致的情况。
作为我看到的不一致的示例,当上面的代码给我 (azimuth,pitch,roll) = (235,-52,-11) 时,这两个免费应用程序显示相似的值。但是当我看到 (278, -58, -52) 应用程序显示 (256, -58, -26) 时,方位角和滚动的差异如此之大,尽管俯仰似乎还可以。