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

Last change on this file since 689 was 490, checked in by campagne, 15 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.s = 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.