Sensor de movimiento vertical

Estoy trabajando en una aplicación para Android que requiere la detección de movimiento vertical. Al mover la tableta hacia arriba, los sensores de giroscopio, acelerómetro y aceleración lineal dan un valor correspondiente que indica movimiento hacia arriba o hacia abajo.

El problema que tengo es que estos sensores también leerán un movimiento hacia arriba / hacia abajo cuando inclines la tableta hacia el usuario o lejos del usuario. Por ejemplo, el valor x en el giroscopio representa el plano vertical. Pero cuando inclina el dispositivo hacia adelante, el valor x cambiará. Cuando hago este movimiento, el mismo sensor que lee movimiento vertical lee un valor para esto. Introduzca aquí la descripción de la imagen

Lo mismo ocurre con el resto de los sensores. He intentado utilizar la orientación junto con el giroscopio para hacer la declaración condicional, si el tono no está cambiando, pero la variable x va hacia arriba / abajo, entonces tenemos movimiento vertical. El problema con esto es que si el usuario se mueve hacia arriba pero ligeramente inclinado, ya no funcionará. También he intentado hacerlo así que si hay un cambio en la inclinación, entonces no hay movimiento vertical. Pero itera tan rápidamente que puede haber un cambio en la inclinación de 1/100 de segundo, pero para el siguiente no lo es.

¿Hay alguna manera que puedo leer sólo cambios verticales y no cambios en el tono de los dispositivos?

Esto es lo que quiero detectar: Introduzca aquí la descripción de la imagen

editar:

"Por favor, venga con una definición matemáticamente sólida de lo que usted considera" moverse hacia arriba. "Esta fue mi pregunta inicial, ¿cómo puedo escribir una función para definir cuando la tableta se mueve hacia arriba o hacia abajo? Considero una traducción vertical que se mueve hacia arriba. Ahora, ¿cómo puedo detectar esto? Simplemente no sé por dónde empezar, gracias.

Ok, aunque esta pregunta es bastante antigua, veo mucha confusión en la presente respuesta y comentarios, así que en caso de que alguien encuentre esto, tengo la intención de aclarar algunas cosas.

El Giroscopio

En primer lugar, el giroscopio no mide el movimiento vertical según su definición (un movimiento de traslación). Mide la rotación alrededor de cada uno de los ejes, que se definen como en la siguiente figura. Por lo tanto, al inclinar el dispositivo hacia adelante y hacia atrás, de hecho gira alrededor del eje x y, por lo tanto, verá valores no nulos en el valor x de su sensor giroscópico.

Ejes del dispositivo

El valor de x en el giroscopio representa el plano vertical.

No estoy seguro de lo que se entiende por "el plano vertical", sin embargo, el valor x ciertamente no representa el propio plano ni la orientación del dispositivo dentro del plano.

El valor x del sensor de giroscopio representa la velocidad angular actual del dispositivo alrededor del eje x (por ejemplo, el cambio de rotación).

Pero cuando inclina el dispositivo hacia adelante, el valor x cambiará. Cuando hago este movimiento, el mismo sensor que lee movimiento vertical lee un valor para esto.

No estoy muy seguro de lo que te estás refiriendo aquí. "El mismo sensor que lee movimiento vertical" Supongo que es el giroscopio, pero como se dijo anteriormente, no lee movimiento vertical. Hace exactamente lo que dice en la lata.

El sistema de coordenadas del dispositivo

Esto es más en respuesta a la respuesta del usuario Ali que la pregunta original, pero sigue siendo relevante en cualquier caso.

Las salidas individuales del sensor de aceleración lineal (o cualquier otro sensor en este caso) se expresan en el sistema de coordenadas del dispositivo , como se muestra en la imagen anterior. Esto significa que si gira un poco el dispositivo, las salidas ya no serán paralelas a ningún eje del mundo con el que coincidan antes. Como tal, usted tendrá que hacer cumplir que el dispositivo esté en una orientación particular para su aplicación, o tener en cuenta la nueva orientación.

El sensor ROTATION_VECTOR , combinado con la matemática quaternion o el método getRotationMatrixFromVector() , es una forma de traducir sus mediciones de las coordenadas del dispositivo a las coordenadas del mundo. Hay otras maneras de lograr el mismo objetivo, pero una vez logrado, la forma en que sostiene su dispositivo no importa para medir el movimiento vertical.

En cualquier caso, el eje que busca es el eje y, no el eje z.

(Si por casualidad querías decir "a lo largo del eje y del dispositivo" como "vertical", simplemente ignora todo el material de orientación y usa el sensor de aceleración lineal)

ruido

Usted mencionó algunos problemas con respecto al ruido y las tasas de actualización en la pregunta, por lo que voy a mencionar aquí. La más simple y una de las maneras más comunes de obtener datos agradables y consistentes de algo que varía con mucha frecuencia es usar un filtro de paso bajo. ¿Qué tipo de filtro es el mejor depende de la aplicación, pero me parece que un filtro de media móvil exponencial es viable en la mayoría de los casos.

Terminar pensamientos

Tenga en cuenta que si usted toma el cuidado apropiado de la orientación, su salida de aceleración lineal transformada será una buena aproximación de movimiento vertical (bien, cambio de movimiento) sin filtrar ningún ruido.

Además, si desea medir el "movimiento" vertical, como en la velocidad, es necesario integrar la salida del acelerómetro. Por varias razones, en la mayoría de los casos esto no resulta muy bien, aunque es menos severo en el caso de la velocidad en lugar de tratar de medir la posición.

OK, sospecho que es sólo una respuesta parcial.

Si desea detectar el movimiento vertical, sólo necesita aceleración lineal, la orientación del dispositivo no importa. Ver

IOS – Cómo saber si el dispositivo se ha subido / bajado (CoreMotion)

o

Cómo calcular el movimiento del teléfono en la dirección vertical del resto?

Por alguna razón usted está preocupado con la orientación del dispositivo, así, y no tengo ni idea de por qué. Sospecho que quieres detectar algo más. Así que por favor díganos más y entonces mejoraré mi respuesta.


ACTUALIZAR

Leí el post en coremotion, y usted mencionó que más alto z menor xey significa movimiento vertical, ¿puede elaborar?

Voy a escribir en pseudo código. Se midió el vector de aceleración lineal (x, y, z) . Calcular

 rel_z = z/sqrt(x^2+y^2+z^2+1.0e-6) 

Si rel_z > 0.9 entonces la aceleración hacia la dirección z domina (movimiento vertical). Obsérvese que la constante 0.9 es arbitraria y puede requerir ajustes (debe ser un número positivo menor que 1). El 1.0e-6 está ahí para evitar la división accidental por cero.

Puede que tenga que agregar otra restricción que z es suficientemente grande. No sé su dispositivo, si mide la gravedad como 1 o 9,81. Supongo que lo mide como 1.

Así que en general:

 if (rel_z > 0.9 && abs(z) > 0.1) { // we have vertical movement 

De nuevo, la constante 0.1 es arbitraria y puede requerir ajustes. Debe ser positivo.


ACTUALIZAR 2

No quiero esto porque girarlo hacia mí no lo mueve hacia arriba

Se mueve hacia arriba : el centro de masa se mueve hacia arriba. Mi código tiene el comportamiento correcto.

Por favor, venga con una definición matemáticamente sólida de lo que usted considera "moverse hacia arriba".

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.