miércoles, 1 de diciembre de 2010

Práctica 4- El nxt-way

En esta práctica, vamos a realizar un robot con un comportamiento parecido al jetway. El robot se mantendrá de pie sobre dos ruedas sin caerse. Para ello utilizamos un sensor de luz que nos dirá la posición en la que se encuentra.
Mediante el muestreo de errores estadísticos (PID) vamos corrigiendo la posición. Si cae hacia delante aceleramos el motor. Si se va hacia atrás, aceleramos el motor hacia atrás.
Para ello, utilizamos tres tipos de errores:

  • Error P: más conocido como error proporcional a la posición con respecto al punto de equilibrio.
  • Error I: según valla incrementándose el error aumenta su valor
  • Error D: más conocido como error derivativo, que compara el estado actual con el anterior
El código utilizado es el siguiente:  

import java.util.Vector;

import lejos.nxt.*;
import lejos.robotics.navigation.TachoPilot;

public class principal {
public static LightSensor LS = new LightSensor(SensorPort.S1);
public static int velocidadBase = 1;
public static TachoPilot navigator = new TachoPilot(5.6f, 11.1f, Motor.C, Motor.A);
public static PID pid = new PID();
public static int valormedio;
public static int errorP;
public static int errorD;
public static int errorI;
public static void main(String[] args) {
try{
Thread.sleep(1000);
while (!Button.ENTER.isPressed()) LCD.drawString(LS.readValue()+"  ",0 ,0 );
LS.calibrateLow();
while (Button.ENTER.isPressed()) LCD.drawString("calibrando",0 ,0 );
while (!Button.ENTER.isPressed()) LCD.drawString("calibrando",0 ,0 );
LS.calibrateHigh();
LCD.clearDisplay();
while (Button.ENTER.isPressed()) LCD.drawString(LS.readValue()+"  ",0 ,0 );
while (!Button.ENTER.isPressed()) LCD.drawString(LS.readValue()+"  ",0 ,0 );
valormedio = LS.readValue();
while (Button.ENTER.isPressed()) {
LCD.drawString(LS.readValue()+"  ",0 ,0 );
LCD.drawString(valormedio+"  ", 0, 1);
}
while (!Button.ENTER.isPressed()) {
LCD.drawString(""+LS.readValue()+"  ",0 ,0 );
LCD.drawString(valormedio+"  ", 0, 1);
}
for (int i=0; i<20; i++) pid.erAcumulado.addElement(0);
navigator.setSpeed(velocidadBase);
navigator.forward();
LCD.clearDisplay();
LCD.drawString(valormedio+" ", 0, 0);
while(!Button.ESCAPE.isPressed()){
int medida = LS.readValue();
pid.actualizarVector(medida);
errorP = pid.calculaerp(valormedio, medida);
errorD = pid.calculaerd(medida);
errorI = pid.calculaeri();
if (velocidadBase*((float)1.3*errorP + errorD + errorI)>0) navigator.backward();
else navigator.forward();
navigator.setMoveSpeed(velocidadBase*((float)1.3*errorP + errorD + errorI));//*1.3
LCD.drawString(errorP+" ",0,1);
LCD.drawString(errorD+" ",0,2);
LCD.drawString(errorI+" ",0,3);
}
} catch(InterruptedException e){}
}
}

class PID{
public Vector erAcumulado = new Vector(20);
public int calculaerp(int valorMedio, int medida){
return (medida - valorMedio);
}
public int calculaerd(int medida){
return (int)(medida - (Integer)erAcumulado.elementAt(18));
}
public int calculaeri(){
int error = 0;
for (int i=0; i<20; i++){
error += (Integer)erAcumulado.elementAt(i);
}
return (int)(error*0.005)*(int)(error*0.005);
}
public void actualizarVector(int error){
erAcumulado.removeElementAt(0);
erAcumulado.addElement(error);
}
}

Como curiosidad, nuestro robot al usar un sensor de luz no se comporta igual en toda las condiciones. Nuestro robot consiguió permanecer de pie mas de 20 segundos, lo cual supera nuestras expectativas. 


miércoles, 24 de noviembre de 2010

Práctica 3

