Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package com.github.c77.base_driver.husky;
00018
00023 import com.github.c77.base_driver.BaseDevice;
00024 import com.github.c77.base_driver.BaseStatus;
00025 import com.github.c77.base_driver.OdometryStatus;
00026 import com.hoho.android.usbserial.driver.UsbSerialDriver;
00027 import com.hoho.android.usbserial.util.SerialInputOutputManager;
00028
00029 import org.apache.commons.logging.Log;
00030 import org.apache.commons.logging.LogFactory;
00031
00032 import java.io.IOException;
00033 import java.nio.ByteBuffer;
00034 import java.util.concurrent.ExecutorService;
00035 import java.util.concurrent.Executors;
00036
00037 public class HuskyBaseDevice implements BaseDevice {
00038 private final long initialTime;
00039
00040 HuskyPacketReader packetReader = new HuskyPacketReader();
00041 HuskyOdometryStatus odometryStatus = new HuskyOdometryStatus();
00042
00043
00044 private static final byte SOH = (byte) 0xAA;
00045 private static final byte PROTOCOL_VERSION = (byte) 0x1;
00046 private static final byte STX = (byte) 0x55;
00047
00048
00049 private static final double SPEED_LIMIT = 100.0;
00050 private static final double SPEED_SCALE = 100.0;
00051
00052 private static final Log log = LogFactory.getLog(HuskyBaseDevice.class);
00053
00054
00055 private final UsbSerialDriver serialDriver;
00056
00057 public BaseStatus getBaseStatus() {
00058 BaseStatus baseStatus;
00059 baseStatus = new BaseStatus();
00060 return baseStatus;
00061 }
00062
00063 @Override
00064 public OdometryStatus getOdometryStatus() {
00065 return odometryStatus;
00066 }
00067
00068
00069 public HuskyBaseDevice(UsbSerialDriver driver) {
00070
00071 initialTime = System.currentTimeMillis();
00072
00073
00074 serialDriver = driver;
00075 try {
00076 serialDriver.open();
00077 serialDriver.setParameters(115200, UsbSerialDriver.DATABITS_8,
00078 UsbSerialDriver.STOPBITS_1, UsbSerialDriver.PARITY_NONE);
00079 log.info("Serial device opened correctly");
00080 } catch (IOException e) {
00081 log.error("Error setting up device: " + e.getMessage(), e);
00082 try {
00083 serialDriver.close();
00084 } catch (Throwable t) {
00085 }
00086 throw new RuntimeException("Couldn't open USB device driver", e);
00087 }
00088
00089
00090
00091 final ExecutorService executorService = Executors.newSingleThreadExecutor();
00092 SerialInputOutputManager serialInputOutputManager;
00093 final SerialInputOutputManager.Listener listener =
00094 new SerialInputOutputManager.Listener() {
00095 @Override
00096 public void onRunError(Exception e) {
00097 }
00098
00099 @Override
00100 public void onNewData(final byte[] data) {
00101 HuskyBaseDevice.this.updateReceivedData(data);
00102 }
00103 };
00104 serialInputOutputManager = new SerialInputOutputManager(serialDriver, listener);
00105 executorService.submit(serialInputOutputManager);
00106 }
00107
00111 private void updateReceivedData(final byte[] bytes) {
00112 HuskyPacket packet = null;
00113 try {
00114
00115 packet = packetReader.parse(ByteBuffer.wrap(bytes));
00116
00117 } catch (HuskyParserException e) {
00118 log.error("Error parsing incoming packet", e);
00119 }
00120
00121
00122 if(packet != null) {
00123 switch(packet.getMessageType()) {
00124
00125
00126 case HuskyPacket.TYPE_ENCODER_DATA:
00127 odometryStatus.update(packet.getPayload());
00128 break;
00129
00130
00131 default:
00132 break;
00133 }
00134 }
00135 }
00136
00140 @Override
00141 public void initialize() {
00142 log.info("Initializing");
00143
00144 sendEncodersRequest();
00145 }
00146
00152 @Override
00153 public void move(double linearVelX, double angVelZ) {
00154
00155
00156 sendMovementPackage(
00157 scaleAndLimitSpeed(linearVelX),
00158 scaleAndLimitSpeed(angVelZ));
00159 }
00160
00161 private static int scaleAndLimitSpeed(double speed) {
00162 return (int)Math.round(Math.max(Math.min(speed * SPEED_SCALE, SPEED_LIMIT), -1.0*SPEED_LIMIT));
00163 }
00164
00168 private void sendEncodersRequest() {
00169 byte [] encoderRequestMessage = new byte[] {
00170 0x00, 0x48, 0x55, 0x0A, 0x00
00171 };
00172 write(buildPackage(encoderRequestMessage));
00173 }
00174
00179 private void sendMovementPackage(int linearSpeed, int angSpeed) {
00180 int linearAccel = 0x00C8;
00181 int MSGType = 0x0204;
00182
00183
00184 byte[] baseControlMsg = new byte[]{
00185 (byte) MSGType,
00186 (byte) (MSGType >> 8),
00187 STX,
00188 (byte) linearSpeed,
00189 (byte) (linearSpeed >> 8),
00190 (byte) angSpeed,
00191 (byte) (angSpeed >> 8),
00192 (byte) linearAccel,
00193 (byte) (linearAccel >> 8)
00194 };
00195
00196 write(buildPackage(baseControlMsg));
00197 }
00198
00199
00203 byte[] buildPackage(byte[] payload) {
00204 char checksum = 0;
00205 int payloadLength = payload.length;
00206 byte[] pkg = new byte[payloadLength + 11];
00207 long msgTime = System.currentTimeMillis();
00208
00209 byte Flags = (byte) 0x01;
00210 byte Length0 = (byte) (payloadLength + 8);
00211 byte Length1 = (byte) ~Length0;
00212 int TimeStamp = (int)msgTime - (int)initialTime;
00213
00214 pkg[0] = SOH;
00215 pkg[1] = Length0;
00216 pkg[2] = Length1;
00217 pkg[3] = PROTOCOL_VERSION;
00218 pkg[4] = (byte) TimeStamp;
00219 pkg[5] = (byte) (TimeStamp >> 8);
00220 pkg[6] = (byte) (TimeStamp >> 16);
00221 pkg[7] = (byte) (TimeStamp >> 24);
00222 pkg[8] = Flags;
00223
00224 for (int i = 9; i < payloadLength + 9; i++) {
00225 pkg[i] = payload[i - 9];
00226 }
00227
00228 checksum = HuskyBaseUtils.checkSum(pkg);
00229 pkg[pkg.length - 2] = (byte)checksum;
00230 pkg[pkg.length - 1] = (byte)(checksum >> 8);
00231
00232 return pkg;
00233 }
00234
00239 private void write(byte[] command) {
00240 try {
00241 serialDriver.write(command, 1000);
00242 } catch(Throwable t) {
00243 log.error("Exception writing command: " + HuskyBaseUtils.byteArrayToString(command), t);
00244 }
00245 }
00246 }