Instrument Neutral Distributed Interface INDI  1.9.5
lx200ap_legacy.cpp
Go to the documentation of this file.
1 /*
2  Astro-Physics INDI driver
3 
4  Copyright (C) 2014 Jasem Mutlaq
5 
6  Based on INDI Astrophysics Driver by Markus Wildi
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 
23 #include "lx200ap.h"
24 
25 #include "indicom.h"
26 #include "lx200driver.h"
27 #include "lx200apdriver.h"
28 
29 #include <libnova/transform.h>
30 
31 #include <cmath>
32 #include <cstring>
33 #include <unistd.h>
34 #include <termios.h>
35 
36 #define MOUNT_TAB "Mount"
37 
38 /* Constructor */
40 {
41  setLX200Capability(LX200_HAS_PULSE_GUIDING);
42  SetTelescopeCapability(GetTelescopeCapability() | TELESCOPE_HAS_PIER_SIDE | TELESCOPE_HAS_PEC | TELESCOPE_CAN_CONTROL_TRACK
43  | TELESCOPE_HAS_TRACK_RATE, 4);
44 
45  sendLocationOnStartup = false;
46  sendTimeOnStartup = false;
47 }
48 
50 {
51  return (const char *)"AstroPhysics";
52 }
53 
55 {
57 
59 
60  IUFillSwitch(&StartUpS[0], "COLD", "Cold", ISS_OFF);
61  IUFillSwitch(&StartUpS[1], "WARM", "Warm", ISS_OFF);
62  IUFillSwitchVector(&StartUpSP, StartUpS, 2, getDeviceName(), "STARTUP", "Mount init.", MAIN_CONTROL_TAB, IP_RW,
63  ISR_1OFMANY, 0, IPS_IDLE);
64 
65  IUFillNumber(&HourangleCoordsN[0], "HA", "HA H:M:S", "%10.6m", 0., 24., 0., 0.);
66  IUFillNumber(&HourangleCoordsN[1], "DEC", "Dec D:M:S", "%10.6m", -90.0, 90.0, 0., 0.);
67  IUFillNumberVector(&HourangleCoordsNP, HourangleCoordsN, 2, getDeviceName(), "HOURANGLE_COORD", "Hourangle Coords",
69 
70  IUFillNumber(&HorizontalCoordsN[0], "AZ", "Az D:M:S", "%10.6m", 0., 360., 0., 0.);
71  IUFillNumber(&HorizontalCoordsN[1], "ALT", "Alt D:M:S", "%10.6m", -90., 90., 0., 0.);
73  "Horizontal Coords", MAIN_CONTROL_TAB, IP_RW, 120, IPS_IDLE);
74 
75 
76  // Max rate is 999.99999X for the GTOCP4.
77  // Using :RR998.9999# just to be safe. 15.041067*998.99999 = 15026.02578
78  TrackRateN[AXIS_RA].min = -15026.0258;
79  TrackRateN[AXIS_RA].max = 15026.0258;
80  TrackRateN[AXIS_DE].min = -998.9999;
81  TrackRateN[AXIS_DE].max = 998.9999;
82 
83  // Motion speed of axis when pressing NSWE buttons
84  IUFillSwitch(&SlewRateS[0], "12", "12x", ISS_OFF);
85  IUFillSwitch(&SlewRateS[1], "64", "64x", ISS_ON);
86  IUFillSwitch(&SlewRateS[2], "600", "600x", ISS_OFF);
87  IUFillSwitch(&SlewRateS[3], "1200", "1200x", ISS_OFF);
88  IUFillSwitchVector(&SlewRateSP, SlewRateS, 4, getDeviceName(), "TELESCOPE_SLEW_RATE", "Slew Rate", MOTION_TAB, IP_RW,
89  ISR_1OFMANY, 0, IPS_IDLE);
90 
91  // Slew speed when performing regular GOTO
92  IUFillSwitch(&APSlewSpeedS[0], "600", "600x", ISS_ON);
93  IUFillSwitch(&APSlewSpeedS[1], "900", "900x", ISS_OFF);
94  IUFillSwitch(&APSlewSpeedS[2], "1200", "1200x", ISS_OFF);
96  0, IPS_IDLE);
97 
98  IUFillSwitch(&SwapS[0], "NS", "North/South", ISS_OFF);
99  IUFillSwitch(&SwapS[1], "EW", "East/West", ISS_OFF);
100  IUFillSwitchVector(&SwapSP, SwapS, 2, getDeviceName(), "SWAP", "Swap buttons", MOTION_TAB, IP_RW, ISR_1OFMANY, 0,
101  IPS_IDLE);
102 
103  IUFillSwitch(&SyncCMRS[USE_REGULAR_SYNC], ":CM#", ":CM#", ISS_OFF);
104  IUFillSwitch(&SyncCMRS[USE_CMR_SYNC], ":CMR#", ":CMR#", ISS_ON);
106  IPS_IDLE);
107 
108  // guide speed
109  IUFillSwitch(&APGuideSpeedS[0], "0.25", "0.25x", ISS_OFF);
110  IUFillSwitch(&APGuideSpeedS[1], "0.5", "0.50x", ISS_OFF);
111  IUFillSwitch(&APGuideSpeedS[2], "1.0", "1.0x", ISS_ON);
113  0, IPS_IDLE);
114 
115  IUFillText(&VersionT[0], "Number", "", nullptr);
116  IUFillTextVector(&VersionTP, VersionT, 1, getDeviceName(), "Firmware Info", "", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
117 
118  IUFillText(&DeclinationAxisT[0], "RELHA", "rel. to HA", "undefined");
119  IUFillTextVector(&DeclinationAxisTP, DeclinationAxisT, 1, getDeviceName(), "DECLINATIONAXIS", "Declination axis",
120  MOUNT_TAB, IP_RO, 0, IPS_IDLE);
121 
122  // Slew threshold
123  IUFillNumber(&SlewAccuracyN[0], "SlewRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0);
124  IUFillNumber(&SlewAccuracyN[1], "SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
126  IPS_IDLE);
127 
129 
130  return true;
131 }
132 
133 void LX200AstroPhysics::ISGetProperties(const char *dev)
134 {
136 
137  /*
138  if (isConnected())
139  {
140  defineProperty(&StartUpSP);
141  defineProperty(&VersionTP);
142 
143  //defineProperty(&DeclinationAxisTP);
144 
145  // Motion group
146  defineProperty(&APSlewSpeedSP);
147  defineProperty(&SwapSP);
148  defineProperty(&SyncCMRSP);
149  defineProperty(&APGuideSpeedSP);
150  defineProperty(&SlewAccuracyNP);
151 
152  LOG_INFO("Please initialize the mount before issuing any command.");
153  }
154  */
155 }
156 
158 {
160 
161  if (isConnected())
162  {
165 
166  //defineProperty(&DeclinationAxisTP);
167 
168  /* Motion group */
174 
175  LOG_INFO("Please initialize the mount before issuing any command.");
176  }
177  else
178  {
181  //deleteProperty(DeclinationAxisTP.name);
187  }
188 
189  return true;
190 }
191 
192 bool LX200AstroPhysics::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
193 {
194  int err = 0;
195 
196  // ignore if not ours //
197  if (strcmp(getDeviceName(), dev))
198  return false;
199 
200  // ============================================================
201  // Satisfy AP mount initialization, see AP key pad manual p. 76
202  // ============================================================
203  if (!strcmp(name, StartUpSP.name))
204  {
205  int switch_nr;
206 
207  IUUpdateSwitch(&StartUpSP, states, names, n);
208 
209  if (initStatus == MOUNTNOTINITIALIZED)
210  {
211  if (timeUpdated == false || locationUpdated == false)
212  {
214  LOG_ERROR("Time and location must be set before mount initialization is invoked.");
215  IDSetSwitch(&StartUpSP, nullptr);
216  return false;
217  }
218 
219  if (StartUpSP.sp[0].s == ISS_ON) // do it only in case a power on (cold start)
220  {
221  if (setBasicDataPart1() == false)
222  {
224  IDSetSwitch(&StartUpSP, "Cold mount initialization failed.");
225  return false;
226  }
227  }
228 
229  initStatus = MOUNTINITIALIZED;
230 
231  if (isSimulation())
232  {
233  SlewRateSP.s = IPS_OK;
234  IDSetSwitch(&SlewRateSP, nullptr);
235 
237  IDSetSwitch(&APSlewSpeedSP, nullptr);
238 
239  IUSaveText(&VersionT[0], "1.0");
240  VersionTP.s = IPS_OK;
241  IDSetText(&VersionTP, nullptr);
242 
243  StartUpSP.s = IPS_OK;
244  IDSetSwitch(&StartUpSP, "Mount initialized.");
245 
246  //currentRA = 0;
247  //currentDEC = 90;
248  }
249  else
250  {
251  // Make sure that the mount is setup according to the properties
252  switch_nr = IUFindOnSwitchIndex(&TrackModeSP);
253 
254  if ( (err = selectAPTrackingMode(PortFD, switch_nr)) < 0)
255  {
256  LOGF_ERROR("StartUpSP: Error setting tracking mode (%d).", err);
257  return false;
258  }
259 
261 
262  // On most mounts SlewRateS defines the MoveTo AND Slew (GOTO) speeds
263  // lx200ap is different - some of the MoveTo speeds are not VALID
264  // Slew speeds so we have to keep two lists.
265  //
266  // SlewRateS is used as the MoveTo speed
267  switch_nr = IUFindOnSwitchIndex(&SlewRateSP);
268  if ( (err = selectAPMoveToRate(PortFD, switch_nr)) < 0)
269  {
270  LOGF_ERROR("StartUpSP: Error setting move rate (%d).", err);
271  return false;
272  }
273 
274  SlewRateSP.s = IPS_OK;
275  IDSetSwitch(&SlewRateSP, nullptr);
276 
277  // APSlewSpeedsS defines the Slew (GOTO) speeds valid on the AP mounts
278  switch_nr = IUFindOnSwitchIndex(&APSlewSpeedSP);
279  if ( (err = selectAPSlewRate(PortFD, switch_nr)) < 0)
280  {
281  LOGF_ERROR("StartUpSP: Error setting slew to rate (%d).", err);
282  return false;
283  }
285  IDSetSwitch(&APSlewSpeedSP, nullptr);
286 
289 
290  // make a IDSet in order the dome controller is aware of the initial values
293 
295 
296  char versionString[64];
297  getAPVersionNumber(PortFD, versionString);
298  VersionTP.s = IPS_OK;
299  IUSaveText(&VersionT[0], versionString);
300  IDSetText(&VersionTP, nullptr);
301 
302  // TODO check controller type here
303  INDI_UNUSED(controllerType);
304  INDI_UNUSED(servoType);
305  //controllerType = ...;
306 
307  StartUpSP.s = IPS_OK;
308  IDSetSwitch(&StartUpSP, "Mount initialized.");
309 
310  }
311  }
312  else
313  {
314  StartUpSP.s = IPS_OK;
315  IDSetSwitch(&StartUpSP, "Mount is already initialized.");
316  }
317  return true;
318  }
319 
320  // =======================================
321  // Swap Buttons
322  // =======================================
323  if (!strcmp(name, SwapSP.name))
324  {
325  int currentSwap;
326 
328  IUUpdateSwitch(&SwapSP, states, names, n);
329  currentSwap = IUFindOnSwitchIndex(&SwapSP);
330 
331  if ((!isSimulation() && (err = swapAPButtons(PortFD, currentSwap)) < 0))
332  {
333  LOGF_ERROR("Error swapping buttons (%d).", err);
334  return false;
335  }
336 
337  SwapS[0].s = ISS_OFF;
338  SwapS[1].s = ISS_OFF;
339  SwapSP.s = IPS_OK;
340  IDSetSwitch(&SwapSP, nullptr);
341  return true;
342  }
343 
344  // ===========================================================
345  // GOTO ("slew") Speed.
346  // ===========================================================
347  if (!strcmp(name, APSlewSpeedSP.name))
348  {
349  IUUpdateSwitch(&APSlewSpeedSP, states, names, n);
350  int slewRate = IUFindOnSwitchIndex(&APSlewSpeedSP);
351 
352  if (!isSimulation() && (err = selectAPSlewRate(PortFD, slewRate) < 0))
353  {
354  LOGF_ERROR("Error setting move to rate (%d).", err);
355  return false;
356  }
357 
359  IDSetSwitch(&APSlewSpeedSP, nullptr);
360  return true;
361  }
362 
363  // ===========================================================
364  // Guide Speed.
365  // ===========================================================
366  if (!strcmp(name, APGuideSpeedSP.name))
367  {
368  IUUpdateSwitch(&APGuideSpeedSP, states, names, n);
369  int guideRate = IUFindOnSwitchIndex(&APGuideSpeedSP);
370 
371  if (!isSimulation() && (err = selectAPGuideRate(PortFD, guideRate) < 0))
372  {
373  LOGF_ERROR("Error setting guiding to rate (%d).", err);
374  return false;
375  }
376 
378  IDSetSwitch(&APGuideSpeedSP, nullptr);
379  return true;
380  }
381 
382  // =======================================
383  // Choose the appropriate sync command
384  // =======================================
385  if (!strcmp(name, SyncCMRSP.name))
386  {
388  IUUpdateSwitch(&SyncCMRSP, states, names, n);
390  SyncCMRSP.s = IPS_OK;
391  IDSetSwitch(&SyncCMRSP, nullptr);
392  return true;
393  }
394 
395  // =======================================
396  // Choose the PEC playback mode
397  // =======================================
398  if (!strcmp(name, PECStateSP.name))
399  {
401  IUUpdateSwitch(&PECStateSP, states, names, n);
403 
404  int pecstate = IUFindOnSwitchIndex(&PECStateSP);
405 
406  if (!isSimulation() && (err = selectAPPECState(PortFD, pecstate) < 0))
407  {
408  LOGF_ERROR("Error setting PEC state (%d).", err);
409  return false;
410  }
411 
412  PECStateSP.s = IPS_OK;
413  IDSetSwitch(&PECStateSP, nullptr);
414 
415  return true;
416  }
417 
418  return LX200Generic::ISNewSwitch(dev, name, states, names, n);
419 }
420 
421 /**************************************************************************************
422 **
423 ***************************************************************************************/
424 bool LX200AstroPhysics::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
425 {
426  if (strcmp(getDeviceName(), dev))
427  return false;
428 
429  // Update slew precision limit
430  if (!strcmp(name, SlewAccuracyNP.name))
431  {
432  if (IUUpdateNumber(&SlewAccuracyNP, values, names, n) < 0)
433  return false;
434 
436 
437  if (SlewAccuracyN[0].value < 3 || SlewAccuracyN[1].value < 3)
438  IDSetNumber(&SlewAccuracyNP, "Warning: Setting the slew accuracy too low may result in a dead lock");
439 
440  IDSetNumber(&SlewAccuracyNP, nullptr);
441  return true;
442  }
443 
444  return LX200Generic::ISNewNumber(dev, name, values, names, n);
445 }
446 
447 bool LX200AstroPhysics::isMountInit()
448 {
449  return (StartUpSP.s != IPS_IDLE);
450 }
451 
453 {
454  if (!isMountInit())
455  return false;
456 
457  if (isSimulation())
458  {
459  mountSim();
460  return true;
461  }
462 
464  {
465  EqNP.s = IPS_ALERT;
466  IDSetNumber(&EqNP, "Error reading RA/DEC.");
467  return false;
468  }
469 
470  if (TrackState == SCOPE_SLEWING)
471  {
472  double dx = targetRA - currentRA;
473  double dy = targetDEC - currentDEC;
474 
475  // Wait until acknowledged or within threshold
476  if (fabs(dx) <= (SlewAccuracyN[0].value / (900.0)) && fabs(dy) <= (SlewAccuracyN[1].value / 60.0))
477  {
479  LOG_INFO("Slew is complete. Tracking...");
480  }
481  }
482  else if (TrackState == SCOPE_PARKING)
483  {
484  double currentAlt, currentAz;
485  if (getLX200Az(PortFD, &currentAz) < 0 || getLX200Alt(PortFD, &currentAlt) < 0)
486  {
487  EqNP.s = IPS_ALERT;
488  IDSetNumber(&EqNP, "Error reading Az/Alt.");
489  return false;
490  }
491 
492  double dx = GetAxis1Park() - currentAz;
493  double dy = GetAxis2Park() - currentAlt;
494 
495  LOGF_DEBUG("Parking... targetAz: %g currentAz: %g dx: %g targetAlt: %g currentAlt: %g dy: %g", GetAxis1Park(),
496  currentAz, dx, GetAxis2Park(), currentAlt, dy);
497 
498  if (fabs(dx) <= (SlewAccuracyN[0].value / (60.0)) && fabs(dy) <= (SlewAccuracyN[1].value / 60.0))
499  {
500  LOG_DEBUG("Parking slew is complete. Asking astrophysics mount to park...");
501 
502  if (!isSimulation() && setAPPark(PortFD) < 0)
503  {
504  LOG_ERROR("Parking Failed.");
505  return false;
506  }
507 
508  SetParked(true);
509  }
510  }
511 
513 
514  syncSideOfPier();
515 
516  return true;
517 }
518 
519 bool LX200AstroPhysics::setBasicDataPart0()
520 {
521  int err;
522  //struct ln_date utm;
523  //struct ln_zonedate ltm;
524 
525  if (isSimulation() == true)
526  {
527  LOG_INFO("setBasicDataPart0 simulation complete.");
528  return true;
529  }
530 
531  if ((err = setAPClearBuffer(PortFD)) < 0)
532  {
533  LOGF_ERROR("Error clearing the buffer (%d): %s", err, strerror(err));
534  return false;
535  }
536 
537  if ((err = setAPLongFormat(PortFD)) < 0)
538  {
539  LOGF_ERROR("Error setting long format failed (%d): %s", err, strerror(err));
540  return false;
541  }
542 
543  if ((err = setAPBackLashCompensation(PortFD, 0, 0, 0)) < 0)
544  {
545  // It seems we need to send it twice before it works!
546  if ((err = setAPBackLashCompensation(PortFD, 0, 0, 0)) < 0)
547  {
548  LOGF_ERROR("Error setting back lash compensation (%d): %s.", err, strerror(err));
549  return false;
550  }
551  }
552 
553  // Detect and set fomat. It should be LONG.
555 
556  return true;
557 }
558 
559 bool LX200AstroPhysics::setBasicDataPart1()
560 {
561  int err = 0;
562 
563  if (InitPark())
564  {
565  // If loading parking data is successful, we just set the default parking values.
566  SetAxis1ParkDefault(LocationN[LOCATION_LATITUDE].value >= 0 ? 0 : 180);
568  }
569  else
570  {
571  // Otherwise, we set all parking data to default in case no parking data is found.
572  SetAxis1Park(LocationN[LOCATION_LATITUDE].value >= 0 ? 0 : 180);
574 
575  SetAxis1ParkDefault(LocationN[LOCATION_LATITUDE].value >= 0 ? 0 : 180);
577  }
578 
579  // Unpark
580  UnPark();
581 
582  // Stop
583  if (!isSimulation() && (err = setAPMotionStop(PortFD)) < 0)
584  {
585  LOGF_ERROR("Stop motion (:Q#) failed, check the mount (%d): %s", err, strerror(err));
586  return false;
587  }
588 
589  // AP always track after unpark? Must check
591 
592  return true;
593 }
594 
595 bool LX200AstroPhysics::Goto(double r, double d)
596 {
597  const struct timespec timeout = {0, 100000000L};
598 
599  targetRA = r;
600  targetDEC = d;
601  char RAStr[64], DecStr[64];
602 
603  fs_sexa(RAStr, targetRA, 2, 3600);
604  fs_sexa(DecStr, targetDEC, 2, 3600);
605 
606  // If moving, let's stop it first.
607  if (EqNP.s == IPS_BUSY)
608  {
609  if (!isSimulation() && abortSlew(PortFD) < 0)
610  {
611  AbortSP.s = IPS_ALERT;
612  IDSetSwitch(&AbortSP, "Abort slew failed.");
613  return false;
614  }
615 
616  AbortSP.s = IPS_OK;
617  EqNP.s = IPS_IDLE;
618  IDSetSwitch(&AbortSP, "Slew aborted.");
619  IDSetNumber(&EqNP, nullptr);
620 
622  {
625  EqNP.s = IPS_IDLE;
628  IDSetSwitch(&MovementNSSP, nullptr);
629  IDSetSwitch(&MovementWESP, nullptr);
630  }
631 
632  // sleep for 100 mseconds
633  nanosleep(&timeout, nullptr);
634  }
635 
636  if (!isSimulation())
637  {
639  {
640  EqNP.s = IPS_ALERT;
641  IDSetNumber(&EqNP, "Error setting RA/DEC.");
642  return false;
643  }
644 
645  int err = 0;
646 
647  /* Slew reads the '0', that is not the end of the slew */
648  if ((err = Slew(PortFD)))
649  {
650  EqNP.s = IPS_ALERT;
651  IDSetNumber(&EqNP, "Error Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
652  slewError(err);
653  return false;
654  }
655  }
656 
658  //EqNP.s = IPS_BUSY;
659 
660  LOGF_INFO("Slewing to RA: %s - DEC: %s", RAStr, DecStr);
661  return true;
662 }
663 
664 
665 int LX200AstroPhysics::SendPulseCmd(int8_t direction, uint32_t duration_msec)
666 {
667  return APSendPulseCmd(PortFD, direction, duration_msec);
668 }
669 
670 
672 {
673  return setBasicDataPart0();
674 }
675 
677 {
678  timeUpdated = false;
679  locationUpdated = false;
680 
681  return LX200Generic::Disconnect();
682 }
683 
684 bool LX200AstroPhysics::Sync(double ra, double dec)
685 {
686  char syncString[256];
687 
688  int syncType = IUFindOnSwitchIndex(&SyncCMRSP);
689 
690  if (!isSimulation())
691  {
692  if (setAPObjectRA(PortFD, ra) < 0 || setAPObjectDEC(PortFD, dec) < 0)
693  {
694  EqNP.s = IPS_ALERT;
695  IDSetNumber(&EqNP, "Error setting RA/DEC. Unable to Sync.");
696  return false;
697  }
698 
699  bool syncOK = true;
700 
701  switch (syncType)
702  {
703  case USE_REGULAR_SYNC:
704  if (::Sync(PortFD, syncString) < 0)
705  syncOK = false;
706  break;
707 
708  case USE_CMR_SYNC:
709  if (APSyncCMR(PortFD, syncString) < 0)
710  syncOK = false;
711  break;
712 
713  default:
714  break;
715  }
716 
717  if (syncOK == false)
718  {
719  EqNP.s = IPS_ALERT;
720  IDSetNumber(&EqNP, "Synchronization failed.");
721  return false;
722  }
723 
724  }
725 
726  currentRA = ra;
727  currentDEC = dec;
728 
729  LOGF_DEBUG("%s Synchronization successful %s", (syncType == USE_REGULAR_SYNC ? "CM" : "CMR"), syncString);
730  LOG_INFO("Synchronization successful.");
731 
732  EqNP.s = IPS_OK;
733 
735 
736  return true;
737 }
738 
739 bool LX200AstroPhysics::updateTime(ln_date *utc, double utc_offset)
740 {
741  struct ln_zonedate ltm;
742 
743  if (isSimulation())
744  {
745  timeUpdated = true;
746  return true;
747  }
748 
749  ln_date_to_zonedate(utc, &ltm, utc_offset * 3600.0);
750 
751  JD = ln_get_julian_day(utc);
752 
753  LOGF_DEBUG("New JD is %.2f", JD);
754 
755  // Set Local Time
756  if (setLocalTime(PortFD, ltm.hours, ltm.minutes, (int)ltm.seconds) < 0)
757  {
758  LOG_ERROR("Error setting local time.");
759  return false;
760  }
761 
762  LOGF_DEBUG("Set Local Time %02d:%02d:%02d is successful.", ltm.hours, ltm.minutes,
763  (int)ltm.seconds);
764 
765  if (setCalenderDate(PortFD, ltm.days, ltm.months, ltm.years) < 0)
766  {
767  LOG_ERROR("Error setting local date.");
768  return false;
769  }
770 
771  LOGF_DEBUG("Set Local Date %02d/%02d/%02d is successful.", ltm.days, ltm.months, ltm.years);
772 
773  if (setAPUTCOffset(PortFD, fabs(utc_offset)) < 0)
774  {
775  LOG_ERROR("Error setting UTC Offset.");
776  return false;
777  }
778 
779  LOGF_DEBUG("Set UTC Offset %g (always positive for AP) is successful.", fabs(utc_offset));
780 
781  LOG_INFO("Time updated.");
782 
783  timeUpdated = true;
784 
785  return true;
786 }
787 
788 bool LX200AstroPhysics::updateLocation(double latitude, double longitude, double elevation)
789 {
790  INDI_UNUSED(elevation);
791 
792  if (isSimulation())
793  {
794  locationUpdated = true;
795  return true;
796  }
797 
798  if (!isSimulation() && setAPSiteLongitude(PortFD, 360.0 - longitude) < 0)
799  {
800  LOG_ERROR("Error setting site longitude coordinates");
801  return false;
802  }
803 
804  if (!isSimulation() && setAPSiteLatitude(PortFD, latitude) < 0)
805  {
806  LOG_ERROR("Error setting site latitude coordinates");
807  return false;
808  }
809 
810  char l[32], L[32];
811  fs_sexa(l, latitude, 3, 3600);
812  fs_sexa(L, longitude, 4, 3600);
813 
814  LOGF_INFO("Site location updated to Lat %.32s - Long %.32s", l, L);
815 
816  locationUpdated = true;
817 
818  return true;
819 }
820 
821 void LX200AstroPhysics::debugTriggered(bool enable)
822 {
823  INDI_UNUSED(enable);
826 }
827 
828 
829 // For most mounts the SetSlewRate() method sets both the MoveTo and Slew (GOTO) speeds.
830 // For AP mounts these two speeds are handled separately - so SetSlewRate() actually sets the MoveTo speed for AP mounts - confusing!
831 // ApSetSlew
832 bool LX200AstroPhysics::SetSlewRate(int index)
833 {
834  if (!isSimulation() && selectAPMoveToRate(PortFD, index) < 0)
835  {
837  IDSetSwitch(&SlewRateSP, "Error setting slew mode.");
838  return false;
839  }
840 
841  SlewRateSP.s = IPS_OK;
842  IDSetSwitch(&SlewRateSP, nullptr);
843  return true;
844 }
845 
847 {
848  if (initStatus == MOUNTNOTINITIALIZED)
849  {
850  LOG_WARN("You must initialize the mount before parking.");
851  return false;
852  }
853 
854  double parkAz = GetAxis1Park();
855  double parkAlt = GetAxis2Park();
856 
857  char AzStr[16], AltStr[16];
858  fs_sexa(AzStr, parkAz, 2, 3600);
859  fs_sexa(AltStr, parkAlt, 2, 3600);
860  LOGF_DEBUG("Parking to Az (%s) Alt (%s)...", AzStr, AltStr);
861 
862  if (isSimulation())
863  {
864  INDI::IEquatorialCoordinates equatorialCoords {0, 0};
865  INDI::IHorizontalCoordinates horizontalCoords {parkAz, parkAlt};
866  INDI::HorizontalToEquatorial(&horizontalCoords, &m_Location, ln_get_julian_from_sys(), &equatorialCoords);
867  Goto(equatorialCoords.rightascension, equatorialCoords.declination);
868  }
869  else
870  {
871  if (setAPObjectAZ(PortFD, parkAz) < 0 || setAPObjectAlt(PortFD, parkAlt) < 0)
872  {
873  LOG_ERROR("Error setting Az/Alt.");
874  return false;
875  }
876 
877  int err = 0;
878 
879  /* Slew reads the '0', that is not the end of the slew */
880  if ((err = Slew(PortFD)))
881  {
882  LOGF_ERROR("Error Slewing to Az %s - Alt %s", AzStr, AltStr);
883  slewError(err);
884  return false;
885  }
886  }
887 
888  EqNP.s = IPS_BUSY;
890  LOG_INFO("Parking is in progress...");
891 
892  return true;
893 }
894 
896 {
897  // First we unpark astrophysics
898  if (isSimulation() == false)
899  {
900  if (setAPUnPark(PortFD) < 0)
901  {
902  LOG_ERROR("UnParking Failed.");
903  return false;
904  }
905  }
906 
907  // Then we sync with to our last stored position
908  double parkAz = GetAxis1Park();
909  double parkAlt = GetAxis2Park();
910 
911  char AzStr[16], AltStr[16];
912  fs_sexa(AzStr, parkAz, 2, 3600);
913  fs_sexa(AltStr, parkAlt, 2, 3600);
914  LOGF_DEBUG("Syncing to parked coordinates Az (%s) Alt (%s)...", AzStr, AltStr);
915 
916  if (isSimulation())
917  {
918  INDI::IEquatorialCoordinates equatorialCoords {0, 0};
919  INDI::IHorizontalCoordinates horizontalCoords {parkAz, parkAlt};
920  INDI::HorizontalToEquatorial(&horizontalCoords, &m_Location, ln_get_julian_from_sys(), &equatorialCoords);
921 
922  currentRA = equatorialCoords.rightascension;
923  currentDEC = equatorialCoords.declination;
924  }
925  else
926  {
927  if (setAPObjectAZ(PortFD, parkAz) < 0 || (setAPObjectAlt(PortFD, parkAlt)) < 0)
928  {
929  LOG_ERROR("Error setting Az/Alt.");
930  return false;
931  }
932 
933  char syncString[256];
934  if (APSyncCM(PortFD, syncString) < 0)
935  {
936  LOG_WARN("Sync failed.");
937  return false;
938  }
939  }
940 
941  SetParked(false);
942  return true;
943 }
944 
946 {
948  INDI::IHorizontalCoordinates horizontalCoords {0, 0};
949  INDI::EquatorialToHorizontal(&equatorialCoords, &m_Location, ln_get_julian_from_sys(), &horizontalCoords);
950  double parkAZ = horizontalCoords.azimuth;
951  double parkAlt = horizontalCoords.altitude;
952 
953  char AzStr[16], AltStr[16];
954  fs_sexa(AzStr, parkAZ, 2, 3600);
955  fs_sexa(AltStr, parkAlt, 2, 3600);
956 
957  LOGF_DEBUG("Setting current parking position to coordinates Az (%s) Alt (%s)...", AzStr,
958  AltStr);
959 
960  SetAxis1Park(parkAZ);
961  SetAxis2Park(parkAlt);
962 
963  return true;
964 }
965 
967 {
968  // Az = 0 for North hemisphere
969  SetAxis1Park(LocationN[LOCATION_LATITUDE].value > 0 ? 0 : 180);
970 
971  // Alt = Latitude
973 
974  return true;
975 }
976 
977 void LX200AstroPhysics::syncSideOfPier()
978 {
979  const char *cmd = ":pS#";
980  // Response
981  char response[16] = { 0 };
982  int rc = 0, nbytes_read = 0, nbytes_written = 0;
983 
984  LOGF_DEBUG("CMD: <%s>", cmd);
985 
986  tcflush(PortFD, TCIOFLUSH);
987 
988  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
989  {
990  char errmsg[256];
991  tty_error_msg(rc, errmsg, 256);
992  LOGF_ERROR("Error writing to device %s (%d)", errmsg, rc);
993  return;
994  }
995 
996  // Read Side
997  if ((rc = tty_read_section(PortFD, response, '#', 3, &nbytes_read)) != TTY_OK)
998  {
999  char errmsg[256];
1000  tty_error_msg(rc, errmsg, 256);
1001  LOGF_ERROR("Error reading from device %s (%d)", errmsg, rc);
1002  return;
1003  }
1004 
1005  response[nbytes_read - 1] = '\0';
1006 
1007  tcflush(PortFD, TCIOFLUSH);
1008 
1009  LOGF_DEBUG("RES: <%s>", response);
1010 
1011  if (!strcmp(response, "East"))
1013  else if (!strcmp(response, "West"))
1015  else
1016  LOGF_ERROR("Invalid pier side response from device-> %s", response);
1017 
1018 }
1019 
1021 {
1023 
1027 
1028  return true;
1029 }
1030 
1031 bool LX200AstroPhysics::SetTrackMode(uint8_t mode)
1032 {
1033  int err = 0;
1034 
1035  if (mode == TRACK_CUSTOM)
1036  {
1038  {
1039  LOGF_ERROR("Error setting tracking mode (%d).", err);
1040  return false;
1041  }
1042 
1043  return SetTrackRate(TrackRateN[AXIS_RA].value, TrackRateN[AXIS_DE].value);
1044  }
1045 
1046  if (!isSimulation() && (err = selectAPTrackingMode(PortFD, mode)) < 0)
1047  {
1048  LOGF_ERROR("Error setting tracking mode (%d).", err);
1049  return false;
1050  }
1051 
1052  return true;
1053 }
1054 
1055 bool LX200AstroPhysics::SetTrackEnabled(bool enabled)
1056 {
1058 }
1059 
1060 bool LX200AstroPhysics::SetTrackRate(double raRate, double deRate)
1061 {
1062  // Convert to arcsecs/s to AP sidereal multiplier
1063  /*
1064  :RR0.0000# = normal sidereal tracking in RA - similar to :RT2#
1065  :RR+1.0000# = 1 + normal sidereal = 2X sidereal
1066  :RR+9.0000# = 9 + normal sidereal = 10X sidereal
1067  :RR-1.0000# = normal sidereal - 1 = 0 or Stop - similar to :RT9#
1068  :RR-11.0000# = normal sidereal - 11 = -10X sidereal (East at 10X)
1069 
1070  :RD0.0000# = normal zero rate for Dec.
1071  :RD5.0000# = 5 + normal zero rate = 5X sidereal clockwise from above - equivalent to South
1072  :RD-5.0000# = normal zero rate - 5 = 5X sidereal counter-clockwise from above - equivalent to North
1073  */
1074 
1075  double APRARate = (raRate - TRACKRATE_SIDEREAL) / TRACKRATE_SIDEREAL;
1076  double APDERate = deRate / TRACKRATE_SIDEREAL;
1077 
1078  if (!isSimulation())
1079  {
1080  if (setAPRATrackRate(PortFD, APRARate) < 0 || setAPDETrackRate(PortFD, APDERate) < 0)
1081  return false;
1082  }
1083 
1084  return true;
1085 }
1086 
1087 bool LX200AstroPhysics::getUTFOffset(double *offset)
1088 {
1089  if (isSimulation())
1090  {
1091  *offset = 3;
1092  return true;
1093  }
1094 
1095  return (getAPUTCOffset(PortFD, offset) == 0);
1096 }
LX200Generic
Definition: lx200generic.h:25
LX200AstroPhysics::Goto
virtual bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
Definition: lx200ap.cpp:1138
LX200AstroPhysics::Park
virtual bool Park() override
Park the telescope to its home position.
Definition: lx200ap.cpp:1740
IP_RO
@ IP_RO
Definition: indiapi.h:183
INDI::Telescope::SCOPE_IDLE
@ SCOPE_IDLE
Definition: inditelescope.h:75
LX200Telescope::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: lx200telescope.cpp:1633
LX200Telescope::mountSim
void mountSim()
Definition: lx200telescope.cpp:1061
setAPUnPark
#define setAPUnPark(fd)
Definition: lx200apdriver.h:26
setAPMotionStop
#define setAPMotionStop(fd)
Definition: lx200apdriver.h:30
LX200AstroPhysics::USE_REGULAR_SYNC
@ USE_REGULAR_SYNC
Definition: lx200ap.h:121
lx200ap.h
INDI::Telescope::SlewRateS
ISwitch * SlewRateS
Definition: inditelescope.h:750
cmd
__u8 cmd[4]
Definition: pwc-ioctl.h:4
LX200AstroPhysics::APSlewSpeedS
ISwitch APSlewSpeedS[3]
Definition: lx200ap.h:113
MOUNT_TAB
#define MOUNT_TAB
Definition: lx200ap_legacy.cpp:36
INDI::Telescope::PIER_WEST
@ PIER_WEST
Definition: inditelescope.h:124
LX200Telescope::DBG_SCOPE
uint8_t DBG_SCOPE
Definition: lx200telescope.h:174
INDI::Telescope::LocationN
INumber LocationN[3]
Definition: inditelescope.h:719
INDI::Telescope::SCOPE_SLEWING
@ SCOPE_SLEWING
Definition: inditelescope.h:76
LOGF_ERROR
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
INDI::Telescope::SCOPE_PARKING
@ SCOPE_PARKING
Definition: inditelescope.h:78
LX200AstroPhysics::SetTrackRate
virtual bool SetTrackRate(double raRate, double deRate) override
SetTrackRate Set custom tracking rates.
Definition: lx200ap.cpp:2202
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
LX200AstroPhysics::UnPark
virtual bool UnPark() override
Unpark the telescope if already parked.
Definition: lx200ap.cpp:1868
INDI::Telescope::setPierSide
void setPierSide(TelescopePierSide side)
Definition: inditelescope.cpp:2605
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
MOTION_TAB
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
Definition: defaultdevice.cpp:36
IDSetText
void IDSetText(const ITextVectorProperty *t, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing text vector property.
selectAPGuideRate
int selectAPGuideRate(int fd, int guideRate)
Definition: lx200apdriver.cpp:518
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
INDI::Telescope::MovementNSSP
ISwitchVectorProperty MovementNSSP
Definition: inditelescope.h:742
LX200AstroPhysics::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: lx200ap.cpp:2149
INDI::Telescope::NewRaDec
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
Definition: inditelescope.cpp:693
INDI::DefaultDevice::isSimulation
bool isSimulation() const
Definition: defaultdevice.cpp:734
IUFillNumber
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidriver.c:348
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
selectAPSlewRate
int selectAPSlewRate(int fd, int slewRate)
Definition: lx200apdriver.cpp:415
LX200AstroPhysics::VersionT
IText VersionT[1]
Definition: lx200ap.h:135
lx200apdriver.h
IUFillTextVector
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:477
LX200AstroPhysics::Disconnect
virtual bool Disconnect() override
Disconnect from device.
Definition: lx200ap.cpp:1544
INDI::Telescope::GetAxis1Park
double GetAxis1Park() const
Definition: inditelescope.cpp:2252
LX200AstroPhysics::VersionTP
ITextVectorProperty VersionTP
Definition: lx200ap.h:136
INDI::Telescope::SetAxis2Park
void SetAxis2Park(double steps)
SetDEPark Set current DEC/ALT parking position. The data park file (stored in ~/.indi/ParkData....
Definition: inditelescope.cpp:2283
INDI_UNUSED
#define INDI_UNUSED(x)
Definition: indidevapi.h:799
INDI::Telescope::SetAxis1ParkDefault
void SetAxis1ParkDefault(double steps)
SetRAPark Set default RA/AZ parking position.
Definition: inditelescope.cpp:2277
LX200AstroPhysics::LX200AstroPhysics
LX200AstroPhysics()
Definition: lx200ap.cpp:54
GUIDE_TAB
const char * GUIDE_TAB
GUIDE_TAB Where all the properties for guiding are located.
Definition: defaultdevice.cpp:42
LX200AstroPhysics::debugTriggered
virtual void debugTriggered(bool enable) override
Inform driver that the debug option was triggered. This function is called after setDebug is triggere...
Definition: lx200ap.cpp:1717
INDI::Telescope::InitPark
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
Definition: inditelescope.cpp:1950
setAPObjectAZ
int setAPObjectAZ(int fd, double az)
Definition: lx200apdriver.cpp:225
LX200AstroPhysics::SwapSP
ISwitchVectorProperty SwapSP
Definition: lx200ap.h:117
getLX200DEC
#define getLX200DEC(fd, x)
Definition: lx200driver.h:118
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
lx200driver.h
setAPPark
#define setAPPark(fd)
Definition: lx200apdriver.h:25
tty_read_section
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:557
LX200Telescope::currentDEC
double currentDEC
Definition: lx200telescope.h:178
IUFillText
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidriver.c:369
INDI::Telescope::EqNP
INumberVectorProperty EqNP
Definition: inditelescope.h:701
INDI::Telescope::m_Location
IGeographicCoordinates m_Location
Definition: inditelescope.h:648
LX200AstroPhysics::SyncCMRS
ISwitch SyncCMRS[2]
Definition: lx200ap.h:119
LX200AstroPhysics::ReadScopeStatus
virtual bool ReadScopeStatus() override
Read telescope status.
Definition: lx200ap.cpp:850
selectAPMoveToRate
int selectAPMoveToRate(int fd, int moveToRate)
Definition: lx200apdriver.cpp:366
setAPRATrackRate
int setAPRATrackRate(int fd, double rate)
Definition: lx200apdriver.cpp:651
setAPObjectDEC
int setAPObjectDEC(int fd, double dec)
Definition: lx200apdriver.cpp:604
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
LX200Telescope::currentRA
double currentRA
Definition: lx200telescope.h:178
LX200AstroPhysics::StartUpS
ISwitch StartUpS[2]
Definition: lx200ap.h:102
INDI::Telescope::TrackRateN
INumber TrackRateN[2]
Definition: inditelescope.h:851
IUResetSwitch
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indicom.c:1442
INDI::Telescope::TrackState
TelescopeStatus TrackState
Definition: inditelescope.h:693
tty_error_msg
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1156
MOUNTINITIALIZED
#define MOUNTINITIALIZED
Definition: lx200ap.h:27
INDI::Telescope::AbortSP
ISwitchVectorProperty AbortSP
Definition: inditelescope.h:710
LX200Telescope::debugTriggered
virtual void debugTriggered(bool enable) override
Inform driver that the debug option was triggered. This function is called after setDebug is triggere...
Definition: lx200telescope.cpp:47
LX200AstroPhysics::SetTrackMode
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
Definition: lx200ap.cpp:2163
setAPObjectAlt
int setAPObjectAlt(int fd, double alt)
Definition: lx200apdriver.cpp:241
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
setAPLongFormat
#define setAPLongFormat(fd)
Definition: lx200apdriver.h:27
LX200AstroPhysics::ISGetProperties
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: lx200ap.cpp:176
LX200AstroPhysics::APGuideSpeedSP
ISwitchVectorProperty APGuideSpeedSP
Definition: lx200ap.h:124
LX200AstroPhysics::APGuideSpeedS
ISwitch APGuideSpeedS[3]
Definition: lx200ap.h:123
LX200AstroPhysics::getUTFOffset
virtual bool getUTFOffset(double *offset) override
Definition: lx200ap.cpp:2229
LX200AstroPhysics::DeclinationAxisTP
ITextVectorProperty DeclinationAxisTP
Definition: lx200ap_legacy.h:108
LX200AstroPhysics::DeclinationAxisT
IText DeclinationAxisT[1]
Definition: lx200ap_legacy.h:107
LX200AstroPhysics::SetDefaultPark
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
Definition: lx200ap.cpp:2096
ra
double ra
Definition: ieqprolegacydriver.cpp:43
LX200Telescope::slewError
virtual void slewError(int slewCode)
Definition: lx200telescope.cpp:1218
LX200AstroPhysics::Handshake
virtual bool Handshake() override
perform handshake with device to check communication
Definition: lx200ap.cpp:1469
tty_write
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:415
INDI::Telescope::TrackModeSP
ISwitchVectorProperty TrackModeSP
Definition: inditelescope.h:842
LX200Telescope::targetRA
double targetRA
Definition: lx200telescope.h:177
setLocalTime
#define setLocalTime(fd, x, y, z)
Definition: lx200driver.h:148
IUFillSwitchVector
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:412
LX200AstroPhysics::updateLocation
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
Definition: lx200ap.cpp:1673
INDI::EquatorialToHorizontal
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.
Definition: libastro.cpp:140
IUFillNumberVector
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:455
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
abortSlew
int abortSlew(int fd)
Definition: lx200driver.cpp:1544
LX200Telescope::initProperties
virtual bool initProperties() override
Called to initialize basic properties required all the time.
Definition: lx200telescope.cpp:64
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
LX200AstroPhysics::APSlewSpeedSP
ISwitchVectorProperty APSlewSpeedSP
Definition: lx200ap.h:114
getLX200Az
#define getLX200Az(fd, x)
Definition: lx200driver.h:125
AP_TRACKING_SIDEREAL
#define AP_TRACKING_SIDEREAL
Definition: lx200apdriver.h:32
LX200AstroPhysics::SendPulseCmd
virtual int SendPulseCmd(int8_t direction, uint32_t duration_msec) override
Definition: lx200ap.cpp:1464
selectAPPECState
int selectAPPECState(int fd, int pecstate)
Definition: lx200apdriver.cpp:331
dec
double dec
Definition: ieqprolegacydriver.cpp:44
INDI::Telescope::MovementWESP
ISwitchVectorProperty MovementWESP
Definition: inditelescope.h:746
LX200Telescope::ISGetProperties
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: lx200telescope.cpp:161
AP_TRACKING_OFF
#define AP_TRACKING_OFF
Definition: lx200apdriver.h:36
LX200AstroPhysics::initProperties
virtual bool initProperties() override
Called to initialize basic properties required all the time.
Definition: lx200ap.cpp:79
LX200Telescope::JD
double JD
Definition: lx200telescope.h:176
getLX200RA
#define getLX200RA(fd, x)
Definition: lx200driver.h:117
LX200AstroPhysics::SyncCMRSP
ISwitchVectorProperty SyncCMRSP
Definition: lx200ap.h:120
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
LX200AstroPhysics::SwapS
ISwitch SwapS[2]
Definition: lx200ap.h:116
selectAPTrackingMode
int selectAPTrackingMode(int fd, int trackMode)
Definition: lx200apdriver.cpp:459
LX200AstroPhysics::updateTime
virtual bool updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
Definition: lx200ap.cpp:1610
IUUpdateSwitch
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:171
INDI::Telescope::SetAxis1Park
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
Definition: inditelescope.cpp:2269
LX200AstroPhysics::StartUpSP
ISwitchVectorProperty StartUpSP
Definition: lx200ap.h:103
LX200AstroPhysics::HourangleCoordsNP
INumberVectorProperty HourangleCoordsNP
Definition: lx200ap.h:106
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
INDI::Telescope::SCOPE_TRACKING
@ SCOPE_TRACKING
Definition: inditelescope.h:77
LX200Telescope::timeFormat
int timeFormat
Definition: lx200telescope.h:169
INDI::Telescope::LOCATION_LATITUDE
@ LOCATION_LATITUDE
Definition: inditelescope.h:117
LOG_DEBUG
#define LOG_DEBUG(txt)
Definition: indilogger.h:75
LX200AstroPhysics::HorizontalCoordsN
INumber HorizontalCoordsN[2]
Definition: lx200ap.h:110
INDI::HorizontalToEquatorial
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
Definition: libastro.cpp:156
INDI::Telescope::PECStateSP
ISwitchVectorProperty PECStateSP
Definition: inditelescope.h:839
LX200AstroPhysics::getDefaultName
virtual const char * getDefaultName() override
Definition: lx200ap.cpp:61
LX200AstroPhysics::SetCurrentPark
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
Definition: lx200ap.cpp:2075
setAPObjectRA
int setAPObjectRA(int fd, double ra)
Definition: lx200apdriver.cpp:589
LX200AstroPhysics::USE_CMR_SYNC
@ USE_CMR_SYNC
Definition: lx200ap.h:121
LOGF_INFO
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
INDI::Telescope::TRACK_CUSTOM
@ TRACK_CUSTOM
Definition: inditelescope.h:98
LOG_ERROR
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
INDI::Telescope::SetParkDataType
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
Definition: inditelescope.cpp:1873
LX200Telescope::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: lx200telescope.cpp:789
INDI::Telescope::SetAxis2ParkDefault
void SetAxis2ParkDefault(double steps)
SetDEParkDefault Set default DEC/ALT parking position.
Definition: inditelescope.cpp:2291
MOUNTNOTINITIALIZED
#define MOUNTNOTINITIALIZED
Definition: lx200ap.h:26
setCalenderDate
int setCalenderDate(int fd, int dd, int mm, int yy)
Definition: lx200driver.cpp:1047
IUSaveText
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indicom.c:1449
name
const char * name
Definition: indiserver.c:116
INDI::Telescope::SetParked
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
Definition: inditelescope.cpp:1937
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
LX200AstroPhysics::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: lx200ap.cpp:506
setAPBackLashCompensation
#define setAPBackLashCompensation(fd, x, y, z)
Definition: lx200apdriver.h:29
setAPSiteLatitude
int setAPSiteLatitude(int fd, double Lat)
Definition: lx200apdriver.cpp:638
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
INDI::Telescope::SlewRateSP
ISwitchVectorProperty SlewRateSP
Definition: inditelescope.h:749
AXIS_RA
@ AXIS_RA
Definition: indibasetypes.h:33
getAPUTCOffset
int getAPUTCOffset(int fd, double *value)
Definition: lx200apdriver.cpp:98
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
LX200AstroPhysics::SetTrackEnabled
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
Definition: lx200ap.cpp:2189
setAPSiteLongitude
int setAPSiteLongitude(int fd, double Long)
Definition: lx200apdriver.cpp:625
TRACKRATE_SIDEREAL
#define TRACKRATE_SIDEREAL
Definition: indicom.h:54
fs_sexa
int fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string.
Definition: indicom.c:137
LX200AstroPhysics::SlewAccuracyN
INumber SlewAccuracyN[2]
Definition: lx200ap_legacy.h:110
APSyncCMR
int APSyncCMR(int fd, char *matchedObject)
Definition: lx200apdriver.cpp:303
IP_RW
@ IP_RW
Definition: indiapi.h:185
LOG_WARN
#define LOG_WARN(txt)
Definition: indilogger.h:73
LX200AstroPhysics::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: lx200ap.cpp:446
set_lx200ap_name
void set_lx200ap_name(const char *deviceName, unsigned int debug_level)
Definition: lx200apdriver.cpp:47
getLX200Alt
#define getLX200Alt(fd, x)
Definition: lx200driver.h:124
checkLX200EquatorialFormat
int checkLX200EquatorialFormat(int fd)
Definition: lx200driver.cpp:1698
setAPUTCOffset
int setAPUTCOffset(int fd, double hours)
Definition: lx200apdriver.cpp:262
ISState
ISState
Switch state.
Definition: indiapi.h:148
LX200AstroPhysics::HourangleCoordsN
INumber HourangleCoordsN[2]
Definition: lx200ap.h:105
INDI::IHorizontalCoordinates
Definition: libastro.h:56
LX200Telescope::targetDEC
double targetDEC
Definition: lx200telescope.h:177
INDI::Telescope::PortFD
int PortFD
Definition: inditelescope.h:864
INDI::Telescope::PARK_AZ_ALT
@ PARK_AZ_ALT
Definition: inditelescope.h:111
IUFindOnSwitchIndex
int IUFindOnSwitchIndex(const ISwitchVectorProperty *sp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indicom.c:1424
_ISwitchVectorProperty::sp
ISwitch * sp
Definition: indiapi.h:384
INDI::IEquatorialCoordinates
Definition: libastro.h:48
LX200AstroPhysics::HorizontalCoordsNP
INumberVectorProperty HorizontalCoordsNP
Definition: lx200ap.h:111
INDI::Telescope::GetAxis2Park
double GetAxis2Park() const
Definition: inditelescope.cpp:2260
LX200Telescope::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: lx200telescope.cpp:699
Slew
int Slew(int fd)
Definition: lx200driver.cpp:1396
swapAPButtons
int swapAPButtons(int fd, int currentSwap)
Definition: lx200apdriver.cpp:562
setAPDETrackRate
int setAPDETrackRate(int fd, double rate)
Definition: lx200apdriver.cpp:699
IUSaveConfigSwitch
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indicom.c:1465
APSyncCM
int APSyncCM(int fd, char *matchedObject)
Definition: lx200apdriver.cpp:276
INDI::DefaultDevice::Disconnect
virtual bool Disconnect()
Disconnect from device.
Definition: defaultdevice.cpp:1083
setAPClearBuffer
#define setAPClearBuffer(fd)
Definition: lx200apdriver.h:28
TTY_OK
@ TTY_OK
Definition: indicom.h:94
getAPVersionNumber
#define getAPVersionNumber(fd, x)
Definition: lx200apdriver.h:24
LX200_24
@ LX200_24
Definition: lx200driver.h:64
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
LX200AstroPhysics::SetSlewRate
virtual bool SetSlewRate(int index) override
SetSlewRate Set desired slew rate index.
Definition: lx200ap.cpp:1729
LX200AstroPhysics::updateProperties
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
Definition: lx200ap.cpp:203
LX200Telescope::updateProperties
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
Definition: lx200telescope.cpp:199
IDSetNumber
void void void IDSetNumber(const INumberVectorProperty *n, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing number vector property.
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
INDI::Telescope::PIER_EAST
@ PIER_EAST
Definition: inditelescope.h:125
LX200AstroPhysics::SlewAccuracyNP
INumberVectorProperty SlewAccuracyNP
Definition: lx200ap_legacy.h:111
IUFillSwitch
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidriver.c:320
AXIS_DE
@ AXIS_DE
Definition: indibasetypes.h:34
LX200AstroPhysics::Sync
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
Definition: lx200ap.cpp:1558
APSendPulseCmd
int APSendPulseCmd(int fd, int direction, int duration_msec)
Definition: lx200apdriver.cpp:748
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
ISS_ON
@ ISS_ON
Definition: indiapi.h:151