No tenemos un buen recuerdo en nuestro paso por esta práctica. Decidimos utilizar la clase Behavior para programar los diferentes comportamientos de HAL 9000.
El caso es que cuando metíamos nuestro código en java en la CPU, el robot no realizaba los objetivos que queríamos que hiciera.

  • Comportamiento de evitación de obstáculos usando sensores de contacto: en este caso, el robot tenía que avanzar todo recto hasta que encuentre un obstáculo. En ese momento utilizamos otro comportamiento HitObject, en el que retrocedía y giraba un angulo con el método rotate para esquivarlo. En la práctica, el robot cuando chocaba, retrocedía y giraba. Queríamos que cuando girase detectase mientras si se choca con otro objeto también ejecute el comportamiento HitObject, pero no lo hicimos por falta de tiempo. 
  • Comportamiento de evitación de obstáculos usando sensores de ultrasonidos: El robot tenía que hacer lo mismo que la práctica anterior pero usando el sensor de ultrasonidos del nxt en vez del de contacto. Para ello además utilizamos vectores para posicionar el objetivo y el obstáculo para poder esquivarlo y llegar a un punto determinado. En la práctica,  el robot no realizaba lo que queríamos. Resulta que el robot tras detectar el obstáculo por el sensor de ultrasonidos, realizaba comportamientos extraños como darse la vuelta (aunque el objetivo estaba delante).
  • Comportamiento ir hacia la luz: El robot debía seguir la luz de una linterna y si desviaba la luz el robot tenía que seguirla. En la práctica, no realizaba este comportamiento, iba hacia delante pasará lo que pasará. El problema es que el estado del robot se quedaba dentro de un búcle y no salia de él aunque la diferencia de luminosidad con respecto a los dos sensores (derecho y izquierdo) cambiará. 
  • Comportamiento ir hacia la luz evitando obstáculos: como no pudimos realizar el anterior hito, pues tampoco se pudimos hacer este. 

martes, 9 de noviembre de 2010

Práctica 2

En esta práctica, utilizamos los sensores que vienen incluidos en legos nxt mindstorm. Los sensores que utilizamos son: el sensor de sonido o micrófono, el de ultrasonidos, el sensor de luz y el de contacto.
Tras conocer todos estos sensores y probar unos cuantos programas de prueba con cada uno, empezamos a hacer la práctica.

  •  En Obtener información, utilizamos los sensores de ultrasonidos y el de luz. En el programa debía especificar el nombre del robot, la distancia media en mm por el sensor de ultrasonidos (que nos daba 255 cm, ya que nunca le daba tiempo a recibir un eco), la luminosidad captada por el sensor de luz ( tanto el valor sin procesar como el porcentaje entre dos valores elegidos como máximo y mínimo), la duración de la batería en mv y la memoria libre en la CPU. En esta práctica no tuvimos mucha complicación ya que utilizamos el metodo LCD.DrawString para imprimir los datos. El problema más llamativo fue el de imprimir la memoria libre. Tras consultar en la API de lejos y un ejemplo en la subdirectorio samples de lejos_nxt, hallamos la forma de hacerlo. 

    
  • En Control de robot con sonido, utilizamos el sensor de sonido o micrófono para hacer que el robot ande mientras no le des una palmada. Tras dar la palmada o que suba el nivel de ruido por encima de unos decibelios, el robot se para. Para que se vuelva a mover es necesario otra palmada. Realiza esto cíclicamente, ya que utilizamos un bucle while. En esta práctica no tuvimos muchos problemas para que funcionase. Medimos el nivel de ruido que detecta el micrófono al dar una palmada y pusimos las condiciones en el bucle. 




  • En Bump & Go! usando sensores de contacto, utilizamos el sensor de contacto situado en la parte de atrás del robot, para que el robot vaya hacia atrás hasta que encuentre un obstáculo. Cuando lo detecta, se mueve unos cm hacia delante y gira un ángulo aleatorio mediante la función Random().



  • En Bump & Go! usando sensores de ultrasonido, el robot se mueve hacia delante hasta que los ecos que le llegan al sensor de ultrasonido al revotar en un obstáculo, le indican que se encuentra a una distancia de 20 cm o menos. En ese momento con navigator.backward() vamos hacia atrás unos cm y giramos un ángulo aleatorio como en el ejercicio anterior. 

miércoles, 27 de octubre de 2010

Práctica 1

Comenzamos con la primera práctica de IAR. Se trata de un práctica para familiarizarnos con el API de leJOS, que nos permite controlar nuestro robot.
Empezamos con programas sencillos como el Hola Mundo, que utilizaba el programa eclipse en linux para programar en java con unas librerías que cogimos de la carpeta lib de leJOS. En ella importamos lejos.nxt y utlizamos los métodos y los atributos del API del entorno de programación:



Después, empezamos con el control de los motores del robot utilizando para ello utilizamos la clase estática Motor y sus variables A,B,C (que se corresponden con cada puerto de la CPU) y algunos métodos como backward, forward etc.. Aquí os dejo un video:

                                       



                                       


                                           
Después hicimos un ejercicio para mostrar por el display los ángulos que van cambian al mover el motor. 
Para que el robot pueda moverse a través de dos motores conectados a dos ruedas motrices utilizamos la clase TachoPilot. 
Montamos nuestro robot para realizar el próximo ejercicio:



