He estado tratando de entender los sensores de orientación de Android durante un tiempo. Creí entenderlo. Entonces me di cuenta de que no. Ahora creo (espero) tener un mejor presentimiento de nuevo, pero todavía no estoy al 100%. Intentaré explicar mi comprensión irregular y espero que la gente pueda corregirme si me equivoco en algunas partes o si lleno los espacios en blanco.
Me imagino que estoy parado a 0 grados de longitud (primer meridiano) y 0 grados de latitud (ecuador). Esta ubicación está en el mar frente a la costa de África, pero tengan paciencia conmigo. Sostengo mi teléfono frente a mi cara para que la parte inferior del teléfono apunte a mis pies; Estoy de cara al norte (mirando hacia Greenwich), por lo que el lado derecho del teléfono apunta al este, hacia África. En esta orientación (con referencia al diagrama de abajo) tengo el eje X apuntando hacia el este, el eje Z apunta hacia el sur y el eje Y apunta hacia el cielo.
Ahora, los sensores del teléfono le permiten determinar la orientación (no la ubicación) del dispositivo en esta situación. Esta parte siempre me ha confundido, probablemente porque quería entender cómo funcionaba algo antes de aceptar que simplemente funcionaba. Parece que el teléfono calcula su orientación utilizando una combinación de dos técnicas diferentes.
Antes de llegar a eso, imagina estar de nuevo parado en ese pedazo de tierra imaginario a 0 grados de latitud y longitud en la dirección mencionada anteriormente. Imagínese también que tiene los ojos vendados y sus zapatos están fijados a una rotonda de juegos. Si alguien te empuja por la espalda, caerás hacia adelante (hacia el norte) y extenderás ambas manos para frenar la caída. De manera similar, si alguien te empuja en el hombro izquierdo, caerás sobre tu mano derecha. Su oído interno tiene "sensores gravitacionales" (clip de youtube) que le permiten detectar si está cayendo hacia adelante / atrás, o hacia la izquierda / derecha o cayendo (¡o hacia arriba!). Por lo tanto, los humanos pueden detectar la alineación y la rotación alrededor de los mismos ejes X y Z que el teléfono.
Ahora imagina que alguien ahora te gira 90 grados en la rotonda para que ahora mires hacia el este. Se le está rotando alrededor del eje Y. Este eje es diferente porque no podemos detectarlo biológicamente. Sabemos que estamos en cierto ángulo pero no sabemos la dirección en relación con el polo norte magnético del planeta. En su lugar, necesitamos usar una herramienta externa ... una brújula magnética. Esto nos permite determinar en qué dirección estamos mirando. Lo mismo ocurre con nuestro teléfono.
Ahora el teléfono también tiene un acelerómetro de 3 ejes. Tengo NOTengo idea de cómo funcionan realmente, pero la forma en que lo visualizo es imaginar la gravedad como una 'lluvia' constante y uniforme que cae del cielo e imaginar los ejes en la figura de arriba como tubos que pueden detectar la cantidad de lluvia que fluye a través. Cuando el teléfono se mantiene en posición vertical, toda la lluvia fluirá a través del 'tubo' en Y. Si el teléfono se gira gradualmente para que la pantalla mire hacia el cielo, la cantidad de lluvia que fluye a través de Y disminuirá a cero, mientras que el volumen a través de Z aumentará de manera constante hasta que fluya la cantidad máxima de lluvia. De manera similar, si ahora inclinamos el teléfono hacia un lado, el tubo X eventualmente recogerá la cantidad máxima de lluvia. Por lo tanto, dependiendo de la orientación del teléfono midiendo la cantidad de lluvia que fluye a través de los 3 tubos, puede calcular la orientación.
El teléfono también tiene una brújula electrónica que se comporta como una brújula normal: su "aguja virtual" apunta al norte magnético. Android fusiona la información de estos dos sensores para que, siempre que se genere una SensorEvent
de, TYPE_ORIENTATION
la values[3]
matriz tenga
valores [0]: Azimut - (la brújula que se dirige al este del norte magnético)
valores [1]: Paso, rotación alrededor del eje x (es el teléfono inclinado hacia adelante o hacia atrás)
valores [2]: Rollo, rotación alrededor del eje y (el teléfono está inclinado sobre su lado izquierdo o derecho)
Así que creo (es decir, no sé) que la razón por la que Android da el acimut (rumbo de la brújula) en lugar de la lectura del tercer acelerómetro es que el rumbo de la brújula es más útil. No estoy seguro de por qué desaprobaron este tipo de sensor, ya que ahora parece que necesita registrar un oyente con el sistema para SensorEvent
s de tipo TYPE_MAGNETIC_FIELD
. La value[]
matriz del evento debe pasarse al SensorManger.getRotationMatrix(..)
método para obtener una matriz de rotación (ver más abajo) que luego se pasa al SensorManager.getOrientation(..)
método. ¿Alguien sabe por qué el equipo de Android está obsoleto Sensor.TYPE_ORIENTATION
? ¿Es una cuestión de eficiencia? Eso es lo que está implícito en uno de los comentarios a una pregunta similar , pero aún necesita registrar un tipo diferente de oyente en eldesarrollo / samples / Compass / src / com / example / android / compass / CompassActivity.java ejemplo.
Ahora me gustaría hablar sobre la matriz de rotación. (Aquí es donde no estoy seguro) Así que arriba tenemos las tres cifras de la documentación de Android, las llamaremos A, B y C.
A = Figura del método SensorManger.getRotationMatrix (..) y representa el sistema de coordenadas del mundo
B = Sistema de coordenadas utilizado por la API SensorEvent.
C = Figura del método SensorManager.getOrientation (..)
Así que tengo entendido que A representa el "sistema de coordenadas del mundo" que supongo que se refiere a la forma en que las ubicaciones en el planeta se dan como un par (latitud, longitud) con una (altitud) opcional. X es el "easting" co-ordenada, Y es el "northing" co-ordenadas. Z apunta al cielo y representa la altitud.
El sistema de coordenadas de los teléfonos que se muestra en la figura B es fijo. Su eje Y siempre apunta hacia arriba. El teléfono calcula constantemente la matriz de rotación y permite el mapeo entre los dos. Entonces, ¿tengo razón al pensar que la matriz de rotación transforma el sistema de coordenadas de B en C? Entonces, cuando llama al SensorManager.getOrientation(..)
método, usa la values[]
matriz con valores que corresponden a la figura C.Cuando el teléfono apunta al cielo, la matriz de rotación es la matriz de identidad (la matriz matemática equivalente a 1), lo que significa que no es necesario un mapeo ya que el dispositivo está alineado con el sistema de coordenadas del mundo.
Okay. Creo que mejor me detengo ahora. Como dije antes, espero que la gente me diga en qué me equivoqué o ayudé a la gente (¡o confundí a la gente aún más!)