View Javadoc
1 /* 2 * CelestronTelescope.java 3 * 4 * Copyright (c) 2003, Raben Systems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 13 * Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * Neither the name of Raben Systems, Inc. nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 package com.raben.telescope.comm; 35 import java.awt.geom.Point2D; 36 import java.io.IOException; 37 import java.util.TimeZone; 38 import java.util.Calendar; 39 import java.util.GregorianCalendar; 40 import java.util.Properties; 41 42 /*** 43 * Implementation of the TelescopeInterface for telescopes 44 * manufactured by Celestron (tm) 45 * @author Vern Raben 46 * @version $Revision: 1.2 $ 47 * 48 * NOTE - this only hardware this has been tested on at present is 49 * Nexstar 11 GPS, Hand Control Version 2.2 and 2.3 using MS Windows XP 50 * and J2SDK 1.4.1 51 * 52 */ 53 public class CelestronTelescope implements TelescopeInterface { 54 55 /*** Serial connection to telescope */ 56 private SerialConnection serialConnection = new SerialConnection(); 57 58 /*** True character */ 59 private static final char TRUE_CHAR = (char) 1; 60 61 /*** Telescope model */ 62 private TelescopeModel telescopeModel = 63 TelescopeModel.CELESTRON_NEXSTAR_GPS; 64 65 /*** Standard Celestron commands */ 66 private CelestronCommand command = new CelestronCommand(); 67 68 /*** Auxiallary Celestron commands */ 69 private CelestronAuxillaryCommand auxCommand = null; 70 71 /*** Connection timeout */ 72 private long timeOut = 30000L; 73 74 /*** UTC TimeZone */ 75 private static final TimeZone TZ = TimeZone.getTimeZone("UTC"); 76 77 /*** Conversion from angle to RA */ 78 private static final double ANGLE_TO_RA = 360.0 / 24.0; 79 80 /*** Conversion from RA to angle */ 81 private static final double RA_TO_ANGLE = 24.0 / 360.0; 82 83 /*** Tracking mode 0=off, 1= azimuth, 2= equ-n, 3=eq-S */ 84 private static int trackingMode = 1; 85 86 /*** Creates a new instance of CelestronTelescope */ 87 public CelestronTelescope() { 88 } 89 90 /*** 91 * Cancel goto command 92 * @exception IOException may occur 93 */ 94 public void cancelGoTo() throws IOException { 95 serialConnection.sendString(command.cancelGoTo()); 96 serialConnection.receiveString(); 97 } 98 99 /*** 100 * Get right ascension and declination 101 * @return Point2D May return NaN if coordinate not received 102 * @exception IOException may occur 103 */ 104 public Point2D getRightAscensionDeclination() throws IOException { 105 Point2D raDec = new Point2D.Double(Double.NaN, Double.NaN); 106 serialConnection.sendString(command.getRightAscensionDeclination()); 107 String response = serialConnection.receiveString(); 108 command.decodeHexadecimal(response, raDec); 109 double decl = raDec.getY(); 110 111 if (decl > 180.0) { 112 decl -= 360.0; 113 } 114 115 raDec.setLocation(raDec.getX() * RA_TO_ANGLE, decl); 116 return raDec; 117 } 118 119 120 /*** 121 * Go to specificied azimuth/altitude coordinate 122 * @param coordinate Point2D 123 * @exception IOException may be thrown 124 */ 125 public void goToAzimuthAltitude(Point2D coordinate) throws IOException { 126 127 double azm = coordinate.getX(); 128 double alt = coordinate.getY(); 129 130 if (alt < 0.0) { 131 alt += 360.0; 132 } 133 134 sendCommand(command.goToAzimuthAltitude(azm, alt)); 135 serialConnection.receiveString(); // ISSUE - do all models ack with # 136 } 137 138 /*** 139 * Go to specified right ascension/declination coordinate 140 * @param coordinate Point2D 141 * @exception IOException may occur 142 */ 143 public void goToRightAscensionDeclination(Point2D coordinate) 144 throws IOException { 145 sendCommand(command.goToRightAscensionDeclination( 146 (coordinate.getX() * ANGLE_TO_RA), coordinate.getY())); 147 serialConnection.receiveString(); // ISSUE - do all models ack with # 148 } 149 150 /*** 151 * Send command to the communications port 152 * @param cmd The command string 153 * @exception IOException may occur 154 */ 155 private void sendCommand(String cmd) throws IOException { 156 157 if ((cmd != null) && (cmd.length() > 0)) { 158 159 if ((TelescopeModel.CELESTRON_NEXSTAR_OGT.equals(telescopeModel)) 160 || (TelescopeModel.CELESTRON_NEXSTAR_5_8.equals( 161 telescopeModel))) { 162 sendInitializeCommand(); 163 serialConnection.sendString(cmd); 164 } else { 165 serialConnection.sendString(cmd); 166 } 167 } 168 169 } 170 171 /*** 172 * Send command to the communication port 173 * @param cmd Character array containing command 174 * @exception IOException may occur 175 */ 176 private void sendCommand(char[] cmd) throws IOException { 177 if ((cmd != null) && (cmd.length > 0)) { 178 serialConnection.sendChars(cmd); 179 } 180 } 181 182 183 184 /*** 185 * Get azimuth and altitude coordinate 186 * @return Current azimuth altitude coordinate 187 * @exception IOException may occur 188 */ 189 public Point2D getAzimuthAltitude() throws IOException { 190 sendCommand(command.getAzimuthAltitude()); 191 Point2D azmAlt = new Point2D.Double(Double.NaN, Double.NaN); 192 String response = serialConnection.receiveString(); 193 command.decodeHexadecimal(response, azmAlt); 194 195 if (azmAlt.getY() > 180.0) { 196 azmAlt.setLocation(azmAlt.getX(), azmAlt.getY() - 360.0); 197 } 198 199 return azmAlt; 200 } 201 202 /*** 203 * Check whether or not telescope is aligned 204 * @return true if aligned, false otherwise 205 * @exception IOException may occur 206 */ 207 public boolean isAligned() throws IOException { 208 boolean aligned = false; 209 sendCommand(command.alignmentComplete()); 210 char[] response = serialConnection.receiveChars(); 211 212 if ((response != null) && (response.length == 2)) { 213 214 if (response[0] == TRUE_CHAR) { 215 aligned = true; 216 } else { 217 aligned = false; 218 } 219 220 } 221 222 return aligned; 223 } 224 225 /*** 226 * Check if communication with telescope is established 227 * @return true if communicating, false otherwise 228 * @exception IOException may occur 229 */ 230 public boolean isCommunicating() throws IOException { 231 boolean communicating = false; 232 233 if ((serialConnection != null) && (serialConnection.isOpen())) { 234 serialConnection.sendString("Kx"); 235 String response = serialConnection.receiveString(); 236 237 if ("x#".equals(response)) { 238 communicating = true; 239 } 240 } 241 242 return communicating; 243 } 244 245 /*** 246 * Check whether telescope is slewing to new coordinate 247 * @return true if telescope is slewing, false otherwise 248 * @exception IOException may occur 249 */ 250 public boolean isSlewing() throws IOException { 251 boolean slewing = false; 252 253 serialConnection.sendString("L"); 254 char[] response = serialConnection.receiveChars(); 255 256 if ((response != null) && (response.length == 2)) { 257 if (response[0] == '1') { 258 slewing = true; 259 } 260 } 261 262 return slewing; 263 } 264 265 /*** 266 * Close connection to telescope 267 */ 268 public void close() { 269 270 if (serialConnection != null) { 271 serialConnection.closeConnection(); 272 } 273 } 274 275 276 /*** 277 * Get control unit version 278 * @return version 279 * @exception IOException may occur 280 */ 281 public String getHandControlVersion() throws IOException { 282 283 int versionVal = 0; 284 serialConnection.sendString("V"); 285 String response = serialConnection.receiveString(); 286 287 if (response.length() > 0) { 288 for (int i = response.length() - 2; i >= 0; i--) { 289 290 switch(i) { 291 case 1: versionVal += 10 * (int) response.charAt(i); 292 break; 293 case 0: versionVal += (int) response.charAt(i); 294 break; 295 } 296 297 } 298 } 299 300 return String.valueOf(versionVal); 301 } 302 303 /*** 304 * Initialize connection to telescope 305 * @exception IOException may be thrown 306 */ 307 public void connect() throws IOException { 308 serialConnection.openConnection(); 309 } 310 311 /*** 312 * Check if connection is open 313 * @return True if connection is open 314 */ 315 public boolean isConnected() { 316 return serialConnection.isOpen(); 317 } 318 319 /*** 320 * Set tracking mode 321 * Must be aligned to switch from off to alt-az* 322 * @param mode (0=tracking off,1=Alt-Az tracking,2=Eq-North,3=Eq-South 323 * @exception IOException may be thrown 324 */ 325 public void setTrackingMode(int mode) throws IOException { 326 String cmd = command.trackingMode(mode); 327 328 if ((cmd != null) && (cmd.length() > 0)) { 329 setDebug(true); 330 serialConnection.sendString(cmd); 331 serialConnection.receiveString(); 332 } 333 } 334 335 336 /*** 337 * Get telescope geographic coordinate from GPS interface 338 * @return Geographic coordinate of telescope in degrees 339 * @exception IOException may occur 340 */ 341 public Point2D getGpsCoordinate() throws IOException { 342 double longitude = Double.NaN; 343 double latitude = Double.NaN; 344 345 if (auxCommand != null) { 346 sendCommand(auxCommand.gpsLongitudeCommand()); 347 char[] retVal = serialConnection.receiveChars(); 348 longitude = auxCommand.decodeGpsCoordinate(retVal); 349 sendCommand(auxCommand.gpsLatitudeCommand()); 350 retVal = serialConnection.receiveChars(); 351 latitude = auxCommand.decodeGpsCoordinate(retVal); 352 } 353 354 return new Point2D.Double(longitude, latitude); 355 } 356 357 358 /*** 359 * Get Date and Time from GPS interface 360 * @return Calendar set to GPS date/time 361 * @exception IOException may occur 362 */ 363 public Calendar getGpsDateTime() throws IOException { 364 int mo = 0; 365 int da = 0; 366 int yr = 0; 367 int hr = 0; 368 int min = 0; 369 int sec = 0; 370 Calendar cal = new GregorianCalendar(TZ); 371 372 if (auxCommand != null) { 373 374 // Get year 375 sendCommand(auxCommand.gpsYearCommand()); 376 char[] retVal = serialConnection.receiveChars(); 377 378 if ((retVal != null) && (retVal.length == 3)) { 379 yr = (retVal[0] << 8) | (retVal[1]); 380 } 381 382 // Get mo and day 383 sendCommand(auxCommand.gpsDateCommand()); 384 retVal = serialConnection.receiveChars(); 385 386 if ((retVal != null) && (retVal.length == 3)) { 387 mo = (int) (retVal[0]) - 1; 388 da = (int) retVal[1]; 389 } 390 391 // Get hr, min, sec 392 sendCommand(auxCommand.gpsTimeCommand()); 393 retVal = serialConnection.receiveChars(); 394 395 if ((retVal != null) && (retVal.length == 4)) { 396 hr = retVal[0]; 397 min = retVal[1]; 398 sec = retVal[2]; 399 } 400 } 401 402 cal.set(yr, mo, da, hr, min, sec); 403 return cal; 404 } 405 406 407 /*** 408 * Check if GPS is linked 409 * @return True if GPS is linked, false otherwise 410 * @exception IOException may occur 411 */ 412 public boolean isGpsLinked() throws IOException { 413 boolean linked = false; 414 415 if (auxCommand != null) { 416 sendCommand(auxCommand.gpsLinkedCommand()); 417 418 char[] chars = serialConnection.receiveChars(); 419 420 if ((chars != null) && (chars.length == 2)) { 421 if (chars[0] == TRUE_CHAR) { 422 linked = true; 423 } else { 424 linked = false; 425 } 426 } 427 } 428 429 return linked; 430 } 431 432 433 /*** 434 * Set azimuth tracking rate 435 * Note - tracking will return to default in approximately 20 seconds 436 * unless tracking is turned off @see setTrackingMode 437 * @param trackRate in arc-sec/sec 438 * @exception IOException may occur 439 */ 440 public void setAzimuthTrackingRate(int trackRate) throws IOException { 441 if (auxCommand != null) { 442 sendCommand(auxCommand.azimuthTrackingRateCommand(trackRate)); 443 String retVal = serialConnection.receiveString(); 444 } 445 } 446 447 /*** Set altitude tracking rate 448 * Note - tracking will return to default in approximately 20 seconds 449 * unless tracking is turned off @see setTrackingMode 450 * @param trackRate in arc-sec/sec 451 * @exception IOException may occur 452 */ 453 public void setAltitudeTrackingRate(int trackRate) throws IOException { 454 if (auxCommand != null) { 455 sendCommand(auxCommand.altitudeTrackingRateCommand(trackRate)); 456 String retVal = serialConnection.receiveString(); 457 } 458 } 459 460 /*** 461 * Get port being used 462 * @return String (default is COM1) 463 */ 464 private String getPortName() { 465 return serialConnection.getPortName(); 466 } 467 468 /*** 469 * Set port to use for connection 470 * @param portName Name of port (default is COM1) 471 * 472 */ 473 private void setPortName(String portName) { 474 serialConnection.setPortName(portName); 475 } 476 477 /*** 478 * Send an initialize command and wait for 1/4 second 479 * Used by original Nexstar GT, Nexstar 5/8 480 * @exception IOException may occur 481 */ 482 private void sendInitializeCommand() throws IOException { 483 serialConnection.sendString("?"); 484 485 try { 486 Thread.sleep(250L); 487 } catch (InterruptedException e) { 488 // ignore 489 } 490 } 491 492 493 /*** 494 * Get telescope model 495 * @return TelescopeModel 496 */ 497 public TelescopeModel getTelescopeModel() { 498 return command.getTelescopeModel(); 499 } 500 501 502 /*** 503 * Set the telescope model 504 * @param model of telescope @see TelescopeModel 505 * ISSUE - Generic Celestron telescope not yet implemented 506 */ 507 public void setTelescopeModel(TelescopeModel model) { 508 509 if (model != null) { 510 511 if (TelescopeModel.CELESTRON.equals(model)) { 512 model = determineTelescopeModel(); 513 } 514 515 command.setTelescopeModel(model); 516 517 // Enable auxillary commands if capable 518 if ((TelescopeModel.CELESTRON_ASC.equals(model)) 519 || (TelescopeModel.CELESTRON_CGE.equals(model)) 520 || (TelescopeModel.CELESTRON_NEXSTAR_GPS.equals(model))) { 521 522 // ISSUE - should probably check version first 523 auxCommand = new CelestronAuxillaryCommand(); 524 } 525 } 526 527 } 528 529 /*** 530 * Send commands to scope to determine specific model 531 * @return TelescopeModel 532 * ISSUE - not yet implemented 533 */ 534 private TelescopeModel determineTelescopeModel() { 535 return TelescopeModel.CELESTRON_NEXSTAR_GPS; 536 } 537 538 /*** 539 * String describing telescope 540 * @return String 541 */ 542 public String toString() { 543 StringBuffer buf = new StringBuffer(getClass().getName()); 544 buf.append("["); 545 buf.append("telescopeModel="); 546 buf.append(telescopeModel.toString()); 547 buf.append("]"); 548 return buf.toString(); 549 } 550 551 /*** 552 * Get telescope properties 553 * @return Telescope properties 554 */ 555 public java.util.Properties getProperties() { 556 Properties props = new Properties(); 557 props.setProperty(ScopeKey.MODEL, telescopeModel.toString()); 558 props.setProperty(ScopeKey.PORT, serialConnection.getPortName()); 559 props.setProperty(ScopeKey.DEBUG, String.valueOf(isDebug())); 560 return props; 561 } 562 563 /*** 564 * Set telescope properties 565 * @param props Properties for setting up telescope such as comm port, 566 * and debug. Supported keys are 567 * com.raben.telescope.port 568 * com.raben.telescope.debug 569 */ 570 public void setProperties(java.util.Properties props) { 571 String port = props.getProperty(ScopeKey.PORT, "COM1"); 572 setPortName(port); 573 String debugStr = props.getProperty(ScopeKey.DEBUG); 574 575 if (debugStr != null) { 576 if ("true".equals(debugStr)) { 577 serialConnection.setDebug(true); 578 } else { 579 serialConnection.setDebug(false); 580 } 581 } 582 } 583 584 /*** Get debug flag 585 * @return True if in debug mode, false otherwise 586 */ 587 public boolean isDebug() { 588 return serialConnection.isDebug(); 589 } 590 591 /*** Set debug flag 592 * @param debug flag 593 */ 594 public void setDebug(boolean debug) { 595 serialConnection.setDebug(debug); 596 } 597 598 public void moveInAzimuth(boolean direction, int rate) throws IOException { 599 System.out.println("moveInAzimuth direction = "+direction+" rate="+rate); 600 sendCommand(auxCommand.azimuthMoveCommand(direction, rate)); 601 } 602 603 public void moveInAltitude(boolean direction, int rate) throws IOException { 604 System.out.println("moveInAltitude"); 605 char[] cmd = auxCommand.altitudeMoveCommand(direction, rate); 606 607 if (cmd != null) { 608 System.out.println(SerialConnection.displayCharArrayAsHexString(cmd)); 609 } 610 else { 611 System.out.println("cmd is null"); 612 } 613 614 sendCommand(auxCommand.altitudeMoveCommand(direction, rate)); 615 } 616 617 } 618

This page was automatically generated by Maven