lunes, 25 de abril de 2011

Cálculo de huecos para adelantamientos

Una de las últimas mejoras en las que he podido progresar ha sido la detección de la zona por la que hay hueco suficiente para poder adelantar.
Para diseñar esta mejora he necesitado aplicar bastante trigonometría:

En esta imagen he representado cómo se calcularía la distancia del oponente al borde izquierdo (para el cálculo al borde derecho sería similar). Supongamos que la zona negra de la imagen es una carretra recta, el rectángulo rojo nuestro vehículo, y el círculo rojo un oponente. Nuestro objetivo es calcular la distancia D_op_b (distancia desde el oponente al borde). Para calcular, básicamente lo que hay que hacer es hallar la diferencia entre D_total (distancia desde nuestro coche al borde) y D_op_x (distancia desde nuestro vehículo al oponente). El problema surge en el cálculo de cada distancia, ya que no es tan simple como pueda parecer, porque entra en juego la variable alpha (ángulo respecto al eje de la pista).
En primer lugar calculamos la D_total; para ello tomamos la distancia proporcionada por S0 (S18 en el caso del cálculo de la distancia del oponente al borde derecho) y la multiplicamos por el coseno de alpha: D_total=S0*cos(Cº). Notar que C=alpha. A continuación necesitamos calcular D_op_x, y para ello necesitamos el ángulo bº. Este ángulo se obtiene mediante la fórmula :

b=( (S_oponente*10) - s.getAngleToTrackAxis())-90

(suponiendo las unidades en grados y siendo S_oponente el índice del sensor que nos ha detectado un oponente).

Una vez que hemos calculado b, podemos cacular D_op_x.

D_op_x=abs( dist_op*cos(b) )

Finalmente, tenemos que calcular si el oponente está a nuestra derecha o izquierda, para sumar o restar el valor D_op_x a D_total. Para realizar este cálculo, previamente tenemos que saber cuál es nuestro "sensor de referencia", esto es, qué sensor está paralelo al eje de la carretera. Esto se calcula fácilmente con la fórmula

referencia=18-(int)(Math.toDegrees(s.getAngleToTrackAxis())/10);

Una vez que sabemos cual es este sensor de referencia, simplemente tenemos que comprobar si el sensor dónde está el oponente tiene un índice menor o mayor. Si el índice es menor, entonces el oponente está a nuestra izquierda, y si es mayor, está a nuestra derecha.

En el caso de que esté a la izquierda, D_op_b =D_total-d_op_x
En el caso de que esté a la derecha, D_op_b =D_total+d_op_x

Con esto, ya tenemos calculado el "hueco", dato que nos servirá para comprobar si nuestro coche es mayor que dicho hueco, y en caso de que sea el mayor hueco que se haya detectado, podríamos plantearnos adelantar si se dan las condiciones (por ejemplo, que nos de tiempo de adelantar antes de llegar a una curva).

En siguientes entradas continuaré ampliando los progresos y trataré con más detalle aspectos que se comentaron en entradas anteriores.

lunes, 18 de abril de 2011

Detección precisa de rectas y curvas

Actualmente me encuentro en la etapa de diseño de reglas, y para ello es imprescindible detectar correctamente cuándo se está en una curva o una recta.
Hasta ahora esto lo detectaba a través del sensor que me proporcionase la mayor distancia, pero daba algunos problemas al encontrarse en curvas y en paralelo al eje de la pista (daba como resultado que estaba en una recta en ese caso). La forma correcta de hacer esta comprobación es la siguiente:

- Hay que calcular la pendiente entre el sensor 0-1 y el 1-2 para la zona izquierda del coche y comprobar si son aproximadamente iguales, esto es, que estén alineados.
Se comprobará que sean aproximadamente iguales porque una recta perfecta no existe en TORCS.

- Para la zona derecha el método es el mismo pero para los pares 16-17 y 17-18.

Si tanto en la derecha como en la izquierda se detectan que los puntos están alineados, entonces se podrá afirmar con seguridad que se está en una recta, y en caso contrario, en una curva. Para saber el sentido de la curva si se podrá utiliza el sensor que nos proporcione la máxima distancia, aunque previamente habrá que calcular cuál es el eje de referencia, que dependerá del ángulo del coche respecto al eje de la pista.

