Pregunta

He estado tratando de entender los sensores de orientación de Android por un tiempo. Pensé que lo entendí. Entonces me di cuenta de que no lo hacía. Ahora creo que (espero) tengo una mejor sensación 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 partes o llené cualquier espacio en blanco.

Me imagino que estoy de pie a 0 grados de longitud (meridiano principal) y 0 grados de latitud (ecuador). Esta ubicación está en realidad 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 me apunte a los pies; Estoy mirando al norte (mirando hacia Greenwich), por lo tanto, el lado derecho del teléfono señala hacia el este hacia África. En esta orientación (con referencia al diagrama a continuación) tengo el eje X apuntando hacia el este, el eje Z apunta al sur e al eje y apunta al cielo.

Ahora los sensores en el teléfono le permiten resolver 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 resuelve su orientación utilizando una combinación de dos técnicas diferentes.

Antes de llegar a eso, imagine volver a estar parado en ese terreno imaginario a 0 grados de latitud y longitud en la dirección mencionada anteriormente. Imagine también que tiene los ojos vendados y que sus zapatos se fijan en una rotonda del patio de recreo. Si alguien te empuja en la parte de atrás, caerás hacia adelante (hacia el norte) y pondrás ambas manos para romper tu caída. Del mismo modo, si alguien te empuja el hombro izquierdo, te caerás sobre tu mano derecha. Tu oído interno tiene "sensores gravitacionales" (clip de youtube) que le permiten detectar si está cayendo hacia adelante/hacia atrás, o cae a la izquierda/derecha o cae (¡o 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 imagine que alguien ahora le gira 90 grados en la rotonda para que ahora esté mirando hacia el este. Estás siendo rotado alrededor del eje Y. Este eje es diferente porque no podemos detectarlo biológicamente. Sabemos que estamos en ángulo por una cierta cantidad, 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 nos enfrentamos. Lo mismo es cierto con nuestro teléfono.

Ahora el teléfono también tiene un acelerómetro de 3 ejes. tengo NO 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. Cuando el teléfono se mantuvo en posición vertical, toda la lluvia fluirá a través del 'tubo'. Si el teléfono gira gradualmente, por lo que su pantalla se enfrenta al cielo, la cantidad de lluvia que fluye a través de Y disminuirá a cero, mientras que el volumen a Z aumentará constantemente hasta que fluya la cantidad máxima de lluvia. Del mismo modo, si ahora inclinamos el teléfono a su lado, el tubo X eventualmente recolectará 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 cada vez sea un SensorEvent de TYPE_ORIENTATION se genera el values[3] la matriz tiene
Valores [0]: Azimut - (el rumbo de la brújula al este de Magnetic North)
Valores [1]: tono, rotación alrededor del eje X (es el teléfono inclinado hacia adelante o hacia atrás)
Valores [2]: Roll, rotación alrededor del eje y (es el teléfono inclinado sobre su lado izquierdo o derecho)

Así que creo que (es decir, no sé) la razón por la que Android le da al acimut (rodamiento de brújulas) en lugar de la lectura del tercer acelerómetro es que el rodamiento de la brújula es simplemente más útil. No estoy seguro de por qué desaprobaron este tipo de sensor, ya que ahora parece que necesita registrar un oyente en el sistema para SensorEventS de tipo TYPE_MAGNETIC_FIELD. Los eventos value[] la matriz debe superarse en SensorManger.getRotationMatrix(..) método para obtener una matriz de rotación (ver más abajo) que luego se pasa a la SensorManager.getOrientation(..) método. ¿Alguien sabe por qué el equipo de Android se desappre? Sensor.TYPE_ORIENTATION? ¿Es una cosa de eficiencia? Eso es lo que está implícito en uno de los comentarios a un pregunta Pero aún necesita registrar un tipo diferente de oyente en el desarrollo/muestras/compass/src/com/ejemplo/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 figuras de la documentación de Android, las llamaremos A, B y C.

A = sensorManger.getrotationMatrix (..) figura del método y representa el sistema de coordenadas del mundo

B = Sistema de coordenadas utilizado por la API Sensorvent.

C = sensorManager.getorientation (..) figura del método

Por lo tanto, entiendo que A representa el "sistema de coordenadas mundial" que supongo que se refiere a la forma en que las ubicaciones en el planeta se dan como una pareja (de latitud, longitud) con una opcional (altitud). X es el "dirección del este" coordinado, y es el "Norma" coordinar. Z apunta al cielo y representa la altitud.

El sistema de coordenadas de teléfonos se muestra en la Figura B se fija. Su eje Y siempre señala la parte superior. La matriz de rotación está siendo calculada constantemente por el teléfono y permite mapeo entre los dos. Entonces, ¿tengo razón al pensar que la matriz de rotación transforma el sistema de coordenadas de B a C? Entonces cuando llamas SensorManager.getOrientation(..) método que usa el 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 (el equivalente matemático de la matriz de 1), lo que significa que no se necesita mapeo ya que el dispositivo está alineado con el sistema de coordenadas del mundo.

Está bien. Creo que es mejor que me detenga ahora. Como dije antes, espero que la gente me diga dónde me he equivocado o ayudé a la gente (¡o a las personas confundidas aún más!)

¿Fue útil?

Solución

Es posible que desee ver el Un giro de pantalla merece otro artículo. Explica por qué necesita la matriz de rotación.

En pocas palabras, los sensores del teléfono siempre usan el mismo sistema de coordenadas, incluso cuando se gira el dispositivo.

En las aplicaciones que no están bloqueadas a una sola orientación, el sistema de coordenadas de la pantalla cambia cuando gira el dispositivo. Por lo tanto, cuando el dispositivo se gira desde su modo de vista predeterminado, el sistema de coordenadas del sensor ya no es el mismo que el sistema de coordenadas de pantalla. La matriz de rotación en este caso se usa para transformar A a C (B siempre permanece fija).

Aquí hay un fragmento de código para mostrarle cómo se puede usar.

SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);

