Моему приложению дополненной реальности нужен компасный вид с камеры, и есть множество примеров получения направления от менеджера сенсоров.
Однако я нахожу результирующее значение разным в зависимости от ориентации телефона -Пейзаж, повернутый вправо, примерно на 10 градусов отличается от пейзажа, повернутого влево (разница между ROTATION_0 и ROTATION_180 меньше, но все же отличается).Этой разницы достаточно, чтобы испортить любой эффект AR.
Это как-то связано с калибровкой?(Я не уверен, что делаю цифру 8 правильно - я пробовал разные способы, которые я нашел на YouTube).
Есть идеи, почему есть разница?Я что-то напутал на матрице вращения?У меня есть возможность ограничить приложение одной ориентацией, но меня все равно беспокоит, что показания компаса все еще не очень точны (даже если после фильтрации они довольно стабильны)
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();
}
}