2010-12-15 21 views
19

Estoy desarrollando una aplicación de realidad aumentada que (de momento) quiere mostrar un cubo simple en la parte superior de una superficie, y poder moverse en el espacio (tanto rotando como desplazándose) para mira el cubo en todos los diferentes ángulos. El problema de la calibración de 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. Para saber la rotación de la cámara es muy simple con el giroscopio y Core Motion. Lo hago de esta manera:Obteniendo desplazamiento de los datos del acelerómetro con Core Motion

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. Más problemas surgen de todos modos 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 y z del vector de aceleración al vector de posición. Esto (aparte 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 de alguna istant? (con diferencia horaria conocida). Al ver algunas otras respuestas, parece que tengo que integrar 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 en absoluto, y no creo que eso sea realmente necesario. Además, existe el problema de que cuando el iPhone todavía está en un avión, los valores del acelerómetro no son nulos (creo que hay algo de ruido). ¿Cuánto debo filtrar esos valores? ¿Debo filtrarlos?

Respuesta

7

Cuando el iPhone 4 era muy nuevo, pasé muchas, muchas horas tratando de obtener un desplazamiento preciso usando acelerómetros y giroscopio. No debería haber mucha preocupación sobre la deriva incremental, ya que el dispositivo solo necesitaba mover un par de metros como máximo y la recopilación de datos generalmente se ejecutaba durante unos minutos como máximo. Probamos todo tipo de enfoques e incluso contamos con 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 todo ... de acuerdo con ingenieros muy conocedores.

Me encantaría escuchar a alguien contradice esto - ya que la aplicación nunca resultó como esperábamos, etc.

21

fresca, hay gente por ahí que luchan con el mismo problema por lo que vale la pena dedicar algo time :-)

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 determinada para sus movimientos, entonces creo que existe la posibilidad de 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 estas sugerencias útiles:

Primero que nada para hacer Las cosas fáciles solo miran a un eje, por ejemplo, x, pero consideran que tanto la izquierda (-x) como la derecha (+ x) tienen una situación representable.

Sí, tiene razón, debe integrar dos veces para obtener la posición en función del tiempo. Y para un procesamiento posterior, debe almacenar el resultado de la primera integración (== velocidad), porque lo necesitará en una etapa posterior para la optimización. Hazlo con mucho cuidado porque cada pequeño error provocará grandes errores 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 realizar 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, 50 tics se procesan y el pequeño error negligible superará el valor "verdadero". Recomiendo encarecidamente no confiar en la regla trapezoidal, sino usar al menos Simpson o una fórmula Newton-Cotes de mayor grado.

Si logró esto, tendrá que vigilar la configuración del filtro 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 reaccione a los eventos, ...

Ahora tendrá una solución que funciona bastante bien en determinadas circunstancias y en un corto plazo período de tiempo. Pero luego de unos segundos te encontrarás con problemas porque tu objeto se está alejando. Ahora ingresará la parte difícil de la solución que no logré manejar con el tiempo :-(

Un enfoque prometedor es introducir algo que llamo "fuerzas sinteticas" o "fuerzas virtuales". estrategia para reaccionar en varias situaciones malas que hacen que el objeto se desplace aunque el dispositivo permanezca fijo (no hay un hablante nativo, es decir, sin moverlo) en sus manos. La más problemática es una velocidad mayor a 0 sin ninguna aceleración. resultado inevitable de la propagación de errores y puede ser manejado por la desaceleración artificial que significa la introducción de una desaceleración virtual, incluso si no existe una contraparte real. Un ejemplo muy simplificado:

if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) { 

    vX *= 0.9; 
} 

`

Necesitará una combinación de tales condiciones para domesticar a la bestia. Se requieren muchos intentos y errores para hacerse una idea del camino correcto y esta será la parte más difícil del problema.

Si alguna vez conseguido descifrar el código, pleeeease que me haga saber, soy muy curioso para ver si es posible, en general, o no :-)

Saludos Kay

5

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

Mi problema es que estoy usando el deviceMotion.y los valores no son correctos. deviceMotion.gravity leer cerca de 0. ¿Alguna idea? - Correcto, aparentemente deviceMotion.gravity tiene valores x, y y z. Si no especifica cuál quiere, obtiene x (que debería estar cerca de 0).

+1

El problema con d = 0,5 * a * t^2, en general, es decir, que requiere una aceleración constante como se describe en http://en.wikipedia.org/wiki/ Aceleración. – Kay

+1

Bueno, suponiendo que v (0) == 0 es crítico, pero necesitamos un punto para comenzar y deberíamos vivir con eso. OMI la parte más crítica aparece después de unos segundos cuando tienes a == 0 y v! = 0 (como se explica en mi respuesta). – Kay

1

Encuentra esta pregunta dos años más tarde, I just find a AR project on iOS 6 docset named pARk, proporciona una captura de desplazamiento aproximado y el cálculo utilizando giroscopio, también conocido como CoreMotion.Framework.

Estoy empezando a inclinar el código.

continuará ...

Cuestiones relacionadas