viernes, 30 de abril de 2010

Carreras por el pasillo del departamental

En esta versión he mejorado la estabilidad en velocidad comparando algunas opciones para determinar la velocidad a la que puede navegar el robot pioneer. Además, he usado un comparador con la velocidad anterior para suavizar los cambios bruscos.

Con esto he evitado el efecto "tembleque" que se produce cuando se modifica la velocidad del robot considerablemente en cada iteración.

Falta por mejorar el algoritmo VFF a uno que tenga en cuenta mejor la distancia a los objetos usando una ecuación trigonométrica y aunque la mejora en la decisión de giro hace que éste tome mejor las curvas sigue siendo lento debido al poco ángulo de visión y a que a poca distancia del objeto éste es plano en su parte inferior por el recorte de la cámara. Probaré a bajar la cámara un poco para evitar ese efecto a corta distancia.

Un problema que me encontraré si hago eso es que la regla de tres dejará de funcionar para estimar el ángulo al que se encuentra cada columna de la imagen y deberé hacer el cálculo por cada pixel. Para mejorar el rendimiento sólo calcularé el ángulo del último pixel de suelo en cada columna, pero aún así las cuentas se complican.

jueves, 29 de abril de 2010

Navegación visual por el pasillo del departamental

Primer acercamiento a la navegación visual sin asistencia de líneas pintadas en el suelo.

Para llegar a una solución he pensado en implementar un algoritmo VFF basado en la distancia en la que se encuentran los objetos que aparecen en la imagen de la cámara de vídeo.

He estimado que la apertura de visión de la cámara es algo inferior a 70º, de modo que se puede estimar el ángulo al que se encuentra cada columna de la imagen con una simple regla de tres.

Queda por mejorar los "saltitos" o efecto "tembleque" que tiene el robot cuando ajusta su velocidad basada en el módulo del vector de repulsión y mejorar la decisión de giro, la encuentro demasiado lenta debido al poco ángulo de visión del que disponemos.

miércoles, 28 de abril de 2010

Sigue líneas visual con umbrales lineales

Por fin he puesto en marcha el introrob para gazebo. Tras tener problemas compilando el newintrorob2.tar.gz por fin descubro que simplemente hay que usar el mismo introrob que viene con jderobot 4.3.

En esta primera implementación creamos tres umbrales lineales que determinarán cómo se comportará el robot ante la tarea de seguir la línea roja.

En el siguiente vídeo muestro cómo se comporta el robot en el pequeño circuito incluido en las prácticas. Podría aumentar la velocidad un poco más, pero el robot pionner se vuelve muy inestable en los giros cerrados ya que tiende a volcar cuando gira, o a desviarse cuando frena o acelera bruscamente.

En la implementación inicial he incluido un algoritmo de compensación de inercia. Con él consigo dejar de girar antes de llegar al punto de destino, de modo que no me lo pase por la inercia de giro del robot. La estimación es lineal y usa únicamente el estado anterior para calcular la posición futura.

martes, 13 de abril de 2010

Comportamiento choca-gira: retoque final

Detecté pero no arreglé un pequeño problema derivado de calcular si ha llegado el robot o no al ángulo de destino. Ahora toca arreglar ese defecto para que la práctica sea completa.

Para comprender el problema debemos saber dos cosas del robot:

Los sensores de orientación del robot no son perfectos, por consiguiente la brújula tiene un margen de error y una granularidad que impide la búsqueda de un ángulo de destino perfecto. Por consiguiente no se busca un ángulo de destino, si no un ángulo de destino con un margen de error de varios grados.

En la imagen puede verse una representación del ángulo de destino:

Gráfica 1

En ella puede verse el ángulo de destino (356º) y el margen de error anterior (356º - 10º = 346º) y posterior (356º + 10º = 366º = 6º).

¿Qué problema existe en la búsqueda de ese sentido de orientación?

Para averiguar si ha llegado o no el robot a su orientación de destino restamos los ángulos destino y actual y obtenemos el valor absoluto.

φ = | φr - φf |

Donde φr es la orientación actual del robot y φd la orientación final a la que debe llegar.

Veamos varios ejemplos de cómo se comporta este mecanismo de cálculo con varios ejemplos:

  • Estamos en 340º: |340 - 356| = 16 (> 10 fuera del margen - CORRECTO).
  • Estamos en 349º: |349 - 356| = 7 (< 10 dentro del marge - CORRECTO).
  • Estamos en 358º: |340 - 356| = 2 (< 10 dentro del margen - CORRECTO).
  • Estamos en 4º: |4 - 356| = 352 (> 10 fuera del margen - INCORRECTO).
  • Estamos en 8º: |8 - 356| = 348 (> 10 fuera del margen - CORRECTO).

