21#include <libnova/transform.h>
24#include <libnova/utility.h>
45bool FileExists(
const std::string &name)
49 return (stat (name.c_str(), &buffer) == 0);
52std::string GetLogTimestamp()
54 time_t Now = time(
nullptr);
59 TimeStruct = *localtime(&Now);
60 strftime(Buffer,
sizeof(Buffer),
"%Y%m%d %H:%M:%S", &TimeStruct);
63 std::chrono::system_clock::time_point NowClock = std::chrono::system_clock::now();
64 std::chrono::system_clock::duration TimePassed = NowClock.time_since_epoch();
66 TimePassed -= std::chrono::duration_cast<std::chrono::seconds>(TimePassed);
67 FinalStr +=
"." + std::to_string(
static_cast<unsigned>(TimePassed / std::chrono::milliseconds(1)));
79 std::remove(TrackLogFileName.c_str());
85 LogMessage(
"MOVE ABORT");
115 if (!activeConnection->
name().compare(
"CONNECTION_TCP"))
131 RecoverAfterReconnection =
false;
132 DEBUGF(
DBG_SCOPE,
"SkywatcherAltAzSimple::Handshake - Result: %d", Result);
139 return "Skywatcher Alt-Az Wedge";
153 char RAStr[32], DecStr[32];
163 AltAz = GetAltAzPosition(
ra,
dec);
164 DEBUGF(
DBG_SCOPE,
"New Altitude %lf degrees %ld microsteps Azimuth %lf degrees %ld microsteps", AltAz.altitude,
166 LogMessage(
"NEW GOTO TARGET: Ra %lf Dec %lf - Alt %lf Az %lf - microsteps %ld %ld",
ra,
dec, AltAz.altitude,
174 long AltitudeOffsetMicrosteps =
176 long AzimuthOffsetMicrosteps =
179 DEBUGF(
DBG_SCOPE,
"Initial deltas Altitude %ld microsteps Azimuth %ld microsteps", AltitudeOffsetMicrosteps,
180 AzimuthOffsetMicrosteps);
205 DEBUGF(
DBG_SCOPE,
"Altitude offset %ld microsteps Azimuth offset %ld microsteps",
206 AltitudeOffsetMicrosteps, AzimuthOffsetMicrosteps);
226 IDLog(
"SkywatcherAltAzSimple::initProperties\n");
243 IUFillText(&BasicMountInfoT[MOTOR_CONTROL_FIRMWARE_VERSION],
"MOTOR_CONTROL_FIRMWARE_VERSION",
244 "Motor control firmware version",
"-");
245 IUFillText(&BasicMountInfoT[MOUNT_CODE],
"MOUNT_CODE",
"Mount code",
"-");
246 IUFillText(&BasicMountInfoT[MOUNT_NAME],
"MOUNT_NAME",
"Mount name",
"-");
247 IUFillText(&BasicMountInfoT[IS_DC_MOTOR],
"IS_DC_MOTOR",
"Is DC motor",
"-");
249 "Basic mount information", DetailedMountInfoPage,
IP_RO, 60,
IPS_IDLE);
251 IUFillNumber(&AxisOneInfoN[MICROSTEPS_PER_REVOLUTION],
"MICROSTEPS_PER_REVOLUTION",
"Microsteps per revolution",
252 "%.0f", 0, 0xFFFFFF, 1, 0);
253 IUFillNumber(&AxisOneInfoN[STEPPER_CLOCK_FREQUENCY],
"STEPPER_CLOCK_FREQUENCY",
"Stepper clock frequency",
"%.0f", 0,
255 IUFillNumber(&AxisOneInfoN[HIGH_SPEED_RATIO],
"HIGH_SPEED_RATIO",
"High speed ratio",
"%.0f", 0, 0xFFFFFF, 1, 0);
256 IUFillNumber(&AxisOneInfoN[MICROSTEPS_PER_WORM_REVOLUTION],
"MICROSTEPS_PER_WORM_REVOLUTION",
257 "Microsteps per worm revolution",
"%.0f", 0, 0xFFFFFF, 1, 0);
265 IUFillSwitch(&AxisOneStateS[SLEWING_FORWARD],
"SLEWING_FORWARD",
"SLEWING_FORWARD",
ISS_OFF);
267 IUFillSwitch(&AxisOneStateS[NOT_INITIALISED],
"NOT_INITIALISED",
"NOT_INITIALISED",
ISS_ON);
271 IUFillNumber(&AxisTwoInfoN[MICROSTEPS_PER_REVOLUTION],
"MICROSTEPS_PER_REVOLUTION",
"Microsteps per revolution",
272 "%.0f", 0, 0xFFFFFF, 1, 0);
273 IUFillNumber(&AxisTwoInfoN[STEPPER_CLOCK_FREQUENCY],
"STEPPER_CLOCK_FREQUENCY",
"Step timer frequency",
"%.0f", 0,
275 IUFillNumber(&AxisTwoInfoN[HIGH_SPEED_RATIO],
"HIGH_SPEED_RATIO",
"High speed ratio",
"%.0f", 0, 0xFFFFFF, 1, 0);
276 IUFillNumber(&AxisTwoInfoN[MICROSTEPS_PER_WORM_REVOLUTION],
"MICROSTEPS_PER_WORM_REVOLUTION",
277 "Microsteps per worm revolution",
"%.0f", 0, 0xFFFFFF, 1, 0);
285 IUFillSwitch(&AxisTwoStateS[SLEWING_FORWARD],
"SLEWING_FORWARD",
"SLEWING_FORWARD",
ISS_OFF);
287 IUFillSwitch(&AxisTwoStateS[NOT_INITIALISED],
"NOT_INITIALISED",
"NOT_INITIALISED",
ISS_ON);
291 IUFillNumber(&AxisOneEncoderValuesN[RAW_MICROSTEPS],
"RAW_MICROSTEPS",
"Raw Microsteps",
"%.0f", 0, 0xFFFFFF, 1, 0);
292 IUFillNumber(&AxisOneEncoderValuesN[MICROSTEPS_PER_ARCSEC],
"MICROSTEPS_PER_ARCSEC",
"Microsteps/arcsecond",
293 "%.4f", 0, 0xFFFFFF, 1, 0);
294 IUFillNumber(&AxisOneEncoderValuesN[OFFSET_FROM_INITIAL],
"OFFSET_FROM_INITIAL",
"Offset from initial",
"%.0f", 0,
296 IUFillNumber(&AxisOneEncoderValuesN[DEGREES_FROM_INITIAL],
"DEGREES_FROM_INITIAL",
"Degrees from initial",
"%.2f",
297 -1000.0, 1000.0, 1, 0);
300 "Axis 1 Encoder values", DetailedMountInfoPage,
IP_RO, 60,
IPS_IDLE);
302 IUFillNumber(&AxisTwoEncoderValuesN[RAW_MICROSTEPS],
"RAW_MICROSTEPS",
"Raw Microsteps",
"%.0f", 0, 0xFFFFFF, 1, 0);
303 IUFillNumber(&AxisTwoEncoderValuesN[MICROSTEPS_PER_ARCSEC],
"MICROSTEPS_PER_ARCSEC",
"Microsteps/arcsecond",
304 "%.4f", 0, 0xFFFFFF, 1, 0);
305 IUFillNumber(&AxisTwoEncoderValuesN[OFFSET_FROM_INITIAL],
"OFFSET_FROM_INITIAL",
"Offset from initial",
"%.0f", 0,
307 IUFillNumber(&AxisTwoEncoderValuesN[DEGREES_FROM_INITIAL],
"DEGREES_FROM_INITIAL",
"Degrees from initial",
"%.2f",
308 -1000.0, 1000.0, 1, 0);
311 "Axis 2 Encoder values", DetailedMountInfoPage,
IP_RO, 60,
IPS_IDLE);
328 IUFillSwitch(&TrackLogModeS[TRACKLOG_ENABLED],
"TRACKLOG_ENABLED",
"Enable logging",
ISS_OFF);
329 IUFillSwitch(&TrackLogModeS[TRACKLOG_DISABLED],
"TRACKLOG_DISABLED",
"Disabled",
ISS_ON);
334 IUFillNumber(&GuidingRatesN[0],
"GUIDERA_RATE",
"microsteps/seconds (RA)",
"%1.3f", 0.00001, 100000.0, 0.00001, 1.0);
335 IUFillNumber(&GuidingRatesN[1],
"GUIDEDEC_RATE",
"microsteps/seconds (Dec)",
"%1.3f", 0.00001, 100000.0, 0.00001, 1.0);
344 IUFillNumber(&TrackingValuesN[0],
"TRACKING_RATE_ALT",
"rate (Alt)",
"%1.3f", 0.001, 10.0, 0.000001, 0.64);
345 IUFillNumber(&TrackingValuesN[1],
"TRACKING_RATE_AZ",
"rate (Az)",
"%1.3f", 0.001, 10.0, 0.000001, 0.64);
346 IUFillNumber(&TrackingValuesN[2],
"TRACKING_TIMEOUT",
"msec (period)",
"%1.3f", 0.001, 10000.0, 0.000001, 1000.0);
381 IDLog(
"SkywatcherAltAzSimple::ISGetProperties\n");
387 UpdateDetailedMountInformation(
false);
413 char *formats[],
char *names[],
int n)
427 if (strcmp(name,
"GUIDE_RATES") == 0)
436 if (strcmp(name,
"TRACKING_VALUES") == 0)
445 if (strcmp(name,
"EQUATORIAL_EOD_COORD") == 0)
450 for (
int x = 0; x < n; x++)
462 if ((
ra >= 0) && (
ra <= 24) && (
dec >= -90) && (
dec <= 90))
473 processGuiderProperties(name, values, names, n);
485 LOGF_WARN(
"getSwitch failed for %s", name);
512 if (name && std::string(name) ==
"SCOPE_CONFIG_NAME")
514 UpdateScopeConfigSwitch();
520void SkywatcherAltAzSimple::UpdateScopeConfigSwitch()
522 if (!
CheckFile(ScopeConfigFileName,
false))
528 FILE *FilePtr = fopen(ScopeConfigFileName.c_str(),
"r");
529 XMLEle *RootXmlNode =
nullptr;
530 XMLEle *CurrentXmlNode =
nullptr;
532 bool DeviceFound =
false;
535 RootXmlNode =
readXMLFile(FilePtr, XmlHandle, ErrMsg);
543 if (std::string(
tagXMLEle(RootXmlNode)) != ScopeConfigRootXmlNode)
551 while (CurrentXmlNode)
553 if (std::string(
tagXMLEle(CurrentXmlNode)) != ScopeConfigDeviceXmlNode)
558 Ap =
findXMLAtt(CurrentXmlNode, ScopeConfigNameXmlNode.c_str());
569 ScopeConfigFileName.c_str());
574 XMLEle *XmlNode =
nullptr;
575 XMLEle *DeviceXmlNode = CurrentXmlNode;
576 std::string ConfigName;
578 for (
int i = 1; i < 7; ++i)
582 CurrentXmlNode =
findXMLEle(DeviceXmlNode, (
"config" + std::to_string(i)).c_str());
585 XmlNode =
findXMLEle(CurrentXmlNode, ScopeConfigLabelApXmlNode.c_str());
596 ISwitch *configSwitch =
IUFindSwitch(&ScopeConfigsSP, (
"SCOPE_CONFIG" + std::to_string(i)).c_str());
598 if (configSwitch !=
nullptr)
604 (
"Config #" + std::to_string(i) +
" - Not used").c_str());
608 if (ConfigName.empty())
611 (
"Config #" + std::to_string(i) +
" - Untitled").c_str());
615 (
"Config #" + std::to_string(i) +
" - " + ConfigName).c_str());
629 double Rate = *((
double *)Switch->aux);
699 DEBUGF(
DBG_SCOPE,
"GetParkDeltaAz: direction %d - position: %d", (
int)target_direction, (
int)target_position);
705 Result = -CurrentAltAz.
azimuth;
709 Result = 360 - CurrentAltAz.
azimuth;
718 Result = -270 - CurrentAltAz.
azimuth;
720 Result = -CurrentAltAz.
azimuth + 90;
725 Result = 90 - CurrentAltAz.
azimuth;
727 Result = 360 - CurrentAltAz.
azimuth + 90;
736 Result = -180 - CurrentAltAz.
azimuth;
738 Result = -CurrentAltAz.
azimuth + 180;
743 Result = 180 - CurrentAltAz.
azimuth;
745 Result = 360 - CurrentAltAz.
azimuth + 180;
754 Result = -90 - CurrentAltAz.
azimuth;
756 Result = -CurrentAltAz.
azimuth + 270;
761 Result = 270 - CurrentAltAz.
azimuth;
763 Result = 360 - CurrentAltAz.
azimuth + 270;
786 if (
IUFindSwitch(&ParkPositionSP,
"PARK_NORTH") !=
nullptr &&
791 if (
IUFindSwitch(&ParkPositionSP,
"PARK_EAST") !=
nullptr &&
796 if (
IUFindSwitch(&ParkPositionSP,
"PARK_SOUTH") !=
nullptr &&
801 if (
IUFindSwitch(&ParkPositionSP,
"PARK_WEST") !=
nullptr &&
807 if (
IUFindSwitch(&ParkMovementDirectionSP,
"PMD_COUNTERCLOCKWISE") !=
nullptr &&
812 if (
IUFindSwitch(&ParkMovementDirectionSP,
"PMD_CLOCKWISE") !=
nullptr &&
823 DEBUGF(
DBG_SCOPE,
"Parking: Delta altitude %1.2f - delta azimuth %1.2f", DeltaAlt, DeltaAz);
824 DEBUGF(
DBG_SCOPE,
"Parking: Altitude offset %ld microsteps Azimuth offset %ld microsteps",
825 AltitudeOffsetMicrosteps, AzimuthOffsetMicrosteps);
852 if (
IUFindSwitch(&UnparkPositionSP,
"UNPARK_NORTH") !=
nullptr &&
857 if (
IUFindSwitch(&UnparkPositionSP,
"UNPARK_EAST") !=
nullptr &&
862 if (
IUFindSwitch(&UnparkPositionSP,
"UNPARK_SOUTH") !=
nullptr &&
867 if (
IUFindSwitch(&UnparkPositionSP,
"UNPARK_WEST") !=
nullptr &&
874 if (
IUFindSwitch(&ParkMovementDirectionSP,
"PMD_COUNTERCLOCKWISE") !=
nullptr &&
879 if (
IUFindSwitch(&ParkMovementDirectionSP,
"PMD_CLOCKWISE") !=
nullptr &&
886 DeltaAlt = CurrentAltAz.
altitude - 3360;
892 DEBUGF(
DBG_SCOPE,
"Unparking: Delta altitude %1.2f - delta azimuth %1.2f", DeltaAlt, DeltaAz);
893 DEBUGF(
DBG_SCOPE,
"Unparking: Altitude offset %ld microsteps Azimuth offset %ld microsteps",
894 AltitudeOffsetMicrosteps, AzimuthOffsetMicrosteps);
931 if (UpdateCount % 5 == 0)
932 UpdateDetailedMountInformation(
true);
947 if (VerboseScopeStatus)
953 CurrentAltAz = AltAz;
954 if (VerboseScopeStatus)
962 RaDec = GetRaDecPosition(AltAz.altitude, AltAz.azimuth);
963 if (VerboseScopeStatus)
965 DEBUGF(
DBG_SCOPE,
"New RA %lf (hours) DEC %lf (degrees)", RaDec.rightascension, RaDec.declination);
967 LogMessage(
"STATUS: Ra %lf Dec %lf - Alt %lf Az %lf - microsteps %ld %ld", RaDec.rightascension, RaDec.declination,
970 NewRaDec(RaDec.rightascension, RaDec.declination);
971 VerboseScopeStatus =
false;
1003 AltAz = GetAltAzPosition(
ra,
dec);
1004 double DeltaAz = CurrentAltAz.
azimuth - AltAz.azimuth;
1005 double DeltaAlt = CurrentAltAz.
altitude - AltAz.altitude;
1007 LogMessage(
"SYNC: Ra %lf Dec %lf",
ra,
dec);
1016 ResetTrackingSeconds =
true;
1025 UpdateDetailedMountInformation(
true);
1032 static bool Slewing =
false;
1033 static bool Tracking =
false;
1034 static int ElapsedTime = 0;
1042 LogMessage(
"SET TIMER: %d msec", TimeoutDuration);
1044 ElapsedTime += TimeoutDuration;
1045 if (ElapsedTime >= 5000)
1048 VerboseScopeStatus =
true;
1057 TrackingStartTimer = 0;
1063 TimeoutDuration = 400;
1066 GuidingPulses.clear();
1069 TrackingStartTimer += TimeoutDuration;
1070 if (TrackingStartTimer < 3000)
1094 TimeoutDuration = (int)
IUFindNumber(&TrackingValuesNP,
"TRACKING_TIMEOUT")->value;
1108 if (ResetTrackingSeconds)
1110 ResetTrackingSeconds =
false;
1116 TrackingMsecs += TimeoutDuration;
1117 if (TrackingMsecs % 60000 == 0)
1130 (
double)TimeoutDuration / 1000);
1140 for (
auto pulse : GuidingPulses)
1142 GuideDeltaAlt += pulse.DeltaAlt;
1143 GuideDeltaAz += pulse.DeltaAz;
1145 GuidingPulses.clear();
1154 AltitudeOffsetMicrosteps = (long)((
float)
IUFindNumber(&GuidingRatesNP,
"GUIDEDEC_RATE")->value * GuideDeltaAlt);
1155 AzimuthOffsetMicrosteps = (long)((
float)
IUFindNumber(&GuidingRatesNP,
"GUIDERA_RATE")->value * GuideDeltaAz);
1159 double DeltaAz = CurrentAltAz.
azimuth - FutureAltAz.azimuth;
1160 double DeltaAlt = CurrentAltAz.
altitude - FutureAltAz.altitude;
1189 AltitudeOffsetMicrosteps = (long)((
double)AltitudeOffsetMicrosteps *
IUFindNumber(&TrackingValuesNP,
1190 "TRACKING_RATE_ALT")->value);
1191 AzimuthOffsetMicrosteps = (long)((
double)AzimuthOffsetMicrosteps *
IUFindNumber(&TrackingValuesNP,
1192 "TRACKING_RATE_AZ")->value);
1194 LogMessage(
"TRACKING: now Alt %lf Az %lf - future Alt %lf Az %lf - microsteps_diff Alt %ld Az %ld",
1195 CurrentAltAz.
altitude, CurrentAltAz.
azimuth, FutureAltAz.altitude, FutureAltAz.azimuth,
1196 AltitudeOffsetMicrosteps, AzimuthOffsetMicrosteps);
1201 if (0 != AzimuthOffsetMicrosteps)
1211 if (0 != AltitudeOffsetMicrosteps)
1221 DEBUGF(
DBG_SCOPE,
"Tracking - AXIS1 error %d (offset: %ld) AXIS2 error %d (offset: %ld)",
1245 TimeoutDuration = 1000;
1248 GuidingPulses.clear();
1260 UpdateDetailedMountInformation(
false);
1317 LogMessage(
"GUIDE NORTH: %1.4f", ms);
1320 GuidingPulses.push_back(Pulse);
1328 LogMessage(
"GUIDE SOUTH: %1.4f", ms);
1331 GuidingPulses.push_back(Pulse);
1339 LogMessage(
"GUIDE WEST: %1.4f", ms);
1342 GuidingPulses.push_back(Pulse);
1350 LogMessage(
"GUIDE EAST: %1.4f", ms);
1353 GuidingPulses.push_back(Pulse);
1359void SkywatcherAltAzSimple::ResetGuidePulses()
1361 GuidingPulses.clear();
1364int SkywatcherAltAzSimple::recover_tty_reconnect()
1366 if (!RecoverAfterReconnection && !SerialPortName.empty() && !FileExists(SerialPortName))
1368 RecoverAfterReconnection =
true;
1371 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
1374 RecoverAfterReconnection =
true;
1375 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
1378 RecoverAfterReconnection =
false;
1384 RecoverAfterReconnection =
false;
1393void SkywatcherAltAzSimple::UpdateDetailedMountInformation(
bool InformClient)
1395 bool BasicMountInfoHasChanged =
false;
1397 if (std::string(BasicMountInfoT[MOTOR_CONTROL_FIRMWARE_VERSION].text) != std::to_string(
MCVersion))
1399 IUSaveText(&BasicMountInfoT[MOTOR_CONTROL_FIRMWARE_VERSION], std::to_string(
MCVersion).c_str());
1400 BasicMountInfoHasChanged =
true;
1402 if (std::string(BasicMountInfoT[MOUNT_CODE].text) != std::to_string(
MountCode))
1405 BasicMountInfoHasChanged =
true;
1407 if (std::string(BasicMountInfoT[IS_DC_MOTOR].text) != std::to_string(
IsDCMotor))
1410 BasicMountInfoHasChanged =
true;
1412 if (BasicMountInfoHasChanged && InformClient)
1416 IUSaveText(&BasicMountInfoT[MOUNT_NAME],
"Merlin");
1418 IUSaveText(&BasicMountInfoT[MOUNT_NAME],
"Az Goto");
1420 IUSaveText(&BasicMountInfoT[MOUNT_NAME],
"Dob Goto");
1422 IUSaveText(&BasicMountInfoT[MOUNT_NAME],
"Virtuoso");
1424 IUSaveText(&BasicMountInfoT[MOUNT_NAME],
"AllView Goto");
1426 bool AxisOneInfoHasChanged =
false;
1431 AxisOneInfoHasChanged =
true;
1436 AxisOneInfoHasChanged =
true;
1441 AxisOneInfoHasChanged =
true;
1446 AxisOneInfoHasChanged =
true;
1448 if (AxisOneInfoHasChanged && InformClient)
1451 bool AxisOneStateHasChanged =
false;
1455 AxisOneStateHasChanged =
true;
1460 AxisOneStateHasChanged =
true;
1465 AxisOneStateHasChanged =
true;
1470 AxisOneStateHasChanged =
true;
1475 AxisOneStateHasChanged =
true;
1480 AxisOneStateHasChanged =
true;
1482 if (AxisOneStateHasChanged && InformClient)
1485 bool AxisTwoInfoHasChanged =
false;
1489 AxisTwoInfoHasChanged =
true;
1494 AxisTwoInfoHasChanged =
true;
1499 AxisTwoInfoHasChanged =
true;
1504 AxisTwoInfoHasChanged =
true;
1506 if (AxisTwoInfoHasChanged && InformClient)
1509 bool AxisTwoStateHasChanged =
false;
1513 AxisTwoStateHasChanged =
true;
1518 AxisTwoStateHasChanged =
true;
1523 AxisTwoStateHasChanged =
true;
1528 AxisTwoStateHasChanged =
true;
1533 AxisTwoStateHasChanged =
true;
1538 AxisTwoStateHasChanged =
true;
1540 if (AxisTwoStateHasChanged && InformClient)
1543 bool AxisOneEncoderValuesHasChanged =
false;
1550 AxisOneEncoderValuesN[DEGREES_FROM_INITIAL].value =
1552 AxisOneEncoderValuesHasChanged =
true;
1554 if (AxisOneEncoderValuesHasChanged && InformClient)
1557 bool AxisTwoEncoderValuesHasChanged =
false;
1564 AxisTwoEncoderValuesN[DEGREES_FROM_INITIAL].value =
1566 AxisTwoEncoderValuesHasChanged =
true;
1568 if (AxisTwoEncoderValuesHasChanged && InformClient)
1578 double JulianOffset = offset_in_sec / (24.0 * 60 * 60);
1587 Location.longitude = 0;
1591 Location.latitude = -90;
1592 Location.longitude = 0;
1613 Location.latitude = 90;
1614 Location.longitude = 0;
1618 Location.latitude = -90;
1619 Location.longitude = 0;
1628void SkywatcherAltAzSimple::LogMessage(
const char* format, ...)
1634 va_start(Ap, format);
1637 std::ofstream LogFile;
1639 LogFile.open(TrackLogFileName.c_str(), std::ios::out | std::ios::app);
1640 if (!LogFile.is_open())
1644 vsnprintf(TempStr,
sizeof(TempStr), format, Ap);
1645 LogFile << GetLogTimestamp() <<
" | " << TempStr <<
"\n";
The Interface class is the base class for all INDI connection plugins.
virtual std::string name()=0
virtual const char * port()
bool Refresh(bool silent=false)
virtual bool Disconnect() override
Disconnect Disconnect from device.
virtual bool Connect() override
Connect Connect to device via the implemented communication medium. Do not perform any handshakes.
INDI::PropertySwitch getSwitch(const char *name) const
void addConfigurationControl()
Add Configuration control to the driver.
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getDriverInterface() const
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.
Connection::Interface * getActiveConnection()
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
INDI::PropertyNumber GuideNSNP
INDI::PropertyNumber GuideWENP
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
TelescopeStatus TrackState
bool CheckFile(const std::string &file_name, bool writable) const
Check if a file exists and it is readable.
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
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...
bool isParked()
isParked is mount currently parked?
Connection::Serial * serialConnection
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
IGeographicCoordinates m_Location
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
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.
void SetSerialPort(int port)
Set the serail port to be usb for mount communication.
bool GetMotorBoardVersion(AXISID Axis)
static constexpr double LOW_SPEED_MARGIN
double MicrostepsToDegrees(AXISID Axis, long Microsteps)
Convert microsteps to angle in degrees.
void SlewTo(AXISID Axis, long OffsetInMicrosteps, bool verbose=true)
Slew to the given offset and stop.
long ZeroPositionEncoders[2]
Zero position encoder values (microsteps).
long CurrentEncoders[2]
Current encoder values (microsteps).
bool GetStatus(AXISID Axis)
long PolarisPositionEncoders[2]
Polaris position (initial) encoder values (microsteps).
bool GetEncoder(AXISID Axis)
Set the CurrentEncoders status variable to the current encoder value in microsteps for the specified ...
long MicrostepsPerWormRevolution[2]
double MicrostepsPerDegree[2]
long DegreesToMicrosteps(AXISID Axis, double AngleInDegrees)
Convert angle in degrees to microsteps.
bool SlowStop(AXISID Axis)
Bring the axis to slow stop in the distance specified by SetSlewModeDeccelerationRampLength.
bool InitMount()
Initialize the communication to the mount.
void Slew(AXISID Axis, double SpeedInRadiansPerSecond, bool IgnoreSilentMode=true)
Start the axis slewing at the given rate.
long MicrostepsPerRevolution[2]
bool IsInMotion(AXISID Axis)
Check if an axis is moving.
long StepperClockFrequency[2]
INDI::Telescope * pChildTelescope
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual const char * getDefaultName() override
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
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 updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
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 ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
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 Goto(double ra, double dec) override
Move the scope to the supplied RA and DEC coordinates.
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool Park() override
Park the telescope to its home position.
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
virtual void TimerHit() override
Called when setTimer() time is up.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
double GetParkDeltaAz(ParkDirection_t target_direction, ParkPosition_t target_position)
const char * GUIDE_TAB
GUIDE_TAB Where all the properties for guiding are located.
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
INDI::PropertyNumber EqNP
INDI::PropertySwitch SlewRateSP
INDI::PropertySwitch CoordSP
void tty_set_generic_udp_format(int enabled)
void IDLog(const char *fmt,...)
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 IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
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.
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
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.
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *svp)
Returns the first ON switch it finds in the vector switch property.
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
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 DEBUG(priority, msg)
Macro to print log messages. Example of usage of the Logger: DEBUG(DBG_DEBUG, "hello " << "world");.
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define DEBUGF(priority, msg,...)
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
LilXML * newLilXML()
Create a new lilxml parser.
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
XMLEle * findXMLEle(XMLEle *ep, const char *tag)
Find an XML element within an XML element.
char * valuXMLAtt(XMLAtt *ap)
Return the value of an XML attribute.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
void delLilXML(LilXML *lp)
Delete a lilxml parser.
XMLEle * readXMLFile(FILE *fp, LilXML *lp, char ynot[])
Handy wrapper to read one xml file.
std::vector< uint8_t > buffer
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.
void HorizontalToEquatorial(IHorizontalCoordinates *object, IGeographicCoordinates *observer, double JD, IEquatorialCoordinates *position)
HorizontalToEquatorial Calculate Equatorial EOD Coordinates from horizontal coordinates.
#define MYDEBUGF(priority, msg,...)
double SlewSpeeds[SLEWMODES]
std::unique_ptr< SkywatcherAltAzSimple > SkywatcherAltAzSimplePtr(new SkywatcherAltAzSimple())
Switch vector property descriptor.