¿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?
- Android - SensorManager comportamiento extraño de getOrientation
- Android: ¿Cómo se trata con baromters inexactos?
- Sistema de coordenadas del dispositivo Android Convert a sistema de coordenadas "usuario"
- Cómo utilizar el evento del sensor Android para determinar si el dispositivo está orientado hacia arriba o hacia abajo
- ¿Qué hace SampleRate.MS16, MS32, MS128 stand para cuando está asociado con oyentes de sensor?
- Diferentes valores entre los sensores TYPE_ACCELEROMETER / TYPE_MAGNETIC_FIELD y TYPE_ORIENTATION
- Comportamiento extraño con el sensor de orientación de Android
- Detectar si el teléfono está en el bolsillo o no
- ¿Cómo voy a detectar el sensor de movimiento en el receptor de radiodifusión?
- ¿Puede guardar / ver un archivo de vídeo y los datos del sensor simultáneamente?
- Valor de Android: Sensor.getResolution ()
- Utilizar getRotationMatrix y getOrientation en Android 2.1
- Android - Cómo acercarse al algoritmo de detección de caídas
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
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
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.
- Uso de la biblioteca de soporte de Android 23.2 en build.gradle bloquea la aplicación (XmlPullParserException: XmlPullParserException: vector de etiqueta drawable no válido)
- Ventaja dibujable sobre mapa de bits para la memoria en android