He de decir que tras realizar multitud de pruebas, no me salían alineados los puntos cuándo el coche estaba en una recta y no estaba parelelo al eje, y descubrí a qué era debido... vi que en el fichero SimpleDriver, los autores modificaban los ángulos de separación de los sensores de distancia al inciarse el conductor (en la función initAngles), y por defecto no están a 10º como pensábamos, sino que tienen distintas precisiones. Por ello, cuando estaba en la fase del diseño de la GUI de telemetría no me salían correctamente las distancias... es decir que no era necesario calcular el radio pequeño que se comentó hace varias entradas.
Aquí dejo una captura en la que se puede ver que ahora se perciben las rectas con gran precisión.



Y aquí dejo otra captura mostrando el método que he nombrado anteriormente. Lo he modificado de forma que los sensores queden separados cada 10º.


Una vez que tenga resuelto el problema de detección de curvas/rectas pasaré a diseñar una máquina de estados, que me servirá para poder elegir distintos conjuntos de reglas, según la situación en la que se esté.
En principio se tendrán los siguientes estados: Inicial, Recta, Curva, Adelantamiento.
Se cambiará de estado cuándo se dispare alguna regla que contenga como consecuente un cambio de estado.

Ejemplo de reglas del estado "adelantar":
0 hay_hueco(izquierda)&da_tiempo(adelantar)->adelantar(izquierda)
1 hay_hueco(derecha)&da_tiempo(adelantar)->adelantar(derecha)
2 hay_hueco(centro)&da_tiempo(adelantar)->adelantar(centro)

Se puede observar que cada vez los antecedentes y los consecuentes están siendo más complejos e inteligentes.

También hay algunas ideas más por desarrollar como:

- La comprobación de la velocidad del oponente para ver si es alcanzable antes de que se llegue a una curva (esto es imprescindible para poder tener antecedentes del tipo "me da tiempo de adelantar").
- El diseño de un controlador difuso para el control de las marchas.
- Diseñar un controlador PID (http://es.wikipedia.org/wiki/Proporcional_integral_derivativo) para realimentar la entrada con la dirección.
- Aplicar teoría del campo eléctrico para realizar adelantamientos (basándose en el comportamientos de cargas del mismo signo, que se repelen)



Y para finalizar esta entrada, dejo 2 vídeos más sobre los adelantamientos que se están logrando



viernes, 8 de abril de 2011

Primer adelantamiento con reglas reactivas

Aquí dejo un vídeo en que se puede observar el resultado de aplicar un conjunto de reglas para lograr adelantamientos (en rectas de momento)

Como curiosidad decir que se está obteniendo un comportamiento inteligente a partir de reglas reactivas muy básicas (swarm intelligence).

La primera versión del conjunto de reglas que estoy utilizando es esta:

0 entorno(recta)&posicion_pista(centro)&dist_op_izq(lejos)&dist_op_centro(cerca)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(-0.7)

1 entorno(recta)&posicion_pista(derecha)&dist_op_izq(lejos)&dist_op_centro(cerca)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(0.8)

2 entorno(recta)&posicion_pista(izquierda)&dist_op_izq(lejos)&dist_op_centro(cerca)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(-0.8)

3 entorno(recta)&posicion_pista(centro)&dist_op_izq(cerca)&dist_op_centro(lejos)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(-0.8)

4 entorno(recta)&posicion_pista(centro)&dist_op_izq(lejos)&dist_op_centro(lejos)&dist_op_der(cerca)->acelerar(0.9)&frenar(0)&direccion(0.8)

5 entorno(recta)&posicion_pista(derecha)&dist_op_izq(cerca)&dist_op_centro(lejos)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(-0.5)

6 entorno(recta)&posicion_pista(derecha)&dist_op_izq(cerca)&dist_op_centro(cerca)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(-0.5)

7 entorno(recta)&posicion_pista(izquierda)&dist_op_izq(lejos)&dist_op_centro(cerca)&dist_op_der(cerca)->acelerar(0.9)&frenar(0)&direccion(0.3)

8
entorno(recta)&posicion_pista(izquierda)&dist_op_izq(cerca)&dist_op_centro(cerca)&dist_op_der(lejos)->acelerar(0.9)&frenar(0)&direccion(-0.7)

miércoles, 6 de abril de 2011

Guía rápida de la aplicación de telemetría para TORCS

Se trata de una aplicación Java que proporciona un entorno de estudio para vehículos del juego TORCS.
Los datos se envían desde el cliente Java de TORCS a la aplicación de telemetría a través de sockets UDP, por lo que se pueden tener la aplicación de telemetría y el cliente Torcs en equipos distintos.

La interfaz gráfica de la aplicación consiste en una serie de pestañas y una barra de menú con distintos botones:

Pestañas
--------
La pestaña Gráficas muestra gráficamente la velocidad, las revoluciones por minuto y la aceleración del vehículo durante la carrera. En cada vuelta la línea tiene un color distinto. Una vez finalizada la carrera, se puede acceder a un control de reproducción, en el que se puede seleccionar el instante deseado. Una vez seleccionado el instante deseado, se mostrará en distintas cajas de textos los valores de las percepciones en dicho instante.
(Diseñado, a falta de testear)



La pestaña Gráficas II muestra gráficamente el nivel de fuel y la marcha del vehículo durante la ejecución de la carrera. En cada vuelta la línea tiene un color distinto.
(Diseñado, a falta de testear)



La pestaña Gráficas acciones muestra gráficamente la aceleración y el frenadodel vehículo.
(Por diseñar, es necesario disponer primero del módulo de IA que está en su fase de diseño para conocer qué acciones se envían)


La pestaña Telemetría muestra en un panel a la izquierda la representación de las distancias tomadas por los 19 sensores de distancia que hay distribuidos en el vehículo cada 10º , a la derecha se muestra un volante que representa la dirección que está tomando el vehículo, y también hay algunas cajas de texto que muestran el entorno por el que está circulando el vehículo ( recta o curva con su correspondiente radio de curvatura). En una futura versión también se incluirá una gráfica de abrras que representará el nivel de acelerado/frenado.
(Diseñado y estable)



La pestaña Mapa va mostrando el mapa del circuito según las distancias tomadas por los sensores.
(Por diseñar)

Menú de opciones
Es una barra con 3 botones en la versión actual:

-Un botón para abrir ficheros log (en formato .xls) y poder analizarlo mediante las gráficas y el control de reproducción.



-Un botón de opciones que de momento solo contiene la opción de si guardar en log o no las percepciones de cada instante de la carrera. Permite al usuario seleccionar el directorio dónde desea almacenar el fichero xls.



-Un botón de acerca de.




Por supuesto hay que señalar que la interfaz será mejorada en futuras versiones y se terminarán de implementar/refinar todas la funcionalidades.

martes, 5 de abril de 2011

Inteligencia artificial

La siguiente fase del PFC consistirá en diseñar e implementar el módulo de IA. Estará compuesto por:

- Un razonador para realizar adelantamientos.
- Un controlador fuzzy para los cambios de marcha.
- Un 'cerebro' en el que almacenar todas las percepciones.

El razonador será un motor de selección de reglas del tipo

(1) P) A1 ^ A2^A3^....^An -> C

