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.