// Register this class as a listener for the accelerometer sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                    SensorManager.SENSOR_DELAY_NORMAL);
// ...and the orientation sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                    SensorManager.SENSOR_DELAY_NORMAL);

//...
// The following code inside a class implementing a SensorEventListener
// ...

float[] inR = new float[16];
float[] I = new float[16];
float[] gravity = new float[3];
float[] geomag = new float[3];
float[] orientVals = new float[3];

double azimuth = 0;
double pitch = 0;
double roll = 0;

public void onSensorChanged(SensorEvent sensorEvent) {
    // If the sensor data is unreliable return
    if (sensorEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        return;

    // Gets the value of the sensor that has been changed
    switch (sensorEvent.sensor.getType()) {  
        case Sensor.TYPE_ACCELEROMETER:
            gravity = sensorEvent.values.clone();
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            geomag = sensorEvent.values.clone();
            break;
    }

    // If gravity and geomag have values then find rotation matrix
    if (gravity != null && geomag != null) {

        // checks that the rotation matrix is found
        boolean success = SensorManager.getRotationMatrix(inR, I,
                                                          gravity, geomag);
        if (success) {
            SensorManager.getOrientation(inR, orientVals);
            azimuth = Math.toDegrees(orientVals[0]);
            pitch = Math.toDegrees(orientVals[1]);
            roll = Math.toDegrees(orientVals[2]);
        }
    }
}

Otros consejos

El rollo es una función de la gravedad, un rollo de 90 grados pone toda la gravedad en el registro X.

El tono es el mismo, un lanzamiento de 90 grados pone todo el componente de la gravedad en el registro Y.

Yaw / Heading / Azimuth no tiene ningún efecto sobre la gravedad, siempre está en ángulo recto con la gravedad, por lo tanto, no importa en qué forma se enfrente a la gravedad será injustible.

Es por eso que necesita una brújula para evaluar, ¿tal vez tiene sentido?

Echa un vistazo a esto: Stackoverflow.com: Q.5202147

Parece que tiene razón hasta los 3 diagramas A, B, c. Después de eso te has confundido.

Estaba teniendo este problema, así que mapeé lo que sucede en diferentes direcciones. Si el dispositivo está montado en forma de paisaje, por ejemplo, en un automóvil monta los 'grados' de la brújula parecen funcionar de 0 a 275 (yendo en sentido horario) por encima de 269 (entre el oeste y el norte) cuenta de -90 a 0, entonces, entonces, entonces, entonces, entonces, entonces, entonces, entonces, entonces, entonces hacia adelante de 0 a 269. 270 se convierte en -90

Todavía en el paisaje pero con el dispositivo acostado boca arriba, mi sensor da 0-360. Y en modo de retrato, se ejecuta 0-360, ambos sobre su espalda y de pie en el retrato.

Espero que ayude a alguien

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top