ROBÓTICA 


Manuel Leal y Gonzalo Abella 

Martes. 03 Junio de 2008

  • Tutoriales

Para compilar la práctica y lanzar todo el entorno de Gazebo y jde hemos creado un script para agilizar las pruebas. Ver código del script.

También colgamos un pequeño tutorial sobre como instalar y usar la aplicación "recordmydesktop" en las máquinas del laboratorio. Pensamos que puede ser útil para cualquiera. Ver tutorial.

  • Mejoras en Detección de Obstáculos.

Tras muchas pruebas hemos mejorado los problemas que teníamos con el sensor de ultrasonido. Hemos ajustado los parámetros de detección y sorteo de obstáculos.

A continuación se muestra resaltado el algoritmo de detección y sorteo de obstáculos en la práctica del SigueLinea.

Ver código detección y sorteo de Obstáculos

Vídeo donde se puede observar cómo esquiva una lata:


Martes, 27 Mayo 2008

  • Mejoras en práctica 3

Hemos mejorado el algoritmo incluyendo distintas velocidades. Así, en tramos en línea recta aumentamos la velocidad y en tramos con curvas, vamos más despacio para evitar perder la línea.

El algoritmo hace lo siguiente:
A parte de mirar la última fila de la imagen y decidir así el grado de giro, observamos también el primer y último píxel de una fila a una altura más o menos intermedia en la cámara para así saber cuándo va a llegar un giro demasiado grande -una curva brusca- y frenar antes de tiempo, no cuando ya estemos metidos en la curva. Así, aunque el robot tenga inercia al frenar, no se sale de la curva pues cuando está en ella, el robot ya va lo suficientemente despacio como para recorrerla sin salirse y/o perderse.

Utilizamos un contador como memoria. Este contador se reinicia cuando observamos una curva brusca. A medida que el contador se va incrementando, vamos aumentando la velocidad del robot. Así, cuando estamos en una recta, el robot va mucho más deprisa frenando de nuevo cuando detectemos a media pantalla otra curva brusca.

Con estos cambios conseguimos recorrer el circuito en poquito más de dos minutos (2:02).

A continuación mostramos el código del SIgueLínea en Gazebo mejorado y el video:

Ver código SigueLinea en Gazebo mejorado

Viernes, 23 Mayo 2008

    • Práctica 3

      Esta semana, aunque todavía tenemos algún problema con la detección de obstáculos en la práctica dos, nos hemod dedicado a la implementación de la práctica 3.

      Una vez comprendimos todo el entorno de desarrollo, el algoritmo que hemos decidio utilizar es el siguiente:

      De todo el array de bytes con los colores rojo, verde y azul obtenidos de la cámara del robot utilizamos para navegar la información de la última fila. Calculamos la cantidad de píxeles blancos que hay a cada lado de la línea obteniendo un valor que posteriormente, una vez adaptado, utilizamos en la velocidad angular. Adaptamos este valor dividiendolo por una constante -un entero calculado haciendo diversas pruebas hasta que vimos cómo funcionaba mejor- ya que si no se hiciera esta adaptación, la velocidad angular del robot sería demasiado grande y el robot realizaría giros muy bruscos oscilando a un lado y otro de la línea roja o inlcuso perdiendo el control.

      En esta primera implementación, el robot va siempre a velocidad constante, realizando el circuito completo en unos 3 minutos.

      A continuación se puede ver el código y el video:

      Ver código SigueLínea en Gazebo


      • Intentando mejorar detección obstáculos
      Por otro lado, esta semana hemos seguido intentando mejorar de alguna forma la detección de obstáculos haciendo cambios en el algoritmo y probando con el sensor de ultrasonido de otros compañeros. Tras diversas pruebas, no hemos conseguido demasiadas mejoras. El problema principal viene cuando una lata se encuentra cerca de una curva, situación en la que el robot no la detecta fácilmente ya que al no encontrarse directamente de frente con ella, las ondas del sensor de sonido puede que no reboten, sino que sean reflejadas no llegando ninguna información de vuelta al robot y, por tanto, dando entender al robot que no hay nada delante siguiendo su camino sin darse cuenta que hay un obstáculo.

Viernes, 16 Mayo 2008

  • Problemas con detección obstáculos

La parte de detección de obstáculos es, sin duda, la parte más difícil de llevar a la realidad. En cuestión de implementación es muy simple, basta con observar la distancia que nos devuelve el sensor de ultrasonido y, cuando algo se encuentre a menos de 10 cm, realizar un giro.