Comprobamos que el robot no terminar en la misma posición cuando termina el cuadrado como nos gustaría que pasará. 
         


                                                   
Hicimos una matriz de covarianza para ver el grado de incertidumbre del robot (en vez de 40 cm le pediremos que recorra 41 cm)
Por último, en la visualización de la trayectoria, centramos un origen de coordenadas para empezar (0,0,0) y según se movía una distancia D,  cambiamos la "x " y "y" iniciales. Cuando giraba, era necesario cambiar el ángulo (3 coordenada) y la "x" y la "y" (para este caso usamos el teorema de pitágoras).

domingo, 17 de octubre de 2010

Práctica 0- segunda parte: instalación del leJOS en el portátil

Después de hacer la práctica 0 en clase, instalamos el entorno leJOS en el portátil para poder hacer las prácticas en casa.
Como nosotros somos más de linux, instalamos  leJOS NXJ para linux desde su página oficial: http://lejos.sourceforge.net/
Una vez hecho esto, descomprimimos el paquete de leJOS con el comando tar de la shell y cambiamos las variables de entorno del fichero bashrc.

           #Pr actica de Rob otica
               export JAVA_HOME=/usr/lib/jvm/java-6-sun
               export NXJ_HOME=/home/sdiazt/practicas/robotica/lejos_nxj
               export PATH=$PATH:$NXJ_HOME/bin

El problema viene cuando queremos compilar la versión de leJOS. Accedemos a el subdirectorio build del directorio lejos_nxj y ejecutamos el comando ant ...... y salta BUILD FAILED!! ante puesto a un montón de errores que no voy a enumerar. Descubrimos que el problema era que para manejar el entorno era necesario instalar unas API o librerías. 
Como no sabíamos que hacer le mande un correo al profesor de prácticas. Él me sugirió que me mirara el blog de alex y pablo, así como el tutorial de leJOS. 
Así que instale libusb y libbluetooth-dev con el comando  sudo apt-get install nombre_libreria de la shell.
También modificamos los permisos de /dev/bus/usb/ con el comando chmod -R 777 /dev/bus/usb/00*.
A pesar de todos los cambios, cuando volvimos a ejecutar ant en el directorio build, volvió a salir el BUILD FAILED.

Así que a la siguiente clase, Carlos Agüero, el profesor de prácticas, nos dijo que nos faltaba instalar el libusb-dev. Lo instalamos junto con, mira tu por donde,a un script programado en C++ (y yo que pensaba que sólo se utilizaba JAVA en leJOS). Volvimos a probar el comando ant en la shell y voila: BUILD SUCCESSFUL!!

Una vez hecho esto, volvimos a meter los programas de HelloWorld y LCDUI en HAL9000, de los que hablamos en la anterior entrada.
                                                    HelloWorld ejecutado en HAL9000

                                                    LCDUI ejecutado en HAL9000


Para que no se apague la CPU de HAL9000, hemos aumentado el tiempo en que la cpu hace sleep a 10 minutos mediante el menú que aparece en el display de HAL9000: menu -->system-->sleep time
Cabe destacar, que tampoco pudimos cambiar el nombre con nxjbrowse en el portátil.

Práctica 0- primera parte: primera práctica en el laboratorio

Empezamos con la primera práctica. Esta práctica sirve para irse familiarizándose con el entorno de programación leJOS (si se escribe así, no es una falta ortográfica) para nuestro robot Lego NXT en el ordenador. Con este entorno podemos utilizar una máquina virtual de JAVA para utilizar en nuestro robot todos los programas que hagamos.

En el laboratorio, con el sistema operativo de software libre ubuntu de linux, seguimos el guión de la práctica sin problemas (no hacia falta descargase el entorno para NXT, ya que ya estaba en nuestra sesión, ni tampoco actualizar el firmware del robot, ya que en la CPU del robot estaba ya instalada la última versión del leJOS: la 0.85.  Simplemente había que configurar las variables de entorno del script bashrc y compilar y enlazar un par de programas ejemplo: HelloWorld y LCDUI. El primero muestra un "Hello World" por la pantalla de la CPU del robot y el otro muestra varios menús de opciones: tales como meter texto, sonidos...
Para acabar  vimos que era imposible cambiar con nxjbrowse el nombre del robot: HALL2009 por HAL9000 debido a problemas con la última versión de leJOS. Aún así, de ahora y en adelante, en este blog nos referiremos al robot con HAL9000.

                                                    CPU DEL ROBOT LEGO NXT: HAL9000


 Llevaremos una caja de herramientas con todo el material del robot (hardware) para llevar mejor las piezas que con la caja de legos.

                          

Nuevo compañero de trabajo

Tenemos un nuevo compañero de prácticas en nuestro grupo: Daniel Yagüe. Nos ayudará con la práctica hasta nuevo aviso.