¡¡¡Abre los ojos!!!

En este caso había que conseguir que solamente con las imágenes obtenidas a través de una webcam el robot se moviera por un determinado espacio.
El territorio por el que se podía desplazar estaba compuesto de colores uniformes:
- Las paredes son grises
- El suelo amarillo
- Las papeleras azules
- Las puertas rojas
Todo esto simplifica bastante el trabajo, ya que no es necesario aplicar filtros de color a la imagen obtenida.
Lo importante de todo este proceso es el algoritmo que gobierna todo, por eso, a continuación comentaré a grandes rasgos el algoritmo usado y sus funciones:
- Función EsPasillo
Indica si el píxel pedido pertenece al pasillo o no.

- Función BuscarHueco
En los parámetros que recibe, dejará almacenada la posición inicial del hueco encontrado
y el tamaño de éste.

- Función CalcularVelocidad
La velocidad se obtiene a partir de la mitad inferior de la columna de píxeles situada en
el centro de la imagen. Si todos esos píxeles pertenecen al pasillo, se aplica la velocidad
máxima; sino, se aplica una velocidad proporcional a los píxeles contiguos que
pertenecen al pasillo, empezando a contar estos píxeles desde la parte inferior de la
imagen.

- Función Yourcode_iteration
Este es el código que se ejecuta de forma periódica.
Principalmente, los pasos que realiza son:
1. Busca hueco
2. Si el hueco es mayor de 50 píxeles, comprobamos la fila de píxeles
correspondiente al 90% de la imagen. A partir de la observación de esa línea,
calculamos 2 ángulos de giro. Uno correspondiente a los obstáculos
observados por la derecha, para lo cual usamos la mitad derecha de la línea
observada; y otro a los encontrados por la izquierda, usando la mitad izquierda
de dicha línea. Por último, sumamos los ángulos obtenidos y tenemos la
dirección final que debemos seguir para esquivar los objetos.
3. Si el ángulo que debemos girar se encuentra entre -15 y 15 grados, avanzamos
a una velocidad de 900 porque más o menos es una línea recta y no tenemos
obstáculos alrededor; sino, avanzamos a una velocidad de 500.
4. Si el hueco del punto 2 no es mayor de 50 píxeles, el robot no tiene claro que
sea capaz de pasar por ese lugar, por lo tanto calculará la velocidad y
aumentará el ángulo de giro. Si el ángulo de giro que esté siguiendo en ese
momento es negativo, se aumentará el giro hacia la derecha, y si es positivo se
aumentará hacia la izquierda.

Durante el periodo de desarrollo pudimos comprobar que las paredes del simulador son bastante parecidas a las de los departamentales (si soplabas se volaban), que las papeleras estaban llenas de piedras… pero en el momento decisivo, ¡todo funcionó correctamente y no observamos nada de esto por no tocar ni papeleras ni paredes! :D
La única pega que observé fue la velocidad a la que se avanzaba, podía haber sido mayor.
Pero no es una pega importante, ya que permitió que el robot terminase en una tercera posición.

Este es el video de la competición:

Práctica final de Lego NXT - Circuito de cajas

¡¡¡Es la última sesión de prácticas con Wall·E!!!
Al llegar a clase, nos sorprendimos de lo que había montado. Se trataba de un circuito de cajas y otros obtáculos en el que nuestro robot debía demostrar sus habilidades!

Como en los grandes premios de la Formula 1, tuvimos algunos minutos para dar unas vueltas de reconocimiento al circuito y realizar los últimos ajustes antes de la competición. Este tiempo y la rápidez con la que efectuamos los cambios en nuestro robot fueron primordiales para poder obtener los resultados que obtuvimos. Entre los ajustes realizados en el pick line están: el tanto por ciento que debía recorrer sobre la distancia medida por el ultrasonido, la modificación externa que sufrió Wall·E para conseguir que su cabeza apuntara hacía abajo (permitiendo así detectar todos los obstáculos del circuito) y algún pequeño ajuste más en el algoritmo principal.

Como habíamos tenido muchos imprevistos antes de la carrera y modificamos bastantes cosas, entre nuestras espectativas no estaba la de subir al podium. Pero la sorpresa llegó en al final del campeonato, cuando vimos que fuimos los 3º!! a tan solo 1 punto del 1º y del 2º. Hasta el último momento tuvimos posibilidades de alzarnos con el trofeo, pero Wall·E en la última decisión que tenía que tomar se equivocó (como se puede observar en el video).



¡Continuamos trabajando!

Práctica final de Lego NXT - Navegación con rádar

Bien!! Wall·E, bien!! por fin le llegó la hora de aprender algo nuevo, y lo más importante, lo aprendió bien.




Lo primero que hicimos fue colocar el sensor de ultrasonidos en un sitio adecuado para su movimiento, permitiéndonos obtener una buena información. Eso nos llevo una clase, pero conseguimos un excelente resultado. Tras algún retoque más, también fue posible conseguir una buena estabilidad a través de engranajes.



Es el momento de crear el algoritmo que permita a nuestro robot encaminarse por el hueco más amplio que observe. Para ello hemos programado un código en el que damos puntuaciones a los valores guardados en el array (las medidas obtenidas por el ultrasonido). En esta puntuación no tenemos en cuenta solo el ángulo que estamos tratando. También influyen los ángulos adyacentes siempre y cuando la distancia obtenida por el ultrasonido en ellos se encuentren entre la distancia del ángulo que puntuamos y un 15% menos.

