Instrument Neutral Distributed Interface INDI
1.9.5
|
Go to the documentation of this file.
32 #include <libnova/julian_day.h>
33 #include <libnova/sidereal_time.h>
40 #include <sys/ioctl.h>
45 #define PMC8_TIMEOUT 5
47 #define PMC8_SIMUL_VERSION_RESP "ESGvES06B9T9"
50 #define PMC8_G11_AXIS0_SCALE 4608000.0
51 #define PMC8_G11_AXIS1_SCALE 4608000.0
53 #define PMC8_EXOS2_AXIS0_SCALE 4147200.0
54 #define PMC8_EXOS2_AXIS1_SCALE 4147200.0
56 #define PMC8_iEXOS100_AXIS0_SCALE 4147200.0
57 #define PMC8_iEXOS100_AXIS1_SCALE 4147200.0
63 #define ARCSEC_IN_CIRCLE 1296000.0
67 #define PMC8_MAX_PRECISE_MOTOR_RATE 62500
70 #define PMC8_PULSE_GUIDE_MIN_MS 20
73 #define PMC8_PULSE_GUIDE_MAX_NOTIMER 250
75 #define PMC8_MAX_RETRIES 3
76 #define PMC8_RETRY_DELAY 30000
77 #define PMC8_MAX_IO_ERROR_THRESHOLD 2
79 #define PMC8_RATE_SIDEREAL 15.0
80 #define PMC8_RATE_LUNAR 14.685
81 #define PMC8_RATE_SOLAR 15.041
82 #define PMC8_RATE_KING 15.0369
143 sprintf(h,
"%08X", tmp);
182 float capped_move_rate = rate;
307 for (
int i = 0; i < 2; i++)
321 int serial = TIOCM_DTR;
322 ioctl(
fd, TIOCMBIC, &serial);
325 for (
int i = 0; i < 2; i++)
332 "Your mount will reset and lose its position anytime you disconnect and reconnect."
333 "See http://indilib.org/devices/telescopes/explore-scientific-g11-pmc-eight/ ");
347 char initCMD[] =
"ESGv!";
352 int nbytes_written = 0;
357 nbytes_read = strlen(response);
377 return (!strncmp(response,
"ESGvES", 6));
383 info->
Model.assign(
"PMC-Eight");
407 char cmd[] =
"ESGi!";
412 int nbytes_written = 0;
417 nbytes_read = strlen(response);
435 if (nbytes_read >= 31)
438 char num_str[3] = {0};
439 strncat(num_str, response + 20, 2);
440 int p9 = (int)strtol(num_str,
nullptr, 10);
466 tcflush(
fd, TCIFLUSH);
476 char cmd[] =
"ESGv!";
482 int nbytes_written = 0;
487 nbytes_read = strlen(response);
507 if (nbytes_read >= 12)
511 strncpy(board, response + 6, nbytes_read - 7);
517 tcflush(
fd, TCIFLUSH);
548 int nbytes_written = 0;
550 snprintf(
cmd,
sizeof(
cmd),
"ESGr%d!", axis);
579 if (nbytes_read != 10)
585 char num_str[16] = {0};
587 strcpy(num_str,
"0X");
588 strncat(num_str, response + 5, 6);
590 int mrate = (int)strtol(num_str,
nullptr, 0);
604 int nbytes_written = 0;
606 snprintf(
cmd,
sizeof(
cmd),
"ESGd%d!", axis);
635 if (nbytes_read != 7)
641 char num_str[16] = {0};
643 strncat(num_str, response + 5, 2);
645 dir = (int)strtol(num_str,
nullptr, 0);
656 char cmd[32], expresp[32];
661 int nbytes_written = 0;
663 snprintf(
cmd,
sizeof(
cmd),
"ESSd%d%d!", axis, dir);
689 snprintf(expresp,
sizeof(expresp),
"ESGd%d%d!", axis, dir);
782 int nbytes_written = 0;
784 snprintf(
cmd,
sizeof(
cmd),
"ESGx!");
805 if (nbytes_read != 9)
811 char num_str[16] = {0};
813 strcpy(num_str,
"0X");
814 strncat(num_str, response + 4, 4);
816 int mrate = (int)strtol(num_str,
nullptr, 0);
827 int refmotor, tmotor;
874 int nbytes_written = 0;
876 snprintf(
cmd,
sizeof(
cmd),
"ESSr%d%04X!", axis, mrate);
895 snprintf(
cmd,
sizeof(
cmd),
"ESGr%d", axis);
903 if (nbytes_read == 10)
905 tcflush(
fd, TCIFLUSH);
947 bool set_pmc8_track_enabled(
int fd,
bool enabled)
954 int nbytes_written = 0;
956 snprintf(
cmd, 32,
":ST%d#", enabled ? 1 : 0);
1011 if (rate < 0) direction = !direction;
1027 int nbytes_read = 0;
1028 int nbytes_written = 0;
1037 snprintf(
cmd,
sizeof(
cmd),
"ESTr%04X!", rateval);
1060 if (nbytes_read != 9)
1066 tcflush(
fd, TCIFLUSH);
1165 char cmd[32], expresp[32];
1169 int nbytes_read = 0;
1170 int nbytes_written = 0;
1172 snprintf(
cmd,
sizeof(
cmd),
"ESSf%d%02X!", axis,
int(rate * 100));
1181 snprintf(expresp,
sizeof(expresp),
"ESGf%d%02X!", axis,
int(rate * 100));
1207 int nbytes_read = 0;
1208 int nbytes_written = 0;
1210 snprintf(
cmd,
sizeof(
cmd),
"ESGf%d!", axis);
1227 if (nbytes_read != 8)
1233 char num_str[16] = {0};
1235 strcpy(num_str,
"0X");
1236 strncat(num_str, response + 5, 2);
1237 int tint = strtol(num_str,
nullptr, 0);
1239 rate = ((double)tint) / 100;
1282 double cur_rate = 0;
1287 long long pulse_start_us;
1288 long long pulse_sofar_us;
1309 timetaken_us = ms * 1000;
1330 cur_rate = ratehint;
1336 cur_rate = ratehint;
1348 double new_rate = cur_rate;
1366 gettimeofday(&tp,
nullptr);
1367 pulse_start_us = tp.tv_sec * 1000000 + tp.tv_usec;
1384 if (new_rate < 0) new_dir = 1;
1399 if (cur_dir != new_dir)
1404 gettimeofday(&tp,
nullptr);
1405 pulse_start_us = tp.tv_sec * 1000000 + tp.tv_usec;
1428 gettimeofday(&tp,
nullptr);
1429 pulse_sofar_us = (tp.tv_sec * 1000000 + tp.tv_usec) - pulse_start_us;
1431 timetaken_us = pulse_sofar_us;
1441 long long pulse_end_us;
1459 tcflush(
fd, TCIFLUSH);
1470 gettimeofday(&tp,
nullptr);
1471 pulse_end_us = tp.tv_sec * 1000000 + tp.tv_usec;
1509 tcflush(
fd, TCIFLUSH);
1522 if (axispos > 8388608)
1523 r = 0 - (16777216 - axispos);
1540 hour_angle = lst -
ra;
1543 if (hour_angle > 12)
1544 hour_angle = hour_angle - 24;
1545 else if (hour_angle <= -12)
1546 hour_angle = hour_angle + 24;
1549 motor_angle = hour_angle - 6;
1551 motor_angle = hour_angle + 6;
1581 hour_angle = motor_angle + 6;
1583 hour_angle = motor_angle - 6;
1587 ra_value = lst - hour_angle;
1591 if (ra_value >= 24.0)
1592 ra_value = ra_value - 24.0;
1593 else if (ra_value < 0.0)
1594 ra_value = ra_value + 24.0;
1600 if (motor_angle >= 0)
1601 dec_value = 90 - motor_angle;
1603 dec_value = 90 + motor_angle;
1613 motor_angle = (
dec - 90.0);
1615 motor_angle = -(
dec - 90.0);
1636 int nbytes_read = 0;
1637 int nbytes_written = 0;
1644 snprintf(
cmd,
sizeof(
cmd),
"ESPt%d%s!", naxis, hexpt);
1656 snprintf(expresp,
sizeof(expresp),
"ESGt%d%s!", naxis, hexpt);
1692 int nbytes_read = 0;
1693 int nbytes_written = 0;
1702 snprintf(
cmd,
sizeof(
cmd),
"ESSp%d%s!", axis, hexpt);
1711 snprintf(expresp,
sizeof(expresp),
"ESGp%d%s!", axis, hexpt);
1745 int nbytes_read = 0;
1746 int nbytes_written = 0;
1754 snprintf(
cmd,
sizeof(
cmd),
"ESGp%d!", axis);
1771 if (nbytes_read != 12)
1777 char num_str[16] = {0};
1779 strcpy(num_str,
"0X");
1780 strncat(num_str, response + 5, 6);
1782 point = (int)strtol(num_str,
nullptr, 0);
1791 int axis_ra_pos, axis_dec_pos;
1881 int racounts, deccounts;
1927 hour_angle = lst -
ra;
1930 if (hour_angle > 12)
1931 hour_angle = hour_angle - 24;
1932 else if (hour_angle <= -12)
1933 hour_angle = hour_angle + 24;
1935 if (hour_angle < 0.0)
1944 int racounts, deccounts;
1990 int racounts, deccounts;
2035 int racounts, deccounts;
2094 if (strstr(errmsg,
"Connection timed out") || strstr(errmsg,
"Bad"))
2100 if (*nbytes_read > 0)
2102 buf[*nbytes_read] =
'\0';
2112 strcpy(buf, buf + 7);
2113 *nbytes_read = *nbytes_read - 7;
2116 if (strncmp(buf,
"AT", 2) == 0)
2118 strcpy(buf, buf + 2);
2119 *nbytes_read = *nbytes_read - 2;
2122 if (strncmp(buf,
"ESGp!", 5) == 0)
2131 if (strncmp(buf, expected, strlen(expected)) != 0)
2168 tcflush(
fd, TCIFLUSH);
2172 if ((err_code =
tty_write(
fd, buf, nbytes, nbytes_written)))
2176 if (strstr(errmsg,
"Broken pipe") || strstr(errmsg,
"Bad"))
bool get_pmc8_is_scope_slewing(int fd, bool &isslew)
int convert_axispos_to_motor(int axispos)
bool set_pmc8_target_position_axis(int fd, PMC8_AXIS axis, int point)
bool get_pmc8_direction_axis(int fd, PMC8_AXIS axis, int &dir)
#define PMC8_RATE_SIDEREAL
PulseGuideState NS_PulseGuideState
double pmc8_sidereal_rate_fraction_ra
void set_pmc8_device(const char *name)
bool set_pmc8_custom_dec_track_rate(int fd, double rate)
void convert_motor_counts_to_hex(int val, char *hex)
bool set_pmc8_direction_axis(int fd, PMC8_AXIS axis, int dir, bool fast)
char pmc8_device[MAXINDIDEVICE]
bool set_pmc8_custom_ra_track_rate(int fd, double rate)
#define PMC8_G11_AXIS1_SCALE
Implementations for common driver routines.
bool stop_pmc8_tracking_motion(int fd)
bool convert_dec_to_motor(double dec, INDI::Telescope::TelescopePierSide sop, int *mcounts)
bool convert_precise_rate_to_motor(double rate, int *mrate)
void set_pmc8_sim_system_status(PMC8_SYSTEM_STATUS value)
struct PulseGuideState PulseGuideState
#define PMC8_SIMUL_VERSION_RESP
PMC8_CONNECTION_TYPE pmc8_connection
bool set_pmc8_custom_ra_move_rate(int fd, double rate)
double round(double value, int decimal_places)
bool convert_motor_rate_to_move_rate(int mrate, double *rate)
INDI::Telescope::TelescopePierSide destSideOfPier(double ra, double dec)
bool get_pmc8_tracking_data(int fd, double &rate, uint8_t &mode)
void set_pmc8_goto_resume(bool resume)
bool get_pmc8_move_rate_axis(int fd, PMC8_AXIS axis, double &rate)
bool stop_pmc8_guide(int fd, PMC8_DIRECTION gdir)
std::string MainBoardFirmware
bool set_pmc8_radec(int fd, double ra, double dec)
void set_pmc8_mountParameters(int index)
bool set_pmc8_track_mode(int fd, uint8_t mode)
bool set_pmc8_guide_rate(int fd, PMC8_AXIS axis, double rate)
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
bool get_pmc8_position(int fd, int &rapoint, int &decpoint)
bool get_pmc8_response(int fd, char *buf, int *nbytes_read, const char *expected=NULL)
#define DEBUGDEVICE(device, priority, msg)
bool convert_motor_to_radec(int racounts, int deccounts, double &ra_value, double &dec_value)
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
bool set_pmc8_move_rate_axis(int fd, PMC8_DIRECTION dir, int reqrate)
bool start_pmc8_guide(int fd, PMC8_DIRECTION gdir, int ms, long &timetaken_us, double ratehint)
bool get_pmc8_position_axis(int fd, PMC8_AXIS axis, int &point)
bool get_pmc8_guide_state(PMC8_DIRECTION gdir, PulseGuideState **pstate)
void set_pmc8_reconnect_flag()
PulseGuideState EW_PulseGuideState
bool get_pmc8_guide_rate(int fd, PMC8_AXIS axis, double &rate)
#define PMC8_MAX_MOVE_RATE
void set_pmc8_debug(bool enable)
bool get_pmc8_track_rate(int fd, double &rate)
bool set_pmc8_target_position(int fd, int rapoint, int decpoint)
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
bool convert_ra_to_motor(double ra, INDI::Telescope::TelescopePierSide sop, int *mcounts)
void set_pmc8_sim_track_rate(PMC8_TRACK_RATE value)
bool get_pmc8_coords(int fd, double &ra, double &dec)
#define PMC8_EXOS2_AXIS1_SCALE
bool send_pmc8_command(int fd, const char *buf, int nbytes, int *nbytes_written)
PMC8_MOUNT_TYPES MountType
PMC8_SYSTEM_STATUS systemStatus
void set_pmc8_simulation(bool enable)
bool get_pmc8_firmware(int fd, FirmwareInfo *info)
#define PMC8_iEXOS100_AXIS0_SCALE
bool get_pmc8_reconnect_flag()
#define PMC8_MAX_IO_ERROR_THRESHOLD
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sideral time given longitude and system clock.
bool set_pmc8_position(int fd, int rapoint, int decpoint)
void set_pmc8_sim_dec(double dec)
#define PMC8_MAX_PRECISE_MOTOR_RATE
bool set_pmc8_ra_tracking(int fd, double rate)
bool check_pmc8_connection(int fd, PMC8_CONNECTION_TYPE connection)
bool convert_move_rate_to_motor(float rate, int *mrate)
#define DEBUGFDEVICE(device, priority, msg,...)
#define PMC8_MAX_TRACK_RATE
#define PMC8_iEXOS100_AXIS1_SCALE
bool slew_pmc8(int fd, double ra, double dec)
bool get_pmc8_model(int fd, FirmwareInfo *info)
void set_pmc8_location(double latitude, double longitude)
#define PMC8_G11_AXIS0_SCALE
#define PMC8_PULSE_GUIDE_MIN_MS
void set_pmc8_sim_move_rate(int value)
bool pmc8_isRev2Compliant
void set_pmc8_sim_ra(double ra)
bool convert_precise_motor_to_rate(int mrate, double *rate)
bool set_pmc8_custom_dec_move_rate(int fd, double rate)
#define PMC8_EXOS2_AXIS0_SCALE
bool sync_pmc8(int fd, double ra, double dec)
double pmc8_sidereal_rate_fraction_de
bool set_pmc8_position_axis(int fd, PMC8_AXIS axis, int point)
bool set_pmc8_axis_motor_rate(int fd, PMC8_AXIS axis, int mrate, bool fast)
bool get_pmc8_main_firmware(int fd, FirmwareInfo *info)
bool set_pmc8_axis_move_rate(int fd, PMC8_AXIS axis, float rate)