miércoles, 15 de diciembre de 2010

Sobre curvas

He pensado que para reconocer una curva correctamente, es insuficiente con saber si es hacia la derecha o hacia la izquierda, se necesita saber también el grado de curvatura que tiene (lo abierta que es). Creo que una buena técnica para averiguar lo abierta que es, podría ser utilizar interpolación lineal, esto es, que a a partir de un cierto número de distancias obtenidas por muestreo, se construya una función que los ajuste (una recta). La idea es interpolar las distancias de los sensores de la zona derecha o izquierda según sea una curva a izquierda o derecha respectivamente.

Con una imagen se ilustra mejor esto que quiero explicar:

El ángulo alpha sería el que nos determine lo abierta que es la curva. Como primera aproximación se podría considerar tener los siguientes tipos de curva: curva muy cerrada (alpha <= 25º), curva cerrada(25º <= alpha <= 45º),curva abierta (45º< alpha <= 60º) y curva muy abierta (60º< alpha <90º). Para el caso de 90º sería una recta, que es un caso que no se debería dar si se ha reconocido como curva correctamente el entorno.

En la versión anterior de la aplicación de telemetría el mapa no se pintaba correctamente, ya que no se podía pintar sólo con la información proporcionada por el vector de "cambios en el entorno", si no que es necesario pintar cada cierto número de muestreos, porque por ejemplo, no se sabe lo larga que es una recta. Además tampoco se podía pintar con precisión las curvas, al no tener información sobre su forma.
Implementaré esta idea y comentaré los resultados.
Saludos.

jueves, 9 de diciembre de 2010

Problema de parpadeo solucionado

Por fin conseguí solucionar el molesto problema del parpadeo en los gráficos, para ello he aplicado la técnica del doble búfer, que básicamente consiste en pintar en memoria la imagen completa que se produce en cada muestreo (en vez de pintar continuamente en pantalla cada componente), y luego volcarla a la pantalla. Los resultados de aplicar esta técnica son excelentes.

Me he basado en este artículo http://www.programacion.com/articulo/graficos_con_java_2d_111/23 para implementarla.

También he comenzado a mostrar durante la carrera todo lo que el vehículo va reconociendo y estoy almacenando todos los cambios de entorno que se reconocen en un vector. Para esta tarea he diseñado una nueva clase llamada "Entorno", en la que almaceno
  1. El estado (ciclo) del vehículo en el momento del cambio de un entorno reconocido a otro.
  2. Una cadena que representa el objeto reconocido (recta, curva_derecha, curva_izquierda, desconocido)
Esta información almacenada será clave para un posterior aprendizaje del circuito.

También he comenzado a dibujar el posible mapa que se obtendría de representar las curvas y rectas conocidas, aunque estoy teniendo algunas dificultades con el scroll, ya que al dibujar dentro de un panel scrollable elementos java2D y mover el scroll, lo que queda fuera del scroll desaparece. Buscaré información sobre este problema por foros y tutoriales.



Me queda por diseñar lo siguiente de momento:
  • Un predictor del entorno próximo.
  • Terminar de diseñar el dibujado de mapa.
  • Comprobar las pendientes de las distancias.

Saludos.

domingo, 5 de diciembre de 2010

Últimos avances

Entre los últimos avances realizados en el proyecto, puedo destacar que estoy utilizando ahora el cliente java champ2010, que tiene algunas mejoras respecto a versiones anteriores, como por ejemplo poder seleccionar los grados de separación entre los sensores de distancia y también poder controlar el embrague.

