2010-04-20 20 views
13

Estoy tratando de hacer una aplicación que detecte qué tipo de forma hizo con su iPhone usando el acelerómetro. Como ejemplo, si dibuja un círculo con su mano sosteniendo el iPhone, la aplicación podría volver a dibujarlo en la pantalla. Esto también podría funcionar con cuadrados o formas más complicadas. El único ejemplo de aplicación que he visto haciendo tal cosa es AirPaint (http://vimeo.com/2276713), pero parece que no puede hacerlo en tiempo real.¿Cómo detectar el movimiento del iPhone en el espacio usando el acelerómetro?

Mi primer intento es aplicar un filtro de paso bajo en los parámetros X e Y desde el acelerómetro, y hacer que un puntero avance hacia estos valores, proporcionalmente al tamaño de la pantalla. Pero esto claramente no es suficiente, tengo una precisión muy baja, y si agito el dispositivo también hace que el puntero se mueva ...

¿Alguna idea de eso? ¿Crees que los datos del acelerómetro son suficientes para hacerlo? ¿O debería considerar usar otros datos, como la brújula?

¡Gracias de antemano!

Respuesta

2

Necesitas buscar la manera de aceleración se refiere a la velocidad y la velocidad a la posición. Mi mente está teniendo un pequeño pedo en este momento, pero estoy seguro de que es integral ... quieres integrar la aceleración con respecto al tiempo. Wikipedia debería ayudarlo con las matemáticas y estoy seguro de que hay una buena biblioteca en alguna parte que puede ayudarlo.

Sólo recuerda sin embargo que los acelerómetros no son perfectos ni encuestados lo suficientemente rápido. Los movimientos realmente repentinos pueden no captarse tan bien. Pero para dibujar suavemente en el aire, debería funcionar bien.

+0

Bien, voy a trabajar en esto. Gracias ! –

+0

Necesita integrar * dos veces * para pasar de la aceleración al desplazamiento. –

10

OK He encontrado algo que parece funcionar, pero todavía tengo algunos problemas. Así es como procedo (admitiendo que el dispositivo se sostiene verticalmente):

1 - Tengo mis valores predeterminados x, y, z.
2 - Extraigo el vector de gravedad de estos datos usando un filtro de paso bajo.
3 - Restamos el vector de gravedad normalizado de cada x, y, y z, y obtenemos la aceleración del movimiento.
4 - Luego, integro este valor de aceleración con respecto al tiempo, así que obtengo la velocidad.
5 - Integro esta velocidad nuevamente con respecto al tiempo, y encuentro una posición.

Todo el código de abajo es en el acelerómetro: didAccelerate: delegado de mi controlador. Estoy tratando de hacer que una bola se mueva según la posición que encontré. Aquí está mi código:

NSTimeInterval interval = 0; 
NSDate *now = [NSDate date]; 
if (previousDate != nil) 
{ 
    interval = [now timeIntervalSinceDate:previousDate]; 
} 
previousDate = now; 

//Isolating gravity vector 
gravity.x = currentAcceleration.x * kFileringFactor + gravity.x * (1.0 - kFileringFactor); 
gravity.y = currentAcceleration.y * kFileringFactor + gravity.y * (1.0 - kFileringFactor); 
gravity.z = currentAcceleration.z * kFileringFactor + gravity.z * (1.0 - kFileringFactor); 
float gravityNorm = sqrt(gravity.x * gravity.x + gravity.y * gravity.y + gravity.z * gravity.z); 

//Removing gravity vector from initial acceleration 
filteredAcceleration.x = acceleration.x - gravity.x/gravityNorm; 
filteredAcceleration.y = acceleration.y - gravity.y/gravityNorm; 
filteredAcceleration.z = acceleration.z - gravity.z/gravityNorm; 

//Calculating velocity related to time interval 
velocity.x = velocity.x + filteredAcceleration.x * interval; 
velocity.y = velocity.y + filteredAcceleration.y * interval; 
velocity.z = velocity.z + filteredAcceleration.z * interval; 

//Finding position 
position.x = position.x + velocity.x * interval * 160; 
position.y = position.y + velocity.y * interval * 230; 

Si ejecuto esto, llegar a ser muy buenos valores, quiero decir que puedo ver la aceleración de entrar en valores positivos o negativos según los movimientos que hago. Pero cuando trato de aplicar esa posición a mi vista de bola, puedo ver que se está moviendo, pero con una propencidad para ir más en una dirección que en la otra. Esto significa, por ejemplo, que si dibujo círculos con mi dispositivo, veré la bola describiendo curvas hacia la esquina superior izquierda de la pantalla. Algo así: http://img685.imageshack.us/i/capturedcran20100422133.png/

¿Tiene alguna idea sobre lo que está sucediendo? ¡Gracias de antemano!

7

El problema es que no puede integrar la aceleración dos veces para obtener la posición.No sin conocer la posición y la velocidad iniciales. ¿Recuerda el término + C que agregó en la escuela cuando aprendió sobre la integración? Bueno, para cuando llegas a la posición, es un término ct + k. Y es significativo. Eso es antes de considerar que los datos de aceleración que está recibiendo se cuantifican y promedian, por lo que no está integrando realmente la aceleración real del dispositivo. Esos errores terminarán siendo grandes cuando se integren dos veces.

Mire la demostración de AirPaint de cerca y verá exactamente lo que está pasando, las formas representadas son significativamente diferentes a las formas que se mueven.

Incluso los dispositivos que tienen algunos sensores de posición y velocidad (un Wiimote, por ejemplo) tienen problemas para realizar el reconocimiento de gestos. Es un problema difícil que la gente pague un buen dinero (a compañías como AILive, por ejemplo) para resolverlo.

Habiendo dicho esto, probablemente puedas distinguir fácilmente entre ciertos tipos de gestos, si sus características a gran escala son diferentes. Se puede detectar un círculo si el dispositivo ha recibido aceleraciones en cada uno de los seis rangos de ángulos (por ejemplo). Podrías detectar entre deslizar el iphone por el aire y sacudirlo.

Decir la diferencia entre un círculo y un cuadrado será mucho más difícil.

+0

Necesito saber la posición inicial y la velocidad del dispositivo antes de comenzar a integrar los valores del acelerómetro? El dispositivo comienza con una velocidad y una posición aproximadas de 0. Probablemente no sea una buena idea, pero incluso si dejo que mi iPhone quede plano sobre una mesa, aún obtengo información de movimiento. Con este cálculo, tengo una idea aproximada de qué forma ha sido dibujada por el usuario, y eso es suficiente para lo que estoy tratando de hacer. Me pregunto cómo podría filtrar los valores del acelerómetro para poder deshacerme de este "comportamiento de movimiento predeterminado", y siempre mantener centradas las posiciones que he encontrado. –

+0

Eso es lo que quiero decir. No puede filtrar para deshacerse del 'movimiento predeterminado' de un acelerómetro, porque no tiene forma de saber qué podría ser. AirPaint supone que el movimiento finalizará en su punto de partida, por lo que puede corregir algunos errores de esa manera. Pero una solución general al problema no es posible en absoluto en los datos de aceleración. El movimiento que recibe cuando el dispositivo está parado también se ve afectado por las imprecisiones en el acelerómetro. Cuando intentes integrar eso dos veces, esas imprecisiones son muy grandes. – Ian

+0

También tendrá errores causados ​​por una ligera torsión en el teléfono durante el movimiento. Debido a que considera que la aceleración de baja frecuencia es la gravedad, los cambios en la inclinación se registrarán como cambios dramáticos en la aceleración. Si me inclino, luego inclino hacia atrás, será equivalente a un gran golpe. – Ian

2

Parece que estás normalizando tu vector de gravedad antes de restar con la aceleración instantánea. Esto mantendría la orientación relativa pero eliminaría cualquier escala relativa. El último dispositivo que probé (no es un Idevice) devolvió la gravedad a aproximadamente -9.8, que probablemente está calibrado a m/s. Suponiendo que no haya otra aceleración, si tuviese que normalizar esto, restarlo del pase filtrado, terminaría con una aceleración actual de -8.8 en lugar de 0.0f;

2 opciones: -Usted simplemente puede restar el vector de gravedad después de que el filtro de paso -Captura la longitud inicial de aceleración vector, normalizar la aceleración y los vectores de gravedad, la escala del vector de aceleración por el punto de la aceleración y la gravedad normales.

También vale la pena recordar para tener en cuenta la orientación del dispositivo.

Cuestiones relacionadas