Android: Problemas al calcular la orientación del dispositivo

Estoy tratando de construir una aplicación de Realidad Aumentada simple, así que empiezo a trabajar con datos de sensores.

De acuerdo con este hilo ( ejemplo de la brújula de Android ) y el ejemplo ( http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html ), el cálculo de la orientación utilizando el Sensor.TYPE_ACCELEROMETER y Sensor. TYPE_MAGNETIC_FIELD no encaja realmente.

Así que no soy capaz de obtener valores "buenos". Los valores azimut no tiene ningún sentido en absoluto, por lo que si sólo muevo el teléfono al alza el valor cambia extremadamente. Incluso si solo hago girar el teléfono, los valores no representan la orientación de los teléfonos.

¿Alguien tiene una idea, que para mejorar la calidad de los valores de acuerdo con el ejemplo dado?

¿En qué tipo de orientación utiliza esta aplicación de ejemplo? De lo que se escribe es este código, la única orientación soportada es vertical o plana sobre la mesa, depende de los dispositivos. ¿Qué quieres decir con "bueno"?

Es normal que el valor no sea "bueno" al girar el dispositivo, se supone que el sistema de coordenadas del dispositivo está funcionando en Vertical, o plano i no lo sé (eje Y vertical a lo largo de la pantalla apuntando hacia arriba, eje Z apuntando hacia fuera La pantalla procedente del centro de la pantalla, eje X perpendicular al eje Y que va a la derecha a lo largo de la pantalla). Teniendo esto, la rotación del dispositivo no girará el sistema de coordenadas del dispositivo, tendrá que remapearlo.

Pero si quieres que el título del dispositivo en la orientación vertical, aquí es un pedazo de código que funciona bien para mí:

@Override public void onSensorChanged(SensorEvent event) { // It is good practice to check that we received the proper sensor event if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { // Convert the rotation-vector to a 4x4 matrix. SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values); SensorManager .remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, mRotationMatrix); SensorManager.getOrientation(mRotationMatrix, orientationVals); // Optionally convert the result from radians to degrees orientationVals[0] = (float) Math.toDegrees(orientationVals[0]); orientationVals[1] = (float) Math.toDegrees(orientationVals[1]); orientationVals[2] = (float) Math.toDegrees(orientationVals[2]); tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: " + orientationVals[1] + "\n Roll (not used): " + orientationVals[2]); } } 

Obtendrá el encabezado (o acimut) en:

 orientationVals[0] 

Respuesta de Tíbó es bueno, pero si registra valor de rollo, usted esperará números irregulares. (Roll es importante para los navegadores AR)

Esto es debido a

 SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, mRotationMatrix); 

Tienes que usar matriz diferente para dentro y fuera de remapear. Este código siguiente funciona para mí con un valor de rollo correcto:

 @Override public void onSensorChanged(SensorEvent event) { // It is good practice to check that we received the proper sensor event if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { // Convert the rotation-vector to a 4x4 matrix. SensorManager.getRotationMatrixFromVector(mRotationMatrixFromVector, event.values); SensorManager.remapCoordinateSystem(mRotationMatrixFromVector, SensorManager.AXIS_X, SensorManager.AXIS_Z, mRotationMatrix); SensorManager.getOrientation(mRotationMatrix, orientationVals); // Optionally convert the result from radians to degrees orientationVals[0] = (float) Math.toDegrees(orientationVals[0]); orientationVals[1] = (float) Math.toDegrees(orientationVals[1]); orientationVals[2] = (float) Math.toDegrees(orientationVals[2]); tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: " + orientationVals[1] + "\n Roll (not used): " + orientationVals[2]); } } 

Probablemente tarde para la fiesta. De todos modos aquí es cómo conseguí el acimut

 private final int sensorType = Sensor.TYPE_ROTATION_VECTOR; float[] rotMat = new float[9]; float[] vals = new float[3]; @Override public void onSensorChanged(SensorEvent event) { sensorHasChanged = false; if (event.sensor.getType() == sensorType){ SensorManager.getRotationMatrixFromVector(rotMat, event.values); SensorManager .remapCoordinateSystem(rotMat, SensorManager.AXIS_X, SensorManager.AXIS_Y, rotMat); SensorManager.getOrientation(rotMat, vals); azimuth = deg(vals[0]); // in degrees [-180, +180] pitch = deg(vals[1]); roll = deg(vals[2]); sensorHasChanged = true; } } 

Espero eso ayude

¿Ha probado el tipo Sensor.TYPE_ROTATION_VECTOR combinado (sensor-fusion). Esto puede dar mejores resultados: Vaya a https://developer.android.com/reference/android/hardware/SensorEvent.html y busque 'rotation_vector'.

  • Obtener el ángulo del dispositivo mediante la función getOrientation ()
  • ¿Cómo puedo bloquear el diseño de mi programa Android a una orientación
  • ¿Qué hace SampleRate.MS16, MS32, MS128 stand para cuando está asociado con oyentes de sensor?
  • Android - Cómo acercarse al algoritmo de detección de caídas
  • Cómo utilizar SensorManager.getOrientation () en lugar de TYPE_ORIENTATION
  • ¿Cómo voy a detectar el sensor de movimiento en el receptor de radiodifusión?
  • Acelerómetro (acceso rápido) mediante NativeActivity NDK
  • Android - SensorManager comportamiento extraño de getOrientation
  • Android: ¿Cómo se trata con baromters inexactos?
  • Galaxy s3 tiene sensor de temperatura?
  • Android PhoneGap obtener guiñada, tono, rollo, relativo a las coordenadas de tierra
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.