RLPark 1.0.0
Reinforcement Learning Framework in Java

SerialPortToRobot.java

Go to the documentation of this file.
00001 package rlpark.plugin.irobot.internal.serial;
00002 
00003 import gnu.io.CommPortIdentifier;
00004 import gnu.io.PortInUseException;
00005 import gnu.io.SerialPort;
00006 import gnu.io.SerialPortEvent;
00007 import gnu.io.SerialPortEventListener;
00008 import gnu.io.UnsupportedCommOperationException;
00009 
00010 import java.io.IOException;
00011 import java.util.Arrays;
00012 import java.util.Collections;
00013 import java.util.HashMap;
00014 import java.util.Map;
00015 import java.util.TooManyListenersException;
00016 import java.util.concurrent.Semaphore;
00017 import java.util.concurrent.TimeUnit;
00018 
00019 import rlpark.plugin.robot.internal.disco.drops.DropByteArray;
00020 import zephyr.plugin.core.api.signals.Listener;
00021 import zephyr.plugin.core.api.signals.Signal;
00022 
00023 public class SerialPortToRobot implements SerialPortEventListener {
00024   static public final boolean ExpectedIgnored = false;
00025   static public boolean DebugSignals = false;
00026 
00027   public static class SerialPortInfo {
00028     public int rate = 115200;
00029     public int databits = SerialPort.DATABITS_8;
00030     public int stopbits = SerialPort.STOPBITS_1;
00031     public int parity = SerialPort.PARITY_NONE;
00032     public int flowControl = SerialPort.FLOWCONTROL_NONE;
00033 
00034     public SerialPortInfo() {
00035       this(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, SerialPort.FLOWCONTROL_NONE);
00036     }
00037 
00038     public SerialPortInfo(int rate, int databits, int stopbits, int parity, int flowControl) {
00039       this.rate = rate;
00040       this.databits = databits;
00041       this.stopbits = stopbits;
00042       this.parity = parity;
00043       this.flowControl = flowControl;
00044     }
00045   }
00046 
00047   protected final SerialStreams serialStreams;
00048   private final String serialPortFileName;
00049   private final CommPortIdentifier identifier;
00050   private final SerialPort serialPort;
00051   private final Map<Integer, Signal<SerialPortToRobot>> signals = Collections
00052       .synchronizedMap(new HashMap<Integer, Signal<SerialPortToRobot>>());
00053   private boolean isClosed;
00054 
00055   public SerialPortToRobot(String fileName, SerialPortInfo portInfo) throws PortInUseException,
00056       UnsupportedCommOperationException, TooManyListenersException, IOException {
00057     serialPortFileName = fileName;
00058     identifier = SerialPorts.getPortIdentifier(serialPortFileName);
00059     if (identifier == null)
00060       throw new RuntimeException("Port identifier " + serialPortFileName + " not found");
00061     serialPort = (SerialPort) identifier.open("RLPark", 150);
00062     serialPort.addEventListener(this);
00063     serialPort.setFlowControlMode(portInfo.flowControl);
00064     serialPort.setSerialPortParams(portInfo.rate, portInfo.databits, portInfo.stopbits, portInfo.parity);
00065     serialStreams = new SerialStreams(serialPort);
00066     setNotifiers();
00067   }
00068 
00069   public void wakeupRobot() {
00070     serialPort.setRTS(false);
00071     serialPort.setDTR(false);
00072     try {
00073       Thread.sleep(500);
00074     } catch (InterruptedException e) {
00075       e.printStackTrace();
00076     }
00077     serialPort.setRTS(true);
00078     serialPort.setDTR(true);
00079   }
00080 
00081   private void setNotifiers() {
00082     serialPort.notifyOnDataAvailable(true);
00083     serialPort.notifyOnOutputEmpty(true);
00084     serialPort.notifyOnBreakInterrupt(true);
00085     serialPort.notifyOnCarrierDetect(true);
00086     serialPort.notifyOnCTS(true);
00087     serialPort.notifyOnDSR(true);
00088     serialPort.notifyOnFramingError(true);
00089     serialPort.notifyOnOverrunError(true);
00090     serialPort.notifyOnParityError(true);
00091     serialPort.notifyOnRingIndicator(true);
00092   }
00093 
00094   public void register(int event, Listener<SerialPortToRobot> listener) {
00095     Signal<SerialPortToRobot> signal = signals.get(event);
00096     if (signal == null) {
00097       signal = new Signal<SerialPortToRobot>();
00098       signals.put(event, signal);
00099     }
00100     signal.connect(listener);
00101   }
00102 
00103   public void unregister(int event, Listener<SerialPortToRobot> listener) {
00104     signals.get(event).disconnect(listener);
00105   }
00106 
00107   @Override
00108   public void serialEvent(SerialPortEvent event) {
00109     Signal<SerialPortToRobot> signal = signals.get(event.getEventType());
00110     if (signal != null)
00111       signal.fire(this);
00112     if (!DebugSignals)
00113       return;
00114     switch (event.getEventType()) {
00115     case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
00116       System.out.println("Event received: outputBufferEmpty");
00117       break;
00118 
00119     case SerialPortEvent.DATA_AVAILABLE:
00120       System.out.println("Event received: dataAvailable");
00121       break;
00122 
00123     case SerialPortEvent.BI:
00124       System.out.println("Event received: breakInterrupt");
00125       break;
00126 
00127     case SerialPortEvent.CD:
00128       System.out.println("Event received: carrierDetect");
00129       break;
00130 
00131     case SerialPortEvent.CTS:
00132       System.out.println("Event received: clearToSend");
00133       break;
00134 
00135     case SerialPortEvent.DSR:
00136       System.out.println("Event received: dataSetReady");
00137       break;
00138 
00139     case SerialPortEvent.FE:
00140       System.out.println("Event received: framingError");
00141       break;
00142 
00143     case SerialPortEvent.OE:
00144       System.out.println("Event received: overrunError");
00145       break;
00146 
00147     case SerialPortEvent.PE:
00148       System.out.println("Event received: parityError");
00149       break;
00150     case SerialPortEvent.RI:
00151       System.out.println("Event received: ringIndicator");
00152       break;
00153     default:
00154       System.out.println("Event received: unknown");
00155     }
00156   }
00157 
00158   public void send(byte[] bytes) throws IOException {
00159     serialStreams.write(bytes);
00160   }
00161 
00162   public void send(char[] chars) throws IOException {
00163     serialStreams.write(DropByteArray.toBytes(chars));
00164   }
00165 
00166   public void send(String command) throws IOException {
00167     serialStreams.write(command.getBytes());
00168   }
00169 
00170   public void close() {
00171     // Produce a SEG FAULT
00172     // serialStreams.close();
00173     if (isClosed)
00174       return;
00175     isClosed = true;
00176   }
00177 
00178   public void sendAndReceive(String command, final String expectedAnswer) throws IOException {
00179     send(command.getBytes());
00180     byte[] received = serialStreams.read(expectedAnswer.length());
00181     if (!ExpectedIgnored && !Arrays.equals(received, expectedAnswer.getBytes()))
00182       throw new IOException(String.format("Return incorrect: expected <%s> was <%s>", expectedAnswer,
00183                                           new String(received)));
00184   }
00185 
00186   public void sendAndWait(char[] chars) throws IOException {
00187     sendAndWait(DropByteArray.toBytes(chars));
00188   }
00189 
00190   public void sendAndWait(byte[] chars) throws IOException {
00191     final Semaphore semaphore = new Semaphore(0);
00192     Listener<SerialPortToRobot> listener = new Listener<SerialPortToRobot>() {
00193       @Override
00194       public void listen(SerialPortToRobot eventInfo) {
00195         semaphore.release();
00196       }
00197     };
00198     register(SerialPortEvent.OUTPUT_BUFFER_EMPTY, listener);
00199     serialStreams.write(chars);
00200     try {
00201       semaphore.tryAcquire(10, TimeUnit.SECONDS);
00202     } catch (InterruptedException e) {
00203       e.printStackTrace();
00204     }
00205     unregister(SerialPortEvent.OUTPUT_BUFFER_EMPTY, listener);
00206   }
00207 
00208   public boolean isClosed() {
00209     return isClosed;
00210   }
00211 
00212   public byte[] read(int size) throws IOException {
00213     return serialStreams.read(size);
00214   }
00215 
00216   static public SerialPortToRobot tryOpenPort(String serialPortFile, SerialPortInfo serialPortInfo) {
00217     for (int trial = 0; trial < 10; trial++) {
00218       SerialPortToRobot serialPort = openPort(serialPortFile, serialPortInfo);
00219       if (serialPort != null)
00220         return serialPort;
00221       try {
00222         Thread.sleep(4000);
00223       } catch (InterruptedException e) {
00224         e.printStackTrace();
00225       }
00226     }
00227     return null;
00228   }
00229 
00230   static public SerialPortToRobot openPort(String serialPortFile, SerialPortInfo serialPortInfo) {
00231     SerialPorts.refreshPortIdentifiers();
00232     SerialPortToRobot serialPort = null;
00233     try {
00234       serialPort = new SerialPortToRobot(serialPortFile, serialPortInfo);
00235     } catch (Exception e) {
00236       e.printStackTrace();
00237     }
00238     return serialPort;
00239   }
00240 
00241   static public void fatalError(String message) {
00242     System.err.println(message);
00243     System.exit(1);
00244   }
00245 
00246   public int purge() {
00247     try {
00248       return serialStreams.read(serialStreams.available()).length;
00249     } catch (IOException e) {
00250       e.printStackTrace();
00251     }
00252     return 0;
00253   }
00254 }
 All Classes Namespaces Files Functions Variables Enumerations
Zephyr
RLPark