47 static constexpr
char Termination =
'#';
48 static constexpr
int TimeOut = 1;
49 static constexpr
int MaxAttempts = 5;
53 static bool resynchronize_needed =
false;
55 static std::mutex dev_mtx;
57 static char lastCmd[40];
64 return static_cast<const char *
>(
"Pulsar2");
70 bool _sendReceiveACK_(
const int fd,
char *received_char)
72 const char ackbuf[1] = {
'\006' };
78 bool success = (write(
fd, ackbuf,
sizeof(ackbuf)) > 0);
81 int error_type =
tty_read(
fd, response, 1, TimeOut, &nbytes_read);
82 success = (error_type ==
TTY_OK && nbytes_read == 1);
85 *received_char = response[0];
101 inline bool _isValidACKResponse_(
char test_char)
118 void _resynchronize_(
const int fd)
121 const int ack_maxtries = 10;
122 int ack_try_cntr = 0;
126 tcflush(
fd, TCIOFLUSH);
127 while (resynchronize_needed && ack_try_cntr++ < ack_maxtries)
129 if (_isValidACKResponse_(lead_ACK) || (_sendReceiveACK_(
fd, &lead_ACK) && _isValidACKResponse_(lead_ACK)))
131 if (_isValidACKResponse_(follow_ACK) || (_sendReceiveACK_(
fd, &follow_ACK) && _isValidACKResponse_(follow_ACK)))
133 if (follow_ACK == lead_ACK)
135 resynchronize_needed =
false;
139 lead_ACK = follow_ACK;
147 tcflush(
fd, TCIFLUSH);
154 tcflush(
fd, TCIFLUSH);
159 if (resynchronize_needed)
161 resynchronize_needed =
false;
174 bool _send_(
const int fd,
const char *
cmd)
176 if (resynchronize_needed) _resynchronize_(
fd);
178 const int nbytes = strlen(
cmd);
179 int nbytes_written = 0;
182 const int errcode =
tty_write(
fd, &
cmd[nbytes_written], nbytes - nbytes_written, &nbytes_written);
191 while (nbytes_written < nbytes);
197 bool _receive_(
const int fd,
char response[],
const char *
cmd)
199 const struct timespec nanosleeptime = {0, 100000000L};
202 int nbytes_read_total = 0;
204 for (attempt = 0; !done; ++attempt)
207 const int errcode =
tty_read_section(
fd, response + nbytes_read_total, Termination, TimeOut, &nbytes_read);
215 if (attempt == MaxAttempts - 1)
225 nanosleep(&nanosleeptime,
nullptr);
231 if (nbytes_read_total == 0 && response[0] == Termination)
235 nbytes_read_total += nbytes_read;
259 const std::lock_guard<std::mutex> lock(dev_mtx);
260 return _send_(
fd,
cmd);
268 response = Termination;
269 const std::lock_guard<std::mutex> lock(dev_mtx);
272 for (
int attempt = 0; response == Termination; ++attempt)
275 const int errcode =
tty_read(
fd, &response,
sizeof(response), TimeOut, &nbytes_read);
281 if (attempt == MaxAttempts - 1)
283 resynchronize_needed =
true;
301 const std::lock_guard<std::mutex> lock(dev_mtx);
302 bool success = _send_(
fd,
cmd);
305 success = _receive_(
fd, response,
cmd);
313 const std::lock_guard<std::mutex> lock(dev_mtx);
314 bool success = _send_(
fd,
cmd);
317 success = _receive_(
fd, response1,
cmd);
318 if (success && response1[1] != Termination)
320 success = _receive_(
fd, response2,
cmd);
339 unsigned long rlen = strlen(response);
345 success = (sscanf(response,
"%d", value) == 1);
357 const std::lock_guard<std::mutex> lock(dev_mtx);
358 resynchronize_needed =
true;
443 static int site_location_initialized = 0;
444 static bool check_ota_side_of_pier =
false;
445 static bool speedsExtended =
false;
450 static char nonGuideSpeedUnit[] =
"1x Sidereal";
451 static char nonGuideSpeedExtendedUnit[] =
"1/6x Sidereal";
460 return static_cast<const char *
>(
"Pulsar2");
476 success = (sscanf(response,
"%1d,%1d",
reinterpret_cast<int *
>(PECra),
reinterpret_cast<int *
>(PECdec)) == 2);
487 success = (sscanf(response,
"%1d,%1d",
reinterpret_cast<int *
>(Rra),
reinterpret_cast<int *
>(Rdec)) == 2);
500 if (sscanf(response,
"%1d,%1d", &ra_tri, &dec_tri) == 2)
517 if (sscanf(response,
"%d", &itype) == 1)
546 if (sscanf(response,
"%d,%d", &result, &dec_dummy) != 2) result = 0;
597 success = (sscanf(response,
"%u,%u", ra_ramp, dec_ramp) == 2);
608 sprintf(
cmd,
"#:YSp%d,%d#", safe_ra_ramp, safe_dec_ramp);
620 success = (sscanf(response,
"%u,%u", red_ra, red_dec) == 2);
631 sprintf(
cmd,
"#:YSr%d,%d#", safe_red_ra, safe_red_dec);
644 success = (sscanf(response,
"%u,%u", mg_ra, mg_dec) == 2);
655 sprintf(
cmd,
"#:YSm%d,%d#", safe_mg_ra, safe_mg_dec);
667 success = (sscanf(response,
"%u:%u", bl_min, bl_sec) == 2);
678 sprintf(
cmd,
"#:YSb%d,%02d#", safe_bl_min, safe_bl_sec);
691 success = (sscanf(response,
"%lf,%lf", hp_alt, hp_az) == 2);
706 sprintf(
cmd,
"#:YSX%+08.4lf,%08.4lf#", safe_hp_alt, safe_hp_az);
717 if (usr_ind < 1 || usr_ind > 3)
return false;
718 char cmd[] =
"#:YGZ_#";
719 cmd[5] = usr_ind +
'0';
726 success = (sscanf(response,
"%lf,%lf", ur_ra, ur_dec) == 2);
751 if (usr_ind < 1 || usr_ind > 3)
return false;
756 sprintf(
cmd,
"#:YSZ%1c%+09.7lf,%+09.7lf#", usr_ind +
'0', safe_ur_ra, safe_ur_dec);
789 if (sscanf(response,
"%d,%d", &result, &dec_dummy) != 2) result = 0;
811 char cmd[] =
"#:YSM_#";
812 cmd[5] =
'0' + (char)((
int)mtype + 1);
823 sprintf(
cmd,
"%s%04d,%04d#", partialCmd, actualCur, actualCur);
842 bool setSpeedInd(
const int fd,
const char *partialCmd,
const int speedInd,
const int maxInd)
848 sprintf(
cmd,
"%s%04d,%04d#", partialCmd, actualInd, actualInd);
859 int maxVal = speedsExtended ? 9999 : 999;
865 int maxVal = speedsExtended ? 9999 : 999;
871 int maxVal = speedsExtended ? 9999 : 999;
877 int maxVal = speedsExtended ? 9999 : 999;
905 success = (sscanf(response,
"%1d,%1d",
reinterpret_cast<int *
>(rot_ra),
reinterpret_cast<int *
>(rot_dec)) == 2);
975 success = (sscanf(response,
"%lf,%lf", lat, lon) == 2);
978 *lon = (*lon) * (-1.0);
994 success = (sscanf(response,
"%2d%*c%2d%*c%2d", m, d, y) == 3);
997 *y += (*y < 50 ? 2000 : 1900);
1012 success = (sscanf(response,
"%2d%*c%2d%*c%2d", h, m, s) == 3);
1023 int degrees, minutes, seconds;
1026 snprintf(full_cmd,
sizeof(full_cmd),
"#:%s %03d:%02d#", partialCmd, degrees, minutes);
1032 bool setSite(
const int fd,
const double longitude,
const double latitude)
1039 static const char *commands[
NumSlewRates] {
"#:RS#",
"#:RM#",
"#:RC#",
"#:RG#" };
1045 static const char *commands[
NumDirections] = {
"#:Mn#",
"#:Me#",
"#:Ms#",
"#:Mw#" };
1051 static const char *commands[
NumDirections] = {
"#:Qn#",
"#:Qe#",
"#:Qs#",
"#:Qw#" };
1075 bool success =
true;
1076 if (safePulseLen > 4)
1079 int splm10 = safePulseLen % 10;
1082 safePulseLen = (splm10 > 4) ? (safePulseLen - splm10) + 10 : safePulseLen - splm10;
1086 snprintf(
cmd,
sizeof(
cmd),
"#:Mg%c%04d#", Pulsar2Commands::DirectionCode[direction], safePulseLen);
1091 LOGF_INFO(
"Pulse guide sent, direction %c, len: %d ms, cmd: %s", Pulsar2Commands::DirectionCode[direction], safePulseLen,
1094 LOGF_INFO(
"Pulse guide FAILED direction %c, len: %d ms, cmd: %s", Pulsar2Commands::DirectionCode[direction], safePulseLen,
1101 bool setTime(
const int fd,
const int h,
const int m,
const int s)
1104 snprintf(full_cmd,
sizeof(full_cmd),
"#:SL %02d:%02d:%02d#", h, m, s);
1109 bool setDate(
const int fd,
const int dd,
const int mm,
const int yy)
1114 snprintf(
cmd,
sizeof(
cmd),
":SC %02d/%02d/%02d#", mm, dd, (yy % 100));
1121 char response[16] = { 0 };
1125 if (response[5] ==
'.')
1139 snprintf(full_cmd,
sizeof(full_cmd),
"#:Sr %02d:%02d:%02d#", h, m, s);
1149 snprintf(full_cmd,
sizeof(full_cmd),
"#:Sd %c%02d:%02d:%02d#", (
dec < 0.0 ?
'-' :
'+' ), abs(d), m, s);
1178 return (result == 1);
1187 static const char ZeroOneChar[2] = {
'0',
'1' };
1191 char cmd[] =
"#:YSN_#";
1192 cmd[5] = ZeroOneChar[(int)ota_side_of_pier];
1202 unsigned int trii =
static_cast<unsigned int>(tri);
1204 sprintf(
cmd,
"#:YSS%u,%u#", trii, 0);
1210 char cmd[] =
"#:YSP_,_#";
1211 cmd[5] = ZeroOneChar[(int)pec_ra];
1212 cmd[7] = ZeroOneChar[(int)pec_dec];
1219 char cmd[] =
"#:YSQ_#";
1220 cmd[5] = ZeroOneChar[(int)pole_crossing];
1227 char cmd[] =
"#:YSR_,_#";
1228 cmd[5] = ZeroOneChar[(int)rc_ra];
1229 cmd[7] = ZeroOneChar[(int)rc_dec];
1237 char cmd[] =
"#:YSn_,_#";
1238 cmd[5] = ZeroOneChar[(int)rot_ra];
1239 cmd[7] = ZeroOneChar[(int)rot_dec];
1250 int is_home_set = -1;
1264 int is_parking = -1;
1298 return static_cast<const char *
>(
"Pulsar2");
1308 LOGF_DEBUG(
"%s",
"Trying to wake up the mount.");
1313 LOGF_DEBUG(
"%s",
"The mount was awake on connection.");
1351 if (this->initialization_complete)
1389 Pulsar2Commands::check_ota_side_of_pier = !Pulsar2Commands::check_ota_side_of_pier;
1390 if (Pulsar2Commands::check_ota_side_of_pier)
1395 if (ota_side_of_pier != Pulsar2Commands::currentOTASideOfPier)
1402 Pulsar2Commands::currentOTASideOfPier = ota_side_of_pier;
1450 int nonGuideSpeedMax = Pulsar2Commands::speedsExtended ? 9999 : 999;
1451 int nonGuideSpeedStep = Pulsar2Commands::speedsExtended ? 100 : 10;
1452 const char *nonGuideSpeedLabel = Pulsar2Commands::speedsExtended ?
"1/6x Sidereal" :
"1x Sidereal";
1459 IUFillNumber(&
FindSpeedIndN[0],
"FIND_SPEED_IND", nonGuideSpeedLabel,
"%.0f", 1, nonGuideSpeedMax, nonGuideSpeedStep, 0.0);
1463 IUFillNumber(&
SlewSpeedIndN[0],
"SLEW_SPEED_IND", nonGuideSpeedLabel,
"%.0f", 1, nonGuideSpeedMax, nonGuideSpeedStep, 0.0);
1467 IUFillNumber(&
GoToSpeedIndN[0],
"GOTO_SPEED_IND", nonGuideSpeedLabel,
"%.0f", 1, nonGuideSpeedMax, nonGuideSpeedStep, 0.0);
1497 IUFillNumber(&
UserRate1N[1],
"USERRATE1_DEC",
"Dec (radians/min)",
"%.7f", -4.1887902, 4.1887902, 0, 0.0);
1573 if (!this->local_properties_updated)
1587 this->local_properties_updated =
true;
1615 local_properties_updated =
false;
1622 storeScopeLocation();
1626 LOG_INFO(
"Initial tty resync complete.");
1646 int ival =
static_cast<int>(
round(values[0]));
1647 if (ival > 0 && ival < 10)
1675 int ival =
static_cast<int>(
round(values[0]));
1676 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1704 int ival =
static_cast<int>(
round(values[0]));
1705 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1733 int ival =
static_cast<int>(
round(values[0]));
1734 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1762 int ival =
static_cast<int>(
round(values[0]));
1763 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1792 int ra_ramp_val =
static_cast<int>(
round(values[0]));
1793 int dec_ramp_val =
static_cast<int>(
round(values[1]));
1794 if (ra_ramp_val >= 1 && ra_ramp_val <= 10 && dec_ramp_val >= 1 && dec_ramp_val <= 10)
1823 int red_ra_val =
static_cast<int>(
round(values[0]));
1824 int red_dec_val =
static_cast<int>(
round(values[1]));
1825 if (red_ra_val >= 100 && red_ra_val <= 6000 && red_dec_val >= 100 && red_dec_val <= 6000)
1854 int mg_ra_val =
static_cast<int>(
round(values[0]));
1855 int mg_dec_val =
static_cast<int>(
round(values[1]));
1856 if (mg_ra_val >= 100 && mg_ra_val <= 6000 && mg_dec_val >= 100 && mg_dec_val <= 6000)
1885 int bl_min_val =
static_cast<int>(
round(values[0]));
1886 int bl_sec_val =
static_cast<int>(
round(values[1]));
1887 if (bl_min_val >= 0 && bl_min_val <= 9 && bl_sec_val >= 0 && bl_sec_val <= 59)
1903 values[0] = bl_min_val;
1904 values[1] = bl_sec_val;
1927 double hp_alt = values[0];
1928 double hp_az = values[1];
1929 if (hp_alt >= -90.0 && hp_alt <= 90.0 && hp_az >= 0.0 && hp_az <= 360.0)
1970 if (!Pulsar2Commands::speedsExtended)
1972 double ur1_ra = values[0];
1973 double ur1_dec = values[1];
1974 if (ur1_ra >= -4.1887902 && ur1_ra <= 4.1887902 && ur1_dec >= -4.1887902 && ur1_dec <= 4.1887902)
1991 values[1] = ur1_dec;
2008 int ival =
static_cast<int>(
round(values[0]));
2009 if (ival >= 200 && ival <= 2000)
2038 int ival =
static_cast<int>(
round(values[0]));
2039 if (ival >= 200 && ival <= 2000)
2068 int ival =
static_cast<int>(
round(values[0]));
2069 if (ival >= 200 && ival <= 2000)
2096 if (strcmp(name,
"GEOGRAPHIC_COORD") == 0)
2104 if (Pulsar2Commands::site_location_initialized < 2)
2106 Pulsar2Commands::site_location_initialized++;
2138 char siteName[64] = {0};
2150 storeScopeLocation();
2170 bool success =
false;
2413 const bool success =
2440 LOG_INFO(
"Attempt to move neither North nor South using MoveNS()");
2444 bool success =
true;
2445 switch (motionCommand)
2451 LOGF_INFO(
"Moving toward %s.", Pulsar2Commands::DirectionName[motionDirection]);
2453 LOG_ERROR(
"Error starting N/S motion.");
2459 Pulsar2Commands::DirectionName[motionDirection]);
2461 LOG_ERROR(
"Error stopping N/S motion.");
2479 LOG_INFO(
"Attempt to move neither West nor East using MoveWE()");
2483 bool success =
true;
2490 LOGF_INFO(
"Moving toward %s.", Pulsar2Commands::DirectionName[motionDirection]);
2492 LOG_ERROR(
"Error starting W/E motion.");
2498 Pulsar2Commands::DirectionName[motionDirection]);
2500 LOG_ERROR(
"Error stopping W/E motion.");
2541 LOG_ERROR(
"Cannot guide while moving.");
2584 LOG_ERROR(
"Cannot guide while moving.");
2625 LOG_ERROR(
"Cannot guide while moving.");
2666 LOG_ERROR(
"Cannot guide while moving.");
2706 bool success =
true;
2709 struct ln_zonedate ltm;
2710 ln_date_to_zonedate(utc, <m, 0.0);
2711 JD = ln_get_julian_day(utc);
2720 LOG_ERROR(
"Error setting UTC date/time.");
2733 bool success =
true;
2740 fs_sexa(l, latitude, 3, 3600);
2741 fs_sexa(L, longitude, 4, 3600);
2743 LOGF_INFO(
"Site coordinates updated to lat: %+f, lon: %+f", latitude, longitude);
2746 LOG_ERROR(
"Error setting site coordinates");
2754 const struct timespec timeout = {0, 100000000L};
2755 char RAStr[64], DecStr[64];
2784 nanosleep(&timeout,
nullptr);
2798 IDSetNumber(&
EqNP,
"Error Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
2802 just_started_slewing =
true;
2807 LOGF_INFO(
"Slewing to RA: %s - DEC: %s", RAStr, DecStr);
2813 const struct timespec timeout = {0, 100000000L};
2857 nanosleep(&timeout,
nullptr);
2876 const struct timespec timeout = {0, 300000000L};
2877 bool success =
true;
2883 nanosleep(&timeout,
nullptr);
2891 char RAresponse[32];
2892 memset(RAresponse,
'\0', 32);
2893 char DECresponse[32];
2894 memset(DECresponse,
'\0', 32);
2900 LOGF_DEBUG(
"Sync RAresponse: %s, DECresponse: %s", RAresponse, DECresponse);
2905 LOG_INFO(
"Synchronization successful.");
2911 LOG_INFO(
"Synchronization failed.");
2918 LOG_INFO(
"Cannot sync while slewing");
2934 LOG_INFO(
"Mount is not parked, so cannot unpark.");
2952 LOG_INFO(
"Telescope has been unparked.");
2961 bool result =
false;
2965 result = !isSlewing();
2999 LOG_DEBUG(
"Failed to ensure that long format coordinates are used.");
3004 const struct timespec getVersionSleepTime = {0, 50000000L};
3005 char versionResponse[40];
3006 memset(versionResponse,
'\0', 40);
3009 char *vp = strstr(versionResponse,
"PULSAR V");
3012 char versionString[20];
3013 memset(versionString,
'\0', 20);
3015 char *vs = versionString;
3016 for (
int i = 0; i < 19 && (isalnum(*vp) || *vp ==
'.'); * (vs++) = *(vp++), i++);
3017 if (strcmp(versionString,
"5.7") < 0) Pulsar2Commands::speedsExtended =
true;
3018 LOGF_INFO(
"Pulsar firmware Version: %s", versionString);
3026 LOG_INFO(
"Could not determine valid firmware version.");
3029 nanosleep(&getVersionSleepTime,
nullptr);
3031 int nonGuideSpeedMax = Pulsar2Commands::speedsExtended ? 9999 : 999;
3032 int nonGuideSpeedStep = Pulsar2Commands::speedsExtended ? 100 : 10;
3033 const char *nonGuideSpeedLabel = Pulsar2Commands::speedsExtended ? Pulsar2Commands::nonGuideSpeedExtendedUnit :
3034 Pulsar2Commands::nonGuideSpeedUnit;
3118 if (guide_speed_ind > 0)
3120 double guide_speed_ind_d =
static_cast<double>(guide_speed_ind);
3128 if (center_speed_ind > 0)
3130 double center_speed_ind_d =
static_cast<double>(center_speed_ind);
3141 if (find_speed_ind > 0)
3143 double find_speed_ind_d =
static_cast<double>(find_speed_ind);
3154 if (slew_speed_ind > 0)
3156 double slew_speed_ind_d =
static_cast<double>(slew_speed_ind);
3167 if (goto_speed_ind > 0)
3169 double goto_speed_ind_d =
static_cast<double>(goto_speed_ind);
3184 double hp_alt, hp_az;
3205 if (tracking_current > 0)
3207 double tracking_current_d =
static_cast<double>(tracking_current);
3220 if (stop_current > 0)
3222 double stop_current_d =
static_cast<double>(stop_current);
3235 if (goto_current > 0)
3237 double goto_current_d =
static_cast<double>(goto_current);
3249 int ra_ramp, dec_ramp;
3252 double ra_ramp_d =
static_cast<double>(ra_ramp);
3253 double dec_ramp_d =
static_cast<double>(dec_ramp);
3254 RampN[0].value = ra_ramp_d;
3255 RampN[1].value = dec_ramp_d;
3266 int red_ra, red_dec;
3269 double ra_red_d =
static_cast<double>(red_ra);
3270 double dec_red_d =
static_cast<double>(red_dec);
3286 double mg_ra_d =
static_cast<double>(mg_ra);
3287 double mg_dec_d =
static_cast<double>(mg_dec);
3303 double bl_min_d =
static_cast<double>(bl_min);
3304 double bl_sec_d =
static_cast<double>(bl_sec);
3320 if (!Pulsar2Commands::speedsExtended)
3322 double ur1_ra, ur1_dec;
3345 bool LX200Pulsar2::storeScopeLocation()
3354 double stdLon = (lon < 0 ? 360.0 + lon : lon);
3406 bool LX200Pulsar2::sendScopeTime()
3409 memset(<m, 0,
sizeof(ltm));
3412 const time_t t = time(
nullptr);
3413 if (gmtime_r(&t, <m) ==
nullptr)
3423 ltm.tm_year -= 1900;
3428 const time_t time_epoch = mktime(<m);
3430 localtime_r(&time_epoch, &utm);
3434 strftime(cdate,
sizeof(cdate),
"%Y-%m-%dT%H:%M:%S", &utm);
3440 IDLog(
"Telescope Local Time: %02d:%02d:%02d\n", ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
3441 IDLog(
"Telescope TimeT Offset: %s\n",
TimeT[1].text);
3442 IDLog(
"Telescope UTC Time: %s\n",
TimeT[0].text);
3451 bool LX200Pulsar2::isSlewing()
3456 auto mount_is_off_target = [
this](void)
3461 bool result = (just_started_slewing ? mount_is_off_target() : true);
3464 int is_slewing = -1;
3467 if (is_slewing == 1)
3469 just_started_slewing =
false;
3473 result = just_started_slewing;
3476 result = mount_is_off_target();
3480 just_started_slewing =
false;
const char * getDeviceName() const
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
virtual bool Disconnect()
Disconnect from device.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
bool isSimulation() const
virtual bool Connect()
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
INumberVectorProperty GuideNSNP
INumberVectorProperty GuideWENP
TelescopeStatus TrackState
ISwitchVectorProperty MovementNSSP
ISwitchVectorProperty AbortSP
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
INumberVectorProperty LocationNP
ITextVectorProperty TimeTP
ISwitchVectorProperty SlewRateSP
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
INumberVectorProperty EqNP
ISwitchVectorProperty ParkSP
uint32_t GetTelescopeCapability() const
GetTelescopeCapability returns the capability of the Telescope.
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
ISwitchVectorProperty MovementWESP
static constexpr char const * ADVANCED_TAB
INumber TrackingCurrentN[1]
virtual bool isSlewComplete() override
INumberVectorProperty TrackingCurrentNP
virtual bool initProperties() override
Called to initialize basic properties required all the time.
ISwitchVectorProperty MountTypeSP
virtual IPState GuideEast(uint32_t ms) override
Guide east for ms milliseconds. East is defined as RA+.
ISwitch TrackingRateIndS[numPulsarTrackingRates]
ISwitchVectorProperty PoleCrossingSP
virtual void getBasicData() override
INumberVectorProperty SlewSpeedIndNP
INumberVectorProperty GoToSpeedIndNP
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool UnPark() override
Unpark the telescope if already parked.
ISwitchVectorProperty PierSideSP
INumberVectorProperty HomePositionNP
virtual bool Handshake() override
perform handshake with device to check communication
INumberVectorProperty GoToCurrentNP
INumberVectorProperty BacklashNP
ISwitchVectorProperty RefractionCorrectionSP
ISwitchVectorProperty RotationDecSP
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool Disconnect() override
Disconnect from device.
ISwitchVectorProperty RotationRASP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
ISwitchVectorProperty PierSideToggleSP
virtual bool updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
INumberVectorProperty GuideSpeedIndNP
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
virtual const char * getDefaultName() override
static constexpr char Null
INumberVectorProperty ReductionNP
INumberVectorProperty RampNP
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
ISwitch RefractionCorrectionS[2]
ISwitchVectorProperty TrackingRateIndSP
virtual bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
ISwitch PeriodicErrorCorrectionS[2]
INumber GuideSpeedIndN[1]
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...
INumberVectorProperty UserRate1NP
INumber CenterSpeedIndN[1]
virtual bool checkConnection() override
INumberVectorProperty StopCurrentNP
virtual bool Park() override
Park the telescope to its home position.
static constexpr bool verboseLogging
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
INumberVectorProperty FindSpeedIndNP
ISwitch PierSideToggleS[1]
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
virtual bool ReadScopeStatus() override
Read telescope status.
static const unsigned int numPulsarTrackingRates
virtual bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
INumberVectorProperty CenterSpeedIndNP
ISwitchVectorProperty PeriodicErrorCorrectionSP
INumberVectorProperty MaingearNP
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool SetSlewRate(int index) override
SetSlewRate Set desired slew rate index.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
int8_t guide_direction_we
static void guideTimeoutHelperNS(void *p)
ITextVectorProperty SiteNameTP
virtual void slewError(int slewCode)
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
static void guideTimeoutHelperWE(void *p)
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...
@ LX200_HAS_PULSE_GUIDING
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool checkConnection()
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual void getBasicData()
void setLX200Capability(uint32_t cap)
ISwitchVectorProperty SiteSP
int8_t guide_direction_ns
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
void IERmTimer(int timerid)
Remove the timer with the given timerid, as returned from IEAddTimer() or IEAddPeriodicTimer().
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
void IDLog(const char *fmt,...)
void getSexComponents(double value, int *d, int *m, int *s)
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
Implementations for common driver routines.
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.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
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.
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.
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.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
void IDMessage(const char *dev, const char *fmt,...)
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define DEBUGDEVICE(device, priority, msg)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define DEBUGFDEVICE(device, priority, msg,...)
int getSiteName(int fd, char *siteName, int siteNum)
int selectSite(int fd, int siteNum)
char lx200Name[MAXINDIDEVICE]
bool setRamp(const int fd, int ra_ramp, int dec_ramp)
bool getHomePosition(const int fd, double *hp_alt, double *hp_az)
bool abortSlew(const int fd)
bool setTrackingCurrent(const int fd, const int mA)
bool getUserRate1(const int fd, double *u1_ra, double *u1_dec)
int getTrackingCurrent(const int fd)
int getCurrentValue(const int fd, const char *cmd)
int getGoToCurrent(const int fd)
bool getPoleCrossingDirection(const int fd, int *direction)
bool setTime(const int fd, const int h, const int m, const int s)
bool setDate(const int fd, const int dd, const int mm, const int yy)
bool setCurrentValue(const int fd, const char *partialCmd, const int mA, const int maxmA)
bool setObjectRA(const int fd, const double ra)
bool getRamp(const int fd, int *ra_ramp, int *dec_ramp)
bool pulseGuide(const int fd, const Direction direction, uint32_t ms)
bool setSlewSpeedInd(const int fd, const int speedInd)
bool getVersion(const int fd, char response[])
bool setRCorrection(const int fd, const RCorrection rc_ra, const RCorrection rc_dec)
bool getPECorrection(const int fd, PECorrection *PECra, PECorrection *PECdec)
bool ensureLongFormat(const int fd)
int getSpeedInd(const int fd, const char *cmd)
bool getMaingear(const int fd, int *mg_ra, int *mg_dec)
MountType getMountType(const int fd)
int getCenterSpeedInd(const int fd)
bool getRCorrection(const int fd, RCorrection *Rra, RCorrection *Rdec)
bool setCenterSpeedInd(const int fd, const int speedInd)
bool setReduction(const int fd, int red_ra, int red_dec)
bool getBacklash(const int fd, int *bl_min, int *bl_sec)
bool setSite(const int fd, const double longitude, const double latitude)
bool setUserRate(const int fd, int usr_ind, double ur_ra, double ur_dec)
bool setMountType(const int fd, Pulsar2Commands::MountType mtype)
bool setRotation(const int fd, const Rotation rot_ra, const Rotation rot_dec)
bool setPoleCrossing(const int fd, const PoleCrossing pole_crossing)
bool setHomePosition(const int fd, double hp_alt, double hp_az)
bool getObjectRADec(const int fd, double *ra, double *dec)
bool isParking(const int fd)
bool getRotation(const int fd, Rotation *rot_ra, Rotation *rot_dec)
bool setSideOfPier(const int fd, const OTASideOfPier ota_side_of_pier)
bool getUTCDate(const int fd, int *m, int *d, int *y)
bool getUserRate(const int fd, int usr_ind, double *ur_ra, double *ur_dec)
bool setSlewMode(const int fd, const SlewMode slewMode)
bool setGoToCurrent(const int fd, const int mA)
TrackingRateInd getTrackingRateInd(const int fd)
int getGuideSpeedInd(const int fd)
bool unpark(const int fd)
bool getPoleCrossing(const int fd, PoleCrossing *pole_crossing)
bool setBacklash(const int fd, int bl_min, int bl_sec)
bool setGuideSpeedInd(const int fd, const int speedInd)
bool setFindSpeedInd(const int fd, const int speedInd)
bool setPECorrection(const int fd, const PECorrection pec_ra, const PECorrection pec_dec)
bool isHomeSet(const int fd)
bool setTrackingRateInd(const int fd, const TrackingRateInd tri)
bool setUserRate2(const int fd, double ur_ra, double ur_dec)
bool moveTo(const int fd, const Direction direction)
int getGoToSpeedInd(const int fd)
bool setUserRate3(const int fd, double ur_ra, double ur_dec)
bool setSpeedInd(const int fd, const char *partialCmd, const int speedInd, const int maxInd)
bool getSideOfPier(const int fd, OTASideOfPier *ota_side_of_pier)
bool setUserRate1(const int fd, double ur_ra, double ur_dec)
int getStopCurrent(const int fd)
bool getUserRate2(const int fd, double *u2_ra, double *u2_dec)
bool getUTCTime(const int fd, int *h, int *m, int *s)
bool getReduction(const int fd, int *red_ra, int *red_dec)
bool getSexa(const int fd, const char *cmd, double *value)
bool setObjectRADec(const int fd, const double ra, const double dec)
bool haltMovement(const int fd, const Direction direction)
bool setDegreesMinutes(const int fd, const char *partialCmd, const double value)
bool startSlew(const int fd)
int getFindSpeedInd(const int fd)
bool setObjectDEC(const int fd, const double dec)
const char * getDeviceName()
bool getSiteLatitudeLongitude(const int fd, double *lat, double *lon)
bool isParked(const int fd)
bool setStopCurrent(const int fd, const int mA)
bool setMaingear(const int fd, int mg_ra, int mg_dec)
bool setGoToSpeedInd(const int fd, const int speedInd)
int getSlewSpeedInd(const int fd)
bool getUserRate3(const int fd, double *u3_ra, double *u3_dec)
bool getSwapTubeDelay(const int fd, int *delay_value)
bool sendOnly(const int fd, const char *cmd)
void resyncTTY(const int fd)
bool sendReceive2(const int fd, const char *cmd, char response1[], char response2[])
bool confirmed(const int fd, const char *cmd, char &response)
bool sendReceiveInt(const int fd, const char *cmd, int *value)
bool sendReceive(const int fd, const char *cmd, char response[])
double round(double value, int decimal_places)