Con respecto al entorno de telemetría, ya tengo diseñado e implementado el almacenamiento de información proporcionada por los sensores mientras se ejecuta el simulador. Una vez que finaliza la carrera se puede desplazar una barra deslizante para observar el estado del vehículo durante el muestreo deseado. Se tiene la limitación de que sólo puede funcionar correctamente la barra deslizante, siempre que se almacenen menos de 2147483648 muestreos, ya que el rango máximo de datos que permite representar el control JSlider es de tipo entero (32bits en el caso de Java) aunque es poco probable que para una carrera se necesite tal cantidad de muestreos -en las pruebas realizadas siempre se necesitaban menos de 50000 muestreos en circutos con varias vueltas-. También he incluído algunos controles adicionales debajo de la barra deslizante para poder resetear todas las cajas de texto y registros al finalizar una carrera y también para poder hacer una selección más fina, pudiendo desplazar el cursor de la barra de uno en uno hacia delante o hacia atrás y también posicionarse en el primer y último muestreo. Además, se representa en el gráfico de la zona de telemetría de la GUI las distancias almacenadas en el muestreo seleccionado , y también aparece en una nueva caja de texto el entorno en el que se encuentra el vehículo en ese instante de muestreo, es decir, si se encuentra en recta, curva a derecha o curva a izquierda (o desconocido si no se adapta el entorno reconocido en ese momento a ninguna condición). Esta deducciones, en un primer diseño, las he tomado en base a la media de las distancias caturadas por los sensores de la zona derecha (sensores 0-8) e izquierda (sensores 10-18) del vehículo y en base a la distancia del sensor central (sensor 9), con resultados aceptables. Otras novedad, sin gran trascendencia, es la inclusión de una barra horizontal en la zona superior de la interfaz en la que tengo pensado incluir una ayuda sobre cómo utilizar la aplicación y también ofrecer la posibilidad de ajustar distintas opciones.


En la última reunión con mi director de proyecto, dicidimos que se mostrase el entorno percibido por el vehículo mientras éste se ejecuta (tal y como está diseñado ahora mismo hay que esperar a que termine la carrera). También se decidió que se debe mostrar también además del entorno actual, el siguiente (algo así como un lookahead, uan predicción de lo que viene). Una vez corregido esto, el siguiente paso será aplicar un algoritmo como aproximación para aprender el circuito:


Inicializar estado_anterior a vacio al comenzar la simulación

En cada muestreo, llamar a update:

update(estado_actual)
{
si (estado_anterior==vacio)
entonces
estado_anterior=estado_actual
guardar(estado_actual)

si (estado_anterior!=estado_actual)
entonces
guardar(estado_actual)
estado_anterior=estado_actual

sino
no hacer nada
}

En resumen, este algoritmo almacenará los cambios que se produzcan del entorno observado, por ejemplo, si el coche está en una recta, se almacenará una única vez el estado mientras esté en dicha recta, y si se produce un cambio de esa recta a una curva, se almacenará de nuevo el estado y así cada vez que se produzca un cambio en el medio observado mediante los sensores de distancia.A partir de almacenar esta información se podrá representar el mapa del circuito.

Quedan algunas mejoras pendientes, como evitar el parpadeo/ralentización en los gráficos de la telemetría y también comprobar las pendientes de los vectores que se dibujan ya que parece que en las rectas no se representa de forma adecuada las medidas capturadas. Otra idea es incluir otra caja de texto en la interfaz gráfica para que se pueda seleccionar la anchura de la pista a examinar, y así conseguir escalar mejor las distancias en su representación.

Saludos a todos los lectores y hasta la próxima entrada en la que seguiré contando mis avances, correcciones y problemas que pudiesen surgir nuevos.

sábado, 27 de noviembre de 2010

Modificando la GUI de telemetría y otras novedades

Actualmente me ecuentro refinando la interfaz gráfica de telemetría, para ello estoy usando el framework de Netbeans, a la vez que refresco el proyecto en Eclipse con F5. Ahora puedo diseñar interfaces con más agilidad, pudiendo dedicarme más a la lógica de la aplicación, que es lo realmente interesante.




En mi última entrevista con mi director de proyecto definimos los siguientes pasos del proyecto. Una vez finalizado la representación gráfica de telemetría, la idea es almacenar el estado del vehículo (esto es, las medidas de distancia, velocidad, distancias a oponentes,etc obtenidas por los sensores) en cada muestreo para emplear este conjunto de datos posteriormente para generar conocimiento acerca del entorno del vehículo. Al estado se accederá mediante una barra de reproducción ( tengo que estudiar el cómo se implementa, pero no parece complicado desde Netbeans).