El problema es consecuencia de dos factores:

Por un lado la poca fiabilidad del sensor de ultrasonido. Cuando el robot se mueve, obtener valores exactos con el sensor es muy difícil. Si se decide pararse para cerciorarse de las medidas que se obtienen, perjudica gravemente en el tiempo que el robot supera el recorrido completo. Por ello, tras diversas pruebas la decisión tomada es analizar el valor del sensor y, cuando este sea inferior a 22 cm, valor que el sensor puede obtener de forma más o menos exacta aún moviéndose; nos paramos y volvemos a medir para ver si hay algo a menos de 10 centímetros y esquivarlo.

Por otro lado tenemos el inconveniente de que una de las ruedas no funciona bien. Con la instruccion steer de la clase navigation.pilot, le indicamos al robot el giro que queremos hacer y la velocidad de las ruedas una con respecto a otra para hacer el círculo del giro con mayor o menor cuerda pero, mientras se está produciendo este giro, uno de los motores de la rueda no funciona bien a veces y el giro realizado por el robot no es perfecto, provocando, a menudo, un choque con la lata que intenta esquivar.


¿Cuándo decidimos medir para esquivar un posible obstáculo?El algoritmo de detección de obstáculos forma parte del SigueLínea. Siempre que voy siguiendo la línea, voy comprobando un posible obstáculo para sortearlo. Este código, por tanto, se puede ver en el algoritmo de SIgueLinea:

Ver código Detección Obstáculos

Miércoles, 14 Mayo 2008

  • Mejoras en algoritmos de Detección de Víctimas y Obstáculos

En el código adjuntado con fecha martes 7 mayo se puede observar qué hace para detectar víctimas de manera óptima y que no reconociera una víctima cuando no la hubiera. Por ejemplo, si para detectar una víctima de color verde es necesario un valor absoluto de entre 30 y 40, justo en el momento en el que el robot perdía la línea y el láser se quedaba apuntando en el borde de esta, entre blanco y negro, el láser recogía un valor entre 30 y 40 y reconocía una víctima cuando no lo había. Por ello, en ese momento decidimos recoger más de un valor (un array de 100 valores) moviéndonos alrededor de la supuesta víctima para así cerciorarnos de que es una víctima auténtica.

Al hacerlo de esta manera había que recoger los valores, luego leerlos y después iniciarlos de nuevo para la siguiente comprobación. Nos dimos cuenta que hacerlo así en la práctica llevaba mucho tiempo y repercutía en la velocidad de avance general del robot a lo largo del circuito. Debido a esto, hemos decidido adaptar en función de las necesidades reales de nuevo el algoritmo para que vaya más rápido.

Ahora también hacemos más de una comprobación alrededor de la víctima pero de manera más eficiente, este algoritmo se puede ver dentro de BuscaLinea. El método se llama reconoceVictimas().

Ver código clase BuscaLinea mejorado


Por otro lado, el otro día hicimos un pequeño esbozo del algoritmo para esquivar obstáculos. Nos hemos estado pegando estos dos días para mejorarlo y, aunque hemos hecho multitud de cambios y multitud de pruebas, creemos que el láser de ultrasonido no nos funciona bien y, aunque creemos tener un buen algoritmo, no siempre resuelve un obstáculo de la manera que quisiéramos. Hablaremos con el profesor para ver la posibilidad de cambiar dicho sensor. El algoritmo de detección de obstáculos está embebido en el de SigueLinea para así poder hacer las dos cosas a la vez. A continuación, pueden echarle un vistazo:

El algoritmo en sí lo que es cuando detecta un posible obstáculo más o menos cerca,aprox a 22 mm, se para, y se pone a hacer comprobaciones parado porque si las hace moviéndose este sensor es extremadamente poco fiable y no funcionaba de forma correcta. Así va tomando medidas y en el momento que esté a menos de 10 mm, se pone a esquivar el obstáculo, teniendo en cuenta que, si está muy cerca, a menos de 7 mm, recula primero, y luego esquiva el obstáculo.

Ver código clase SigueLinea mejorado

Para terminar, el código del programa principal. El resto de clases no las hemos modificado, se pueden ver más abajo.

Ver código Programa Principal

A continuación mostramos un vídeo donde se puede ver los objetivos de la práctica sin la detección de obstáculos:


