RLPark 1.0.0
Reinforcement Learning Framework in Java
|
00001 package rlpark.plugin.irobot.internal.descriptors; 00002 00003 import gnu.io.SerialPortEvent; 00004 00005 import java.util.ArrayList; 00006 import java.util.List; 00007 00008 import rlpark.plugin.irobot.internal.serial.SerialPortToRobot; 00009 import rlpark.plugin.rltoys.utils.Utils; 00010 import rlpark.plugin.robot.internal.statemachine.StateMachine; 00011 import zephyr.plugin.core.api.signals.Listener; 00012 import zephyr.plugin.core.api.signals.Signal; 00013 00014 public class SerialLinkStateMachine { 00015 public final SerialPortToCreate serialPort; 00016 private final StateMachine<Byte> stateMachine; 00017 public Signal<byte[]> onDataPacket = new Signal<byte[]>(); 00018 private final Listener<SerialPortToRobot> serialListener = new Listener<SerialPortToRobot>() { 00019 @Override 00020 public void listen(SerialPortToRobot eventInfo) { 00021 readAvailableData(); 00022 } 00023 }; 00024 private final Listener<StateMachine<Byte>> stateMachineListener = new Listener<StateMachine<Byte>>() { 00025 @Override 00026 public void listen(StateMachine<Byte> stateMachine) { 00027 dispatchReceivedDataIfCorrect(); 00028 } 00029 }; 00030 private final List<DataNode> dataNodes; 00031 private final byte[] data; 00032 private final ChecksumNode checksumNode; 00033 00034 public SerialLinkStateMachine(SerialPortToCreate serialPort, List<SerialLinkNode> nodes) { 00035 this(serialPort, null, nodes); 00036 } 00037 00038 public SerialLinkStateMachine(SerialPortToCreate serialPort, ChecksumNode checksumNode, SerialLinkNode... nodes) { 00039 this(serialPort, checksumNode, Utils.asList(nodes)); 00040 } 00041 00042 public SerialLinkStateMachine(SerialPortToCreate serialPort, ChecksumNode checksumNode, List<SerialLinkNode> nodes) { 00043 this.serialPort = serialPort; 00044 dataNodes = createDataNodeList(nodes); 00045 data = createData(dataNodes); 00046 List<SerialLinkNode> stateMachineNodes = new ArrayList<SerialLinkNode>(nodes); 00047 if (checksumNode != null) 00048 stateMachineNodes.add(checksumNode); 00049 stateMachine = new StateMachine<Byte>(stateMachineNodes); 00050 stateMachine.onEnd.connect(stateMachineListener); 00051 this.checksumNode = checksumNode; 00052 serialPort.register(SerialPortEvent.DATA_AVAILABLE, serialListener); 00053 } 00054 00055 private byte[] createData(List<DataNode> dataNodes) { 00056 int dataLength = 0; 00057 for (DataNode node : dataNodes) 00058 dataLength += node.length(); 00059 return new byte[dataLength]; 00060 } 00061 00062 private List<DataNode> createDataNodeList(List<SerialLinkNode> nodes) { 00063 List<DataNode> dataNodes = new ArrayList<DataNode>(); 00064 for (SerialLinkNode node : nodes) 00065 if (node instanceof DataNode) 00066 dataNodes.add((DataNode) node); 00067 return dataNodes; 00068 } 00069 00070 protected void dispatchReceivedDataIfCorrect() { 00071 if (checksumNode == null || checksumNode.isPacketValid()) 00072 onDataPacket.fire(fillDataPacket()); 00073 } 00074 00075 private byte[] fillDataPacket() { 00076 int index = 0; 00077 for (DataNode node : dataNodes) { 00078 System.arraycopy(node.data, 0, data, index, node.data.length); 00079 index += node.data.length; 00080 } 00081 return data; 00082 } 00083 00084 public void readAvailableData() { 00085 byte[] available = serialPort.getAvailable(); 00086 for (byte b : available) 00087 stateMachine.step(b); 00088 } 00089 }