import lejos.nxt.*;
import lejos.navigation.Pilot;;
public class usoRadar {

/**
* @param args
*/
final static int amplitud = 180;
final static int resolucion = 10;
final static int velocidad = 500;
private static int Puntuar(int[] distancias){
int puntos[] = new int[amplitud/resolucion];
int mayor, pos;
for (int i=1; i<(amplitud/resolucion -1);i++){ puntos[i] = distancias[i]; if (distancias[i-1]>=127){
puntos[i]+=distancias[i-1];
}else{
puntos[i]-= (125-distancias[i-1])*(1.5);
}
if (distancias[i+1]>=127){
puntos[i]+=distancias[i+1];
}else{
puntos[i]-= (125-distancias[i+1])*(1.5);
}
}

mayor=puntos[0];
pos=0;
for (int j=1; j < (amplitud/resolucion); j++) { if (mayor < mayor="puntos[j];" pos="j;" sonic =" new" radar =" new" pilot =" new" data =" new" data =" radar.newScan();" giro =" Puntuar(data)*resolucion;">90){
pilot.rotate(-(giro-90));
}else{
pilot.rotate(90 - giro);
}
Button.waitForPress();

pilot.travel((int)(-data[giro/resolucion]/1.5));

}
}

}


Y aquí van algunos videos de como se maneja nuestro robot. Pero donde mejor se va a notar su comportamiento va a ser en el circuito creado por los profesores.



Proyecto Wiimote y lego Mindstorm

Este grupo de 5 chicos que estudian la asignatura de Biocibernética Computacional en la Universidad de las Palmas de Gran Canaria han decidido crear un proyecto, mediante el cual quieren controlar los movimientos del lego Mindstorm usando un mando de la wii.

Para ello probaron este diseño, que no iba a funcionar porque las ruedas traseras no giraban:
Por lo que decidieron cambiar de modelo ( nosotros tambien hemos pasado por esto muchas veces ).

Lo mas importante era controlar al robot a través de una conexión bluetooth, cosa que hicieron y con lo que consiguieron resolver una parte del problema. Para ello utilizaron un pequeño programa (creado por ellos mismos para el control mediante el teclado del robot por Bluetooth).

El siguiente paso era conectar el Wiimote al ordenador y éste, a la vez, al lego. El primer paso fue probar la conexión entre Wiiremote y PC que se realiza fácilmente usando un pequeño programita llamado GlobePie, que permite asociar cada botón del mando de Nintendo a cualquier pulsación de teclado. Lo siguiente fue conectar independientemente el NXT al ordenador mediante Bluesolei.


Al cabo de un tiempo y con gran esfuerzo, llegaron al punto de mover el NXT con los movimientos del mando sin llegar a tocar ningún boton del mismo!



Ya lo único que les quedaba era ajustar la sensibilidad de los movimientos entre el mando y el robot y mejoras en pasos anteriores.



¡Llegó la hora! En el siguiente video se muestra la defensa final de su proyecto. Que envidia!



Y por último nos dejan un video, donde aparcan el robot entre unos obtáculos:



Jaja y ya por que no jugar a la Wii con la aplicacion creada! Aqui un video de ellos jugando a los bolos.



Su derección es: http://www.canarias7.es/blogs/niutin/biocibernetica/wiibot/

Ejercicio opcional - Comportamientos

Esta vez a Wall·E se medio atraganto en su etapa de aprendizaje, ahora toca mostrar los malos momentos. Después de muchas pruebas se consiguió que nuestro pequeño robot siguiese una linea negra, aunque de forma muy nerviosa. Al modificarlo para arreglar este "nerviosismo" y hacer que el robot fuese más tranquilo, cambiamos algo que no debíamos y todavía no hemos podido arreglarlo (por falta de tiempo).

Disponemos de algún video de Wall·E en sus primeros intentos de seguir líneas. Como es un prototipo inicial, podremos observar que bastantes fallos a la hora de buscar la línea. Justo eso es lo que intentábamos arreglar cuando Wall·E decidió no seguir más líneas.


Lo bueno de todo esto, es que nos hemos dado cuenta de la importancia de programar usando varios comportamientos y que luego, dependiendo de cada circustancia, podamos indicar que se ejecute uno, otro o varios; ya sea mediante un árbitro o un autómata de estados finitos.

Práctica 3: El uso de los threads

¡¡¡Wall·E es increible!!!

Cansado de avanzar y de girar usando solamente una función, Wall·E será capaz de mostrar datos de forma concurrente!

En el siguiente video, a Wall·E le hemos desactivado los motores para poder observar bien los datos que capta. Estos datos son mostrandos por pantalla (se visualiza el dato antiguo y el nuevo del sensor de luz).

Para apreciar mejor los cambios de datos que recoge el sensor hemos utilizado un objeto negro. No se aprecia muy bien la diferencia entre el dato nuevo y el dato viejo debido a que el código se ejecuta muy rápidamente y la información mostrada en la pantalla es actualizada varias veces por segundo, pero podemos afirmar que Wall·E realiza su función perfectamente:



Ahora le activamos los motores y comprobamos el correcto funcionamiento de los dos threads ejecutándose de forma concurrente, uno controlando el movimiento del robot y el otro mostrando la información por la pantalla.

Práctica 3: Navegando con la clase Pilot

¡¡Por fin!!
Wall·E se va haciendo mayor y por ello va adquiriendo más independencia.
Lo siguiente que va a hacer es mediante el uso de la clase Pitot. Wall·E avanzará describiendo un 8 en el suelo, pudiéndose observar en el siguiente video la complicación existente a la hora de realizar los giros.


Esta dificultad consiste en que para realizar el giro hay que tener en cuenta distintos factores (diámetro de la rueda, distancia entre ruedas...) y cualquier modificación el diseño de Wall·E (modificaciónes en su aspecto externo) implica que haya que reeditar este programa.
En el siguiente video se muestra su funcionamiento: