From 53b947df484159f5934898ba6c0aa69a9c869007 Mon Sep 17 00:00:00 2001
From: Ido Hadanny
+ * Run it with something like:
+ Run it with something like:
+ Run it with something like:
+ Run it with something like: Some code taken from processing.serial.Serial. Thanks guys!
+ * On creation, the class initializes the parameters, then tries to read .roomba_config.
+ * If it can read the config file and parse out the parameters, it sets the parameters to
+ * the values in the config file. Apps can read the current settings for display using methods
+ * on the class. Apps can override the settings by accepting user input and setting the
+ * parameters using methods on the class, or the connect() method. Parameters that are
+ * changed by the app are re-written in the config file, for use as defaults next run.
+ * Command-line apps can make these parameters optional, by using the defaults if the
+ * user doesn't specify them.
+ *
+ * SVN id value is $Id: RoombaCommSerial.java 136 2010-04-06 00:07:23Z black.123 $
+ */
+public class RoombaCommSerial extends RoombaComm implements SerialPortEventListener
+{
+static final int databits = 8;
+ static final int parity = SerialPort.PARITY_NONE;
+ static final int stopbits = SerialPort.STOPBITS_1;
+ /**
+ * The time to wait in milliseconds after sending sensors command before
+ * attempting to read
+ */
+ public static int updateSensorsPause = 400;
+
+ /** the serial input stream, normally you don't need access to this */
+ public InputStream input;
+ /** the serial output stream, normally you don't need access to this */
+ public OutputStream output;
+
+ /**
+ * RXTX bombs when flushing output sometimes, so by default do not
+ * flush the output stream. If the output is too buffered to be
+ * useful, do:
+ * roombacomm.comm.flushOutput = true;
+ * before using it and see if it works.
+ */
+ public boolean flushOutput = false;
+ byte buffer[] = new byte[32768];
+ int bufferLast;
+
+ //int bufferSize = 26; // how big before reset or event firing
+ //boolean bufferUntil;
+ //int bufferUntilByte;
+
+ /**
+ * Let you check to see if a port is in use by another Rooomba
+ * before trying to use it.
+ */
+ public static boolean isPortInUse( String pname ) {
+ if (ports != null && pname != null){
+ Boolean inuse = (Boolean) ports.get( pname );
+ if( inuse !=null ) {
+ return inuse.booleanValue();
+ }
+ }
+ return false;
+ }
+
+ // constructor
+ public RoombaCommSerial() {
+ super();
+ makePorts();
+ readConfigFile();
+ }
+ public RoombaCommSerial(boolean autoupdate) {
+ super(autoupdate);
+ makePorts();
+ readConfigFile();
+ }
+ public RoombaCommSerial(boolean autoupdate, int updateTime) {
+ super(autoupdate, updateTime);
+ makePorts();
+ readConfigFile();
+ }
+
+ void makePorts() {
+ if( ports == null )
+ ports = Collections.synchronizedMap(new TreeMap());
+ }
+ /**
+ * Connect to a serial port specified by portid
+ * doesn't guarantee connection to Roomba, just to serial port
+ * @param portid name of port, e.g. "/dev/cu.KeySerial1" or "COM3"
+ * @return true if connect was successful, false otherwise
+ */
+ public boolean connect(String portid) {
+ logmsg("connecting to port '"+portid+"'");
+ portname = portid;
+ writeConfigFile(portname, getProtocol(), waitForDSR?'Y':'N');
+
+ if( isPortInUse( portid ) ) {
+ logmsg("port is in use");
+ return false;
+ }
+
+ connected = open_port();
+
+ if( connected ) {
+ // log in the global ports hash if the port is in use now or not
+ ports.put( portname, new Boolean( connected ) );
+ sensorsValid = false;
+ }
+ else {
+ disconnect();
+ }
+
+ return connected;
+ }
+ public boolean connect(String portid,String protocal) {
+ String setProt="OI";
+ if (protocal.equalsIgnoreCase("SCI")){
+ setProt="SCI";
+ }
+ if (protocal.equalsIgnoreCase("OI")){
+ setProt="OI";
+ }
+ setProtocol(setProt);
+ logmsg("connecting to port '"+portid+"' using protocal '"+setProt+"'");
+ return connect(portid);
+ }
+
+ /**
+ * Disconnect from serial port
+ */
+ public void disconnect() {
+ connected = false;
+
+ // log in the global ports hash if the port is in use now or not
+ if (ports != null && portname != null ){
+ ports.put( portname, new Boolean( connected ) );
+ }
+
+ try {
+ // do io streams need to be closed first?
+ if (input != null) input.close();
+ if (output != null) output.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ input = null;
+ output = null;
+
+ try {
+ if (serialPort != null) serialPort.close(); // close the port
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ serialPort = null;
+ }
+
+ /**
+ * subclassed. FIXME:
+ */
+ public boolean send(byte[] bytes) {
+ try {
+ output.write(bytes);
+ if( flushOutput ) output.flush(); // hmm, not sure if a good idea
+ } catch (Exception e) { // null pointer or serial port dead
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ /**
+ * This will handle both ints, bytes and chars transparently.
+ */
+ public boolean send(int b) { // will also cover char or byte
+ try {
+ output.write(b & 0xff); // for good measure do the &
+ if( flushOutput ) output.flush(); // hmm, not sure if a good idea
+ } catch (Exception e) { // null pointer or serial port dead
+ //errorMessage("send", e);
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ /**
+ * toggles DD line via serial port DTR (if available)
+ */
+ public void wakeup() {
+ serialPort.setDTR(false);
+ pause(500);
+ serialPort.setDTR(true);
+ }
+
+ /**
+ * Update sensors. Block for up to 1000 ms waiting for update
+ * To use non-blocking, call sensors() and then poll sensorsValid()
+ */
+ public boolean updateSensors() {
+ System.out.println("updateSensors-start");
+ sensorsValid = false;
+ sensors(); // requests sensor group 0
+ for(int i=0; i < 20; i++) {
+ if( sensorsValid ) {
+ if ((buffer[1] > 1) || (buffer[1] < 0)) {
+ sensorsValid = false;
+ logmsg("updateSensors: received invalid data while attempting to read Roomba sensors!");
+ System.out.println("updateSensors: received invalid data while attempting to read Roomba sensors!");
+ } else {
+ logmsg("updateSensors: sensorsValid!");
+ System.out.println("updateSensors: sensorsValid!");
+ }
+
+ break;
+ }
+ logmsg("updateSensors: pausing...");
+ System.out.println("updateSensors: pausing...");
+ pause( 50 );
+ }
+ if (!sensorsValid){
+ logmsg("updateSensors: no data received.");
+ };
+ System.out.println("updateSensors: end");
+ return sensorsValid;
+ }
+
+ /**
+ * Update sensors. Block for up to 1000 ms waiting for update
+ * To use non-blocking, call sensors() and then poll sensorsValid()
+ */
+ public boolean updateSensors(int packetcode) {
+ sensorsValid = false;
+ sensors(packetcode);
+ for(int i=0; i < 20; i++) {
+ if( sensorsValid ) {
+ logmsg("updateSensors: sensorsValid!");
+ break;
+ }
+ logmsg("updateSensors: pausing...");
+ pause( 50 );
+ }
+
+ return sensorsValid;
+ }
+
+ /**
+ * called by serialEvent when we have enough bytes to make sensors valid
+ */
+ public void computeSensors() {
+ sensorsValid = true;
+ sensorsLastUpdateTime = System.currentTimeMillis();
+ computeSafetyFault();
+ }
+ /*
+ pause(updateSensorsPause); // take a breather to let data come back
+ sensorsValid = false; // assume the worst, we're gothy
+ int n = available();
+ //logmsg("updateSensors:n="+n);
+ if( n >= 26) { // there are enough bytes to read
+ n = readBytes(sensor_bytes);
+ if( n==26 ) { // did we get enough?
+ sensorsValid = true; // then everything's good, otherwise bad
+ computeSafetyFault();
+ }
+ } else {
+ logmsg("updateSensors:only "+n+" bytes available, not updating sensors");
+ }
+
+ //logmsg("buffer contains: "+ buffer );
+ return sensorsValid;
+ */
+
+ /**
+ * If this just hangs and never completes on Windows,
+ * it may be because the DLL doesn't have its exec bit set.
+ * Why the hell that'd be the case, who knows.
+ * FIXME: deal more gracefully
+ * (from processing.serial.Serial)
+ */
+ public String[] listPorts() {
+ Map ps = Collections.synchronizedMap(new LinkedHashMap());
+ //Vector list = new Vector();
+ try {
+ //System.err.println("trying");
+ Enumeration portList=null;
+ try {
+ portList = CommPortIdentifier.getPortIdentifiers();
+ } catch (Exception e) {
+ //System.err.println("2");
+ errorMessage("listPorts1", e);
+ }
+ //System.err.println("got port list");
+ while (portList.hasMoreElements()) {
+ CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement();
+ logmsg("Found port: " + portId.getName());
+
+ if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
+ String name = portId.getName();
+ //list.addElement(name);
+ Boolean state = (Boolean) ports.get( name );
+ if( state==null ) state = new Boolean(false);
+ ps.put( name, state );
+ }
+ }
+ } catch (UnsatisfiedLinkError e) {
+ //System.err.println("1");
+ errorMessage("listPorts", e);
+ } catch (Exception e) {
+ //System.err.println("2");
+ errorMessage("listPorts", e);
+ }
+ //System.err.println("move out");
+ /*
+ for( Enumeration e = list.elements(); e.hasMoreElements(); ) {
+ String p = (String) e.nextElement();
+ if( ! ports.containsKey( p ) ) {
+ ports.put( p, new Boolean(false) );
+ }
+ }
+
+ // DEBUG
+ System.err.println("ports hashtable:");
+ for( Enumeration e = ports.keys(); e.hasMoreElements(); ) {
+ String p = (String) e.nextElement();
+ Boolean b = (Boolean) ports.get(p);
+ System.err.println("port:"+p+", inuse:"+b);
+ }
+ */
+ ports = ps;
+ String outgoing[] =
+ (String[]) new TreeSet(ports.keySet()).toArray(new String[0]);
+
+ return outgoing;
+ }
+
+
+ public boolean isWaitForDSR() {
+ return waitForDSR;
+ }
+
+ public void setWaitForDSR(boolean waitForDSR) {
+ this.waitForDSR = waitForDSR;
+ writeConfigFile(portname, getProtocol(), waitForDSR?'Y':'N');
+ }
+
+ public String getPortname() {
+ return portname;
+ }
+
+ public void setPortname(String p) {
+ portname = p;
+ logmsg("Port: " + portname);
+ writeConfigFile(portname, getProtocol(), waitForDSR?'Y':'N');
+
+ }
+
+ // -------------------------------------------------------------
+
+ // below only used internally to this class
+ // -------------------------------------------------------------
+
+ /**
+ * internal method, used by connect()
+ * FIXME: make it faile more gracefully, recognize bad port
+ */
+ private boolean open_port() {
+ boolean success = false;
+ try {
+ Enumeration portList = CommPortIdentifier.getPortIdentifiers();
+ while (portList.hasMoreElements()) {
+ CommPortIdentifier portId =
+ (CommPortIdentifier) portList.nextElement();
+
+ if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
+ System.out.println("found " + portId.getName());
+ if (portId.getName().equals(portname)) {
+ logmsg("open_port:"+ portId.getName());
+ serialPort = (SerialPort)portId.open("roomba serial", 2000);
+ //port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
+ input = serialPort.getInputStream();
+ output = serialPort.getOutputStream();
+ serialPort.setSerialPortParams(rate,databits,stopbits,parity);
+ serialPort.addEventListener(this);
+ serialPort.notifyOnDataAvailable(true);
+ logmsg("port "+portname+" opened successfully");
+
+ if( waitForDSR ) {
+ int i=40;
+ while( !serialPort.isDSR() && i-- != 0) {
+ logmsg("DSR not ready yet");
+ pause(150); // 150*40 = 6 seconds
+ }
+ success = serialPort.isDSR();
+ } else {
+ success = true;
+ }
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ logmsg("connect failed: "+e);
+ serialPort = null;
+ input = null;
+ output = null;
+ }
+
+ return success;
+ }
+
+ /**
+ * callback for SerialPortEventListener
+ * (from processing.serial.Serial)
+ */
+ synchronized public void serialEvent(SerialPortEvent serialEvent) {
+ try {
+ logmsg("serialEvent:"+serialEvent+", Available:"+input.available());
+ if (serialEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
+ while (input.available() > 0) {
+ logmsg("serialEvent: available="+input.available());
+ buffer[bufferLast++] = (byte) input.read();
+ if( bufferLast == 26 ) {
+ bufferLast = 0;
+ System.arraycopy(buffer, 0, sensor_bytes, 0, 26);
+ computeSensors();
+ }
+ /*
+ synchronized (buffer) {
+ if (bufferLast == buffer.length) {
+ byte temp[] = new byte[bufferLast << 1];
+ System.arraycopy(buffer, 0, temp, 0, bufferLast);
+ buffer = temp;
+ }
+ buffer[bufferLast++] = (byte) input.read();
+ }
+ */
+ } // while
+ }
+ } catch (IOException e) {
+ errorMessage("serialEvent", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void playSong(RoombaComm roombacomm, String rtttl){
+ ArrayList notelist = RTTTLParser.parse( rtttl );
+ int songsize = notelist.size();
+ // if within the size of a roomba song, make the nsong, then play
+ if( songsize <= 16 ) {
+ updateDisplay("creating a song with createSong()", true);
+ int notearray[] = new int[songsize*2];
+ int j=0;
+ for( int i=0; i< songsize; i++ ) {
+ Note note = (Note) notelist.get(i);
+ int sec64ths = note.duration * 64/1000;
+ notearray[j++] = note.notenum;
+ notearray[j++] = sec64ths;
+ }
+ roombacomm.createSong( 1, notearray );
+ roombacomm.playSong( 1 );
+ }
+ // otherwise, try to play it in realtime
+ else {
+ updateDisplay("playing song in realtime with playNote()",true);
+ int fudge = 20;
+ for( int i=0; i< songsize; i++ ) {
+ Note note = (Note) notelist.get(i);
+ int duration = note.duration;
+ int sec64ths = duration*64/1000;
+ if( sec64ths < 5 ) sec64ths = 5;
+ if( note.notenum != 0 )
+ roombacomm.playNote( note.notenum, sec64ths );
+ roombacomm.pause( duration + fudge );
+ }
+ }
+ }
+}
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTCPClient.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTCPClient.java
new file mode 100644
index 0000000..34c16cf
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTCPClient.java
@@ -0,0 +1,451 @@
+/*
+ * RoombaComm TCP Interface
+ *
+ *
+ * Copyright (c) 2005 Tod E. Kurt, tod@todbot.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+
+package com.hackingroomba.roombacomm;
+
+
+import java.net.*;
+import java.io.*;
+
+import com.hackingroomba.roombacomm.*;
+/*
+ * SVN id value is $Id: RoombaCommTCPClient.java 182 2010-11-02 03:49:10Z bouchier $
+ */
+public class RoombaCommTCPClient extends RoombaComm implements Runnable
+{
+ String host = null;
+ int port = -1;
+
+ Socket socket;
+ InputStream input;
+ OutputStream output;
+
+ Thread thread;
+ private byte buffer[] = new byte[32768];
+ int bufferIndex;
+ int bufferLast;
+
+
+ // constructor
+ public RoombaCommTCPClient() {
+ super();
+ }
+
+ public RoombaCommTCPClient(RobotConnection rc)
+ {
+ super(rc);
+ }
+
+ public boolean connect(String portid) {
+ String s[] = portid.split(":");
+ if( s.length < 2 ) {
+ logmsg("bad portid "+portid);
+ return false;
+ }else{
+ logmsg("portid is ("+portid+")");
+ port=0;
+ host = s[0];
+ if (host != null){
+ logmsg("Host is ("+host+")");
+ }else{
+ logmsg("Host is (null)");
+ return false;
+ }
+ try {
+ port = Integer.parseInt(s[1]);
+ } catch( Exception e ) {
+ logmsg("bad port "+e);
+ return false;
+ }
+ logmsg("connecting to '"+host+":"+port+"'");
+ try {
+ socket = new Socket(host, port);
+ socket.setKeepAlive(true);
+ socket.setSoTimeout(30000);// timeout in milliseconds - 30 sec
+ input = socket.getInputStream();
+ output = socket.getOutputStream();
+ thread = new Thread(this);
+ thread.start();
+ //this.setConnected(this.updateSensors()); // test if we are connected or not
+ this.setConnected(true); // TODO: fix this properly
+ } catch( Exception e ) {
+ logmsg("connect: "+e); //e.printStackTrace();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void disconnect() {
+ try {
+ // do io streams need to be closed first?
+ if (input != null) input.close();
+ if (output != null) output.close();
+ this.setConnected(false);
+ } catch (Exception e) {
+ System.out.print("exception in disconnect");
+ e.printStackTrace();
+ }
+ thread = null;
+ input = null;
+ output = null;
+
+ try {
+ if (socket != null) socket.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ socket = null;
+ }
+
+ public boolean send(byte[] bytes) {
+ // use robotConnection if it exists, else do it the old way
+ if (robotConnection != null) {
+ return(robotConnection.send(bytes));
+ }
+
+ try {
+ //logmsg("Send_byte( "+bytes+")");
+ output.write(bytes);
+ output.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean send(int b) { // will also cover char
+ // use robotConnection if it exists, else do it the old way
+ if (robotConnection != null) {
+ return(robotConnection.send(b));
+ }
+
+ try {
+ //logmsg("Send_( "+b+" & 0xff)");
+ output.write(b & 0xff); // for good measure do the &
+ output.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ return false;
+ }
+
+ public void wakeup() {
+ logmsg("wakup unimplemented");
+ }
+
+ public boolean updateSensorsOLD() {
+ sensorsValid = false;
+ for(int i=0; i < 20; i++) {
+ sensors();
+ if( sensorsValid ) {
+ if ((buffer[1] > 1) || (buffer[1] < 0)) {
+ sensorsValid = false;
+ logmsg("updateSensors: received invalid data while attempting to read Roomba sensors!");
+ } else {
+ logmsg("updateSensors: sensorsValid!");
+ }
+ break;
+ }
+ logmsg("updateSensors: pausing...");
+ pause( 50 );
+ }
+ return sensorsValid;
+ }
+
+ // copied from RoombaCommSerial
+ public void computeSensors() {
+ sensorsValid = true;
+ sensorsLastUpdateTime = System.currentTimeMillis();
+ computeSafetyFault();
+ }
+
+ public String[] listPorts() {
+ String s[] = new String[0];
+ if( host !=null && port !=-1 ) {
+ String p[] = { host+":"+port };
+ return p;
+ }
+ return s;
+ }
+
+
+ //////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void run() {
+ bufferLast = 0;
+ while (Thread.currentThread() == thread) {
+ try {
+ while (input != null) {
+ buffer[bufferLast++] = (byte) input.read(); // this will block - wait until there's something
+ //logmsg("TCP received sensor data: " + buffer[bufferLast-1]);
+ if( bufferLast == readRequestLength ) {
+ bufferLast = 0;
+ System.arraycopy(buffer, 0, sensor_bytes, 0, 26);
+ sensorsValid = true;
+ //computeSensors();
+ }
+
+// synchronized (getBuffer()) {
+// if (bufferLast == getBuffer().length) {
+// byte temp[] = new byte[bufferLast << 1];
+// System.arraycopy(getBuffer(), 0, temp, 0, bufferLast);
+// setBuffer(temp);
+// }
+// getBuffer()[bufferLast++] = (byte) input.read();
+// }
+ }
+
+// try {
+// // uhh.. not sure what's best here.. since blocking,
+// // do we need to worry about sleeping much? or is this
+// // gonna try to slurp cpu away from the main applet?
+// Thread.sleep(10);
+// } catch (InterruptedException ex) { }
+
+ } catch (IOException e) {
+ System.err.println("run:"+e);
+ }
+ }
+ }
+
+ /**
+ * Returns the number of bytes that have been read from serial
+ * and are waiting to be dealt with by the user.
+ */
+ public int available() {
+ return (bufferLast - bufferIndex);
+ }
+
+ /**
+ * Ignore all the bytes read so far and empty the buffer.
+ */
+ public void clear() {
+ bufferLast = 0;
+ bufferIndex = 0;
+ }
+
+ /**
+ * Returns a number between 0 and 255 for the next byte that's
+ * waiting in the buffer.
+ * Returns -1 if there was no byte (although the user should
+ * first check available() to see if things are ready to avoid this)
+ */
+ public int read() {
+ if (bufferIndex == bufferLast) return -1;
+
+ synchronized (getBuffer()) {
+ int outgoing = getBuffer()[bufferIndex++] & 0xff;
+ if (bufferIndex == bufferLast) { // rewind
+ bufferIndex = 0;
+ bufferLast = 0;
+ }
+ return outgoing;
+ }
+ }
+
+
+ /**
+ * Returns the next byte in the buffer as a char.
+ * Returns -1, or 0xffff, if nothing is there.
+ */
+ public char readChar() {
+ if (bufferIndex == bufferLast) return (char)(-1);
+ return (char) read();
+ }
+
+
+ /**
+ * Return a byte array of anything that's in the serial buffer.
+ * Not particularly memory/speed efficient, because it creates
+ * a byte array on each read, but it's easier to use than
+ * readBytes(byte b[]) (see below).
+ */
+ public byte[] readBytes() {
+ if (bufferIndex == bufferLast) return null;
+
+ synchronized (getBuffer()) {
+ int length = bufferLast - bufferIndex;
+ byte outgoing[] = new byte[length];
+ System.arraycopy(getBuffer(), bufferIndex, outgoing, 0, length);
+
+ bufferIndex = 0; // rewind
+ bufferLast = 0;
+ return outgoing;
+ }
+ }
+
+ /**
+ * Grab whatever is in the serial buffer, and stuff it into a
+ * byte buffer passed in by the user. This is more memory/time
+ * efficient than readBytes() returning a byte[] array.
+ *
+ * Returns an int for how many bytes were read. If more bytes
+ * are available than can fit into the byte array, only those
+ * that will fit are read.
+ */
+ public int readBytes(byte outgoing[]) {
+ if (bufferIndex == bufferLast) return 0;
+
+ synchronized (getBuffer()) {
+ int length = bufferLast - bufferIndex;
+ if (length > outgoing.length) length = outgoing.length;
+ System.arraycopy(getBuffer(), bufferIndex, outgoing, 0, length);
+
+ bufferIndex += length;
+ if (bufferIndex == bufferLast) {
+ bufferIndex = 0; // rewind
+ bufferLast = 0;
+ }
+ return length;
+ }
+ }
+
+
+ /**
+ * Reads from the serial port into a buffer of bytes up to and
+ * including a particular character. If the character isn't in
+ * the serial buffer, then 'null' is returned.
+ */
+ public byte[] readBytesUntil(int interesting) {
+ if (bufferIndex == bufferLast) return null;
+ byte what = (byte)interesting;
+
+ synchronized (getBuffer()) {
+ int found = -1;
+ for (int k = bufferIndex; k < bufferLast; k++) {
+ if (getBuffer()[k] == what) {
+ found = k;
+ break;
+ }
+ }
+ if (found == -1) return null;
+
+ int length = found - bufferIndex + 1;
+ byte outgoing[] = new byte[length];
+ System.arraycopy(getBuffer(), bufferIndex, outgoing, 0, length);
+
+ bufferIndex = 0; // rewind
+ bufferLast = 0;
+ return outgoing;
+ }
+ }
+
+
+ /**
+ * Reads from the serial port into a buffer of bytes until a
+ * particular character. If the character isn't in the serial
+ * buffer, then 'null' is returned.
+ *
+ * If outgoing[] is not big enough, then -1 is returned,
+ * and an error message is printed on the console.
+ * If nothing is in the buffer, zero is returned.
+ * If 'interesting' byte is not in the buffer, then 0 is returned.
+ */
+ public int readBytesUntil(int interesting, byte outgoing[]) {
+ if (bufferIndex == bufferLast) return 0;
+ byte what = (byte)interesting;
+
+ synchronized (getBuffer()) {
+ int found = -1;
+ for (int k = bufferIndex; k < bufferLast; k++) {
+ if (getBuffer()[k] == what) {
+ found = k;
+ break;
+ }
+ }
+ if (found == -1) return 0;
+
+ int length = found - bufferIndex + 1;
+ if (length > outgoing.length) {
+ System.err.println("readBytesUntil() byte buffer is" +
+ " too small for the " + length +
+ " bytes up to and including char " + interesting);
+ return -1;
+ }
+ //byte outgoing[] = new byte[length];
+ System.arraycopy(getBuffer(), bufferIndex, outgoing, 0, length);
+
+ bufferIndex += length;
+ if (bufferIndex == bufferLast) {
+ bufferIndex = 0; // rewind
+ bufferLast = 0;
+ }
+ return length;
+ }
+ }
+
+
+ /**
+ * Return whatever has been read from the serial port so far
+ * as a String. It assumes that the incoming characters are ASCII.
+ *
+ * If you want to move Unicode data, you can first convert the
+ * String to a byte stream in the representation of your choice
+ * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
+ */
+ public String readString() {
+ if (bufferIndex == bufferLast) return null;
+ return new String(readBytes());
+ }
+
+
+ /**
+ * Combination of readBytesUntil and readString. See caveats in
+ * each function. Returns null if it still hasn't found what
+ * you're looking for.
+ *
+ * If you want to move Unicode data, you can first convert the
+ * String to a byte stream in the representation of your choice
+ * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
+ */
+ public String readStringUntil(int interesting) {
+ byte b[] = readBytesUntil(interesting);
+ if (b == null) return null;
+ return new String(b);
+ }
+
+ /**
+ * @param buffer the buffer to set
+ */
+ public void setBuffer(byte buffer[]) {
+ this.buffer = buffer;
+ }
+
+ /**
+ * @return the buffer
+ */
+ public byte[] getBuffer() {
+ return buffer;
+ }
+
+
+}
+
+
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTest.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTest.java
new file mode 100644
index 0000000..482f064
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTest.java
@@ -0,0 +1,102 @@
+/*
+ * RoombaCommtest -- small GUI to test out RoombaComm
+ *
+ * Copyright (c) 2006 Tod E. Kurt, tod@todbot.com, ThingM
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+
+package com.hackingroomba.roombacomm;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+
+/**
+ * A simple wrapper for RoombaCommPanel.
+ *
+ */
+public class RoombaCommTest extends JFrame implements WindowListener {
+
+ RoombaCommPanel rcPanel;
+ boolean hwhandshake = false;
+ boolean debug = false;
+
+ public static void main(String[] args) {
+ new RoombaCommTest(args);
+ }
+
+ public RoombaCommTest(String[] args) {
+ super("RoombaCommTest");
+ addWindowListener(this);
+
+ for( int i=0; i < args.length; i++ ) {
+ if( args[i].endsWith("hwhandshake") )
+ hwhandshake = true;
+ else if (args[i].endsWith("debug"))
+ debug = true;
+ }
+
+ rcPanel = new RoombaCommPanel(debug);
+
+ rcPanel.setShowHardwareHandhake( hwhandshake );
+
+ Container content = getContentPane();
+ //content.setBackground(Color.lightGray);
+ content.add( rcPanel ); // , BorderLayout.CENTER );
+
+ setResizable(false);
+ pack();
+ setVisible(true);
+ }
+
+
+ /** implement windowlistener */
+ public void windowClosing(WindowEvent event) {
+ rcPanel.disconnect();
+ System.exit(0);
+ }
+ /** implement windowlistener */
+ public void windowClosed(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowOpened(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowActivated(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowDeactivated(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowIconified(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowDeiconified(WindowEvent event) {
+ // do nothing
+ }
+
+}
+
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTestOld.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTestOld.java
new file mode 100644
index 0000000..00cc78b
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommTestOld.java
@@ -0,0 +1,387 @@
+//
+// RoombaCommtest -- small GUI to test out RoombaComm
+//
+// Tod E. Kurt, tod@todbot.com
+//
+//
+
+package com.hackingroomba.roombacomm;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+
+public class RoombaCommTestOld extends JFrame implements ActionListener,ChangeListener,WindowListener {
+ static final String VERSION = "DO NOT USE";
+
+ JPanel ctrlPanel, selectPanel, buttonPanel, displayPanel;
+ JComboBox portChoices;
+ JTextArea displayText;
+ JButton connectButton;
+ JSlider speedSlider;
+
+ RoombaComm roombacomm;
+
+ public static void main(String[] args) {
+ new RoombaCommTestOld();
+ }
+
+ public RoombaCommTestOld() {
+ super("RoombaCommTestOld");
+ setResizable(false);
+ //setNativeLookAndFeel();
+ addWindowListener(this);
+
+ roombacomm = new RoombaCommSerial();
+
+ Container content = getContentPane();
+ content.setBackground(Color.lightGray);
+
+ makeSelectPanel();
+ content.add( selectPanel, BorderLayout.NORTH );
+
+ makeCtrlPanel();
+ content.add( ctrlPanel, BorderLayout.EAST );
+
+ makeButtonPanel();
+ content.add( buttonPanel, BorderLayout.CENTER );
+
+ makeDisplayPanel();
+ content.add( displayPanel, BorderLayout.SOUTH );
+
+ pack();
+ setVisible(true);
+ displayText.append("RoombaCommTestOld, version "+VERSION+"\n");
+ }
+
+ /** implement actionlistener */
+ public void actionPerformed(ActionEvent event) {
+ String action = event.getActionCommand();
+ if( "comboBoxChanged".equals(action) ) {
+ return;
+ }
+ displayText.append(action+"\n");
+ if( "connect".equals(action) ) {
+ roombacomm.debug=true;
+ if( roombacomm.connected() ) {
+ roombacomm.disconnect(); // just in case
+ connectButton.setText(" connect ");
+ return;
+ }
+ else {
+ displayText.append("could not connect...darn\n");
+ }
+ connectButton.setText("connecting");
+ String portname = (String) portChoices.getSelectedItem();
+ if( ! roombacomm.connect( portname ) ) {
+ displayText.append("Couldn't connect to "+portname+"\n");
+ return;
+ }
+ displayText.append("Roomba startup\n");
+ roombacomm.startup();
+ roombacomm.control();
+ roombacomm.playNote( 72, 10 ); // C
+ roombacomm.pause( 200 );
+ connectButton.setText("disconnect");
+ displayText.append("Roomba connected\n");
+ return;
+ }
+
+ // stop right here if we're not connected
+ if( !roombacomm.connected() ) {
+ displayText.append("not connected!\n");
+ return;
+ }
+
+ if( "stop".equals(action) ) {
+ roombacomm.stop();
+ }
+ else if( "forward".equals(action) ) {
+ roombacomm.goForward();
+ }
+ else if( "backward".equals(action) ) {
+ roombacomm.goBackward();
+ }
+ else if( "spinleft".equals(action) ) {
+ roombacomm.spinLeft();
+ }
+ else if( "spinright".equals(action) ) {
+ roombacomm.spinRight();
+ }
+ else if( "test".equals(action) ) {
+ displayText.append("Playing some notes\n");
+ roombacomm.playNote( 72, 10 ); // C
+ roombacomm.pause( 200 );
+ roombacomm.playNote( 79, 10 ); // G
+ roombacomm.pause( 200 );
+ roombacomm.playNote( 76, 10 ); // E
+ roombacomm.pause( 200 );
+
+ displayText.append("Spinning left, then right\n");
+ roombacomm.spinLeft();
+ roombacomm.pause(1000);
+ roombacomm.spinRight();
+ roombacomm.pause(1000);
+ roombacomm.stop();
+
+ displayText.append("Going forward, then backward\n");
+ roombacomm.goForward();
+ roombacomm.pause(1000);
+ roombacomm.goBackward();
+ roombacomm.pause(1000);
+ roombacomm.stop();
+ }
+ else if( "reset".equals(action) ) {
+ roombacomm.stop();
+ roombacomm.startup();
+ roombacomm.control();
+ }
+ else if( "power-off".equals(action) ) {
+ roombacomm.powerOff();
+ }
+ else if( "wakeup".equals(action) ) {
+ roombacomm.wakeup();
+ }
+ else if( "beep-lo".equals(action) ) {
+ roombacomm.playNote( 36, 10 ); // C0
+ roombacomm.pause( 200 );
+ }
+ else if( "beep-hi".equals(action) ) {
+ roombacomm.playNote( 120, 10 ); // C7
+ roombacomm.pause( 200 );
+ }
+ else if( "clean".equals(action) ) {
+ roombacomm.clean();
+ }
+ else if( "spot".equals(action) ) {
+ roombacomm.spot();
+ }
+ else if( "vacuum-on".equals(action) ) {
+ roombacomm.vacuum(true);
+ }
+ else if( "vacuum-off".equals(action) ) {
+ roombacomm.vacuum(false);
+ }
+ else if( "sensors".equals(action) ) {
+ if( roombacomm.updateSensors() )
+ displayText.append( roombacomm.sensorsAsString()+"\n");
+ else
+ displayText.append("couldn't read Roomba. Is it connected?\n");
+ }
+ }
+
+ /** implement ChangeListener, for the slider */
+ public void stateChanged(ChangeEvent e) {
+ //System.err.println("stateChanged:"+e);
+ JSlider src = (JSlider)e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ int speed = (int)src.getValue();
+ speed = (speed<1) ? 1 : speed; // don't allow zero speed
+ displayText.append("setting speed = "+speed+"\n");
+ roombacomm.setSpeed(speed);
+ }
+ }
+
+ /**
+ *
+ */
+ void makeCtrlPanel() {
+ JPanel ctrlPanel1 = new JPanel(new GridLayout(3,3));
+
+ ctrlPanel1.add(new JLabel());
+ JButton but_forward =
+ new JButton(createImageIcon("images/forward.png", "forward"));
+ ctrlPanel1.add( but_forward, BorderLayout.NORTH );
+ ctrlPanel1.add(new JLabel());
+
+ JButton but_spinleft =
+ new JButton(createImageIcon("images/spinleft.png", "spinleft"));
+ ctrlPanel1.add( but_spinleft, BorderLayout.WEST );
+ JButton but_stop =
+ new JButton(createImageIcon("images/stop.png", "stop"));
+ ctrlPanel1.add( but_stop, BorderLayout.CENTER );
+ JButton but_spinright =
+ new JButton( createImageIcon("images/spinright.png", "spinright"));
+ ctrlPanel1.add( but_spinright, BorderLayout.EAST);
+
+ ctrlPanel1.add(new JLabel());
+ JButton but_backward =
+ new JButton(createImageIcon("images/backward.png", "backward"));
+ ctrlPanel1.add( but_backward, BorderLayout.SOUTH );
+ ctrlPanel1.add(new JLabel());
+
+ JLabel sliderLabel = new JLabel("speed (mm/s)", JLabel.CENTER);
+ speedSlider = new JSlider(JSlider.HORIZONTAL, 0, 500, 200 );
+ speedSlider.setPaintTicks(true);
+ speedSlider.setMajorTickSpacing(100);
+ speedSlider.setMinorTickSpacing(25);
+ speedSlider.setPaintLabels(true);
+ speedSlider.addChangeListener(this);
+
+ ctrlPanel = new JPanel();
+ ctrlPanel.setLayout( new BoxLayout(ctrlPanel, BoxLayout.Y_AXIS ) );
+
+ ctrlPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Movement"), BorderFactory.createEmptyBorder(5,5,5,5)));
+ ctrlPanel.add( ctrlPanel1 );
+ ctrlPanel.add( speedSlider );
+ ctrlPanel.add( sliderLabel );
+
+ but_spinleft.setActionCommand("spinleft");
+ but_spinright.setActionCommand("spinright");
+ but_forward.setActionCommand("forward");
+ but_backward.setActionCommand("backward");
+ but_stop.setActionCommand("stop");
+ but_spinleft.addActionListener(this);
+ but_spinright.addActionListener(this);
+ but_forward.addActionListener(this);
+ but_backward.addActionListener(this);
+ but_stop.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeSelectPanel() {
+ selectPanel = new JPanel();
+ //Create a combo box with choices.
+ String[] ports = roombacomm.listPorts();
+ portChoices = new JComboBox(ports);
+ portChoices.setSelectedIndex(0);
+ connectButton = new JButton();
+ connectButton.setText(" connect ");
+ connectButton.setActionCommand("connect");
+
+ //Add a border around the select panel.
+ selectPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Select Roomba Port"), BorderFactory.createEmptyBorder(5,5,5,5)));
+
+ selectPanel.add(portChoices);
+ selectPanel.add(connectButton);
+
+ //Listen to events from the combo box.
+ portChoices.addActionListener(this);
+ connectButton.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeButtonPanel() {
+ //buttonPanel = new JPanel();
+ //buttonPanel.setLayout( new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
+ buttonPanel = new JPanel( new GridLayout( 8,2 ) );
+ buttonPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Commands"), BorderFactory.createEmptyBorder(5,5,5,5)));
+
+ JButton but_reset = new JButton("reset");
+ buttonPanel.add( but_reset );
+ but_reset.addActionListener(this);
+
+ JButton but_test = new JButton("test");
+ buttonPanel.add( but_test );
+ but_test.addActionListener(this);
+
+ JButton but_power = new JButton("power-off");
+ buttonPanel.add( but_power );
+ but_power.addActionListener(this);
+
+ JButton but_wakeup = new JButton("wakeup");
+ buttonPanel.add( but_wakeup );
+ but_wakeup.addActionListener(this);
+
+ JButton but_beeplo = new JButton("beep-lo");
+ buttonPanel.add( but_beeplo );
+ but_beeplo.addActionListener(this);
+
+ JButton but_beephi = new JButton("beep-hi");
+ buttonPanel.add( but_beephi );
+ but_beephi.addActionListener(this);
+
+ JButton but_clean = new JButton("clean");
+ buttonPanel.add( but_clean );
+ but_clean.addActionListener(this);
+
+ JButton but_spot = new JButton("spot");
+ buttonPanel.add( but_spot );
+ but_spot.addActionListener(this);
+
+ JButton but_vacon = new JButton("vacuum-on");
+ buttonPanel.add( but_vacon );
+ but_vacon.addActionListener(this);
+
+ JButton but_vacoff = new JButton("vacuum-off");
+ buttonPanel.add( but_vacoff );
+ but_vacoff.addActionListener(this);
+
+ JButton but_sensors = new JButton("sensors");
+ buttonPanel.add( but_sensors );
+ but_sensors.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeDisplayPanel() {
+ displayPanel = new JPanel();
+ displayPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Display"), BorderFactory.createEmptyBorder(1,1,1,1)));
+
+ displayText = new JTextArea(5,30);
+ displayText.setLineWrap(true);
+ DefaultCaret dc = new DefaultCaret();
+ // only works on Java 1.5+
+ // dc.setUpdatePolicy( DefaultCaret.ALWAYS_UPDATE );
+ displayText.setCaret(dc);
+ JScrollPane scrollPane =
+ new JScrollPane(displayText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
+ displayPanel.add( scrollPane );
+
+ }
+
+ /** implement windowlistener */
+ public void windowClosing(WindowEvent event) {
+ if( roombacomm.connected() )
+ roombacomm.disconnect();
+ System.exit(0);
+ }
+ /** implement windowlistener */
+ public void windowClosed(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowOpened(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowActivated(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowDeactivated(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowIconified(WindowEvent event) {
+ // do nothing
+ }
+ /** implement windowlistener */
+ public void windowDeiconified(WindowEvent event) {
+ // do nothing
+ }
+
+
+ /** Returns an ImageIcon, or null if the path was invalid. */
+ protected static ImageIcon createImageIcon(String path,
+ String description) {
+ java.net.URL imgURL = RoombaCommTestOld.class.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL, description);
+ } else {
+ System.err.println("Couldn't find file: " + path);
+ return null;
+ }
+ }
+
+
+}
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaRecorder.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaRecorder.java
new file mode 100644
index 0000000..81cd305
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaRecorder.java
@@ -0,0 +1,591 @@
+/*
+ * RoombaRecorder --
+ *
+ * Copyright (c) 2006 Tod E. Kurt, tod@todbot.com, ThingM
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+
+package com.hackingroomba.roombacomm;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.filechooser.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ * A simple wrapper for multiple MacroRecorderPanels
+ *
+ */
+public class RoombaRecorder extends JFrame implements WindowListener,ActionListener {
+
+ static final String helpMsg = ""+
+ //"
+ Run it with something like:
+ Run it with something like:
+ * Run it with something like:
+ Run it with something like: Overview
+ * This class contains the operations available from an ArduinoBot
+**/
+
+public class ArduinoBot extends RoombaComm {
+
+ // connection variables
+ private Integer compassHeading;
+ private String arduinoString;
+ private RobotConnection robotConnection;
+ private RobotType robotType;
+
+ // compass variables
+ private int compassOffset = 0;
+ private boolean compassOffsetInitialized = false;
+
+ // encoder variables
+ private int encoder;
+
+ private long startTime;
+ public long elapsedTime;
+
+ public ArduinoBot() {
+ super();
+ }
+
+ public ArduinoBot(RobotConnection robotConnection) {
+ super(robotConnection);
+ this.robotConnection = robotConnection;
+ }
+
+ /**
+ * Initialize an Arduino robot controller
+ */
+ public boolean initArduinoBot(RobotType rt)
+ {
+ byte[] robotTypeMsg = "robot m\r".getBytes(); // message to Arduino to tell it the robot type
+
+ robotType = rt; // record robotType for later use
+ System.out.println("checking for ArduinoBot... \n");
+ try {
+ Thread.sleep(2000);
+ } catch (Exception e) {System.out.println("Exception in Thread.sleep()"); }
+
+ // send the robot type message to Arduino, so it knows how to read the encoders, and any other robot-specific things
+ if (robotType.robotType == RobotType.robotTypes.frankenRoomba) {
+ System.out.println("Sending robot r to Arduino");
+ robotTypeMsg = "robot r\r".getBytes();
+ } else if (robotType.robotType == robotTypes.tankbot) {
+ System.out.println("Sending robot t to Arduino");
+ robotTypeMsg = "robot t\r".getBytes();
+ }
+ send(robotTypeMsg);
+
+ printCompass();
+ printEncoders();
+ return true;
+ }
+
+
+ /**
+ * Send a single byte to the ArduinoBot
+ * (defined as int because of stupid java signed bytes). SendToArduino method of RobotConnection
+ * is used because this is an ardunobot, which requires a leading m and trailing Overview
+ * This class contains the communications layer-independent parts of
+ * how to communicate with an Arduino. It does assume a very serial port-like
+ * interaction.
+**/
+
+public class ArduinoClient {
+ private static final long serialVersionUID = 1L;
+ private static final int lumBufHeight = 32;
+
+ String usage =
+ "Usage: \n"+
+ " ArduinoClient {--arduinoServer|-s}
+ java roombacomm.AudioLocalizerClient --localizerServer 192.168.0.150 --localizerPortNum 5005 --debug
+*/
+ public class AudioLocalizerClient {
+ private static final long serialVersionUID = 1L;
+ private static final int lumBufHeight = 32;
+
+ String usage =
+ "Usage: \n"+
+ " AudioLocalizerClient --localizerServer
+ Usage:
+ roombacomm.AudioLocalizerClient --localizerServer
+ where
+ [options] can be one or more of:
+ -debug -- turn on debug output
+
+ java roombacomm.BumpTurn /dev/cu.KeySerial1
+
+*/
+public class BumpTurn {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.Drive
+ Usage:
+ roombacomm.Drive serialportname [protocol] [options]
+ where:
+ protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+
+ * java roombacomm.Drive /dev/cu.KeySerial1 byte1 byte2 byte3 byte4
+ *
+ */
+public class Drive {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.Drive
+ * Usage:
+ * roombacomm.Drive serialportname [protocol] velocity radius waittime [options]
+ * where protocol (optional) is SCI or OI
+ * velocity is in mm/sec
+ * radius is mm from the centerpoint
+ * waittime is in milliseconds
+ * [options] can be one or more of:
+ * -debug -- turn on debug output
+ * -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ * -nohwhandshake -- don't use hardware-handshaking
+ *
+ java roombacomm.DriveRealTime /dev/cu.KeySerial1
+*/
+public class DriveRealTime extends JFrame implements KeyListener {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.DriveRealTime
+ Usage:
+ roombacomm.DriveRealTime serialportname [protocol] [options]
+ where:
+ protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+
+ * java roombacomm.ListSerialPorts
+ *
+ *
+ */
+public class ListSerialPorts {
+
+ public static void main(String[] args) {
+
+ RoombaComm roombacomm = new RoombaCommSerial();
+ String portlist[];
+ //roombacomm.debug = true;
+
+ portlist = roombacomm.listPorts();
+ System.err.println("Available ports:");
+ for(int i=0;i
+ java roombacomm.LogoA /dev/cu.KeySerial1
+
+*/
+public class LogoA {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.LogoA
+ Usage:
+ roombacomm.LogoA serialportname [protocol] [options]
+ where:
+ protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -debug -- turn on debug output
+
+ java roombacomm.RTTTLPlay /dev/cu.KeySerial1 'tron:d=4,o=5,b=200:8f6,8c6,8g,e,8p,8f6,8c6,8g,8f6,8c6,8g,e,8p,8f6,8c6,8g,e.,2d'
+ */
+public class RTTTLPlay {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.RTTTLPlay
+ Usage:
+ roombacomm.RTTTLPlay serialportname [protocol] rttl_string [options]
+ where:
+ protocol (optional) is SCI or OI
+ rttl_string is a string of notes
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+ -flush -- flush on sends(), normally not needed
+
+
+ java roombacomm.Bsquare /dev/cu.KeySerial1 [protocol] command velocity distance
+*/
+ public class Roborama {
+
+ private int maxLineWidth = 30;
+ private int minLineWidth = 5;
+ private int height = 120;
+ private int width = 160;
+ String usage =
+ "Usage: \n"+
+ " roombacomm.Roborama
+ Usage:
+ roombacomm.Bsquare
+ where
+ protocol (optional) is SCI or OI
+ command is one of:
+ f -- forward or back; direction controlled by +/- speed
+ bcw or bccw -- clockwise or counter-clockwise b-square
+ onb -- out and back
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+ velocity and distance are in inches\n";
+ Overview
+ * This class contains the communications layer-independent parts of
+ * how to communicate with a Roomba. It does assume a very serial port-like
+ * interaction.
+ *
+ * Standard lifecyle of this object (and its subclasses)
+ * RoombaComm roomba = new RoombaCommSubClass(); // (e.g. RoombaCommSerial)
+ * roomba.listports(); // if implemented
+ * roomba.connect("someportid");
+ * roomba.startup();
+ * roomba.updateSensors();
+ * while( ... ) {
+ * roomba.sensors();
+ * roomba.playNote( 53, 12 );
+ * roomba.goForward( 400 );
+ * roomba.spinRight( 45 );
+ * if( roomba.bump() ) roomba.goBackward( 100 );
+ * }
+ * roomba.disconnect();
+ *
+ *
+ * API levels
+ * Describe different API levels
+ *
+ * Sensor Functions
+ * Describe sensor functions
+ *
+ * Sublass behavior
+ * Describe subclassing strategries
+ *
+ *
+ * @author Tod E. Kurt
+ * SVN id value is $Id: RoombaComm.java 182 2010-11-02 03:49:10Z bouchier $
+ */
+public abstract class RoombaComm
+{
+ /** version of the library */
+ static public final String VERSION = "0.96.3";
+
+ /**
+ * contains a list of all the ports
+ * keys are port names (e.g. "/dev/usbserial1")
+ * values are Boolean in-use indicator
+ */
+ protected static Map ports = null;
+
+ /** turns on/off various debugging messages */
+ public boolean debug = false;
+
+ public boolean isDebug() {
+ return debug;
+ }
+
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /** distance between wheels on the roomba, in millimeters */
+ public static final int wheelbase = 258;
+ /** mm/deg is circumference distance divided by 360 degrees */
+ public static final float
+ millimetersPerDegree = (float)(wheelbase * Math.PI / 360.0);
+ /** mm/rad is a circumference distance divied by two pi */
+ public static final float
+ millimetersPerRadian = (float)(wheelbase/2);
+
+ /** default speed for movement operations if speed isn't specified */
+ public static final int defaultSpeed = 200;
+
+ /** default update time in ms for auto sensors update */
+ public static final int defaultSensorsUpdateTime = 200;
+
+ /** current mode, if known */
+ int mode;
+
+ /** current speed for movement operations that don't take a speed */
+ public int speed = defaultSpeed;
+
+ /** computed boolean for when Roomba is errored out of safe mode */
+ boolean safetyFault = false;
+ /** if sensor variables have been updated successfully */
+ protected boolean sensorsValid = false;
+ /** Set to true to make sensors auto-update (at expense of serial b/w) */
+ boolean sensorsAutoUpdate = false;
+ /** Time in milliseconds between sensor updates */
+ int sensorsUpdateTime = 200;
+ /** last time (System.currentTimeMillis) that the sensors were updated */
+ protected long sensorsLastUpdateTime;
+ /** how many bytes we expect to read from the sensor command */
+ protected int readRequestLength;
+
+ /** internal storage for all roomba sensor data */
+ protected byte[] sensor_bytes = new byte[1024];
+
+ /** connected to a serial port or not, not necessarily to roomba */
+ boolean connected = false;
+
+ public boolean isConnected() {
+ String str = this.getSensorsAsString();
+ if (str != null && str.length() >=1){
+ if (debug){
+ logmsg("isConnected found sensorString as ("+str+")");
+ }
+ this.setConnected(true);
+ return true;
+ }else{
+ if (debug){
+ if (str != null){
+ logmsg("isConnected found sensorString ("+str+")");
+ }else{
+ logmsg("isConnected found sensorString (null)");
+ }
+ }
+ }
+ return connected;
+ }
+
+ public void setConnected(boolean connected) {
+ this.connected = connected;
+ }
+
+ /** set of flgs for the current state of the LEDs */
+ /** note this is a superset of all protocol's supported */
+ private boolean redOn = false;
+ private boolean greenOn = false;
+ private boolean toggleSpot = false;
+ private boolean toggleClean = false;
+ private boolean toggleMax = false;
+ private boolean toggleDirt = false;
+ private boolean toggleDock = false;
+ private boolean toggleCheckRobot = false;
+ private int power_color = 0;
+ private int power_int = 0;
+
+ /** default RoombaComm protocol to identify classes of API calls to be made */
+ private String protocol = "SCI";
+ /** default baud rate for the default protocol */
+ protected int rate = 57600;
+
+ protected String portname = null;
+ /** connection object to use when appropriate */
+ RobotConnection robotConnection;
+
+
+ /**
+ * Some "virtual" serial ports like Bluetooth serial on Windows
+ * return weird errors deep inside RXTX if an opened port is used
+ * before the virtual COM port is ready. One way to check that it
+ * is ready is to look for the DSR line going high.
+ * However, most simple, real serial ports do not do hardware handshaking
+ * so never set DSR high.
+ * Thus, if using Bluetooth serial on Windows, do:
+ * roombacomm.waitForDSR = true;
+ * before using it and see if it works.
+ */
+ public boolean waitForDSR = false;
+
+ /** The RXTX port object, normally you don't need access to this */
+ public SerialPort serialPort = null;
+
+ public RoombaComm() {
+ connected = false;
+ mode = MODE_UNKNOWN;
+ }
+
+ public RoombaComm(boolean autoUpdate) {
+ this();
+ if( autoUpdate )
+ startAutoUpdate();
+ }
+
+ public RoombaComm(boolean autoUpdate, int updateTime) {
+ this(autoUpdate);
+ sensorsUpdateTime = updateTime;
+ }
+
+ public RoombaComm(RobotConnection rc) {
+ robotConnection = rc;
+ }
+ public void startAutoUpdate() {
+ new Thread( new Runnable() {
+ public void run() {
+ try {
+ while( sensorsUpdateTime > 0 ) {
+ if( connected() ) sensors();
+ Thread.sleep( sensorsUpdateTime );
+ }
+ } catch(InterruptedException ex) {}
+ }
+ }).start();
+ }
+
+ /**
+ * List available ports
+ * @return a list available portids, if applicable
+ * or empty set if no ports,
+ * or return null if list is not enumerable
+ */
+ public abstract String[] listPorts();
+
+ /**
+ * Connect to a port
+ * (for serial, portid is serial port name, for net, portid is url?)
+ * @return true on successful connect, false otherwise
+ */
+ public abstract boolean connect(String portid);
+ /**
+ * Disconnect from a port, clean up any memory in use
+ */
+ public abstract void disconnect();
+
+
+ /**
+ * Send given byte array to Roomba.
+ * @param bytes byte array of ROI commands to send
+ * @return true on successful send
+ */
+ public abstract boolean send(byte[] bytes);
+
+ /**
+ * Send a single byte to the Roomba
+ * (defined as int because of stupid java signed bytes)
+ * @param b byte of an ROI command to send
+ * @return true on successful send
+ */
+ public abstract boolean send(int b);
+
+ /**
+ * Query Roomba for sensor status and sync its state with this object's
+ * Subclasses should query Roomba and fill up 'sensor_bytes' with the full
+ * sensor data set
+ * If a RooombaComm object is constructed with 'autoUpdate' true,
+ * calling this method is not required because a separate thread is created
+ * to do sensor updating.
+ *
+ * @return true on successful sensor update, false otherwise
+ */
+ //public abstract boolean updateSensors();
+
+ /**
+ * Wake's Roomba up, if possible, thus optional
+ * To wake up the Roomba requires twiddling its DD line, often
+ * hooked up to the RS-232 DTR line, which may not be available in some
+ * implementations
+ */
+ public void wakeup() {
+ logmsg("subclass has not implemented");
+// byte cmd[] = { (byte)POWER, (byte)v, (byte)power_color, (byte)power_intensity };
+// send(cmd);
+// MSComm1.Output = "+++" & Chr(13)
+// MSComm1.Output = "ATSW22,6,1,1" & Chr(13)
+// MSComm1.Output = "ATSW23,6,0,1" & Chr(13)
+// MSComm1.Output = "ATSW23,6,1,1" & Chr(13)
+// MSComm1.Output = "ATMD" & Chr(13)
+ String str="+++\nATSW22,6,1,1\n,ATSW23,6,0,1\nATSW23,6,1,1\nATMD\n";
+ send(str.getBytes());
+// byte bytes[] = str.getBytes();
+// for (int i = 0; i < bytes.length; i++) {
+//
+// }
+ }
+
+ /**
+ * Put Roomba in safe mode.
+ * As opposed to full mode. Safe mode is the preferred working state
+ * when playing with the Roomba as it provides some measure of
+ * autonomous self-preservation if it encounters a cliff or is picked up
+ * If that happens it goes into passive mode and must be 'reset()'.
+ * @see #reset()
+ */
+ public void startup() {
+ logmsg("startup");
+ speed = defaultSpeed;
+ start();
+ }
+
+ /**
+ * Reset Roomba after a fault. This takes it out of whatever mode it was
+ * in and puts it into safe mode.
+ * This command also syncs the object's sensor state with the Roomba's
+ * by calling updateSensors()
+ * @see #startup()
+ * @see #updateSensors()
+ */
+ public void reset() {
+ logmsg("reset");
+ stop();
+ startup();
+ control();
+ updateSensors();
+ }
+
+ /** Send START command */
+ public void start() {
+ logmsg("start");
+ mode = MODE_PASSIVE;
+ send( START );
+ }
+ /** Send CONTROL command */
+ public void control() {
+ logmsg("control");
+ mode = MODE_SAFE;
+ send( CONTROL );
+ // set blue dirt LED on so we know roomba is powered on & under control
+ // (and we don't forget to turn it off, and run it's batteries flat)
+ // FIXME: first time after a poweron, the lights flash then turn off
+ setLEDs(false, false, false, false, false, true, 128, 255);
+ }
+ /** Send SAFE command */
+ public void safe() {
+ logmsg("safe");
+ mode = MODE_SAFE;
+ send( SAFE );
+ }
+ /** Send FULL command */
+ public void full() {
+ logmsg("full");
+ mode = MODE_FULL;
+ send( FULL );
+ }
+
+ /**
+ * Power off the Roomba. Once powered off, the only way to wake it
+ * is via wakeup() (if implemented) or via a physically pressing
+ * the Power button
+ * @see #wakeup()
+ */
+ public void powerOff() {
+ logmsg("powerOff");
+ mode = MODE_UNKNOWN;
+ send( POWER );
+ }
+
+ /** Send the SPOT command */
+ public void spot() {
+ logmsg("spot");
+ mode = MODE_PASSIVE;
+ send( SPOT );
+ }
+ /** Send the CLEAN command */
+ public void clean() {
+ logmsg("clean");
+ mode = MODE_PASSIVE;
+ send( CLEAN );
+ }
+ /** Send the max command */
+ public void max() {
+ logmsg("max");
+ mode = MODE_PASSIVE;
+ send( MAX );
+ }
+ /** Send the max command */
+ public void dock() {
+ logmsg("dock");
+ mode = MODE_PASSIVE;
+// send( CLEAN );
+ send( DOCK );
+ }
+ /**
+ * Send the SENSORS command
+ * with one of the SENSORS_ arguments
+ * Typically, one does "sensors(SENSORS_ALL)" to get all sensor data
+ * @param packetcode one of SENSORS_ALL, SENSORS_PHYSICAL,
+ * SENSORS_INTERNAL, or SENSORS_POWER, or for roomba 5xx, it
+ * is the sensor packet number (from the spec)
+ */
+ public void sensors(int packetcode ) {
+ sensorsValid = false;
+ logmsg("sensors:"+packetcode);
+ switch (packetcode) {
+ case 0: readRequestLength = 26; break;
+ case 1: readRequestLength = 10; break;
+ case 2: readRequestLength = 6; break;
+ case 3: readRequestLength = 10; break;
+ case 4: readRequestLength = 14; break;
+ case 5: readRequestLength = 12; break;
+ case 6: readRequestLength = 52; break;
+ case 100: readRequestLength = 80; break;
+ case 101: readRequestLength = 28; break;
+ case 106: readRequestLength = 12; break;
+ case 107: readRequestLength = 9; break;
+ case 19:
+ case 20:
+ case 22:
+ case 23:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 39:
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 46:
+ case 47:
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+ case 54:
+ case 55:
+ case 56:
+ case 57: readRequestLength = 2; break;
+ default: readRequestLength = 1; break;
+ }
+
+ byte cmd[] = { (byte)SENSORS, (byte)packetcode};
+ send(cmd);
+ }
+
+ /**
+ * get all sensor data
+ */
+ public void sensors() {
+ readRequestLength = 26;
+ sensors( SENSORS_ALL );
+ }
+ /**
+ * Read roomba 26-byte sensor record using robotConnection. Tries once to read valid data, allowing 100ms
+ * timeout on each attempt.
+ * @return true if read 26 bytes of valid data. Data has been stored in sensor_bytes. False otherwise
+ */
+ public boolean updateSensors()
+ {
+ return updateSensors(SENSORS_ALL);
+ }
+
+ public boolean updateSensors(int sensorGroup)
+ {
+ int sensorGroupSize;
+
+ if (robotConnection == null) {
+ System.out.println("Error at ArduinoBot.updateSensors(): no connection object for robot");
+ return false;
+ }
+
+ switch(sensorGroup) {
+ case SENSORS_ALL: sensorGroupSize = 26; break;
+ case 100: sensorGroupSize = 80; break;
+ default:
+ System.err.println("Invalid sensor group in updateSensors(): " + sensorGroup);
+ return false;
+ }
+ sensors(sensorGroup);
+ return getSensorData(sensorGroupSize);
+ }
+
+ /**
+ * Query a list of sensors. This is a roomba 5xx only command.
+ * @param sensorList A byte array containing the sensor groups requested to be read
+ * @param returnLen The number of bytes of data expected to be returned from roomba
+ */
+ public void queryList(byte[] sensorList, int returnLen)
+ {
+ int i = 0;
+ int j;
+
+ sensorsValid = false;
+ readRequestLength = returnLen;
+ byte cmd[] = new byte[2+sensorList.length];
+ cmd[i++] = (byte) QUERYLIST;
+ cmd[i++] = (byte)sensorList.length;
+ for (j=0; j
+ * This method uses the value of handshakeButton and portChoices to make the serial connection.
+ * This method also "chirps" the Roomba when it connects to provide an audio feedback/confirmation of the connection.
+ *
+ * @return true, if successful
+ */
+ public boolean connect() {
+ debugPrintln(debug,"connect-start");
+ String portname = (String) portChoices.getSelectedItem();
+ roombaCommSerial.setWaitForDSR(handshakeButton.isSelected());
+ int i = protocolChoices.getSelectedIndex();
+ roombaCommSerial.setProtocol((i == 0) ? "SCI" : "OI");
+ if (portname == null){
+ // we do not yet have ports so refresh the list
+ setCommPorts();
+ }
+ updateDisplay("connecting to " + portname + "\n");
+ connectButton.setText("connecting");
+ if (portname != null){
+ if (!roombaCommSerial.connect(portname)) {
+ updateDisplay("Couldn't connect to " + portname + "\n");
+ connectButton.setText(" connect ");
+ debugPrintln(debug,"connect-end (could not connect)");
+ return false;
+ }else{
+ updateDisplay("connected to " + portname + "\n");
+ }
+ }else{
+ updateDisplay("you must first select a COMM port to use before you can attempt to connect");
+ jTabbedPanelConfig.setSelectedIndex(1);
+ return false;
+ }
+ updateDisplay("Roomba startup\n");
+
+ roombaCommSerial.startup();
+ roombaCommSerial.control();
+ roombaCommSerial.playNote(72, 10); // C , test note
+ roombaCommSerial.pause(200);
+
+ connectButton.setText("disconnect");
+ connectButton.setActionCommand("disconnect");
+ roombaComm = roombaCommSerial;
+ updateDisplay("Checking for Roomba... ");
+ if (roombaCommSerial.updateSensors()) {
+ updateDisplay("Roomba found!\n");
+ debugPrintln(debug,"connect-end");
+ return true;
+ }else{
+ updateDisplay("No Roomba. :( Is it turned on?\n");
+ debugPrintln(debug,"connect-end");
+ return true ;
+ }
+ }
+
+ /**
+ * Connect to a Roomba using a network connection.
+ * This method uses the value of protocol to set the connection to the correct Roomba API version.
+ * This method uses the value of host and port to make the network connection.
+ * This method also "chirps" the Roomba when it connects to provide an audio feedback/confirmation of the connection.
+ *
+ * @param portname the portname
+ * @return true, if successful
+ */
+ public boolean connectNet(String portname) {
+ debugPrintln(debug,"connectNet called");
+ int i = protocolChoices.getSelectedIndex();
+ if (roombaCommTCPClient == null){
+ roombaCommTCPClient = new RoombaCommTCPClient();
+ roombaCommTCPClient.setConnected(false);
+ }
+ roombaCommTCPClient.setProtocol((i == 0) ? "SCI" : "OI");
+ if (!roombaCommTCPClient.connect(portname)) {
+ updateDisplay("Couldn't connect to " + portname);
+ return false;
+ }
+ updateDisplay("Roomba startup on port " + portname);
+ roombaCommTCPClient.startup();
+ roombaCommTCPClient.control();
+ // roombacomm.setSensorsAutoUpdate(true);
+ roombaCommTCPClient.pause(30);
+ //TODO: I am not sure this works yet... need to test to confirm. (2010.03.03)
+ //TODO: The commented block below did not work.. so I commented it and hardcoded a "true" for the connect
+ updateDisplay("Checking for Roomba... \n");
+ roombaCommTCPClient.setConnected(true);
+// if (roombaCommTCPClient.updateSensors()) {
+// updateDisplay("Roomba found!\n");
+// updateDisplay(roombaCommTCPClient.getSensorsAsString());
+// } else {
+// updateDisplay("No Roomba. :( Is it turned on?\n");
+// }
+ updateDisplay("buffer is(" + roombaCommTCPClient.getBuffer() + ")",
+ this.debug);
+ updateDisplay("connected (" + roombaCommTCPClient.connected() + ")\n");
+ if (roombaCommTCPClient.connected()) {
+ updateDisplay("Playing some notes\n");
+ roombaCommTCPClient.playNote(72, 10); // C
+ roombaCommTCPClient.pause(200);
+ roombaCommTCPClient.playNote(79, 10); // G
+ roombaCommTCPClient.pause(200);
+ roombaCommTCPClient.playNote(76, 10); // E
+ roombaCommTCPClient.pause(200);
+ netButton.setText("disconnect-net");
+ netButton.setActionCommand("disconnect-net");
+ roombaComm = roombaCommTCPClient; // set the pointer so that the
+ // action stuff can work against
+ // any class
+ }
+ return true;
+ }
+
+ /**
+ * Disconnect from the roomba when it is connected via a serial connection.
+ */
+ public void disconnect() {
+ roombaCommSerial.disconnect();
+ connectButton.setText(" connect ");
+ connectButton.setActionCommand("connect");
+ }
+
+ /**
+ * Disconnect from the roomba when it is connected via a network connection.
+ */
+ public void disconnectNet() {
+ roombaCommTCPClient.disconnect();
+ netButton.setText(" net ");
+ netButton.setActionCommand("net");
+ }
+
+ /**
+ * Play a (MIDI) note, that is, make the Roomba a musical instrument
+ * notenums 32-127:
notenum == corresponding note played thru beeper
+ * velocity == duration in number of 1/64s of a second (e.g. 64==1 second)
+ * notenum 24: notenum == main vacuum velocity == non-zero turns on, zero
+ * turns off
notenum 25: blink LEDs, velcoity is color of Power
notenum 28 & 29: spin left & spin right, velocity is speed
+ *
+ * @param notenum 32-127
corresponding note played thru beeper
+ * @param velocity duration in number of 1/64s of a second (e.g. 64==1 second)
+ */
+ public void playMidiNote(int notenum, int velocity) {
+ updateDisplay("play note: " + notenum + "," + velocity + "\n");
+ if (!roombaCommSerial.connected())
+ return;
+
+ if (notenum >= 31) { // G and above
+ if (velocity == 0)
+ return;
+ if (velocity < 4)
+ velocity = 4; // has problems at lower durations
+ else
+ velocity = velocity / 2;
+ roombaCommSerial.playNote(notenum, velocity);
+ } else if (notenum == 24) { // C
+ roombaCommSerial.vacuum(!(velocity == 0));
+ } else if (notenum == 25) { // C#
+ boolean lon = (velocity != 0);
+ int inten = (lon) ? 255 : 128; // either full bright or half bright
+ roombaCommSerial.setLEDs(lon, lon, lon, lon, lon, lon,
+ velocity * 2, inten);
+ } else if (notenum == 28) { // E
+ if (velocity != 0)
+ roombaCommSerial.spinLeftAt(velocity * 2);
+ else
+ roombaCommSerial.stop();
+ } else if (notenum == 29) { // F
+ if (velocity != 0)
+ roombaCommSerial.spinRightAt(velocity * 2);
+ else
+ roombaCommSerial.stop();
+ }
+ }
+
+ /**
+ * implement actionlistener.
+ *
+ * @param event the event
+ */
+ public void actionPerformed(ActionEvent event) {
+ String action = event.getActionCommand();
+ updateDisplay(formatter.format(new Date()) + ": action (" + action
+ + ") happened\n", this.debug);
+ if ("comboBoxChanged".equals(action)) {
+ int i = protocolChoices.getSelectedIndex();
+ if (roombaComm != null) {
+ roombaComm.setProtocol((i == 0) ? "SCI" : "OI");
+ } else {
+ updateDisplay(
+ formatter.format(new Date())
+ + ": null roombaComm object found in actionPerformed\n",
+ this.debug);
+ }
+ return;
+ }
+ if ("net".equals(action)) {
+ if (jTextFieldHost != null && jTextFieldHost.getText() != null && jTextFieldPort != null && jTextFieldPort.getText() != null){
+ if(connectNet(jTextFieldHost.getText()+":"+jTextFieldPort.getText())){
+ // TODO: find a way to hide/disable the other connect tab until the session is disconnected
+// getJTabbedPanelConfig().getComponentAt(1).setVisible(false); // hide the Serial tab while we are connected with a Net port
+ }else{
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(0).setVisible(true); // make sure the net tab is not hidden when we fail to connect
+ }
+ }else{
+ updateDisplay("connect (via net) pressed with missing values:");
+ if (jTextFieldHost != null && jTextFieldHost.getText() != null){
+ updateDisplay(" host :"+jTextFieldHost.getText());
+ }else{
+ updateDisplay(" host : MISSING VALUE");
+ }
+ if (jTextFieldPort != null && jTextFieldPort.getText() != null){
+ updateDisplay(" port :"+jTextFieldPort.getText());
+ }else{
+ updateDisplay(" port : MISSING VALUE");
+ }
+ }
+ return;
+ } else if ("disconnect-net".equals(action)) {
+ disconnectNet();
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(1).setVisible(true); // show the serial tab while we disconnect from the net
+ return;
+ }
+ if ("connect".equals(action)) {
+ if (connect()){
+ // TODO: find a way to hide/disable the other connect tab until the session is disconnected
+ }else{
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(0).setEnabled(true); // make sure the net tab is not hidden when we fail to connect
+// getJTabbedPanelConfig().repaint(100);
+ }
+ return;
+ } else if ("disconnect".equals(action)) {
+ disconnect();
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(0).setEnabled(true); // show the net tab while we disconnect from the serial
+ return;
+ }
+ // stop right here if we're not connected
+ if (roombaComm == null || !roombaComm.connected()) {
+ updateDisplay("not connected!\n");
+ return;
+ }
+
+ if ("stop".equals(action)) {
+ roombaComm.stop();
+ } else if ("forward".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.goForward();
+ } else if ("backward".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.goBackward();
+ } else if ("spinleft".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.spinLeft();
+ } else if ("spinright".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.spinRight();
+ } else if ("turnleft".equals(action)) {
+ roombaComm.turnLeft();
+ } else if ("turnright".equals(action)) {
+ roombaComm.turnRight();
+ } else if ("max".equals(action)) {
+ roombaComm.max();
+ } else if ("dock".equals(action)) {
+ roombaComm.dock();
+ } else if ("test".equals(action)) {
+ LogoA.square(roombaComm, 300);
+ } else if ("OSU".equals(action)) {
+ updateDisplay("Going to play OSU\n");
+ roombaComm.stop();
+ roombaComm.pause(500);
+ playSong(
+ roombaComm,
+ "OSU:d=4,o=5,b=125:a,g,a#,a,8g#,a,8g#,2a,8p,8f,8g,8g#,a,8g#,a,8g#,a,g,f,a,g,8a,g,d,8f,8p,8f,8p,8f,8p,8f,8p,c6,a,g,f,8a#,a,8g,f,p,c6,a,g,a,8a#,a,8a#,c6,p,2d6,d,8c6,a#,g,f,8f,8f,8g,a#,8g,a#,a,2a#");
+ // playSong(roombacomm,"Baa Baa Black Sheep:d=4,o=5,b=125:c,c,g,g,8a,8b,8c6,8a,g,p,f,f,e,e,d,d,c");
+ roombaComm.stop();
+ } else if ("Play RTTL".equals(action)){
+ updateDisplay("Going to prompt for rttl string...\n");
+ String rttl ="";
+ updateDisplay("Going to play rttl string ("+rttl+")...\n");
+ } else if ("Tribble On".equals(action)) {
+ tribbleOn = true;
+ tribbleStart(roombaComm, displayText, tribbleOn);
+ } else if ("reset".equals(action)) {
+ roombaComm.stop();
+ roombaComm.startup();
+ roombaComm.control();
+ } else if ("passive".equals(action)) {
+ //passive / start command
+ roombaComm.start();
+ } else if ("safe".equals(action)) {
+ roombaComm.safe();
+ } else if ("full".equals(action)) {
+ roombaComm.full();
+ } else if ("power-off".equals(action)) {
+ roombaComm.powerOff();
+ } else if ("power-on".equals(action)) {
+ roombaComm.powerOn();
+ } else if ("wakeup".equals(action)) {
+ roombaComm.wakeup();
+ } else if ("beep-lo".equals(action)) {
+ roombaComm.playNote(50, 32); // C1
+ roombaComm.pause(200);
+ } else if ("beep-hi".equals(action)) {
+ roombaComm.playNote(90, 32); // C7
+ roombaComm.pause(200);
+ } else if ("clean".equals(action)) {
+ roombaComm.clean();
+ } else if ("spot".equals(action)) {
+ roombaComm.spot();
+ } else if ("vacuum-on".equals(action)) {
+ roombaComm.vacuum(true);
+ } else if ("vacuum-off".equals(action)) {
+ roombaComm.vacuum(false);
+ } else if ("blink-leds".equals(action)) {
+ roombaComm.setLEDs(true, true, true, true, true, true, 255, 255);
+ roombaComm.pause(300);
+ roombaComm.setLEDs(false, false, false, false, false, false, 0, 128);
+ } else if ("sensors".equals(action)) {
+ if (roombaComm.updateSensors())
+ updateDisplay(roombaComm.sensorsAsString() + "\n");
+ else
+ updateDisplay("couldn't read Roomba. Is it connected?\n");
+ } else if ("chargedata".equals(action)) {
+ if (roombaComm.updateSensors())
+ updateDisplay("*****\n" + roombaComm.chargeDataAsString()+ "\n");
+ else
+ updateDisplay("couldn't read Roomba. Is it connected?\n");
+ } else if ("toggleGreen".equals(action)) {
+ setChgGreenLED(roombaComm, !greenOn);
+ } else if ("toggleRed".equals(action)) {
+ setChgRedLED(roombaComm, !redOn);
+ } else if ("toggleSpot".equals(action)) {
+ setChgSpotLED(roombaComm, !toggleSpot);
+ } else if ("toggleClean".equals(action)) {
+ setChgCleanLED(roombaComm, !toggleClean);
+ } else if ("toggleMax".equals(action)) {
+ setChgMaxLED(roombaComm, !toggleMax);
+ } else if ("toggleDirt".equals(action)) {
+ setChgDirtLED(roombaComm, !toggleDirt);
+ } else if ("toggleCheckRobot".equals(action)) {
+ setToggleCheckRobot(roombaComm, !toggleCheckRobot);
+ } else if ("toggleDock".equals(action)) {
+ setToggleDock(roombaComm, !toggleDock);
+ }
+ }
+
+ /**
+ * implement ChangeListener, for the slider.
+ *
+ * @param e the e
+ */
+ public void stateChanged(ChangeEvent e) {
+ // System.err.println("stateChanged:"+e);
+ JSlider src = (JSlider) e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ int speed = (int) src.getValue();
+ speed = (speed < 1) ? 1 : speed; // don't allow zero speed
+ if (roombaComm != null){
+ updateDisplay("setting speed = " + speed + "\n");
+ roombaComm.setSpeed(speed);
+ }
+ }
+ }
+
+ /**
+ * TODO: comment needed for makePanels.
+ */
+ void makePanels() {
+ debugPrintln(debug,"makePanels-start");
+ getContentPane().add(getJPanel4xx(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 2, 2));
+ makeDisplayPanel();
+ updateDisplay("RoombaComm, version " + RoombaComm.VERSION + "\n");
+ debugPrintln(debug,"makePanels-finish");
+ }
+
+ /**
+ * TODO: need comment for makeDisplayPanel.
+ */
+ void makeDisplayPanel() {
+ JTextArea displayText2 = new JTextArea(25, 30);
+ displayText2.setLineWrap(true);
+ DefaultCaret dc = new DefaultCaret();
+ dc.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
+ }
+
+ /**
+ * Update display.
+ *
+ * @param s the s
+ */
+ protected void updateDisplay(String s) {
+ debugPrintln(debug,"updateDisplay(string): start");
+ displayText.append(s);
+ if (s != null && !(s.endsWith("\n"))) {
+ displayText.append("\n");
+ }
+ debugPrintln(debug,"updateDisplay(string): reposition to "+displayText.getDocument().getLength());
+ displayText.getParent().validate();
+ displayText.getParent().repaint(100);
+ displayText.setText(displayText.getText() );
+ debugPrintln(debug,"updateDisplay(string): end");
+ }
+
+ /**
+ * Update display.
+ *
+ * @param s the s
+ * @param onlyDebug the only debug
+ */
+ protected void updateDisplay(String s, boolean onlyDebug) {
+ if (onlyDebug && (roombaCommSerial.debug || roombaCommTCPClient.debug)) {
+ updateDisplay(s);
+ debugPrintln(true,s);
+ }
+ }
+
+ /**
+ * Update display.
+ *
+ * @param roombacomm the roombacomm
+ * @param jtextarea the jtextarea
+ * @param s the s
+ * @param onlyDebug the only debug
+ */
+ protected static void updateDisplay(RoombaComm roombacomm,
+ JTextArea jtextarea, String s, boolean onlyDebug) {
+ if (onlyDebug && roombacomm.debug) {
+ jtextarea.append(s);
+ jtextarea.setCaretPosition(jtextarea.getDocument().getLength());
+ jtextarea.getParent().validate();
+ jtextarea.getParent().repaint(100);
+ System.out.println(s);
+ }
+ }
+
+ /**
+ * Returns an ImageIcon, or null if the path was invalid.
+ *
+ * @param path the path
+ * @param description the description
+ * @return the image icon
+ */
+ protected static ImageIcon createImageIcon(String path, String description) {
+ java.net.URL imgURL = RoombaCommFrame.class.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL, description);
+ } else {
+ System.err.println("Couldn't find file: " + path);
+ return null;
+ }
+ }
+
+ // uh... we should try to avoid @SuppressWarnings ...
+ /**
+ * Play song.
+ *
+ * @param roombacomm the roombacomm
+ * @param rtttl the rtttl
+ */
+ @SuppressWarnings("unchecked")
+ protected void playSong(RoombaComm roombacomm, String rtttl) {
+ ArrayList notelist = RTTTLParser.parse(rtttl);
+ int songsize = notelist.size();
+ // if within the size of a roomba song, make the nsong, then play
+ if (songsize <= 16) {
+ updateDisplay("creating a song with createSong()", this.debug);
+ int notearray[] = new int[songsize * 2];
+ int j = 0;
+ for (int i = 0; i < songsize; i++) {
+ Note note = (Note) notelist.get(i);
+ int sec64ths = note.duration * 64 / 1000;
+ notearray[j++] = note.notenum;
+ notearray[j++] = sec64ths;
+ }
+ roombacomm.createSong(1, notearray);
+ roombacomm.playSong(1);
+ }
+ // otherwise, try to play it in realtime
+ else {
+ updateDisplay("playing song in realtime with playNote()\n",
+ this.debug);
+ int fudge = 20;
+ for (int i = 0; i < songsize; i++) {
+ Note note = (Note) notelist.get(i);
+ int duration = note.duration;
+ int sec64ths = duration * 64 / 1000;
+ if (sec64ths < 5)
+ sec64ths = 5;
+ if (note.notenum != 0)
+ roombacomm.playNote(note.notenum, sec64ths);
+ roombacomm.pause(duration + fudge);
+ }
+ }
+ }
+
+ /**
+ * Tribble start.
+ *
+ * @param roombacomm the roombacomm
+ * @param jtextarea the jtextarea
+ * @param tribbleOn the tribble on
+ */
+ protected static void tribbleStart(RoombaComm roombacomm,
+ JTextArea jtextarea, boolean tribbleOn) {
+ createTribblePurrSong(roombacomm);
+
+ updateDisplay(roombacomm, jtextarea, "Press return to exit.", roombacomm.debug);
+
+ while (tribbleOn) {
+ purr(roombacomm, jtextarea);
+ if (Math.random() < 0.1)
+ bark(roombacomm, jtextarea);
+ roombacomm.pause(1500 + (int) (Math.random() * 500));
+ // tribbleOn = keyIsPressed();
+ roombacomm.updateSensors();
+ boolean b = roombacomm.maxButton();
+ updateDisplay(roombacomm, jtextarea, "max button is (" + b + ")",roombacomm.debug);
+ tribbleOn = (!b);
+ }
+ }
+
+ /**
+ * Purr.
+ *
+ * @param roombacomm the roombacomm
+ * @param jtextarea the jtextarea
+ */
+ protected static void purr(RoombaComm roombacomm, JTextArea jtextarea) {
+ updateDisplay(roombacomm, jtextarea, "purr", roombacomm.debug);
+ roombacomm.playSong(5);
+ for (int i = 0; i < 5; i++) {
+ roombacomm.spinLeftAt(75);
+ roombacomm.pause(100);
+ roombacomm.spinRightAt(75);
+ roombacomm.pause(100);
+ roombacomm.stop();
+ }
+ }
+
+ /**
+ * Creates the tribble purr song.
+ *
+ * @param roombacomm the roombacomm
+ */
+ protected static void createTribblePurrSong(RoombaComm roombacomm) {
+ int song[] = { 68, 4, 67, 4, 66, 4, 65, 4, 64, 4, 63, 4, 62, 4, 61, 4,
+ 60, 4, 59, 4, 60, 4, 61, 4, };
+ roombacomm.createSong(5, song);
+ }
+
+ /**
+ * Bark.
+ *
+ * @param roombacomm the roombacomm
+ * @param jtextarea the jtextarea
+ */
+ protected static void bark(RoombaComm roombacomm, JTextArea jtextarea) {
+ updateDisplay(roombacomm, jtextarea, "bark", roombacomm.debug);
+ roombacomm.vacuum(true);
+ roombacomm.playNote(50, 5);
+ roombacomm.pause(150);
+ roombacomm.vacuum(false);
+ }
+
+ /**
+ * Gets the power_color.
+ *
+ * @return the power_color
+ */
+ protected int getPower_color() {
+ return power_color;
+ }
+
+ /**
+ * Sets the power_color.
+ *
+ * @param power_color the new power_color
+ */
+ protected void setPower_color(int power_color) {
+ if (power_color >= 0 && power_color <= 255) {
+ this.power_color = power_color;
+ } else {
+ this.power_color = 0;
+ updateDisplay("invalid power color attempted (" + power_color + ")");
+ }
+ }
+
+ /**
+ * Gets the power_int.
+ *
+ * @return the power_int
+ */
+ protected int getPower_int() {
+ return power_int;
+ }
+
+ /**
+ * Sets the power_int.
+ *
+ * @param power_int the new power_int
+ */
+ protected void setPower_int(int power_int) {
+
+ if (power_color >= 0 && power_color <= 255) {
+ this.power_int = power_int;
+ } else {
+ this.power_int = 0;
+ updateDisplay("invalid power intensity attempted (" + power_color
+ + ")");
+ }
+ }
+
+ /**
+ * Sets the lE ds.
+ *
+ * @param roombacomm the new lE ds
+ */
+ protected void setLEDs(RoombaComm roombacomm) {
+ if (!roombacomm.connected())
+ return;
+ if (roombacomm.getProtocol().equalsIgnoreCase("SCI")) {
+ roombacomm.setLEDs(this.greenOn, this.redOn, this.toggleSpot,
+ this.toggleClean, this.toggleMax, this.toggleDirt,
+ this.power_color, this.power_int);
+ }
+ if (roombacomm.getProtocol().equalsIgnoreCase("OI")) {
+ roombacomm.setLEDsOI(this.toggleCheckRobot, this.toggleSpot,
+ this.toggleDock, this.toggleDirt, this.power_color,
+ this.power_int);
+ }
+ return;
+ }
+
+ /**
+ * Sets the chg green led.
+ *
+ * @param roombacomm the roombacomm
+ * @param green the green
+ */
+ protected void setChgGreenLED(RoombaComm roombacomm, boolean green) {
+ this.greenOn = green;
+ updateDisplay("setChgGreenLED", this.debug);
+ this.setLEDs(roombacomm);
+ }
+
+ /**
+ * Sets the chg red led.
+ *
+ * @param roombacomm the roombacomm
+ * @param red the red
+ */
+ protected void setChgRedLED(RoombaComm roombacomm, boolean red) {
+ this.redOn = red;
+ updateDisplay("setChgRedLED", this.debug);
+ this.setLEDs(roombacomm);
+ }
+
+ /**
+ * Sets the chg spot led.
+ *
+ * @param roombacomm the roombacomm
+ * @param spot the spot
+ */
+ protected void setChgSpotLED(RoombaComm roombacomm, boolean spot) {
+ updateDisplay("setChgSpotLED value(" + spot + ")", this.debug);
+ roombacomm.setChgSpotLED(roombacomm, spot);
+ this.toggleSpot = roombacomm.isToggleSpot();
+ }
+
+ /**
+ * Sets the chg clean led.
+ *
+ * @param roombacomm the roombacomm
+ * @param clean the clean
+ */
+ protected void setChgCleanLED(RoombaComm roombacomm, boolean clean) {
+ updateDisplay("setChgCleanLED value(" + clean + ")", this.debug);
+ roombacomm.setChgCleanLED(roombacomm, clean);
+ this.toggleClean = roombacomm.isToggleClean();
+ }
+
+ /**
+ * Sets the chg max led.
+ *
+ * @param roombacomm the roombacomm
+ * @param max the max
+ */
+ protected void setChgMaxLED(RoombaComm roombacomm, boolean max) {
+ updateDisplay("setChgMaxLED value(" + max + ")", this.debug);
+ roombacomm.setChgMaxLED(roombacomm, max);
+ this.toggleMax = roombacomm.isToggleMax();
+ }
+
+ /**
+ * Sets the chg dirt led.
+ *
+ * @param roombacomm the roombacomm
+ * @param dirt the dirt
+ */
+ protected void setChgDirtLED(RoombaComm roombacomm, boolean dirt) {
+ updateDisplay("setChgDirtLED value(" + dirt + ")", this.debug);
+ roombacomm.setChgDirtLED(roombacomm, dirt);
+ this.toggleDirt = roombacomm.isToggleDirt();
+ }
+
+ /**
+ * Sets the toggle check robot.
+ *
+ * @param roombacomm the roombacomm
+ * @param CheckRobot the check robot
+ */
+ public void setToggleCheckRobot(RoombaComm roombacomm, boolean CheckRobot) {
+ updateDisplay("setChgCheckRobotLED value(" + CheckRobot + ")",this.debug);
+ roombacomm.setChgCheckRobotLED(roombacomm, CheckRobot);
+ this.toggleCheckRobot = roombacomm.isToggleCheckRobot();
+ }
+
+ /**
+ * Sets the toggle dock.
+ *
+ * @param roombacomm the roombacomm
+ * @param dock the dock
+ */
+ public void setToggleDock(RoombaComm roombacomm, boolean dock) {
+ updateDisplay("setChgDockLED value(" + dock + ")", this.debug);
+ roombacomm.setChgDockLED(roombacomm, dock);
+ this.toggleDock = roombacomm.isToggleDock();
+ }
+
+ /**
+ * Sets the chg power color led.
+ *
+ * @param roombacomm the roombacomm
+ * @param power_color the power_color
+ */
+ protected void setChgPowerColorLED(RoombaComm roombacomm, int power_color) {
+ updateDisplay("setChgPowerColorLED value(" + power_color + ")",this.debug);
+ roombacomm.setChgPowerColorLED(roombacomm, power_color);
+ // this.power_color
+ // TODO: Keep track of power color
+ }
+
+ /**
+ * Sets the chg power intensity led.
+ *
+ * @param roombacomm the roombacomm
+ * @param power_intensity the power_intensity
+ */
+ protected void setChgPowerIntensityLED(RoombaComm roombacomm, int power_intensity) {
+ updateDisplay("setChgPowerIntensityLED value(" + power_intensity + ")",this.debug);
+ roombacomm.setChgPowerIntensityLED(roombacomm, power_intensity);
+ // TODO: Keep track of Power Intensity
+ }
+
+ /**
+ * Gets the toggle check robot.
+ *
+ * @return the toggle check robot
+ */
+ public boolean getToggleCheckRobot() {
+ return toggleCheckRobot;
+ }
+
+ /**
+ * Gets the toggle dock.
+ *
+ * @return the toggle dock
+ */
+ public boolean getToggleDock() {
+ return toggleDock;
+ }
+
+ /**
+ * Gets the j tabbed panel config.
+ *
+ * @return the j tabbed panel config
+ */
+ private JTabbedPane getJTabbedPanelConfig() {
+ if(jTabbedPanelConfig == null) {
+ jTabbedPanelConfig = new JTabbedPane();
+ jTabbedPanelConfig.setPreferredSize(new java.awt.Dimension(139, 28));
+ jTabbedPanelConfig.addTab("Net", null, getJPanelConfigNet(), "set the TCP network settings here");
+ jTabbedPanelConfig.addTab("Serial", null, getJPanelConfigSerial(), "set the serial settings here");
+ }
+ jTabbedPanelConfig.setMinimumSize(new Dimension(200,100));
+ jTabbedPanelConfig.setPreferredSize(new java.awt.Dimension(254, 100));
+ jTabbedPanelConfig.setToolTipText("Use one of the two connection methods to communicate with the Roomba");
+ // Register a change listener
+ jTabbedPanelConfig.addChangeListener(new ChangeListener() {
+ // This method is called whenever the selected tab changes
+ public void stateChanged(ChangeEvent evt) {
+ debugPrintln(debug,"jTabbedPanelConfig - state changed");
+ JTabbedPane pane = (JTabbedPane)evt.getSource();
+ // Get current tab
+ int sel = pane.getSelectedIndex();
+ debugPrintln(debug,"jTabbedPanelConfig - tab "+sel+" selected");
+ debugPrintln(debug,"jTabbedPanelConfig - roombaCommSerial.isConnected() "+roombaCommSerial.isConnected());
+ debugPrintln(debug,"jTabbedPanelConfig - roombaCommTCPClient.isConnected() "+roombaCommTCPClient.isConnected());
+ if (roombaCommTCPClient.isConnected() && roombaCommSerial.isConnected()){
+ debugPrintln(debug,"***** I have no idea why both should ever be connected at the same time... THIS IS STRANGE *****");
+ }
+ if (sel == 1){
+ setCommPorts();
+ if (roombaCommTCPClient.isConnected() && !roombaCommSerial.isConnected()){
+ pane.setSelectedIndex(0);
+ debugPrintln(debug,"active net connection found setting focus to the correct tab");
+ }
+ }
+ if (sel == 0){
+ if (!roombaCommTCPClient.isConnected() && roombaCommSerial.isConnected()){
+ pane.setSelectedIndex(1);
+ debugPrintln(debug,"active Serial connection found setting focus to the correct tab");
+ }
+ }
+ }
+ });
+ return jTabbedPanelConfig;
+ }
+
+ /**
+ * Gets the j panel config net.
+ *
+ * @return the j panel config net
+ */
+ private JPanel getJPanelConfigNet() {
+ if(jPanelConfigNet == null) {
+ jPanelConfigNet = new JPanel();
+ GridBagLayout jPanelConfigNetLayout = new GridBagLayout();
+ jPanelConfigNetLayout.rowWeights = new double[] {0.0, 0.1};
+ jPanelConfigNetLayout.rowHeights = new int[] {26, 7};
+ jPanelConfigNetLayout.columnWeights = new double[] {0.1, 0.1, 0.1};
+ jPanelConfigNetLayout.columnWidths = new int[] {7, 7, 7};
+ jPanelConfigNet.setLayout(jPanelConfigNetLayout);
+ jPanelConfigNet.setPreferredSize(new java.awt.Dimension(318, 72));
+ jPanelConfigNet.add(getJLabelHost(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigNet.add(getJTextFieldHost(), new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigNet.add(getJLabelPort(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigNet.add(getJTextFieldPort(), new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ netButton = new JButton();
+ jPanelConfigNet.add(netButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ netButton.setText("connect");
+ netButton.setActionCommand("net");
+ netButton.addActionListener(this);
+ }
+ }
+ return jPanelConfigNet;
+ }
+
+ /**
+ * Gets the j panel config serial.
+ *
+ * @return the j panel config serial
+ */
+ private JPanel getJPanelConfigSerial() {
+ if(jPanelConfigSerial == null) {
+ jPanelConfigSerial = new JPanel();
+ GridBagLayout jPanelConfigSerialLayout = new GridBagLayout();
+ jPanelConfigSerial.setPreferredSize(new java.awt.Dimension(318, 72));
+ jPanelConfigSerialLayout.rowWeights = new double[] {0.1};
+ jPanelConfigSerialLayout.rowHeights = new int[] {7};
+ jPanelConfigSerialLayout.columnWeights = new double[] {0.0, 0.1, 0.1};
+ jPanelConfigSerialLayout.columnWidths = new int[] {77, 7, 7};
+ jPanelConfigSerial.setLayout(jPanelConfigSerialLayout);
+ jPanelConfigSerial.addFocusListener(new FocusAdapter() {
+ public void focusGained(FocusEvent evt) {
+ jPanelConfigSerialFocusGained(evt);
+ }
+ });
+ {
+ portChoices = new JComboBox();
+ jPanelConfigSerial.add(portChoices, new GridBagConstraints(1, -1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ portChoices.validate();
+ portChoices.repaint();
+ portChoices.addActionListener(this);
+ }
+ {
+ connectButton = new JButton();
+ jPanelConfigSerial.add(connectButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigSerial.add(getJLabelCOMM(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0));
+ connectButton.setText(" connect ");
+ connectButton.setActionCommand("connect");
+ connectButton.addActionListener(this);
+ }
+ }
+ return jPanelConfigSerial;
+ }
+
+ /**
+ * Gets the j label host.
+ *
+ * @return the j label host
+ */
+ private JLabel getJLabelHost() {
+ if(jLabelHost == null) {
+ jLabelHost = new JLabel();
+ jLabelHost.setLayout(null);
+ jLabelHost.setText("Host");
+ jLabelHost.setPreferredSize(new java.awt.Dimension(39, 17));
+ jLabelHost.setLabelFor(getJTextFieldHost());
+ jLabelHost.setToolTipText("Set the hostname/IP address");
+ }
+ return jLabelHost;
+ }
+
+ /**
+ * Gets the j text field host.
+ *
+ * @return the j text field host
+ */
+ private JTextField getJTextFieldHost() {
+ if(jTextFieldHost == null) {
+ jTextFieldHost = new JTextField();
+ jTextFieldHost.setText("192.168.2.15");
+ jTextFieldHost.setToolTipText("Set the hostname/IP address");
+ }
+ return jTextFieldHost;
+ }
+
+ /**
+ * Gets the j panel1.
+ *
+ * @return the j panel1
+ */
+ private JPanel getJPanel1() {
+ if(jPanel1 == null) {
+ jPanel1 = new JPanel();
+ GridBagLayout jPanel1Layout = new GridBagLayout();
+ jPanel1Layout.rowWeights = new double[] {0.1};
+ jPanel1Layout.rowHeights = new int[] {7};
+ jPanel1Layout.columnWeights = new double[] {0.1, 0.1};
+ jPanel1Layout.columnWidths = new int[] {7, 7};
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1.setPreferredSize(new java.awt.Dimension(800,320));
+ {
+ ledPanel = new JPanel();
+ GridBagLayout ledPanelLayout = new GridBagLayout();
+ ledPanel.setLayout(ledPanelLayout);
+ jPanel1.add(ledPanel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ ledPanelSCIOnly = new JPanel(new GridLayout(3, 3));
+ GridBagLayout ledPanel1Layout = new GridBagLayout();
+ ledPanel.add(getLedPanelShared(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ ledPanel.add(getJPanel4x(), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ ledPanel.add(ledPanelSCIOnly, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ ledPanel1Layout.rowWeights = new double[] {0.1};
+ ledPanel1Layout.rowHeights = new int[] {7};
+ ledPanel1Layout.columnWeights = new double[] {0.1, 0.1, 0.1, 0.1};
+ ledPanel1Layout.columnWidths = new int[] {7, 7, 7, 7};
+ ledPanelSCIOnly.setLayout(ledPanel1Layout);
+ ButtonGroup group = new ButtonGroup();
+ String off="None";
+ String green="Green";
+ String red="Red";
+ String both="Orange";
+ {
+ JRadioButton statusOffButton = new JRadioButton(off);
+ ledPanelSCIOnly.add(statusOffButton, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ statusOffButton.setMnemonic(KeyEvent.VK_N);
+ statusOffButton.setActionCommand("StatusLED-" + off);
+ statusOffButton.setSelected(true);
+ group.add(statusOffButton);
+ statusOffButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, false);
+ setChgRedLED(roombaCommSerial, false);
+ }
+ });
+ }
+ {
+ JRadioButton statusGreenButton = new JRadioButton(green);
+ ledPanelSCIOnly.add(statusGreenButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ statusGreenButton.setMnemonic(KeyEvent.VK_G);
+ statusGreenButton.setActionCommand("StatusLED-" + green);
+ group.add(statusGreenButton);
+ statusGreenButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, true);
+ setChgRedLED(roombaCommSerial, false);
+ }
+ });
+ }
+ {
+ JRadioButton statusRedButton = new JRadioButton(red);
+ ledPanelSCIOnly.add(statusRedButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ statusRedButton.setMnemonic(KeyEvent.VK_R);
+ statusRedButton.setActionCommand("StatusLED-" + red);
+ group.add(statusRedButton);
+ statusRedButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, false);
+ setChgRedLED(roombaCommSerial, true);
+ }
+ });
+ }
+ {
+ JRadioButton statusBothButton = new JRadioButton(both);
+ ledPanelSCIOnly.add(statusBothButton, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ statusBothButton.setMnemonic(KeyEvent.VK_O);
+ statusBothButton.setActionCommand("StatusLED-" + both);
+ group.add(statusBothButton);
+ statusBothButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, true);
+ setChgRedLED(roombaCommSerial, true);
+ }
+ });
+ }
+ }
+ {
+ powerColorSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 100);
+ ledPanel.add(powerColorSlider, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 2, 2));
+ powerColorSlider.setPaintTicks(true);
+ powerColorSlider.setMajorTickSpacing(100);
+ powerColorSlider.setMinorTickSpacing(25);
+ powerColorSlider.setPaintLabels(true);
+ powerColorSlider.setSize(200, 46);
+ powerColorSlider.setPreferredSize(new java.awt.Dimension(224, 48));
+ powerColorSlider.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ JSlider src = (JSlider) e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ setPower_color((int) src.getValue());
+ updateDisplay("setting Power Color = " + getPower_color()
+ + "\n");
+ setLEDs(roombaCommSerial);
+ }
+ }
+ });
+ }
+ {
+ JLabel powerColorLabel = new JLabel("PowerColor", JLabel.CENTER);
+ ledPanel.add(powerColorLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 2, 2));
+ }
+ {
+ powerColorIntensity = new JSlider(JSlider.HORIZONTAL, 0, 255, 100);
+ ledPanel.add(powerColorIntensity, new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 2, 2));
+ powerColorIntensity.setPaintTicks(true);
+ powerColorIntensity.setMajorTickSpacing(100);
+ powerColorIntensity.setMinorTickSpacing(25);
+ powerColorIntensity.setPaintLabels(true);
+ powerColorIntensity.setPreferredSize(new java.awt.Dimension(248, 45));
+ powerColorIntensity.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ // System.err.println("stateChanged:"+e);
+ JSlider src = (JSlider) e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ setPower_int((int) src.getValue());
+ updateDisplay("setting Power Color Intensity = "
+ + getPower_int() + "\n");
+ setLEDs(roombaCommSerial);
+ }
+ }
+ });
+ }
+ {
+ JLabel powerColorIntensityLabel = new JLabel("PowerColorIntensity",
+ JLabel.CENTER);
+ ledPanel.add(powerColorIntensityLabel, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 2, 2));
+ }
+ ledPanelLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
+ ledPanelLayout.rowHeights = new int[] {7, 7, 7, 7, 7, 7, 7};
+ ledPanelLayout.columnWeights = new double[] {0.1};
+ ledPanelLayout.columnWidths = new int[] {7};
+ ledPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("LEDs"),BorderFactory.createEmptyBorder(5,5,5,5)));
+ ledPanel.setPreferredSize(new java.awt.Dimension(288, 313));
+ }
+
+ {
+ ctrlPanel = new JPanel();
+ jPanel1.add(ctrlPanel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ JPanel ctrlPanel1 = new JPanel();
+ ctrlPanel.add(ctrlPanel1);
+ {
+ JButton but_turnleft = new JButton();
+ ctrlPanel1.add(but_turnleft);
+ but_turnleft.setActionCommand("turnleft");
+ but_turnleft.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_turnleft.png")));
+ but_turnleft.addActionListener(this);
+ }
+ {
+ JButton but_forward = new JButton();
+ ctrlPanel1.add(but_forward);
+ but_forward.setActionCommand("forward");
+ but_forward.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_forward.png")));
+ but_forward.addActionListener(this);
+ }
+ {
+ JButton but_turnright = new JButton();
+ ctrlPanel1.add(but_turnright);
+ but_turnright.setActionCommand("turnright");
+ but_turnright.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_turnright.png")));
+ but_turnright.addActionListener(this);
+ }
+ {
+ JButton but_spinleft = new JButton();
+ ctrlPanel1.add(but_spinleft);
+ but_spinleft.setActionCommand("spinleft");
+ but_spinleft.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_spinleft.png")));
+ but_spinleft.addActionListener(this);
+ }
+ {
+ JButton but_stop = new JButton();
+ ctrlPanel1.add(but_stop);
+ but_stop.setActionCommand("stop");
+ but_stop.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_stop.png")));
+ but_stop.addActionListener(this);
+ }
+ {
+ JButton but_spinright = new JButton();
+ ctrlPanel1.add(but_spinright);
+ but_spinright.setActionCommand("spinright");
+ but_spinright.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_spinright.png")));
+ but_spinright.addActionListener(this);
+ }
+ {
+ ctrlPanel1.add(new JLabel());
+ }
+ {
+ JButton but_backward = new JButton();
+ ctrlPanel1.add(but_backward);
+ but_backward.setActionCommand("backward");
+ but_backward.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_backward.png")));
+ but_backward.setPreferredSize(new java.awt.Dimension(55, 78));
+ but_backward.addActionListener(this);
+ }
+ {
+ ctrlPanel1.add(new JLabel());
+ }
+ ctrlPanel1.setLayout(new GridLayout(3, 3));
+ ctrlPanel1.setPreferredSize(new java.awt.Dimension(194, 199));
+ ctrlPanel1.setSize(194, 199);
+// ctrlPanel1.setTabTitle("");
+ }
+ {
+ speedSlider = new JSlider(JSlider.HORIZONTAL, 0, 500, 200);
+ ctrlPanel.add(speedSlider);
+ speedSlider.setPaintTicks(true);
+ speedSlider.setMajorTickSpacing(100);
+ speedSlider.setMinorTickSpacing(25);
+ speedSlider.setPaintLabels(true);
+ speedSlider.addChangeListener(this);
+ }
+ {
+ JLabel sliderLabel = new JLabel();
+ ctrlPanel.add(sliderLabel);
+ sliderLabel.setText("speed (mm/s)");
+ sliderLabel.setAlignmentX(JLabel.CENTER);
+ }
+ ctrlPanel.setLayout(new BoxLayout(ctrlPanel, BoxLayout.Y_AXIS));
+ ctrlPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Movement"),BorderFactory.createEmptyBorder(5,5,5,5)));
+ }
+ }
+ return jPanel1;
+ }
+
+ /**
+ * Gets the j label port.
+ *
+ * @return the j label port
+ */
+ private JLabel getJLabelPort() {
+ if(jLabelPort == null) {
+ jLabelPort = new JLabel();
+ jLabelPort.setText("Port");
+ jLabelPort.setPreferredSize(new java.awt.Dimension(39, 33));
+ jLabelPort.setLabelFor(getJTextFieldPort());
+ jLabelPort.setToolTipText("Set the TCP port");
+ }
+ return jLabelPort;
+ }
+
+ /**
+ * Gets the j text field port.
+ *
+ * @return the j text field port
+ */
+ private JTextField getJTextFieldPort() {
+ if(jTextFieldPort == null) {
+ jTextFieldPort = new JTextField();
+ jTextFieldPort.setToolTipText("Set the TCP port");
+ jTextFieldPort.setText("5001");
+ }
+ return jTextFieldPort;
+ }
+
+ /**
+ * J panel config serial focus gained.
+ *
+ * @param evt the evt
+ */
+ private void jPanelConfigSerialFocusGained(FocusEvent evt) {
+ debugPrintln(debug,"jPanelConfigSerial.focusGained, event="+evt);
+ //TODO add your code for jPanelConfigSerial.focusGained
+ // make sure we have a roombaCommSerial object
+ setCommPorts();
+ }
+
+ /**
+ * Sets the comm ports.
+ */
+ private void setCommPorts() {
+ debugPrintln(debug,"setCommPorts-start");
+ if (roombaCommSerial == null){
+ debugPrintln(debug,"setCommPorts-roombaCommSerial is null");
+ roombaCommSerial = new RoombaCommSerial(this.debug);
+ }
+ if (portChoices != null) {
+ debugPrintln(debug,"setCommPorts-portChoices object is not null");
+ // if the list of ports is empty then try to fill it
+ if (portChoices.getItemCount() ==0){
+ // fill in the comm ports (combo box) with choices.
+ debugPrintln(debug,"setCommPorts-getting list of ports");
+ String[] ports = roombaCommSerial.listPorts();
+ // for now short cutting looking for serial ports to speed up start/stop of the UI
+ // String[] ports = {"a","b"};
+ debugPrintln(debug,"setCommPorts-found "+ports.length+" serialports");
+ for (int i = 0; i < ports.length; i++) {
+ String s = ports[i];
+ debugPrintln(debug,"setCommPorts-adding ["+i+"] as "+s);
+ portChoices.addItem(ports[i]);
+ if (s.equals(roombaCommSerial.getPortname())) {
+ debugPrintln(debug,"setCommPorts- setting port as selected due to "+roombaCommSerial.getPortname());
+ portChoices.setSelectedItem(s);
+ }
+ }
+ portChoices.validate();
+ portChoices.repaint();
+ }
+ }
+ debugPrintln(debug,"setCommPorts-start");
+ }
+
+ /**
+ * Gets the j label comm.
+ *
+ * @return the j label comm
+ */
+ private JLabel getJLabelCOMM() {
+ if(jLabelCOMM == null) {
+ jLabelCOMM = new JLabel();
+ jLabelCOMM.setText("COM");
+ }
+ return jLabelCOMM;
+ }
+
+ /**
+ * Gets the j panel2.
+ *
+ * @return the j panel2
+ */
+ private JPanel getJPanel2() {
+ if(jPanel2 == null) {
+ jPanel2 = new JPanel();
+ GridBagLayout jPanel2Layout = new GridBagLayout();
+ jPanel2Layout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
+ jPanel2Layout.rowHeights = new int[] {7, 7, 7, 7, 7, 7};
+ jPanel2Layout.columnWeights = new double[] {0.0};
+ jPanel2Layout.columnWidths = new int[] {150};
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2.setBorder(BorderFactory.createTitledBorder(null,"Commands",TitledBorder.LEADING,TitledBorder.DEFAULT_POSITION));
+ jPanel2.setPreferredSize(new java.awt.Dimension(233,505));
+ jPanel2.add(getJPanelModes(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelSounds(), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelTestPrograms(), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelVacuum(), new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelPower(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanel4(), new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ }
+ return jPanel2;
+ }
+
+ /**
+ * Gets the j panel3.
+ *
+ * @return the j panel3
+ */
+ private JPanel getJPanel3() {
+ if(jPanel3 == null) {
+ jPanel3 = new JPanel();
+ jPanel3.setVisible(false);
+ GridBagLayout jPanel3Layout = new GridBagLayout();
+ jPanel3Layout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
+ jPanel3Layout.rowHeights = new int[] {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+ jPanel3Layout.columnWeights = new double[] {0.1};
+ jPanel3Layout.columnWidths = new int[] {7};
+ jPanel3.setLayout(jPanel3Layout);
+ {
+ JButton but_nyi = new JButton();
+ jPanel3.add(but_nyi, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi.setText("nyi");
+ but_nyi.setVisible(false);
+ }
+ {
+ JButton but_nyi2 = new JButton();
+ jPanel3.add(but_nyi2, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi2.setText("nyi2");
+ but_nyi2.setVisible(false);
+ }
+ {
+ JButton but_nyi3 = new JButton();
+ jPanel3.add(but_nyi3, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi3.setText("nyi3");
+ but_nyi3.setVisible(false);
+ }
+ {
+ JButton but_nyi4 = new JButton();
+ jPanel3.add(but_nyi4, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi4.setText("nyi4");
+ but_nyi4.setVisible(false);
+ }
+ {
+ JButton but_nyi5 = new JButton();
+ jPanel3.add(but_nyi5, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi5.setText("nyi5");
+ but_nyi5.setVisible(false);
+ }
+ {
+ JButton but_nyi6 = new JButton();
+ jPanel3.add(but_nyi6, new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi6.setText("nyi6");
+ but_nyi6.setVisible(false);
+ }
+ {
+ JButton but_nyi7 = new JButton();
+ jPanel3.add(but_nyi7, new GridBagConstraints(0, 8, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi7.setText("nyi7");
+ but_nyi7.setVisible(false);
+ }
+ {
+ jButton2 = new JButton();
+ jPanel3.add(jButton2, new GridBagConstraints(0, 9, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton2.setText("nyi5");
+ jButton2.setVisible(false);
+ }
+ {
+ jButton1 = new JButton();
+ jPanel3.add(jButton1, new GridBagConstraints(0, 10, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton1.setText("nyi6");
+ jButton1.setVisible(false);
+ }
+ {
+ jButton3 = new JButton();
+ jPanel3.add(jButton3, new GridBagConstraints(0, 11, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton3.setText("nyi3");
+ jButton3.setVisible(false);
+ }
+ {
+ jButton4 = new JButton();
+ jPanel3.add(jButton4, new GridBagConstraints(0, 12, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton4.setText("nyi2");
+ jButton4.setVisible(false);
+ }
+ }
+ return jPanel3;
+ }
+
+ /**
+ * Gets the j panel modes.
+ *
+ * @return the j panel modes
+ */
+ private JPanel getJPanelModes() {
+ if(jPanelModes == null) {
+ jPanelModes = new JPanel();
+ GridBagLayout jPanelModesLayout = new GridBagLayout();
+ jPanelModesLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1};
+ jPanelModesLayout.rowHeights = new int[] {7, 7, 7, 7, 7};
+ jPanelModesLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelModesLayout.columnWidths = new int[] {95, 95};
+ jPanelModes.setLayout(jPanelModesLayout);
+ jPanelModes.setBorder(BorderFactory.createTitledBorder("Modes"));
+ {
+ JButton but_spot = new JButton();
+ jPanelModes.add(but_spot, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_spot.setText("spot");
+ but_spot.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_spot.addActionListener(this);
+ }
+ {
+ JButton but_full = new JButton();
+ jPanelModes.add(but_full, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_full.setText("full");
+ but_full.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_full.addActionListener(this);
+ }
+ {
+ JButton but_safe = new JButton();
+ jPanelModes.add(but_safe, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_safe.setText("safe");
+ but_safe.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_safe.addActionListener(this);
+ }
+ {
+ JButton but_dock = new JButton();
+ jPanelModes.add(but_dock, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_dock.setText("dock");
+ but_dock.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_dock.addActionListener(this);
+ }
+ {
+ JButton but_max = new JButton();
+ jPanelModes.add(but_max, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_max.setText("max");
+ but_max.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_max.addActionListener(this);
+ }
+ {
+ JButton but_clean = new JButton();
+ jPanelModes.add(but_clean, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_clean.setText("clean");
+ but_clean.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_clean.addActionListener(this);
+ }
+ {
+ JButton but_wakeup = new JButton();
+ jPanelModes.add(but_wakeup, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_wakeup.setText("wakeup");
+ but_wakeup.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_wakeup.addActionListener(this);
+ }
+ {
+ JButton but_reset = new JButton();
+ jPanelModes.add(but_reset, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_reset.setText("reset");
+ but_reset.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_reset.addActionListener(this);
+ }
+ {
+ JButton but_passive = new JButton();
+ jPanelModes.add(but_passive, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_passive.setText("passive");
+ but_passive.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_passive.addActionListener(this);
+ }
+ }
+ return jPanelModes;
+ }
+
+ /**
+ * Gets the j panel sounds.
+ *
+ * @return the j panel sounds
+ */
+ private JPanel getJPanelSounds() {
+ if(jPanelSounds == null) {
+ jPanelSounds = new JPanel();
+ GridBagLayout jPanelSoundsLayout = new GridBagLayout();
+ jPanelSoundsLayout.rowWeights = new double[] {0.1, 0.1};
+ jPanelSoundsLayout.rowHeights = new int[] {7, 7};
+ jPanelSoundsLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelSoundsLayout.columnWidths = new int[] {95, 95};
+ jPanelSounds.setLayout(jPanelSoundsLayout);
+ jPanelSounds.setBorder(BorderFactory.createTitledBorder("Sounds"));
+ {
+ JButton but_OSU = new JButton();
+ jPanelSounds.add(but_OSU, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_OSU.setText("OSU");
+ but_OSU.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_OSU.addActionListener(this);
+ }
+ {
+ JButton but_beeplo = new JButton();
+ jPanelSounds.add(but_beeplo, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_beeplo.setText("beep-lo");
+ but_beeplo.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_beeplo.addActionListener(this);
+ }
+ {
+ JButton but_beephi = new JButton();
+ jPanelSounds.add(but_beephi, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_beephi.setText("beep-hi");
+ but_beephi.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_beephi.addActionListener(this);
+ }
+ {
+ JButton but_playRTTL = getBut_playRTTL();
+ jPanelSounds.add(getBut_playRTTL(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_playRTTL.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_playRTTL.addActionListener(this);
+ }
+ }
+ return jPanelSounds;
+ }
+
+ /**
+ * Gets the j panel test programs.
+ *
+ * @return the j panel test programs
+ */
+ private JPanel getJPanelTestPrograms() {
+ if(jPanelTestPrograms == null) {
+ jPanelTestPrograms = new JPanel();
+ GridBagLayout jPanelTestProgramsLayout = new GridBagLayout();
+ jPanelTestProgramsLayout.rowWeights = new double[] {0.1};
+ jPanelTestProgramsLayout.rowHeights = new int[] {7};
+ jPanelTestProgramsLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelTestProgramsLayout.columnWidths = new int[] {95, 95};
+ jPanelTestPrograms.setLayout(jPanelTestProgramsLayout);
+ jPanelTestPrograms.setBorder(BorderFactory.createTitledBorder("Test Programs"));
+ {
+ JButton but_TribbleOn = new JButton();
+ jPanelTestPrograms.add(but_TribbleOn, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_TribbleOn.setText("Tribble On");
+ but_TribbleOn.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_TribbleOn.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_TribbleOn.setSize(93, 26);
+ but_TribbleOn.addActionListener(this);
+ }
+ {
+ JButton but_test = new JButton();
+ jPanelTestPrograms.add(but_test, new GridBagConstraints(1, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_test.setText("LogoA.square");
+ but_test.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_test.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_test.setSize(93, 26);
+ but_test.addActionListener(this);
+ }
+ }
+ return jPanelTestPrograms;
+ }
+
+ /**
+ * Gets the j panel4.
+ *
+ * @return the j panel4
+ */
+ private JPanel getJPanel4() {
+ if(jPanelSensors == null) {
+ jPanelSensors = new JPanel();
+ GridBagLayout jPanelSensorsLayout = new GridBagLayout();
+ jPanelSensorsLayout.rowWeights = new double[] {0.1};
+ jPanelSensorsLayout.rowHeights = new int[] {7};
+ jPanelSensorsLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelSensorsLayout.columnWidths = new int[] {95, 95};
+ jPanelSensors.setLayout(jPanelSensorsLayout);
+ jPanelSensors.setBorder(BorderFactory.createTitledBorder(null, "Sensors", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ {
+ JButton but_chargedata = new JButton();
+ jPanelSensors.add(but_chargedata, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
+ but_chargedata.setText("chargedata");
+ but_chargedata.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_chargedata.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_chargedata.setSize(93, 26);
+ but_chargedata.addActionListener(this);
+ }
+ {
+ JButton but_sensors = new JButton();
+ jPanelSensors.add(but_sensors, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
+ but_sensors.setText("sensors");
+ but_sensors.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_sensors.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_sensors.setSize(93, 26);
+ but_sensors.addActionListener(this);
+ }
+ }
+ return jPanelSensors;
+ }
+
+ /**
+ * Gets the j panel vacuum.
+ *
+ * @return the j panel vacuum
+ */
+ private JPanel getJPanelVacuum() {
+ if(jPanelVacuum == null) {
+ jPanelVacuum = new JPanel();
+ GridBagLayout jPanelVacuumLayout = new GridBagLayout();
+ jPanelVacuumLayout.rowWeights = new double[] {0.1};
+ jPanelVacuumLayout.rowHeights = new int[] {7};
+ jPanelVacuumLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelVacuumLayout.columnWidths = new int[] {95, 95};
+ jPanelVacuum.setLayout(jPanelVacuumLayout);
+ jPanelVacuum.setBorder(BorderFactory.createTitledBorder(BorderFactory.createTitledBorder(""), "Vacuum", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ {
+ JButton but_vacon = new JButton();
+ jPanelVacuum.add(but_vacon, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_vacon.setText("vacuum-on");
+ but_vacon.setSize(93, 26);
+ but_vacon.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_vacon.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_vacon.addActionListener(this);
+ }
+ {
+ JButton but_vacoff = new JButton();
+ but_vacoff.setLayout(null);
+ jPanelVacuum.add(but_vacoff, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_vacoff.setText("vacuum-off");
+ but_vacoff.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_vacoff.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_vacoff.setSize(93, 26);
+ but_vacoff.addActionListener(this);
+ }
+ }
+ return jPanelVacuum;
+ }
+
+ /**
+ * Gets the j panel power.
+ *
+ * @return the j panel power
+ */
+ private JPanel getJPanelPower() {
+ if(jPanelPower == null) {
+ jPanelPower = new JPanel();
+ GridBagLayout jPanelPowerLayout = new GridBagLayout();
+ jPanelPower.setBorder(BorderFactory.createTitledBorder(null, "Power", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ jPanelPowerLayout.rowWeights = new double[] {0.1};
+ jPanelPowerLayout.rowHeights = new int[] {7};
+ jPanelPowerLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelPowerLayout.columnWidths = new int[] {95, 95};
+ jPanelPower.setLayout(jPanelPowerLayout);
+ {
+ JButton but_powerOn = new JButton();
+ jPanelPower.add(but_powerOn, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_powerOn.setText("power-on");
+ but_powerOn.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_powerOn.addActionListener(this);
+ }
+ {
+ JButton but_power = new JButton();
+ jPanelPower.add(but_power, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_power.setText("power-off");
+ but_power.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_power.addActionListener(this);
+ }
+ }
+ return jPanelPower;
+ }
+
+ /**
+ * Gets the j text pane1.
+ *
+ * @return the j text pane1
+ */
+ private JTextPane getJTextPane1() {
+ if(jTextPane1 == null) {
+ jTextPane1 = new JTextPane();
+ jTextPane1.setText("Set the Protocal, then connect via a network or Serial connection.\nThen you can use the Commands, LED's, and/or Movement controls to operate your Roomba.");
+ jTextPane1.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ jTextPane1.setOpaque(false);
+ }
+ return jTextPane1;
+ }
+
+ /**
+ * Gets the j panel4x.
+ *
+ * @return the j panel4x
+ */
+ private JPanel getJPanel4x() {
+ if(ledPanelOIOnly == null) {
+ ledPanelOIOnly = new JPanel();
+ GridBagLayout jPanel4Layout = new GridBagLayout();
+ ledPanelOIOnly.setPreferredSize(new java.awt.Dimension(134, 49));
+ jPanel4Layout.rowWeights = new double[] {0.1};
+ jPanel4Layout.rowHeights = new int[] {7};
+ jPanel4Layout.columnWeights = new double[] {0.1, 0.1, 0.1, 0.1};
+ jPanel4Layout.columnWidths = new int[] {7, 7, 7, 7};
+ ledPanelOIOnly.setLayout(jPanel4Layout);
+ ledPanelOIOnly.setVisible(false);
+ {
+ JButton but_toggleDock = new JButton();
+ GridBagLayout but_toggleDockLayout = new GridBagLayout();
+ ledPanelOIOnly.add(but_toggleDock, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_toggleDock.setActionCommand("toggleDock");
+ but_toggleDock.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_dockOn.png")));
+ but_toggleDock.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleDock.setSize(40, 40);
+ but_toggleDockLayout.rowWeights = new double[] {0.1};
+ but_toggleDockLayout.rowHeights = new int[] {7};
+ but_toggleDockLayout.columnWeights = new double[] {0.1, 0.1};
+ but_toggleDockLayout.columnWidths = new int[] {7, 7};
+ but_toggleDock.setLayout(but_toggleDockLayout);
+ but_toggleDock.addActionListener(this);
+ }
+ {
+ JButton but_toggleCheckRobot = new JButton();
+ GridBagLayout but_toggleCheckRobotLayout = new GridBagLayout();
+ ledPanelOIOnly.add(but_toggleCheckRobot, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_toggleCheckRobot.setActionCommand("toggleCheckRobot");
+ but_toggleCheckRobot.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_checkrobotOn.png")));
+ but_toggleCheckRobot.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleCheckRobot.setSize(40, 40);
+ but_toggleCheckRobotLayout.rowWeights = new double[] {0.1};
+ but_toggleCheckRobotLayout.rowHeights = new int[] {7};
+ but_toggleCheckRobotLayout.columnWeights = new double[] {0.1, 0.1};
+ but_toggleCheckRobotLayout.columnWidths = new int[] {7, 7};
+ but_toggleCheckRobot.setLayout(but_toggleCheckRobotLayout);
+ but_toggleCheckRobot.addActionListener(this);
+ }
+ }
+ return ledPanelOIOnly;
+ }
+
+ /**
+ * Gets the led panel shared.
+ *
+ * @return the led panel shared
+ */
+ private JPanel getLedPanelShared() {
+ if(ledPanelShared == null) {
+ ledPanelShared = new JPanel();
+ {
+ JButton but_toggleSpot = new JButton();
+ ledPanelShared.add(but_toggleSpot);
+ but_toggleSpot.setActionCommand("toggleSpot");
+ but_toggleSpot.setIcon(getIcon("com/hackingroomba/roombacomm/images/but_spotOn.png"));
+ but_toggleSpot.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleSpot.setSize(40, 40);
+ but_toggleSpot.addActionListener(this);
+ }
+ {
+ JButton but_toggleClean = new JButton();
+ ledPanelShared.add(but_toggleClean);
+ but_toggleClean.setActionCommand("toggleClean");
+ but_toggleClean.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_cleanOn.png")));
+ but_toggleClean.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleClean.setSize(40, 40);
+ but_toggleClean.addActionListener(this);
+ }
+ {
+ JButton but_toggleDirt = new JButton();
+ ledPanelShared.add(but_toggleDirt);
+ but_toggleDirt.setActionCommand("toggleDirt");
+ but_toggleDirt.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_dirtOn.png")));
+ but_toggleDirt.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleDirt.setSize(40, 40);
+ but_toggleDirt.addActionListener(this);
+ }
+ {
+ JButton but_toggleMax = new JButton();
+ ledPanelShared.add(but_toggleMax);
+ but_toggleMax.setActionCommand("toggleMax");
+ but_toggleMax.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_maxOn.png")));
+ but_toggleMax.setSize(40, 40);
+ but_toggleMax.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleMax.addActionListener(this);
+ }
+ }
+ return ledPanelShared;
+ }
+
+ /**
+ * Gets the icon.
+ *
+ * @param str the str
+ * @return the icon
+ * @return
+ */
+ private ImageIcon getIcon(String str) {
+ java.net.URL file =getClass().getClassLoader().getResource(str);
+ if (file != null){
+ return new ImageIcon(file);
+ }else{
+ // return the default icon
+ //TODO: Get a better default icon. :)
+ System.err.println("failed to find icon (" + str + ")");
+ return new ImageIcon("com/hackingroomba/roombacomm/images/but_spotOn.png");
+ }
+ }
+
+ /**
+ * Gets the j panel4xx.
+ *
+ * @return the j panel4xx
+ */
+ private JPanel getJPanel4xx() {
+ if(jPanel4 == null) {
+ jPanel4 = new JPanel();
+ GridBagLayout jPanel4Layout1 = new GridBagLayout();
+ jPanel4.setLayout(jPanel4Layout1);
+ jPanel4.setPreferredSize(new java.awt.Dimension(806, 608));
+ {
+ selectPanel = new JPanel();
+ GridBagLayout selectPanelLayout = new GridBagLayout();
+ selectPanel.setLayout(selectPanelLayout);
+ jPanel4.add(selectPanel, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ protocolChoices = new JComboBox(protocols);
+ selectPanel.add(protocolChoices, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 0, 5), 0, 0));
+ protocolChoices.setSelectedIndex(protocolChoices.getSelectedIndex() >=0 ? protocolChoices.getSelectedIndex() : 0);
+ protocolChoices.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0), "Protocal", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ protocolChoices.setToolTipText("Set the protocal based on the roomba hardware version");
+ protocolChoices.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent evt) {
+ debugPrintln(debug,"protocolChoices.itemStateChanged, event="+evt);
+ //TODO add your code for protocolChoices.itemStateChanged
+ if (evt.getItem().equals(protocolChoices.getItemAt(0)) && (evt.getStateChange() == ItemEvent.SELECTED)){
+ ledPanelOIOnly.setVisible(false);
+ ledPanelSCIOnly.setVisible(true);
+ }
+ if (evt.getItem().equals(protocolChoices.getItemAt(1)) && (evt.getStateChange() == ItemEvent.SELECTED)){
+ ledPanelOIOnly.setVisible(true);
+ ledPanelSCIOnly.setVisible(false);
+ }
+ ledPanelOIOnly.repaint();
+ ledPanelSCIOnly.repaint();
+ }
+ });
+ protocolChoices.addActionListener(this);
+ }
+ {
+ handshakeButton = new JCheckBox("h/w
handshake");
+ selectPanel.add(handshakeButton, new GridBagConstraints(0, 2, 1, 1, 0.1, 0.1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ selectPanel.add(getJTabbedPanelConfig(), new GridBagConstraints(1, 1, 1, 2, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ selectPanel.add(getJTextPane1(), new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 2, 2));
+ handshakeButton.setPreferredSize(new java.awt.Dimension(148, 40));
+ handshakeButton.setText("h/w handshake");
+ handshakeButton.setToolTipText("check if you want to use the hardware handshake setting");
+ }
+ selectPanelLayout.rowWeights = new double[] {0.0, 0.0};
+ selectPanelLayout.rowHeights = new int[] {53, 58};
+ selectPanelLayout.columnWeights = new double[] {0.0, 0.0};
+ selectPanelLayout.columnWidths = new int[] {177, 375};
+ selectPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Select Roomba Type & Port"),BorderFactory.createEmptyBorder(1,1,1,1)));
+ selectPanel.setPreferredSize(new java.awt.Dimension(535,128));
+ }
+ {
+ displayPanel = new JPanel();
+ jPanel4.add(displayPanel, new GridBagConstraints(1, 2, 3, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ jPanel4.add(getJPanel1(), new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jPanel4.add(getJPanel2(), new GridBagConstraints(2, 0, 1, 2, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jPanel4.add(getJPanel3(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ GridBagLayout displayPanelLayout = new GridBagLayout();
+ displayPanelLayout.rowWeights = new double[] {0.1};
+ displayPanelLayout.rowHeights = new int[] {7};
+ displayPanelLayout.columnWeights = new double[] {0.1};
+ displayPanelLayout.columnWidths = new int[] {7};
+ displayPanel.setLayout(displayPanelLayout);
+ displayPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Display"),BorderFactory.createEmptyBorder(1,1,1,1)));
+ displayPanel.setPreferredSize(new java.awt.Dimension(803, 67));
+ {
+ displayText = new JTextArea(10, 75);
+ displayText.setEditable(false);
+ JScrollPane scrollPane = new JScrollPane(displayText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ displayPanel.add(scrollPane, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ scrollPane.setSize(795, 163);
+ scrollPane.setPreferredSize(new java.awt.Dimension(791, 38));
+ displayText.setLineWrap(false);
+ }
+ }
+ jPanel4Layout1.rowWeights = new double[] {0.1, 0.1, 2.0};
+ jPanel4Layout1.rowHeights = new int[] {7, 7, 80};
+ jPanel4Layout1.columnWeights = new double[] {0.1, 0.1, 0.1};
+ jPanel4Layout1.columnWidths = new int[] {7, 7, 7};
+ }
+ return jPanel4;
+ }
+
+ /**
+ * Debug println.
+ *
+ * @param debug the debug
+ * @param str the str
+ */
+ private void debugPrintln(boolean debug, String str){
+ if (debug){
+ System.out.println(str);
+ }
+ }
+
+ /**
+ * This window closed.
+ *
+ * @param evt the evt
+ */
+ private void thisWindowClosed(WindowEvent evt) {
+ System.out.println("this.windowClosed, event="+evt);
+ //TODO: add code for this.windowClosed ? Do we need anything else?
+ dispose();
+ }
+
+ /**
+ * Gets the but_play rttl.
+ *
+ * @return the but_play rttl
+ */
+ private JButton getBut_playRTTL() {
+ if(but_playRTTL == null) {
+ but_playRTTL = new JButton();
+ but_playRTTL.setText("Play RTTL");
+ but_playRTTL.setVisible(false);
+ }
+ return but_playRTTL;
+ }
+}
\ No newline at end of file
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommGUI.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommGUI.java
new file mode 100644
index 0000000..4d588c3
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommGUI.java
@@ -0,0 +1,125 @@
+/*
+ * RoombaCommGUI -- GUI to test out RoombaComm
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+package com.hackingroomba.roombacomm;
+
+/**
+ * A simple wrapper for RoombaCommFrame.
+ *
+ * This class shows someone how to use RoombaCommFrame from the "outside".
+ * AKA: No Java Swing skills needed for this class. (is the goal)
+ *
+ * SVN id value is $Id: RoombaCommGUI.java 136 2010-04-06 00:07:23Z black.123 $
+ */
+import jargs.examples.gnu.AutoHelpParser;
+//TODO: CMB: add support for different initial GUI sizes (640(w)x480(H),1024x768... maybe others)
+import jargs.gnu.CmdLineParser;
+
+/**
+ * This is an example class that will demonstrate how to use RoombaCommFrame.java.
+ * It also demonstrates a use of jargs to support command line parsing for this class.
+ *
+ */
+public class RoombaCommGUI {
+
+ /** The hwhandshake. */
+ boolean hwhandshake = false;
+
+ /** The debug boolean will increase STDOUT to show details about the process at runtime. */
+ boolean debug = false;
+
+ /**
+ * The main method simply instantiates an instance of this class and passes in any command line arguments to that class.
+ * See RoombaCommGUI(java.lang.String[] args) for details about Command Line Interface (CLI) values
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+ new RoombaCommGUI(args);
+ }
+
+ /**
+ * Instantiates a new RoombaComm GUI without any args.
+ */
+ public RoombaCommGUI() {
+ this(new String[0]);
+ }
+
+ /**
+ * Instantiates a new RoombaComm GUI with any args by use of jargs.
+ *
+ * @param args the args
+ * --hwhandshake boolean value (true,false)
+ * -d,--debug boolean value to increase STDOUT
+ * -h,--help print usage input and exit
+ */
+ public RoombaCommGUI(String[] args) {
+ AutoHelpParser parser = new AutoHelpParser();
+ CmdLineParser.Option hwhandshake_opt = parser.addHelp(parser.addBooleanOption("hwhandshake"),"Use this to turn on the hardware hand shake");
+ CmdLineParser.Option debug_opt = parser.addHelp(parser.addBooleanOption('d', "debug"),"output more information at runtime");
+ CmdLineParser.Option help_opt = parser.addHelp(parser.addBooleanOption('h', "help"),"Show this help message");
+ if (args != null){
+ String[] org_args = args;
+ try {
+ parser.parse(args);
+ }
+ catch ( CmdLineParser.OptionException e ) {
+ System.err.println(e.getMessage());
+ parser.printUsage();
+ System.exit(2);
+ }
+ if ( Boolean.TRUE.equals(parser.getOptionValue(hwhandshake_opt))) {
+ hwhandshake = true;
+ }
+ if ( Boolean.TRUE.equals(parser.getOptionValue(debug_opt))) {
+ debug = true;
+ }
+ if (debug){
+ for( int i=0; i < org_args.length; i++ ) {
+ System.out.println(i+": "+org_args[i]);
+ }
+ }
+ if ( Boolean.TRUE.equals(parser.getOptionValue(help_opt))) {
+ parser.printUsage();
+ System.exit(0);
+ }
+ }
+ // Schedule a job for the event dispatch thread:
+ // creating and showing this application's GUI.
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ createAndShowGUI(debug);
+ }
+ });
+ }
+
+ /**
+ * Create the GUI and show it. For thread safety,
+ * this method should be invoked from the event dispatch thread.
+ *
+ * @param debug to increase STDOUT at runtime
+ */
+ private static void createAndShowGUI(boolean debug) {
+ RoombaCommFrame rcPanel = new RoombaCommFrame(debug);
+ rcPanel.setResizable(true);
+ rcPanel.pack();
+ rcPanel.setVisible(true);
+ }
+}
\ No newline at end of file
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommPanel.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommPanel.java
new file mode 100644
index 0000000..9ccdd0e
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommPanel.java
@@ -0,0 +1,1854 @@
+/*
+ * RoombaCommPanel -
+ *
+ * Copyright (c) 2006 Tod E. Kurt, tod@todbot.com, ThingM
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+package com.hackingroomba.roombacomm;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTextPane;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.text.DefaultCaret;
+
+/**
+ * A Panel containing controls for testing RoombaComm. Normally put inside of a
+ * frame, for example see RoombaCommTest
+ *
+ * SVN id value is $Id: RoombaCommPanel.java 136 2010-04-06 00:07:23Z black.123 $
+ */
+public class RoombaCommPanel extends JPanel implements ActionListener,
+ ChangeListener {
+
+ private static final long serialVersionUID = 1L;
+
+ {
+ // Set Look & Feel
+ try {
+ javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ JPanel ctrlPanel, selectPanel, buttonPanel, displayPanel, ledPanel;
+ private JTextPane jTextPane1;
+ private JPanel jPanelPower;
+ private JPanel jPanelVacuum;
+ private JPanel jPanelSensors;
+ private JPanel jPanelTestPrograms;
+ JComboBox portChoices;
+ JComboBox protocolChoices;
+ JCheckBox handshakeButton;
+ JTextArea displayText;
+ JButton connectButton;
+ JButton netButton;
+ JSlider speedSlider, powerColorSlider, powerColorIntensity;
+ private boolean debug = false;
+ boolean tribbleOn = false;
+ // default values for flags for LEDs
+ boolean redOn = false;
+ boolean greenOn = false;
+ boolean toggleSpot = false;
+ boolean toggleClean = false;
+ boolean toggleMax = false;
+ boolean toggleDirt = false;
+ boolean toggleCheckRobot = false;
+ boolean toggleDock = false;
+ private JPanel jPanelSounds;
+ private JPanel jPanelModes;
+ private JPanel jPanel3;
+ private JPanel jPanel2;
+ private JLabel jLabelCOMM;
+ private JTextField jTextFieldPort;
+ private JLabel jLabelPort;
+ private JPanel jPanel1;
+ private JTextField jTextFieldHost;
+ private JLabel jLabelHost;
+ private JPanel jPanelConfigSerial;
+ private JPanel jPanelConfigNet;
+ private JTabbedPane jTabbedPanelConfig;
+ private JButton jButton4;
+ private JButton jButton3;
+ private JButton jButton2;
+ private JButton jButton1;
+ int power_color = 0;
+ int power_int = 0;
+ RoombaCommSerial roombaCommSerial;
+ RoombaComm roombaComm;
+ RoombaCommTCPClient roombaCommTCPClient;
+ SimpleDateFormat formatter = new SimpleDateFormat(
+ "EEE, dd-MMM-yyyy HH:mm:ss");
+ public RoombaCommPanel() {
+ this(false);
+ }
+
+ public RoombaCommPanel(boolean debug) {
+// super(new BorderLayout());
+ super();
+// this.setContentPane(contentPane)
+ System.out.println("RoombaCommPanel-start");
+ System.out.println(" debug is ("+debug+")");
+ initialize();
+ roombaCommSerial = new RoombaCommSerial();
+ roombaCommTCPClient = new RoombaCommTCPClient();
+ this.debug = debug;
+ roombaCommSerial.debug = debug;
+ roombaCommTCPClient.debug = debug;
+ System.out.println("RoombaCommPanel-makePanels-start");
+ makePanels();
+ System.out.println("RoombaCommPanel-makePanels-end");
+ System.out.println("RoombaCommPanel-end");
+ }
+
+ /**
+ * This method initializes this
+ *
+ */
+ private void initialize() {
+ Dimension defaultSize = new Dimension(800,600);
+ this.addComponentListener(new java.awt.event.ComponentListener() {
+ public void componentResized(java.awt.event.ComponentEvent e) {
+ System.out.println("147-componentResized("+e.getComponent().getWidth()+","+e.getComponent().getHeight()+")"); // TODO Auto-generated Event stub componentResized()
+ }
+ public void componentMoved(java.awt.event.ComponentEvent e) {
+ }
+ public void componentShown(java.awt.event.ComponentEvent e) {
+ }
+ public void componentHidden(java.awt.event.ComponentEvent e) {
+ }
+ });
+ System.out.println("initialize : setting size to (" +defaultSize.getWidth()+","+defaultSize.getHeight()+")");
+ GridBagLayout thisLayout = new GridBagLayout();
+ this.setSize(defaultSize);
+ thisLayout.rowWeights = new double[] {0.0, 0.0, 0.1};
+ thisLayout.rowHeights = new int[] {137, 304, 5};
+ thisLayout.columnWeights = new double[] {0.0, 0.0};
+ thisLayout.columnWidths = new int[] {538, 206};
+ this.setLayout(thisLayout);
+ this.setPreferredSize(new java.awt.Dimension(800, 600)); //638
+// {
+// buttonPanel = new JPanel();
+// this.add(buttonPanel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+// GridBagLayout buttonPanelLayout = new GridBagLayout();
+// buttonPanelLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
+// buttonPanelLayout.rowHeights = new int[] {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+// buttonPanelLayout.columnWeights = new double[] {0.0, 0.0};
+// buttonPanelLayout.columnWidths = new int[] {10, 10};
+// buttonPanel.setLayout(buttonPanelLayout);
+// buttonPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Commands"),BorderFactory.createEmptyBorder(5,5,5,5)));
+// buttonPanel.setMinimumSize(new java.awt.Dimension(0,10));
+// buttonPanel.setSize(200, 411);
+// buttonPanel.setPreferredSize(new java.awt.Dimension(242, 249));
+// }
+ }
+
+ /**
+ * Set to 'false' to hide the "h/w handshake" button, which seems to be only
+ * needed on Windows
+ */
+ public void setShowHardwareHandhake(boolean b) {
+ handshakeButton.setVisible(b);
+ }
+
+ /** */
+ public boolean connect() {
+ System.out.println("connect-start");
+ String portname = (String) portChoices.getSelectedItem();
+ // roombacomm.debug=true;
+ roombaCommSerial.setWaitForDSR(handshakeButton.isSelected());
+ int i = protocolChoices.getSelectedIndex();
+ roombaCommSerial.setProtocol((i == 0) ? "SCI" : "OI");
+ if (portname == null){
+ // I guess we do not yet have ports so refresh the list
+ setCommPorts();
+ }
+ updateDisplay("connecting to " + portname + "\n");
+ connectButton.setText("connecting");
+ if (portname != null){
+ if (!roombaCommSerial.connect(portname)) {
+ updateDisplay("Couldn't connect to " + portname + "\n");
+ connectButton.setText(" connect ");
+ // roombacomm.debug=false;
+ System.out.println("connect-end (could not connect)");
+ return false;
+ }else{
+ updateDisplay("connected to " + portname + "\n");
+ }
+ }else{
+ updateDisplay("you must first select a COMM port to use before you can attempt to connect");
+ jTabbedPanelConfig.setSelectedIndex(1);
+ return false;
+ }
+ updateDisplay("Roomba startup\n");
+
+ roombaCommSerial.startup();
+ roombaCommSerial.control();
+ roombaCommSerial.playNote(72, 10); // C , test note
+ roombaCommSerial.pause(200);
+
+ connectButton.setText("disconnect");
+ connectButton.setActionCommand("disconnect");
+ roombaComm = roombaCommSerial;
+ // roombacomm.debug=true;
+ updateDisplay("Checking for Roomba... ");
+ if (roombaCommSerial.updateSensors()) {
+ updateDisplay("Roomba found!\n");
+ System.out.println("connect-end");
+ return true;
+ }else{
+ updateDisplay("No Roomba. :( Is it turned on?\n");
+ System.out.println("connect-end");
+ return true ;
+ }
+ }
+
+ public boolean connectNet(String portname) {
+ System.out.println("connectNet called");
+ int i = protocolChoices.getSelectedIndex();
+ if (roombaCommTCPClient == null){
+ roombaCommTCPClient = new RoombaCommTCPClient();
+ roombaCommTCPClient.setConnected(false);
+ }
+ roombaCommTCPClient.setProtocol((i == 0) ? "SCI" : "OI");
+
+ if (!roombaCommTCPClient.connect(portname)) {
+ updateDisplay("Couldn't connect to " + portname);
+ return false;
+ }
+
+ updateDisplay("Roomba startup on port " + portname);
+ roombaCommTCPClient.startup();
+ roombaCommTCPClient.control();
+ // roombacomm.setSensorsAutoUpdate(true);
+ roombaCommTCPClient.pause(30);
+
+ updateDisplay("Checking for Roomba... \n");
+ // roombaCommTCPClient.setDebug(true);
+ if (roombaCommTCPClient.updateSensors()) {
+ updateDisplay("Roomba found!\n");
+ updateDisplay(roombaCommTCPClient.getSensorsAsString());
+ } else {
+ updateDisplay("No Roomba. :( Is it turned on?\n");
+ }
+ updateDisplay("buffer is(" + roombaCommTCPClient.getBuffer() + ")",
+ this.debug);
+ // roombaCommTCPClient.setDebug(false);
+ // roombacomm.updateSensors();
+ updateDisplay("connected (" + roombaCommTCPClient.connected() + ")\n");
+ if (roombaCommTCPClient.connected()) {
+ updateDisplay("Playing some notes\n");
+ roombaCommTCPClient.playNote(72, 10); // C
+ roombaCommTCPClient.pause(200);
+ roombaCommTCPClient.playNote(79, 10); // G
+ roombaCommTCPClient.pause(200);
+ roombaCommTCPClient.playNote(76, 10); // E
+ roombaCommTCPClient.pause(200);
+ netButton.setText("disconnect-net");
+ netButton.setActionCommand("disconnect-net");
+ roombaComm = roombaCommTCPClient; // set the pointer so that the
+ // action stuff can work against
+ // any class
+ }
+
+ // roombaCommSerial.setWaitForDSR(handshakeButton.isSelected());
+ //
+ //
+ // connectButton.setText("connecting");
+ // if( ! roombaCommSerial.connect( portname ) ) {
+ // updateDisplay("Couldn't connect to "+portname+"\n");
+ // connectButton.setText(" connect ");
+ // //roombacomm.debug=false;
+ // return false;
+ // }
+ // updateDisplay("Roomba startup\n");
+ //
+ // roombaCommSerial.startup();
+ // roombaCommSerial.control();
+ // roombaCommSerial.playNote( 72, 10 ); // C , test note
+ // roombaCommSerial.pause( 200 );
+ //
+ // connectButton.setText("disconnect");
+ // connectButton.setActionCommand("disconnect");
+ // //roombacomm.debug=true;
+ // updateDisplay("Checking for Roomba... ");
+ // if( roombaCommSerial.updateSensors() )
+ // updateDisplay("Roomba found!\n");
+ // else
+ // updateDisplay("No Roomba. :( Is it turned on?\n");
+
+ return true;
+ }
+
+ /** */
+ public void disconnect() {
+ roombaCommSerial.disconnect();
+ connectButton.setText(" connect ");
+ connectButton.setActionCommand("connect");
+ }
+
+ public void disconnectNet() {
+ roombaCommTCPClient.disconnect();
+ netButton.setText(" net ");
+ netButton.setActionCommand("net");
+ }
+
+ /**
+ * Play a (MIDI) note, that is, make the Roomba a musical instrument
+ * notenums 32-127: notenum == corresponding note played thru beeper
+ * velocity == duration in number of 1/64s of a second (e.g. 64==1second)
+ * notenum 24: notenum == main vacuum velocity == non-zero turns on, zero
+ * turns off notenum 25: blink LEDs, velcoity is color of Power notenum 28 &
+ * 29: spin left & spin right, velocity is speed
+ *
+ */
+ public void playMidiNote(int notenum, int velocity) {
+ updateDisplay("play note: " + notenum + "," + velocity + "\n");
+ if (!roombaCommSerial.connected())
+ return;
+
+ if (notenum >= 31) { // G and above
+ if (velocity == 0)
+ return;
+ if (velocity < 4)
+ velocity = 4; // has problems at lower durations
+ else
+ velocity = velocity / 2;
+ roombaCommSerial.playNote(notenum, velocity);
+ } else if (notenum == 24) { // C
+ roombaCommSerial.vacuum(!(velocity == 0));
+ } else if (notenum == 25) { // C#
+ boolean lon = (velocity != 0);
+ int inten = (lon) ? 255 : 128; // either full bright or half bright
+ roombaCommSerial.setLEDs(lon, lon, lon, lon, lon, lon,
+ velocity * 2, inten);
+ } else if (notenum == 28) { // E
+ if (velocity != 0)
+ roombaCommSerial.spinLeftAt(velocity * 2);
+ else
+ roombaCommSerial.stop();
+ } else if (notenum == 29) { // F
+ if (velocity != 0)
+ roombaCommSerial.spinRightAt(velocity * 2);
+ else
+ roombaCommSerial.stop();
+ }
+ }
+
+ /** implement actionlistener */
+ public void actionPerformed(ActionEvent event) {
+ String action = event.getActionCommand();
+ updateDisplay(formatter.format(new Date()) + ": action (" + action
+ + ") happened\n", this.debug);
+ // roombacomm.setLEDs(false, false, false, false, false, false, 0, 0);
+ if ("comboBoxChanged".equals(action)) {
+// String portname = (String) portChoices.getSelectedItem();
+ int i = protocolChoices.getSelectedIndex();
+ if (roombaComm != null) {
+ roombaComm.setProtocol((i == 0) ? "SCI" : "OI");
+ } else {
+ updateDisplay(
+ formatter.format(new Date())
+ + ": null roombaComm object found in actionPerformed\n",
+ this.debug);
+ }
+ return;
+ }
+ // updateDisplay(action+"\n");
+ if ("net".equals(action)) {
+ if (jTextFieldHost != null && jTextFieldHost.getText() != null && jTextFieldPort != null && jTextFieldPort.getText() != null){
+ if(connectNet(jTextFieldHost.getText()+":"+jTextFieldPort.getText())){
+ // TODO: find a way to hide/disable the other connect tab until the session is disconnected
+// getJTabbedPanelConfig().getComponentAt(1).setVisible(false); // hide the Serial tab while we are connected with a Net port
+ }else{
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(0).setVisible(true); // make sure the net tab is not hidden when we fail to connect
+ }
+
+ }else{
+ updateDisplay("connect (via net) pressed with missing values:");
+ if (jTextFieldHost != null && jTextFieldHost.getText() != null){
+ updateDisplay(" host :"+jTextFieldHost.getText());
+ }else{
+ updateDisplay(" host : MISSING VALUE");
+ }
+ if (jTextFieldPort != null && jTextFieldPort.getText() != null){
+ updateDisplay(" port :"+jTextFieldPort.getText());
+ }else{
+ updateDisplay(" port : MISSING VALUE");
+ }
+ }
+ return;
+ } else if ("disconnect-net".equals(action)) {
+ disconnectNet();
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(1).setVisible(true); // show the serial tab while we disconnect from the net
+ return;
+ }
+ if ("connect".equals(action)) {
+ if (connect()){
+ // TODO: find a way to hide/disable the other connect tab until the session is disconnected
+ }else{
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(0).setEnabled(true); // make sure the net tab is not hidden when we fail to connect
+// getJTabbedPanelConfig().repaint(100);
+ }
+ return;
+ } else if ("disconnect".equals(action)) {
+ disconnect();
+ // TODO: reenable/show the other tab(s)
+// getJTabbedPanelConfig().getComponentAt(0).setEnabled(true); // show the net tab while we disconnect from the serial
+ return;
+ }
+ // stop right here if we're not connected
+ if (roombaComm == null || !roombaComm.connected()) {
+ updateDisplay("not connected!\n");
+ return;
+ }
+
+ if ("stop".equals(action)) {
+ roombaComm.stop();
+ } else if ("forward".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.goForward();
+ } else if ("backward".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.goBackward();
+ } else if ("spinleft".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.spinLeft();
+ } else if ("spinright".equals(action)) {
+ // updateDisplay("Speed is("+roombaComm.getSpeed()+")\n");
+ roombaComm.spinRight();
+ } else if ("turnleft".equals(action)) {
+ roombaComm.turnLeft();
+ } else if ("turnright".equals(action)) {
+ roombaComm.turnRight();
+ } else if ("max".equals(action)) {
+ roombaComm.max();
+ } else if ("dock".equals(action)) {
+ roombaComm.dock();
+ } else if ("test".equals(action)) {
+ LogoA.square(roombaComm, 300);
+ /*
+ * updateDisplay("Playing some notes\n"); roombacomm.playNote( 72,
+ * 10 ); // C roombacomm.pause( 200 ); roombacomm.playNote( 79, 10
+ * ); // G roombacomm.pause( 200 ); roombacomm.playNote( 76, 10 );
+ * // E roombacomm.pause( 200 );
+ *
+ * updateDisplay("Spinning left, then right\n");
+ * roombacomm.spinLeft(); roombacomm.pause(1000);
+ * roombacomm.spinRight(); roombacomm.pause(1000);
+ * roombacomm.stop();
+ *
+ * updateDisplay("Going forward, then backward\n");
+ * roombacomm.goForward(); roombacomm.pause(1000);
+ * roombacomm.goBackward(); roombacomm.pause(1000);
+ * roombacomm.stop();
+ */
+ } else if ("OSU".equals(action)) {
+ updateDisplay("Going to play OSU\n");
+
+ roombaComm.stop();
+ roombaComm.pause(500);
+ // RTTTLPlay rp = new RTTTLPlay();
+ // /dev/cu.KeySerial1
+ // 'tron:d=4,o=5,b=200:8f6,8c6,8g,e,8p,8f6,8c6,8g,8f6,8c6,8g,e,8p,8f6,8c6,8g,e.,2d'
+ // String[]
+ // osuSong={roombacomm.getPortname(),"OSU:d=4,o=5,b=125:a,g,a#,a,8g#,a,8g#,2a,8p,8f,8g,8g#,a,8g#,a,8g#,a,g,f,a,g,8a,g,d,8f,8p,8f,8p,8f,8p,8f,8p,c6,a,g,f,8a#,a,8g,f,p,c6,a,g,a,8a#,a,8a#,c6,p,2d6,d,8c6,a#,g,f,8f,8f,8g,a#,8g,a#,a,2a#"};
+ playSong(
+ roombaComm,
+ "OSU:d=4,o=5,b=125:a,g,a#,a,8g#,a,8g#,2a,8p,8f,8g,8g#,a,8g#,a,8g#,a,g,f,a,g,8a,g,d,8f,8p,8f,8p,8f,8p,8f,8p,c6,a,g,f,8a#,a,8g,f,p,c6,a,g,a,8a#,a,8a#,c6,p,2d6,d,8c6,a#,g,f,8f,8f,8g,a#,8g,a#,a,2a#");
+
+ // playSong(roombacomm,
+ // "Baa Baa Black Sheep:d=4,o=5,b=125:c,c,g,g,8a,8b,8c6,8a,g,p,f,f,e,e,d,d,c");
+ roombaComm.stop();
+ } else if ("Tribble On".equals(action)) {
+ tribbleOn = true;
+ tribbleStart(roombaComm, displayText, tribbleOn);
+ } else if ("reset".equals(action)) {
+ roombaComm.stop();
+ roombaComm.startup();
+ roombaComm.control();
+ } else if ("passive".equals(action)) {
+ //passive / start command
+ roombaComm.start();
+ } else if ("safe".equals(action)) {
+ roombaComm.safe();
+ } else if ("full".equals(action)) {
+ roombaComm.full();
+ } else if ("power-off".equals(action)) {
+ roombaComm.powerOff();
+ } else if ("power-on".equals(action)) {
+ roombaComm.powerOn();
+ } else if ("wakeup".equals(action)) {
+ roombaComm.wakeup();
+ } else if ("beep-lo".equals(action)) {
+ roombaComm.playNote(50, 32); // C1
+ roombaComm.pause(200);
+ } else if ("beep-hi".equals(action)) {
+ roombaComm.playNote(90, 32); // C7
+ roombaComm.pause(200);
+ } else if ("clean".equals(action)) {
+ roombaComm.clean();
+ } else if ("spot".equals(action)) {
+ roombaComm.spot();
+ } else if ("vacuum-on".equals(action)) {
+ roombaComm.vacuum(true);
+ } else if ("vacuum-off".equals(action)) {
+ roombaComm.vacuum(false);
+ } else if ("blink-leds".equals(action)) {
+ roombaComm.setLEDs(true, true, true, true, true, true, 255, 255);
+ roombaComm.pause(300);
+ roombaComm
+ .setLEDs(false, false, false, false, false, false, 0, 128);
+ } else if ("sensors".equals(action)) {
+ if (roombaComm.updateSensors())
+ updateDisplay(roombaComm.sensorsAsString() + "\n");
+ else
+ updateDisplay("couldn't read Roomba. Is it connected?\n");
+ } else if ("chargedata".equals(action)) {
+ if (roombaComm.updateSensors())
+ updateDisplay("*****\n" + roombaComm.chargeDataAsString()
+ + "\n");
+ else
+ updateDisplay("couldn't read Roomba. Is it connected?\n");
+ } else if ("toggleGreen".equals(action)) {
+ setChgGreenLED(roombaComm, !greenOn);
+ } else if ("toggleRed".equals(action)) {
+ setChgRedLED(roombaComm, !redOn);
+ } else if ("toggleSpot".equals(action)) {
+ setChgSpotLED(roombaComm, !toggleSpot);
+ } else if ("toggleClean".equals(action)) {
+ setChgCleanLED(roombaComm, !toggleClean);
+ } else if ("toggleMax".equals(action)) {
+ setChgMaxLED(roombaComm, !toggleMax);
+ } else if ("toggleDirt".equals(action)) {
+ setChgDirtLED(roombaComm, !toggleDirt);
+ } else if ("toggleCheckRobot".equals(action)) {
+ setToggleCheckRobot(roombaComm, !toggleCheckRobot);
+ } else if ("toggleDock".equals(action)) {
+ setToggleDock(roombaComm, !toggleDock);
+ }
+
+ }
+
+ /** implement ChangeListener, for the slider */
+ public void stateChanged(ChangeEvent e) {
+ // System.err.println("stateChanged:"+e);
+ JSlider src = (JSlider) e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ int speed = (int) src.getValue();
+ speed = (speed < 1) ? 1 : speed; // don't allow zero speed
+ updateDisplay("setting speed = " + speed + "\n");
+ roombaComm.setSpeed(speed);
+ }
+ }
+
+ /**
+ *
+ */
+ void makePanels() {
+ System.out.println("makePanels-start");
+ makeSelectPanel();
+ this.add(selectPanel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 2, 2));
+ makeCtrlPanel();
+ makeLedPanel();
+ makeButtonPanel();
+ makeDisplayPanel();
+ this.add(displayPanel, new GridBagConstraints(0, 2, 2, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 2, 2));
+ this.add(getJPanel1(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 2, 2));
+ this.add(getJPanel2(), new GridBagConstraints(1, 0, 1, 2, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 2, 2));
+ this.add(getJPanel3(), new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+
+ // pack(); //setVisible(true);
+ updateDisplay("RoombaComm, version " + RoombaComm.VERSION + "\n");
+ System.out.println("makePanels-finish");
+ }
+ void makeButtonPanel(){
+// jPanel1.add(buttonPanel, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ }
+ void makeSelectPanel() {
+ selectPanel = new JPanel();
+ GridBagLayout selectPanelLayout = new GridBagLayout();
+ selectPanelLayout.rowWeights = new double[] {0.0, 0.0};
+ selectPanelLayout.rowHeights = new int[] {53, 58};
+ selectPanelLayout.columnWeights = new double[] {0.0, 0.0};
+ selectPanelLayout.columnWidths = new int[] {181, 88};
+ selectPanel.setLayout(selectPanelLayout);
+
+ // Create a combo box with protocols
+ String[] protocols = { "Roomba 1xx-4xx (SCI)", "Roomba 5xx (OI)" };
+ protocolChoices = new JComboBox(protocols);
+ String p = roombaCommSerial.getProtocol();
+ protocolChoices.setSelectedIndex(p.equals("SCI") ? 0 : 1);
+
+// // Create a combo box with choices.
+// // String[] ports = roombaCommSerial.listPorts();
+// // for now short cutting looking for serial ports to speed up start/stop of the UI
+// String[] ports = {"a","b"};
+// System.out.println("found "+ports.length+" serialports");
+// // portChoices = new JComboBox(ports);
+ portChoices = new JComboBox();
+// for (int i = 0; i < ports.length; i++) {
+// String s = ports[i];
+// System.out.println("adding ["+i+"] as "+s);
+// portChoices.addItem(ports[i]);
+// if (s.equals(roombaCommSerial.getPortname())) {
+// System.out.println(" setting port as selected due to "+roombaCommSerial.getPortname());
+// portChoices.setSelectedItem(s);
+// }
+// }
+
+ handshakeButton = new JCheckBox("h/w
handshake");
+ // net button
+
+ // Add a border around the select panel.
+ selectPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
+ .createTitledBorder("Select Roomba Type & Port"), BorderFactory
+ .createEmptyBorder(1, 1, 1, 1)));
+ System.out.println("577-setPreferredSize");
+ selectPanel.setPreferredSize(new java.awt.Dimension(535, 128));
+ System.out.println("577-setPreferredSize-done");
+ selectPanel.add(protocolChoices, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 5, 0, 5), 0, 0));
+ protocolChoices.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0), "Protocal", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ protocolChoices.setToolTipText("Set the protocal based on the roomba hardware version");
+// selectPanel.setJMenuBar(getJMenuBar1());
+ selectPanel.add(handshakeButton, new GridBagConstraints(0, 2, 1, 1, 0.1, 0.1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ handshakeButton.setPreferredSize(new java.awt.Dimension(148, 40));
+ handshakeButton.setText("h/w handshake");
+ handshakeButton.setToolTipText("check if you want to use the hardware handshake setting");
+ selectPanel.add(getJTabbedPanelConfig(), new GridBagConstraints(1, 1, 1, 2, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ selectPanel.add(getJTextPane1(), new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 2, 2));
+
+ // Listen to events from the combo box.
+ protocolChoices.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeCtrlPanel() {
+
+ }
+
+ void makeLedPanel() {
+
+ // if (roombaCommSerial.getProtocol().equalsIgnoreCase("SCI")) {
+// String off = "None";
+// String green = "Green";
+// String red = "Red";
+// String both = "Orange";
+
+ // Group the radio buttons.
+// ButtonGroup group = new ButtonGroup();
+ // }
+
+ // powerColorIntensity.addChangeListener(this);
+ // powerColorIntensity.addChangeListener(new ChangeListener() {setPow
+ // });
+
+ } // End make led panel
+
+ /**
+ *
+ */
+ void makeDisplayPanel() {
+ displayPanel = new JPanel();
+ GridBagLayout displayPanelLayout = new GridBagLayout();
+ displayPanelLayout.rowWeights = new double[] {0.1};
+ displayPanelLayout.rowHeights = new int[] {7};
+ displayPanelLayout.columnWeights = new double[] {0.1};
+ displayPanelLayout.columnWidths = new int[] {7};
+ displayPanel.setLayout(displayPanelLayout);
+ displayPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
+ .createTitledBorder("Display"), BorderFactory
+ .createEmptyBorder(1, 1, 1, 1)));
+ displayPanel.setPreferredSize(new java.awt.Dimension(412, 45));
+ {
+ displayText = new JTextArea(10, 75);
+ displayPanel.add(displayText, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ displayText.setLineWrap(false);
+ DefaultCaret caret = (DefaultCaret)displayText.getCaret();
+ caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
+ displayText.setCaret(caret);
+ displayText.setPreferredSize(new java.awt.Dimension(825, 27));
+ displayText.setSize(795, 160);
+
+ }
+
+ JTextArea displayText2 = new JTextArea(25, 30);
+ displayText2.setLineWrap(true);
+ DefaultCaret dc = new DefaultCaret();
+ dc.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
+ // only works on Java 1.5+
+ // dc.setUpdatePolicy( DefaultCaret.ALWAYS_UPDATE );
+ JScrollPane scrollPane = new JScrollPane(displayText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.getVerticalScrollBar();
+ // scrollPane.add(displayText2,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ // JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ displayPanel.add(scrollPane, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ scrollPane.setSize(795, 163);
+ scrollPane.setPreferredSize(new java.awt.Dimension(766, 81));
+ }
+
+ protected void updateDisplay(String s) {
+ System.out.println("updateDisplay(string): start");
+ displayText.append(s);
+ if (s != null && !(s.endsWith("\n"))) {
+ displayText.append("\n");
+ }
+// displayText.setCaretPosition(displayText.getDocument().getLength());
+ System.out.println("updateDisplay(string): reposition to "+displayText.getDocument().getLength());
+ // TODO: need to find a way to auto scroll to the end of the text so the user can just follow along.
+ // currently on my PC. I am not even able to scroll down to the end of the text. sigh...
+ displayText.getParent().validate();
+ displayText.getParent().repaint(100);
+ displayText.setText(displayText.getText() );
+
+//// for (int i = 0; i < 20; i++) {
+//// displayText.append("This is text " + i + "\n");
+// scrollPaneVbar.setValue(scrollPaneVbar.getMaximum());
+// scrollPaneVbar.paint(scrollPaneVbar.getGraphics());
+// displayText.scrollRectToVisible(displayText.getVisibleRect());
+// if (displayText != null && displayText.getGraphics() != null){
+// displayText.paint(displayText.getGraphics());
+// scrollPaneVbar.getParent().getParent().repaint(100);
+//// displayText.repaint(100);
+// System.out.println("displayText calling paint on displayText "); // this should never happen
+// }else{
+// if (displayText != null){
+// System.out.println("displayText is null"); // this should never happen
+// }
+// if (displayText.getGraphics() != null){
+// System.out.println("displayText.getGraphics is null"); // this might happen?
+// }
+// }
+// try {
+// Thread.sleep(250);
+// } catch (InterruptedException ex) {
+//// Logger.getLogger(ScrollTextView.class.getName()).log(Level.SEVERE, null, ex);
+// System.out.println("InterruptedException while trying to update displayText");
+// }
+//// }
+// // displayText.getParent().validate();
+ System.out.println("updateDisplay(string): end");
+ }
+
+ protected void updateDisplay(String s, boolean onlyDebug) {
+ if (onlyDebug && (roombaCommSerial.debug || roombaCommTCPClient.debug)) {
+ updateDisplay(s);
+ System.out.println(s);
+ }
+ }
+
+ protected static void updateDisplay(RoombaComm roombacomm,
+ JTextArea jtextarea, String s, boolean onlyDebug) {
+ if (onlyDebug && roombacomm.debug) {
+ jtextarea.append(s);
+ jtextarea.setCaretPosition(jtextarea.getDocument().getLength());
+ jtextarea.getParent().validate();
+ jtextarea.getParent().repaint(100);
+ System.out.println(s);
+ }
+ }
+
+ /** Returns an ImageIcon, or null if the path was invalid. */
+ protected static ImageIcon createImageIcon(String path, String description) {
+ // yes, this is supposed to say "RoombaCommTest"
+ java.net.URL imgURL = RoombaCommPanel.class.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL, description);
+ } else {
+ System.err.println("Couldn't find file: " + path);
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void playSong(RoombaComm roombacomm, String rtttl) {
+ ArrayList notelist = RTTTLParser.parse(rtttl);
+ int songsize = notelist.size();
+ // if within the size of a roomba song, make the nsong, then play
+ if (songsize <= 16) {
+ updateDisplay("creating a song with createSong()", this.debug);
+ int notearray[] = new int[songsize * 2];
+ int j = 0;
+ for (int i = 0; i < songsize; i++) {
+ Note note = (Note) notelist.get(i);
+ int sec64ths = note.duration * 64 / 1000;
+ notearray[j++] = note.notenum;
+ notearray[j++] = sec64ths;
+ }
+ roombacomm.createSong(1, notearray);
+ roombacomm.playSong(1);
+ }
+ // otherwise, try to play it in realtime
+ else {
+ updateDisplay("playing song in realtime with playNote()\n",
+ this.debug);
+ int fudge = 20;
+ for (int i = 0; i < songsize; i++) {
+ Note note = (Note) notelist.get(i);
+ int duration = note.duration;
+ int sec64ths = duration * 64 / 1000;
+ if (sec64ths < 5)
+ sec64ths = 5;
+ if (note.notenum != 0)
+ roombacomm.playNote(note.notenum, sec64ths);
+ roombacomm.pause(duration + fudge);
+ }
+ }
+ }
+
+ protected static void tribbleStart(RoombaComm roombacomm,
+ JTextArea jtextarea, boolean tribbleOn) {
+ createTribblePurrSong(roombacomm);
+
+ updateDisplay(roombacomm, jtextarea, "Press return to exit.",
+ roombacomm.debug);
+
+ while (tribbleOn) {
+
+ purr(roombacomm, jtextarea);
+
+ if (Math.random() < 0.1)
+ bark(roombacomm, jtextarea);
+
+ roombacomm.pause(1500 + (int) (Math.random() * 500));
+ // tribbleOn = keyIsPressed();
+ roombacomm.updateSensors();
+ boolean b = roombacomm.maxButton();
+ updateDisplay(roombacomm, jtextarea, "max button is (" + b + ")",
+ roombacomm.debug);
+ tribbleOn = (!b);
+ }
+ }
+
+ protected static void purr(RoombaComm roombacomm, JTextArea jtextarea) {
+ updateDisplay(roombacomm, jtextarea, "purr", roombacomm.debug);
+ roombacomm.playSong(5);
+ for (int i = 0; i < 5; i++) {
+ roombacomm.spinLeftAt(75);
+ roombacomm.pause(100);
+ roombacomm.spinRightAt(75);
+ roombacomm.pause(100);
+ roombacomm.stop();
+ }
+ }
+
+ protected static void createTribblePurrSong(RoombaComm roombacomm) {
+ int song[] = { 68, 4, 67, 4, 66, 4, 65, 4, 64, 4, 63, 4, 62, 4, 61, 4,
+ 60, 4, 59, 4, 60, 4, 61, 4, };
+ roombacomm.createSong(5, song);
+ }
+
+ protected static void bark(RoombaComm roombacomm, JTextArea jtextarea) {
+ updateDisplay(roombacomm, jtextarea, "bark", roombacomm.debug);
+ roombacomm.vacuum(true);
+ roombacomm.playNote(50, 5);
+ roombacomm.pause(150);
+ roombacomm.vacuum(false);
+ }
+
+ protected int getPower_color() {
+ return power_color;
+ }
+
+ protected void setPower_color(int power_color) {
+ if (power_color >= 0 && power_color <= 255) {
+ this.power_color = power_color;
+ } else {
+ this.power_color = 0;
+ updateDisplay("invalid power color attempted (" + power_color + ")");
+ }
+ }
+
+ protected int getPower_int() {
+ return power_int;
+ }
+
+ protected void setPower_int(int power_int) {
+
+ if (power_color >= 0 && power_color <= 255) {
+ this.power_int = power_int;
+ } else {
+ this.power_int = 0;
+ updateDisplay("invalid power intensity attempted (" + power_color
+ + ")");
+ }
+ }
+
+ protected void setLEDs(RoombaComm roombacomm) {
+ if (!roombacomm.connected())
+ return;
+ if (roombacomm.getProtocol().equalsIgnoreCase("SCI")) {
+ roombacomm.setLEDs(this.greenOn, this.redOn, this.toggleSpot,
+ this.toggleClean, this.toggleMax, this.toggleDirt,
+ this.power_color, this.power_int);
+ }
+ if (roombacomm.getProtocol().equalsIgnoreCase("OI")) {
+ roombacomm.setLEDsOI(this.toggleCheckRobot, this.toggleSpot,
+ this.toggleDock, this.toggleDirt, this.power_color,
+ this.power_int);
+ }
+ return;
+ }
+
+ protected void setChgGreenLED(RoombaComm roombacomm, boolean green) {
+ this.greenOn = green;
+ updateDisplay("setChgGreenLED", this.debug);
+ this.setLEDs(roombacomm);
+ }
+
+ protected void setChgRedLED(RoombaComm roombacomm, boolean red) {
+ this.redOn = red;
+ updateDisplay("setChgRedLED", this.debug);
+ this.setLEDs(roombacomm);
+ }
+
+ protected void setChgSpotLED(RoombaComm roombacomm, boolean spot) {
+ updateDisplay("setChgSpotLED value(" + spot + ")", this.debug);
+ roombacomm.setChgSpotLED(roombacomm, spot);
+ this.toggleSpot = roombacomm.isToggleSpot();
+ }
+
+ protected void setChgCleanLED(RoombaComm roombacomm, boolean clean) {
+ updateDisplay("setChgCleanLED value(" + clean + ")", this.debug);
+ roombacomm.setChgCleanLED(roombacomm, clean);
+ this.toggleClean = roombacomm.isToggleClean();
+ }
+
+ protected void setChgMaxLED(RoombaComm roombacomm, boolean max) {
+ // updateDisplay("setChgMaxLED",this.debug);
+ // this.toggleMax=max;
+ // this.setLEDs(roombacomm);
+ updateDisplay("setChgMaxLED value(" + max + ")", this.debug);
+ roombacomm.setChgMaxLED(roombacomm, max);
+ this.toggleMax = roombacomm.isToggleMax();
+ }
+
+ protected void setChgDirtLED(RoombaComm roombacomm, boolean dirt) {
+ updateDisplay("setChgDirtLED value(" + dirt + ")", this.debug);
+ roombacomm.setChgDirtLED(roombacomm, dirt);
+ this.toggleDirt = roombacomm.isToggleDirt();
+ }
+
+ public void setToggleCheckRobot(RoombaComm roombacomm, boolean CheckRobot) {
+ updateDisplay("setChgCheckRobotLED value(" + CheckRobot + ")",
+ this.debug);
+ roombacomm.setChgCheckRobotLED(roombacomm, CheckRobot);
+ this.toggleCheckRobot = roombacomm.isToggleCheckRobot();
+ }
+
+ public void setToggleDock(RoombaComm roombacomm, boolean dock) {
+ updateDisplay("setChgDockLED value(" + dock + ")", this.debug);
+ roombacomm.setChgDockLED(roombacomm, dock);
+ this.toggleDock = roombacomm.isToggleDock();
+ }
+
+ protected void setChgPowerColorLED(RoombaComm roombacomm, int power_color) {
+ updateDisplay("setChgPowerColorLED value(" + power_color + ")",
+ this.debug);
+ // this.power_color=power_color;
+ roombacomm.setChgPowerColorLED(roombacomm, power_color);
+ // this.power_color
+ // TODO: Keep track of power color
+ }
+
+ protected void setChgPowerIntensityLED(RoombaComm roombacomm,
+ int power_intensity) {
+ updateDisplay("setChgPowerIntensityLED value(" + power_intensity + ")",
+ this.debug);
+ roombacomm.setChgPowerIntensityLED(roombacomm, power_intensity);
+ // TODO: Keep track of Power Intensity
+ }
+
+ public boolean getToggleCheckRobot() {
+ return toggleCheckRobot;
+ }
+
+ public boolean getToggleDock() {
+ return toggleDock;
+ }
+
+// private JPanel getJPanelMiddle() {
+// if(jPanelMiddle == null) {
+// jPanelMiddle = new JPanel();
+// }
+// return jPanelMiddle;
+// }
+
+ private JTabbedPane getJTabbedPanelConfig() {
+ if(jTabbedPanelConfig == null) {
+ jTabbedPanelConfig = new JTabbedPane();
+ jTabbedPanelConfig.setPreferredSize(new java.awt.Dimension(139, 28));
+ jTabbedPanelConfig.addTab("Net", null, getJPanelConfigNet(), "set the TCP network settings here");
+ jTabbedPanelConfig.addTab("Serial", null, getJPanelConfigSerial(), "set the serial settings here");
+ }
+ jTabbedPanelConfig.setMinimumSize(new Dimension(200,100));
+ jTabbedPanelConfig.setPreferredSize(new java.awt.Dimension(323, 100));
+ jTabbedPanelConfig.setToolTipText("Use one of the two connection methods to communicate with the Roomba");
+ // Register a change listener
+ jTabbedPanelConfig.addChangeListener(new ChangeListener() {
+ // This method is called whenever the selected tab changes
+ public void stateChanged(ChangeEvent evt) {
+ System.out.println("jTabbedPanelConfig - state changed");
+ JTabbedPane pane = (JTabbedPane)evt.getSource();
+ // Get current tab
+ int sel = pane.getSelectedIndex();
+ System.out.println("jTabbedPanelConfig - tab "+sel+" selected");
+ System.out.println("jTabbedPanelConfig - roombaCommSerial.isConnected() "+roombaCommSerial.isConnected());
+ System.out.println("jTabbedPanelConfig - roombaCommTCPClient.isConnected() "+roombaCommTCPClient.isConnected());
+ if (roombaCommTCPClient.isConnected() && roombaCommSerial.isConnected()){
+ System.out.println("***** I have no idea why both should ever be connected at the same time... THIS IS STRANGE *****");
+ }
+ if (sel == 1){
+ setCommPorts();
+ if (roombaCommTCPClient.isConnected() && !roombaCommSerial.isConnected()){
+ pane.setSelectedIndex(0);
+ System.out.println("active net connection found setting focus to the correct tab");
+ }
+ }
+ if (sel == 0){
+ if (!roombaCommTCPClient.isConnected() && roombaCommSerial.isConnected()){
+ pane.setSelectedIndex(1);
+ System.out.println("active Serial connection found setting focus to the correct tab");
+ }
+ }
+ }
+ });
+
+ return jTabbedPanelConfig;
+ }
+
+ private JPanel getJPanelConfigNet() {
+ if(jPanelConfigNet == null) {
+ jPanelConfigNet = new JPanel();
+ GridBagLayout jPanelConfigNetLayout = new GridBagLayout();
+ jPanelConfigNetLayout.rowWeights = new double[] {0.0, 0.1};
+ jPanelConfigNetLayout.rowHeights = new int[] {26, 7};
+ jPanelConfigNetLayout.columnWeights = new double[] {0.1, 0.1, 0.1};
+ jPanelConfigNetLayout.columnWidths = new int[] {7, 7, 7};
+ jPanelConfigNet.setLayout(jPanelConfigNetLayout);
+ jPanelConfigNet.setPreferredSize(new java.awt.Dimension(318, 72));
+ jPanelConfigNet.add(getJLabelHost(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigNet.add(getJTextFieldHost(), new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigNet.add(getJLabelPort(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigNet.add(getJTextFieldPort(), new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ netButton = new JButton();
+ jPanelConfigNet.add(netButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ netButton.setText("connect");
+ netButton.setActionCommand("net");
+ netButton.addActionListener(this);
+ }
+ }
+ return jPanelConfigNet;
+ }
+
+ private JPanel getJPanelConfigSerial() {
+ if(jPanelConfigSerial == null) {
+ jPanelConfigSerial = new JPanel();
+ GridBagLayout jPanelConfigSerialLayout = new GridBagLayout();
+ jPanelConfigSerial.setPreferredSize(new java.awt.Dimension(318, 72));
+ jPanelConfigSerialLayout.rowWeights = new double[] {0.1};
+ jPanelConfigSerialLayout.rowHeights = new int[] {7};
+ jPanelConfigSerialLayout.columnWeights = new double[] {0.1, 0.1, 0.1};
+ jPanelConfigSerialLayout.columnWidths = new int[] {7, 7, 7};
+ jPanelConfigSerial.setLayout(jPanelConfigSerialLayout);
+ jPanelConfigSerial.addFocusListener(new FocusAdapter() {
+ public void focusGained(FocusEvent evt) {
+ jPanelConfigSerialFocusGained(evt);
+ }
+ });
+ {
+ portChoices = new JComboBox();
+ jPanelConfigSerial.add(portChoices, new GridBagConstraints(1, -1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ portChoices.validate();
+ portChoices.repaint();
+ portChoices.addActionListener(this);
+ }
+ {
+ connectButton = new JButton();
+ jPanelConfigSerial.add(connectButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jPanelConfigSerial.add(getJLabelCOMM(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0));
+ connectButton.setText(" connect ");
+ connectButton.setActionCommand("connect");
+ connectButton.addActionListener(this);
+ }
+ }
+ return jPanelConfigSerial;
+ }
+
+ private JLabel getJLabelHost() {
+ if(jLabelHost == null) {
+ jLabelHost = new JLabel();
+ jLabelHost.setLayout(null);
+ jLabelHost.setText("Host");
+ jLabelHost.setPreferredSize(new java.awt.Dimension(39, 17));
+ jLabelHost.setLabelFor(getJTextFieldHost());
+ jLabelHost.setToolTipText("Set the hostname/IP address");
+ }
+ return jLabelHost;
+ }
+
+ private JTextField getJTextFieldHost() {
+ if(jTextFieldHost == null) {
+ jTextFieldHost = new JTextField();
+ jTextFieldHost.setText("192.168.15.240");
+ jTextFieldHost.setToolTipText("Set the hostname/IP address");
+ }
+ return jTextFieldHost;
+ }
+
+ private JPanel getJPanel1() {
+ if(jPanel1 == null) {
+ jPanel1 = new JPanel();
+ GridBagLayout jPanel1Layout = new GridBagLayout();
+ jPanel1Layout.rowWeights = new double[] {0.1};
+ jPanel1Layout.rowHeights = new int[] {7};
+ jPanel1Layout.columnWeights = new double[] {0.1, 0.1};
+ jPanel1Layout.columnWidths = new int[] {7, 7};
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1.setPreferredSize(new java.awt.Dimension(800, 320));
+ {
+ ledPanel = new JPanel();
+ GridBagLayout ledPanelLayout = new GridBagLayout();
+ ledPanel.setLayout(ledPanelLayout);
+ jPanel1.add(ledPanel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ JPanel ledPanel1 = new JPanel(new GridLayout(3, 3));
+ ledPanel.add(ledPanel1, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ ButtonGroup group = new ButtonGroup();
+ String off="None";
+ String green="Green";
+ String red="Red";
+ String both="Orange";
+ {
+ JRadioButton statusOffButton = new JRadioButton(off);
+ ledPanel1.add(statusOffButton);
+ statusOffButton.setMnemonic(KeyEvent.VK_N);
+ statusOffButton.setActionCommand("StatusLED-" + off);
+ statusOffButton.setSelected(true);
+ group.add(statusOffButton);
+ statusOffButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, false);
+ setChgRedLED(roombaCommSerial, false);
+ }
+ });
+ }
+ {
+ JRadioButton statusGreenButton = new JRadioButton(green);
+ ledPanel1.add(statusGreenButton);
+ statusGreenButton.setMnemonic(KeyEvent.VK_G);
+ statusGreenButton.setActionCommand("StatusLED-" + green);
+ group.add(statusGreenButton);
+ statusGreenButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, true);
+ setChgRedLED(roombaCommSerial, false);
+ }
+ });
+ }
+ {
+ JRadioButton statusRedButton = new JRadioButton(red);
+ ledPanel1.add(statusRedButton);
+ statusRedButton.setMnemonic(KeyEvent.VK_R);
+ statusRedButton.setActionCommand("StatusLED-" + red);
+ group.add(statusRedButton);
+ statusRedButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, false);
+ setChgRedLED(roombaCommSerial, true);
+ }
+ });
+ }
+ {
+ JRadioButton statusBothButton = new JRadioButton(both);
+ ledPanel1.add(statusBothButton);
+ statusBothButton.setMnemonic(KeyEvent.VK_O);
+ statusBothButton.setActionCommand("StatusLED-" + both);
+ group.add(statusBothButton);
+ statusBothButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDisplay("setting Power Color = " + e.getActionCommand()
+ + "\n");
+ setChgGreenLED(roombaCommSerial, true);
+ setChgRedLED(roombaCommSerial, true);
+ }
+ });
+ }
+ {
+ JButton but_toggleSpot = new JButton();
+ ledPanel1.add(but_toggleSpot);
+ but_toggleSpot.setActionCommand("toggleSpot");
+ but_toggleSpot.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_spotOn.png")));
+ but_toggleSpot.setPreferredSize(new java.awt.Dimension(46, 50));
+ but_toggleSpot.setSize(40, 40);
+ but_toggleSpot.addActionListener(this);
+ }
+ {
+ JButton but_toggleClean = new JButton();
+ ledPanel1.add(but_toggleClean);
+ but_toggleClean.setActionCommand("toggleClean");
+ but_toggleClean.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_cleanOn.png")));
+ but_toggleClean.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleClean.setSize(40, 40);
+ but_toggleClean.addActionListener(this);
+ }
+ {
+ JButton but_toggleDirt = new JButton();
+ ledPanel1.add(but_toggleDirt);
+ but_toggleDirt.setActionCommand("toggleDirt");
+ but_toggleDirt.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_dirtOn.png")));
+ but_toggleDirt.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleDirt.setSize(40, 40);
+ but_toggleDirt.addActionListener(this);
+ }
+ {
+ JButton but_toggleMax = new JButton();
+ ledPanel1.add(but_toggleMax);
+ but_toggleMax.setActionCommand("toggleMax");
+ but_toggleMax.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_maxOn.png")));
+ but_toggleMax.setSize(40, 40);
+ but_toggleMax.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleMax.addActionListener(this);
+ }
+ {
+ JButton but_toggleDock = new JButton();
+ ledPanel1.add(but_toggleDock);
+ but_toggleDock.setActionCommand("toggleDock");
+ but_toggleDock.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_dockOn.png")));
+ but_toggleDock.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleDock.setSize(40, 40);
+ but_toggleDock.addActionListener(this);
+ }
+ {
+ JButton but_toggleCheckRobot = new JButton();
+ ledPanel1.add(but_toggleCheckRobot);
+ but_toggleCheckRobot.setActionCommand("toggleCheckRobot");
+ but_toggleCheckRobot.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_checkrobotOn.png")));
+ but_toggleCheckRobot.setPreferredSize(new java.awt.Dimension(40, 40));
+ but_toggleCheckRobot.setSize(40, 40);
+ but_toggleCheckRobot.addActionListener(this);
+ }
+ }
+ {
+ powerColorSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 100);
+ ledPanel.add(powerColorSlider, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 2, 2));
+ powerColorSlider.setPaintTicks(true);
+ powerColorSlider.setMajorTickSpacing(100);
+ powerColorSlider.setMinorTickSpacing(25);
+ powerColorSlider.setPaintLabels(true);
+ powerColorSlider.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ JSlider src = (JSlider) e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ setPower_color((int) src.getValue());
+ updateDisplay("setting Power Color = " + getPower_color()
+ + "\n");
+ setLEDs(roombaCommSerial);
+ }
+ }
+ });
+ }
+ {
+ JLabel powerColorLabel = new JLabel("PowerColor", JLabel.CENTER);
+ ledPanel.add(powerColorLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 2, 2));
+ }
+ {
+ powerColorIntensity = new JSlider(JSlider.HORIZONTAL, 0, 255, 100);
+ ledPanel.add(powerColorIntensity, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 2, 2));
+ powerColorIntensity.setPaintTicks(true);
+ powerColorIntensity.setMajorTickSpacing(100);
+ powerColorIntensity.setMinorTickSpacing(25);
+ powerColorIntensity.setPaintLabels(true);
+ powerColorIntensity.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ // System.err.println("stateChanged:"+e);
+ JSlider src = (JSlider) e.getSource();
+ if (!src.getValueIsAdjusting()) {
+ setPower_int((int) src.getValue());
+ updateDisplay("setting Power Color Intensity = "
+ + getPower_int() + "\n");
+ setLEDs(roombaCommSerial);
+ }
+ }
+ });
+ }
+ {
+ JLabel powerColorIntensityLabel = new JLabel("PowerColorIntensity",
+ JLabel.CENTER);
+ ledPanel.add(powerColorIntensityLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 2, 2));
+ }
+ ledPanelLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1};
+ ledPanelLayout.rowHeights = new int[] {7, 7, 7, 7, 7};
+ ledPanelLayout.columnWeights = new double[] {0.1};
+ ledPanelLayout.columnWidths = new int[] {7};
+ ledPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("LEDs"),BorderFactory.createEmptyBorder(5,5,5,5)));
+ ledPanel.setPreferredSize(new java.awt.Dimension(288, 313));
+ }
+
+ {
+ ctrlPanel = new JPanel();
+ jPanel1.add(ctrlPanel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+ {
+ JPanel ctrlPanel1 = new JPanel();
+ ctrlPanel.add(ctrlPanel1);
+ {
+ JButton but_turnleft = new JButton();
+ ctrlPanel1.add(but_turnleft);
+ but_turnleft.setActionCommand("turnleft");
+ but_turnleft.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_turnleft.png")));
+ but_turnleft.addActionListener(this);
+ }
+ {
+ JButton but_forward = new JButton();
+ ctrlPanel1.add(but_forward);
+ but_forward.setActionCommand("forward");
+ but_forward.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_forward.png")));
+ but_forward.addActionListener(this);
+ }
+ {
+ JButton but_turnright = new JButton();
+ ctrlPanel1.add(but_turnright);
+ but_turnright.setActionCommand("turnright");
+ but_turnright.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_turnright.png")));
+ but_turnright.addActionListener(this);
+ }
+ {
+ JButton but_spinleft = new JButton();
+ ctrlPanel1.add(but_spinleft);
+ but_spinleft.setActionCommand("spinleft");
+ but_spinleft.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_spinleft.png")));
+ but_spinleft.addActionListener(this);
+ }
+ {
+ JButton but_stop = new JButton();
+ ctrlPanel1.add(but_stop);
+ but_stop.setActionCommand("stop");
+ but_stop.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_stop.png")));
+ but_stop.addActionListener(this);
+ }
+ {
+ JButton but_spinright = new JButton();
+ ctrlPanel1.add(but_spinright);
+ but_spinright.setActionCommand("spinright");
+ but_spinright.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_spinright.png")));
+ but_spinright.addActionListener(this);
+ }
+ {
+ ctrlPanel1.add(new JLabel());
+ }
+ {
+ JButton but_backward = new JButton();
+ ctrlPanel1.add(but_backward);
+ but_backward.setActionCommand("backward");
+ but_backward.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/hackingroomba/roombacomm/images/but_backward.png")));
+ but_backward.setPreferredSize(new java.awt.Dimension(55, 78));
+ but_backward.addActionListener(this);
+ }
+ {
+ ctrlPanel1.add(new JLabel());
+ }
+ ctrlPanel1.setLayout(new GridLayout(3, 3));
+ ctrlPanel1.setPreferredSize(new java.awt.Dimension(194, 199));
+ ctrlPanel1.setSize(194, 199);
+// ctrlPanel1.setTabTitle("");
+ }
+ {
+ speedSlider = new JSlider(JSlider.HORIZONTAL, 0, 500, 200);
+ ctrlPanel.add(speedSlider);
+ speedSlider.setPaintTicks(true);
+ speedSlider.setMajorTickSpacing(100);
+ speedSlider.setMinorTickSpacing(25);
+ speedSlider.setPaintLabels(true);
+ speedSlider.addChangeListener(this);
+ }
+ {
+ JLabel sliderLabel = new JLabel();
+ ctrlPanel.add(sliderLabel);
+ sliderLabel.setText("speed (mm/s)");
+ sliderLabel.setAlignmentX(JLabel.CENTER);
+ }
+ ctrlPanel.setLayout(new BoxLayout(ctrlPanel, BoxLayout.Y_AXIS));
+ ctrlPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Movement"),BorderFactory.createEmptyBorder(5,5,5,5)));
+ }
+ }
+ return jPanel1;
+ }
+
+ private JLabel getJLabelPort() {
+ if(jLabelPort == null) {
+ jLabelPort = new JLabel();
+ jLabelPort.setText("Port");
+ jLabelPort.setPreferredSize(new java.awt.Dimension(39, 33));
+ jLabelPort.setLabelFor(getJTextFieldPort());
+ jLabelPort.setToolTipText("Set the TCP port");
+ }
+ return jLabelPort;
+ }
+
+ private JTextField getJTextFieldPort() {
+ if(jTextFieldPort == null) {
+ jTextFieldPort = new JTextField();
+ jTextFieldPort.setToolTipText("Set the TCP port");
+ jTextFieldPort.setText("5001");
+ }
+ return jTextFieldPort;
+ }
+
+ private void jPanelConfigSerialFocusGained(FocusEvent evt) {
+ System.out.println("jPanelConfigSerial.focusGained, event="+evt);
+ //TODO add your code for jPanelConfigSerial.focusGained
+ // make sure we have a roombaCommSerial object
+ setCommPorts();
+ }
+
+ /**
+ *
+ */
+ private void setCommPorts() {
+ System.out.println("setCommPorts-start");
+ if (roombaCommSerial == null){
+ System.out.println("setCommPorts-roombaCommSerial is null");
+ roombaCommSerial = new RoombaCommSerial(this.debug);
+ }
+ if (portChoices != null) {
+ System.out.println("setCommPorts-portChoices object is not null");
+ // if the list of ports is empty then try to fill it
+ if (portChoices.getItemCount() ==0){
+ // fill in the comm ports (combo box) with choices.
+ System.out.println("setCommPorts-getting list of ports");
+ String[] ports = roombaCommSerial.listPorts();
+ // for now short cutting looking for serial ports to speed up start/stop of the UI
+ // String[] ports = {"a","b"};
+ System.out.println("setCommPorts-found "+ports.length+" serialports");
+ for (int i = 0; i < ports.length; i++) {
+ String s = ports[i];
+ System.out.println("setCommPorts-adding ["+i+"] as "+s);
+ portChoices.addItem(ports[i]);
+ if (s.equals(roombaCommSerial.getPortname())) {
+ System.out.println("setCommPorts- setting port as selected due to "+roombaCommSerial.getPortname());
+ portChoices.setSelectedItem(s);
+ }
+ }
+ portChoices.validate();
+ portChoices.repaint();
+ }
+ }
+ System.out.println("setCommPorts-start");
+ }
+
+ private JLabel getJLabelCOMM() {
+ if(jLabelCOMM == null) {
+ jLabelCOMM = new JLabel();
+ jLabelCOMM.setText("COM");
+ }
+ return jLabelCOMM;
+ }
+
+ private JPanel getJPanel2() {
+ if(jPanel2 == null) {
+ jPanel2 = new JPanel();
+ GridBagLayout jPanel2Layout = new GridBagLayout();
+ jPanel2Layout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
+ jPanel2Layout.rowHeights = new int[] {7, 7, 7, 7, 7, 7};
+ jPanel2Layout.columnWeights = new double[] {0.0};
+ jPanel2Layout.columnWidths = new int[] {150};
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2.setBorder(BorderFactory.createTitledBorder(null, "Commands", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ jPanel2.setPreferredSize(new java.awt.Dimension(233, 505));
+ jPanel2.add(getJPanelModes(), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelSounds(), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelTestPrograms(), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelVacuum(), new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanelPower(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ jPanel2.add(getJPanel4(), new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
+ }
+ return jPanel2;
+ }
+
+ private JPanel getJPanel3() {
+ if(jPanel3 == null) {
+ jPanel3 = new JPanel();
+ jPanel3.setVisible(false);
+ GridBagLayout jPanel3Layout = new GridBagLayout();
+ jPanel3Layout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
+ jPanel3Layout.rowHeights = new int[] {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+ jPanel3Layout.columnWeights = new double[] {0.1};
+ jPanel3Layout.columnWidths = new int[] {7};
+ jPanel3.setLayout(jPanel3Layout);
+ {
+ JButton but_nyi = new JButton();
+ jPanel3.add(but_nyi, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi.setText("nyi");
+ but_nyi.setVisible(false);
+ }
+ {
+ JButton but_nyi2 = new JButton();
+ jPanel3.add(but_nyi2, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi2.setText("nyi2");
+ but_nyi2.setVisible(false);
+ }
+ {
+ JButton but_nyi3 = new JButton();
+ jPanel3.add(but_nyi3, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi3.setText("nyi3");
+ but_nyi3.setVisible(false);
+ }
+ {
+ JButton but_nyi4 = new JButton();
+ jPanel3.add(but_nyi4, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi4.setText("nyi4");
+ but_nyi4.setVisible(false);
+ }
+ {
+ JButton but_nyi5 = new JButton();
+ jPanel3.add(but_nyi5, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi5.setText("nyi5");
+ but_nyi5.setVisible(false);
+ }
+ {
+ JButton but_nyi6 = new JButton();
+ jPanel3.add(but_nyi6, new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi6.setText("nyi6");
+ but_nyi6.setVisible(false);
+ }
+ {
+ JButton but_nyi7 = new JButton();
+ jPanel3.add(but_nyi7, new GridBagConstraints(0, 8, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ but_nyi7.setText("nyi7");
+ but_nyi7.setVisible(false);
+ }
+ {
+ jButton2 = new JButton();
+ jPanel3.add(jButton2, new GridBagConstraints(0, 9, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton2.setText("nyi5");
+ jButton2.setVisible(false);
+ }
+ {
+ jButton1 = new JButton();
+ jPanel3.add(jButton1, new GridBagConstraints(0, 10, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton1.setText("nyi6");
+ jButton1.setVisible(false);
+ }
+ {
+ jButton3 = new JButton();
+ jPanel3.add(jButton3, new GridBagConstraints(0, 11, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton3.setText("nyi3");
+ jButton3.setVisible(false);
+ }
+ {
+ jButton4 = new JButton();
+ jPanel3.add(jButton4, new GridBagConstraints(0, 12, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ jButton4.setText("nyi2");
+ jButton4.setVisible(false);
+ }
+ }
+ return jPanel3;
+ }
+
+ private JPanel getJPanelModes() {
+ if(jPanelModes == null) {
+ jPanelModes = new JPanel();
+ GridBagLayout jPanelModesLayout = new GridBagLayout();
+ jPanelModesLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1};
+ jPanelModesLayout.rowHeights = new int[] {7, 7, 7, 7, 7};
+ jPanelModesLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelModesLayout.columnWidths = new int[] {95, 95};
+ jPanelModes.setLayout(jPanelModesLayout);
+ jPanelModes.setBorder(BorderFactory.createTitledBorder("Modes"));
+ {
+ JButton but_spot = new JButton();
+ jPanelModes.add(but_spot, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_spot.setText("spot");
+ but_spot.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_spot.addActionListener(this);
+ }
+ {
+ JButton but_full = new JButton();
+ jPanelModes.add(but_full, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_full.setText("full");
+ but_full.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_full.addActionListener(this);
+ }
+ {
+ JButton but_safe = new JButton();
+ jPanelModes.add(but_safe, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_safe.setText("safe");
+ but_safe.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_safe.addActionListener(this);
+ }
+ {
+ JButton but_dock = new JButton();
+ jPanelModes.add(but_dock, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_dock.setText("dock");
+ but_dock.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_dock.addActionListener(this);
+ }
+ {
+ JButton but_max = new JButton();
+ jPanelModes.add(but_max, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_max.setText("max");
+ but_max.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_max.addActionListener(this);
+ }
+ {
+ JButton but_clean = new JButton();
+ jPanelModes.add(but_clean, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_clean.setText("clean");
+ but_clean.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_clean.addActionListener(this);
+ }
+ {
+ JButton but_wakeup = new JButton();
+ jPanelModes.add(but_wakeup, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_wakeup.setText("wakeup");
+ but_wakeup.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_wakeup.addActionListener(this);
+ }
+ {
+ JButton but_reset = new JButton();
+ jPanelModes.add(but_reset, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_reset.setText("reset");
+ but_reset.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_reset.addActionListener(this);
+ }
+ {
+ JButton but_passive = new JButton();
+ jPanelModes.add(but_passive, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_passive.setText("passive");
+ but_passive.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_passive.addActionListener(this);
+ }
+ }
+ return jPanelModes;
+ }
+
+ private JPanel getJPanelSounds() {
+ if(jPanelSounds == null) {
+ jPanelSounds = new JPanel();
+ GridBagLayout jPanelSoundsLayout = new GridBagLayout();
+ jPanelSoundsLayout.rowWeights = new double[] {0.1, 0.1};
+ jPanelSoundsLayout.rowHeights = new int[] {7, 7};
+ jPanelSoundsLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelSoundsLayout.columnWidths = new int[] {95, 95};
+ jPanelSounds.setLayout(jPanelSoundsLayout);
+ jPanelSounds.setBorder(BorderFactory.createTitledBorder("Sounds"));
+ {
+ JButton but_OSU = new JButton();
+ jPanelSounds.add(but_OSU, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_OSU.setText("OSU");
+ but_OSU.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_OSU.addActionListener(this);
+ }
+ {
+ JButton but_beeplo = new JButton();
+ jPanelSounds.add(but_beeplo, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_beeplo.setText("beep-lo");
+ but_beeplo.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_beeplo.addActionListener(this);
+ }
+ {
+ JButton but_beephi = new JButton();
+ jPanelSounds.add(but_beephi, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_beephi.setText("beep-hi");
+ but_beephi.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_beephi.addActionListener(this);
+ }
+ }
+ return jPanelSounds;
+ }
+
+ private JPanel getJPanelTestPrograms() {
+ if(jPanelTestPrograms == null) {
+ jPanelTestPrograms = new JPanel();
+ GridBagLayout jPanelTestProgramsLayout = new GridBagLayout();
+ jPanelTestProgramsLayout.rowWeights = new double[] {0.1};
+ jPanelTestProgramsLayout.rowHeights = new int[] {7};
+ jPanelTestProgramsLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelTestProgramsLayout.columnWidths = new int[] {95, 95};
+ jPanelTestPrograms.setLayout(jPanelTestProgramsLayout);
+ jPanelTestPrograms.setBorder(BorderFactory.createTitledBorder("Test Programs"));
+ {
+ JButton but_TribbleOn = new JButton();
+ jPanelTestPrograms.add(but_TribbleOn, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_TribbleOn.setText("Tribble On");
+ but_TribbleOn.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_TribbleOn.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_TribbleOn.setSize(93, 26);
+ but_TribbleOn.addActionListener(this);
+ }
+ {
+ JButton but_test = new JButton();
+ jPanelTestPrograms.add(but_test, new GridBagConstraints(1, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_test.setText("LogoA.square");
+ but_test.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_test.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_test.setSize(93, 26);
+ but_test.addActionListener(this);
+ }
+ }
+ return jPanelTestPrograms;
+ }
+
+ private JPanel getJPanel4() {
+ if(jPanelSensors == null) {
+ jPanelSensors = new JPanel();
+ GridBagLayout jPanelSensorsLayout = new GridBagLayout();
+ jPanelSensorsLayout.rowWeights = new double[] {0.1};
+ jPanelSensorsLayout.rowHeights = new int[] {7};
+ jPanelSensorsLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelSensorsLayout.columnWidths = new int[] {95, 95};
+ jPanelSensors.setLayout(jPanelSensorsLayout);
+ jPanelSensors.setBorder(BorderFactory.createTitledBorder(null, "Sensors", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ {
+ JButton but_chargedata = new JButton();
+ jPanelSensors.add(but_chargedata, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
+ but_chargedata.setText("chargedata");
+ but_chargedata.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_chargedata.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_chargedata.setSize(93, 26);
+ but_chargedata.addActionListener(this);
+ }
+ {
+ JButton but_sensors = new JButton();
+ jPanelSensors.add(but_sensors, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
+ but_sensors.setText("sensors");
+ but_sensors.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_sensors.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_sensors.setSize(93, 26);
+ but_sensors.addActionListener(this);
+ }
+ }
+ return jPanelSensors;
+ }
+
+ private JPanel getJPanelVacuum() {
+ if(jPanelVacuum == null) {
+ jPanelVacuum = new JPanel();
+ GridBagLayout jPanelVacuumLayout = new GridBagLayout();
+ jPanelVacuumLayout.rowWeights = new double[] {0.1};
+ jPanelVacuumLayout.rowHeights = new int[] {7};
+ jPanelVacuumLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelVacuumLayout.columnWidths = new int[] {95, 95};
+ jPanelVacuum.setLayout(jPanelVacuumLayout);
+ jPanelVacuum.setBorder(BorderFactory.createTitledBorder(BorderFactory.createTitledBorder(""), "Vacuum", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ {
+ JButton but_vacon = new JButton();
+ jPanelVacuum.add(but_vacon, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_vacon.setText("vacuum-on");
+ but_vacon.setSize(93, 26);
+ but_vacon.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_vacon.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_vacon.addActionListener(this);
+ }
+ {
+ JButton but_vacoff = new JButton();
+ but_vacoff.setLayout(null);
+ jPanelVacuum.add(but_vacoff, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_vacoff.setText("vacuum-off");
+ but_vacoff.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_vacoff.setPreferredSize(new java.awt.Dimension(93, 26));
+ but_vacoff.setSize(93, 26);
+ but_vacoff.addActionListener(this);
+ }
+ }
+ return jPanelVacuum;
+ }
+
+ private JPanel getJPanelPower() {
+ if(jPanelPower == null) {
+ jPanelPower = new JPanel();
+ GridBagLayout jPanelPowerLayout = new GridBagLayout();
+ jPanelPower.setBorder(BorderFactory.createTitledBorder(null, "Power", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION));
+ jPanelPowerLayout.rowWeights = new double[] {0.1};
+ jPanelPowerLayout.rowHeights = new int[] {7};
+ jPanelPowerLayout.columnWeights = new double[] {0.1, 0.1};
+ jPanelPowerLayout.columnWidths = new int[] {95, 95};
+ jPanelPower.setLayout(jPanelPowerLayout);
+ {
+ JButton but_powerOn = new JButton();
+ jPanelPower.add(but_powerOn, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_powerOn.setText("power-on");
+ but_powerOn.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_powerOn.addActionListener(this);
+ }
+ {
+ JButton but_power = new JButton();
+ jPanelPower.add(but_power, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
+ but_power.setText("power-off");
+ but_power.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ but_power.addActionListener(this);
+ }
+ }
+ return jPanelPower;
+ }
+
+ private JTextPane getJTextPane1() {
+ if(jTextPane1 == null) {
+ jTextPane1 = new JTextPane();
+ jTextPane1.setText("Set the Protocal, then connect via a network or Serial connection.\nThen you can use the Commands, LED's, and/or Movement controls to operate your Roomba.");
+ jTextPane1.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ jTextPane1.setOpaque(false);
+ }
+ return jTextPane1;
+ }
+
+}
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommSerial.java b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommSerial.java
new file mode 100644
index 0000000..c768baf
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/RoombaCommSerial.java
@@ -0,0 +1,505 @@
+/*
+ * RoombaComm Serial Interface
+ *
+ * Copyright (c) 2006 Tod E. Kurt, tod@todbot.com, ThingM
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+package com.hackingroomba.roombacomm;
+
+import gnu.io.*;
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * The serial-port based implementation of RoombaComm.
+ * Handles both physical RS-232 ports, USB adapter ports like Keyspan
+ * USA-19HS, and Bluetooth serial port profiles.
+ *
+ *
"+
+ " Roomba Movement Keyboard Shortcuts
"+
+ ""+
+ "
"+
+ " Application Control Keyboard Shortcuts
"+
+ ""+
+ "
"+
+ "";
+
+ JPanel contentPane;
+ JPanel recordPanel;
+ JTabbedPane tabbedPane;
+ JButton stopButton,recordButton,playButton;
+ JCheckBox loopButton;
+ JCheckBox playAllButton;
+ JFileChooser fc;
+ File file;
+ boolean hwhandshake = false;
+ int maxRoombas = 16;
+ int lastTab = 0;
+ HashMap clipboard;
+ RoombaRecorderPanel rrpanel; // just to make some of code lines shorter
+ boolean movingForward = false; // is roomba moving forward or not
+ boolean vacuuming = false; // is roomba vacuuming or not
+ int turnval = 0;
+
+ public static void main(String[] args) {
+ new RoombaRecorder(args);
+ }
+
+ public RoombaRecorder(String[] args) {
+ super("RoombaRecorder");
+ addWindowListener(this);
+
+ for(int i=0; i < args.length; i++) {
+ if(args[i].endsWith("hwhandshake"))
+ hwhandshake = true;
+ }
+
+ clipboard = new HashMap();
+ fc = new JFileChooser();
+
+ setResizable(false);
+
+ makeMenu();
+
+ makeRecordPanel();
+
+ // Create and set up the content pane.
+ tabbedPane = new JTabbedPane();
+ tabbedPane.setOpaque(true); //content panes must be opaque
+ openNewTab();
+
+ contentPane = new JPanel(new BorderLayout());
+
+ contentPane.add(recordPanel, BorderLayout.NORTH);
+ contentPane.add(tabbedPane, BorderLayout.CENTER);
+
+ //Container content = getContentPane();
+ setContentPane(contentPane);
+
+ addBindings();
+ bindKeys();
+
+ // Display the window.
+ pack(); //setSize(400, 400);
+ setVisible(true);
+
+ //setFocusableWindowState(false); // prevent focus
+ }
+
+ void makeMenu() {
+ JMenuBar menubar = new JMenuBar();
+ JMenuItem item;
+
+ JMenu file = new JMenu("File");
+ JMenu edit = new JMenu("Edit");
+ JMenu help = new JMenu("Help");
+
+ file.setMnemonic(KeyEvent.VK_F);
+ edit.setMnemonic(KeyEvent.VK_E);
+ help.setMnemonic(KeyEvent.VK_H);
+
+ item = new JMenuItem("New Tab");
+ item.addActionListener(this);
+ file.add(item);
+ item = new JMenuItem("Close Tab");
+ item.addActionListener(this);
+ file.add(item);
+ item = new JMenuItem("Open Set");
+ item.addActionListener(this);
+ file.add(item);
+ item = new JMenuItem("Save Set");
+ item.addActionListener(this);
+ file.add(item);
+ item = new JMenuItem("Quit");
+ item.addActionListener(this);
+ file.add(item);
+
+ item = new JMenuItem("Cut");
+ item.addActionListener(this);
+ edit.add(item);
+ item = new JMenuItem("Copy");
+ item.addActionListener(this);
+ edit.add(item);
+ item = new JMenuItem("Paste");
+ item.addActionListener(this);
+ edit.add(item);
+
+ item = new JMenuItem("Help");
+ item.addActionListener(this);
+ help.add(item);
+
+ menubar.add(file);
+ menubar.add(edit);
+ menubar.add(help);
+
+ setJMenuBar(menubar);
+ }
+
+ void makeRecordPanel() {
+ recordPanel = new JPanel();
+ recordPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Action Record"), BorderFactory.createEmptyBorder())); //1,1,1,1)));
+ stopButton = new JButton(createImageIcon("images/but_transport_stop.png","stop"));
+ stopButton.setActionCommand("stop");
+ stopButton.addActionListener(this);
+ recordPanel.add(stopButton);
+ playButton = new JButton(createImageIcon("images/but_transport_play.png","play"));
+ playButton.setSelectedIcon(createImageIcon("images/but_transport_play_push.png","play"));
+ playButton.setActionCommand("play");
+ playButton.addActionListener(this);
+ recordPanel.add(playButton);
+ recordButton = new JButton(createImageIcon("images/but_transport_record.png","record"));
+ recordButton.setSelectedIcon(createImageIcon("images/but_transport_record_push.png","record"));
+ recordButton.setActionCommand("record");
+ recordButton.addActionListener(this);
+ recordPanel.add(recordButton);
+
+ loopButton = new JCheckBox("loop");
+ loopButton.setText("loop");
+ loopButton.setActionCommand("loop");
+ loopButton.addActionListener(this);
+ recordPanel.add(loopButton);
+
+ playAllButton = new JCheckBox("play all");
+ playAllButton.addActionListener(this);
+ recordPanel.add(playAllButton);
+ }
+
+ void addBindings() {
+ InputMap inputMap = contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+ KeyStroke key;
+
+ //key = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0);
+ //contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove(key);
+
+ key = KeyStroke.getKeyStroke('T',KeyEvent.CTRL_MASK);
+ inputMap.put(key, "new-tab");
+ key = KeyStroke.getKeyStroke('T',KeyEvent.META_MASK);
+ inputMap.put(key, "new-tab");
+ key = KeyStroke.getKeyStroke('N',KeyEvent.CTRL_MASK);
+ inputMap.put(key, "new-tab");
+ key = KeyStroke.getKeyStroke('N',KeyEvent.META_MASK);
+ inputMap.put(key, "new-tab");
+
+ key = KeyStroke.getKeyStroke('W',KeyEvent.CTRL_MASK);
+ inputMap.put(key, "close-tab");
+ key = KeyStroke.getKeyStroke('W',KeyEvent.META_MASK);
+ inputMap.put(key, "close-tab");
+
+ key = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,KeyEvent.CTRL_MASK);
+ inputMap.put(key, "right-tab");
+ key = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,KeyEvent.CTRL_MASK);
+ inputMap.put(key, "left-tab");
+ key = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,KeyEvent.META_MASK);
+ inputMap.put(key, "right-tab");
+ key = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,KeyEvent.META_MASK);
+ inputMap.put(key, "left-tab");
+
+ key = KeyStroke.getKeyStroke('X',KeyEvent.CTRL_MASK);
+ inputMap.put(key, "cut");
+ key = KeyStroke.getKeyStroke('X',KeyEvent.META_MASK);
+ inputMap.put(key, "cut");
+ key = KeyStroke.getKeyStroke('C',KeyEvent.CTRL_MASK);
+ inputMap.put(key, "copy");
+ key = KeyStroke.getKeyStroke('C',KeyEvent.META_MASK);
+ inputMap.put(key, "copy");
+ key = KeyStroke.getKeyStroke('V',KeyEvent.CTRL_MASK);
+ inputMap.put(key, "paste");
+ key = KeyStroke.getKeyStroke('V',KeyEvent.META_MASK);
+ inputMap.put(key, "paste");
+
+ ActionMap actionMap = contentPane.getActionMap();
+ actionMap.put("new-tab", new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ openNewTab();
+ } });
+ actionMap.put("close-tab",new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ closeCurrentTab();
+ } });
+ actionMap.put("left-tab",new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ cycleTabLeft();
+ } });
+ actionMap.put("right-tab",new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ cycleTabRight();
+ } });
+ actionMap.put("cut",new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ clipboard = getCurrentTab().cut();
+ } });
+ actionMap.put("copy",new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ clipboard = getCurrentTab().copy();
+ } });
+ actionMap.put("paste",new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ getCurrentTab().paste(clipboard);
+ } });
+ }
+
+ /**
+ * Bind keys to actions using a custom KeyEventPostProcessor
+ * (fixme: why can't this go in the panel?)
+ */
+ void bindKeys() {
+ // ahh, the succinctness of java
+ KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+
+ kfm.addKeyEventDispatcher( new KeyEventDispatcher() {
+ public boolean dispatchKeyEvent(KeyEvent e) {
+ String action=null;
+ if(e.getID() != KeyEvent.KEY_PRESSED)
+ return false;
+ if(e.getModifiers() != 0)
+ return false;
+ switch(e.getKeyCode()) {
+ case KeyEvent.VK_UP:
+ action = "forward";
+ movingForward=true;
+ turnval = 0;
+ break;
+ case KeyEvent.VK_DOWN:
+ action="backward";
+ movingForward=false;
+ turnval = 0;
+ break;
+ case KeyEvent.VK_LEFT:
+ if(movingForward) {
+ turnval = (turnval==0) ? 100 : turnval-turnval/2;
+ if(turnval<10) { action="spinleft"; turnval=0; }
+ else action = "turn"+turnval;
+ }
+ else action = "spinleft";
+ //action = (movingForward) ? "turn100" : "spinleft";
+ break;
+ case KeyEvent.VK_RIGHT:
+ if(movingForward) {
+ turnval = (turnval==0) ? -100 : turnval-turnval/2;
+ if(turnval>-10) { action="spinright"; turnval=0; }
+ else action = "turn"+turnval;
+ }
+ else action = "spinright";
+ //action = (movingForward) ? "turn-100" : "spinright";
+ break;
+ case KeyEvent.VK_SPACE:
+ action="stop";
+ movingForward=false;
+ turnval = 0;
+ break;
+ case KeyEvent.VK_L:
+ action="blink-leds";
+ break;
+ case KeyEvent.VK_R:
+ action="reset";
+ break;
+ case KeyEvent.VK_T:
+ action="test";
+ break;
+ case KeyEvent.VK_V:
+ vacuuming = !vacuuming;
+ action = (vacuuming) ? "vacuum-on":"vacuum-off";
+ break;
+ case KeyEvent.VK_1:
+ action="50";
+ break;
+ case KeyEvent.VK_2:
+ action="100";
+ break;
+ case KeyEvent.VK_3:
+ action="150";
+ break;
+ case KeyEvent.VK_4:
+ action="250";
+ break;
+ case KeyEvent.VK_5:
+ action="400";
+ break;
+ case KeyEvent.VK_6:
+ action="500";
+ break;
+ }
+
+ if(action!=null)
+ getCurrentTab().actionPerformed(new ActionEvent(this,0,action));
+ //System.out.println("process '"+e.getKeyCode()+"' "+e);
+ return true;
+ }
+ });
+ }
+
+ /** Implement Actionlistener */
+ public void actionPerformed(ActionEvent event) {
+ String action = event.getActionCommand();
+ //System.out.println("action:"+action+", event: "+event);
+ if("stop".equals(action)) {
+ playButton.setSelected(false);
+ recordButton.setSelected(false);
+ for(int i=0; i
handshake");
+
+ //Add a border around the select panel.
+ selectPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Select Roomba Port"), BorderFactory.createEmptyBorder()));
+
+ selectPanel.add(portChoices);
+ selectPanel.add(connectButton);
+ selectPanel.add(handshakeButton);
+
+ //Listen to events from the combo box.
+ portChoices.addActionListener(this);
+ connectButton.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeCtrlPanel() {
+ JPanel ctrlPanel1 = new JPanel(new GridLayout(3,3));
+
+ JButton but_turnleft =
+ new JButton(createImageIcon("images/but_turnleft.png","turnleft"));
+ ctrlPanel1.add(but_turnleft);
+ JButton but_forward =
+ new JButton(createImageIcon("images/but_forward.png","forward"));
+ ctrlPanel1.add(but_forward);
+ JButton but_turnright =
+ new JButton(createImageIcon("images/but_turnright.png","turnright"));
+ ctrlPanel1.add(but_turnright);
+
+ JButton but_spinleft =
+ new JButton(createImageIcon("images/but_spinleft.png","spinleft"));
+ ctrlPanel1.add(but_spinleft);
+ JButton but_stop =
+ new JButton(createImageIcon("images/but_stop.png", "stop"));
+ ctrlPanel1.add(but_stop);
+ JButton but_spinright =
+ new JButton(createImageIcon("images/but_spinright.png","spinright"));
+ ctrlPanel1.add(but_spinright);
+
+ ctrlPanel1.add(new JLabel());
+ JButton but_backward =
+ new JButton(createImageIcon("images/but_backward.png","backward"));
+ ctrlPanel1.add(but_backward);
+ ctrlPanel1.add(new JLabel());
+
+ JLabel speedLabel = new JLabel("speed (mm/s)", JLabel.CENTER);
+ JRadioButton speed050button = new JRadioButton("50");
+ JRadioButton speed100button = new JRadioButton("100");
+ JRadioButton speed150button = new JRadioButton("150");
+ JRadioButton speed250button = new JRadioButton("250");
+ JRadioButton speed400button = new JRadioButton("400");
+ JRadioButton speed500button = new JRadioButton("500");
+ speed050button.setVerticalTextPosition(SwingConstants.BOTTOM);
+ speed050button.setHorizontalTextPosition(SwingConstants.CENTER);
+ speed100button.setVerticalTextPosition(SwingConstants.BOTTOM);
+ speed100button.setHorizontalTextPosition(SwingConstants.CENTER);
+ speed150button.setVerticalTextPosition(SwingConstants.BOTTOM);
+ speed150button.setHorizontalTextPosition(SwingConstants.CENTER);
+ speed250button.setVerticalTextPosition(SwingConstants.BOTTOM);
+ speed250button.setHorizontalTextPosition(SwingConstants.CENTER);
+ speed400button.setVerticalTextPosition(SwingConstants.BOTTOM);
+ speed400button.setHorizontalTextPosition(SwingConstants.CENTER);
+ speed500button.setVerticalTextPosition(SwingConstants.BOTTOM);
+ speed500button.setHorizontalTextPosition(SwingConstants.CENTER);
+
+ speed250button.setSelected(true);
+
+ speed050button.addActionListener(this);
+ speed100button.addActionListener(this);
+ speed150button.addActionListener(this);
+ speed250button.addActionListener(this);
+ speed400button.addActionListener(this);
+ speed500button.addActionListener(this);
+
+ ButtonGroup speedGroup = new ButtonGroup();
+ speedGroup.add(speed050button);
+ speedGroup.add(speed100button);
+ speedGroup.add(speed150button);
+ speedGroup.add(speed250button);
+ speedGroup.add(speed400button);
+ speedGroup.add(speed500button);
+
+ JPanel ctrlPanel2 = new JPanel();
+ ctrlPanel2.add(speed050button);
+ ctrlPanel2.add(speed100button);
+ ctrlPanel2.add(speed150button);
+ ctrlPanel2.add(speed250button);
+ ctrlPanel2.add(speed400button);
+ ctrlPanel2.add(speed500button);
+
+ ctrlPanel = new JPanel();
+ ctrlPanel.setLayout(new BoxLayout(ctrlPanel, BoxLayout.Y_AXIS));
+ ctrlPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Movement"), BorderFactory.createEmptyBorder()));//5,5,5,5)));
+ ctrlPanel.add(ctrlPanel1);
+ ctrlPanel.add(ctrlPanel2);
+ ctrlPanel.add(speedLabel);
+
+ but_turnleft.setActionCommand("turnleft");
+ but_turnright.setActionCommand("turnright");
+ but_spinleft.setActionCommand("spinleft");
+ but_spinright.setActionCommand("spinright");
+ but_forward.setActionCommand("forward");
+ but_backward.setActionCommand("backward");
+ but_stop.setActionCommand("stop");
+ but_turnleft.addActionListener(this);
+ but_turnright.addActionListener(this);
+ but_spinleft.addActionListener(this);
+ but_spinright.addActionListener(this);
+ but_forward.addActionListener(this);
+ but_backward.addActionListener(this);
+ but_stop.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeButtonPanel() {
+ buttonPanel = new JPanel(new GridLayout(8,2));
+ buttonPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Commands"), BorderFactory.createEmptyBorder()));//5,5,5,5)));
+
+ JButton but_reset = new JButton("reset");
+ JButton but_test = new JButton("test");
+ JButton but_power = new JButton("power-off");
+ JButton but_wakeup = new JButton("wakeup");
+ JButton but_beeplo = new JButton("beep-lo");
+ JButton but_beephi = new JButton("beep-hi");
+ JButton but_clean = new JButton("clean");
+ JButton but_spot = new JButton("spot");
+ JButton but_vacon = new JButton("vacuum-on");
+ JButton but_vacoff = new JButton("vacuum-off");
+ JButton but_blinkleds = new JButton("blink-leds");
+ JButton but_sensors = new JButton("sensors");
+
+ buttonPanel.add(but_reset);
+ buttonPanel.add(but_test);
+ buttonPanel.add(but_power);
+ buttonPanel.add(but_wakeup);
+ buttonPanel.add(but_beeplo);
+ buttonPanel.add(but_beephi);
+ buttonPanel.add(but_clean);
+ buttonPanel.add(but_spot);
+ buttonPanel.add(but_vacon);
+ buttonPanel.add(but_vacoff);
+ buttonPanel.add(but_blinkleds);
+ buttonPanel.add(but_sensors);
+
+ but_reset.addActionListener(this);
+ but_test.addActionListener(this);
+ but_power.addActionListener(this);
+ but_wakeup.addActionListener(this);
+ but_beeplo.addActionListener(this);
+ but_beephi.addActionListener(this);
+ but_clean.addActionListener(this);
+ but_spot.addActionListener(this);
+ but_vacon.addActionListener(this);
+ but_vacoff.addActionListener(this);
+ but_blinkleds.addActionListener(this);
+ but_sensors.addActionListener(this);
+ }
+
+ /**
+ *
+ */
+ void makeDisplayPanel() {
+ displayPanel = new JPanel();
+ displayPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Display"), BorderFactory.createEmptyBorder()));//1,1,1,1)));
+
+ displayText = new JTextArea(5,30);
+ displayText.setEditable(false);
+ displayText.setLineWrap(true);
+ DefaultCaret dc = new DefaultCaret();
+ // only works on Java 1.5+
+ //dc.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
+ displayText.setCaret(dc);
+ JScrollPane scrollPane =
+ new JScrollPane(displayText,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ displayPanel.add(scrollPane);
+ }
+
+ public void updateDisplay(String s) {
+ displayText.append(s);
+ displayText.setCaretPosition(displayText.getDocument().getLength());
+ }
+
+ /** Returns an ImageIcon, or null if the path was invalid. */
+ protected static ImageIcon createImageIcon(String path,
+ String description) {
+ // yes, this is supposed to say "RoombaCommTest"
+ java.net.URL imgURL = RoombaCommPanel.class.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL, description);
+ } else {
+ System.err.println("Couldn't find file: " + path);
+ return null;
+ }
+ }
+
+ public int millis() {
+ int millisOffset = 0;
+ return (int) (System.currentTimeMillis() - millisOffset);
+ }
+
+}
diff --git a/roombacomm-client/src/com/hackingroomba/roombacomm/SimpleTest.java b/roombacomm-client/src/com/hackingroomba/roombacomm/SimpleTest.java
new file mode 100644
index 0000000..3c55daa
--- /dev/null
+++ b/roombacomm-client/src/com/hackingroomba/roombacomm/SimpleTest.java
@@ -0,0 +1,148 @@
+/*
+ * roombacomm.SimpleTest
+ *
+ * Copyright (c) 2005 Tod E. Kurt, tod@todbot.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+
+package com.hackingroomba.roombacomm;
+
+/**
+ A simple test of RoombaComm and RoombaCommSerial functionality.
+
+ java roombacomm.SimpleTest /dev/cu.KeySerial1
+ *
+ */
+public class SimpleTest {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.SimpleTest
+ Usage:
+ roombacomm.SimpleTest serialportname [protocol] [options]
+ where:
+ protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+ -flush -- flush on sends(), normally not needed
+ *
+ java roombacomm.Spiral /dev/cu.KeySerial1
+
+ */
+public class Spiral {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.Spiral
+ Usage:
+ roombacomm.Spiral
+ where: protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+
+ java roombacomm.Spiro1 /dev/cu.KeySerial1 velocity radius waittime
+ */
+public class Spiro1 {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.Spiro1
+ Usage: \n"+
+ roombacomm.Spiro1
+ where:
+ protocol (optional) is SCI or OI
+ velocity and radius in mm, waittime in milliseconds
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+
+ * java roombacomm.Spiro1 /dev/cu.KeySerial1 velocity radius waittime
+ *
+ *
+ */
+public class Spiro2 {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.Spiro2
+ java roombacomm.Spy /dev/cu.KeySerial1
+ */
+public class Spy {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.Spy
+ Usage:
+ roombacomm.Spy
+ where: protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -pause
+ java roombacomm.SpyAuto /dev/cu.KeySerial1
+ Usage:
+ roombacomm.SpyAuto serialportname [protocol] [options]
+ *
+ */
+public class SpyAuto {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.SpyAuto
+ where: protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -pause n -- pause n millseconds between sensor read
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+ -flush -- flush on sends(), normally not needed
+ -power -- power on/off Roomba (if interface supports it)
+
+ java roombacomm.SpySimple /dev/cu.KeySerial1
+ Usage:
+ roombacomm.SpySimple serialportname [protocol] [options]
+ *
+ */
+public class SpySimple {
+
+ static String usage =
+ "Usage: \n"+
+ " roombacomm.SpySimple
+ where: protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -pause n -- pause n millseconds between sensor read
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+ -flush -- flush on sends(), normally not needed *
+ java roombacomm.Test /dev/cu.KeySerial1
+ Usage:
+ roombacomm.Test serialportname [protocol] [options]
+ *
+ where: protocol (optional) is SCI or OI
+ [options] can be one or more of:
+ -debug -- turn on debug output
+ -hwhandshake -- use hardware-handshaking, for Windows Bluetooth
+ -nohwhandshake -- don't use hardware-handshaking
+ -flush -- flush on sends(), normally not needed
+ -power -- power on/off Roomba (if interface supports it)
+ *
+ * java roombacomm.Tribble /dev/cu.KeySerial1 [protocol]+ * + */ +public class Tribble { + + static RoombaCommSerial roombacomm; + + public static void main(String[] args) { + new Tribble(args); + } + + Tribble(String[] args) + { + if( args.length == 0 ) { + System.out.println("Tribble
+ * Where: protocol (optional) is SCI or OI + *
+ Run it with something like:
+ java roombacomm.Waggle /dev/cu.KeySerial1 [protocol] velocity radius waittime [options] + where: + protocol (optional) is SCI or OI + velocity and radius in mm, waittime in milliseconds + [options] can be one or more of: + -debug -- turn on debug output + -hwhandshake -- use hardware-handshaking, for Windows Bluetooth + -nohwhandshake -- don't use hardware-handshaking + *+ * + */ +public class Waggle { + + static String usage = + "Usage: \n"+ + " roombacomm.Waggle
+ * java roombacomm.SimpleTest /dev/cu.KeySerial1 + *+ * + */ +public class SimpleTest { + + static String usage = + "Usage: \n"+ + " roombacomm.net.SimpleTest
+ java roombacomm.WatchVideo --videoServer 192.168.0.150 --videoPortNum 5005 -x 160 -y 120 --debug+*/ + public class watchVideo { + + private int height = 120; + private int width = 160; + String usage = + "Usage: \n"+ + " roombacomm.Roborama --videoServer
+ Usage: + roombacomm.WatchVideo --videoServer--videoPortNum + -x -y [options]
+ where + [options] can be one or more of: + -debug -- turn on debug output + -hwhandshake -- use hardware-handshaking, for Windows Bluetooth + -nohwhandshake -- don't use hardware-handshaking +