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

Last change on this file since 620 was 501, checked in by frichard, 14 years ago

-BAOControl : petite interface permettant de contrôler les antennes via le pilote indi_BAO
-Le pilote indi_BAO utilise désormais libindi v 0.7

File size: 26.4 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   enable_simulation(false); 
166
167 }
168
169/**************************************************************************************
170**
171***************************************************************************************/
172LX200Basic::~LX200Basic()
173{
174
175}
176
177/**************************************************************************************
178** Initialize all properties & set default values.
179***************************************************************************************/
180void LX200Basic::init_properties()
181{
182    // Connection
183    IUFillSwitch(&ConnectS[0], "CONNECT", "Connect", ISS_OFF);
184    IUFillSwitch(&ConnectS[1], "DISCONNECT", "Disconnect", ISS_ON);
185    IUFillSwitchVector(&ConnectSP, ConnectS, NARRAY(ConnectS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
186
187    // Coord Set
188    IUFillSwitch(&OnCoordSetS[0], "SLEW", "Slew", ISS_ON);
189    IUFillSwitch(&OnCoordSetS[1], "TRACK", "Track", ISS_OFF);
190    IUFillSwitch(&OnCoordSetS[2], "SYNC", "Sync", ISS_OFF);
191    IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
192
193    // Abort
194    IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF);
195    IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
196
197    // Port
198    IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyS0");
199    IUFillTextVector(&PortTP, PortT, NARRAY(PortT), mydev, "DEVICE_PORT", "Ports", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
200
201    // Object Name
202    IUFillText(&ObjectT[0], "OBJECT_NAME", "Name", "--");
203    IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
204
205    // Equatorial Coords - SET
206    IUFillNumber(&EquatorialCoordsWN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
207    IUFillNumber(&EquatorialCoordsWN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
208    IUFillNumberVector(&EquatorialCoordsWNP, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), mydev, "EQUATORIAL_EOD_COORD_REQUEST" , "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
209
210    // Equatorial Coords - READ
211    IUFillNumber(&EquatorialCoordsRN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
212    IUFillNumber(&EquatorialCoordsRN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
213    IUFillNumberVector(&EquatorialCoordsRNP, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), mydev, "EQUATORIAL_EOD_COORD" , "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE);
214
215    // Slew threshold
216    IUFillNumber(&SlewAccuracyN[0], "SlewRA",  "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0);
217    IUFillNumber(&SlewAccuracyN[1], "SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
218    IUFillNumberVector(&SlewAccuracyNP, SlewAccuracyN, NARRAY(SlewAccuracyN), mydev, "Slew Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
219
220    // Track threshold
221    IUFillNumber(&TrackAccuracyN[0], "TrackRA", "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0);
222    IUFillNumber(&TrackAccuracyN[1], "TrackDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
223    IUFillNumberVector(&TrackAccuracyNP, TrackAccuracyN, NARRAY(TrackAccuracyN), mydev, "Tracking Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
224}
225
226/**************************************************************************************
227** Define LX200 Basic properties to clients.
228***************************************************************************************/
229void LX200Basic::ISGetProperties(const char *dev)
230{
231
232 if (dev && strcmp (mydev, dev))
233    return;
234
235  // Main Control
236  IDDefSwitch(&ConnectSP, NULL);
237  IDDefText(&PortTP, NULL);
238  IDDefText(&ObjectTP, NULL);
239  IDDefNumber(&EquatorialCoordsWNP, NULL);
240  IDDefNumber(&EquatorialCoordsRNP, NULL);
241  IDDefSwitch(&OnCoordSetSP, NULL);
242  IDDefSwitch(&AbortSlewSP, NULL);
243
244  // Options
245  IDDefNumber(&SlewAccuracyNP, NULL);
246  IDDefNumber(&TrackAccuracyNP, NULL);
247 
248}
249
250/**************************************************************************************
251** Process Text properties
252***************************************************************************************/
253void LX200Basic::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
254{
255        // Ignore if not ours
256        if (strcmp (dev, mydev))
257            return;
258
259        // ===================================
260        // Port Name
261        // ===================================
262        if (!strcmp(name, PortTP.name) )
263        {
264          if (IUUpdateText(&PortTP, texts, names, n) < 0)
265                return;
266
267          PortTP.s = IPS_OK;
268          IDSetText (&PortTP, NULL);
269          return;
270        }
271
272        if (is_connected() == false)
273        {
274                IDMessage(mydev, "LX200 Basic is offline. Please connect before issuing any commands.");
275                reset_all_properties();
276                return;
277        }
278
279       // ===================================
280       // Object Name
281       // ===================================
282       if (!strcmp (name, ObjectTP.name))
283       {
284
285          if (IUUpdateText(&ObjectTP, texts, names, n) < 0)
286                return;
287
288          ObjectTP.s = IPS_OK;
289          IDSetText(&ObjectTP, NULL);
290          return;
291       }
292}
293
294/**************************************************************************************
295**
296***************************************************************************************/
297void LX200Basic::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
298{
299       
300        // Ignore if not ours
301        if (strcmp (dev, mydev))
302            return;
303
304        if (is_connected() == false)
305        {
306                IDMessage(mydev, "LX200 Basic is offline. Please connect before issuing any commands.");
307                reset_all_properties();
308                return;
309        }
310
311        // ===================================
312        // Equatorial Coords
313        // ===================================
314        if (!strcmp (name, EquatorialCoordsWNP.name))
315        {
316          int i=0, nset=0, error_code=0;
317          double newRA =0, newDEC =0;
318
319            for (nset = i = 0; i < n; i++)
320            {
321                INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
322                if (eqp == &EquatorialCoordsWN[0])
323                {
324                    newRA = values[i];
325                    nset += newRA >= 0 && newRA <= 24.0;
326                } else if (eqp == &EquatorialCoordsWN[1])
327                {
328                    newDEC = values[i];
329                    nset += newDEC >= -90.0 && newDEC <= 90.0;
330                }
331            }
332
333          if (nset == 2)
334          {
335           char RAStr[32], DecStr[32];
336
337           fs_sexa(RAStr, newRA, 2, 3600);
338           fs_sexa(DecStr, newDEC, 2, 3600);
339         
340           #ifdef INDI_DEBUG
341           IDLog("We received JNow RA %g - DEC %g\n", newRA, newDEC);
342           IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);
343           #endif
344           
345           if (!simulation && ( (error_code = setObjectRA(fd, newRA)) < 0 || ( error_code = setObjectDEC(fd, newDEC)) < 0))
346           {
347             handle_error(&EquatorialCoordsWNP, error_code, "Setting RA/DEC");
348             return;
349           } 
350           
351           targetRA  = newRA;
352           targetDEC = newDEC;
353           
354           if (process_coords() == false)
355           {
356             EquatorialCoordsWNP.s = IPS_ALERT;
357             IDSetNumber(&EquatorialCoordsWNP, NULL);
358             
359           }
360        } // end nset
361        else
362        {
363                EquatorialCoordsWNP.s = IPS_ALERT;
364                IDSetNumber(&EquatorialCoordsWNP, "RA or Dec missing or invalid");
365        }
366
367            return;
368     } /* end EquatorialCoordsWNP */
369
370        // ===================================
371        // Update tracking precision limits
372        // ===================================
373        if (!strcmp (name, TrackAccuracyNP.name))
374        {
375                if (IUUpdateNumber(&TrackAccuracyNP, values, names, n) < 0)
376                        return;
377
378                TrackAccuracyNP.s = IPS_OK;
379
380                if (TrackAccuracyN[0].value < 3 || TrackAccuracyN[1].value < 3)
381                        IDSetNumber(&TrackAccuracyNP, "Warning: Setting the tracking accuracy too low may result in a dead lock");
382                else
383                        IDSetNumber(&TrackAccuracyNP, NULL);
384                return;
385        }
386
387        // ===================================
388        // Update slew precision limit
389        // ===================================
390        if (!strcmp(name, SlewAccuracyNP.name))
391        {
392                if (IUUpdateNumber(&SlewAccuracyNP, values, names, n) < 0)
393                        return;
394               
395                SlewAccuracyNP.s = IPS_OK;
396
397                if (SlewAccuracyN[0].value < 3 || SlewAccuracyN[1].value < 3)
398                        IDSetNumber(&TrackAccuracyNP, "Warning: Setting the slew accuracy too low may result in a dead lock");
399
400                IDSetNumber(&SlewAccuracyNP, NULL);
401                return;
402               
403
404        }
405}
406
407/**************************************************************************************
408**
409***************************************************************************************/
410void LX200Basic::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
411{
412        // ignore if not ours //
413        if (strcmp (mydev, dev))
414            return;
415
416        // ===================================
417        // Connect Switch
418        // ===================================
419        if (!strcmp (name, ConnectSP.name))
420        {
421            if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0)
422                return;
423
424            connect_telescope();
425            return;
426        }
427
428        if (is_connected() == false)
429        {
430                IDMessage(mydev, "LX200 Basic is offline. Please connect before issuing any commands.");
431                reset_all_properties();
432                return;
433        }
434
435        // ===================================
436        // Coordinate Set
437        // ===================================
438        if (!strcmp(name, OnCoordSetSP.name))
439        {
440           if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0)
441                return;
442
443          currentSet = get_switch_index(&OnCoordSetSP);
444          OnCoordSetSP.s = IPS_OK;
445          IDSetSwitch(&OnCoordSetSP, NULL);
446        }
447         
448        // ===================================
449        // Abort slew
450        // ===================================
451        if (!strcmp (name, AbortSlewSP.name))
452        {
453
454          IUResetSwitch(&AbortSlewSP);
455          abortSlew(fd);
456
457            if (EquatorialCoordsWNP.s == IPS_BUSY)
458            {
459                AbortSlewSP.s = IPS_OK;
460                EquatorialCoordsWNP.s       = IPS_IDLE;
461                EquatorialCoordsRNP.s       = IPS_IDLE;
462                IDSetSwitch(&AbortSlewSP, "Slew aborted.");
463                IDSetNumber(&EquatorialCoordsWNP, NULL);
464                IDSetNumber(&EquatorialCoordsRNP, NULL);
465            }
466
467            return;
468        }
469
470}
471
472/**************************************************************************************
473** Retry connecting to the telescope on error. Give up if there is no hope.
474***************************************************************************************/
475void LX200Basic::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
476{
477 
478  nvp->s = IPS_ALERT;
479 
480  /* First check to see if the telescope is connected */
481    if (check_lx200_connection(fd))
482    {
483      /* The telescope is off locally */
484      ConnectS[0].s = ISS_OFF;
485      ConnectS[1].s = ISS_ON;
486      ConnectSP.s = IPS_BUSY;
487      IDSetSwitch(&ConnectSP, "Telescope is not responding to commands, will retry in 10 seconds.");
488     
489      IDSetNumber(nvp, NULL);
490      IEAddTimer(10000, retry_connection, &fd);
491      return;
492    }
493   
494   /* If the error is a time out, then the device doesn't support this property */
495      if (err == -2)
496      {
497       nvp->s = IPS_ALERT;
498       IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
499      }
500      else
501    /* Changing property failed, user should retry. */
502       IDSetNumber( nvp , "%s failed.", msg);
503       
504       fault = true;
505}
506
507/**************************************************************************************
508** Set all properties to idle and reset most switches to clean state.
509***************************************************************************************/
510void LX200Basic::reset_all_properties()
511{
512    ConnectSP.s                 = IPS_IDLE;
513    OnCoordSetSP.s              = IPS_IDLE; 
514    AbortSlewSP.s               = IPS_IDLE;
515    PortTP.s                    = IPS_IDLE;
516    ObjectTP.s                  = IPS_IDLE;
517    EquatorialCoordsWNP.s       = IPS_IDLE;
518    EquatorialCoordsRNP.s       = IPS_IDLE;
519    SlewAccuracyNP.s            = IPS_IDLE;
520    TrackAccuracyNP.s           = IPS_IDLE;
521
522    IUResetSwitch(&OnCoordSetSP);
523    IUResetSwitch(&AbortSlewSP);
524
525    OnCoordSetS[0].s = ISS_ON;
526    ConnectS[0].s = ISS_OFF;
527    ConnectS[1].s = ISS_ON;
528
529    IDSetSwitch(&ConnectSP, NULL);
530    IDSetSwitch(&OnCoordSetSP, NULL);
531    IDSetSwitch(&AbortSlewSP, NULL);
532    IDSetText(&PortTP, NULL);
533    IDSetText(&ObjectTP, NULL);
534    IDSetNumber(&EquatorialCoordsWNP, NULL);
535    IDSetNumber(&EquatorialCoordsRNP, NULL);
536    IDSetNumber(&SlewAccuracyNP, NULL);
537    IDSetNumber(&TrackAccuracyNP, NULL);
538}
539
540/**************************************************************************************
541**
542***************************************************************************************/
543void LX200Basic::correct_fault()
544{
545  fault = false;
546  IDMessage(mydev, "Telescope is online.");
547}
548
549/**************************************************************************************
550**
551***************************************************************************************/
552bool LX200Basic::is_connected()
553{
554  if (simulation) return true;
555 
556  return (ConnectSP.sp[0].s == ISS_ON);
557}
558
559/**************************************************************************************
560**
561***************************************************************************************/
562static void retry_connection(void * p)
563{
564  int fd = *((int *) p);
565
566  if (check_lx200_connection(fd))
567        telescope->connection_lost();
568  else
569        telescope->connection_resumed();
570}
571
572/**************************************************************************************
573**
574***************************************************************************************/
575void LX200Basic::ISPoll()
576{       
577        if (is_connected() == false || simulation)
578         return;
579
580        double dx, dy;
581        int error_code=0;
582
583        switch (EquatorialCoordsWNP.s)
584        {
585                case IPS_IDLE:
586                getLX200RA(fd, &currentRA);
587                getLX200DEC(fd, &currentDEC);
588       
589                // Only update values if there are some interesting changes
590                if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
591                {
592                        lastRA = currentRA;
593                        lastDEC = currentDEC;
594                        IDSetNumber (&EquatorialCoordsRNP, NULL);
595                }
596                break;
597
598                case IPS_BUSY:
599                getLX200RA(fd, &currentRA);
600                getLX200DEC(fd, &currentDEC);
601                dx = targetRA - currentRA;
602                dy = targetDEC - currentDEC;
603
604                // Wait until acknowledged or within threshold
605                if ( fabs(dx) <= (SlewAccuracyN[0].value/(900.0)) && fabs(dy) <= (SlewAccuracyN[1].value/60.0))
606                {
607                        lastRA  = currentRA;
608                        lastDEC = currentDEC;
609                        IUResetSwitch(&OnCoordSetSP);
610                        OnCoordSetSP.s = IPS_OK;
611                        EquatorialCoordsWNP.s = IPS_OK;
612                        EquatorialCoordsRNP.s = IPS_OK;
613                        IDSetNumber (&EquatorialCoordsWNP, NULL);
614                        IDSetNumber (&EquatorialCoordsRNP, NULL);
615
616                        switch (currentSet)
617                        {
618                                case LX200_SLEW:
619                                OnCoordSetSP.sp[LX200_SLEW].s = ISS_ON;
620                                IDSetSwitch (&OnCoordSetSP, "Slew is complete.");
621                                break;
622                 
623                                case LX200_TRACK:
624                                OnCoordSetSP.sp[LX200_TRACK].s = ISS_ON;
625                                IDSetSwitch (&OnCoordSetSP, "Slew is complete. Tracking...");
626                                break;
627                 
628                                case LX200_SYNC:
629                                break;
630                        }
631                 
632                }
633                else
634                        IDSetNumber (&EquatorialCoordsRNP, NULL);
635                break;
636
637                case IPS_OK:
638         
639                if ( (error_code = getLX200RA(fd, &currentRA)) < 0 || (error_code = getLX200DEC(fd, &currentDEC)) < 0)
640                {
641                        handle_error(&EquatorialCoordsRNP, error_code, "Getting RA/DEC");
642                        return;
643                }
644       
645                if (fault == true)
646                        correct_fault();
647       
648                if ( (currentRA != lastRA) || (currentDEC != lastDEC))
649                {
650                        lastRA  = currentRA;
651                        lastDEC = currentDEC;
652                        IDSetNumber (&EquatorialCoordsRNP, NULL);
653                }
654                break;
655
656                case IPS_ALERT:
657                break;
658        }
659}
660
661/**************************************************************************************
662**
663***************************************************************************************/
664bool LX200Basic::process_coords()
665{
666
667  int  error_code;
668  char syncString[256];
669  char RAStr[32], DecStr[32];
670  double dx, dy;
671 
672  switch (currentSet)
673  {
674
675    // Slew
676    case LX200_SLEW:
677          lastSet = LX200_SLEW;
678          if (EquatorialCoordsWNP.s == IPS_BUSY)
679          {
680             IDLog("Aboring Slew\n");
681             abortSlew(fd);
682
683             // sleep for 100 mseconds
684             usleep(100000);
685          }
686
687          if ( !simulation && (error_code = Slew(fd)))
688          {
689            slew_error(error_code);
690            return false;
691          }
692
693          EquatorialCoordsWNP.s = IPS_BUSY;
694          EquatorialCoordsRNP.s = IPS_BUSY;
695          fs_sexa(RAStr, targetRA, 2, 3600);
696          fs_sexa(DecStr, targetDEC, 2, 3600);
697          IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
698          IDSetNumber(&EquatorialCoordsRNP, NULL);
699          IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
700          break;
701
702     // Track
703     case LX200_TRACK:
704          //IDLog("We're in LX200_TRACK\n");
705          if (EquatorialCoordsWNP.s == IPS_BUSY)
706          {
707             IDLog("Aboring Slew\n");
708             abortSlew(fd);
709
710             // sleep for 200 mseconds
711             usleep(200000);
712          }
713
714          dx = fabs ( targetRA - currentRA );
715          dy = fabs (targetDEC - currentDEC);
716
717          if (dx >= (TrackAccuracyN[0].value/(60.0*15.0)) || (dy >= TrackAccuracyN[1].value/60.0)) 
718          {
719                if ( !simulation && (error_code = Slew(fd)))
720                {
721                        slew_error(error_code);
722                        return false;
723                }
724
725                fs_sexa(RAStr, targetRA, 2, 3600);
726                fs_sexa(DecStr, targetDEC, 2, 3600);
727                EquatorialCoordsWNP.s = IPS_BUSY;
728                EquatorialCoordsRNP.s = IPS_BUSY;
729                IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
730                IDSetNumber(&EquatorialCoordsRNP, NULL);
731                IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
732          }
733          else
734          {
735            //IDLog("Tracking called, but tracking threshold not reached yet.\n");
736            EquatorialCoordsWNP.s = IPS_OK;
737            EquatorialCoordsRNP.s = IPS_OK;
738
739            if (lastSet != LX200_TRACK)
740              IDSetNumber(&EquatorialCoordsWNP, "Tracking...");
741            else
742              IDSetNumber(&EquatorialCoordsWNP, NULL);
743
744            IDSetNumber(&EquatorialCoordsRNP, NULL);
745          }
746          lastSet = LX200_TRACK;
747      break;
748
749    // Sync
750    case LX200_SYNC:
751          lastSet = LX200_SYNC;
752          EquatorialCoordsWNP.s = IPS_IDLE;
753           
754          if ( !simulation && ( error_code = Sync(fd, syncString) < 0) )
755          {
756                IDSetNumber( &EquatorialCoordsWNP , "Synchronization failed.");
757                return false;
758          }
759
760          if (simulation)
761          {
762             EquatorialCoordsRN[0].value = EquatorialCoordsWN[0].value;
763             EquatorialCoordsRN[1].value = EquatorialCoordsWN[1].value;
764          }
765
766          EquatorialCoordsWNP.s = IPS_OK;
767          EquatorialCoordsRNP.s = IPS_OK;
768          IDSetNumber(&EquatorialCoordsRNP, NULL);
769          IDLog("Synchronization successful %s\n", syncString);
770          IDSetNumber(&EquatorialCoordsWNP, "Synchronization successful.");
771          break;
772    }
773
774   return true;
775
776}
777
778/**************************************************************************************
779**
780***************************************************************************************/
781int LX200Basic::get_switch_index(ISwitchVectorProperty *sp)
782{
783 for (int i=0; i < sp->nsp ; i++)
784     if (sp->sp[i].s == ISS_ON)
785      return i;
786
787 return -1;
788}
789
790/**************************************************************************************
791**
792***************************************************************************************/
793void LX200Basic::connect_telescope()
794{
795     switch (ConnectSP.sp[0].s)
796     {
797      case ISS_ON: 
798       
799        if (simulation)
800        {
801          ConnectSP.s = IPS_OK;
802          IDSetSwitch (&ConnectSP, "Simulated telescope is online.");
803          return;
804        }
805       
806         if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK)
807         {
808           ConnectS[0].s = ISS_OFF;
809           ConnectS[1].s = ISS_ON;
810           IDSetSwitch (&ConnectSP, "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", PortT[0].text);
811           return;
812         }
813
814         if (check_lx200_connection(fd))
815         {   
816           ConnectS[0].s = ISS_OFF;
817           ConnectS[1].s = ISS_ON;
818           IDSetSwitch (&ConnectSP, "Error connecting to Telescope. Telescope is offline.");
819           return;
820         }
821
822        ConnectSP.s = IPS_OK;
823        IDSetSwitch (&ConnectSP, "Telescope is online. Retrieving basic data...");
824        get_initial_data();
825        break;
826
827     case ISS_OFF:
828         ConnectS[0].s = ISS_OFF;
829         ConnectS[1].s = ISS_ON;
830         ConnectSP.s = IPS_IDLE;
831         if (simulation)
832         {
833            IDSetSwitch (&ConnectSP, "Simulated Telescope is offline.");
834            return;
835         }
836         IDSetSwitch (&ConnectSP, "Telescope is offline.");
837         IDLog("Telescope is offline.");
838         
839         tty_disconnect(fd);
840         break;
841    }
842}
843
844/**************************************************************************************
845**
846***************************************************************************************/
847void LX200Basic::get_initial_data()
848{
849
850  // Make sure short
851  checkLX200Format(fd);
852
853  // Get current RA/DEC
854  getLX200RA(fd, &currentRA);
855  getLX200DEC(fd, &currentDEC);
856
857  IDSetNumber (&EquatorialCoordsRNP, NULL); 
858}
859
860/**************************************************************************************
861**
862***************************************************************************************/
863void LX200Basic::slew_error(int slewCode)
864{
865    OnCoordSetSP.s = IPS_IDLE;
866
867    if (slewCode == 1)
868        IDSetSwitch (&OnCoordSetSP, "Object below horizon.");
869    else if (slewCode == 2)
870        IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit.");
871    else
872        IDSetSwitch (&OnCoordSetSP, "Slew failed.");
873}
874
875/**************************************************************************************
876**
877***************************************************************************************/
878void LX200Basic::enable_simulation(bool enable)
879{
880   simulation = enable;
881   
882   if (simulation)
883     IDLog("Warning: Simulation is activated.\n");
884   else
885     IDLog("Simulation is disabled.\n");
886}
887
888/**************************************************************************************
889**
890***************************************************************************************/
891void LX200Basic::connection_lost()
892{
893    ConnectSP.s = IPS_IDLE;
894    IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
895    return;
896 
897}
898
899/**************************************************************************************
900**
901***************************************************************************************/
902void LX200Basic::connection_resumed()
903{
904  ConnectS[0].s = ISS_ON;
905  ConnectS[1].s = ISS_OFF;
906  ConnectSP.s = IPS_OK;
907   
908  IDSetSwitch(&ConnectSP, "The connection to the telescope has been resumed.");
909}
Note: See TracBrowser for help on using the repository browser.