sábado, 7 de junio de 2008

El tiro por la culata

Al cabo de un rato terminé encontrando el motivo por el que recibía esos valores negativos tan extraños. Aunque todo indicaba lo contrario el valor devuelto por la instrucción xhat[-1] es correcto para el vector xhat (que raro que yo me equivoque).

Al principio pensé que el problema radicaba en que yo solicitaba el valor del vector cuando este estaba siendo tratado por el filtro. Me explico: actualmente tengo dos clases, una llamada Kalman encargada de filtrar la información cuando se agreguen valores leídos por el mando, y la clase Wiimote que entre otras muchas cosas trata las "interrupciones" del mando, entregándosela al objeto kalman para que la filtre, un momento después se solicita el último dato del vector ya filtrado para así calcular velocidad y espacio en tiempo real.

Para evitar esto (un error de programación por mi parte) creé un vector nuevo, copia del anterior, que sólo se actualiza cuando toda la información ha sido filtrada, de forma que siempre devolverá un valor filtrado (aunque sea uno que ya ha sido entregado). Pero esto tampoco funciona, los valores extraños siguen apareciendo, y ahora mismo no se como resolverlo.

Calcularé velocidad y espacio una vez terminado un movimiento, no es igual de 'bonito' pero creo que es la última baza que me queda para utilizar el mando (al menos con el enfoque actual)

miércoles, 4 de junio de 2008

El que la sigue la persigue

Ayer por fin encontré donde está el fallo, el por qué no funciona, la línea que estropea todo... pero lo mas triste es que no se como repararlo.

El problema está, y no está, en el filtro Kalman. La implementación que tengo de él funciona perfectamente. Este algoritmo crea un array perteneciente al paquete numpy (que proporciona arrays mucho mas útiles que los de python estandar) para almacenar los datos filtrados. Es de este array (al que llamo xhat) del que extraigo los datos para calcular la velocidad y el espacio.

Ahora un breve repaso al manejo de arrays en python

Creamos una variable 'vector' que contiene tres números, en este caso enteros

>>> vector = numpy.array([1, 2, 3])


Si queremos acceder a la primera posción (contando desde 0) sólo tenemos que ejecutar

>>> vector[0]
1


Para un vector de números 'flotantes'

>>> vector = numpy.array([1.1, 2.1, 3.1])
>>> vector[-1]
3.1


Con el índice negativo comenzamos a contar desde el final

Por defecto, el paquete numpy crea arrays de tipo float64 que permite almacenar números mas grandes, aunque esto es algo que puede modificarse en el momento de crear el array.

El problema viene ahora, el algoritmo rellena el array xhat, de tal forma que si quisiera obtener el último elemento de este para hacer mis cálculos, ejecutaría una instrucción tan sencilla como esta

>>> xhat[-1]


y al menos yo esperaba obtener un número 'flotante', pero... no. Por algo que no entiendo, que parece ser contra natura, obtengo otro número. Si, otro número. No es el número xhat[-1] redondeado, no. Ni siquiera parecido, es, simplemente, otro número. Que en la mayoría de los casos viene a ser algo aproximado de -1.04... que provoca que la velocidad descienda por debajo del 0

¿Por qué?

Vaya usted a saber, yo llevo desde ayer preguntando a google y no me dice nada coherente. Lo bueno es que he encontrado el problema, lo malo, que roza lo absurdo.

Menos mal que al ser tan cabezota terminaré encontrando la solución, y seguro que es una tontería

martes, 3 de junio de 2008

Pruebas, pruebas, pruebas...

Desde la última entrada he realizado pruebas con el código actual. Los resultados, para ser francos, no son muy esperanzadores. En ocasiones la medición es de una exactitud asombrosa, y en otras, son un desastre. No me refiero a que el error cometido sea de 5 cm, ni siquiera 10. Muchos experimentos arrojan medidas negativas de dos decenas de centímetros, y eso no es muy normal.

He revisado ya varias veces el ćodigo referente a la cinemática, lo he contrastado con libros de física y parece ser todo correcto. El filtro de kalman parece funcionar correctamente, ya que la aproximación gráfica que obtengo de la aceleración se ajusta increíblemente bien a la realidad. Y sin embargo, en muchos experimentos termino obteniendo una velocidad negativa y por consiguiente un retroceso en el espacio. Aún dejando varios segundos el mando en reposo, sin que exista mas fuerza que la gravedad actuando sobre él (fuerza que para mi experimento no es significativa)

He encontrado un artículo bastante técnico sobre este asunto (aplicado también al wiimote) que he releído varias veces. Es posible que mi tosco inglés no me permita sacar todo el jugo al texto, pero creo que lo esencial si lo aplico en mi algoritmo.

De momento, sigo con pruebas, pruebas y pruebas...

martes, 27 de mayo de 2008

De pruebas en (el) Ibiza

Ante los esperanzadores resultados de ayer, esta mañana me he ido a "darle cera" al acelerómetro. El experimento ha sido sencillo, acelerar de 0 km/h hasta 80 km/h, y frenar de nuevo hasta detener el coche. Han sido dos pruebas, y la distancia recorrida de aproximadamente 200mts (medido con el odómetro del coche y teniendo en cuenta que mi coche mide a una escala de 100 metros)

  • Test 1

  • En la primera carrera sólo he tomado una instantánea de las gráficas, sólo la gráfica de la aceleración me resulta un poco chocante, yo esperaba que la aceleración se hiciese negativa al frenar el coche, sin embargo no es así



    Las otras dos gráficas tienen la forma esperada, si bien la velocidad no sufre al final un aumento, el espacio si contempla la "falda de montaña" esperada


  • Test 2

  • En esta ocasión si he medido la distancia medida por el wiimote, 260 metros, que se acerca mucho a la medida por el coche (teniendo en cuenta que esta no es exacta). La velocidad tampoco ha desentonado mucho y se ha aproximado a 80km/h.






