指南针的方向因手机方向而异 [英] Compass direction is different depending on phone orientation
问题描述
我的增强现实应用程序需要摄像机视图的指南针方位,并且有很多示例可以从传感器管理器获取方向.
My augmented reality app needs the compass bearing of the camera view, and there's plenty of examples of getting the direction from the sensormanager.
但是,我发现结果值因手机方向而异-向右旋转的横向与向左旋转的横向大约10度(ROTATION_0和ROTATION_180之间的差异较小,但仍然不同).这种差异足以破坏任何AR效果.
However I'm finding the resulting value different depending on the phone orientation - landscape rotated to right is about 10 degrees different to landscape rotated to left (difference between ROTATION_0 and ROTATION_180 is less, but still different). This difference is enough to ruin any AR effect.
与校准有关吗? (我不相信自己在正确地完成8件事的数字-我尝试了各种在youtube上找到的方法).
Is it something to do with calibration? (I'm not convinced I'm doing the figure of 8 thing properly - I've tried various ways I've found on youtube).
任何想法为何会有区别?我搞砸了旋转矩阵的东西吗?我可以选择将应用程序限制为一个方向,但是仍然令我感到担忧的是,指南针的读数仍然不是很准确(即使经过过滤后它还是很稳定的)
Any ideas why there's a difference? Have I messed up on the rotation matrix stuff? I have the option of restricting the app to a single orientation, but it still concerns me that the compass reading still isn't very accurate (even though after filtering it's fairly stable)
public void onSensorChanged(SensorEvent event) {
if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float[] rotationMatrixA = mRotationMatrixA;
if (SensorManager.getRotationMatrix(rotationMatrixA, null, mGravity, mGeomagnetic)) {
float[] rotationMatrixB = mRotationMatrixB;
Display display = getWindowManager().getDefaultDisplay();
int deviceRot = display.getRotation();
switch (deviceRot)
{
// portrait - normal
case Surface.ROTATION_0: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_X, SensorManager.AXIS_Z,
rotationMatrixB);
break;
// rotated left (landscape - keys to bottom)
case Surface.ROTATION_90: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_X,
rotationMatrixB);
break;
// upside down
case Surface.ROTATION_180: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_X, SensorManager.AXIS_Z,
rotationMatrixB);
break;
// rotated right
case Surface.ROTATION_270: SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X,
rotationMatrixB);
break;
default: break;
}
float[] dv = new float[3];
SensorManager.getOrientation(rotationMatrixB, dv);
// add to smoothing filter
fd.AddLatest((double)dv[0]);
}
mDraw.invalidate();
}
}
推荐答案
尝试一下
public void onSensorChanged(SensorEvent event) {
if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) mGravity = event.values.clone ();
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) mGeomagnetic = event.values.clone ();
if (mGravity != null && mGeomagnetic != null) {
float[] rotationMatrixA = mRotationMatrixA;
if (SensorManager.getRotationMatrix(rotationMatrixA, null, mGravity, mGeomagnetic)) {
float[] rotationMatrixB = mRotationMatrixB;
SensorManager.remapCoordinateSystem(rotationMatrixA,
SensorManager.AXIS_X, SensorManager.AXIS_Z,
rotationMatrixB);
float[] dv = new float[3];
SensorManager.getOrientation(rotationMatrixB, dv);
// add to smoothing filter
fd.AddLatest((double)dv[0]);
}
mDraw.invalidate();
}
}
您不需要switch语句,由于stackoverflow问题,关于getRotationMatrix,remapCoordinateSystem和getOrientation似乎存在很多困惑.
我可能会在不久的将来写详细的解释.
You do not need the switch statement, there seems to be a lot of confusion concerning getRotationMatrix, remapCoordinateSystem and getOrientation from stackoverflow questions.
I probably will write a detail explanation of these in the near future.
这篇关于指南针的方向因手机方向而异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!