Lunes, 12 Mayo 2008

  • Reestructuración básica de la práctica debido a los problemas con la clase Behavior

Como ya se ha venido comentando en post anteriores, uno de los problemas de la clase Behavior es que el método supress no lo podíamos controlar. Saltaba cuando no tenía que saltar y se quedaba bloqueado sin ejecutar más código, teniendo que reiniciar el robot. Por ello, hemos decidido reestructurar el código y, aunque vamos a seguir utilzando todas las clases construidas con los dos comportamientos básicos(SigueLinea y BuscaLinea), no vamos a dejar que la clase arbitrator controle los comportamientos de nuestro robot, sino que controlaremos nosotros mismos los comportamientos justo como lo hace esta clase:

- Comprobaremos primero si el método takeControl() se cumple, y si esto es así, llamaremos al método action(). Estos cambios los hemos hecho en el programa principal, se puede ver en el código adjunto que colgaremos a lo largo de esta semana con mejoras realizadas también en los algoritmos.


Martes, 7 Mayo 2008

  • Cambios en la practica para intentar mejorar los problemas de la clase Behavior

Para intentar evitar los problemas del método supress así como para hacer varias cosas a la vez ( como por ejemplo que compruebe que no hay obstáculos delante mientras avanza, o que compruebe cuando se sale del camino si hay una víctima o una discontinuidad o si se ha salido realmente de la línea) hemos aunado todos los comportamientos reduciendolos a 2.

  1. SigueLinea
  2. BuscaLinea

Hemos aprovechado también para hacer alguna mejora en el algoritmo de detección de víctimas y un esbozo del algoritmo que evitará los osbtáculos. A continuación se incluye el código de nuevo con los cambios y mejoras:

Dentro del comportamiento SigueLinea se incluye la deteccion de obstáculos.

Dentro del comportamiento BuscaLinea se incluye la detección de víctimas y discontinuidades.

Ver codigo Class SIgueLinea

Ver codigo Class BuscaLinea

Ver codigo Class My_Pilot

Ver codigo Class MyLightSensor

Ver codigo TestSigueLinea

Miercoles, 30 Abril 2008

  • Muchísimos problemas con la clase Behavior

Desgraciadamente estamos teniendo muchísimos problemas con la clase Behavior. No funciona como creíamos que debería funcionar y lamentablemente nos está haciendo perder mucho tiempo intentando solucionar los problemas de esta clase. La clase Behavior está compuesta por 3 métodos:

  1. action(), método donde se incluye las instrucciones del comportamiento. Por ejemplo, para la clase ReconoceVistimas, dentro de este método irán las instrucciones para reconocer a la víctima.
  2. takeControl(). Método booleano que decide si debe ejecutarse este comportamiento o no
  3. suppress(). Metodo que se ejecuta cuando deja de cumplirse la condición y por tanto, ya no se ejecuta el método action, sino este.

Inicialmente creíamos que esto era así pero la práctica nos dice lo contrario. El método suppress no sabemos bien cómo funciona. Cuando lanzamos el programa, el robot va comprobando los distintos comportamientos que debe ejecutar llamando a los métodod takeControl() de cada comportamiento y ejecutando aquellos que se cumpla la condición. Sin embargo, siempre en algún momento indeterminado, se ejecuta el método suppress de algún comportamiento y el robot se queda ahí bloqueado. No sabemos cómo funciona este método, y no sabemos cuando y por qué se ejecuta.

Martes, 29 Abril 2008

  • Cambios importantes en la práctica 2

Durante la semana pasada, descubrimos una clase en el API que nos parecía muy interesante para nuestro proyecto del SigueLinea y decidimos utilizarla. Esta clase es la clase Behavior. Durante la semana pasada e inicios de esta hemos estado cambiando todo el código para adaptarlo a esta clase. Hemos modulado el código implementando cada conjunto de métodos de cada sensor en una clase distinta. Hemos adaptado el programa principal a esta nueva clase.

A continucación se puede ver el código del proyecto SigueLinea implementado con la clase Behavior.

Ver codigo Class TestSigueLinea

Ver codigo Class MyLightSensor

Ver codigo Class My_Pilot

Ver codigo Class BuscaLinea

Ver codigo Class ReconoceVictimas

Ver codigo Class SigueLinea


Lunes, 28 Abril 2008

  • Implementada detección víctimas

