Bump-Go en LeJOS

IMG_2034_En este artículo voy a explicar el manejo básico de los motores así como del sensor de contacto, y después pondré un programa de ejemplo: el Bump-Go en LeJOS (que es un problema clásico de la robótica) con sensor de contacto. Este programa es un poco más complejo que el del anterior artículo (Manejo básico del LCD y los botones en LeJOS), pero no es muy difícil de implementar.

Manejo básico de los motores:

Los motores son una clase de objetos (class Motor), que como ya comenté en mi primer artículo poseen tanto métodos como atributos. En este caso como atributos nos interesa principalmente a qué puerto está conectado. Para acceder a un método o atributo de una clase se pone primero el nombre de la clase de objeto, a continuación un punto y posteriormente el nombre del atributo o clase. Para acceder, por ejemplo, al motor que está en el puerto A escribiremos:

Motor.A

Si queremos que este motor se mueva hacia adelante sería:

Motor.A.forward();

Una vez visto esto haré un repaso a los métodos básicos de la clase de objeto Motor:

void setSpeed(int velocidad): Establece la velocidad del motor (en grados por segundo).

void backward() : El motor gira hacia atras.

void forward() : El motor gira hacia adelante.

void rotate(int grados) : El motor gira un número de grados y se detiene.

void rotate(int grados, boolean devolverControl) : El motor gira un número de grados y se detiene. Además devuelve el control al programa inmediatamente para que pueda ejecutar otros métodos mientras está girando (en caso de que devolverControl sea true).

void stop() : Para el motor.

Con estos comandos ya podremos hacer que el robot navegue, aunque por supuesto hay comandos y clases más complejas para cuando se necesite mayor precisión.

Manejo del sensor de contacto:

El sensor de contacto es el más simple de los sensores del NXT. Básicamente tiene dos estados, pulsado o sin pulsar. Por tanto contará con un único método en LeJOS:

boolean isPressed() : Devuelve true en caso de que esté pulsado y false en caso contrario.

En Java es necesario declarar los sensores antes de poder usarlos, indicando qué tipo de sensor va a ir y en qué puerto. Para declarar, por ejemplo, un sensor de contacto en el puerto de sensores 1 tendremos que escribir:

TouchSensor contacto1 = new TouchSensor(SensorPort.S1);

Ahora ya podríamos usar este sensor de contacto tranquilamente:

presionado = contacto1.isPressed();

Bump&Go:

Bump&Go es un robot móvil que se mueve erráticamente por una habitación o piso, esquivando cualquier obstáculo que encuentre a su paso. En este caso, y dado que usaremos el sensor de contacto, podemos decir que más que esquivar lo que el robot irá haciendo cada vez que colisione con un obstáculo es dar marcha atrás y girar para encontrar otra posible ruta sin obstáculos. Puesto que su comportamiento va a ser aleatorio, está claro que será capaz de recorrer una habitación entera. Es solo cuestión de tiempo el que lo logre. De hecho este tipo de comportamiento se emplea, por ejemplo, en los robots aspiradora: el movimiento aleatorio esquivando obstáculos permite recorrer en su totalidad una habitación desconocida, lo que cumple con el objetivo de mantener limpia la habitación. Implementado simplemente así es un tipo de navegación muy simple, y tiene la ventaja de no exigir la necesidad de ningún sistema de localización, puesto que al tratarse de un movimiento aleatorio no se requiere conocer la posición del robot. (Versiones más avanzadas permiten que el robot pueda volver a la base para recargar las baterías. El problema de volver a una ubicación determinada sí requiere de un sistema más evolucionado).

IMG_2033_

Un posible código solución del problema sería el siguiente:

import lejos.nxt.*;
public class BumpAndGo {

public static void main(String[] args) throws Exception
{
TouchSensor contacto1 = new TouchSensor(SensorPort.S1);
Motor.A.setSpeed(400);
Motor.B.setSpeed(400);
LCD.drawString(“Pulse ESCAPE”, 2, 3);
LCD.drawString(“para parar”, 3, 5);
while (true){
Motor.A.forward();
Motor.B.forward();
if (contacto1.isPressed()){
Motor.A.stop();
Motor.B.stop();
Motor.A.rotate(-100,true);
Motor.B.rotate(-400,false);
}
if (Button.ESCAPE.isPressed()){
break;
}
}
LCD.clear();
Motor.A.stop();
Motor.B.stop();
LCD.drawString(“Adios”, 6, 4);
Thread.sleep(2000);
}

}

A continuación explicaré las lineas más importantes, recordad que en mi artículo anterior comente el programa entero, así que si tenéis dudas sobre alguna línea de este código (que no esté comentada en este artículo) estará seguramente comentada en el programa de mi artículo anterior:

06 – Declaración del sensor de contacto en el puerto uno. Así ya estará listo para su uso.

07 – Establecemos la velocidad del motor A (en este caso a 400 grados por segundo). Os recomiendo que para empezar a probar esta velocidad sea más reducida (por ejemplo 200) y luego vayáis subiendo una vez funcione.

08 – Lo mismo para el motor B.

11 – Esto es lo que se denomina un bucle infinito. Todo lo que haya dentro de los { } se repetira infinitas veces, o hasta que haya un break;

12 – Ponemos el motor A en marcha adelante, por tanto comenzará a moverse.

13 – Lo mismo para el motor B.

14 – La expresión condicional if típica de programación. Lo que hace es ejecutar lo que hay entre { } si se cumple la condición que hay dentro de los paréntesis (en este caso es si el sensor de contacto esta apretado o no).

15 – Para el motor A

16 – Para el motor B

17 – Hace que el motor A gire -700 grados (realmente este valor podría ser aleatorio, siempre y cuando sea negativo, ya que queremos que el robot de marcha atrás después de chocarse y si es posible gire un poco). Como dije en la explicación de métodos de la clase Motor puesto que devolverControl es true el programa se seguirá ejecutando a la vez que este motor va girando, por lo tanto:

18 – El motor B gira -400 grados a la vez que el motor A gira sus -700. Además hasta que no termine de girar programa no seguirá, ya que que en este caso devolverControl es false. Puesto que el valor es menor que el de A el efecto conjunto será que el robot dará marcha atrás y luego girará.

20 – Si el botón ESCAPE del NXT está pulsado, ejecutará:

21 – Salir del búcle.

Las lineas de después del búcle seguro que ya sois capaces de descifrarlas entre las explicaciones de este artículo y las de los anteriores.

En resumidas cuentas lo que hace este programa es que el robot ande marcha adelante hasta chocarse con un obstáculo; entonces dará marcha atrás, girará y seguirá otra vez moviéndose adelante. El robot solo detendrá la ejecución del programa cuando presionemos el botón ESCAPE del NXT. Aquí os pongo un vídeo demostrativo con el mismo programa que os he escrito en el artículo (recordad hacer un buen parachoques o puede que se os atasque):

Si tenéis alguna duda podéis postearla en el foro.

Comments are closed.