RLPark 1.0.0
Reinforcement Learning Framework in Java
|
00001 package rlpark.plugin.irobot.internal.descriptors; 00002 00003 import gnu.io.SerialPort; 00004 00005 import java.io.IOException; 00006 import java.util.ArrayList; 00007 import java.util.List; 00008 import java.util.concurrent.Semaphore; 00009 00010 import rlpark.plugin.irobot.data.IRobotLabels; 00011 import rlpark.plugin.irobot.internal.serial.SerialPortToRobot; 00012 import rlpark.plugin.irobot.internal.serial.SerialPortToRobot.SerialPortInfo; 00013 import rlpark.plugin.robot.internal.disco.drops.Drop; 00014 import zephyr.plugin.core.api.signals.Listener; 00015 00016 public class RoombaSerialDescriptor implements IRobotSerialDescriptor { 00017 static class PacketRequester implements Runnable, Listener<byte[]> { 00018 private final SerialPortToRobot serialPort; 00019 private final Semaphore semaphore = new Semaphore(2); 00020 00021 PacketRequester(SerialPortToRobot serialPort) { 00022 this.serialPort = serialPort; 00023 } 00024 00025 @Override 00026 public void run() { 00027 while (sendRequest()) { 00028 avoidOverloading(); 00029 acquireSemaphore(); 00030 } 00031 } 00032 00033 private void avoidOverloading() { 00034 try { 00035 Thread.sleep(50); 00036 } catch (InterruptedException e) { 00037 e.printStackTrace(); 00038 } 00039 } 00040 00041 private boolean sendRequest() { 00042 if (serialPort.isClosed()) 00043 return false; 00044 try { 00045 serialPort.send(new byte[] { (byte) 142, 100 }); 00046 } catch (IOException e) { 00047 e.printStackTrace(); 00048 serialPort.close(); 00049 return false; 00050 } 00051 return true; 00052 } 00053 00054 private void acquireSemaphore() { 00055 try { 00056 semaphore.acquire(); 00057 } catch (InterruptedException e) { 00058 e.printStackTrace(); 00059 } 00060 } 00061 00062 @Override 00063 public void listen(byte[] eventInfo) { 00064 semaphore.release(); 00065 } 00066 } 00067 00068 static public final boolean SetupFireflyMandatory = true; 00069 static public final long Latency = 10; 00070 private PacketRequester packetRequester; 00071 00072 private boolean setupFirefly(SerialPortToRobot serialPort) { 00073 System.out.println("Setting up Roomba's firefly..."); 00074 try { 00075 serialPort.sendAndReceive("$$$", "CMD\r\n"); 00076 serialPort.sendAndReceive("U,115k,N\r", "AOK\r\n"); 00077 } catch (IOException e) { 00078 System.out.println("Setting up Firefly has failed..."); 00079 if (SetupFireflyMandatory) { 00080 e.printStackTrace(); 00081 return false; 00082 } 00083 } 00084 return true; 00085 } 00086 00087 private boolean setupRoomba(final SerialPortToRobot serialPort) { 00088 System.out.println("Setting up Roomba..."); 00089 serialPort.wakeupRobot(); 00090 try { 00091 serialPort.sendAndWait(new char[] { 128 }); 00092 serialPort.sendAndWait(new char[] { 131 }); 00093 } catch (IOException e) { 00094 e.printStackTrace(); 00095 return false; 00096 } 00097 packetRequester = new PacketRequester(serialPort); 00098 new Thread(packetRequester).start(); 00099 return true; 00100 } 00101 00102 @Override 00103 public boolean initializeRobotCommunication(SerialPortToRobot serialPort) throws IOException { 00104 boolean fireflySet = setupFirefly(serialPort); 00105 if (!fireflySet) 00106 return false; 00107 return setupRoomba(serialPort); 00108 } 00109 00110 @Override 00111 public SerialLinkStateMachine createStateMachine(SerialPortToRobot serialPort) { 00112 List<SerialLinkNode> serialLinkNodes = new ArrayList<SerialLinkNode>(); 00113 serialLinkNodes.add(new DataNode(IRobotLabels.RoombaSensorsPacketSize)); 00114 SerialLinkStateMachine serialLinkStateMachine = new SerialLinkStateMachine((SerialPortToCreate) serialPort, 00115 serialLinkNodes); 00116 serialLinkStateMachine.onDataPacket.connect(packetRequester); 00117 return serialLinkStateMachine; 00118 } 00119 00120 @Override 00121 public Drop createSensorDrop() { 00122 return DropDescriptors.newRoombaSensorDrop(); 00123 } 00124 00125 @Override 00126 public byte[] messageOnNoClient() { 00127 return new byte[] { (byte) 146, 0, 0, 0, 0 }; 00128 } 00129 00130 @Override 00131 public SerialPortInfo portInfo() { 00132 return new SerialPortInfo(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 00133 SerialPort.FLOWCONTROL_NONE); 00134 } 00135 }