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

Last change on this file since 612 was 490, checked in by campagne, 14 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.