import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import lejos.pc.comm.*; /** * Provides Bluetooth communications services to RCNavitationControl:<br> * 1. connect to NXT * 2. send commands using the Command emum * 3. receives robot position * @author Roger */ public class RCNavComms { /** * constructor establishes call back path of the RCNavigationControl * @param control */ public RCNavComms(RCNavigationControl control) { this.control = control; System.out.println(" RCNavComms start"); } /** * connects to NXT using Bluetooth * @param name of NXT * @param address bluetooth address */ public boolean connect(String name, String address) { System.out.println(" connecting to " + name + " " + address); connector = new NXTConnector(); boolean connected = connector.connectTo(name, address, NXTCommFactory.BLUETOOTH); System.out.println(" connect result " + connected); if (!connected) { return connected; } dataIn = connector.getDataIn(); dataOut = connector.getDataOut(); if (dataIn == null) { connected = false; return connected; } if (!reader.isRunning) { reader.start(); } return connected; } /** * inner class to monitor for an incoming message after a command has been sent <br> * calls showRobotPosition() on the controller */ class Reader extends Thread { public boolean reading = false; int count = 0; boolean isRunning = false; public void run() { isRunning = true; while (isRunning) { if (reading) //reads one message at a time { System.out.println("reading "); float x = 0; float y = 0; float h = 0; boolean ok = false; try { x = dataIn.readFloat(); y = dataIn.readFloat(); h = dataIn.readFloat(); ok = true; System.out.println("data " + x + " " + y + " " + h); } catch (IOException e) { System.out.println("connection lost"); count++; isRunning = count < 20;// give up ok = false; } if (ok) { control.showtRobotPosition(x, y, h); reading = false; } try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(RCNavComms.class.getName()).log(Level.SEVERE, null, ex); } } }// if reading Thread.yield(); }//while is running } /** * sends a command with a variable number of float parameters. * see http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html * the section on Arbitrary Number of Arguments * @param c a Command enum * @param data an array of floats built from the collection list parameters. */ public void send(Command c, float... data) { while(reader.reading) { Thread.yield(); } try { dataOut.writeInt(c.ordinal()); // convert the enum to an integer for (float d : data) // iterate over the data array { dataOut.writeFloat(d); } dataOut.flush(); } catch (IOException e) { System.out.println(" send throws exception " + e); } reader.reading = true; //reader: listen for response } /** * used by reader */ private DataInputStream dataIn; /** * used by send() */ private DataOutputStream dataOut; private Reader reader = new Reader(); private NXTConnector connector; private RCNavigationControl control; }