Con lo que me ha costado llegar a programar esto espero no estar demasiado tiempo con la calibración del filtro. Seguiré haciendo pruebas a bajas y altas velocidades hasta que los resultados sean algo coherentes.

lunes, 26 de mayo de 2008

Comienzan a salir las cosas

Bien, después de muchas horas de desesperación creo estar cerca de poder usar el wiimote para conocer la distancia recorrida por el robot, o en otras palabras, tener un sistema de odometría fiable.

Primero unos repasos de la física del instituto. Si disponemos de un objeto que se desplaza a lo largo del espacio (s) y medimos el tiempo (t)que invierte en este desplazamiento, podemos obtener su velocidad (v), con algo tan simple como derivar el espacio respecto del tiempo

v = s / t

Donde s corresponde al incremento del espacio (s1 - s0) y t al incremento del tiempo (t1 - t0). Bien, si derivamos de nuevo la velocidad respecto al tiempo, podremos obtener la aceleración del objeto. Siendo esta aceleración un movimiento conocido por todos como "movimiento uniformemente acelerado".

Para recorrer el camino al contrario, simplemente tenemos que calcular las integrales de estos valores respecto del tiempo, es decir, conociendo la aceleración (a):

v = v0 + a(t - t0)

y el espacio:

s = s0 + v0(t - t0) + 1/2 (a (t - t0))

Ahora el experimento, en un movimiento acotado de 30 cm desplazamos el mando por la horizontal desde una v0 = 0 hasta una velocidad final también 0, los resultados obtenidos son los siguientes:

  • La aceleración tiene errores de lectura


  • La velocidad desciende por debajo de cero (como si el objeto invirtiese la dirección del movimiento)


  • Y el espacio retrocede a lo largo del tiempo aproximándose a cero


Bien, con esto no voy a ninguna parte, así que aplicando el filtro de kalman a la aceleración, los resultados obtenidos son los siguientes:

  • La aceleración se ha suavizado, ahora se ajusta mas a la realidad


  • La velocidad no ha tenido mejoras, seguimos cayendo por debajo de cero


  • Y como era de esperar, el espacio "retrocede"



Así que utilizamos de nuevo el filtro de kalman, pero esta vez aplicado primero a la aceleración y luego a la velocidad. Los resultados son los siguientes:

  • La aceleración filtrada, obtiene una gráfica mas real


  • La velocidad, esta vez si desciende de forma normalizada, sin llegar a 0, pero sin tomar valores negativos


  • Ahora si, el espacio aumenta, pero sobrepasa los 30cm del experimento hasta el doble



Y la última prueba, filtrando el espacio con los datos a su vez filtrados de velocidad y aceleración. Las gráficas correspondientes a estas dos últimas no varían

  • Pero retrocedemos en los resultados esperados para el espacio



Conclusiones: El filtro de kalman resulta tremendamente útil para obtener una información mas cercana a la realidad que la obtenida por medio de las mediciones, ya que nos permite eliminar el ruido. Sin embargo, sólo en una de las pruebas el resultado espacial ha estado cercano a los 30cm del experimento (con un error de 1cm). Así que algo he dejado en el aire, tal vez sean los ajustes del filtro.

¿alguna sugerencia?

viernes, 23 de mayo de 2008

Wiimote GUI

Como ayer era incapaz de mirar el mando de la wii sin sentir deseos de matar a Mario decidí seguir trabajando con ello, pero yendo por la tangente. Así que programé en GTK una interfaz gráfica para ver las lecturas del mando.

La cosa es bastante simple, y no tiene otra misión que pintar en una ventana lo que hasta ahora he visto por consola, pero haciendo las pruebas he visto que un problema que ya apareció se intensifica un poco. Sufro un desbordamiento en la pila de mensajes enviados por el mando, ¿soy lento recogiendo los mensajes?, ¿lento procesando?, ¿será la biblioteca que uso de python?

El caso es que un programa similar creado por los chicos de cwiid no adolece de este desbordamiento y no pone al portatil al borde de la levitación, por lo que me inclino en pensar que es python el culpable (¡no voy a ser yo!)

miércoles, 21 de mayo de 2008

Aceleraciones y desaceleraciones

Mientras continúo intentando conocer el espacio recorrido por medio de las aceleraciones medidas por el mando de la wii, he encontrado un proyecto que ya intentó esto mismo, pero en su caso "sujetando" el mando a la rueda del robot para hallar el espacio por medio de las rotaciones que daba el mando.

La dirección del proyecto es esta http://wiibotics.blogspot.com/

y su conclusión... esta otra

Conclusions

My original inspiration for working with the wiimote turned out to be a somewhat-solved problem, since many cursor-control scripts have been written to turn the wiimote into a mouse. I had hoped to make it possible to use such control without being bound to a pair of IR hotspots, but I suspect that the wiimote accelerometer alone will never be accurate and sensitive enough to make this feasible.

Although I had high hopes for the Wiimote being realized as a fully-fledged robot, in half a semester, I was only able to bring it up to speed as an alternative solution to a common problem in robotics: measuring wheel rotation. Still, I hope that this will be its proverbial foot in the door; a stepping stone to more widespread and varied uses. Sensing the grade of the road under a car-like vehicle is as simple as mounting a wiimote parallel to the ground and reading the pitch. With that same wiimote we could do bump-sensing by watching for the force along the long axis of the wiimote to rise above a certain threshhold. I have no doubt that many more uses could be found.


Espero que todo el trabajo que llevo llegue a mejor puerto y no termine escribiendo unas conclusiones similares