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

Last change on this file since 612 was 490, checked in by campagne, 14 years ago

import libindi (JEC)

File size: 22.9 KB
Line 
1#if 0
2    Celestron GPS
3    Copyright (C) 2003 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
29#include "celestronprotocol.h"
30#include "celestrongps.h"
31
32#define mydev           "Celestron GPS"
33
34/* Handy Macros */
35#define currentRA       EquatorialCoordsRN[0].value
36#define currentDEC      EquatorialCoordsRN[1].value
37#define targetRA        EquatorialCoordsWN[0].value
38#define targetDEC       EquatorialCoordsWN[1].value
39
40/* Enable to log debug statements
41#define CELESTRON_DEBUG 1
42*/
43
44CelestronGPS *telescope = NULL;
45
46
47/* There is _one_ binary for all LX200 drivers, but each binary is renamed
48** to its device name (i.e. lx200gps, lx200_16..etc). The main function will
49** fetch from std args the binary name and ISInit will create the apporpiate
50** device afterwards. If the binary name does not match any known devices,
51** we simply create a generic device
52*/
53extern char* me;
54
55#define COMM_GROUP      "Communication"
56#define BASIC_GROUP     "Main Control"
57#define MOVE_GROUP      "Movement Control"
58
59static void ISPoll(void *);
60
61/*INDI controls */
62static ISwitch SlewModeS[]       = {{"Slew", "", ISS_ON, 0, 0}, {"Find", "", ISS_OFF, 0, 0}, {"Centering", "", ISS_OFF, 0, 0}, {"Guide", "", ISS_OFF, 0, 0}};
63
64/* Equatorial Coordinates: Request */
65static INumber EquatorialCoordsWN[] = {    {"RA",  "RA  H:M:S", "%10.6m",  0., 24., 0., 0., 0, 0, 0},    {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};
66static INumberVectorProperty EquatorialCoordsWNP = {  mydev, "EQUATORIAL_EOD_COORD_REQUEST", "Equatorial JNow", BASIC_GROUP, IP_WO, 120, IPS_IDLE,  EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), "", 0};
67
68/* Equatorial Coordinates: Info */
69static INumber EquatorialCoordsRN[] = {    {"RA",  "RA  H:M:S", "%10.6m",  0., 24., 0., 0., 0, 0, 0},    {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};
70static INumberVectorProperty EquatorialCoordsRNP = {  mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RO, 120, IPS_IDLE,  EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), "", 0};
71
72/* Tracking precision */
73INumber TrackingAccuracyN[] = {
74    {"TrackRA",  "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0, 0, 0, 0},
75    {"TrackDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0},
76};
77static INumberVectorProperty TrackingAccuracyNP = {mydev, "Tracking Accuracy", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, TrackingAccuracyN, NARRAY(TrackingAccuracyN), "", 0};
78
79/* Slew precision */
80INumber SlewAccuracyN[] = {
81    {"SlewRA",  "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0, 0, 0, 0},
82    {"SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0},
83};
84static INumberVectorProperty SlewAccuracyNP = {mydev, "Slew Accuracy", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, SlewAccuracyN, NARRAY(SlewAccuracyN), "", 0};
85
86/* Fundamental group */
87static ISwitch ConnectS[]          = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}};
88static ISwitchVectorProperty ConnectSP  = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ConnectS, NARRAY(ConnectS), "", 0};
89
90static IText PortT[]                    = {{"PORT", "Port", 0, 0, 0, 0}};
91static ITextVectorProperty PortTP               = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0};
92
93/* Movement group */
94static ISwitch OnCoordSetS[]     = {{"SLEW", "Slew", ISS_ON, 0 , 0}, {"TRACK", "Track", ISS_OFF, 0, 0}, {"SYNC", "Sync", ISS_OFF, 0, 0}};
95static ISwitchVectorProperty OnCoordSetSP    = { mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, OnCoordSetS, NARRAY(OnCoordSetS), "", 0};
96
97static ISwitch AbortSlewS[]      = {{"ABORT", "Abort", ISS_OFF, 0, 0}};
98static ISwitchVectorProperty AbortSlewSP     = { mydev, "TELESCOPE_ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, AbortSlewS, NARRAY(AbortSlewS), "", 0};
99static ISwitchVectorProperty SlewModeSP      = { mydev, "Slew rate", "", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SlewModeS, NARRAY(SlewModeS), "", 0};
100
101/* Movement (Arrow keys on handset). North/South */
102static ISwitch MovementNSS[]       = {{"MOTION_NORTH", "North", ISS_OFF, 0, 0}, {"MOTION_SOUTH", "South", ISS_OFF, 0, 0}};
103
104static ISwitchVectorProperty MovementNSSP      = { mydev, "TELESCOPE_MOTION_NS", "North/South", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementNSS, NARRAY(MovementNSS), "", 0};
105
106/* Movement (Arrow keys on handset). West/East */
107static ISwitch MovementWES[]       = {{"MOTION_WEST", "West", ISS_OFF, 0, 0}, {"MOTION_EAST", "East", ISS_OFF, 0, 0}};
108
109static ISwitchVectorProperty MovementWESP      = { mydev, "TELESCOPE_MOTION_WE", "West/East", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0};
110
111
112/* send client definitions of all properties */
113void ISInit()
114{
115  static int isInit=0;
116
117 if (isInit)
118  return;
119
120 isInit = 1;
121
122  IUSaveText(&PortT[0], "/dev/ttyS0");
123 
124  telescope = new CelestronGPS();
125
126  IEAddTimer (POLLMS, ISPoll, NULL);
127}
128
129void ISGetProperties (const char *dev)
130{ ISInit(); telescope->ISGetProperties(dev);}
131void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
132{ ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);}
133void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
134{ ISInit(); telescope->ISNewText(dev, name, texts, names, n);}
135void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
136{ ISInit(); telescope->ISNewNumber(dev, name, values, names, n);}
137void ISPoll (void *p) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;}
138void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) 
139{
140  INDI_UNUSED(dev);
141  INDI_UNUSED(name);
142  INDI_UNUSED(sizes);
143  INDI_UNUSED(blobsizes);
144  INDI_UNUSED(blobs);
145  INDI_UNUSED(formats);
146  INDI_UNUSED(names);
147  INDI_UNUSED(n);
148}
149void ISSnoopDevice (XMLEle *root) 
150{
151  INDI_UNUSED(root);
152}
153
154/**************************************************
155*** LX200 Generic Implementation
156***************************************************/
157
158CelestronGPS::CelestronGPS()
159{
160
161   lastRA = 0;
162   lastDEC = 0;
163   currentSet   = 0;
164   lastSet      = -1;
165
166   // Children call parent routines, this is the default
167   IDLog("initilizaing from Celeston GPS device...\n");
168
169}
170
171void CelestronGPS::ISGetProperties(const char *dev)
172{
173
174 if (dev && strcmp (mydev, dev))
175    return;
176
177  // COMM_GROUP
178  IDDefSwitch (&ConnectSP, NULL);
179  IDDefText   (&PortTP, NULL);
180 
181  // BASIC_GROUP
182  IDDefNumber (&EquatorialCoordsWNP, NULL);
183  IDDefNumber (&EquatorialCoordsRNP, NULL);
184  IDDefSwitch (&OnCoordSetSP, NULL);
185  IDDefSwitch (&AbortSlewSP, NULL);
186  IDDefSwitch (&SlewModeSP, NULL);
187
188  // Movement group
189  IDDefSwitch (&MovementNSSP, NULL);
190  IDDefSwitch (&MovementWESP, NULL);
191  IDDefNumber (&TrackingAccuracyNP, NULL);
192  IDDefNumber (&SlewAccuracyNP, NULL);
193 
194  /* Send the basic data to the new client if the previous client(s) are already connected. */         
195  if (ConnectSP.s == IPS_OK)
196        getBasicData();
197
198}
199
200void CelestronGPS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
201{
202        IText *tp;
203
204        INDI_UNUSED(n);
205
206        // ignore if not ours //
207        if (strcmp (dev, mydev))
208            return;
209
210        if (!strcmp(name, PortTP.name) )
211        {
212          PortTP.s = IPS_OK;
213
214          tp = IUFindText( &PortTP, names[0] );
215          if (!tp)
216           return;
217
218          IUSaveText(&PortT[0], texts[0]);
219          IDSetText (&PortTP, NULL);
220          return;
221        }
222}
223
224int CelestronGPS::handleCoordSet()
225{
226
227  int i=0;
228  char RAStr[32], DecStr[32];
229
230  switch (currentSet)
231  {
232
233    // Slew
234    case 0:
235          lastSet = 0;
236          if (EquatorialCoordsWNP.s == IPS_BUSY)
237          {
238             StopNSEW();
239             // sleep for 500 mseconds
240             usleep(500000);
241          }
242
243          if ((i = SlewToCoords(targetRA, targetDEC)))
244          {
245            slewError(i);
246            return (-1);
247          }
248
249          EquatorialCoordsWNP.s = IPS_BUSY;
250          EquatorialCoordsRNP.s = IPS_BUSY;
251          fs_sexa(RAStr, targetRA, 2, 3600);
252          fs_sexa(DecStr, targetDEC, 2, 3600);
253          IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
254          IDSetNumber(&EquatorialCoordsRNP, NULL);
255          IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
256          break;
257
258
259  // Track
260  case 1: 
261          if (EquatorialCoordsWNP.s == IPS_BUSY)
262          {
263              StopNSEW();
264             // sleep for 500 mseconds
265             usleep(500000);
266          }
267
268          if ( (fabs ( targetRA - currentRA ) >= (TrackingAccuracyN[0].value/(15.0*60.0))) ||
269               (fabs (targetDEC - currentDEC) >= (TrackingAccuracyN[1].value)/60.0))
270          {
271
272                #ifdef CELESTRON_DEBUG
273                IDLog("Exceeded Tracking threshold, will attempt to slew to the new target.\n");
274                IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA);
275                IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC);
276                #endif
277
278                if (( i =  SlewToCoords(targetRA, targetDEC)))
279                {
280                        slewError(i);
281                        return (-1);
282                }
283               
284                fs_sexa(RAStr, targetRA, 2, 3600);
285                fs_sexa(DecStr, targetDEC, 2, 3600);
286                EquatorialCoordsWNP.s = IPS_BUSY;
287                EquatorialCoordsRNP.s = IPS_BUSY;
288                IDSetNumber(&EquatorialCoordsWNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr);
289                IDSetNumber(&EquatorialCoordsRNP, NULL);
290                IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
291          }
292          else
293          {
294            #ifdef CELESTRON_DEBUG
295            IDLog("Tracking called, but tracking threshold not reached yet.\n");
296            #endif
297            EquatorialCoordsWNP.s = IPS_OK;
298            EquatorialCoordsRNP.s = IPS_OK;
299            if (lastSet != 1)
300              IDSetNumber(&EquatorialCoordsWNP, "Tracking...");
301            else
302              IDSetNumber(&EquatorialCoordsWNP, NULL);
303
304              IDSetNumber(&EquatorialCoordsRNP, NULL);
305          }
306          lastSet = 1;
307      break;
308     
309    // Sync
310    case 2:
311          lastSet = 2;
312          OnCoordSetSP.s = IPS_OK;
313          SyncToCoords(targetRA, targetDEC);
314          EquatorialCoordsWNP.s = IPS_OK;
315          EquatorialCoordsRNP.s = IPS_OK;
316          IDSetNumber(&EquatorialCoordsWNP, "Synchronization successful.");
317          IDSetNumber(&EquatorialCoordsRNP, NULL);
318          break;
319   }
320
321   return (0);
322
323}
324
325void CelestronGPS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
326{
327        double newRA=0, newDEC=0;
328
329        // ignore if not ours //
330        if (strcmp (dev, mydev))
331            return;
332
333        struct tm *tp;
334        time_t t;
335
336        time (&t);
337        tp = gmtime (&t);
338
339        if (!strcmp (name, TrackingAccuracyNP.name))
340        {
341                if (!IUUpdateNumber(&TrackingAccuracyNP, values, names, n))
342                {
343                        TrackingAccuracyNP.s = IPS_OK;
344                        IDSetNumber(&TrackingAccuracyNP, NULL);
345                        return;
346                }
347               
348                TrackingAccuracyNP.s = IPS_ALERT;
349                IDSetNumber(&TrackingAccuracyNP, "unknown error while setting tracking precision");
350                return;
351        }
352
353        if (!strcmp(name, SlewAccuracyNP.name))
354        {
355                IUUpdateNumber(&SlewAccuracyNP, values, names, n);
356                {
357                        SlewAccuracyNP.s = IPS_OK;
358                        IDSetNumber(&SlewAccuracyNP, NULL);
359                        return;
360                }
361               
362                SlewAccuracyNP.s = IPS_ALERT;
363                IDSetNumber(&SlewAccuracyNP, "unknown error while setting slew precision");
364                return;
365        }
366
367        if (!strcmp (name, EquatorialCoordsWNP.name))
368        {
369          int i=0, nset=0;
370
371          if (checkPower(&EquatorialCoordsWNP))
372           return;
373
374            for (nset = i = 0; i < n; i++)
375            {
376                INumber *eqp = IUFindNumber (&EquatorialCoordsWNP, names[i]);
377                if (eqp == &EquatorialCoordsWN[0])
378                {
379                    newRA = values[i];
380                    nset += newRA >= 0 && newRA <= 24.0;
381                } else if (eqp == &EquatorialCoordsWN[1])
382                {
383                    newDEC = values[i];
384                    nset += newDEC >= -90.0 && newDEC <= 90.0;
385                }
386            }
387
388          if (nset == 2)
389          {
390           //EquatorialCoordsNP.s = IPS_BUSY;
391
392           tp->tm_mon   += 1;
393           tp->tm_year  += 1900;
394
395           targetRA  = newRA;
396           targetDEC = newDEC;
397               
398           if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY)
399           {
400                IUResetSwitch(&MovementNSSP);
401                IUResetSwitch(&MovementWESP);
402                MovementNSSP.s = MovementWESP.s = IPS_IDLE;
403                IDSetSwitch(&MovementNSSP, NULL);
404                IDSetSwitch(&MovementWESP, NULL);
405           }
406           
407               if (handleCoordSet())
408               {
409                EquatorialCoordsWNP.s = IPS_ALERT;
410                IDSetNumber(&EquatorialCoordsWNP, NULL);
411               }
412            }
413            else
414            {
415                EquatorialCoordsWNP.s = IPS_ALERT;
416                IDSetNumber(&EquatorialCoordsWNP, "RA or Dec missing or invalid.");
417            }
418
419            return;
420         }
421}
422
423void CelestronGPS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
424{
425
426        int index;
427
428        INDI_UNUSED(names);
429
430        // ignore if not ours //
431        if (strcmp (dev, mydev))
432            return;
433
434        // FIRST Switch ALWAYS for power
435        if (!strcmp (name, ConnectSP.name))
436        {
437         if (IUUpdateSwitch(&ConnectSP, states, names, n) < 0) return;
438         connectTelescope();
439         return;
440        }
441
442        if (!strcmp(name, OnCoordSetSP.name))
443        {
444          if (checkPower(&OnCoordSetSP))
445           return;
446
447         
448          if (IUUpdateSwitch(&OnCoordSetSP, states, names, n) < 0) return;
449          currentSet = getOnSwitch(&OnCoordSetSP);
450        }
451       
452        // Abort Slew
453        if (!strcmp (name, AbortSlewSP.name))
454        {
455          if (checkPower(&AbortSlewSP))
456          {
457            AbortSlewSP.s = IPS_ALERT;
458            IDSetSwitch(&AbortSlewSP, NULL);
459            return;
460          }
461         
462          IUResetSwitch(&AbortSlewSP);
463          StopNSEW();
464
465            if (EquatorialCoordsWNP.s == IPS_BUSY)
466            {
467                AbortSlewSP.s = IPS_OK;
468                EquatorialCoordsWNP.s       = IPS_IDLE;
469                EquatorialCoordsRNP.s       = IPS_IDLE;
470                IDSetSwitch(&AbortSlewSP, "Slew aborted.");
471                IDSetNumber(&EquatorialCoordsWNP, NULL);
472                IDSetNumber(&EquatorialCoordsRNP, NULL);
473            }
474            else if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY)
475            {
476                MovementNSSP.= MovementWESP.s =  IPS_IDLE; 
477       
478                AbortSlewSP.s = IPS_OK;         
479                EquatorialCoordsRNP.s       = IPS_IDLE;
480                IUResetSwitch(&MovementNSSP);
481                IUResetSwitch(&MovementWESP);
482                IUResetSwitch(&AbortSlewSP);
483
484                IDSetSwitch(&AbortSlewSP, "Slew aborted.");
485                IDSetSwitch(&MovementNSSP, NULL);
486                IDSetSwitch(&MovementWESP, NULL);
487                IDSetNumber(&EquatorialCoordsRNP, NULL);
488            }
489            else
490            {
491                AbortSlewSP.s = IPS_OK;
492                IDSetSwitch(&AbortSlewSP, NULL);
493            }
494
495            return;
496        }
497
498        // Slew mode
499        if (!strcmp (name, SlewModeSP.name))
500        {
501          if (checkPower(&SlewModeSP))
502           return;
503
504          IUResetSwitch(&SlewModeSP);
505          IUUpdateSwitch(&SlewModeSP, states, names, n);
506          index = getOnSwitch(&SlewModeSP);
507          SetRate(index);
508         
509          SlewModeSP.s = IPS_OK;
510          IDSetSwitch(&SlewModeSP, NULL);
511          return;
512        }
513
514        // Movement (North/South)
515        if (!strcmp (name, MovementNSSP.name))
516        {
517          if (checkPower(&MovementNSSP))
518           return;
519
520         int last_move=-1;
521         int current_move = -1;
522
523        // -1 means all off previously
524         last_move = getOnSwitch(&MovementNSSP);
525
526         if (IUUpdateSwitch(&MovementNSSP, states, names, n) < 0)
527                return;
528
529        current_move = getOnSwitch(&SlewModeSP);
530
531        // Previosuly active switch clicked again, so let's stop.
532        if (current_move == last_move)
533        {
534                StopSlew((current_move == 0) ? NORTH : SOUTH);
535                IUResetSwitch(&MovementNSSP);
536                MovementNSSP.s = IPS_IDLE;
537                IDSetSwitch(&MovementNSSP, NULL);
538                return;
539        }
540
541        #ifdef CELESTRON_DEBUG
542        IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move);
543        #endif
544
545        // 0 (North) or 1 (South)
546        last_move      = current_move;
547
548        // Correction for Celestron Driver: North 0 - South 3
549        current_move = (current_move == 0) ? NORTH : SOUTH;
550
551        StartSlew(current_move);
552       
553          MovementNSSP.s = IPS_BUSY;
554          IDSetSwitch(&MovementNSSP, "Moving toward %s", (current_move == NORTH) ? "North" : "South");
555          return;
556        }
557
558        // Movement (West/East)
559        if (!strcmp (name, MovementWESP.name))
560        {
561          if (checkPower(&MovementWESP))
562           return;
563
564         int last_move=-1;
565         int current_move = -1;
566
567        // -1 means all off previously
568         last_move = getOnSwitch(&MovementWESP);
569
570         if (IUUpdateSwitch(&MovementWESP, states, names, n) < 0)
571                return;
572
573        current_move = getOnSwitch(&SlewModeSP);
574
575        // Previosuly active switch clicked again, so let's stop.
576        if (current_move == last_move)
577        {
578                StopSlew((current_move ==0) ? WEST : EAST);
579                IUResetSwitch(&MovementWESP);
580                MovementWESP.s = IPS_IDLE;
581                IDSetSwitch(&MovementWESP, NULL);
582                return;
583        }
584
585        #ifdef CELESTRON_DEBUG
586        IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move);
587        #endif
588
589        // 0 (West) or 1 (East)
590        last_move      = current_move;
591
592        // Correction for Celestron Driver: West 1 - East 2
593        current_move = (current_move == 0) ? WEST : EAST;
594
595        StartSlew(current_move);
596       
597          MovementWESP.s = IPS_BUSY;
598          IDSetSwitch(&MovementWESP, "Moving toward %s", (current_move == WEST) ? "West" : "East");
599          return;
600        }
601}
602
603
604int CelestronGPS::getOnSwitch(ISwitchVectorProperty *sp)
605{
606 for (int i=0; i < sp->nsp ; i++)
607     if (sp->sp[i].s == ISS_ON)
608      return i;
609
610 return -1;
611}
612
613
614int CelestronGPS::checkPower(ISwitchVectorProperty *sp)
615{
616  if (ConnectSP.s != IPS_OK)
617  {
618    if (!strcmp(sp->label, ""))
619       IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->name);
620    else
621       IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->label);
622       
623    sp->s = IPS_IDLE;
624    IDSetSwitch(sp, NULL);
625    return -1;
626  }
627
628  return 0;
629}
630
631int CelestronGPS::checkPower(INumberVectorProperty *np)
632{
633  if (ConnectSP.s != IPS_OK)
634  {
635    if (!strcmp(np->label, ""))
636       IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->name);
637    else
638       IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->label);
639       
640    np->s = IPS_IDLE;
641    IDSetNumber(np, NULL);
642    return -1;
643  }
644  return 0;
645}
646
647int CelestronGPS::checkPower(ITextVectorProperty *tp)
648{
649
650  if (ConnectSP.s != IPS_OK)
651  {
652    if (!strcmp(tp->label, ""))
653       IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->name);
654    else
655       IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->label);
656       
657    tp->s = IPS_IDLE;
658    IDSetText(tp, NULL);
659    return -1;
660  }
661
662  return 0;
663
664}
665
666void CelestronGPS::ISPoll()
667{
668       double dx, dy;
669       int status;
670
671        switch (EquatorialCoordsWNP.s)
672        {
673        case IPS_IDLE:
674        if (ConnectSP.s != IPS_OK)
675         break;
676        currentRA = GetRA();
677        currentDEC = GetDec();
678
679        if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
680        {
681                lastRA  = currentRA;
682                lastDEC = currentDEC;
683                IDSetNumber (&EquatorialCoordsRNP, NULL);
684
685        }
686        break;
687
688        case IPS_BUSY:
689            currentRA = GetRA();
690            currentDEC = GetDec();
691            dx = targetRA - currentRA;
692            dy = targetDEC - currentDEC;
693
694            #ifdef CELESTRON_DEBUG
695            IDLog("targetRA is %f, currentRA is %f\n", (float) targetRA, (float) currentRA);
696            IDLog("targetDEC is %f, currentDEC is %f\n****************************\n", (float) targetDEC, (float) currentDEC);
697            #endif
698
699            status = CheckCoords(targetRA, targetDEC, SlewAccuracyN[0].value/(15.0*60.0) , SlewAccuracyN[1].value/60.0);
700
701            // Wait until acknowledged or within 3.6', change as desired.
702            switch (status)
703            {
704            case 0:             /* goto in progress */
705                IDSetNumber (&EquatorialCoordsRNP, NULL);
706                break;
707            case 1:             /* goto complete within tolerance */
708            case 2:             /* goto complete but outside tolerance */
709                currentRA = targetRA;
710                currentDEC = targetDEC;
711
712                EquatorialCoordsWNP.s = IPS_OK;
713                EquatorialCoordsRNP.s = IPS_OK;
714
715                if (currentSet == 0)
716                {
717                  IDSetNumber (&EquatorialCoordsWNP, "Slew is complete.");
718                  IDSetNumber (&EquatorialCoordsRNP, NULL);
719                }
720                else
721                {
722                  IDSetNumber (&EquatorialCoordsWNP, "Slew is complete. Tracking...");
723                  IDSetNumber (&EquatorialCoordsRNP, NULL);
724                }
725               
726                break;
727            }   
728            break;
729
730        case IPS_OK:
731        if (ConnectSP.s != IPS_OK)
732         break;
733        currentRA = GetRA();
734        currentDEC = GetDec();
735
736        if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01)
737        {
738                lastRA  = currentRA;
739                lastDEC = currentDEC;
740                IDSetNumber (&EquatorialCoordsRNP, NULL);
741
742        }
743        break;
744
745
746        case IPS_ALERT:
747            break;
748        }
749
750        switch (MovementNSSP.s)
751        {
752          case IPS_IDLE:
753           break;
754         case IPS_BUSY:
755             currentRA = GetRA();
756             currentDEC = GetDec();
757             IDSetNumber (&EquatorialCoordsRNP, NULL);
758
759             break;
760         case IPS_OK:
761           break;
762         case IPS_ALERT:
763           break;
764         }
765
766        switch (MovementWESP.s)
767        {
768          case IPS_IDLE:
769           break;
770         case IPS_BUSY:
771             currentRA = GetRA();
772             currentDEC = GetDec();
773             IDSetNumber (&EquatorialCoordsRNP, NULL);
774
775             break;
776         case IPS_OK:
777           break;
778         case IPS_ALERT:
779           break;
780         }
781
782}
783
784void CelestronGPS::getBasicData()
785{
786
787  currentRA = GetRA();
788  currentDEC = GetDec();
789
790  IDSetNumber(&EquatorialCoordsRNP, NULL);
791
792}
793
794void CelestronGPS::connectTelescope()
795{
796
797     switch (ConnectSP.sp[0].s)
798     {
799      case ISS_ON:
800
801         if (ConnectTel(PortTP.tp[0].text) < 0)
802         {
803           ConnectS[0].s = ISS_OFF;
804           ConnectS[1].s = ISS_ON;
805           IDSetSwitch (&ConnectSP, "Error connecting to port %s. Make sure you have BOTH write and read permission to the port.", PortTP.tp[0].text);
806           return;
807         }
808
809        ConnectSP.s = IPS_OK;
810        IDSetSwitch (&ConnectSP, "Telescope is online. Retrieving basic data...");
811        getBasicData();
812        break;
813
814     case ISS_OFF:
815         IDSetSwitch (&ConnectSP, "Telescope is offline.");
816         IDLog("Telescope is offline.");
817         DisconnectTel();
818         break;
819
820    }
821}
822
823void CelestronGPS::slewError(int slewCode)
824{
825    EquatorialCoordsWNP.s = IPS_ALERT;
826
827    switch (slewCode)
828    {
829      case 1:
830       IDSetNumber (&EquatorialCoordsWNP, "Invalid newDec in SlewToCoords");
831       break;
832      case 2:
833       IDSetNumber (&EquatorialCoordsWNP, "RA count overflow in SlewToCoords");
834       break;
835      case 3:
836       IDSetNumber (&EquatorialCoordsWNP, "Dec count overflow in SlewToCoords");
837       break;
838      case 4:
839       IDSetNumber (&EquatorialCoordsWNP, "No acknowledgment from telescope after SlewToCoords");
840       break;
841      default:
842       IDSetNumber (&EquatorialCoordsWNP, "Unknown error");
843       break;
844    }
845
846}
Note: See TracBrowser for help on using the repository browser.