En el artículo anterior vimos que es posible comunicar PC y NXT gracias a las librerías de LeJOS. Hoy vamos a mostrar cómo conectar y manejar varios NXT simultáneamente a través de Bluetooth con LeJOS, y la diferencia respecto a manejar varios NXT desde otro NXT, como su mucha menor latencia.
Comunicación con el PC:
Como puse en el artículo anterior, para comunicar cualquier dispositivo Bluetooth con el ordenador necesitamos un adaptador Bluetooth para el ordenador, que puede estar integrado en la placa base, o se puede adquirir por separado. Para ver cómo echadle un vistazo a dicho artículo.
Las ventajas de conectar varios NXT a un PC en lugar de a otro NXT maestro son claras: no tenemos problemas de latencias tan altas como las comunicaciones NXT-NXT, tenemos un número prácticamente ilimitado de conexiones en lugar de las tres máximas que acepta un NXT, y además la potencia de cálculo de un ordenador no es comparable con la de un NXT. Podríamos incluso crear un interfaz gráfico para manejar un NXT radio-control desde el PC.
Lo mejor del tipo de comunicaciones que vamos a usar es que no necesitamos subir ningún programa al NXT, todo lo hacemos desde el PC, lo cual nos facilita muchas cosas, desde las comunicaciones hasta la velocidad para realizar cálculos complejos.
En el artículo anterior ya mostré qué métodos se utilizan para realizar la conexión, por tanto si queremos conectarnos con varios NXT sólo tendremos que repetir el proceso de conexión varias veces, asegurándonos de que todos los NXT se han conectado correctamente con el PC. Es importante dejar un retardo después de realizar varias conexiones, de forma que nos aseguraremos que todos están listos para recibir ordenes.
Una vez estén todas las conexiones listas podemos dar ordenes a uno u otro NXT indistintamente. Recordad que para elegir a cuál vais a dar una instrucción es necesario usar antes el método:
NXTCommand.getSingleton().setNXTComm(nombre_conexión.getNXTComm());
poniendo en nombre_conexión el nombre que le hayamos dado a la conexión que queramos utilizar (Ej.: conn1, conn3, …). Usad este método cada vez que queráis cambiar el objetivo de vuestras ordenes. Por ejemplo, si quiero mover el motor A con dos NXT, cuyas conexiones son conn1 y conn2 sería:
NXTCommand.getSingleton().setNXTComm(conn1.getNXTComm());
Motor.A.forward();
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.forward();
Es MUY importante que al final del programa cerréis las conexiones con el método close() o el PC no os conectará con los NXT la segunda vez que queráis usar el programa (tendrías que apagar y encender los NXT en su lugar).
Programa de ejemplo:
En el programa de ejemplo vamos a hacer que el ordenador ordene a dos NXT moverse simultáneamente describiendo un cuadrado. Es importante que la forma de los robots sea la misma para que quede bien, ya que si la distancia entre las ruedas es mayor, o uno pesa más que otro ya no se moverían igual.
No estamos utilizando la librería Navigation de LeJOS, por lo que el cálculo del cuadrado lo hemos hecho aproximado, rotando los motores un número determinado de grados. Lo importante es que este programa consigue mover simultáneamente los dos robots desde el PC, cosa que sería imposible desde otro NXT debido a las latencias. El código sería el siguiente:
import lejos.nxt.*;
import lejos.nxt.remote.NXTCommand;
import lejos.pc.comm.*;
/*
ElectricBricks Entertainment S.L.
Autor: Álvaro Peláez Santana
Fecha: 13/04/2010
Nombre: MultiControl
Descripción: Programa que controla remotamente dos NXT desde un PC,
ordenándoles que realicen una figura geométrica simultáneamente.
*/
public class MultiControl {
public static void main(String [] args) throws Exception {
NXTConnector conn = new NXTConnector();
if (!conn.connectTo(“NXT”, NXTComm.LCP)) {
System.err.println(“Conexión Fallida”);
System.exit(1);
}
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
NXTConnector conn2 = new NXTConnector();
if (!conn2.connectTo(“NXTTorna”, NXTComm.LCP)) {
System.err.println(“Conexión Fallida”);
System.exit(1);
}
Thread.sleep(1000);
int x = 720;
int y = 520;
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(y, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(y);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(y, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(y);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(y, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(y);
NXTCommand.getSingleton().setNXTComm(conn.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x, true);
NXTCommand.getSingleton().setNXTComm(conn2.getNXTComm());
Motor.A.rotate(x, true);
Motor.B.rotate(x);
Thread.sleep(1000);
conn.close();
conn2.close();
}
}
Este tampoco es un programa muy complejo, si tenéis alguna duda sobre el manejo de motores en LeJOS os recomiendo el este artículo. Aquí os dejo un vídeo demostración del funcionamiento de este programa, que como podéis ver hace que los NXT se comporten de manera casí simultánea:
Por último, insistir en que si tenéis alguna duda posteadla en el foro. Un saludo y hasta otro artículo.