00001 /* 00002 * Degausser.java 00003 * 00004 * Copyright (C) 2005 Project SQUID, http://www.cs.helsinki.fi/group/squid/ 00005 * 00006 * This file is part of Ikayaki. 00007 * 00008 * Ikayaki is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * Ikayaki is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with Ikayaki; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 package ikayaki.squid; 00024 00025 import ikayaki.Settings; 00026 00027 import java.util.Stack; 00028 import java.util.concurrent.SynchronousQueue; 00029 import java.util.concurrent.TimeUnit; 00030 00038 public class Degausser implements SerialIOListener { 00039 00043 private Stack<String> messageBuffer; 00044 00048 private SynchronousQueue<String> queue; 00049 private int pollTimeout = 60; 00050 00054 protected SerialIO serialIO; 00055 00059 private int degausserDelay; 00060 00064 private int degausserRamp; 00065 00066 private boolean waitingForMessage = false; 00067 private double minimumField; 00068 private double maximumField; 00069 00070 private boolean demagnetizing = false; 00071 00076 public Degausser() throws SerialIOException { 00077 this.serialIO = SerialIO.openPort(new SerialParameters(Settings.getDegausserPort())); 00078 serialIO.addSerialIOListener(this); 00079 messageBuffer = new Stack<String>(); 00080 queue = new SynchronousQueue<String>(); 00081 this.degausserDelay = Settings.getDegausserDelay(); 00082 this.degausserRamp = Settings.getDegausserRamp(); 00083 this.minimumField = Settings.getDegausserMinimumField(); 00084 this.maximumField = Settings.getDegausserMaximumField(); 00085 00086 //needs to call new functions setDelay() and setRamp(). TODO 00087 //TODO: do we need to check values? (original does) 00088 try { 00089 blockingWrite("DCD" + this.degausserDelay); 00090 } catch (SerialIOException ex1) { 00091 System.err.println("Error using port in degausser:" + ex1); 00092 } 00093 try { 00094 blockingWrite("DCR" + this.degausserRamp); 00095 } catch (SerialIOException ex1) { 00096 System.err.println("Error using port in degausser:" + ex1); 00097 } 00098 } 00099 00104 public void updateSettings() { 00105 // No check, only two options. Doesnt matter. 00106 this.degausserDelay = Settings.getDegausserDelay(); 00107 this.degausserRamp = Settings.getDegausserRamp(); 00108 this.minimumField = Settings.getDegausserMinimumField(); 00109 this.maximumField = Settings.getDegausserMaximumField(); 00110 try { 00111 blockingWrite("DCD" + this.degausserDelay); 00112 } catch (SerialIOException ex1) { 00113 System.err.println("Error using port in degausser:" + ex1); 00114 } 00115 try { 00116 blockingWrite("DCR" + this.degausserRamp); 00117 } catch (SerialIOException ex1) { 00118 System.err.println("Error using port in degausser:" + ex1); 00119 } 00120 } 00121 00127 protected void setCoil(char coil) { 00128 if (coil == 'X' || coil == 'Y' || coil == 'Z') { 00129 try { 00130 blockingWrite("DCC" + coil); 00131 } catch (SerialIOException e) { 00132 e.printStackTrace(); 00133 } 00134 } else { 00135 throw new IllegalArgumentException("coil = " + coil); 00136 } 00137 } 00138 00146 protected void setAmplitude(double amplitude) { 00147 if (amplitude >= minimumField && amplitude <= maximumField) { 00148 try { 00149 String amps = Integer.toString((int) Math.round(amplitude * 10.0)); 00150 while (amps.length() < 4) { 00151 amps = "0" + amps; 00152 } 00153 blockingWrite("DCA" + amps); 00154 Thread.sleep(1500); // needs to wait for the degausser to process the command 00155 00156 } catch (SerialIOException e) { 00157 e.printStackTrace(); 00158 } catch (InterruptedException e) { 00159 e.printStackTrace(); 00160 } 00161 } else { 00162 throw new IllegalArgumentException("amplitude = " + amplitude); 00163 } 00164 } 00165 00169 protected void executeRampUp() { 00170 try { 00171 blockingWrite("DERU"); 00172 } catch (SerialIOException e) { 00173 e.printStackTrace(); 00174 } 00175 } 00176 00180 protected void executeRampDown() { 00181 try { 00182 blockingWrite("DERD"); 00183 } catch (SerialIOException e) { 00184 e.printStackTrace(); 00185 } 00186 } 00187 00191 protected void executeRampCycle() { 00192 try { 00193 blockingWrite("DERC"); 00194 } catch (SerialIOException e) { 00195 e.printStackTrace(); 00196 } 00197 } 00198 00199 protected void blockingWrite(String command) throws SerialIOException { 00200 try { 00201 serialIO.writeMessage(command + "\r"); 00202 00203 waitingForMessage = true; 00204 String answer = queue.take(); 00205 waitingForMessage = false; 00206 00207 if (!command.equals(answer)) { 00208 // for (int i = 0; i < answer.length(); i++) { 00209 // System.out.println((int) answer.charAt(i)); 00210 // } 00211 // throw new IllegalArgumentException("sent: " + command + " recieved: " + answer); 00212 System.err.println("Degausser.blockingWrite() sent: " + command + " recieved: " + answer); 00213 } 00214 00215 } catch (InterruptedException e) { 00216 e.printStackTrace(); 00217 } 00218 } 00219 00226 public boolean demagnetizeZ(double amp) { 00227 setAmplitude(amp); 00228 setCoil('Z'); 00229 demagnetizing = true; 00230 executeRampCycle(); 00231 00232 // need to wait for DONE message or TRACK ERROR message 00233 waitingForMessage = true; 00234 String answer = null; 00235 try { 00236 answer = queue.take(); 00237 } catch (InterruptedException e) { 00238 e.printStackTrace(); 00239 } 00240 waitingForMessage = false; 00241 demagnetizing = false; 00242 00243 if (answer.equals("DONE")) { 00244 return true; 00245 } else { 00246 return false; 00247 } 00248 00249 } 00250 00257 public boolean demagnetizeY(double amp) { 00258 setAmplitude(amp); 00259 setCoil('Y'); 00260 demagnetizing = true; 00261 executeRampCycle(); 00262 00263 // need to wait for DONE message or TRACK ERROR message 00264 waitingForMessage = true; 00265 String answer = null; 00266 try { 00267 answer = (String) queue.take(); 00268 } catch (InterruptedException e) { 00269 e.printStackTrace(); 00270 } 00271 waitingForMessage = false; 00272 demagnetizing = false; 00273 00274 if (answer.equals("DONE")) { 00275 return true; 00276 } else { 00277 return false; 00278 } 00279 } 00280 00281 public boolean isDemagnetizing() { 00282 return demagnetizing; 00283 } 00284 00290 public char getRampStatus() { 00291 try { 00292 blockingWrite("DSS"); 00293 } catch (SerialIOException e) { 00294 e.printStackTrace(); 00295 } 00296 waitingForMessage = true; 00297 String answer = null; 00298 try { 00299 answer = (String) queue.poll(pollTimeout, TimeUnit.SECONDS); 00300 } catch (InterruptedException e) { 00301 e.printStackTrace(); 00302 } 00303 waitingForMessage = false; 00304 return answer.charAt(1); 00305 } 00306 00312 public int getRamp() { 00313 try { 00314 blockingWrite("DSS"); 00315 } catch (SerialIOException e) { 00316 e.printStackTrace(); 00317 } 00318 waitingForMessage = true; 00319 String answer = null; 00320 try { 00321 answer = (String) queue.poll(pollTimeout, TimeUnit.SECONDS); 00322 } catch (InterruptedException e) { 00323 e.printStackTrace(); 00324 } 00325 waitingForMessage = false; 00326 return (int) answer.charAt(4); 00327 } 00328 00334 public int getDelay() { 00335 try { 00336 blockingWrite("DSS"); 00337 } catch (SerialIOException e) { 00338 e.printStackTrace(); 00339 } 00340 waitingForMessage = true; 00341 String answer = null; 00342 try { 00343 answer = (String) queue.poll(pollTimeout, TimeUnit.SECONDS); 00344 } catch (InterruptedException e) { 00345 e.printStackTrace(); 00346 } 00347 waitingForMessage = false; 00348 return (int) answer.charAt(7); 00349 } 00350 00356 public char getCoil() { 00357 try { 00358 blockingWrite("DSS"); 00359 } catch (SerialIOException e) { 00360 e.printStackTrace(); 00361 } 00362 waitingForMessage = true; 00363 String answer = null; 00364 try { 00365 answer = (String) queue.poll(pollTimeout, TimeUnit.SECONDS); 00366 } catch (InterruptedException e) { 00367 e.printStackTrace(); 00368 } 00369 waitingForMessage = false; 00370 return answer.charAt(10); 00371 } 00372 00378 public int getAmplitude() { 00379 try { 00380 blockingWrite("DSS"); 00381 } catch (SerialIOException e) { 00382 e.printStackTrace(); 00383 } 00384 waitingForMessage = true; 00385 String answer = null; 00386 try { 00387 answer = (String) queue.poll(pollTimeout, TimeUnit.SECONDS); 00388 } catch (InterruptedException e) { 00389 e.printStackTrace(); 00390 } 00391 waitingForMessage = false; 00392 00393 return Integer.parseInt(answer.substring(13, 17)); 00394 } 00395 00401 public boolean isOK() { 00402 if (this.serialIO != null) { 00403 return true; 00404 } else { 00405 return false; 00406 } 00407 } 00408 00409 public void serialIOEvent(SerialIOEvent event) { 00410 //TODO: problem when Degausser and Magnetometer uses same port :/ 00411 String message = event.getCleanMessage(); 00412 if (message != null) { 00413 if (waitingForMessage) { 00414 try { 00415 queue.put(message); 00416 } catch (InterruptedException e) { 00417 System.err.println("Interrupted Degausser message event"); 00418 } catch (NullPointerException e) { 00419 System.err.println("Null from SerialEvent in Degausser"); 00420 } 00421 } 00422 messageBuffer.add(message); 00423 } 00424 } 00425 }