00001
00002
00003
00004
00005
00006
00007 package com.github.c77.base_driver.kobuki;
00008 import org.apache.commons.codec.binary.Hex;
00009 import org.apache.commons.logging.Log;
00010 import org.apache.commons.logging.LogFactory;
00011
00012 import java.nio.ByteBuffer;
00013 import java.util.Arrays;
00014
00015 public class KobukiPacketReader {
00016
00017 Log log = LogFactory.getLog(KobukiPacketReader.class);
00018
00019
00020 private byte[] sensorPacket = new byte[15];
00021 private byte[] inertialSensorPacket = new byte[4];
00022 private byte[] dockingIRPacket = new byte[3];
00023 private byte[] wheelCurrentPacket = new byte[4];
00024 private enum parserState {
00025 INIT, PARTIAL, COMPLETE;
00026 }
00027
00028 private parserState curState;
00029 private volatile byte[] stored;
00030 private int bytesStillNeeded;
00031 private int totalSize;
00032 private int bytesStoredIndex;
00033
00034 public KobukiPacketReader() {
00035 curState = parserState.INIT;
00036 stored = new byte[500];
00037 bytesStillNeeded = 0;
00038 totalSize = 0;
00039 bytesStoredIndex = 0;
00040 }
00041
00042 public final void newPacket(ByteBuffer buff) {
00043 if(curState == parserState.INIT || curState == parserState.COMPLETE) {
00044 for(int i=0; i < buff.array().length-2; i++){
00045 if(buff.array()[i] == -86 && buff.array()[i+1] == 85) {
00046 curState = parserState.PARTIAL;
00047 if((buff.array().length-i) >= (buff.array()[i+2]+4)) {
00048 byte[] packet = new byte[byteToInt(buff.array()[i+2])+2];
00049
00050 System.arraycopy(buff.array(), i + 2, packet, 0, byteToInt(buff.array()[i+2]) + 2);
00051 if(verifyChecksum(byteToInt(buff.array()[i+2]) + 2, packet)) {
00052 System.arraycopy(packet, 1, packet, 0, packet.length - 1);
00053 goodPacket(byteToInt(buff.array()[i+2]) ,packet);
00054 } else {
00055
00056 }
00057 curState = parserState.COMPLETE;
00058 } else {
00059 System.arraycopy(buff.array(), i+2, stored, 0, (buff.array().length-(i+2)));
00060 bytesStillNeeded = (buff.array()[i+2] + 2) - (buff.array().length-(i+2));
00061 totalSize = buff.array()[i+2] + 2;
00062 bytesStoredIndex = buff.array().length - (i+2);
00063 }
00064 }
00065 }
00066 } else {
00067 System.arraycopy(buff.array(), 0, stored, bytesStoredIndex, bytesStillNeeded);
00068 if(verifyChecksum(totalSize, stored)) {
00069 System.arraycopy(stored, 1, stored, 0, stored.length - 1);
00070 goodPacket(totalSize - 2, stored);
00071 } else {
00072
00073 }
00074 curState = parserState.COMPLETE;
00075 }
00076 }
00077
00078 private final boolean verifyChecksum(int length, byte[] packet) {
00079
00080 byte checksum = 0;
00081
00082 for(int i = 0; i < length - 1; i++) {
00083
00084 checksum ^= packet[i];
00085 }
00086
00087 if(packet[length - 1] == checksum) {
00088 return true;
00089 } else {
00090 return false;
00091 }
00092 }
00093
00094 private final void goodPacket(int length ,byte[] packet) {
00095
00096
00097
00098
00099 int curPlace = 0;
00100 byte[] toSend = new byte[100];
00101 System.arraycopy(packet, 0, toSend, 0, (packet[1]+2));
00102 curPlace = packet[1] + 2;
00103 sortParts(toSend);
00104
00105 for(int i = 0; i < 6; i++) {
00106 Arrays.fill(toSend, (byte)0);
00107
00108 System.arraycopy(packet, curPlace, toSend, 0, packet[curPlace+1] + 2);
00109 curPlace = curPlace + packet[curPlace+1] + 2;
00110 sortParts(toSend);
00111 }
00112 }
00113
00114 private final void sortParts(byte[] packet){
00115 switch(packet[0]){
00116 case 1:
00117 sensorPacket(packet);
00118 break;
00119 case 3:
00120 dockingIRPacket(packet);
00121 break;
00122 case 4:
00123 inertialSensorPacket(packet);
00124 break;
00125 case 6:
00126 wheelCurrentPacket(packet);
00127 break;
00128 default:
00129 break;
00130 }
00131 }
00132
00133 private final int byteToInt(byte b) {
00134 return b & 0xFF;
00135 }
00136
00137 public final void sensorPacket(byte[] packet) {
00138 System.arraycopy(packet, 2, sensorPacket, 0, 15);
00139 }
00140
00141 private final void inertialSensorPacket(byte[] packet) {
00142 System.arraycopy(packet, 2, inertialSensorPacket, 0, 4);
00143 }
00144
00145 private final void dockingIRPacket(byte[] packet) {
00146 System.arraycopy(packet, 2, dockingIRPacket, 0, 3);
00147 }
00148
00149 private final void wheelCurrentPacket(byte[] packet) {
00150 System.arraycopy(packet, 2, wheelCurrentPacket, 0, 2);
00151 }
00152
00156 public final byte[] getSensorPacket() {
00157 return sensorPacket;
00158 }
00159
00163 public final byte[] getInertialSensorPacket() {
00164 return inertialSensorPacket;
00165 }
00166
00170 public final byte[] getDockingIRPacket() {
00171 return dockingIRPacket;
00172 }
00173
00177 public final byte[] getWheelCurrentPacket() {
00178 return wheelCurrentPacket;
00179 }
00180 }