25#include <libnova/julian_day.h>
34static std::unique_ptr<ScopeSim> telescope_sim(
new ScopeSim());
54 srand(
static_cast<uint32_t
>(time(
nullptr)));
66 return "Telescope Simulator";
80 simPierSideSP[PS_OFF].
fill(
"PS_OFF",
"Off",
ISS_OFF);
81 simPierSideSP[PS_ON].
fill(
"PS_ON",
"On",
ISS_ON);
85 mountModelNP[MM_IH].
fill(
"MM_IH",
"Ha Zero (IH) '",
"%.1f", -10800, 10800, 0.1, 0);
86 mountModelNP[MM_ID].
fill(
"MM_ID",
"Dec Zero (ID) '",
"%.1f", -10800, 10800, 0.1, 0);
87 mountModelNP[MM_CH].
fill(
"MM_CH",
"Cone (CH) '",
"%.1f", -300, 300, 0.1, 0);
88 mountModelNP[MM_NP].
fill(
"MM_NP",
"Ha/Dec (NP) '",
"%.1f", -300, 300, 0.1, 0);
89 mountModelNP[MM_MA].
fill(
"MM_MA",
"Pole Azm (MA) '",
"%.1f", -300, 300, 0.1, 0);
90 mountModelNP[MM_ME].
fill(
"MM_ME",
"Pole elev (ME) '",
"%.1f", -300, 300, 0.1, 0);
94 flipHourAngleNP[0].
fill(
"FLIP_HA",
"Hour Angle (deg)",
"%g", -20, 20, 0.1, 0);
98 mountAxisNP[PRIMARY].
fill(
"PRIMARY",
"Primary (Ha)",
"%g", -180, 180, 0.01, 0);
99 mountAxisNP[SECONDARY].
fill(
"SECONDARY",
"Secondary (Dec)",
"%g", -180, 180, 0.01, 0);
103 decBacklashNP[0].
fill(
"DEC_BACKLASH",
"DEC Backlash (ms)",
"%.0f", 0, 5000, 0, 0);
107 PACDeviceTP[0].
fill(
"PAC_DEVICE",
"Alignment Corrector",
"Alignment Correction Simulator");
111 const char *pacDevice = PACDeviceTP[0].
getText();
112 if (pacDevice && strlen(pacDevice) > 0)
118 GuideRateNP[
RA_AXIS].
fill(
"GUIDE_RATE_WE",
"W/E Rate",
"%g", 0, 1, 0.1, 0.5);
119 GuideRateNP[
DEC_AXIS].
fill(
"GUIDE_RATE_NS",
"N/S Rate",
"%g", 0, 1, 0.1, 0.5);
149 EqPENP[PE_RA].
fill(
"RA_PE",
"RA (hh:mm:ss)",
"%010.6m", 0, 24, 0, 0);
150 EqPENP[PE_DEC].
fill(
"DEC_PE",
"DEC (dd:mm:ss)",
"%010.6m", -90, 90, 0, 0);
167 simPierSideSP.
load();
168 updateMountAndPierSide();
171 alignment.
setCorrections(mountModelNP[MM_IH].getValue() / 60.0, mountModelNP[MM_ID].getValue() / 60.0,
172 mountModelNP[MM_CH].getValue() / 60.0, mountModelNP[MM_NP].getValue() / 60.0,
173 mountModelNP[MM_MA].getValue() / 60.0, mountModelNP[MM_ME].getValue() / 60.0);
176 flipHourAngleNP.
load();
178 decBacklashNP.
load();
188 updateMountAndPierSide();
211 Angle instHA, instDec;
216 m_currentRA = (alignment.
lst() - instHA).Hours();
217 m_currentDEC = instDec.
Degrees();
248 Angle primary, secondary;
254 m_targetRA = m_currentRA;
255 m_targetDEC = m_currentDEC;
263 const char *pacDevice = PACDeviceTP[0].
getText();
264 if (pacDevice && strlen(pacDevice) > 0)
284 LOG_INFO(
"Telescope simulator is online.");
292 LOG_INFO(
"Telescope simulator is offline.");
297void ScopeSim::updateCurrentCoordsFromAxes()
299 Angle instHA, instDec;
301 m_currentRA = (alignment.
lst() - instHA).Hours();
302 m_currentDEC = instDec.
Degrees();
306 double corrRA, corrDec;
307 bool corrected =
false;
318 double encoderRA = (alignment.
lst() - instHA).Hours();
326 m_currentRA = corrRA;
327 m_currentDEC = corrDec;
332void ScopeSim::setTargetFromAxisPosition(
Angle primary,
Angle secondary)
334 Angle instHA, instDec;
336 m_targetRA = (alignment.
lst() - instHA).Hours();
337 m_targetDEC = instDec.
Degrees();
347 double JDoffset = dt / 86400.0;
354 double raDriftHrsPerSec = 0;
362 double dtFromNow = (JD - JDnow) * 86400.0;
367 bool targetChanged = std::abs(m_LastTrackingRA - m_targetRA) > 1e-6 ||
368 std::abs(m_LastTrackingDec - m_targetDEC) > 1e-6;
370 if (!m_IsPipelinePrimed || targetChanged)
372 getAltAz(JDnow - JDoffset, m_TrackingWindowCoords[0]);
373 getAltAz(JDnow, m_TrackingWindowCoords[1]);
374 getAltAz(JDnow + JDoffset, m_TrackingWindowCoords[2]);
375 m_IsPipelinePrimed =
true;
376 m_LastTrackingRA = m_targetRA;
377 m_LastTrackingDec = m_targetDEC;
381 m_TrackingWindowCoords[0] = m_TrackingWindowCoords[1];
382 m_TrackingWindowCoords[1] = m_TrackingWindowCoords[2];
383 getAltAz(JDnow + JDoffset, m_TrackingWindowCoords[2]);
392 double pAz[3] = { m_TrackingWindowCoords[0].
azimuth,
393 m_TrackingWindowCoords[1].
azimuth,
394 m_TrackingWindowCoords[2].
azimuth
396 pAz[0] = pAz[1] +
range180(pAz[0] - pAz[1]);
397 pAz[2] = pAz[1] +
range180(pAz[2] - pAz[1]);
400 double az_a = (pAz[2] + pAz[0] - 2.0 * pAz[1]) / 2.0;
401 double az_b = (pAz[2] - pAz[0]) / 2.0;
402 double alt_a = (m_TrackingWindowCoords[2].
altitude + m_TrackingWindowCoords[0].
altitude
403 - 2.0 * m_TrackingWindowCoords[1].
altitude) / 2.0;
404 double alt_b = (m_TrackingWindowCoords[2].
altitude - m_TrackingWindowCoords[0].
altitude) / 2.0;
407 double targetAzNext = az_a + az_b + pAz[1];
408 double targetAltNext = alt_a + alt_b + m_TrackingWindowCoords[1].
altitude;
411 double azRate =
range180(targetAzNext - m_currentAz) / dt * 3600.0;
412 double altRate = (targetAltNext - m_currentAlt) / dt * 3600.0;
423 Angle trueRa, trueDec;
425 EqPENP[PE_RA].setValue(trueRa.
Hours());
426 EqPENP[PE_DEC].setValue(trueDec.
Degrees());
433 updateCurrentCoordsFromAxes();
457 LOG_INFO(
"Telescope slew is complete. Parked");
477 LOG_INFO(
"Telescope slew is complete. Tracking...");
483 Angle tPrimary, tSecondary;
485 double dPri = (axisPrimary.
position - tPrimary).Degrees();
486 double dSec = (axisSecondary.
position - tSecondary).Degrees();
487 LOGF_DEBUG(
"slew accuracy pri %f arcsec, sec %f arcsec", dPri * 3600, dSec * 3600);
498 if (guidingEW && !axisPrimary.
IsGuiding())
506 if (guidingNS && !axisSecondary.
IsGuiding())
518 if (std::fabs(mountAxisNP[PRIMARY].getValue() - PrimaryAngle) > 0.0001 ||
519 std::fabs(mountAxisNP[SECONDARY].getValue() - SecondaryAngle) > 0.0001)
521 mountAxisNP[PRIMARY].setValue(PrimaryAngle);
522 mountAxisNP[SECONDARY].setValue(SecondaryAngle);
531 char RAStr[64], DecStr[64];
532 fs_sexa(RAStr, m_currentRA, 2, 3600);
533 fs_sexa(DecStr, m_currentDEC, 2, 3600);
534 DEBUGF(DBG_SCOPE,
"Current RA: %s Current DEC: %s", RAStr, DecStr);
536 NewRaDec(m_currentRA, m_currentDEC);
555 double instrumentAlt, instrumentAz_INDI;
563 setTargetFromAxisPosition(
Angle(instrumentAz_INDI),
Angle(instrumentAlt));
567 LOGF_INFO(
"Slewing to RA: %.4f Dec: %.4f", m_targetRA, m_targetDEC);
572 double targetRA = r, targetDec = d;
584 LOGF_INFO(
"EQ Goto: alignment corrected RA %.4fh Dec %.4f -> RA %.4fh Dec %.4f",
585 r, d, targetRA, targetDec);
589 LOG_WARN(
"EQ Goto: TransformCelestialToTelescope FAILED, using raw coordinates");
627 Angle instHA, instDec;
631 double encoderRA = (alignment.
lst() - instHA).Hours();
644 LOG_WARN(
"Sync not stored in the alignment database: geographic location is not known yet.");
662 LOGF_INFO(
"Sync replaced %d older alignment point(s) at the same position.", replaced);
668 LOGF_DEBUG(
"Sync at RA %f Dec %f m_targetRA %f m_targetDEC %f",
669 ra,
dec, m_targetRA, m_targetDEC);
674 NewRaDec(m_currentRA, m_currentDEC);
690 setTargetFromAxisPosition(indi_az, alt);
704void ScopeSim::StartSlew(
double ra,
double dec, TelescopeStatus status)
709 Angle primary, secondary;
717 setTargetFromAxisPosition(primary, secondary);
718 char RAStr[64], DecStr[64];
720 fs_sexa(RAStr, m_targetRA, 2, 3600);
721 fs_sexa(DecStr, m_targetDEC, 2, 3600);
723 const char * statusStr;
727 statusStr =
"Parking";
730 statusStr =
"Slewing";
733 statusStr =
"unknown";
737 LOGF_INFO(
"%s to RA: %s - DEC: %s", statusStr, RAStr, DecStr);
754 if (strcmp(name,
"GUIDE_RATE") == 0)
756 GuideRateNP.
update(values, names, n);
765 if (mountModelNP.
isUpdated(values, names, n))
767 mountModelNP.
update(values, names, n);
768 alignment.
setCorrections(mountModelNP[MM_IH].getValue() / 60.0, mountModelNP[MM_ID].getValue() / 60.0,
769 mountModelNP[MM_CH].getValue() / 60.0, mountModelNP[MM_NP].getValue() / 60.0,
770 mountModelNP[MM_MA].getValue() / 60.0, mountModelNP[MM_ME].getValue() / 60.0);
774 mountModelNP.
apply();
780 flipHourAngleNP.
update(values, names, n);
782 flipHourAngleNP.
apply();
788 decBacklashNP.
update(values, names, n);
790 decBacklashNP.
apply();
791 m_DecGuideBacklashMs = decBacklashNP[0].getValue();
816 updateMountAndPierSide();
822 if (!simPierSideSP.
update(states, names, n))
826 simPierSideSP.
apply();
827 updateMountAndPierSide();
848 if (strcmp(name,
"ALIGNMENT_SUBSYSTEM_MATH_PLUGINS") == 0 ||
849 strcmp(name,
"ALIGNMENT_SUBSYSTEM_ACTIVE") == 0)
864 PACDeviceTP.
update(texts, names, n);
867 const char *pacDevice = PACDeviceTP[0].
getText();
868 if (pacDevice && strlen(pacDevice) > 0)
885 const char *pacDevice = PACDeviceTP[0].
getText();
887 if (pacDevice && strlen(pacDevice) > 0 && deviceName && strcmp(deviceName, pacDevice) == 0)
889 if (!strcmp(propName,
"PAC_MANUAL_ADJUSTMENT"))
898 if (!strcmp(elemName,
"MANUAL_AZ_STEP"))
900 else if (!strcmp(elemName,
"MANUAL_ALT_STEP"))
906 if (!strcmp(stateStr,
"Ok"))
912 double oldMA = mountModelNP[MM_MA].getValue();
913 double oldME = mountModelNP[MM_ME].getValue();
914 double newMA = oldMA + m_snoopedAzError * 60.0;
915 double newME = oldME + m_snoopedAltError * 60.0;
917 mountModelNP[MM_MA].setValue(newMA);
918 mountModelNP[MM_ME].setValue(newME);
919 alignment.
setCorrections(mountModelNP[MM_IH].getValue() / 60.0, mountModelNP[MM_ID].getValue() / 60.0,
920 mountModelNP[MM_CH].getValue() / 60.0, mountModelNP[MM_NP].getValue() / 60.0,
921 mountModelNP[MM_MA].getValue() / 60.0, mountModelNP[MM_ME].getValue() / 60.0);
924 mountModelNP.
apply();
926 LOGF_INFO(
"Applied PAC correction: MA %.4f -> %.4f, ME %.4f -> %.4f (arcmin)",
927 oldMA, newMA, oldME, newME);
932 updateCurrentCoordsFromAxes();
933 NewRaDec(m_currentRA, m_currentDEC);
945 axisSecondary.
Abort();
955 LOG_ERROR(
"Please unpark the mount before issuing any motion commands.");
959 mcRate = std::max(1, std::min(4, mcRate));
964 LOGF_DEBUG(
"MoveNS dir %s, motion %s, rate %d", dir ==
DIRECTION_NORTH ?
"N" :
"S", command == 0 ?
"start" :
"stop", rate);
975 LOG_ERROR(
"Please unpark the mount before issuing any motion commands.");
980 mcRate = std::max(1, std::min(4, mcRate));
983 LOGF_DEBUG(
"MoveWE dir %d, motion %s, rate %d", dir ==
DIRECTION_EAST ?
"E" :
"W", command == 0 ?
"start" :
"stop", rate);
989uint32_t ScopeSim::backlashComputation(uint32_t ms)
991 if (m_DecGuideRemainingBacklash <= 0)
993 m_DecGuideRemainingBacklash = 0;
995 else if (m_DecGuideRemainingBacklash >= ms)
997 m_DecGuideRemainingBacklash -= ms;
1002 ms -= m_DecGuideRemainingBacklash;
1003 m_DecGuideRemainingBacklash = 0;
1008uint32_t ScopeSim::applyDecBacklash(
double rate, uint32_t ms)
1010 const bool changingDirections = (rate < 0 && m_GuideDecLastNorth) ||
1011 (rate > 0 && !m_GuideDecLastNorth);
1012 m_GuideDecLastNorth = rate >= 0;
1014 if (!changingDirections)
1016 ms = backlashComputation(ms);
1021 if (m_DecGuideRemainingBacklash <= 0)
1022 m_DecGuideRemainingBacklash = m_DecGuideBacklashMs;
1023 else if (m_DecGuideRemainingBacklash >= m_DecGuideBacklashMs)
1024 m_DecGuideRemainingBacklash = 0;
1026 m_DecGuideRemainingBacklash = m_DecGuideBacklashMs - m_DecGuideRemainingBacklash;
1028 ms = backlashComputation(ms);
1033void ScopeSim::guideAltAzDecomposed(
double dNS,
double dEW, uint32_t ms)
1044 double H = (alignment.
lst() -
Angle(m_currentRA * 15.0)).radians();
1047 double alt = m_currentAlt *
M_PI / 180.0;
1048 double cosAlt = std::cos(alt);
1050 if (std::abs(cosAlt) > 1e-4)
1052 double sinQ = std::sin(H) * std::cos(lat) / cosAlt;
1053 double cosQ = (std::sin(lat) - std::sin(
dec) * std::sin(alt))
1054 / (std::cos(
dec) * cosAlt);
1056 double dAlt_N = cosQ;
1057 double dAz_N = -sinQ / cosAlt;
1058 double dAlt_E = sinQ;
1059 double dAz_E = cosQ / cosAlt;
1061 axisPrimary.
StartGuide(dNS * dAz_N + dEW * dAz_E, ms);
1062 axisSecondary.
StartGuide(dNS * dAlt_N + dEW * dAlt_E, ms);
1076 guideAltAzDecomposed(GuideRateNP[
DEC_AXIS].getValue(), 0.0, ms);
1080 double rate = GuideRateNP[
DEC_AXIS].getValue();
1083 ms = applyDecBacklash(rate, ms);
1094 guideAltAzDecomposed(-GuideRateNP[
DEC_AXIS].getValue(), 0.0, ms);
1098 double rate = GuideRateNP[
DEC_AXIS].getValue();
1101 ms = applyDecBacklash(-rate, ms);
1111 guideAltAzDecomposed(0.0, -GuideRateNP[
RA_AXIS].getValue(), ms);
1121 guideAltAzDecomposed(0.0, GuideRateNP[
RA_AXIS].getValue(), ms);
1184 m_IsPipelinePrimed =
false;
1204 GuideRateNP.
save(fp);
1206 simPierSideSP.
save(fp);
1207 mountModelNP.
save(fp);
1208 flipHourAngleNP.
save(fp);
1209 decBacklashNP.
save(fp);
1210 PACDeviceTP.
save(fp);
1218 LOGF_DEBUG(
"Update location %8.3f, %8.3f, %4.0f", latitude, longitude, elevation);
1233 alignment.
clockOffsetDays = ln_get_julian_day(utc) - ln_get_julian_from_sys();
1238bool ScopeSim::updateMountAndPierSide()
1243 if (mountType < 0 || pierSide < 0)
1247 if (mountType == m_MountType && pierSide == m_PierSide)
1250 const int previousMountType = m_MountType;
1251 m_MountType = mountType;
1252 m_PierSide = pierSide;
1254 LOGF_INFO(
"update mount and pier side: Pier Side %s, mount type %d", pierSide == 0 ?
"Off" :
"On", mountType);
1257 int pierSide = PS_ON;
1261 LOG_INFO(
"AltAz mount type experimental");
1285 LOGF_WARN(
"Mount type changed between ALTAZ and equatorial: clearing %d alignment sync point(s) "
1328 LOG_INFO(
"Finding home position...");
1337 LOG_INFO(
"Setting home position to current position.");
1342 LOG_INFO(
"Going to home position.");
void setCorrections(double ih, double id, double ch, double np, double ma, double me)
setCorrections set the values of the six corrections
void instrumentHaDecToMount(Angle instrumentHa, Angle instrumentDec, Angle *primary, Angle *secondary)
void mountToApparentRaDec(Angle primary, Angle secondary, Angle *apparentRa, Angle *apparentDec)
mountToApparentRaDec: convert mount position to apparent Ra, Dec
void setFlipHourAngle(double deg)
void mountToInstrumentHaDec(Angle primary, Angle secondary, Angle *instrumentHa, Angle *instrumentDec)
mountToInstrumentHaDec: convert mount axis positions to instrument (encoder) HA/Dec without applying ...
The Angle class This class implements an angle type. This holds an angle that is always in the range ...
Angle TrackingRateDegSec
TrackingRateDegSec.
void setDegrees(double degrees)
void StartGuide(double rate, uint32_t durationMs)
StartGuide start guiding.
void Tracking(bool enabled)
void StartSlew(Angle angle)
void TrackRate(AXIS_TRACK_RATE rate)
TrackRate set the track rate to one of the standard rates.
void ProcessAlignmentNumberProperties(Telescope *pTelescope, const char *name, double values[], char *names[], int n)
Call this function from within the ISNewNumber processing path. The function will handle any alignmen...
bool SkyToTelescopeAltAz(double actualRA, double actualDec, double &mountAlt, double &mountAz, double JD=ln_get_julian_from_sys())
Converts an actual sky location to coordinates to send to the mount, usually called in Goto.
void ProcessAlignmentSwitchProperties(Telescope *pTelescope, const char *name, ISState *states, char *names[], int n)
Call this function from within the ISNewSwitch processing path. The function will handle any alignmen...
void InitAlignmentProperties(Telescope *pTelescope)
Initialize alignment subsystem properties. It is recommended to call this function within initPropert...
bool TelescopeAltAzToSky(double mountAlt, double mountAz, double &actualRA, double &actualDec, double JD=ln_get_julian_from_sys())
Converts a mount location to actual sky coordinates, usually called in ReadScopeStatus.
bool AddAlignmentEntryAltAz(double actualRA, double actualDec, double mountAlt, double mountAz, double JD=ln_get_julian_from_sys())
Adds an alignment point to the model database, usually called from Sync.
void SaveAlignmentConfigProperties(FILE *fp)
Call this function to save persistent alignment related properties. This function should be called fr...
void ProcessAlignmentTextProperties(Telescope *pTelescope, const char *name, char *texts[], char *names[], int n)
Call this function from within the ISNewText processing path. The function will handle any alignment ...
void RemoveSyncPoint(const AlignmentDatabaseEntry &CandidateEntry, double Tolerance=0.1)
Remove a sync point that falls within the tolerance of a candidate point.
AlignmentDatabaseType & GetAlignmentDatabase()
Get a reference to the in memory database.
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
void UpdateLocation(double latitude, double longitude, double elevation)
Call this function from within the updateLocation processing path.
void UpdateSize()
Call this function when the number of entries in the database changes.
The following INDI properties are used to manage math plugins.
bool TransformTelescopeToCelestialJD(const TelescopeDirectionVector &ApparentTelescopeDirectionVector, double &RightAscension, double &Declination, double JulianDate)
TransformTelescopeToCelestialJD Transforms Mount Coords to Celestial (Sky) Coordinates.
bool TransformCelestialToTelescopeJD(double RightAscension, double Declination, double JulianDate, TelescopeDirectionVector &ApparentTelescopeDirectionVector)
TransformCelestialToTelescopeJD Transforms Celestial (Sky) Coords to Mount Coordinates.
bool Initialise(InMemoryDatabase *pInMemoryDatabase)
Initialise or re-initialise the math plugin. Re-reading the in memory database as necessary.
void SetAlignmentSubsystemActive(bool enable)
SetAlignmentSubsystemActive Enable or Disable alignment subsystem.
void SetApproximateMountAlignmentFromMountType(MountType_t Type)
Call this function to set the ApproximateMountAlignment property of the current Math Plugin....
const TelescopeDirectionVector TelescopeDirectionVectorFromAltitudeAzimuth(INDI::IHorizontalCoordinates HorizontalCoordinates)
Calculates a normalised direction vector from the supplied altitude and azimuth.
void EquatorialCoordinatesFromTelescopeDirectionVector(const TelescopeDirectionVector TelescopeDirectionVector, INDI::IEquatorialCoordinates &EquatorialCoordinates)
Calculates equatorial coordinates from the supplied telescope direction vector and declination.
const TelescopeDirectionVector TelescopeDirectionVectorFromEquatorialCoordinates(INDI::IEquatorialCoordinates EquatorialCoordinates)
Calculates a telescope direction vector from the supplied equatorial coordinates.
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in 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 getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
uint32_t getDriverInterface() const
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
virtual void GuideComplete(INDI_EQ_AXIS axis)
Call GuideComplete once the guiding pulse is complete.
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
INDI::PropertyNumber GuideWENP
void initProperties(const char *groupName)
Initialize guider properties. It is recommended to call this function within initProperties() of your...
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Call this function whenever client updates GuideNSNP or GuideWSP properties in the primary device....
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool load()
load Attempt to load property values from configuration file.
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
bool isUpdated(const double values[], const char *const names[], int n) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
bool update(const char *const texts[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
INDI::PropertyViewText * getText() const
TelescopeStatus TrackState
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
void SetAxis1ParkDefault(double steps)
SetRAPark Set default RA/AZ parking position.
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.
double GetAxis1Park() const
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...
double GetAxis2Park() const
bool isParked()
isParked is mount currently parked?
virtual int AddTrackMode(const char *name, const char *label, bool isDefault=false)
AddTrackMode.
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.
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
@ TELESCOPE_CAN_HOME_FIND
@ TELESCOPE_HAS_TRACK_RATE
@ TELESCOPE_HAS_PIER_SIDE
@ TELESCOPE_HAS_TRACK_MODE
@ TELESCOPE_CAN_CONTROL_TRACK
IGeographicCoordinates m_Location
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.
void setPierSide(TelescopePierSide side)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
void SetAxis2Park(double steps)
SetDEPark Set current DEC/ALT parking position. The data park file (stored in ~/.indi/ParkData....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
void SetAxis2ParkDefault(double steps)
SetDEParkDefault Set default DEC/ALT parking position.
The ScopeSim class provides a simple mount simulator of an equatorial mount.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
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.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState ExecuteHomeAction(TelescopeHomeAction action) override
Execute a homing action.
virtual const char * getDefaultName() override
virtual bool Disconnect() override
Disconnect from device.
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 updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
virtual bool Goto(double, double) override
Move the scope to the supplied RA and DEC coordinates.
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 Park() override
Park the telescope to its home position.
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool SetTrackRate(double raRate, double deRate) override
SetTrackRate Set custom tracking rates.
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual IPState GuideEast(uint32_t ms) override
Guide east for ms milliseconds. East is defined as RA+.
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.
TelescopePierSide currentPierSide
INDI::PropertyNumber TrackRateNP
INDI::PropertyNumber EqNP
INDI::PropertySwitch HomeSP
INDI::PropertySwitch SlewRateSP
INDI::PropertySwitch TrackModeSP
INDI::PropertySwitch MountTypeSP
void sendTimeFromSystem()
INDI::PropertyNumber LocationNP
INDI::PropertyNumber ParkPositionNP
double range180(double r)
range180 Limits an angle to be between -180 to +180 degrees
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 IDSnoopDevice(const char *snooped_device, const char *snooped_property)
Function a Driver calls to snoop on another Device. Snooped messages will then arrive via ISSnoopDevi...
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(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_EXTRA1(fmt,...)
#define DEBUGF(priority, msg,...)
#define TRACKRATE_SIDEREAL
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
A little DOM-style library to handle parsing and processing an XML file.
Namespace to encapsulate the INDI Alignment Subsystem classes. For more information see "INDI Alignme...
Namespace to encapsulate INDI client, drivers, and mediator classes.
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.
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 normalised direction vector (direction cosines)
static Logger & getInstance()
Method to get a reference to the object (i.e., Singleton) It is a static method.
int addDebugLevel(const char *debugLevelName, const char *LoggingLevelName)
Adds a new debugging level to the driver.