| 157 | kaklik | 1 | /*
 | 
        
           |  |  | 2 |     AVRcamVIEW: A PC application to test out the functionallity of the
 | 
        
           |  |  | 3 |      AVRcam real-time image processing engine.
 | 
        
           |  |  | 4 |     Copyright (C) 2004    Brent A. Taylor
 | 
        
           |  |  | 5 |   | 
        
           |  |  | 6 |     This program is free software; you can redistribute it and/or
 | 
        
           |  |  | 7 |     modify it under the terms of the GNU General Public
 | 
        
           |  |  | 8 |     License as published by the Free Software Foundation; either
 | 
        
           |  |  | 9 |     version 2 of the License, or (at your option) any later version.
 | 
        
           |  |  | 10 |   | 
        
           |  |  | 11 |     This program is distributed in the hope that it will be useful,
 | 
        
           |  |  | 12 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 13 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
        
           |  |  | 14 |     General Public License for more details.
 | 
        
           |  |  | 15 |   | 
        
           |  |  | 16 |     You should have received a copy of the GNU General Public
 | 
        
           |  |  | 17 |     License along with this program; if not, write to the Free Software
 | 
        
           |  |  | 18 |     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 |    For more information on the AVRcamVIEW, please contact:
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 |    taylorba@comcast.net
 | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 |    or go to www.jrobot.net for more details regarding the system.
 | 
        
           |  |  | 25 | */
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | package avr.device;
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 | import java.io.*;
 | 
        
           |  |  | 30 | import java.nio.*;
 | 
        
           |  |  | 31 | import java.util.*;
 | 
        
           |  |  | 32 | import javax.comm.*;
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 | import java.awt.*;
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 | import avr.connection.*;
 | 
        
           |  |  | 37 | import avr.connection.event.*;
 | 
        
           |  |  | 38 | import avr.device.event.*;
 | 
        
           |  |  | 39 | import avr.io.*;
 | 
        
           |  |  | 40 | import avr.lang.*;
 | 
        
           |  |  | 41 |   | 
        
           |  |  | 42 | public class Device implements ConnectionListener {
 | 
        
           |  |  | 43 |   | 
        
           |  |  | 44 |    public static void main(String[] args) throws Exception {
 | 
        
           |  |  | 45 |       Device device = new Device();
 | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 |       SerialParams params = new SerialParams();
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 |       device.setConnection(new SerialConnection("COM1", params));
 | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |       device.connect();
 | 
        
           |  |  | 52 |       device.sendPing();
 | 
        
           |  |  | 53 |       device.sendDumpFrame();
 | 
        
           |  |  | 54 |       device.sendGetVersion();
 | 
        
           |  |  | 55 |       device.sendSetRegisters(new HashMap());
 | 
        
           |  |  | 56 |       device.sendReset();
 | 
        
           |  |  | 57 |       device.sendEnableTracking();
 | 
        
           |  |  | 58 |       device.sendDisableTracking();
 | 
        
           |  |  | 59 |       device.sendSetColorMap(null, null, null);
 | 
        
           |  |  | 60 |   | 
        
           |  |  | 61 |       try {
 | 
        
           |  |  | 62 |          System.in.read();
 | 
        
           |  |  | 63 |       } catch(IOException ioe) {
 | 
        
           |  |  | 64 |          ioe.printStackTrace();
 | 
        
           |  |  | 65 |       }
 | 
        
           |  |  | 66 |       device.disconnect();
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 |    }
 | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 |    private static final String ACK = "ACK";
 | 
        
           |  |  | 71 |    private static final String NCK = "NCK";
 | 
        
           |  |  | 72 |    private static final String VERSION = "AVR";
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 |    private static final String COLOR_MAP_KEY = "avr.color.map";
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 |    // timeout after 3 seconds
 | 
        
           |  |  | 77 |    private static final int RESPONSE_TIMEOUT = 3000;
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 |    private java.util.List connectionListeners;
 | 
        
           |  |  | 80 |    private java.util.List dataListeners;
 | 
        
           |  |  | 81 |    private AbstractConnection con;
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 |    private InputStream in;
 | 
        
           |  |  | 84 |    private OutputStream out;
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 86 |    private int[][] colorMap;
 | 
        
           |  |  | 87 |    private Color[] mapColors;
 | 
        
           |  |  | 88 |   | 
        
           |  |  | 89 |    private Timer responseTimer;
 | 
        
           |  |  | 90 |    private TimerTask responseTask;
 | 
        
           |  |  | 91 |   | 
        
           |  |  | 92 |    public Device() {
 | 
        
           |  |  | 93 |       connectionListeners = new ArrayList(3);
 | 
        
           |  |  | 94 |       dataListeners = new ArrayList(3);
 | 
        
           |  |  | 95 |       loadMap();
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |       responseTimer = new Timer();
 | 
        
           |  |  | 98 |    }
 | 
        
           |  |  | 99 |   | 
        
           |  |  | 100 |    public Color[] getMapColors() {
 | 
        
           |  |  | 101 |       return mapColors;
 | 
        
           |  |  | 102 |    }
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 |    public int[][] getColorMap() {
 | 
        
           |  |  | 105 |       return colorMap;
 | 
        
           |  |  | 106 |    }
 | 
        
           |  |  | 107 |   | 
        
           |  |  | 108 |    public void setColorMap(int[][] colorMap) {
 | 
        
           |  |  | 109 |       this.colorMap = colorMap;
 | 
        
           |  |  | 110 |       setMapColors();
 | 
        
           |  |  | 111 |       saveMap();
 | 
        
           |  |  | 112 |    }
 | 
        
           |  |  | 113 |   | 
        
           |  |  | 114 |    public void saveMap() {
 | 
        
           |  |  | 115 |       try {
 | 
        
           |  |  | 116 |          ByteArrayOutputStream bOut = new ByteArrayOutputStream();
 | 
        
           |  |  | 117 |          DataOutputStream dOut = new DataOutputStream(bOut);
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 |          dOut.writeInt(colorMap.length);
 | 
        
           |  |  | 120 |          for(int i = 0; i < colorMap.length; i++) {
 | 
        
           |  |  | 121 |             dOut.writeInt(colorMap[i].length);
 | 
        
           |  |  | 122 |             for(int j = 0; j < colorMap[i].length; j++) {
 | 
        
           |  |  | 123 |                dOut.writeInt(colorMap[i][j]);
 | 
        
           |  |  | 124 |             }
 | 
        
           |  |  | 125 |          }
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 |          dOut.close();
 | 
        
           |  |  | 128 |   | 
        
           |  |  | 129 |          AVRSystem.PREFS.putByteArray(COLOR_MAP_KEY, bOut.toByteArray());
 | 
        
           |  |  | 130 |   | 
        
           |  |  | 131 |       } catch(Exception e) {
 | 
        
           |  |  | 132 |          e.printStackTrace();
 | 
        
           |  |  | 133 |       }
 | 
        
           |  |  | 134 |    }
 | 
        
           |  |  | 135 |   | 
        
           |  |  | 136 |    public void loadMap() {
 | 
        
           |  |  | 137 |       try {
 | 
        
           |  |  | 138 |          byte[] data = AVRSystem.PREFS.getByteArray(COLOR_MAP_KEY, null);
 | 
        
           |  |  | 139 |          if(data != null) {
 | 
        
           |  |  | 140 |             ByteArrayInputStream bIn = new ByteArrayInputStream(data);
 | 
        
           |  |  | 141 |             DataInputStream dIn = new DataInputStream(bIn);
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |             int width = dIn.readInt();
 | 
        
           |  |  | 144 |             colorMap = new int[width][];
 | 
        
           |  |  | 145 |             for(int i = 0; i < colorMap.length; i++) {
 | 
        
           |  |  | 146 |                colorMap[i] = new int[dIn.readInt()];
 | 
        
           |  |  | 147 |                for(int j = 0; j < colorMap[i].length; j++) {
 | 
        
           |  |  | 148 |                   colorMap[i][j] = dIn.readInt();
 | 
        
           |  |  | 149 |                }
 | 
        
           |  |  | 150 |             }
 | 
        
           |  |  | 151 |   | 
        
           |  |  | 152 |             dIn.close();
 | 
        
           |  |  | 153 |          } else {
 | 
        
           |  |  | 154 |             colorMap = new int[3][AVRSystem.NUM_INTENSITIES];
 | 
        
           |  |  | 155 |          }
 | 
        
           |  |  | 156 |   | 
        
           |  |  | 157 |          setMapColors();
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 |       } catch(Exception e) {
 | 
        
           |  |  | 160 |          e.printStackTrace();
 | 
        
           |  |  | 161 |       }
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |    }
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 |    private void setMapColors() {
 | 
        
           |  |  | 166 |       mapColors = new Color[8];
 | 
        
           |  |  | 167 |   | 
        
           |  |  | 168 |       for(int col = 0; col < mapColors.length; col++) {
 | 
        
           |  |  | 169 |          int value = 0;
 | 
        
           |  |  | 170 |   | 
        
           |  |  | 171 |          int red = 0;
 | 
        
           |  |  | 172 |          int green = 0;
 | 
        
           |  |  | 173 |          int blue = 0;
 | 
        
           |  |  | 174 |   | 
        
           |  |  | 175 |          int numRed = 0;
 | 
        
           |  |  | 176 |          int numGreen = 0;
 | 
        
           |  |  | 177 |          int numBlue = 0;
 | 
        
           |  |  | 178 |   | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |          for(int i = 0; i < AVRSystem.NUM_INTENSITIES; i++) {
 | 
        
           |  |  | 181 |   | 
        
           |  |  | 182 |             if((colorMap[0][i] & (0x01 << (7 - col))) != 0) {
 | 
        
           |  |  | 183 |                red += i << 4;
 | 
        
           |  |  | 184 |                numRed++;
 | 
        
           |  |  | 185 |             }
 | 
        
           |  |  | 186 |   | 
        
           |  |  | 187 |             if((colorMap[1][i] & (0x01 << (7 - col))) != 0) {
 | 
        
           |  |  | 188 |                green += i << 4;
 | 
        
           |  |  | 189 |                numGreen++;
 | 
        
           |  |  | 190 |             }
 | 
        
           |  |  | 191 |   | 
        
           |  |  | 192 |             if((colorMap[2][i] & (0x01 << (7 - col))) != 0) {
 | 
        
           |  |  | 193 |                blue += i << 4;
 | 
        
           |  |  | 194 |                numBlue++;
 | 
        
           |  |  | 195 |             }
 | 
        
           |  |  | 196 |   | 
        
           |  |  | 197 |          }
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 |          if(numRed > 0) {
 | 
        
           |  |  | 200 |             red /= numRed;
 | 
        
           |  |  | 201 |          }
 | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 |          if(numGreen > 0) {
 | 
        
           |  |  | 204 |             green /= numGreen;
 | 
        
           |  |  | 205 |          }
 | 
        
           |  |  | 206 |   | 
        
           |  |  | 207 |          if(numBlue > 0) {
 | 
        
           |  |  | 208 |             blue /= numBlue;
 | 
        
           |  |  | 209 |          }
 | 
        
           |  |  | 210 |   | 
        
           |  |  | 211 |          value = (red << 16) | (green << 8) | blue;
 | 
        
           |  |  | 212 |   | 
        
           |  |  | 213 |          mapColors[col] = new Color(value);
 | 
        
           |  |  | 214 |       }
 | 
        
           |  |  | 215 |   | 
        
           |  |  | 216 |    }
 | 
        
           |  |  | 217 |   | 
        
           |  |  | 218 |    public AbstractConnection getConnection() {
 | 
        
           |  |  | 219 |       return con;
 | 
        
           |  |  | 220 |    }
 | 
        
           |  |  | 221 |   | 
        
           |  |  | 222 |    public void setConnection(AbstractConnection con) {
 | 
        
           |  |  | 223 |       this.con = con;
 | 
        
           |  |  | 224 |    }
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 |    public boolean isConnected() {
 | 
        
           |  |  | 227 |       return con != null && con.isConnected();
 | 
        
           |  |  | 228 |    }
 | 
        
           |  |  | 229 |   | 
        
           |  |  | 230 |    public void addConnectionListener(ConnectionListener listener) {
 | 
        
           |  |  | 231 |       AVRSystem.LOG.finest("Added Connection Listener: " + listener);
 | 
        
           |  |  | 232 |       connectionListeners.add(listener);
 | 
        
           |  |  | 233 |    }
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 |    public void removeConnectionListener(ConnectionListener listener) {
 | 
        
           |  |  | 236 |       AVRSystem.LOG.finest("Removed Connection Listener: " + listener);
 | 
        
           |  |  | 237 |       connectionListeners.remove(listener);
 | 
        
           |  |  | 238 |    }
 | 
        
           |  |  | 239 |   | 
        
           |  |  | 240 |    public void connected(ConnectionEvent event) {
 | 
        
           |  |  | 241 |       ConnectionListener[] listeners = (ConnectionListener[])connectionListeners.toArray(new ConnectionListener[connectionListeners.size()]);
 | 
        
           |  |  | 242 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 243 |          ((ConnectionListener)listeners[i]).connected(event);
 | 
        
           |  |  | 244 |       }
 | 
        
           |  |  | 245 |    }
 | 
        
           |  |  | 246 |   | 
        
           |  |  | 247 |    public void disconnected(ConnectionEvent event) {
 | 
        
           |  |  | 248 |       ConnectionListener[] listeners = (ConnectionListener[])connectionListeners.toArray(new ConnectionListener[connectionListeners.size()]);
 | 
        
           |  |  | 249 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 250 |          ((ConnectionListener)listeners[i]).disconnected(event);
 | 
        
           |  |  | 251 |       }
 | 
        
           |  |  | 252 |    }
 | 
        
           |  |  | 253 |   | 
        
           |  |  | 254 |    public void connect() throws Exception {
 | 
        
           |  |  | 255 |   | 
        
           |  |  | 256 |       if(!isConnected()) {
 | 
        
           |  |  | 257 |          con.connect();
 | 
        
           |  |  | 258 |   | 
        
           |  |  | 259 |          if(con instanceof SerialConnection) {
 | 
        
           |  |  | 260 |             SerialPort serialPort = (SerialPort)con.getConnectionObject();
 | 
        
           |  |  | 261 |             serialPort.notifyOnDataAvailable(true);
 | 
        
           |  |  | 262 |             try {
 | 
        
           |  |  | 263 |                serialPort.addEventListener(new SerialEventHandler(this));
 | 
        
           |  |  | 264 |             } catch(TooManyListenersException tmle) {
 | 
        
           |  |  | 265 |                AVRSystem.LOG.severe(tmle.getMessage());
 | 
        
           |  |  | 266 |             }
 | 
        
           |  |  | 267 |          }
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |          in = new AVRInputStream(con.getInputStream());
 | 
        
           |  |  | 270 |          out = con.getOutputStream();
 | 
        
           |  |  | 271 |   | 
        
           |  |  | 272 |          AVRSystem.LOG.config("Device connected to " + con.toString());
 | 
        
           |  |  | 273 |   | 
        
           |  |  | 274 |          connected(new ConnectionEvent(con));
 | 
        
           |  |  | 275 |   | 
        
           |  |  | 276 |       }
 | 
        
           |  |  | 277 |    }
 | 
        
           |  |  | 278 |   | 
        
           |  |  | 279 |    public void disconnect() {
 | 
        
           |  |  | 280 |   | 
        
           |  |  | 281 |       if(isConnected()) {
 | 
        
           |  |  | 282 |          try {
 | 
        
           |  |  | 283 |             con.disconnect();
 | 
        
           |  |  | 284 |             AVRSystem.LOG.config("Device Disconnected");
 | 
        
           |  |  | 285 |             disconnected(new ConnectionEvent(con));
 | 
        
           |  |  | 286 |             con = null;
 | 
        
           |  |  | 287 |          } catch(IOException ioe) {
 | 
        
           |  |  | 288 |             AVRSystem.LOG.severe(ioe.getMessage());
 | 
        
           |  |  | 289 |          }
 | 
        
           |  |  | 290 |       }
 | 
        
           |  |  | 291 |    }
 | 
        
           |  |  | 292 |   | 
        
           |  |  | 293 |    public InputStream getInputStream() {
 | 
        
           |  |  | 294 |       return in;
 | 
        
           |  |  | 295 |    }
 | 
        
           |  |  | 296 |   | 
        
           |  |  | 297 |    public void addDataListener(DataListener dl) {
 | 
        
           |  |  | 298 |       if(dataListeners.add(dl)) {
 | 
        
           |  |  | 299 |          AVRSystem.LOG.finest("Added Data Listener: " + dl);
 | 
        
           |  |  | 300 |       }
 | 
        
           |  |  | 301 |    }
 | 
        
           |  |  | 302 |   | 
        
           |  |  | 303 |    public void removeDataListener(DataListener dl) {
 | 
        
           |  |  | 304 |       if(dataListeners.remove(dl)) {
 | 
        
           |  |  | 305 |          AVRSystem.LOG.finest("Removed Data Listener: " + dl);
 | 
        
           |  |  | 306 |       }
 | 
        
           |  |  | 307 |    }
 | 
        
           |  |  | 308 |   | 
        
           |  |  | 309 |    protected void handleString(String data) {
 | 
        
           |  |  | 310 |       if(data.equals(ACK)) {
 | 
        
           |  |  | 311 |          fireACKReceived();
 | 
        
           |  |  | 312 |       } else if(data.equals(NCK)) {
 | 
        
           |  |  | 313 |          fireNCKReceived();
 | 
        
           |  |  | 314 |       } else if(data.startsWith(VERSION)) {
 | 
        
           |  |  | 315 |          fireVERSIONReceived(data);
 | 
        
           |  |  | 316 |       } else {
 | 
        
           |  |  | 317 |          StringBuffer builder = new StringBuffer("UNKNOWN PACKET: (");
 | 
        
           |  |  | 318 |          ByteBuffer bytes = ByteBuffer.wrap(data.getBytes());
 | 
        
           |  |  | 319 |          builder.append(bytes.remaining()).append(") ");
 | 
        
           |  |  | 320 |          while(bytes.hasRemaining()) {
 | 
        
           |  |  | 321 |             builder.append(Integer.toHexString(bytes.get() & 0xFF)).append(' ');
 | 
        
           |  |  | 322 |          }
 | 
        
           |  |  | 323 |          AVRSystem.LOG.warning(builder.toString());
 | 
        
           |  |  | 324 |       }
 | 
        
           |  |  | 325 |    }
 | 
        
           |  |  | 326 |   | 
        
           |  |  | 327 |    protected void handleData(ByteBuffer data) {
 | 
        
           |  |  | 328 |       if(data.hasRemaining()) {
 | 
        
           |  |  | 329 |          byte dataType = data.get();
 | 
        
           |  |  | 330 |          if(dataType == 0x0B) {
 | 
        
           |  |  | 331 |             fireFrameDataReceived(data);
 | 
        
           |  |  | 332 |          } else if(dataType == 0x0A) {
 | 
        
           |  |  | 333 |             fireTrackingDataReceived(data);
 | 
        
           |  |  | 334 |          } else {
 | 
        
           |  |  | 335 |             handleString(new String(data.array(), 0, data.limit()));
 | 
        
           |  |  | 336 |          }
 | 
        
           |  |  | 337 |       }
 | 
        
           |  |  | 338 |    }
 | 
        
           |  |  | 339 |   | 
        
           |  |  | 340 |    protected void fireACKReceived() {
 | 
        
           |  |  | 341 |       if(responseTask != null) {
 | 
        
           |  |  | 342 |          responseTask.cancel();
 | 
        
           |  |  | 343 |       }
 | 
        
           |  |  | 344 |       AVRSystem.LOG.info("Received: ACK");
 | 
        
           |  |  | 345 |       DataListener[] listeners = (DataListener[])dataListeners.toArray(new DataListener[dataListeners.size()]);
 | 
        
           |  |  | 346 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 347 |          ((DataListener)listeners[i]).ack();
 | 
        
           |  |  | 348 |       }
 | 
        
           |  |  | 349 |    }
 | 
        
           |  |  | 350 |   | 
        
           |  |  | 351 |    private void fireResponseTimerExpired() {
 | 
        
           |  |  | 352 |       AVRSystem.LOG.severe("Response Timer Expired");
 | 
        
           |  |  | 353 |       DataListener[] listeners = (DataListener[])dataListeners.toArray(new DataListener[dataListeners.size()]);
 | 
        
           |  |  | 354 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 355 |          ((DataListener)listeners[i]).responseTimerExpired();
 | 
        
           |  |  | 356 |       }
 | 
        
           |  |  | 357 |    }
 | 
        
           |  |  | 358 |   | 
        
           |  |  | 359 |    protected void fireNCKReceived() {
 | 
        
           |  |  | 360 |       if(responseTask != null) {
 | 
        
           |  |  | 361 |          responseTask.cancel();
 | 
        
           |  |  | 362 |       }
 | 
        
           |  |  | 363 |       AVRSystem.LOG.info("Received: NCK");
 | 
        
           |  |  | 364 |       DataListener[] listeners = (DataListener[])dataListeners.toArray(new DataListener[dataListeners.size()]);
 | 
        
           |  |  | 365 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 366 |          ((DataListener)listeners[i]).nck();
 | 
        
           |  |  | 367 |       }
 | 
        
           |  |  | 368 |    }
 | 
        
           |  |  | 369 |   | 
        
           |  |  | 370 |    protected void fireVERSIONReceived(String version) {
 | 
        
           |  |  | 371 |       if(responseTask != null) {
 | 
        
           |  |  | 372 |          responseTask.cancel();
 | 
        
           |  |  | 373 |       }
 | 
        
           |  |  | 374 |       AVRSystem.LOG.info("Received: " + version);
 | 
        
           |  |  | 375 |       DataListener[] listeners = (DataListener[])dataListeners.toArray(new DataListener[dataListeners.size()]);
 | 
        
           |  |  | 376 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 377 |          ((DataListener)listeners[i]).version(version);
 | 
        
           |  |  | 378 |       }
 | 
        
           |  |  | 379 |    }
 | 
        
           |  |  | 380 |   | 
        
           |  |  | 381 |    protected void fireFrameDataReceived(ByteBuffer data) {
 | 
        
           |  |  | 382 |   | 
        
           |  |  | 383 |       int position = data.position();
 | 
        
           |  |  | 384 |       StringBuffer buf = new StringBuffer("Received: Frame Dump (" + (data.get(position) & 0xFF) + ")");
 | 
        
           |  |  | 385 |   | 
        
           |  |  | 386 |       data.position(0);
 | 
        
           |  |  | 387 |   | 
        
           |  |  | 388 |       while(data.hasRemaining()) {
 | 
        
           |  |  | 389 |          int b = data.get() & 0xFF;
 | 
        
           |  |  | 390 |          buf.append(' ').append(((b & 0xF0) == 0) ? "0" : "").append(Integer.toHexString(b).toUpperCase());
 | 
        
           |  |  | 391 |       }
 | 
        
           |  |  | 392 |   | 
        
           |  |  | 393 |       data.position(position);
 | 
        
           |  |  | 394 |   | 
        
           |  |  | 395 |       AVRSystem.LOG.info(buf.toString());
 | 
        
           |  |  | 396 | //      AVRSystem.LOG.info("Received: Frame Dump (" + (data.get(data.position()) & 0xFF) + ")");
 | 
        
           |  |  | 397 |       DataListener[] listeners = (DataListener[])dataListeners.toArray(new DataListener[dataListeners.size()]);
 | 
        
           |  |  | 398 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 399 |          data.mark();
 | 
        
           |  |  | 400 |          ((DataListener)listeners[i]).frameData(data);
 | 
        
           |  |  | 401 |          data.reset();
 | 
        
           |  |  | 402 |       }
 | 
        
           |  |  | 403 |    }
 | 
        
           |  |  | 404 |   | 
        
           |  |  | 405 |    protected void fireTrackingDataReceived(ByteBuffer data) {
 | 
        
           |  |  | 406 |   | 
        
           |  |  | 407 |       int position = data.position();
 | 
        
           |  |  | 408 |       StringBuffer buf = new StringBuffer("Received: Tracking Info (" + (data.get(position) & 0xFF) + ")");
 | 
        
           |  |  | 409 |   | 
        
           |  |  | 410 |       data.position(0);
 | 
        
           |  |  | 411 |   | 
        
           |  |  | 412 |       while(data.hasRemaining()) {
 | 
        
           |  |  | 413 |          int b = data.get() & 0xFF;
 | 
        
           |  |  | 414 |          buf.append(' ').append(((b & 0xF0) == 0) ? "0" : "").append(Integer.toHexString(b).toUpperCase());
 | 
        
           |  |  | 415 |       }
 | 
        
           |  |  | 416 |   | 
        
           |  |  | 417 |       data.position(position);
 | 
        
           |  |  | 418 |   | 
        
           |  |  | 419 |       AVRSystem.LOG.info(buf.toString());
 | 
        
           |  |  | 420 |       DataListener[] listeners = (DataListener[])dataListeners.toArray(new DataListener[dataListeners.size()]);
 | 
        
           |  |  | 421 |       for(int i = 0; i < listeners.length; i++) {
 | 
        
           |  |  | 422 |          data.mark();
 | 
        
           |  |  | 423 |          ((DataListener)listeners[i]).trackingData(data);
 | 
        
           |  |  | 424 |          data.reset();
 | 
        
           |  |  | 425 |       }
 | 
        
           |  |  | 426 |    }
 | 
        
           |  |  | 427 |   | 
        
           |  |  | 428 |    private void sendRequest(byte[] data) throws IOException {
 | 
        
           |  |  | 429 |       sendRequest(data, 0, data.length);
 | 
        
           |  |  | 430 |    }
 | 
        
           |  |  | 431 |   | 
        
           |  |  | 432 |    private void sendRequest(byte[] data, int off, int len) throws IOException {
 | 
        
           |  |  | 433 |   | 
        
           |  |  | 434 |       responseTask = new ResponseTask();
 | 
        
           |  |  | 435 |       responseTimer.schedule(responseTask, RESPONSE_TIMEOUT);
 | 
        
           |  |  | 436 |   | 
        
           |  |  | 437 |       if(isConnected()) {
 | 
        
           |  |  | 438 |   | 
        
           |  |  | 439 |          out.write(data, off, len);
 | 
        
           |  |  | 440 |          out.write((byte)'\n');
 | 
        
           |  |  | 441 |          out.flush();
 | 
        
           |  |  | 442 |   | 
        
           |  |  | 443 |          StringBuffer builder = new StringBuffer("Sending: ");
 | 
        
           |  |  | 444 |          for(int i = off; i < len; i++) {
 | 
        
           |  |  | 445 |             builder.append((char)data[i]);
 | 
        
           |  |  | 446 |          }
 | 
        
           |  |  | 447 |          AVRSystem.LOG.info(builder.toString());
 | 
        
           |  |  | 448 |       } else {
 | 
        
           |  |  | 449 |          AVRSystem.LOG.warning("AVRcam not connected.");
 | 
        
           |  |  | 450 |       }
 | 
        
           |  |  | 451 |    }
 | 
        
           |  |  | 452 |   | 
        
           |  |  | 453 |    public void sendSetRegisters(Map registers) throws IOException {
 | 
        
           |  |  | 454 |       ByteBuffer buffer = ByteBuffer.allocate(60);
 | 
        
           |  |  | 455 |       buffer.put((byte)'C')
 | 
        
           |  |  | 456 |             .put((byte)'R');
 | 
        
           |  |  | 457 |   | 
        
           |  |  | 458 |      Set entries = registers.entrySet();
 | 
        
           |  |  | 459 |      for(Iterator i = entries.iterator(); i.hasNext();) {
 | 
        
           |  |  | 460 |         Map.Entry entry = (Map.Entry)i.next();
 | 
        
           |  |  | 461 |         buffer.put((byte)' ').put(entry.getKey().toString().getBytes())
 | 
        
           |  |  | 462 |               .put((byte)' ').put(entry.getValue().toString().getBytes());
 | 
        
           |  |  | 463 |      }
 | 
        
           |  |  | 464 |   | 
        
           |  |  | 465 |       buffer.put((byte)'\r');
 | 
        
           |  |  | 466 |       buffer.flip();
 | 
        
           |  |  | 467 |       sendRequest(buffer.array(), 0, buffer.remaining());
 | 
        
           |  |  | 468 |    }
 | 
        
           |  |  | 469 |   | 
        
           |  |  | 470 |    public void sendDisableTracking() throws IOException {
 | 
        
           |  |  | 471 |       sendRequest(new byte[] { (byte)'D', (byte)'T', (byte)'\r'} );
 | 
        
           |  |  | 472 |    }
 | 
        
           |  |  | 473 |   | 
        
           |  |  | 474 |    public void sendDumpFrame() throws IOException {
 | 
        
           |  |  | 475 |       sendRequest(new byte[] { (byte)'D', (byte)'F', (byte)'\r'} );
 | 
        
           |  |  | 476 |    }
 | 
        
           |  |  | 477 |   | 
        
           |  |  | 478 |    public void sendEnableTracking() throws IOException {
 | 
        
           |  |  | 479 |       sendRequest(new byte[] { (byte)'E', (byte)'T', (byte)'\r'} );
 | 
        
           |  |  | 480 |    }
 | 
        
           |  |  | 481 |   | 
        
           |  |  | 482 |    public void sendGetVersion() throws IOException {
 | 
        
           |  |  | 483 |       sendRequest(new byte[] { (byte)'G', (byte)'V', (byte)'\r'} );
 | 
        
           |  |  | 484 |    }
 | 
        
           |  |  | 485 |   | 
        
           |  |  | 486 |    public void sendPing() throws IOException {
 | 
        
           |  |  | 487 |       sendRequest(new byte[] { (byte)'P', (byte)'G', (byte)'\r'} );
 | 
        
           |  |  | 488 |    }
 | 
        
           |  |  | 489 |   | 
        
           |  |  | 490 |    public void sendReset() throws IOException {
 | 
        
           |  |  | 491 |       sendRequest(new byte[] { (byte)'R', (byte)'S', (byte)'\r'} );
 | 
        
           |  |  | 492 |    }
 | 
        
           |  |  | 493 |   | 
        
           |  |  | 494 |    public void sendSetColorMap(int[] red, int[] green, int[] blue) throws IOException {
 | 
        
           |  |  | 495 |       ByteBuffer buffer = ByteBuffer.allocate(2 + 4 * red.length * 3 + 1);
 | 
        
           |  |  | 496 |       buffer.put("SM".getBytes());
 | 
        
           |  |  | 497 |       for(int i = 0; i < red.length; i++) {
 | 
        
           |  |  | 498 |          buffer.put((" " + red[i] + "").getBytes());
 | 
        
           |  |  | 499 |       }
 | 
        
           |  |  | 500 |       for(int i = 0; i < green.length; i++) {
 | 
        
           |  |  | 501 |          buffer.put((" " + green[i] + "").getBytes());
 | 
        
           |  |  | 502 |       }
 | 
        
           |  |  | 503 |       for(int i = 0; i < blue.length; i++) {
 | 
        
           |  |  | 504 |          buffer.put((" " + blue[i] + "").getBytes());
 | 
        
           |  |  | 505 |       }
 | 
        
           |  |  | 506 |       buffer.put("\r".getBytes());
 | 
        
           |  |  | 507 |       buffer.flip();
 | 
        
           |  |  | 508 |       sendRequest(buffer.array(), 0, buffer.remaining());
 | 
        
           |  |  | 509 |    }
 | 
        
           |  |  | 510 |   | 
        
           |  |  | 511 |    public void sendCameraData(ByteBuffer data) throws IOException {
 | 
        
           |  |  | 512 |   | 
        
           |  |  | 513 |       out.write((byte)0x0A);
 | 
        
           |  |  | 514 |       out.write(data.array(), 0, data.remaining());
 | 
        
           |  |  | 515 |       out.write((byte)0xFF);
 | 
        
           |  |  | 516 |   | 
        
           |  |  | 517 |       out.flush();
 | 
        
           |  |  | 518 |   | 
        
           |  |  | 519 |    }
 | 
        
           |  |  | 520 |   | 
        
           |  |  | 521 |    private final static class SerialEventHandler implements SerialPortEventListener {
 | 
        
           |  |  | 522 |   | 
        
           |  |  | 523 |       private Device device;
 | 
        
           |  |  | 524 |   | 
        
           |  |  | 525 |       public SerialEventHandler(Device device) {
 | 
        
           |  |  | 526 |          this.device = device;
 | 
        
           |  |  | 527 |       }
 | 
        
           |  |  | 528 |   | 
        
           |  |  | 529 |       public void serialEvent(SerialPortEvent spe) {
 | 
        
           |  |  | 530 |          if(spe.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
 | 
        
           |  |  | 531 |   | 
        
           |  |  | 532 |             try {
 | 
        
           |  |  | 533 |   | 
        
           |  |  | 534 |                do {
 | 
        
           |  |  | 535 |   | 
        
           |  |  | 536 |                   byte[] data = new byte[1024];
 | 
        
           |  |  | 537 |   | 
        
           |  |  | 538 |                   int bytesRead = device.getInputStream().read(data);
 | 
        
           |  |  | 539 |                   if(bytesRead > 0) {
 | 
        
           |  |  | 540 |                      // take only bytesRead - 1 to remove the
 | 
        
           |  |  | 541 |                      // terminating character '\r' or 0xFF
 | 
        
           |  |  | 542 |                      EventQueue.invokeLater(new GUITask(device, ByteBuffer.wrap(data, 0, bytesRead - 1)));
 | 
        
           |  |  | 543 |                   }
 | 
        
           |  |  | 544 |   | 
        
           |  |  | 545 |                } while(device.getInputStream().available() > 0);
 | 
        
           |  |  | 546 |   | 
        
           |  |  | 547 |             } catch(IOException ioe) {
 | 
        
           |  |  | 548 |                AVRSystem.LOG.severe(ioe.getMessage());
 | 
        
           |  |  | 549 |                device.disconnect();
 | 
        
           |  |  | 550 |             }
 | 
        
           |  |  | 551 |   | 
        
           |  |  | 552 |          }
 | 
        
           |  |  | 553 |       }
 | 
        
           |  |  | 554 |   | 
        
           |  |  | 555 |    }
 | 
        
           |  |  | 556 |   | 
        
           |  |  | 557 |    private final static class GUITask implements Runnable {
 | 
        
           |  |  | 558 |       private ByteBuffer data;
 | 
        
           |  |  | 559 |       private Device device;
 | 
        
           |  |  | 560 |   | 
        
           |  |  | 561 |       public GUITask(Device device, ByteBuffer data) {
 | 
        
           |  |  | 562 |          this.device = device;
 | 
        
           |  |  | 563 |          this.data = data;
 | 
        
           |  |  | 564 |       }
 | 
        
           |  |  | 565 |   | 
        
           |  |  | 566 |       public void run() {
 | 
        
           |  |  | 567 |          device.handleData(data);
 | 
        
           |  |  | 568 |       }
 | 
        
           |  |  | 569 |   | 
        
           |  |  | 570 |    }
 | 
        
           |  |  | 571 |   | 
        
           |  |  | 572 |    private final class ResponseTask extends TimerTask {
 | 
        
           |  |  | 573 |   | 
        
           |  |  | 574 |       public void run() {
 | 
        
           |  |  | 575 |          // make sure we fire the timer expired event
 | 
        
           |  |  | 576 |          // using the Event Dispatch Thread.  If not,
 | 
        
           |  |  | 577 |          // queue this TimerTask in the Event Queue.
 | 
        
           |  |  | 578 |          if(EventQueue.isDispatchThread()) {
 | 
        
           |  |  | 579 |             fireResponseTimerExpired();
 | 
        
           |  |  | 580 |          } else {
 | 
        
           |  |  | 581 |             EventQueue.invokeLater(this);
 | 
        
           |  |  | 582 |          }
 | 
        
           |  |  | 583 |       }
 | 
        
           |  |  | 584 |   | 
        
           |  |  | 585 |    }
 | 
        
           |  |  | 586 |   | 
        
           |  |  | 587 |    /**
 | 
        
           |  |  | 588 |     * Only used for debugging purposes, this will simulate an ACK coming from the device.
 | 
        
           |  |  | 589 |     */
 | 
        
           |  |  | 590 |    public void simulateACK() {
 | 
        
           |  |  | 591 |       fireACKReceived();
 | 
        
           |  |  | 592 |    }
 | 
        
           |  |  | 593 |   | 
        
           |  |  | 594 |    /**
 | 
        
           |  |  | 595 |     * Only used for debugging purposes, this will simulate an NCK coming from the device.
 | 
        
           |  |  | 596 |     */
 | 
        
           |  |  | 597 |    public void simulateNCK() {
 | 
        
           |  |  | 598 |       fireNCKReceived();
 | 
        
           |  |  | 599 |    }
 | 
        
           |  |  | 600 |   | 
        
           |  |  | 601 | }
 |