Esta semana hemos estado implementando la detección de víctimas y la hemos añadido al algoritmo de SigueLinea. Uno de los problemas principales que hemos tenido es que reconocía más víctimas de las que había. En muchas ocasiones, cuando se ponía a buscar línea pitaba como si hubiera reconocido una víctima. Tras hacer trazas en pantalla, observamos que justo cuando la luz apunta al borde de la línea negra, al salirse del camino, el valor que recoge el láser es una mezcla del valor del laser cuando es negro y del valor del láser cuando es blanco, lo que se traduce en un valor intermedio a ambos, que puede coincidir con el valor del láser apuntando a verde. Es por ello que en muchas ocasiones que no había víctima, el robot reconocía una víctima falsa.

Para resolver lo explicado anteriormente, lo que hacemos cuando el valor recogido por el láser corresponde a una posible víctima, nos movemos unos 5 milímetros, y volvemos a medir. En este caso, al moverse, ya no estaremos en un borde del camino y, si al volver a medir, seguimos obteniendo valores que corresponde con una víctima, es cuando avisamos que hemos reconocido una víctima. Esta parte se puede ver en el código del método esVictima().

Ver codigo Class SIgueLinea

Ver codigo Class test SigueLinea


Miércoles, 23 Abril 2008

  • Terminado implementación resolución discontinuidades y mejoras en algoritmo sigue línea

Hoy hemos realizado la implementación para resolver el problema de las discontinuidades. Además, hemos aprovechado para incluir alguna mejora en el sigue línea:

  • Usamos distintas velocidades para buscar linea y para avanzar: A la hora de buscar linea reducimos la velocidad pues aprovechamos mientras está girando para buscar la línea y para detectarla, es más preciso si el robot va despacio. En cambio, cuando se trata de avanzar, aprovechamos y aumentamos la velocidad hasta que pierde la línea minimizando así, en media, el tiempo que tarda el robot en recorrer un circuito completo, una habitación, etc.
  • Memorizamos el sentido del último giro realizado. Con esto, el robot tarda, en general, menos en encontrar una línea. Lo primero que hace el robot cuando pierde una línea es oscilar para encontrarla de nuevo. A la hora de oscilar, debe decidir si oscilar hacia la izquierda o la derecha. Al tener el último giro memorizado, el robot en su primera oscilación al buscar la línea, girará donde esta variable le indique. Por ejemplo, cuando tenemos una curva a la izquierda, el robot a medida que la recorre se va saliendo constantemente dejando la línea a la izquierda. Gracias a esta variable que memoriza el sentido, el robot siempre empezará a buscar la línea girando hacia la izquierda, lo que permite encontrarla rápidamente. En caso contrario, girará después hacia la derecha.
  • Otra mejora realizada es controlar la cantidad de grados que gira el robot para no perder demasiado tiempo buscando líneas y resolviendo discontinuidades:
  1. Inicialmente, cuando el robot pierde una línea lo que hace es buscarla, método en el que la búsqueda la realizamos de forma muy local, es decir, girando apenas 15 grados para cada lado. Esto es perfectamente válido pues la mayoría de las curvas no están formadas por drásticos giros.
  2. Sino tiene éxito buscando la línea, pasa a ver si hay alguna discontinuidad. En este caso,el giro será algo más amplio e irá acompañado de un avance de unos 2 cm para superar la discontinuidad.
  3. Si tampoco tiene éxito, entonces el robot considera que se encuentra posiblemente perdido o ante un giro brusco de 90 grados en la línea (una esquina) y entonces, busca la línea pero en una amplitud mucho mayor, de unos 180 grados.

Ver código SigueLinea2 con mejoras y resolución de discontinuidad
Ver codigo Class TestSigueLinea

Otro video donde mostramos el robot ejecutando este código:

Martes, 22 Abril 2008

  • Terminado sigue línea

Hemos terminado la implementación de la clase "SigueLinea" y su correspondiente programa de prueba. El algoritmo es muy sencillo. Cuenta con dos métodos. Uno es "buscaLinea" que se pone a girar de un lado a otro aumentando cada vez el radio de giro mientras busca la línea, y "avanza" que mueve al robot mientras el sensor lea la línea negra.

Además hemos implementado algunas optimizaciones:


Jueves, 17 Abril 2008

  • Mejoras en implementación del algoritmo de navegación en práctica 1

