1 package JSci.instruments.pi; 2 3 import JSci.instruments.*; 4 5 import java.awt.*; 6 import java.awt.event.*; 7 import javax.swing.*; 8 import javax.swing.event.*; 9 import java.util.*; 10 import java.util.prefs.*; 11 import java.io.*; 12 import java.text.*; 13 14 22 public abstract class Mercury extends PositionControlAdapter { 23 24 private int port; 25 private int axis; 26 private double bias = 0.0; 27 private String type = ""; 28 private String version = ""; 29 private static final int numAxis = 10 ; 30 private static final int numPorts = 10; 31 private static RandomAccessFile rf[] = new RandomAccessFile[] {null, null, null, null, null, null}; private Preferences persPref = Preferences.userRoot().node("/it/unimi/pi/Mercury"); 33 34 35 private String readLine() { 36 String s=""; 37 char c; 38 try { 39 while ((c=(char)rf[port].readByte())!=13) s+=c; 40 rf[port].readByte(); 41 rf[port].readByte(); 42 } 43 catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 44 return s; 45 } 46 47 51 protected Mercury(int p,int n) { 52 if (n<0) throw(new IllegalArgumentException (n+": axis number should be positive")); 53 if (p<0) throw(new IllegalArgumentException (n+": ttyS port number should be positive")); 54 port=p; 55 axis=n; 56 try { 57 if (rf[port]==null) rf[port]=new RandomAccessFile("/dev/ttyS"+port,"rw"); 58 synchronized (rf[port]) { 59 rf[port].writeByte(1); 61 rf[port].writeBytes(""+axis); 62 rf[port].writeBytes("rt"); 63 rf[port].writeByte(13); 64 rf[port].writeByte(1); 66 rf[port].writeBytes(""+axis); 67 rf[port].writeBytes("ve"); 68 rf[port].writeByte(13); 69 version=readLine(); 70 } 71 } 72 catch (FileNotFoundException e) { throw new IllegalArgumentException ("/dev/ttyS"+port+"does not exist"); } 73 catch (IOException e) { throw(new IllegalArgumentException ("Error writing to /dev/ttyS"+port)); } 74 bias=persPref.getDouble("zero-"+port+"-"+axis,0.0); 75 } 76 77 78 81 protected final void setLimitSwitches(boolean b) { 82 try { 83 synchronized (rf[port]) { 84 rf[port].writeByte(1); 85 rf[port].writeBytes(""+axis); 86 if (b) rf[port].writeBytes("lh"); 87 else rf[port].writeBytes("ll"); 88 rf[port].writeByte(13); 89 } 90 } 91 catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 92 } 93 94 96 protected void findCenter() { 97 try { 98 synchronized (rf[port]) { 99 rf[port].writeByte(1); 100 rf[port].writeBytes(""+axis); 101 rf[port].writeBytes("fe"); 102 rf[port].writeByte(13); 103 } 104 } 105 catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 106 } 107 108 111 116 public void setPosition(double p) { 117 if (p==currPos) return; 118 currPos=p; 119 doSetPosition(p); 120 persPref.putDouble("zero-"+port+"-"+axis,p); 121 fireStateChanged(); 122 } 123 124 125 private void doSetPosition(double p) { 126 try { 127 synchronized (rf[port]) { 128 rf[port].writeByte(1); 129 rf[port].writeBytes(""+axis); 130 rf[port].writeBytes("ma"+(long)(p-bias)); 131 rf[port].writeByte(13); 132 } 133 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 134 } 135 136 140 public double getPosition() { 141 if (Double.isNaN(currPos)) currPos=doGetPosition(); 142 return Math.rint(currPos); 143 } 144 private double currPos = Double.NaN; 145 146 public double doGetPosition() { 147 double p = 0.0; 148 try { 149 synchronized (rf[port]) { 150 rf[port].writeByte(1); 151 rf[port].writeBytes(""+axis); 152 rf[port].writeBytes("tt"); 153 rf[port].writeByte(13); 154 p=Double.parseDouble(readLine().substring(2)); 155 } 156 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 157 return p+bias; 158 } 159 160 164 public double getActualPosition() { 165 double p = 0.0; 166 try { 167 synchronized (rf[port]) { 168 rf[port].writeByte(1); 169 rf[port].writeBytes(""+axis); 170 rf[port].writeBytes("tp"); 171 rf[port].writeByte(13); 172 p=Double.parseDouble(readLine().substring(2)); 173 } 174 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 175 return p+bias; 176 } 177 178 181 public double getMinimum() { return Math.rint(persPref.getDouble("min-"+port+"-"+axis,getPosition())); } 182 183 186 public double getMaximum() { return Math.rint(persPref.getDouble("max-"+port+"-"+axis,getPosition())); } 187 188 191 public void setMinimum(double m) { persPref.putDouble("min-"+port+"-"+axis,m); } 192 193 196 public void setMaximum(double m) { persPref.putDouble("max-"+port+"-"+axis,m); } 197 198 201 public String getUnit() {return "counts";} 202 203 206 public double getMinorStep() {return 400.0;} 207 208 211 public double getMajorStep() {return 4000.0;} 212 213 217 public double getPositionError() { return doGetPositionError(); } 218 219 223 public double doGetPositionError() { 224 double p = 0.0; 225 try { 226 synchronized (rf[port]) { 227 rf[port].writeByte(1); 228 rf[port].writeBytes(""+axis); 229 rf[port].writeBytes("te"); 230 rf[port].writeByte(13); 231 p=Double.parseDouble(readLine().substring(2)); 232 } 233 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 234 return p; 235 } 236 237 240 245 public void setVelocity(double v) { 246 try { 247 synchronized (rf[port]) { 248 rf[port].writeByte(1); 249 rf[port].writeBytes(""+axis); 250 rf[port].writeBytes("sv"+(long)v); 251 rf[port].writeByte(13); 252 } 253 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 254 } 255 256 260 public double getVelocity() { 261 double p = 0.0; 262 try { 263 synchronized (rf[port]) { 264 rf[port].writeByte(1); 265 rf[port].writeBytes(""+axis); 266 rf[port].writeBytes("ty"); 267 rf[port].writeByte(13); 268 p=Double.parseDouble(readLine().substring(2)); 269 } 270 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 271 return p; 272 } 273 274 278 public double getActualVelocity() { 279 double p = 0.0; 280 try { 281 synchronized (rf[port]) { 282 rf[port].writeByte(1); 283 rf[port].writeBytes(""+axis); 284 rf[port].writeBytes("tv"); 285 rf[port].writeByte(13); 286 p=Double.parseDouble(readLine().substring(2)); 287 } 288 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 289 return p; 290 } 291 292 295 public double getMaxVelocity() { return Double.POSITIVE_INFINITY; } 296 297 300 public double getVelocityStep() {return 100000.0;} 301 302 305 public String getVelocityUnit() {return "counts/cycle";} 306 307 310 312 protected void clearErrors() {} 313 314 317 protected void setMotorOn(boolean b) { 318 try { 319 synchronized (rf[port]) { 320 rf[port].writeByte(1); 321 rf[port].writeBytes(""+axis); 322 if (b) rf[port].writeBytes("mn"); 323 else rf[port].writeBytes("mf"); 324 rf[port].writeByte(13); 325 } 326 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 327 motor_on=b; 328 } 329 private boolean motor_on = true; 330 331 334 protected boolean getMotorOn() { return motor_on; } 335 336 339 protected void setBrake(boolean b) { 340 try { 341 synchronized (rf[port]) { 342 rf[port].writeByte(1); 343 rf[port].writeBytes(""+axis); 344 if (b) rf[port].writeBytes("bn"); 345 else rf[port].writeBytes("bf"); 346 rf[port].writeByte(13); 347 } 348 } catch (IOException e) { throw new RuntimeException ("Cannot communicate with ttyS"+port); } 349 brake_on=b; 350 } 351 private boolean brake_on; 352 353 356 protected boolean getBrake() { return brake_on; } 357 358 359 360 363 protected Hashtable getEventStatus() { return null; } 364 protected static final String EVENT_MOTION_COMPLETE = "Motion complete"; 365 protected static final String EVENT_WRAP_AROUND = "Wrap around"; 366 protected static final String EVENT_BREAKPOINT1 = "Breakpoint 1"; 367 protected static final String EVENT_CAPTURE_RECEIVED = "Capture received"; 368 protected static final String EVENT_MOTION_ERROR = "Motion error"; 369 protected static final String EVENT_POS_LIMIT = "Positive limit"; 370 protected static final String EVENT_NEG_LIMIT = "Negative limit"; 371 protected static final String EVENT_INSTRUCTION_ERR = "Instruction error"; 372 protected static final String EVENT_COMMUNICATION_ERR = "Communication error"; 373 protected static final String EVENT_BREAKPOINT2 = "Breakpoint 2"; 374 375 378 protected Hashtable getSignalStatus() { return null; } 379 protected static final String SIGNAL_ENCODER_A = "Encoder A"; 380 protected static final String SIGNAL_ENCODER_B = "Encoder B"; 381 protected static final String SIGNAL_ENCODER_INDEX = "Encoder index"; 382 protected static final String SIGNAL_ENCODER_HOME = "Encoder home"; 383 protected static final String SIGNAL_POS_LIMIT = "Positive limit"; 384 protected static final String SIGNAL_NEG_LIMIT = "Negative limit"; 385 protected static final String SIGNAL_AXIS_IN = "Axis in"; 386 protected static final String SIGNAL_HALL_A = "Hall A"; 387 protected static final String SIGNAL_HALL_B = "Hall B"; 388 protected static final String SIGNAL_HALL_C = "Hall C"; 389 protected static final String SIGNAL_AXIS_OUT = "Axis out"; 390 protected static final String SIGNAL_STEP_OUTPUT = "Step output"; 391 protected static final String SIGNAL_MOTOR_OUTPUT = "Motor output"; 392 393 394 397 protected Hashtable getActivityStatus() { return null; } 398 protected static final String ACTIVITY_PHASING_INITD = "Not for the PI boards!!!"; 399 protected static final String ACTIVITY_MAX_VELOCITY = "Running at max velocity"; 400 protected static final String ACTIVITY_TRACKING = "Tracking"; 401 protected static final String ACTIVITY_PROFILE_MODE_0 = "Profile mode 0"; 402 protected static final String ACTIVITY_PROFILE_MODE_1 = "Profile mode 1"; 403 protected static final String ACTIVITY_PROFILE_MODE_2 = "Profile mode 2"; 404 protected static final String ACTIVITY_RESERVED = "Reserved"; 405 protected static final String ACTIVITY_AXIS_SETTLED = "Setteled"; 406 protected static final String ACTIVITY_MOTOR_STATUS = "Motor status"; 407 protected static final String ACTIVITY_POSITION_CAPTURE = "Position capture"; 408 protected static final String ACTIVITY_IN_MOTION = "In motion"; 409 protected static final String ACTIVITY_ACT_POS_LIMIT = "Actual positive limit"; 410 protected static final String ACTIVITY_ACT_NEG_LIMIT = "Actual negative limit"; 411 412 413 414 public void sleep() { 415 do { 416 try { 417 Thread.sleep(200); 418 } 419 catch (InterruptedException e) {} 420 } while (Math.abs(doGetPositionError())>19.5); 421 } 422 423 426 427 432 protected JPanel createPositionPanel(boolean monitor,boolean vertical, boolean inverted) { 433 final JButton setLimits = new JButton("Limits"); 434 final JSpinner spinner; 435 JButton plus,minus; 436 JPanel fastMovement = new JPanel(); 437 JPanel r = new JPanel(); 438 fastMovement.setLayout(new BorderLayout()); 439 r.setLayout(new FlowLayout()); 440 if (vertical) { 441 plus = new JButton("^"); 442 minus = new JButton("v"); 443 fastMovement.add("North",plus); 444 fastMovement.add("South",minus); 445 } 446 else { 447 plus = new JButton(">"); 448 minus = new JButton("<"); 449 fastMovement.add("East",plus); 450 fastMovement.add("West",minus); 451 } 452 spinner=new JSpinner(new SpinnerNumberModel(getPosition(),getMinimum(),getMaximum(),getMinorStep())); 453 454 Dimension dim = spinner.getPreferredSize(); 455 dim.setSize(100,dim.getHeight()); 456 spinner.setPreferredSize(dim); 457 458 r.add(spinner); 459 r.add(new JLabel("("+getUnit()+")")); 460 r.add(fastMovement); 461 462 if (monitor) { 463 final JSpinner actpos; 464 actpos = new JSpinner(new SpinnerNumberModel(getPosition(),getMinimum(),getMaximum(),getMinorStep() )); 465 dim = actpos.getPreferredSize(); 466 dim.setSize(100,dim.getHeight()); 467 actpos.setPreferredSize(dim); 468 actpos.setEnabled(false); 469 r.add(new JLabel("Actual: ")); 470 r.add(actpos); 471 r.add(new JLabel("("+getUnit()+")")); 472 class ActposChangeListener implements ChangeListener,Runnable { 473 private boolean running = false; 474 public void run() { 475 Thread t = new Thread (new Runnable () { 476 public void run() { sleep(); running=false; } 477 }); 478 t.setDaemon(true); 479 t.start(); 480 do { 481 actpos.setValue(new Double (getActualPosition())); 482 try { Thread.sleep(100); } catch (InterruptedException e) {} 483 } while (running); 484 actpos.setValue(new Double (getActualPosition())); 485 } 486 public void stateChanged(ChangeEvent event) { 487 if (running) return; 488 Thread t = new Thread (this); 489 t.setDaemon(true); 490 running=true; 491 t.start(); 492 } 493 } 494 addChangeListener(new ActposChangeListener()); 495 } 496 497 if (!inverted) { 498 minus.addActionListener(new ActionListener() { 499 public void actionPerformed(ActionEvent e) { 500 double p=getPosition()-getMajorStep(); 501 if (p>=getMinimum()) spinner.setValue(new Double (p)); 502 } 503 }); 504 plus.addActionListener(new ActionListener() { 505 public void actionPerformed(ActionEvent e) { 506 double p=getPosition()+getMajorStep(); 507 if (p<=getMaximum()) spinner.setValue(new Double (p)); 508 } 509 }); 510 } 511 else { 512 minus.addActionListener(new ActionListener() { 513 public void actionPerformed(ActionEvent e) { 514 double p=getPosition()+getMajorStep(); 515 if (p<=getMaximum()) spinner.setValue(new Double (p)); 516 } 517 }); 518 plus.addActionListener(new ActionListener() { 519 public void actionPerformed(ActionEvent e) { 520 double p=getPosition()-getMajorStep(); 521 if (p>=getMinimum()) spinner.setValue(new Double (p)); 522 } 523 }); 524 } 525 spinner.addChangeListener(new ChangeListener() { 526 public void stateChanged(ChangeEvent event) { 527 double p=((Double )spinner.getValue()).doubleValue(); 528 setPosition(p); 529 } 530 }); 531 addChangeListener(new ChangeListener() { 532 public void stateChanged(ChangeEvent event) { 533 spinner.setValue(new Double (getPosition())); 534 } 535 }); 536 537 r.add(setLimits); 538 setLimits.addActionListener(new ActionListener() { 539 public void actionPerformed(ActionEvent e) { 540 if (setLimitsDialog==null) setLimits(); 541 if (!setLimitsDialog.isVisible()) setLimitsDialog.setVisible(true); 542 setLimitsDialog.toFront(); 543 } 544 }); 545 546 r.setBorder( 547 BorderFactory.createTitledBorder( 548 BorderFactory.createEtchedBorder(), 549 "Position" 550 ) 551 ); 552 return r; 553 } 554 555 558 protected JPanel createVelocityPanel(boolean monitor) { 559 final JSpinner vel; 560 final JRadioButton inMotion; 561 JPanel r = new JPanel(); 562 r.setLayout(new FlowLayout()); 563 vel = new JSpinner(new SpinnerNumberModel(getVelocity(),0.0,getMaxVelocity(),getVelocityStep())); 564 inMotion = new JRadioButton("In motion"); 565 inMotion.setSelected(false); 566 inMotion.setEnabled(false); 567 568 Dimension dim = vel.getPreferredSize(); 569 dim.setSize(100,dim.getHeight()); 570 vel.setPreferredSize(dim); 571 572 r.add(vel); 573 r.add(new JLabel("("+getVelocityUnit()+")")); 574 575 if (monitor) { 576 final JSpinner actvel; 577 actvel = new JSpinner(new SpinnerNumberModel(getActualVelocity(),-getMaxVelocity(),getMaxVelocity(),getVelocityStep()) ); 578 579 dim = actvel.getPreferredSize(); 580 dim.setSize(100,dim.getHeight()); 581 actvel.setPreferredSize(dim); 582 actvel.setEnabled(false); 583 r.add(new JLabel("Actual: ")); 584 r.add(actvel); 585 r.add(new JLabel("("+getVelocityUnit()+")")); 586 class ActvelChangeListener implements ChangeListener,Runnable { 587 private boolean running = false; 588 public void run() { 589 Thread t = new Thread (new Runnable () { 590 public void run() { 591 inMotion.setSelected(true); 592 sleep(); 593 running=false; 594 inMotion.setSelected(false); 595 } 596 }); 597 t.setDaemon(true); 598 t.start(); 599 do { 600 actvel.setValue(new Double (getActualVelocity())); 601 try { Thread.sleep(100); } catch (InterruptedException e) {} 602 } while (running); 603 actvel.setValue(new Double (getActualVelocity())); 604 } 605 public void stateChanged(ChangeEvent event) { 606 if (running) return; 607 Thread t = new Thread (this); 608 t.setDaemon(true); 609 running=true; 610 t.start(); 611 } 612 } 613 addChangeListener(new ActvelChangeListener()); 614 } 615 616 r.add(inMotion); 617 618 vel.addChangeListener(new ChangeListener() { 619 public void stateChanged(ChangeEvent event) { 620 double v=((Double )vel.getValue()).doubleValue(); 621 setVelocity(v); 622 } 623 }); 624 625 r.setBorder( 626 BorderFactory.createTitledBorder( 627 BorderFactory.createEtchedBorder(), 628 "Velocity" 629 ) 630 ); 631 return r; 632 } 633 634 637 protected JPanel createButtonControlPanel() { 638 JPanel r = new JPanel(); 639 JButton 640 bFindHome,bSetMotorOn, 641 bSetBrake,bSetMotorMode,bSetOutputMode, 642 bClearErrors; 643 r.setLayout(new FlowLayout()); 644 645 bFindHome = new JButton("Find home"); 646 bSetMotorOn = new JButton("Motor ON"); 647 bSetBrake = new JButton("Brake ON"); 648 bSetMotorMode = new JButton("Motor mode 1"); 649 bSetOutputMode = new JButton("DAC"); 650 bClearErrors = new JButton("Clear error"); 651 652 bFindHome.addActionListener(new ActionListener() { 653 public void actionPerformed(ActionEvent e) { 654 findCenter(); 655 } 656 }); 657 bSetMotorOn.addActionListener(new ActionListener() { 658 public void actionPerformed(ActionEvent e) { 659 setMotorOn(!getMotorOn()); 660 } 661 }); 662 bSetBrake.addActionListener(new ActionListener() { 663 public void actionPerformed(ActionEvent e) { 664 setBrake(!getBrake()); 665 } 666 }); 667 bClearErrors.addActionListener(new ActionListener() { 668 public void actionPerformed(ActionEvent e) { 669 clearErrors(); 670 } 671 }); 672 673 r.add(bFindHome); 674 r.add(bSetMotorOn); 675 r.add(bSetBrake); 676 r.add(bClearErrors); 677 678 r.setBorder( 679 BorderFactory.createTitledBorder( 680 BorderFactory.createEtchedBorder(), 681 "Motor controls" 682 ) 683 ); 684 return r; 685 } 686 687 688 692 public abstract Component getControlComponent(); 693 694 695 698 699 public static final String C150PD = "C-150.PD"; 700 701 public static final String C136 = "C-136.10"; 702 703 public static final String M126PD = "M-126.PD"; 704 705 public static final String RAW = "Raw"; 706 707 713 public static Mercury createMotorDevice(String t,int p,int n, double gf) { 714 if (gf==0.0) throw(new IllegalArgumentException ("Gear factor = 0")); 715 if (!( t.equals(RAW) || t.equals(C150PD) || t.equals(C136) || t.equals(M126PD) )) 716 throw(new IllegalArgumentException ("Motor type not supported")); 717 if ( t.equals(RAW) && gf!=1.0 ) throw(new IllegalArgumentException ("Gear factor must be 1.0 for Row motor type")); 718 Mercury c = null; 719 final JPanel ccomp = new JPanel(); 720 final double rpc; 721 final double vpc; 722 final double maxv; 723 final String propname = "vel-"+p+"-"+n+"-"+t; 724 final String posUnit; 725 final String velUnit; 726 if (t.equals(RAW)) { 727 rpc = 1.0; 728 vpc = 1.0; 729 maxv = Double.POSITIVE_INFINITY; 730 posUnit = "counts"; 731 velUnit = "counts/s"; 732 } 733 else if (t.equals(C150PD)) { 734 rpc = gf/4000.0; 735 vpc = gf/4000.0; 736 maxv = 100.0 * Math.abs(gf); 737 posUnit = "turns"; 738 velUnit = "turns/s"; 739 } 740 else if (t.equals(C136)) { 741 rpc = gf / 2000.0; 742 vpc = gf / 2000.0; 743 maxv = 3.3 * Math.abs(gf) ; 744 posUnit = "turns"; 745 velUnit = "turns/s"; 746 } 747 else { 748 if (! t.equals(M126PD)) throw new IllegalArgumentException ("Unknown motor type: "+t); 749 rpc = 0.5/4000.0 * gf; 750 vpc = 0.5/4000.0 * gf; 751 maxv = 15.0 * Math.abs(gf); 752 posUnit = "mm"; 753 velUnit = "mm/s"; 754 } 755 756 c = new Mercury(p,n) { 757 public void setPosition(double p) { if (p>=getMinimum() && p<=getMaximum()) super.setPosition(p/rpc); } 758 public double getPosition() { return super.getPosition()*rpc; } 759 public double getActualPosition() { return super.getActualPosition()*rpc; } 760 public double getMinimum() { return rpc*((rpc>0.0)?super.getMinimum():super.getMaximum()); } 761 public double getMaximum() { return rpc*((rpc>0.0)?super.getMaximum():super.getMinimum()); } 762 public void setMinimum(double m) { if (rpc>0.0) super.setMinimum(m/rpc); else super.setMaximum(m/rpc); } 763 public void setMaximum(double m) { if (rpc>0.0) super.setMaximum(m/rpc); else super.setMinimum(m/rpc); } 764 public String getUnit() { return posUnit; } 765 public double getMinorStep() { return super.getMinorStep()*Math.abs(rpc);} 766 public double getMajorStep() { return super.getMajorStep()*Math.abs(rpc);} 767 public double getPositionError() { return super.getPositionError()*rpc; } 768 public void setVelocity(double v) { 769 if (v>0.0 && v<getMaxVelocity()) { 770 super.setVelocity(v/Math.abs(vpc)); 771 super.persPref.putDouble(propname,v); 772 } 773 } 774 public double getVelocity() { return super.getVelocity()*Math.abs(vpc); } 775 public double getActualVelocity() { return super.getActualVelocity()*vpc; } 776 public double getMaxVelocity() { return maxv; } 777 public double getVelocityStep() { return super.getVelocityStep()*Math.abs(vpc); } 778 public String getVelocityUnit() { return velUnit; } 779 public Component getControlComponent() { return ccomp; } 780 }; 781 if (t.equals(M126PD)) c.setLimitSwitches(true); 782 if ( ! t.equals(RAW)) c.setMotorOn(true); 783 784 if (!(c.getPosition()>=c.getMinimum() && c.getPosition()<=c.getMaximum())) throw new IllegalArgumentException ("( Minimum <= Position <= Maximum ) failed"); 785 786 c.type=t; 787 c.setVelocity(c.persPref.getDouble("vel-"+c.port+"-"+c.axis+"-"+c.type,0.1)); 788 789 ccomp.setLayout(new BorderLayout()); 790 if (t.equals(M126PD)) ccomp.add("North",c.createPositionPanel(true,true,false)); 791 else ccomp.add("North",c.createPositionPanel(true,false,false)); 792 ccomp.add("Center",c.createVelocityPanel(true)); 793 795 ccomp.setBorder( 796 BorderFactory.createTitledBorder( 797 BorderFactory.createEtchedBorder(), 798 "ttyS"+p+" Axis "+n+" "+t 799 ) 800 ); 801 return c; 802 } 803 804 808 public static Mercury createMotorDevice(String t,int p,int n) { 809 return createMotorDevice(t,p,n,1.0); 810 } 811 812 813 814 815 public String toString() { 816 return getClass().getName()+ 817 "[\nPort=ttyS"+port+",axis="+axis+",type="+type+",version="+version+"]"; 818 } 819 820 823 824 private static void printHelp() { 825 System.out.println( 826 "Useful controls for the Mercury board. Parameters can be supplied.\n"+ 827 "Syntax:\n"+ 828 "java it.unimi.pi.Mercury {options} {commands}\n"+ 829 "The options can be:\n"+ 830 "-h : print the help\n"+ 831 "-m type : set the motor type (\"Raw\" by default)\n"+ 832 "-p ttyS_number : set the ttyS port number (0 by default)\n"+ 833 "-n axis_number : set the axis number (0 by default)\n"+ 834 "-g gear_factor : set the gear factor (1 by default)\n"+ 835 "The commands can be:\n"+ 836 "setMinimum position : set the minimum of the position (only root can do this)\n"+ 837 "setMaximum position : set the maximum of the position (only root can do this)\n"+ 838 "setPosition position : move the motor to the given position\n"+ 839 "setLimits : graphical interface for setting limits of the given motor (only root can do this)\n"+ 840 "monitor : open a window with the control component for the desired motor.\n"+ 841 "motors : print a list of known motor types. \"Raw\" is a generic motor, with the\n"+ 842 "units used by the board.\n" 843 ); 844 System.exit(0); 845 } 846 847 865 public static void main(String [] args) { 866 String t="Raw"; 867 int a=0; 868 double gf=1.0; 869 int p=0; 870 int n=0; 871 while (n<args.length) { 872 if (args[n].equals("-m")) { 873 n++; 874 if (n>=args.length) printHelp(); 875 t=args[n]; 876 } else 877 if (args[n].equals("-p")) { 878 n++; 879 if (n>=args.length) printHelp(); 880 p=Integer.parseInt(args[n]); 881 } else 882 if (args[n].equals("-n")) { 883 n++; 884 if (n>=args.length) printHelp(); 885 a=Integer.parseInt(args[n]); 886 } else 887 if (args[n].equals("-g")) { 888 n++; 889 if (n>=args.length) printHelp(); 890 gf=Double.parseDouble(args[n]); 891 } else 892 if (args[n].equals("-h")) printHelp(); 893 else break; 894 n++; 895 } 896 897 Mercury c = createMotorDevice(t,p,a,gf); 898 899 while (n<args.length) { 900 if (args[n].equals("setMinimum")) { 901 n++; 902 if (n>=args.length) printHelp(); 903 c.setMinimum(Double.parseDouble(args[n])); 904 } else 905 if (args[n].equals("setMaximum")) { 906 n++; 907 if (n>=args.length) printHelp(); 908 c.setMaximum(Double.parseDouble(args[n])); 909 } else 910 if (args[n].equals("setPosition")) { 911 n++; 912 if (n>=args.length) printHelp(); 913 c.setPosition(Double.parseDouble(args[n])); 914 } else 915 if (args[n].equals("setLimits")) 916 c.setLimits(); 917 else 918 if (args[n].equals("monitor")) { 919 JFrame frm = new JFrame("Mercury"); 920 frm.getContentPane().add(c.getControlComponent()); 921 frm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 922 frm.pack(); 923 frm.show(); 924 } else 925 if (args[n].equals("motors")) { 926 System.out.println("Supported motor types:\nRaw\nC-150.PD\nC-136.10\nM-126.PD\n\n"); 927 } else printHelp(); 928 n++; 929 } 930 } 931 932 933 936 JFrame setLimitsDialog = null; 937 941 public void setLimits() { 942 setLimitsDialog = new JFrame("Axis "+axis+" "+type+" Set limits"); 943 final JSpinner min = new JSpinner(new SpinnerNumberModel(getMinimum(),Double.NEGATIVE_INFINITY,getPosition(),getMinorStep())); 944 final JSpinner pos = new JSpinner(new SpinnerNumberModel(getPosition(),getMinimum(),getMaximum(),getMinorStep())); 945 final JSpinner max = new JSpinner(new SpinnerNumberModel(getMaximum(),getPosition(),Double.POSITIVE_INFINITY,getMinorStep())); 946 final JRadioButton rbPos = new JRadioButton("None",true); 947 final JRadioButton rbMin = new JRadioButton("Min",false); 948 final JRadioButton rbMax = new JRadioButton("Max",false); 949 JButton toMin = new JButton("Move to min"); 950 JButton toMax = new JButton("Move to max"); 951 ButtonGroup bg = new ButtonGroup(); 952 bg.add(rbPos);bg.add(rbMin);bg.add(rbMax); 953 954 min.addChangeListener(new ChangeListener() { 955 public void stateChanged(ChangeEvent e) { 956 double v = ((Double )min.getValue()).doubleValue(); 957 setMinimum(v); 958 if (rbPos.isSelected()) 959 ((SpinnerNumberModel)pos.getModel()).setMinimum(new Double (getMinimum())); 960 if (rbMin.isSelected()) { 961 pos.setValue(new Double (getMinimum())); 962 ((SpinnerNumberModel)pos.getModel()).setMinimum(new Double (getMinimum())); 963 ((SpinnerNumberModel)pos.getModel()).setMaximum(new Double (getMinimum())); 964 ((SpinnerNumberModel)max.getModel()).setMinimum(new Double (getMinimum())); 965 } 966 if (rbMax.isSelected()) 967 ((SpinnerNumberModel)max.getModel()).setMinimum(new Double (getMinimum())); 968 } 969 }); 970 pos.addChangeListener(new ChangeListener() { 971 private double currPos = 0.0; 972 public void stateChanged(ChangeEvent e) { 973 if (currPos == 0.0) currPos = getPosition(); 974 double v = ((Double )pos.getValue()).doubleValue(); 975 if (v==currPos) return; 976 currPos=v; 977 setPosition(v); 978 if (rbPos.isSelected()) { 979 ((SpinnerNumberModel)min.getModel()).setMaximum(new Double (getPosition())); 980 ((SpinnerNumberModel)max.getModel()).setMinimum(new Double (getPosition())); 981 } 982 } 983 }); 984 max.addChangeListener(new ChangeListener() { 985 public void stateChanged(ChangeEvent e) { 986 double v = ((Double )max.getValue()).doubleValue(); 987 setMaximum(v); 988 if (rbPos.isSelected()) 989 ((SpinnerNumberModel)pos.getModel()).setMaximum(new Double (getMaximum())); 990 if (rbMin.isSelected()) 991 ((SpinnerNumberModel)min.getModel()).setMaximum(new Double (getMaximum())); 992 if (rbMax.isSelected()) { 993 pos.setValue(new Double (getMaximum())); 994 ((SpinnerNumberModel)pos.getModel()).setMinimum(new Double (getMaximum())); 995 ((SpinnerNumberModel)pos.getModel()).setMaximum(new Double (getMaximum())); 996 ((SpinnerNumberModel)min.getModel()).setMaximum(new Double (getMaximum())); 997 } 998 } 999 }); 1000 1001 rbPos.addActionListener(new ActionListener() { 1002 public void actionPerformed(ActionEvent e) { 1003 ((SpinnerNumberModel)min.getModel()).setMaximum(new Double (getPosition())); 1004 ((SpinnerNumberModel)max.getModel()).setMinimum(new Double (getPosition())); 1005 ((SpinnerNumberModel)pos.getModel()).setMinimum(new Double (getMinimum())); 1006 ((SpinnerNumberModel)pos.getModel()).setMaximum(new Double (getMaximum())); 1007 } 1008 }); 1009 rbMin.addActionListener(new ActionListener() { 1010 public void actionPerformed(ActionEvent e) { 1011 pos.setValue(new Double (getMinimum())); 1012 ((SpinnerNumberModel)min.getModel()).setMaximum(new Double (getMaximum())); 1013 ((SpinnerNumberModel)pos.getModel()).setMinimum(new Double (getMinimum())); 1014 ((SpinnerNumberModel)pos.getModel()).setMaximum(new Double (getMinimum())); 1015 ((SpinnerNumberModel)max.getModel()).setMinimum(new Double (getMinimum())); 1016 } 1017 }); 1018 rbMax.addActionListener(new ActionListener() { 1019 public void actionPerformed(ActionEvent e) { 1020 pos.setValue(new Double (getMaximum())); 1021 ((SpinnerNumberModel)max.getModel()).setMinimum(new Double (getMinimum())); 1022 ((SpinnerNumberModel)pos.getModel()).setMinimum(new Double (getMaximum())); 1023 ((SpinnerNumberModel)pos.getModel()).setMaximum(new Double (getMaximum())); 1024 ((SpinnerNumberModel)min.getModel()).setMaximum(new Double (getMaximum())); 1025 } 1026 }); 1027 1028 toMin.addActionListener(new ActionListener() { 1029 public void actionPerformed(ActionEvent e) { 1030 if (rbPos.isSelected()) 1031 pos.setValue(new Double (getMinimum())); 1032 } 1033 }); 1034 toMax.addActionListener(new ActionListener() { 1035 public void actionPerformed(ActionEvent e) { 1036 if (rbPos.isSelected()) 1037 pos.setValue(new Double (getMaximum())); 1038 } 1039 }); 1040 1041 Dimension dim = min.getPreferredSize(); 1042 dim = new Dimension(100,(int)dim.getHeight()); 1043 min.setPreferredSize(dim); 1044 dim = pos.getPreferredSize(); 1045 dim = new Dimension(100,(int)dim.getHeight()); 1046 pos.setPreferredSize(dim); 1047 dim = max.getPreferredSize(); 1048 dim = new Dimension(100,(int)dim.getHeight()); 1049 max.setPreferredSize(dim); 1050 1051 setLimitsDialog.getContentPane().setLayout(new GridBagLayout()); 1052 GridBagConstraints constr = new GridBagConstraints(); 1053 constr.fill=GridBagConstraints.NONE; 1054 constr.anchor=GridBagConstraints.EAST; 1055 constr.weightx=0; 1056 constr.weighty=0; 1057 1058 constr.gridx=0;constr.gridy=0;constr.gridwidth=1;constr.gridheight=1; 1059 setLimitsDialog.getContentPane().add(new JLabel("Maximum:"),constr); 1060 constr.gridx=1;constr.gridy=0;constr.gridwidth=1;constr.gridheight=1; 1061 setLimitsDialog.getContentPane().add(max,constr); 1062 constr.gridx=2;constr.gridy=0;constr.gridwidth=1;constr.gridheight=1; 1063 setLimitsDialog.getContentPane().add(new JLabel(getUnit()),constr); 1064 constr.gridx=0;constr.gridy=1;constr.gridwidth=1;constr.gridheight=1; 1065 setLimitsDialog.getContentPane().add(new JLabel("Position:"),constr); 1066 constr.gridx=1;constr.gridy=1;constr.gridwidth=1;constr.gridheight=1; 1067 setLimitsDialog.getContentPane().add(pos,constr); 1068 constr.gridx=2;constr.gridy=1;constr.gridwidth=1;constr.gridheight=1; 1069 setLimitsDialog.getContentPane().add(new JLabel(getUnit()),constr); 1070 constr.gridx=0;constr.gridy=2;constr.gridwidth=1;constr.gridheight=1; 1071 setLimitsDialog.getContentPane().add(new JLabel("Minimum:"),constr); 1072 constr.gridx=1;constr.gridy=2;constr.gridwidth=1;constr.gridheight=1; 1073 setLimitsDialog.getContentPane().add(min,constr); 1074 constr.gridx=2;constr.gridy=2;constr.gridwidth=1;constr.gridheight=1; 1075 setLimitsDialog.getContentPane().add(new JLabel(getUnit()),constr); 1076 constr.gridx=0;constr.gridy=3;constr.gridwidth=1;constr.gridheight=1; 1077 setLimitsDialog.getContentPane().add(new JLabel("Anchor to: "),constr); 1078 constr.anchor=GridBagConstraints.WEST; 1079 constr.gridx=1;constr.gridy=4;constr.gridwidth=1;constr.gridheight=1; 1080 setLimitsDialog.getContentPane().add(rbPos,constr); 1081 constr.gridx=1;constr.gridy=5;constr.gridwidth=1;constr.gridheight=1; 1082 setLimitsDialog.getContentPane().add(rbMin,constr); 1083 constr.gridx=1;constr.gridy=6;constr.gridwidth=1;constr.gridheight=1; 1084 setLimitsDialog.getContentPane().add(rbMax,constr); 1085 constr.anchor=GridBagConstraints.CENTER; 1086 constr.gridx=0;constr.gridy=7;constr.gridwidth=1;constr.gridheight=1; 1087 setLimitsDialog.getContentPane().add(toMin,constr); 1088 constr.gridx=1;constr.gridy=7;constr.gridwidth=1;constr.gridheight=1; 1089 setLimitsDialog.getContentPane().add(toMax,constr); 1090 1091 setLimitsDialog.pack(); 1092 setLimitsDialog.setResizable(false); 1093 setLimitsDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 1094 setLimitsDialog.setVisible(true); 1095 } 1096 1097 1098 1099} 1100 1101 | Popular Tags |