A partir de este conjunto de datos almacenados, se deberá poder deducir si el coche se encuentra en una recta o una curva; y en el caso de las curvas se deberá poder deducir también el sentido de ésta (derecha o izquierda) y la distancia a la que está la siguiente curva.

Finlemente, la última etapa será aprender el circuito mediante alguna técnica de IA, concretamente del campo de Aprendizaje Automático. En un principio he decidido emplear redes neuronales para esta tarea, aunque de momento no poseo los conocimientos suficientes para implementarlas (estoy cursando la asignatura de Aprendizaje en estos momentos y en ésta me instruirán sobre esta técnica y otras más).
Una vez conseguidos todos estos objetivos, también implementaré un módulo para pintar el mapa a partir de toda la información generada.

Saludos y hasta la próxima entrada.

jueves, 25 de noviembre de 2010

Grabar vídeo de carrera



Investigando por la red, he leído (http://usuarios.multimania.es/f1torcs/tutorial/index.html) que es posible grabar vídeos de las carreras de Torcs, que es una opción que viene en el juego, aunque algo oculta. Se puede crear un vídeo de forma fácil, solo se necesita el programa open source VirtualDubMod" (descargable desde http://virtualdubmod.sourceforge.net/).

Pasos a seguir
  1. Crear las imágenes png con TORCS.
Hay que configurar el ficheros torcs/config/raceengine.xml



Hay que configurar la habilitación de captura(yes), el número de frames por segundo (fps) y el directorio de salida.


Ejecutar una carrera en torcs , y para crear el vídeo pulsar la tecla c. Las imágenes png del vídeo se salvarán en el directorio de salida.

El nombre de las imágenes es: torcs-0001-00000000.png, torcs-0001-00000001.png, torcs-0001-00000002.png, torcs-0001-00000003.png...


    1. Crear el vídeo a partir de las imágenes

Ahora usaremos VirtualDubMod. Ejecutarlo y hacer click en File->Open Video File y seleccionar torcs-0001-00000000.png y hacer click en Open, (todas las imágenes creadas con torcs serán cargadas a VirtualDubMod.

Ir a video-> Frame Rate y conigurar al ratio que se eligiese en torcs/confing/raceengine.xml.

Ahora a File->Save y seleccionar la compresión, escribir el nombre del vídeo y hacer click en Save.Este paso puede tardar un poco, después de ésto el vídeo estará creado.

Si se desea se puede modificar el vídeo con las herramientas que suministra VirtualDubMod, como cambiar la resolución.

miércoles, 24 de noviembre de 2010

Telemetría

Como ya he comentado en la entrada anterior, mi proyecto constará de 2 partes: una parte será el desarrollo de un entorno de telemetría para poder estudiar el comportamiento del coche, y la otra parte consistirá en aplicar técnicas de IA para hacer que el coche aprenda el circuito (ésto aún no está definido como se hará, puede ser con algoritmos genéticos, redes neuronales u otro tipo de técnica de aprendizaje automático) .

Pasemos a describir el estado actual del componente de telemetría. Este componente está subdividido en varias secciones, una de ellas es la representación gráfica de medidas de distancia tomadas, otra sección es la representación numérica de las distancias, en otra tenemos un control de grabación de datos, y en otra tenemos un reproductor de vídeos.



La aplicación está realizada en Java usando para la interfaz gráfica (en adelante GUI) la librería SWING. Tengo que señalar que la realización de GUIs en Java es tediosa y no es para nada una tarea trivial, ya que he programado toda la GUI a código al haber pocos frameworks para swing que permitan arrastrar y soltar componentes como en el IDE Visual Studio.
Es cierto que en versiones anteriores de Eclipse existía un plugin llamado Visual Editor, pero que actualmente ha quedado desafasado y no es compatible con las versiones actuales de Eclipse, pero para evitar más problemas de compatibilidades de otro tipo por utilizar una versión antigua, prefiero utilizar una versión reciente de Eclipse, en este caso la Helios.

Por fortuna, después de mucho investigar por internet (y después de haber escrito gran parte de la GUI directamente en código), leí en esta web http://netbeanside61.blogspot.com/2008/04/eclipse-project-using-gui-designed-from.html que el IDE NetBeans trae incorporado un framework de edición de GUIs, que se puede emplear combinadamente con Eclipse desde una opción que tiene de "importar proyecto de Eclipse". Una vez importado, se pueden crear las GUIs y después únicamente hay que refrescar los fuentes del proyecto en Eclipse para tener accesibles las GUIs creadas en el otro entorno.



La cantidad de tiempo que me ha consumido y sigue consumiendo el diseño y refinamiento de la GUI está siendo elevado, pero es satisfactorio ver que con un poco de esfuerzo se puede conseguir una GUI aceptable.

Para conseguir representar las medidas en la zona de telemetría, he empleado la API Java2D, que permite dibujar distintos tipos de figuras geométricas, tales como líneas, arcos, circunferencias, círculos rellenos y óvalos con propiedades configurables. Entrando un poco más a nivel de implementación, señalo que he usado coordenadas polares, que se adaptaban muy bien a este caso, ya que tenía que dibujar rectas que partían desde el centro de una circunferencia y se alargaban proporcionalmente a la medida del sensor que representaba cada una , siendo el máximo de distancia el equivalente a que la recta toque el arco de la circunferencia. Como hay 19 sensores de distancia , he tenido que dividir los 180º de la semicircunferencia superior en 19 partes.

El cambio de coordenadas cartesianas a polares es el siguiente:
x=r*cos(alpha)
y=r*sen(alpha)

Continuaré explicando el resto de secciones de la interfaz en siguientes entradas.

jueves, 4 de noviembre de 2010

Sobre mi proyecto

Introducción
El proyecto consistirá en el diseño y desarrollo de un conductor virtual y de una herramienta visual de telemetría básica, donde poder estudiar y depurar el comportamiento del agente. Tanto en el agente como en la telemetría se aplicarán algunas técnicas de IA.

El entorno en el que se desarrollará el proyecto es el simulador de carreras de coches TORCS http://torcs.sourceforge.net/.

Sobre TORCS
Este juego es de código abierto, y tenemos la posibilidad de conectar un cliente que implemente al conductor del vehículo con el motor del juego. Dicho cliente está disponible para los lenguajes de programación C++ y Java, y para mi PFC me he decantado por el de Java, por la cantidad de librerías que tiene disponible y mi mayor familiarización con este lenguaje.

Temporalización del PFC
Mi objetivo es finalizarlo a muy a tardar, en septiembre de 2011, aunque preferiría tenerlo terminado para julio del 2011. Tengo que señalar que me encuentro cursando 5º a la vez que desarrollo el proyecto, por lo que en gran medida mi tiempo disponible va a estar condicionado por la carga de trabajos y prácticas que tenga en el resto de asignaturas. Mi idea es realizar el proyecto mediante una metodología iterativa incremental, es decir ir construyendo la aplicación poco a poco revisando en cada nueva iteración lo que llevo hecho de la anterior, refinando así lo que quedase pendiente. Idealmente las iteraciones serán de 15 días. De hecho, tengo una "entrevista" con mi director de proyecto cada 15 días también, para que vaya viendo mis avances y que vaya corrigiendo lo que no vea correcto.

Herramientas y software a emplear
He seleccionado como IDE Eclipse, ya que es el mejor IDE para Java actualmente junto con NetBeans. También estoy usando tecnologías web 2.0, como en el caso de este blog o el uso de un disco duro virtual en el que voy colocando los fuentes, ficheros y documentos necesarios en cada iteración.
Estoy empleando como sistema operativo Windows 7, aunque debe funcionar correctamente en cualquier otro sistema operativo siempre que se tenga instalada la máquina virtual de Java.

Presentación

Hola a tod@s:
Mi nombre es Ricardo Moreno Hernández, soy natural de Huelva y a día de la escritura de esta entrada tengo 24 años. Actualmente estoy finalizando mis estudios de Ingeniería Informática (2º ciclo) en la Universidad de Hueva.
En Octubre de 2010 he comenzado mi Proyecto Fin de Carrera, requisito indispensable para poder ser Ingeniero en Informática y mi intención es utilizar este blog como medio de comunicación en dónde iré comentando mis progresos y problemas que vayan surgiendo durante la realización del mismo.