Hemos realizado una mejora en el algoritmo de navegación:

Inicialmente el robot tenía que tomar una decisión entre cuatro posibles: Ir hacia delante, hacia la izquierda, hacia la derecha o hacia atrás. En la nueva versión del algoritmo, lo hemos generalizado para decidir entre N posibles casos. El rango de direcciones posibles viene determinado por la amplitud del radar. A partir de esta amplitud se reparten las N posibles direcciones en las que el robot, en función de los obstáculos que detecte con el radar, puede decidir. Además se ha cambiado el nombre de la clase a Navegacion que es mucho más intuitivo. A continuación se puede ver el código del algoritmo de navegación mejorado y todos los métodos de la clase y el programa de prueba testRadar.

Ver código Class Navegación

Ver código TestRadar


Miércoles, 16 Abril 2008

  • Terminada práctica 1:

Para esta práctica hemos implementado una clase llamada por el momento mapa la cual contiene información del mapa con el que el robot navega. En esta misma clase hemos implementado un algoritmo básico de navegación en el que elige ir hacia delante, izquierda, derecha o marcha atrás dependiendo de donde se encuentre un obstáculo. No hemos tenido ningún problema ya que el algoritmo es muy sencillo. A continuación se puede acceder al código:


Jueves, 10 Abril 2008

  • TODO: Ajustar el escalado para la representación gráfica. Montaje del radar en el robot.
  • Terminada implementación de la clase Radar:

Uno de los problemas que nos hemos encontrado ha sido la representación de los datos que recogemos con el sensor de ultrasonido. Una vez transformadas las coordenadas de polares a cartesianas y escalado el dato a la resolución de la pantalla (100 * 64) nos dimos cuenta de que no dibujaba de forma correcta. Después de hacer comprobaciones y revisar el código nos dimos cuenta que, aunque todo el cálculo matemático estaba correcto, había que trasladar el punto donde se encuentra el robot al centro de la pantalla.

Una vez hecho esto, comprobamos que el radar funciona perfectamente cuando no hay ningún obstáculo pues dibuja en pantalla un semicírculo perfecto sin ningún obstáculo. El problema nos viene cuando hay obstáculos. Puesto que es un motor mecánico, hacer la medición a lo largo de todo el barrido es un proceso relativamente lento, y hace que el robot tarde en detectar un obstáculo más de lo deseado. Si aumentamos la amplitud del barrido, la información que se obtiene es muy pobre( apenas 5 o 6 datos en una semicircunferencia). Por el contrario, un barrido más preciso, hace que la detección de obstáculos sea lenta.

A continuación se puede acceder al código de la clase radar:

Ver código Class Radar

Jueves, 03 Abril 2008

  • Inicio de la práctica 1: Implementados el constructor y el método "newScan()" de la clase Radar. No ha habido ningún problema relevante.

Miércoles, 02 Abril 2008

  • Instalando el firmware en el robot:

Tras intentar instalar la versión 0.5 de lejos y comprobar que no es posible debido a que nos daba un par de errores a la hora de generar el fichero nxjflash hemos decidido instalar por el momento la versión 0.4 que ya teníamos precompilada en los equipos del laboratorio.

  • Problema de la gestión de recursos en la práctica 0:

El programa finalizaba inesperadamente por quedarse sin memoria. Cada vez que se intenta escribir un string, se crea un objeto anónimo con el contenido de dicho string. Debido a que la versión 0.4 de Lejos no tiene recolector de basura, estos objetos anónimos no se liberan y siguen ocupando memoria. Por ello hemos tenido que modificar todas las funciones "drawString()" para que utilicen objetos estáticos que creamos inicialmente y que luego utilizamos repetidamente.

  • Terminada la práctica 0. (pendiente insertar foto de la pantalla)

Lo único interesante en esta práctica es que hay que tener cuidado con los objetos que instancias anónimamente porque si lo haces dentro de un bucle infinito, te quedas sin memoria enseguida, al no liberarse dicha memoria cuando deja de estar vigente el objeto que la reserva. Esto es debido a que el recolector de basura no está bien implementado en la versión 0.4 de lejos, como ya hemos comentado en el punto anterior.

A continuación se puede acceder al código de la práctica 0:

Ver código HelloWorld.java

Martes, 01 Abril 2008

  • Terminada la implementación de la práctica 0. Por el momento, no hay nada relevante que comentar sobre esta práctica.