source: BAORadio/libindi/v1/drivers/telescope/lx200basic.cpp@ 689

Last change on this file since 689 was 490, checked in by campagne, 15 years ago

import libindi (JEC)

File size: 26.2 KB
Line 
1#if 0
2 LX200 Basic Driver
3 Copyright (C) 2005 Jasem Mutlaq (mutlaqja@ikarustech.com)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19#endif
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <math.h>
26#include <unistd.h>
27#include <time.h>
28#include <memory>
29
30#include <config.h>
31
32/* INDI Common Library Routines */
33#include "indicom.h"
34
35/* LX200 Command Set */
36#include "lx200driver.h"
37
38/* Our driver header */
39#include "lx200basic.h"
40
41using namespace std;
42
43/* Our telescope auto pointer */
44auto_ptr<LX200Basic> telescope(0);
45
46const int POLLMS = 1000; // Period of update, 1 second.
47const char *mydev = "LX200 Basic"; // Name of our device.
48
49const char *BASIC_GROUP = "Main Control"; // Main Group
50const char *OPTIONS_GROUP = "Options"; // Options Group
51
52/* Handy Macros */
53#define currentRA EquatorialCoordsRN[0].value
54#define currentDEC EquatorialCoordsRN[1].value
55#define targetRA EquatorialCoordsWN[0].value
56#define targetDEC EquatorialCoordsWN[1].value
57
58static void ISPoll(void *);
59static void retry_connection(void *);
60
61/**************************************************************************************
62** Send client definitions of all properties.
63***************************************************************************************/
64void ISInit()
65{
66 static int isInit=0;
67
68 if (isInit)
69 return;
70
71 if (telescope.get() == 0) telescope.reset(new LX200Basic());
72
73 isInit = 1;
74
75 IEAddTimer (POLLMS, ISPoll, NULL);
76}
77
78/**************************************************************************************
79**
80***************************************************************************************/
81void ISGetProperties (const char *dev)
82{
83 ISInit();
84 telescope->ISGetProperties(dev);
85}
86
87/**************************************************************************************
88**
89***************************************************************************************/
90void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
91{
92 ISInit();
93 telescope->ISNewSwitch(dev, name, states, names, n);
94}
95
96/**************************************************************************************
97**
98***************************************************************************************/
99void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
100{
101 ISInit();
102 telescope->ISNewText(dev, name, texts, names, n);
103}
104
105/**************************************************************************************
106**
107***************************************************************************************/
108void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
109{
110 ISInit();
111 telescope->ISNewNumber(dev, name, values, names, n);
112}
113
114/**************************************************************************************
115**
116***************************************************************************************/
117void ISPoll (void *p)
118{
119 INDI_UNUSED(p);
120
121 telescope->ISPoll();
122 IEAddTimer (POLLMS, ISPoll, NULL);
123}
124
125/**************************************************************************************
126**
127***************************************************************************************/
128void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
129{
130 INDI_UNUSED(dev);
131 INDI_UNUSED(name);
132 INDI_UNUSED(sizes);
133 INDI_UNUSED(blobsizes);
134 INDI_UNUSED(blobs);
135 INDI_UNUSED(formats);
136 INDI_UNUSED(names);
137 INDI_UNUSED(n);
138}
139
140/**************************************************************************************
141**
142***************************************************************************************/
143void ISSnoopDevice (XMLEle *root)
144{
145 INDI_UNUSED(root);
146}
147
148/**************************************************************************************
149** LX200 Basic constructor
150***************************************************************************************/
151LX200Basic::LX200Basic()
152{
153 init_properties();
154
155 lastSet = -1;
156 fd = -1;
157 simulation = false;
158 lastRA = 0;
159 lastDEC = 0;
160 currentSet = 0;
161
162 IDLog("Initilizing from LX200 Basic device...\n");
163 IDLog("Driver Version: 2007-09-28\n");
164
165 //enableSimulation(true);
166}
167
168/**************************************************************************************
169**
170***************************************************************************************/
171LX200Basic::~LX200Basic()
172{
173
174}
175
176/**************************************************************************************
177** Initialize all properties & set default values.
178***************************************************************************************/
179void LX200Basic::init_properties()
180{
181 // Connection
182 IUFillSwitch(&ConnectS[0], "CONNECT", "Connect", ISS_OFF);
183 IUFillSwitch(&ConnectS[1], "DISCONNECT", "Disconnect", ISS_ON);
184 IUFillSwitchVector(&ConnectSP, ConnectS, NARRAY(ConnectS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
185
186 // Coord Set
187 IUFillSwitch(&OnCoordSetS[0], "SLEW", "Slew", ISS_ON);
188 IUFillSwitch(&OnCoordSetS[1], "TRACK", "Track", ISS_OFF);
189 IUFillSwitch(&OnCoordSetS[2], "SYNC", "Sync", ISS_OFF);
190 IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
191
192 // Abort
193 IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
194 IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
195
196 // Port
197 IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyS0");
198 IUFillTextVector(&PortTP, PortT, NARRAY(PortT), mydev, "DEVICE_PORT", "Ports", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
199
200 // Object Name
201 IUFillText(&ObjectT[0], "OBJECT_NAME", "Name", "--");
202 IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
203
204 // Equatorial Coords - SET
205 IUFillNumber(&EquatorialCoordsWN[0], "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.);
206 IUFillNumber(&EquatorialCoordsWN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
207 IUFillNumberVector(&EquatorialCoordsWNP, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), mydev, "EQUATORIAL_EOD_COORD_REQUEST" , "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
208
209 // Equatorial Coords - READ
210 IUFillNumber(&EquatorialCoordsRN[0], "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.);
211 IUFillNumber(&EquatorialCoordsRN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
212 IUFillNumberVector(&EquatorialCoordsRNP, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), mydev, "EQUATORIAL_EOD_COORD" , "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE);
213
214 // Slew threshold
215 IUFillNumber(&SlewAccuracyN[0], "SlewRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0);
216 IUFillNumber(&SlewAccuracyN[1], "SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
217 IUFillNumberVector(&SlewAccuracyNP, SlewAccuracyN, NARRAY(SlewAccuracyN), mydev, "Slew Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
218
219 // Track threshold
220 IUFillNumber(&TrackAccuracyN[0], "TrackRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0);
221 IUFillNumber(&TrackAccuracyN[1], "TrackDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
222 IUFillNumberVector(&TrackAccuracyNP, TrackAccuracyN, NARRAY(TrackAccuracyN), mydev, "Tracking Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
223}
224
225/**************************************************************************************
226** Define LX200 Basic properties to clients.
227***************************************************************************************/
228void LX200Basic::ISGetProperties(const char *dev)
229{
230
231 if (dev && strcmp (mydev, dev))
232 return;
233
234 // Main Control
235 IDDefSwitch(&ConnectSP, NULL);
236 IDDefText(&PortTP, NULL);
237 IDDefText(&ObjectTP, NULL);
238 IDDefNumber(&EquatorialCoordsWNP, NULL);
239 IDDefNumber(&EquatorialCoordsRNP, NULL);
240 IDDefSwitch(&OnCoordSetSP, NULL);
241 IDDefSwitch(&AbortSlewSP, NULL);
242
243 // Options
244 IDDefNumber(&SlewAccuracyNP, NULL);
245 IDDefNumber(&TrackAccuracyNP, NULL);
246
247}
248
249/**************************************************************************************
250** Process Text properties
251***************************************************************************************/
252void LX200Basic::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
253{
254 // Ignore if not ours
255 if (strcmp (dev, mydev))
256 return;
257
258 // ===================================
259 // Port Name
260 // ===================================
261 if (!strcmp(name, PortTP.name) )
262 {
263 if (IUUpdateText(&PortTP, texts, names, n) < 0)
264 return;
265
266 PortTP.s = IPS_OK;
267 IDSetText (&PortTP, NULL);
268 return;
269 }
270
271 if (is_connected() == false)
272 {
273 IDMessage(mydev, "LX200 Basic is offline. Please connect before issuing any commands.");
274 reset_all_properties();
275 return;
276 }
277
278 // ===================================
279 // Object Name
280 // ===================================
281 if (!strcmp (name, ObjectTP.name))
282 {
283
284 if (IUUpdateText(&ObjectTP, texts, names, n) < 0)
285 return;
286
287 ObjectTP.s = IPS_OK;
288 IDSetText(&ObjectTP, NULL);
289 return;
290 }
291}
292
293/**************************************************************************************
294**
295***************************************************************************************/
296void LX200Basic::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
297{
298
299 // Ignore if not ours
300 if (strcmp (dev, mydev))
301 return;
302
303 if (is_connected() == false)
304 {
305 IDMessage(mydev, "LX200 Basic is offline. Please connect before issuing any commands.");
306 reset_all_properties();
307 return;
308 }
309
310 // ===================================
311 // Equatorial Coords
312 // ===================================
313 if (!strcmp (name, EquatorialCoordsWNP.name))
314 {
315 int i=0, nset=0, error_code=0;
316 double newRA =0, newDEC =0;
317
318 for (nset = i = 0; i < n; i++)
319 {
320 INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
321 if (eqp == &EquatorialCoordsWN[0])
322 {
323 newRA = values[i];
324 nset += newRA >= 0 && newRA <= 24.0;
325 } else if (eqp == &EquatorialCoordsWN[1])
326 {
327 newDEC = values[i];
328 nset += newDEC >= -90.0 && newDEC <= 90.0;
329 }
330 }
331
332 if (nset == 2)
333 {
334 char RAStr[32], DecStr[32];
335
336 fs_sexa(RAStr, newRA, 2, 3600);
337 fs_sexa(DecStr, newDEC, 2, 3600);
338
339 #ifdef INDI_DEBUG
340 IDLog("We received JNow RA %g - DEC %g\n", newRA, newDEC);
341 IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);
342 #endif
343
344 if ( (error_code = setObjectRA(fd, newRA)) < 0 || ( error_code = setObjectDEC(fd, newDEC)) < 0)
345 {
346 handle_error(&EquatorialCoordsWNP, error_code, "Setting RA/DEC");
347 return;
348 }
349
350 targetRA = newRA;
351 targetDEC = newDEC;
352
353 if (process_coords() == false)
354 {
355 EquatorialCoordsWNP.s = IPS_ALERT;
356 IDSetNumber(&EquatorialCoordsWNP, NULL);
357
358 }
359 } // end nset
360 else
361 {
362 EquatorialCoordsWNP.s = IPS_ALERT;
363 IDSetNumber(&EquatorialCoordsWNP, "RA or Dec missing or invalid");
364 }
365
366 return;
367 } /* end EquatorialCoordsWNP */
368
369 // ===================================
370 // Update tracking precision limits
371 // ===================================
372 if (!strcmp (name, TrackAccuracyNP.name))
373 {
374 if (IUUpdateNumber(&TrackAccuracyNP, values, names, n) < 0)
375 return;
376
377 TrackAccuracyNP.s = IPS_OK;
378
379 if (TrackAccuracyN[0].value < 3 || TrackAccuracyN[1].value < 3)
380 IDSetNumber(&TrackAccuracyNP, "Warning: Setting the tracking accuracy too low may result in a dead lock");
381 else
382 IDSetNumber(&TrackAccuracyNP, NULL);
383 return;
384 }
385
386 // ===================================
387 // Update slew precision limit
388 // ===================================
389 if (!strcmp(name, SlewAccuracyNP.name))
390 {
391 if (IUUpdateNumber(&SlewAccuracyNP, values, names, n) < 0)
392 return;
393
394 SlewAccuracyNP.s = IPS_OK;
395
396 if (SlewAccuracyN[0].value < 3 || SlewAccuracyN[1].value < 3)
397 IDSetNumber(&TrackAccuracyNP, "Warning: Setting the slew accuracy too low may result in a dead lock");
398
399 IDSetNumber(&SlewAccuracyNP, NULL);
400 return;
401
402
403 }
404}
405
406/**************************************************************************************
407**
408***************************************************************************************/
409void LX200Basic::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
410{
411 // ignore if not ours //
412 if (strcmp (mydev, dev))
413 return;
414
415 // ===================================
416 // Connect Switch
417 // ===================================
418 if (!strcmp (name, ConnectSP.name))
419 {
420 if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
421 return;
422
423 connect_telescope();
424 return;
425 }
426
427 if (is_connected() == false)
428 {
429 IDMessage(mydev, "LX200 Basic is offline. Please connect before issuing any commands.");
430 reset_all_properties();
431 return;
432 }
433
434 // ===================================
435 // Coordinate Set
436 // ===================================
437 if (!strcmp(name, OnCoordSetSP.name))
438 {
439 if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)
440 return;
441
442 currentSet = get_switch_index(&OnCoordSetSP);
443 OnCoordSetSP.s = IPS_OK;
444 IDSetSwitch(&OnCoordSetSP, NULL);
445 }
446
447 // ===================================
448 // Abort slew
449 // ===================================
450 if (!strcmp (name, AbortSlewSP.name))
451 {
452
453 IUResetSwitch(&AbortSlewSP);
454 abortSlew(fd);
455
456 if (EquatorialCoordsWNP.s == IPS_BUSY)
457 {
458 AbortSlewSP.s = IPS_OK;
459 EquatorialCoordsWNP.s = IPS_IDLE;
460 EquatorialCoordsRNP.s = IPS_IDLE;
461 IDSetSwitch(&AbortSlewSP, "Slew aborted.");
462 IDSetNumber(&EquatorialCoordsWNP, NULL);
463 IDSetNumber(&EquatorialCoordsRNP, NULL);
464 }
465
466 return;
467 }
468
469}
470
471/**************************************************************************************
472** Retry connecting to the telescope on error. Give up if there is no hope.
473***************************************************************************************/
474void LX200Basic::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
475{
476
477 nvp->s = IPS_ALERT;
478
479 /* First check to see if the telescope is connected */
480 if (check_lx200_connection(fd))
481 {
482 /* The telescope is off locally */
483 ConnectS[0].s = ISS_OFF;
484 ConnectS[1].s = ISS_ON;
485 ConnectSP.s = IPS_BUSY;
486 IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
487
488 IDSetNumber(nvp, NULL);
489 IEAddTimer(10000, retry_connection, &fd);
490 return;
491 }
492
493 /* If the error is a time out, then the device doesn't support this property */
494 if (err == -2)
495 {
496 nvp->s = IPS_ALERT;
497 IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
498 }
499 else
500 /* Changing property failed, user should retry. */
501 IDSetNumber( nvp , "%s failed.", msg);
502
503 fault = true;
504}
505
506/**************************************************************************************
507** Set all properties to idle and reset most switches to clean state.
508***************************************************************************************/
509void LX200Basic::reset_all_properties()
510{
511 ConnectSP.s = IPS_IDLE;
512 OnCoordSetSP.s = IPS_IDLE;
513 AbortSlewSP.s = IPS_IDLE;
514 PortTP.s = IPS_IDLE;
515 ObjectTP.s = IPS_IDLE;
516 EquatorialCoordsWNP.s = IPS_IDLE;
517 EquatorialCoordsRNP.s = IPS_IDLE;
518 SlewAccuracyNP.s = IPS_IDLE;
519 TrackAccuracyNP.s = IPS_IDLE;
520
521 IUResetSwitch(&OnCoordSetSP);
522 IUResetSwitch(&AbortSlewSP);
523
524 OnCoordSetS[0].s = ISS_ON;
525 ConnectS[0].s = ISS_OFF;
526 ConnectS[1].s = ISS_ON;
527
528 IDSetSwitch(&ConnectSP, NULL);
529 IDSetSwitch(&OnCoordSetSP, NULL);
530 IDSetSwitch(&AbortSlewSP, NULL);
531 IDSetText(&PortTP, NULL);
532 IDSetText(&ObjectTP, NULL);
533 IDSetNumber(&EquatorialCoordsWNP, NULL);
534 IDSetNumber(&EquatorialCoordsRNP, NULL);
535 IDSetNumber(&SlewAccuracyNP, NULL);
536 IDSetNumber(&TrackAccuracyNP, NULL);
537}
538
539/**************************************************************************************
540**
541***************************************************************************************/
542void LX200Basic::correct_fault()
543{
544 fault = false;
545 IDMessage(mydev, "Telescope is online.");
546}
547
548/**************************************************************************************
549**
550***************************************************************************************/
551bool LX200Basic::is_connected()
552{
553 if (simulation) return true;
554
555 return (ConnectSP.sp[0].s == ISS_ON);
556}
557
558/**************************************************************************************
559**
560***************************************************************************************/
561static void retry_connection(void * p)
562{
563 int fd = *((int *) p);
564
565 if (check_lx200_connection(fd))
566 telescope->connection_lost();
567 else
568 telescope->connection_resumed();
569}
570
571/**************************************************************************************
572**
573***************************************************************************************/
574void LX200Basic::ISPoll()
575{
576 if (is_connected() == false)
577 return;
578
579 double dx, dy;
580 int error_code=0;
581
582 switch (EquatorialCoordsWNP.s)
583 {
584 case IPS_IDLE:
585 getLX200RA(fd, &currentRA);
586 getLX200DEC(fd, &currentDEC);
587
588 // Only update values if there are some interesting changes
589 if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
590 {
591 lastRA = currentRA;
592 lastDEC = currentDEC;
593 IDSetNumber (&EquatorialCoordsRNP, NULL);
594 }
595 break;
596
597 case IPS_BUSY:
598 getLX200RA(fd, &currentRA);
599 getLX200DEC(fd, &currentDEC);
600 dx = targetRA - currentRA;
601 dy = targetDEC - currentDEC;
602
603 // Wait until acknowledged or within threshold
604 if ( fabs(dx) <= (SlewAccuracyN[0].value/(900.0)) && fabs(dy) <= (SlewAccuracyN[1].value/60.0))
605 {
606 lastRA = currentRA;
607 lastDEC = currentDEC;
608 IUResetSwitch(&OnCoordSetSP);
609 OnCoordSetSP.s = IPS_OK;
610 EquatorialCoordsWNP.s = IPS_OK;
611 EquatorialCoordsRNP.s = IPS_OK;
612 IDSetNumber (&EquatorialCoordsWNP, NULL);
613 IDSetNumber (&EquatorialCoordsRNP, NULL);
614
615 switch (currentSet)
616 {
617 case LX200_SLEW:
618 OnCoordSetSP.sp[LX200_SLEW].s = ISS_ON;
619 IDSetSwitch (&OnCoordSetSP, "Slew is complete.");
620 break;
621
622 case LX200_TRACK:
623 OnCoordSetSP.sp[LX200_TRACK].s = ISS_ON;
624 IDSetSwitch (&OnCoordSetSP, "Slew is complete. Tracking...");
625 break;
626
627 case LX200_SYNC:
628 break;
629 }
630
631 }
632 else
633 IDSetNumber (&EquatorialCoordsRNP, NULL);
634 break;
635
636 case IPS_OK:
637
638 if ( (error_code = getLX200RA(fd, &currentRA)) < 0 || (error_code = getLX200DEC(fd, &currentDEC)) < 0)
639 {
640 handle_error(&EquatorialCoordsRNP, error_code, "Getting RA/DEC");
641 return;
642 }
643
644 if (fault == true)
645 correct_fault();
646
647 if ( (currentRA != lastRA) || (currentDEC != lastDEC))
648 {
649 lastRA = currentRA;
650 lastDEC = currentDEC;
651 IDSetNumber (&EquatorialCoordsRNP, NULL);
652 }
653 break;
654
655 case IPS_ALERT:
656 break;
657 }
658}
659
660/**************************************************************************************
661**
662***************************************************************************************/
663bool LX200Basic::process_coords()
664{
665
666 int error_code;
667 char syncString[256];
668 char RAStr[32], DecStr[32];
669 double dx, dy;
670
671 switch (currentSet)
672 {
673
674 // Slew
675 case LX200_SLEW:
676 lastSet = LX200_SLEW;
677 if (EquatorialCoordsWNP.s == IPS_BUSY)
678 {
679 IDLog("Aboring Slew\n");
680 abortSlew(fd);
681
682 // sleep for 100 mseconds
683 usleep(100000);
684 }
685
686 if ((error_code = Slew(fd)))
687 {
688 slew_error(error_code);
689 return false;
690 }
691
692 EquatorialCoordsWNP.s = IPS_BUSY;
693 EquatorialCoordsRNP.s = IPS_BUSY;
694 fs_sexa(RAStr, targetRA, 2, 3600);
695 fs_sexa(DecStr, targetDEC, 2, 3600);
696 IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
697 IDSetNumber(&EquatorialCoordsRNP, NULL);
698 IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
699 break;
700
701 // Track
702 case LX200_TRACK:
703 //IDLog("We're in LX200_TRACK\n");
704 if (EquatorialCoordsWNP.s == IPS_BUSY)
705 {
706 IDLog("Aboring Slew\n");
707 abortSlew(fd);
708
709 // sleep for 200 mseconds
710 usleep(200000);
711 }
712
713 dx = fabs ( targetRA - currentRA );
714 dy = fabs (targetDEC - currentDEC);
715
716 if (dx >= (TrackAccuracyN[0].value/(60.0*15.0)) || (dy >= TrackAccuracyN[1].value/60.0))
717 {
718 if ((error_code = Slew(fd)))
719 {
720 slew_error(error_code);
721 return false;
722 }
723
724 fs_sexa(RAStr, targetRA, 2, 3600);
725 fs_sexa(DecStr, targetDEC, 2, 3600);
726 EquatorialCoordsWNP.s = IPS_BUSY;
727 EquatorialCoordsRNP.s = IPS_BUSY;
728 IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
729 IDSetNumber(&EquatorialCoordsRNP, NULL);
730 IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
731 }
732 else
733 {
734 //IDLog("Tracking called, but tracking threshold not reached yet.\n");
735 EquatorialCoordsWNP.s = IPS_OK;
736 EquatorialCoordsRNP.s = IPS_OK;
737
738 if (lastSet != LX200_TRACK)
739 IDSetNumber(&EquatorialCoordsWNP, "Tracking...");
740 else
741 IDSetNumber(&EquatorialCoordsWNP, NULL);
742
743 IDSetNumber(&EquatorialCoordsRNP, NULL);
744 }
745 lastSet = LX200_TRACK;
746 break;
747
748 // Sync
749 case LX200_SYNC:
750 lastSet = LX200_SYNC;
751 EquatorialCoordsWNP.s = IPS_IDLE;
752
753 if ( ( error_code = Sync(fd, syncString) < 0) )
754 {
755 IDSetNumber( &EquatorialCoordsWNP , "Synchronization failed.");
756 return false;
757 }
758
759 EquatorialCoordsWNP.s = IPS_OK;
760 EquatorialCoordsRNP.s = IPS_OK;
761 IDSetNumber(&EquatorialCoordsRNP, NULL);
762 IDLog("Synchronization successful %s\n", syncString);
763 IDSetNumber(&EquatorialCoordsWNP, "Synchronization successful.");
764 break;
765 }
766
767 return true;
768
769}
770
771/**************************************************************************************
772**
773***************************************************************************************/
774int LX200Basic::get_switch_index(ISwitchVectorProperty *sp)
775{
776 for (int i=0; i < sp->nsp ; i++)
777 if (sp->sp[i].s == ISS_ON)
778 return i;
779
780 return -1;
781}
782
783/**************************************************************************************
784**
785***************************************************************************************/
786void LX200Basic::connect_telescope()
787{
788 switch (ConnectSP.sp[0].s)
789 {
790 case ISS_ON:
791
792 if (simulation)
793 {
794 ConnectSP.s = IPS_OK;
795 IDSetSwitch (&ConnectSP, "Simulated telescope is online.");
796 return;
797 }
798
799 if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK)
800 {
801 ConnectS[0].s = ISS_OFF;
802 ConnectS[1].s = ISS_ON;
803 IDSetSwitch (&ConnectSP, "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", PortT[0].text);
804 return;
805 }
806
807 if (check_lx200_connection(fd))
808 {
809 ConnectS[0].s = ISS_OFF;
810 ConnectS[1].s = ISS_ON;
811 IDSetSwitch (&ConnectSP, "Error connecting to Telescope. Telescope is offline.");
812 return;
813 }
814
815 ConnectSP.s = IPS_OK;
816 IDSetSwitch (&ConnectSP, "Telescope is online. Retrieving basic data...");
817 get_initial_data();
818 break;
819
820 case ISS_OFF:
821 ConnectS[0].s = ISS_OFF;
822 ConnectS[1].s = ISS_ON;
823 ConnectSP.s = IPS_IDLE;
824 if (simulation)
825 {
826 IDSetSwitch (&ConnectSP, "Simulated Telescope is offline.");
827 return;
828 }
829 IDSetSwitch (&ConnectSP, "Telescope is offline.");
830 IDLog("Telescope is offline.");
831
832 tty_disconnect(fd);
833 break;
834 }
835}
836
837/**************************************************************************************
838**
839***************************************************************************************/
840void LX200Basic::get_initial_data()
841{
842
843 // Make sure short
844 checkLX200Format(fd);
845
846 // Get current RA/DEC
847 getLX200RA(fd, &currentRA);
848 getLX200DEC(fd, &currentDEC);
849
850 IDSetNumber (&EquatorialCoordsRNP, NULL);
851}
852
853/**************************************************************************************
854**
855***************************************************************************************/
856void LX200Basic::slew_error(int slewCode)
857{
858 OnCoordSetSP.s = IPS_IDLE;
859
860 if (slewCode == 1)
861 IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
862 else if (slewCode == 2)
863 IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
864 else
865 IDSetSwitch (&OnCoordSetSP, "Slew failed.");
866}
867
868/**************************************************************************************
869**
870***************************************************************************************/
871void LX200Basic::enable_simulation(bool enable)
872{
873 simulation = enable;
874
875 if (simulation)
876 IDLog("Warning: Simulation is activated.\n");
877 else
878 IDLog("Simulation is disabled.\n");
879}
880
881/**************************************************************************************
882**
883***************************************************************************************/
884void LX200Basic::connection_lost()
885{
886 ConnectSP.s = IPS_IDLE;
887 IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
888 return;
889
890}
891
892/**************************************************************************************
893**
894***************************************************************************************/
895void LX200Basic::connection_resumed()
896{
897 ConnectS[0].s = ISS_ON;
898 ConnectS[1].s = ISS_OFF;
899 ConnectSP.s = IPS_OK;
900
901 IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
902}
Note: See TracBrowser for help on using the repository browser.