iphone ios4 accelerometer augmented-reality gyroscope

iphone - Obtención de desplazamiento de los datos del acelerómetro con Core Motion



ios4 accelerometer (4)

Estoy desarrollando una aplicación de realidad aumentada que (en este momento) desea mostrar un cubo simple sobre una superficie y poder moverse en el espacio (tanto girando como desplazándose) para mirar el cubo en todos los ángulos diferentes. El problema de calibrar la cámara no se aplica aquí, ya que le pido al usuario que coloque el iPhone en la superficie en la que desea colocar el cubo y luego presione un botón para restablecer la actitud. Descubrir la rotación de la cámara es muy simple con el giroscopio y Core Motion. Lo hago de esta manera:

if (referenceAttitude != nil) { [attitude multiplyByInverseOfAttitude:referenceAttitude]; } CMRotationMatrix mat = attitude.rotationMatrix; GLfloat rotMat[] = { mat.m11, mat.m21, mat.m31, 0, mat.m12, mat.m22, mat.m32, 0, mat.m13, mat.m23, mat.m33, 0, 0, 0, 0, 1 }; glMultMatrixf(rotMat);

Esto funciona muy bien. De todos modos, surgen más problemas cuando trato de encontrar el desplazamiento en el espacio durante una aceleración. El ejemplo de Apple Teapot con Core Motion simplemente agrega los valores x, y, z del vector de aceleración al vector de posición. Esto (además de no tener mucho sentido) tiene el resultado de devolver el objeto a la posición original después de una aceleración. (Dado que la aceleración va de positiva a negativa o viceversa). Lo hicieron así:

translation.x += userAcceleration.x; translation.y += userAcceleration.y; translation.z += userAcceleration.z;

¿Qué debo hacer para averiguar el desplazamiento de la aceleración en algunos istantes? (Con diferencia horaria conocida). Mirando algunas otras respuestas, parece que tengo que integrarme dos veces para obtener la velocidad de la aceleración y luego la posición de la velocidad. Pero no hay ningún ejemplo en el código, y no creo que sea realmente necesario. Además, existe el problema de que cuando el iPhone todavía está en un plano, los valores del acelerómetro no son nulos (creo que hay algo de ruido). ¿Cuánto debo filtrar esos valores? ¿Se supone que debo filtrarlos?


Cuando el iPhone 4 era muy nuevo, pasé muchas, muchas horas tratando de obtener un desplazamiento preciso utilizando acelerómetros y giroscopio. No debería haber habido mucha preocupación acerca de la deriva incremental, ya que el dispositivo solo necesitaba moverse un par de metros a lo sumo y la recopilación de datos por lo general se ejecutaba durante unos minutos como máximo. Probamos todo tipo de enfoques e incluso tuvimos la ayuda de varios ingenieros de Apple. En última instancia, parecía que el giroscopio no estaba a la altura de la tarea. Fue bueno para la orientación 3D, pero eso fue ... otra vez, de acuerdo con ingenieros muy conocedores.

Me encantaría escuchar a alguien contradecir esto, porque la aplicación nunca resultó como esperábamos, etc.



Genial, hay personas que están luchando con el mismo problema, así que vale la pena pasar un tiempo :-)

Estoy de acuerdo con la declaración de Westsider, ya que pasé unas semanas experimentando con diferentes enfoques y terminé con malos resultados. Estoy seguro de que no habrá una solución aceptable para distancias más grandes o movimientos lentos que duren más de 1 o 2 segundos. Si puede vivir con algunas restricciones como distancias pequeñas (<10 cm) y una velocidad mínima dada para sus movimientos, entonces creo que podría haber una oportunidad para encontrar una solución, sin ninguna garantía. Si es así, te llevará un tiempo bastante difícil de investigación y mucha frustración, pero si lo consigues, será muy genial :-) Tal vez encuentres útiles estas sugerencias:

En primer lugar, para facilitar las cosas, simplemente observe un eje, por ejemplo, x, pero considere que tanto la izquierda (-x) como la derecha (+ x) tienen una situación representable.

Sí, tienes razón, tienes que integrarte dos veces para obtener la posición en función del tiempo. Y para un procesamiento adicional, debe almacenar el resultado de la primera integración (== velocidad), porque lo necesitará en una etapa posterior para la optimización. Hágalo con mucho cuidado porque cada pequeño error producirá errores enormes después de un corto período de tiempo.

Siempre tenga en cuenta que incluso un error muy pequeño (por ejemplo, <0.1%) crecerá rápidamente después de hacer la integración dos veces. La situación empeorará después de un segundo si configura el acelerómetro con, digamos, 50 Hz, es decir, se procesan 50 tics y el pequeño error desatendido superará el valor "verdadero". Recomiendo encarecidamente no confiar en la regla trapezoidal, sino usar al menos Simpson o una fórmula de Newton-Cotes de grado superior.

Si logró esto, tendrá que estar atento a la configuración del filtrado de paso bajo correcto. No puedo dar un valor general, pero como regla general, experimentar con factores de filtrado entre 0,2 y 0,8 será un buen punto de partida. El valor correcto depende del caso de negocio que necesite, por ejemplo, qué tipo de juego, qué tan rápido reacciona ante los eventos, ...

Ahora tendrá una solución que funciona bastante bien en ciertas circunstancias y dentro de un corto período de tiempo. Pero después de unos segundos se encontrará con problemas porque su objeto se está alejando. Ahora ingresará a la parte difícil de la solución que no pude manejar finalmente dentro del alcance de tiempo dado :-(

Un enfoque prometedor es introducir algo que yo llamo "fuerzas sintécticas" o "fuerzas virtuales". Esta es una estrategia para reaccionar ante varias situaciones adversas que provocan que el objeto se aleje, aunque el dispositivo permanezca fijo ("sin hablante nativo, quiero decir sin moverme") en sus manos. El más problemático es una velocidad mayor que 0 sin ninguna aceleración. Este es un resultado inevitable de la propagación de errores y se puede manejar mediante una ralentización artificial que significa introducir una desaceleración virtual incluso si no hay una contraparte real. Un ejemplo muy simplificado:

if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) { vX *= 0.9; }

`

Necesitarás una combinación de tales condiciones para domesticar a la bestia. Se requiere mucho intento y error para tener una idea de cuál es el camino correcto y esta será la parte difícil del problema.

Si alguna vez logró descifrar el código, por favor, avíseme, tengo mucha curiosidad por ver si es posible en general o no :-)

Saludos Kay


También estoy tratando de conseguir el desplazamiento en el iPhone. En lugar de usar la integración, utilicé la fórmula física básica de d = .5a * t ^ 2 asumiendo una velocidad inicial de 0 (no suena como que puedes asumir una velocidad inicial de 0). Hasta ahora parece funcionar bastante bien.

Mi problema es que estoy usando deviceMotion y los valores no son correctos. deviceMotion.gravity leer cerca de 0. ¿Alguna idea? - OK Fijo, aparentemente deviceMotion.gravity tiene valores de ax, y y z. Si no especifica qué desea, vuelve x (que debería estar cerca de 0).