¿Cómo debo calcular el azimut, el tono, la orientación cuando mi dispositivo Android no es plano?

Estoy usando los sensores de campo magnético y de gravedad de Android para calcular la orientación a través de SensorManager.getRotationMatrix y SensorManager.getOrientation. Esto me da el azimut, el tono y los números de orientación. Los resultados parecen sensibles cuando el dispositivo está acostado sobre una mesa.

Sin embargo, he deshabilitado conmutadores entre retrato y paisaje en el manifiesto, de modo que getWindowManager (). GetDefaultDisplay (). GetRotation () siempre es cero. Cuando giro el dispositivo en 90 grados para que esté de pie vertical me encuentro con problemas. A veces los números parecen bastante equivocados, y me he dado cuenta de que esto se relaciona con la cerradura de Gimbal . Sin embargo, otras aplicaciones no parecen tener este problema. Por ejemplo, comparé mi aplicación con dos aplicaciones de prueba de sensor gratuitas ( Sensor Tester (Dicotomica) y Sensor Monitoring (Software de R) ). Mi aplicación está de acuerdo con estas aplicaciones cuando el dispositivo es plano, pero al girar el dispositivo a la posición vertical puede haber diferencias significativas. Las dos aplicaciones parecen estar de acuerdo, así que ¿cómo se solucionan este problema?

Creo que la mejor manera de definir sus ángulos de orientación cuando el dispositivo no es plano es utilizar un sistema de coordenadas angulares más apropiado que los ángulos Euler estándar que obtiene de SensorManager.getOrientation(...) . Sugiero el que describo aquí en math.stackexchange.com . También he puesto algún código que lo implementa en una respuesta aquí . Aparte de una buena definición de azimut, también tiene una definición del ángulo de tono que es exactamente el ángulo dado por Math.acos(rotationMatrix[8]) que se menciona en otra respuesta aquí.

Puede obtener detalles completos de los dos enlaces que he dado en el primer párrafo. Sin embargo, en resumen, su matriz de rotación R de SensorManager.getRotationMatrix (…) es

Ecuación con definición de matriz R

Donde (E x , E y , E z ), (N x , N y , N z ) y (G x , G y , G z ) son vectores que apuntan hacia el este, el norte y en la dirección de la gravedad. Entonces el ángulo azimutal que usted quiere es dado por

Ecuación que define el ángulo azimutal

Cuando el dispositivo no es plano, tiene que llamar a remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR); Antes de llamar a getOrientation .

Los retornos de azimuth por getOrientation se obtienen mediante la proyección ortogonal del Y axis unidad del dispositivo en el East-North plane del mundo y luego calcular el ángulo entre el vector de proyección resultante y el eje Norte.

Ahora normalmente pensamos en dirección como la dirección donde la cámara trasera está apuntando. Esa es la dirección de -Z donde Z es el eje del dispositivo que apunta fuera de la pantalla. Cuando el dispositivo es plano, no pensamos en la dirección y aceptamos lo que jamás se haya dado. Pero cuando no es plana, esperamos que sea la dirección de -Z . Pero getOrientation calcula la dirección del Y axis , por lo que necesitamos intercambiar los Y and Z axes antes de llamar a getOrientation . Eso es exactamente lo que hace remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR) , mantiene el X axis intacto y remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR) Z to Y

Ahora, ¿cómo saber cuándo remap o no. Puede hacerlo comprobando

 float inclination = (float) Math.acos(rotationMatrix[8]); if (result.inclination < TWENTY_FIVE_DEGREE_IN_RADIAN || result.inclination > ONE_FIFTY_FIVE_DEGREE_IN_RADIAN) { // device is flat just call getOrientation } else { // call remap } 

La inclinación anterior es el ángulo entre la pantalla del dispositivo y el plano East-North del mundo. Muestra cuánto está inclinando el dispositivo.

  • Android: Problemas al calcular la orientación del dispositivo
  • ¿Cómo rastrear la posición de un dispositivo Android en un edificio?
  • Acelerómetro (acceso rápido) mediante NativeActivity NDK
  • Activar y desactivar la pantalla mediante programación en android
  • Obtener el ángulo del dispositivo mediante la función getOrientation ()
  • Protocolo de comunicación fiable y ligero para móviles
  • ¿El filtrado del acelerómetro de Android?
  • ¿Cómo puedo bloquear el diseño de mi programa Android a una orientación
  • Rotación Opengl de Android con datos de sensores
  • ¿Cómo reemplazar adecuadamente Sensor.TYPE_ORIENTATION (que ahora está obsoleto)?
  • ¿Cómo puedo rotar la pantalla sólo en modo horizontal en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.