Las reglas estarán expresadas mediante lógica de predicados de primer orden (http://es.wikipedia.org/wiki/L%C3%B3gica_de_primer_orden).


Es decir tenemos un conjunto de reglas, y un conjunto de hechos (percepciones y medidas sintetizadas a partir de las percepciones), y a partir de esta base de conocimiento, deducimos la acción a realizar.

R |= A ( " Del conjunto de reglas, se deduce la acción ")

En la fórmula de ejemplo (1)La P representa la prioridad, los Ai son los antecedentes ( condiciones que provienen de cálculos y análisis de las percepciones) y C será la acción consecuente.
Las reglas serán tanto simbólicas, como no simbólicas (es decir, representaremos valores tanto con cadenas de letras -- cerca, lejos, etc- como con valores numéricos - 20, 10, etc- según el caso).

El funcionamiento es como se describe a continuación:
Inicialmente leemos el fichero o la base de datos en la que tengamos las reglas almacenadas.
A continuación se ordenan por orden de prioridad (0...N).
El motor se activará cada vez que se detecte algún rival mediante los sensores de oponentes.
Una vez activado, se pasará a un bucle en el que se irá evaluando cada regla, y en el momento que sean verdaderos todos los antecedentes, se seleccionará dicha regla y se disparará la acción consecuente ( la acción estará compuesta por 3 acciones propias de Torcs -aceleración,frenado y dirección).

La evaluación de la regla consistirá en analizar la regla mediante un parser, tokenizando cada antecedente y comprobando que su valor sea cierto para el instante actual. Si todos los antecedentes son ciertos, entonces la regla será evaluada como verdadera y será seleccionada.
A continuación una vez seleccionada, se analizará la parte consecuente y se enviará el conjunto de acciones al cliente.

El controlador fuzzy consistirá en diseñar un controlador difuso de tipo Mamdani, en el que las reglas representarán etiquetas con grados. En próximas entradas se describirá con más precisión y de forma práctica, ya que la teoría en la que se basa es algo tediosa.

El cerebro, en realidad ya existe desde hace varias versiones, es la lista de todas las percepciones tomadas en cada instante.