我在获取方向传感器读数时遇到了问题。 传感器读数似乎不可靠,所以我使用了两个免费的传感器测试应用程序(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)我已经检查了准确性灵敏度,并且当两个传感器都声称具有高准确性时,不一致性会发生。
作为我看到的不一致性的例子,当上面的代码给出(方位角,俯仰角,翻滚角)=(235,-52,-11)时,两个免费应用程序显示类似的值。但是当我看到(278,-58,-52)时,应用程序显示(256,-58,-26),因此方位角和翻滚角都有很大的差异,尽管俯仰角似乎没问题。
remapCoordinates()
。我在你的帖子(http://math.stackexchange.com/questions/381649/whats-the-best-3d-angular-co-ordinate-system-for-working-with-smartphone-apps/382048#382048)中读到你认为`remapCoordinates()`不是一个好的解决方案。但是在你的例子中,roll也会影响azimuth。那么如何在你的方法中忽略roll呢? - unlimited101