Podemos resumir el comportamiento de este cálculo en la siguiente ilustración:

Gráfica 2

En ella podemos ver que cuando el ángulo es cercano al destino pero éste no "cruza" el eje de abscisas todo funciona correctamente (zona verde) pero si estamos dentro de un ángulo al otro lado del eje de abscisas entonces nos encontramos con que los cálculos fallan.

¿Cómo arreglarlo?

Existen varias soluciones. La que proponen en clase es comprobar cuándo el robot puede verse involucrado en este tipo de situaciones y modificar el cálculo de la diferencia en ese caso.

¿Cómo?

Veamos la siguiente ilustración:

Gráfica 3

Podemos ver dos zonas la anaranjada y la azulada. Corresponden al arco comprendido entre 10º y 0º (zona anaranjada) y de 0º a -10º (zona azulada).

Podríamos hacer sectores y comprobar cuándo pasan por el eje de abscisas y arreglarlo. Una serie de sentencias condicionales nos ayudarían en la tarea.

Pero hay una forma más sencilla, comprobando únicamente cuándo el cálculo podría darnos problemas.

¿Cómo podríamos averiguar eso?

Podríamos hacer las siguientes comprobaciones:

  • Si el robot está orientado en un ángulo inferior a 10º (zona anaranjada) y el destino es superior a 350º (zona azulada) le quitamos 360 grados al ángulo de destino.
  • Si el robot está orientado en un ángulo superior a 350º (zona azulada) y el destino es inferior a 10º (zona anaranjada) le quitamos 360 grados al ángulo del robot.

Con eso los cálculos saldrían correctos. Podemos comprobarlo con los ejemplos anteriores.

Pensemos que la condición "el destino es superior a 350º" siempre se está cumpliendo de modo que sólo hay que restarle 360º al destino cuando el robot tiene su ángulo de giro por debajo de los 10º de margen:

  • Estamos en 340º: |340 - 356| = 16 (> 10 fuera del margen - CORRECTO).
  • Estamos en 349º: |349 - 356| = 7 (< 10 dentro del marge - CORRECTO).
  • Estamos en 358º: |340 - 356| = 2 (< 10 dentro del margen - CORRECTO).
  • Estamos en 4º: |4 - (356 - 360)| = |4 + 4)| = 8 (< 10 dentro del margen - CORRECTO).
  • Estamos en 8º: |8 - (356 - 360)| = |8 + 4| = 12 (> 10 fuera del margen - CORRECTO).

¿Y no existe una solución más simple?

Casi siempre hay una solución mejor a la que inicialmente pensamos de forma natural.

Basta con restarle a 360º el ángulo calculado si éste supera los 180º.

Lo comprobamos con el ejemplo anterior:

  • Estamos en 340º: |340 - 356| = 16 (> 10 fuera del margen - CORRECTO).
  • Estamos en 349º: |349 - 356| = 7 (< 10 dentro del marge - CORRECTO).
  • Estamos en 358º: |340 - 356| = 2 (< 10 dentro del margen - CORRECTO).
  • Estamos en 4º: |4 - 356| = 352 -> 360 - 352 = 8 (< 10 dentro del margen - CORRECTO).
  • Estamos en 8º: |8 - 356| = 348(*) -> 360 - 348 = 12 (> 10 fuera del margen - CORRECTO).

(*)Para minimizar el hitrate de dicha comprobación y ahorrarnos restas innecesarias comprobamos que únicamente esté por encima del margen superior, 350º, que será cuando nos interfiera en el cálculo en vez de hacerlo cada vez que supere los 180º.

En estos ejemplos hemos usado un error de 10º y hemos usado grados para facilitar los cálculos pero en la práctica el margen de error con el ángulo de destino es de tan sólo 5º y todos los cálculos se hacen en radianes.

En el siguiente vídeo muestro el funcionamiento del cálculo. Estamos calculando el ángulo de diferencia de manera continua, pero cuando la diferencia es mayor de 330º (360º - 30º) habilitamos el cálculo de corrección.

Hay que notar que en la práctica existen dos umbrales de decisión: <30º para girar más despacio y <5º para decidir que se ha llegado al objetivo. De modo que hay que tener en cuenta el umbral más bajo (360º - 30º) o no aplicar la optimización. De no hacerlo el robot podría pasar girando sobre los 5º de margen y pasarse en el giro, teniendo que completar una nueva vuelta y rezar que no vuelva a ocurrir lo mismo.