Mi aplicación de realidad aumentada necesita el rumbo de la brújula de la vista de la cámara, y hay muchos ejemplos de cómo obtener la dirección del administrador del sensor.La dirección de la brújula es diferente dependiendo de la orientación del teléfono
Sin embargo el valor resultante es diferente dependiendo de la orientación del teléfono: el paisaje girado a la derecha es aproximadamente 10 grados diferente al paisaje girado a la izquierda (la diferencia entre ROTATION_0 y ROTATION_180 es menor, pero aún diferente). Esta diferencia es suficiente para arruinar cualquier efecto AR.
¿Tiene algo que ver con la calibración? (No estoy convencido de que estoy haciendo la figura de 8 correctamente, he intentado de varias maneras que encontré en youtube).
¿Alguna idea de por qué hay una diferencia? ¿Me he equivocado en las cosas de la matriz de rotación? Tengo la opción de restringir la aplicación a una sola orientación, pero todavía me preocupa que la lectura de la brújula todavía no es muy preciso (a pesar de que después de la filtración es bastante estable)
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();
}
}
Hombre! He estado buscando SO durante más de 2 horas, y hay muchas respuestas INCORRECTAS. La tuya es la primera que realmente funciona correctamente para mí. Gracias por esto. – BoD
He copiado y editado la publicación. No me di cuenta de que Mush tenía mGravity = event.values, debería ser event.values.clone(). Lo mismo para mGeomagnetic –
'SensorManager.remapCoordinateSystem' es la solución. Gracias. –