28 #include <libnova/sidereal_time.h>
29 #include <libnova/transform.h>
39 const std::array<uint32_t, AstroTrac::SLEW_MODES> AstroTrac::SLEW_SPEEDS = {{1, 2, 4, 8, 32, 64, 128, 600, 700, 800}};
47 SetTelescopeCapability(TELESCOPE_CAN_PARK | TELESCOPE_CAN_SYNC | TELESCOPE_CAN_GOTO | TELESCOPE_CAN_ABORT |
48 TELESCOPE_HAS_TIME | TELESCOPE_HAS_LOCATION | TELESCOPE_HAS_TRACK_MODE | TELESCOPE_HAS_TRACK_RATE |
49 TELESCOPE_CAN_CONTROL_TRACK | TELESCOPE_HAS_TRACK_RATE | TELESCOPE_HAS_PIER_SIDE,
51 setTelescopeConnection(CONNECTION_TCP);
67 AddTrackMode(
"TRACK_SIDEREAL",
"Sidereal",
true);
68 AddTrackMode(
"TRACK_SOLAR",
"Solar");
69 AddTrackMode(
"TRACK_LUNAR",
"Lunar");
70 AddTrackMode(
"TRACK_CUSTOM",
"Custom");
73 for (uint8_t i = 0; i < SLEW_MODES; i++)
75 sprintf(SlewRateSP.sp[i].label,
"%dx", SLEW_SPEEDS[i]);
76 SlewRateSP.sp[i].aux = (
void *)&SLEW_SPEEDS[i];
81 int configMountType = MOUNT_GEM;
83 MountTypeSP[MOUNT_GEM].fill(
"MOUNT_GEM",
"GEM",
85 MountTypeSP[MOUNT_SINGLE_ARM].fill(
"MOUNT_SINGLE_ARM",
"Single ARM",
90 AccelerationNP[
AXIS_RA].fill(
"AXIS_RA",
"RA arcsec/sec^2",
"%.2f", 0, 3600, 100, 0);
91 AccelerationNP[
AXIS_DE].fill(
"AXIS_DE",
"DE arcsec/sec^2",
"%.2f", 0, 3600, 100, 0);
95 EncoderNP[
AXIS_RA].fill(
"AXIS_RA",
"Hour Angle",
"%.2f", -3600, 3600, 100, 0);
96 EncoderNP[
AXIS_DE].fill(
"AXIS_DE",
"Declination",
"%.2f", -3600, 3600, 100, 0);
99 TrackState = SCOPE_IDLE;
101 SetParkDataType(PARK_RA_DEC_ENCODER);
105 tcpConnection->setDefaultHost(
"192.168.1.1");
106 tcpConnection->setDefaultPort(23);
108 setDriverInterface(getDriverInterface() | GUIDER_INTERFACE);
112 InitAlignmentProperties(
this);
114 SetApproximateMountAlignmentFromMountType(EQUATORIAL);
119 getSwitch(
"ALIGNMENT_SUBSYSTEM_ACTIVE")[0].setState(
ISS_ON);
131 defineProperty(MountTypeSP);
148 defineProperty(FirmwareTP);
149 defineProperty(AccelerationNP);
150 defineProperty(EncoderNP);
151 defineProperty(&GuideNSNP);
152 defineProperty(&GuideWENP);
153 defineProperty(GuideRateNP);
159 SetAxis1ParkDefault(0);
160 SetAxis2ParkDefault(0);
167 SetAxis1ParkDefault(0);
168 SetAxis2ParkDefault(0);
173 deleteProperty(FirmwareTP);
174 deleteProperty(AccelerationNP);
175 deleteProperty(EncoderNP);
176 deleteProperty(GuideNSNP.name);
177 deleteProperty(GuideWENP.name);
178 deleteProperty(GuideRateNP);
195 bool AstroTrac::getVersion()
197 char response[DRIVER_LEN] = {0};
198 if (sendCommand(
"<1zv?>", response))
200 FirmwareTP[0].setText(response + 4, 4);
212 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
213 snprintf(command, DRIVER_LEN,
"<%da?>", axis + 1);
214 if (sendCommand(command, response))
218 std::string acceleration = std::regex_replace(
220 std::regex(
"<.a(\\d+)>"),
223 AccelerationNP[axis].setValue(std::stoi(acceleration));
228 LOGF_DEBUG(
"Failed to parse acceleration (%s)", response);
238 bool AstroTrac::setAcceleration(
INDI_EQ_AXIS axis, uint32_t a)
240 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
242 snprintf(command, DRIVER_LEN,
"<%da%u>", axis + 1, a);
243 if (sendCommand(command, response))
244 return response[3] ==
'#';
255 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
256 snprintf(command, DRIVER_LEN,
"<%dv?>", axis + 1);
257 if (sendCommand(command, response))
261 std::string velocity = std::regex_replace(
263 std::regex(
"<.v([+-]?[0-9]+\\.[0-9]+?)>"),
266 TrackRateN[axis].value = std::stod(velocity) * (m_Location.latitude >= 0 ? 1 : -1);
271 LOGF_DEBUG(
"Failed to parse velocity (%s)", response);
281 bool AstroTrac::setVelocity(
INDI_EQ_AXIS axis,
double value)
283 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
286 snprintf(command, DRIVER_LEN,
"<%dve%f>", axis + 1, value * (m_Location.latitude >= 0 ? 1 : -1));
287 if (sendCommand(command, response))
288 return response[4] ==
'#';
299 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
301 snprintf(command, DRIVER_LEN,
"<%dx>", axis + 1);
302 if (sendCommand(command, response))
303 return response[3] ==
'#';
312 bool AstroTrac::isSlewComplete()
314 char HAResponse[DRIVER_LEN] = {0}, DEResponse[DRIVER_LEN] = {0};
315 if (sendCommand(
"<1t?>", HAResponse) && sendCommand(
"<2t?>", DEResponse))
317 return (HAResponse[3] ==
'0' && DEResponse[3] ==
'0');
326 bool AstroTrac::syncEncoder(
INDI_EQ_AXIS axis,
double value)
328 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
330 snprintf(command, DRIVER_LEN,
"<%dy%f>", axis + 1, value);
331 if (sendCommand(command, response))
332 return response[3] ==
'#';
340 bool AstroTrac::slewEncoder(
INDI_EQ_AXIS axis,
double value)
342 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
344 snprintf(command, DRIVER_LEN,
"<%dp%f>", axis + 1, value);
345 if (sendCommand(command, response))
346 return response[3] ==
'#';
359 char command[DRIVER_LEN] = {0}, response[DRIVER_LEN] = {0};
360 snprintf(command, DRIVER_LEN,
"<%dp?>", axis + 1);
361 if (sendCommand(command, response))
365 char regex_str[64] = {0};
366 snprintf(regex_str, 64,
"<%dp([+-]?[0-9]+\\.[0-9]+?)>", axis + 1);
367 std::string position = std::regex_replace(
369 std::regex(regex_str),
372 EncoderNP[axis].setValue(std::stod(position));
381 char regex_str[64] = {0};
382 snprintf(regex_str, 64,
"<%dp([+-]?[0-9]+\\.[0-9]+?)>", other + 1);
383 std::string position = std::regex_replace(
385 std::regex(regex_str),
388 EncoderNP[other].setValue(std::stod(position));
393 LOGF_DEBUG(
"Failed to parse position (%s)", response);
408 void AstroTrac::getRADEFromEncoders(
double haEncoder,
double deEncoder,
double &
ra,
double &de)
410 static const double jitter = 0.0005;
414 if (haEncoder > jitter * -1 && haEncoder < jitter)
416 if (deEncoder > jitter * -1 && deEncoder < jitter)
420 if (LocationN[LOCATION_LATITUDE].value >= 0)
423 if (MountTypeSP.findOnSwitchIndex() == MOUNT_SINGLE_ARM || deEncoder >= 0)
425 de =
std::min(90 - deEncoder, 90.0);
426 ha = -6.0 + (haEncoder / 360.0) * 24.0 ;
432 ha = 6.0 + (haEncoder / 360.0) * 24.0 ;
438 if (MountTypeSP.findOnSwitchIndex() == MOUNT_SINGLE_ARM || deEncoder <= 0)
440 de =
std::max(-90 - deEncoder, -90.0);
441 ha = -6.0 - (haEncoder / 360.0) * 24.0 ;
446 de = -90 + deEncoder;
447 ha = 6.0 - (haEncoder / 360.0) * 24.0 ;
454 char RAStr[32] = {0}, DecStr[32] = {0};
457 LOGF_DEBUG(
"Encoders HA: %.4f DE: %.4f Processed: HA: %.4f DE: %.4f (%s) LST: %.4f RA: %.4f (%s)",
458 haEncoder, deEncoder, ha, de, DecStr, lst,
ra, RAStr);
467 void AstroTrac::getEncodersFromRADE(
double ra,
double de,
double &haEncoder,
double &deEncoder)
472 if (LocationN[LOCATION_LATITUDE].value >= 0)
475 if (MountTypeSP.findOnSwitchIndex() == MOUNT_SINGLE_ARM || dHA <= 0)
477 deEncoder = -(de - 90.0);
478 haEncoder = (dHA + 6.0) * 360.0 / 24.0;
483 deEncoder = de - 90.0;
484 haEncoder = (dHA - 6.0) * 360.0 / 24.0;
490 if (MountTypeSP.findOnSwitchIndex() == MOUNT_SINGLE_ARM || dHA <= 0)
492 deEncoder = -(de + 90.0);
493 haEncoder = -(dHA + 6.0) * 360.0 / 24.0;
498 deEncoder = (de + 90.0);
499 haEncoder = -(dHA - 6.0) * 360 / 24.0;
515 NewEntry.
TelescopeDirection = TelescopeDirectionVectorFromEquatorialCoordinates(m_MountInternalCoordinates);
518 if (!CheckForDuplicateSyncPoint(NewEntry, 0.001))
520 GetAlignmentDatabase().push_back(NewEntry);
528 char RAStr[32], DecStr[32];
531 LOGF_INFO(
"Syncing to JNOW RA %s - DEC %s", RAStr, DecStr);
536 LOGF_DEBUG(
"Sync - duplicate entry RA: %lf(%lf) DEC: %lf",
ra * 360.0 / 24.0,
ra,
dec);
545 double haEncoder = 0, deEncoder = 0;
547 if (getTelescopeFromSkyCoordinates(
ra,
dec, telescopeCoordinates))
549 char mountRAString[32] = {0}, mountDEString[32] = {0}, skyRAString[32] = {0}, skyDEString[32] = {0};
555 LOGF_DEBUG(
"GOTO Sky RA: %s DE: %s ---> Mount RA: %s DE: %s", skyRAString, skyDEString, mountRAString, mountDEString);
561 double tHA = calculateSlewTime(haEncoder - EncoderNP[
AXIS_RA].getValue());
565 LOGF_DEBUG(
"GOTO Encoders HA: %.4f (%.4f + %.4f) DE: %.4f", haEncoder + tHA, haEncoder, tHA, deEncoder);
568 bool rc1 = slewEncoder(
AXIS_RA, haEncoder + tHA);
569 bool rc2 = slewEncoder(
AXIS_DE, deEncoder);
573 TrackState = SCOPE_SLEWING;
575 char RAStr[32], DecStr[32];
578 LOGF_INFO(
"Slewing to JNOW RA %s - DEC %s", RAStr, DecStr);
591 double AstroTrac::calculateSlewTime(
double distance)
594 distance = fabs(distance) * 3600.0;
597 double accelerate_decelerate = MAX_SLEW_VELOCITY * MAX_SLEW_VELOCITY / AccelerationNP[
AXIS_RA].getValue();
600 if (distance < accelerate_decelerate)
602 return (2 * sqrt(distance / AccelerationNP[
AXIS_RA].getValue()));
607 return (2.0 * MAX_SLEW_VELOCITY / AccelerationNP[
AXIS_RA].getValue() + (distance - accelerate_decelerate) /
618 double ra = 0, de = 0, skyRA = 0, skyDE = 0;
623 double lastHAEncoder = EncoderNP[
AXIS_RA].getValue();
624 double lastDEEncoder = EncoderNP[
AXIS_DE].getValue();
627 getRADEFromEncoders(EncoderNP[
AXIS_RA].getValue(), EncoderNP[
AXIS_DE].getValue(),
ra, de);
629 if (std::fabs(lastHAEncoder - EncoderNP[
AXIS_RA].getValue()) > 0
630 || std::fabs(lastDEEncoder - EncoderNP[
AXIS_DE].getValue()) > 0)
638 if (TrackState == SCOPE_SLEWING || TrackState == SCOPE_PARKING)
642 if (TrackState == SCOPE_SLEWING)
644 LOG_INFO(
"Slew complete, tracking...");
645 TrackState = SCOPE_TRACKING;
646 SetTrackEnabled(
true);
651 SetTrackEnabled(
false);
657 m_MountInternalCoordinates.rightascension =
ra;
658 m_MountInternalCoordinates.declination = de;
659 TDV = TelescopeDirectionVectorFromEquatorialCoordinates(m_MountInternalCoordinates);
661 if (TransformTelescopeToCelestial(TDV, skyRA, skyDE))
664 double dHA =
rangeHA(lst - skyRA);
665 setPierSide(dHA < 0 ? PIER_EAST : PIER_WEST);
667 char mountRAString[32] = {0}, mountDEString[32] = {0}, skyRAString[32] = {0}, skyDEString[32] = {0};
669 fs_sexa(mountDEString, de, 2, 3600);
670 fs_sexa(skyRAString, skyRA, 2, 3600);
671 fs_sexa(skyDEString, skyDE, 2, 3600);
673 LOGF_DEBUG(
"Mount RA: %s DE: %s ---> Sky RA: %s DE: %s", mountRAString, mountDEString, skyRAString, skyDEString);
675 NewRaDec(skyRA, skyDE);
679 LOG_ERROR(
"TransformTelescopeToCelestial failed in ReadScopeStatus");
689 if (TransformCelestialToTelescope(
ra, de, 0.0, TDV))
691 EquatorialCoordinatesFromTelescopeDirectionVector(TDV, telescopeCoordinates);
692 LOGF_DEBUG(
"TransformCelestialToTelescope: RA=%lf DE=%lf, TDV (x :%lf, y: %lf, z: %lf), local hour RA %lf DEC %lf",
705 if (slewEncoder(
AXIS_RA, GetAxis1Park()) && slewEncoder(
AXIS_DE, GetAxis2Park()))
707 TrackState = SCOPE_PARKING;
708 LOG_INFO(
"Parking is in progress...");
732 ProcessAlignmentTextProperties(
this, name, texts, names, n);
746 if (GuideRateNP.isNameMatch(name))
748 GuideRateNP.update(values, names, n);
749 GuideRateNP.setState(
IPS_OK);
755 if (AccelerationNP.isNameMatch(name))
757 AccelerationNP.update(values, names, n);
761 AccelerationNP.setState(
IPS_OK);
765 AccelerationNP.apply();
770 if (EncoderNP.isNameMatch(name))
772 if (slewEncoder(
AXIS_RA, values[0]) && slewEncoder(
AXIS_DE, values[1]))
774 TrackState = SCOPE_SLEWING;
775 EncoderNP.setState(
IPS_OK);
784 processGuiderProperties(name, values, names, n);
787 ProcessAlignmentNumberProperties(
this, name, values, names, n);
802 if (MountTypeSP.isNameMatch(name))
804 MountTypeSP.update(states, names, n);
805 MountTypeSP.setState(
IPS_OK);
811 ProcessAlignmentSwitchProperties(
this, name, states, names, n);
822 char *formats[],
char *names[],
int n)
827 ProcessAlignmentBLOBProperties(
this, name, sizes, blobsizes, blobs, formats, names, n);
849 if (TrackState == SCOPE_PARKED)
851 LOG_ERROR(
"Please unpark the mount before issuing any motion commands.");
855 if (command == MOTION_START)
859 setVelocity(
AXIS_DE, velocity);
875 if (TrackState == SCOPE_PARKED)
877 LOG_ERROR(
"Please unpark the mount before issuing any motion commands.");
881 if (command == MOTION_START)
885 setVelocity(
AXIS_RA, velocity);
903 SetApproximateMountAlignmentFromMountType(EQUATORIAL);
922 SetAxis1Park(EncoderNP[
AXIS_RA].getValue());
923 SetAxis2Park(EncoderNP[
AXIS_DE].getValue());
947 double dDE = GuideRateNP.at(
AXIS_DE)->getValue() * rate * ms / 1000.0;
949 setVelocity(
AXIS_DE, rate + dDE);
968 double dDE = GuideRateNP.at(
AXIS_DE)->getValue() * rate * ms / 1000.0;
970 setVelocity(
AXIS_DE, rate - dDE);
987 double dRA = GuideRateNP.at(
AXIS_RA)->getValue() * TrackRateN[
AXIS_RA].value * ms / 1000.0;
1006 double dRA = GuideRateNP.at(
AXIS_RA)->getValue() * TrackRateN[
AXIS_RA].value * ms / 1000.0;
1024 return setVelocity(
AXIS_RA, raRate) && setVelocity(
AXIS_DE, deRate);
1032 double dRA = 0, dDE = 0;
1033 if (mode == TRACK_SIDEREAL)
1035 else if (mode == TRACK_SOLAR)
1037 else if (mode == TRACK_LUNAR)
1039 else if (mode == TRACK_CUSTOM)
1041 dRA = TrackRateN[
AXIS_RA].value;
1042 dDE = TrackRateN[
AXIS_DE].value;
1071 MountTypeSP.save(fp);
1072 SaveAlignmentConfigProperties(fp);
1079 void AstroTrac::simulateMount()
1082 uint32_t elapsed = m_SimulationTimer.elapsed();
1087 m_SimulationTimer.restart();
1098 haVelocity *= MovementWESP.s ==
IPS_BUSY ? 1 : 0;
1099 deVelocity *= MovementNSSP.s ==
IPS_BUSY ? 1 : 0;
1102 double elapsedDistanceHA = (elapsed / 1000.0 * haVelocity) / 3600.0;
1103 double elapsedDistanceDE = (elapsed / 1000.0 * deVelocity) / 3600.0;
1106 SimData.currentMechanicalHA += elapsedDistanceHA;
1107 if (
SimData.currentMechanicalHA > 180)
1108 SimData.currentMechanicalHA -= 360;
1109 else if (
SimData.currentMechanicalHA < -180)
1110 SimData.currentMechanicalHA += 360;
1112 SimData.currentMechanicalDE += elapsedDistanceDE;
1113 if (
SimData.currentMechanicalDE > 180)
1114 SimData.currentMechanicalDE -= 360;
1115 else if (
SimData.currentMechanicalDE < -180)
1116 SimData.currentMechanicalDE += 360;
1130 double elapsedDistance = (elapsed / 1000.0 * MAX_SLEW_VELOCITY) / 3600.0;
1133 double dHA =
SimData.targetMechanicalHA -
SimData.currentMechanicalHA;
1134 if (std::abs(dHA) <= elapsedDistance)
1137 SimData.currentMechanicalHA += elapsedDistance;
1139 SimData.currentMechanicalHA -= elapsedDistance;
1142 double dDE =
SimData.targetMechanicalDE -
SimData.currentMechanicalDE;
1143 if (std::abs(dDE) <= elapsedDistance)
1146 SimData.currentMechanicalDE += elapsedDistance;
1148 SimData.currentMechanicalDE -= elapsedDistance;
1152 case SCOPE_TRACKING:
1155 SimData.currentMechanicalHA += (elapsed / 1000.0 * TrackRateN[
AXIS_RA].value) / 3600.0;
1156 if (
SimData.currentMechanicalHA > 180)
1157 SimData.currentMechanicalHA = 180;
1158 else if (
SimData.currentMechanicalHA < -180)
1159 SimData.currentMechanicalHA = -180;
1165 m_SimulationTimer.restart();
1174 m_SimulationTimer.start();
1180 bool AstroTrac::handleSimulationCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
1185 if (strstr(
cmd,
"zv?"))
1187 snprintf(res, res_len,
"<%czvSIMU>",
cmd[1]);
1190 else if (strstr (
cmd,
"p?"))
1192 snprintf(res, res_len,
"<%cp%.6f>",
cmd[1],
cmd[1] ==
'1' ?
SimData.currentMechanicalHA :
SimData.currentMechanicalDE);
1195 else if (strstr (
cmd,
"p"))
1198 sscanf(
cmd,
"<%*cp%lf", &value);
1203 snprintf(res, res_len,
"<%cp#>",
cmd[1]);
1206 else if (strstr (
cmd,
"a?"))
1208 snprintf(res, res_len,
"<%ca%u>",
cmd[1],
SimData.acceleration[
cmd[1] -
'1']);
1211 else if (strstr (
cmd,
"a"))
1214 sscanf(
cmd,
"<%*ca%u", &value);
1216 snprintf(res, res_len,
"<%ca#>",
cmd[1]);
1219 else if (strstr (
cmd,
"v?"))
1221 snprintf(res, res_len,
"<%cv%.6f>",
cmd[1],
SimData.velocity[
cmd[1] -
'1']);
1224 else if (strstr (
cmd,
"ve"))
1227 sscanf(
cmd,
"<%*cve%lf", &value);
1229 snprintf(res, res_len,
"<%cve#>",
cmd[1]);
1232 else if (strstr (
cmd,
"t"))
1236 result = std::abs(
SimData.currentMechanicalHA -
SimData.targetMechanicalHA) <= DIFF_THRESHOLD ?
'0' :
'1';
1238 result = std::abs(
SimData.currentMechanicalDE -
SimData.targetMechanicalDE) <= DIFF_THRESHOLD ?
'0' :
'1';
1239 snprintf(res, res_len,
"<%ct%c#>",
cmd[1], result);
1242 else if (strstr (
cmd,
"x"))
1244 snprintf(res, res_len,
"<%cx#>",
cmd[1]);
1253 bool AstroTrac::sendCommand(
const char *
cmd,
char * res,
int cmd_len,
int res_len)
1255 int nbytes_written = 0, nbytes_read = 0, rc = -1;
1258 return handleSimulationCommand(
cmd, res, cmd_len, res_len);
1260 tcflush(PortFD, TCIOFLUSH);
1264 char hex_cmd[DRIVER_LEN * 3] = {0};
1265 hexDump(hex_cmd,
cmd, cmd_len);
1279 LOGF_ERROR(
"Serial write error: %s.", errstr);
1290 rc =
tty_read(PortFD, res, res_len, DRIVER_TIMEOUT, &nbytes_read);
1292 rc =
tty_nread_section(PortFD, res, DRIVER_LEN, DRIVER_STOP_CHAR, DRIVER_TIMEOUT, &nbytes_read);
1298 LOGF_ERROR(
"Serial read error: %s.", errstr);
1304 char hex_res[DRIVER_LEN * 3] = {0};
1305 hexDump(hex_res, res, res_len);
1313 tcflush(PortFD, TCIOFLUSH);
1321 void AstroTrac::hexDump(
char * buf,
const char * data,
int size)
1323 for (
int i = 0; i < size; i++)
1324 sprintf(buf + 3 * i,
"%02X ",
static_cast<uint8_t
>(data[i]));
1327 buf[3 * size - 1] =
'\0';
1333 std::vector<std::string> AstroTrac::split(
const std::string &input,
const std::string ®ex)
1336 std::regex re(regex);
1337 std::sregex_token_iterator
1338 first{input.begin(), input.end(), re, -1},
1340 return {first, last};
std::unique_ptr< AstroTrac > AstroTrac_mount(new AstroTrac())
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual const char * getDefaultName() override
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool SetTrackRate(double raRate, double deRate) override
SetTrackRate Set custom tracking rates.
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual void simulationTriggered(bool enable) override
Handle Simulation Trigger.
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 saveConfigItems(FILE *fp) override
Config Items.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) override
Process the client newBLOB command.
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
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 SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
virtual bool Park() override
Park the telescope to its home position.
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState GuideEast(uint32_t ms) override
Guide east for ms milliseconds. East is defined as RA+.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
virtual bool updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
virtual bool Goto(double ra, double dec) override
Move the scope to the supplied RA and DEC coordinates.
void UpdateLocation(double latitude, double longitude, double elevation)
Call this function from within the updateLocation processing path.
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Process the client newBLOB command.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
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 updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
static void singleShot(int msec, const std::function< void()> &callback)
This static function calls a the given function after a given time interval.
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.
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
double rangeHA(double r)
rangeHA Limits the hour angle value to be between -12 —> 12
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
double range24(double r)
range24 Limits a number to be between 0-24 range.
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
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[].
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Implementations for common driver routines.
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sideral time given longitude and system clock.
#define TRACKRATE_SIDEREAL
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
#define LOGF_INFO(fmt,...)
#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,...)
int isSlewComplete(int fd)
Namespace to encapsulate the INDI Alignment Subsystem classes. For more information see "INDI Alignme...
bool getVersion(const int fd, char response[])
const char * getDeviceName()
@ value
the parser finished reading a JSON value
Entry in the in memory alignment database.
double RightAscension
Right ascension in decimal hours. N.B. libnova works in decimal degrees so conversion is always neede...
double ObservationJulianDate
TelescopeDirectionVector TelescopeDirection
Normalised vector giving telescope pointing direction. This is referred to elsewhere as the "apparent...
double Declination
Declination in decimal degrees.
int PrivateDataSize
This size in bytes of any private data.
Holds a nomalised direction vector (direction cosines)