47static constexpr char Termination =
'#';
48static constexpr int TimeOut = 1;
49static constexpr int MaxAttempts = 5;
53static bool resynchronize_needed =
false;
55static std::mutex dev_mtx;
57static char lastCmd[40];
64 return static_cast<const char *
>(
"Pulsar2");
70bool _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];
101inline bool _isValidACKResponse_(
char test_char)
118void _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;
174bool _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);
197bool _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;
443static int site_location_initialized = 0;
444static bool check_ota_side_of_pier =
false;
445static bool speedsExtended =
false;
450static char nonGuideSpeedUnit[] =
"1x Sidereal";
451static 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);
606 int safe_ra_ramp = std::min(std::max(1, ra_ramp), 10);
607 int safe_dec_ramp = std::min(std::max(1, dec_ramp), 10);
608 sprintf(
cmd,
"#:YSp%d,%d#", safe_ra_ramp, safe_dec_ramp);
620 success = (sscanf(response,
"%u,%u", red_ra, red_dec) == 2);
629 int safe_red_ra = std::min(std::max(100, red_ra), 6000);
630 int safe_red_dec = std::min(std::max(100, red_dec), 6000);
631 sprintf(
cmd,
"#:YSr%d,%d#", safe_red_ra, safe_red_dec);
644 success = (sscanf(response,
"%u,%u", mg_ra, mg_dec) == 2);
653 int safe_mg_ra = std::min(std::max(100, mg_ra), 6000);
654 int safe_mg_dec = std::min(std::max(100, mg_dec), 6000);
655 sprintf(
cmd,
"#:YSm%d,%d#", safe_mg_ra, safe_mg_dec);
667 success = (sscanf(response,
"%u:%u", bl_min, bl_sec) == 2);
676 int safe_bl_min = std::min(std::max(0, bl_min), 9);
677 int safe_bl_sec = std::min(std::max(0, bl_sec), 59);
678 sprintf(
cmd,
"#:YSb%d,%02d#", safe_bl_min, safe_bl_sec);
691 success = (sscanf(response,
"%lf,%lf", hp_alt, hp_az) == 2);
700 double safe_hp_alt = std::min(std::max(0.0, hp_alt), 90.0);
705 double safe_hp_az = std::min(std::max(0.0004, hp_az), 359.9994);
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;
754 double safe_ur_ra = std::min(std::max(-4.1887902, ur_ra), 4.1887902);
755 double safe_ur_dec = std::min(std::max(-4.1887902, ur_dec), 4.1887902);
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);
822 int actualCur = std::min(std::max(mA, 100), maxmA);
823 sprintf(
cmd,
"%s%04d,%04d#", partialCmd, actualCur, actualCur);
842bool setSpeedInd(
const int fd,
const char *partialCmd,
const int speedInd,
const int maxInd)
847 int actualInd = std::min(std::max(speedInd, 1), 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);
1032bool 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#" };
1073 int safePulseLen = std::min(std::max(1,
static_cast<int>(ms)), 9990);
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,
1101bool 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);
1109bool 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);
1187static 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)
1390 Pulsar2Commands::check_ota_side_of_pier = !Pulsar2Commands::check_ota_side_of_pier;
1391 if (Pulsar2Commands::check_ota_side_of_pier)
1396 if (ota_side_of_pier != Pulsar2Commands::currentOTASideOfPier)
1403 Pulsar2Commands::currentOTASideOfPier = ota_side_of_pier;
1451 int nonGuideSpeedMax = Pulsar2Commands::speedsExtended ? 9999 : 999;
1452 int nonGuideSpeedStep = Pulsar2Commands::speedsExtended ? 100 : 10;
1453 const char *nonGuideSpeedLabel = Pulsar2Commands::speedsExtended ?
"1/6x Sidereal" :
"1x Sidereal";
1460 IUFillNumber(&
FindSpeedIndN[0],
"FIND_SPEED_IND", nonGuideSpeedLabel,
"%.0f", 1, nonGuideSpeedMax, nonGuideSpeedStep, 0.0);
1464 IUFillNumber(&
SlewSpeedIndN[0],
"SLEW_SPEED_IND", nonGuideSpeedLabel,
"%.0f", 1, nonGuideSpeedMax, nonGuideSpeedStep, 0.0);
1468 IUFillNumber(&
GoToSpeedIndN[0],
"GOTO_SPEED_IND", nonGuideSpeedLabel,
"%.0f", 1, nonGuideSpeedMax, nonGuideSpeedStep, 0.0);
1498 IUFillNumber(&
UserRate1N[1],
"USERRATE1_DEC",
"Dec (radians/min)",
"%.7f", -4.1887902, 4.1887902, 0, 0.0);
1574 if (!this->local_properties_updated)
1588 this->local_properties_updated =
true;
1616 local_properties_updated =
false;
1623 storeScopeLocation();
1627 LOG_INFO(
"Initial tty resync complete.");
1647 int ival =
static_cast<int>(
round(values[0]));
1648 if (ival > 0 && ival < 10)
1676 int ival =
static_cast<int>(
round(values[0]));
1677 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1705 int ival =
static_cast<int>(
round(values[0]));
1706 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1734 int ival =
static_cast<int>(
round(values[0]));
1735 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1763 int ival =
static_cast<int>(
round(values[0]));
1764 if (ival > 0 && ival < (Pulsar2Commands::speedsExtended ? 10000 : 1000))
1793 int ra_ramp_val =
static_cast<int>(
round(values[0]));
1794 int dec_ramp_val =
static_cast<int>(
round(values[1]));
1795 if (ra_ramp_val >= 1 && ra_ramp_val <= 10 && dec_ramp_val >= 1 && dec_ramp_val <= 10)
1824 int red_ra_val =
static_cast<int>(
round(values[0]));
1825 int red_dec_val =
static_cast<int>(
round(values[1]));
1826 if (red_ra_val >= 100 && red_ra_val <= 6000 && red_dec_val >= 100 && red_dec_val <= 6000)
1855 int mg_ra_val =
static_cast<int>(
round(values[0]));
1856 int mg_dec_val =
static_cast<int>(
round(values[1]));
1857 if (mg_ra_val >= 100 && mg_ra_val <= 6000 && mg_dec_val >= 100 && mg_dec_val <= 6000)
1886 int bl_min_val =
static_cast<int>(
round(values[0]));
1887 int bl_sec_val =
static_cast<int>(
round(values[1]));
1888 if (bl_min_val >= 0 && bl_min_val <= 9 && bl_sec_val >= 0 && bl_sec_val <= 59)
1904 values[0] = bl_min_val;
1905 values[1] = bl_sec_val;
1928 double hp_alt = values[0];
1929 double hp_az = values[1];
1930 if (hp_alt >= -90.0 && hp_alt <= 90.0 && hp_az >= 0.0 && hp_az <= 360.0)
1971 if (!Pulsar2Commands::speedsExtended)
1973 double ur1_ra = values[0];
1974 double ur1_dec = values[1];
1975 if (ur1_ra >= -4.1887902 && ur1_ra <= 4.1887902 && ur1_dec >= -4.1887902 && ur1_dec <= 4.1887902)
1992 values[1] = ur1_dec;
2009 int ival =
static_cast<int>(
round(values[0]));
2010 if (ival >= 200 && ival <= 2000)
2039 int ival =
static_cast<int>(
round(values[0]));
2040 if (ival >= 200 && ival <= 2000)
2069 int ival =
static_cast<int>(
round(values[0]));
2070 if (ival >= 200 && ival <= 2000)
2097 if (strcmp(name,
"GEOGRAPHIC_COORD") == 0)
2105 if (Pulsar2Commands::site_location_initialized < 2)
2107 Pulsar2Commands::site_location_initialized++;
2139 char siteName[64] = {0};
2151 storeScopeLocation();
2171 bool success =
false;
2414 const bool success =
2442 LOG_INFO(
"Attempt to move neither North nor South using MoveNS()");
2446 bool success =
true;
2447 switch (motionCommand)
2453 LOGF_INFO(
"Moving toward %s.", Pulsar2Commands::DirectionName[motionDirection]);
2455 LOG_ERROR(
"Error starting N/S motion.");
2461 Pulsar2Commands::DirectionName[motionDirection]);
2463 LOG_ERROR(
"Error stopping N/S motion.");
2481 LOG_INFO(
"Attempt to move neither West nor East using MoveWE()");
2485 bool success =
true;
2492 LOGF_INFO(
"Moving toward %s.", Pulsar2Commands::DirectionName[motionDirection]);
2494 LOG_ERROR(
"Error starting W/E motion.");
2500 Pulsar2Commands::DirectionName[motionDirection]);
2502 LOG_ERROR(
"Error stopping W/E motion.");
2546 LOG_ERROR(
"Cannot guide while moving.");
2590 LOG_ERROR(
"Cannot guide while moving.");
2632 LOG_ERROR(
"Cannot guide while moving.");
2674 LOG_ERROR(
"Cannot guide while moving.");
2715 bool success =
true;
2718 struct ln_zonedate ltm;
2719 ln_date_to_zonedate(utc, <m, 0.0);
2720 JD = ln_get_julian_day(utc);
2729 LOG_ERROR(
"Error setting UTC date/time.");
2742 bool success =
true;
2749 fs_sexa(l, latitude, 3, 3600);
2750 fs_sexa(L, longitude, 4, 3600);
2752 LOGF_INFO(
"Site coordinates updated to lat: %+f, lon: %+f", latitude, longitude);
2755 LOG_ERROR(
"Error setting site coordinates");
2763 const struct timespec timeout = {0, 100000000L};
2764 char RAStr[64], DecStr[64];
2795 nanosleep(&timeout,
nullptr);
2810 LOGF_ERROR(
"Error Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr);
2815 just_started_slewing =
true;
2820 LOGF_INFO(
"Slewing to RA: %s - DEC: %s", RAStr, DecStr);
2826 const struct timespec timeout = {0, 100000000L};
2833 LOG_ERROR(
"No parking position defined.");
2840 LOG_ERROR(
"Scope has already been parked.");
2874 nanosleep(&timeout,
nullptr);
2894 const struct timespec timeout = {0, 300000000L};
2895 bool success =
true;
2901 nanosleep(&timeout,
nullptr);
2905 LOG_ERROR(
"Error setting RA/DEC. Unable to Sync.");
2910 char RAresponse[32];
2911 memset(RAresponse,
'\0', 32);
2912 char DECresponse[32];
2913 memset(DECresponse,
'\0', 32);
2919 LOGF_DEBUG(
"Sync RAresponse: %s, DECresponse: %s", RAresponse, DECresponse);
2924 LOG_INFO(
"Synchronization successful.");
2937 LOG_INFO(
"Cannot sync while slewing");
2954 LOG_INFO(
"Mount is not parked, so cannot unpark.");
2973 LOG_INFO(
"Telescope has been unparked.");
2982 bool result =
false;
2986 result = !isSlewing();
3020 LOG_DEBUG(
"Failed to ensure that long format coordinates are used.");
3025 const struct timespec getVersionSleepTime = {0, 50000000L};
3026 char versionResponse[40];
3027 memset(versionResponse,
'\0', 40);
3030 char *vp = strstr(versionResponse,
"PULSAR V");
3033 char versionString[20];
3034 memset(versionString,
'\0', 20);
3036 char *vs = versionString;
3037 for (
int i = 0; i < 19 && (isalnum(*vp) || *vp ==
'.'); * (vs++) = *(vp++), i++);
3038 if (strcmp(versionString,
"5.7") < 0) Pulsar2Commands::speedsExtended =
true;
3039 LOGF_INFO(
"Pulsar firmware Version: %s", versionString);
3047 LOG_INFO(
"Could not determine valid firmware version.");
3050 nanosleep(&getVersionSleepTime,
nullptr);
3052 int nonGuideSpeedMax = Pulsar2Commands::speedsExtended ? 9999 : 999;
3053 int nonGuideSpeedStep = Pulsar2Commands::speedsExtended ? 100 : 10;
3054 const char *nonGuideSpeedLabel = Pulsar2Commands::speedsExtended ? Pulsar2Commands::nonGuideSpeedExtendedUnit :
3055 Pulsar2Commands::nonGuideSpeedUnit;
3139 if (guide_speed_ind > 0)
3141 double guide_speed_ind_d =
static_cast<double>(guide_speed_ind);
3149 if (center_speed_ind > 0)
3151 double center_speed_ind_d =
static_cast<double>(center_speed_ind);
3162 if (find_speed_ind > 0)
3164 double find_speed_ind_d =
static_cast<double>(find_speed_ind);
3175 if (slew_speed_ind > 0)
3177 double slew_speed_ind_d =
static_cast<double>(slew_speed_ind);
3188 if (goto_speed_ind > 0)
3190 double goto_speed_ind_d =
static_cast<double>(goto_speed_ind);
3205 double hp_alt, hp_az;
3226 if (tracking_current > 0)
3228 double tracking_current_d =
static_cast<double>(tracking_current);
3241 if (stop_current > 0)
3243 double stop_current_d =
static_cast<double>(stop_current);
3256 if (goto_current > 0)
3258 double goto_current_d =
static_cast<double>(goto_current);
3270 int ra_ramp, dec_ramp;
3273 double ra_ramp_d =
static_cast<double>(ra_ramp);
3274 double dec_ramp_d =
static_cast<double>(dec_ramp);
3275 RampN[0].value = ra_ramp_d;
3276 RampN[1].value = dec_ramp_d;
3287 int red_ra, red_dec;
3290 double ra_red_d =
static_cast<double>(red_ra);
3291 double dec_red_d =
static_cast<double>(red_dec);
3307 double mg_ra_d =
static_cast<double>(mg_ra);
3308 double mg_dec_d =
static_cast<double>(mg_dec);
3324 double bl_min_d =
static_cast<double>(bl_min);
3325 double bl_sec_d =
static_cast<double>(bl_sec);
3341 if (!Pulsar2Commands::speedsExtended)
3343 double ur1_ra, ur1_dec;
3366bool LX200Pulsar2::storeScopeLocation()
3375 double stdLon = (lon < 0 ? 360.0 + lon : lon);
3427bool LX200Pulsar2::sendScopeTime()
3430 memset(<m, 0,
sizeof(ltm));
3433 const time_t t = time(
nullptr);
3434 if (gmtime_r(&t, <m) ==
nullptr)
3444 ltm.tm_year -= 1900;
3449 const time_t time_epoch = mktime(<m);
3451 localtime_r(&time_epoch, &utm);
3455 strftime(cdate,
sizeof(cdate),
"%Y-%m-%dT%H:%M:%S", &utm);
3461 IDLog(
"Telescope Local Time: %02d:%02d:%02d\n", ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
3472bool LX200Pulsar2::isSlewing()
3477 auto mount_is_off_target = [
this](void)
3482 bool result = (just_started_slewing ? mount_is_off_target() : true);
3485 int is_slewing = -1;
3488 if (is_slewing == 1)
3490 just_started_slewing =
false;
3494 result = just_started_slewing;
3497 result = mount_is_off_target();
3501 just_started_slewing =
false;
INDI::PropertyText getText(const char *name) 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...
INDI::PropertyNumber GuideNSNP
INDI::PropertyNumber GuideWENP
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
int findOnSwitchIndex() const
TelescopeStatus TrackState
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
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.
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)
@ LX200_HAS_PULSE_GUIDING
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...
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.
INDI::PropertySwitch ParkSP
INDI::PropertySwitch AbortSP
INDI::PropertySwitch MovementNSSP
INDI::PropertyNumber EqNP
INDI::PropertySwitch SlewRateSP
INDI::PropertyText TimeTP
INDI::PropertySwitch MovementWESP
INDI::PropertyNumber LocationNP
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 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 LOGF_ERROR(fmt,...)
#define DEBUGFDEVICE(device, priority, msg,...)
char lx200Name[MAXINDIDEVICE]
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)
const char * getDeviceName()
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)
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)