9 #include "ksmessagebox.h"
10 #include "driverinfo.h"
14 #include "skymapcomposite.h"
15 #include "ksnotification.h"
17 #include <KActionCollection>
18 #include <KLocalizedString>
21 #include <qdbusmetatype.h>
23 #include <indi_debug.h>
36 Mount::Mount(GenericDevice *parent) : ConcreteDevice(parent)
39 centerLockTimer.setInterval(5000);
40 centerLockTimer.setSingleShot(
true);
48 updateCoordinatesTimer.setInterval(1000);
49 updateCoordinatesTimer.setSingleShot(
false);
54 currentCoords.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->
geo()->lat());
55 emit newCoords(currentCoords, pierSide(), hourAngle());
59 qRegisterMetaType<ISD::Mount::Status>(
"ISD::Mount::Status");
60 qDBusRegisterMetaType<ISD::Mount::Status>();
62 qRegisterMetaType<ISD::Mount::PierSide>(
"ISD::Mount::PierSide");
63 qDBusRegisterMetaType<ISD::Mount::PierSide>();
71 void Mount::registerProperty(INDI::Property prop)
73 if (prop.isNameMatch(
"TELESCOPE_INFO"))
75 auto ti = prop.getNumber();
80 bool aperture_ok =
false, focal_ok =
false;
83 auto aperture = ti->findWidgetByName(
"TELESCOPE_APERTURE");
84 if (aperture && aperture->getValue() <= 0)
86 if (getDriverInfo()->getAuxInfo().contains(
"TELESCOPE_APERTURE"))
88 temp = getDriverInfo()->getAuxInfo().value(
"TELESCOPE_APERTURE").toDouble(&aperture_ok);
91 aperture->setValue(temp);
92 auto g_aperture = ti->findWidgetByName(
"GUIDER_APERTURE");
93 if (g_aperture && g_aperture->getValue() <= 0)
94 g_aperture->setValue(aperture->getValue());
99 auto focal_length = ti->findWidgetByName(
"TELESCOPE_FOCAL_LENGTH");
100 if (focal_length && focal_length->getValue() <= 0)
102 if (getDriverInfo()->getAuxInfo().contains(
"TELESCOPE_FOCAL_LENGTH"))
104 temp = getDriverInfo()->getAuxInfo().value(
"TELESCOPE_FOCAL_LENGTH").toDouble(&focal_ok);
107 focal_length->setValue(temp);
108 auto g_focal = ti->findWidgetByName(
"GUIDER_FOCAL_LENGTH");
109 if (g_focal && g_focal->getValue() <= 0)
110 g_focal->setValue(focal_length->getValue());
115 if (aperture_ok && focal_ok)
118 else if (prop.isNameMatch(
"ON_COORD_SET"))
120 m_canGoto = IUFindSwitch(prop.getSwitch(),
"TRACK") !=
nullptr;
121 m_canSync = IUFindSwitch(prop.getSwitch(),
"SYNC") !=
nullptr;
122 m_canFlip = IUFindSwitch(prop.getSwitch(),
"FLIP") !=
nullptr;
124 else if (prop.isNameMatch(
"TELESCOPE_PIER_SIDE"))
126 auto svp = prop.getSwitch();
127 int currentSide = svp->findOnSwitchIndex();
128 if (currentSide != m_PierSide)
130 m_PierSide =
static_cast<PierSide
>(currentSide);
131 emit pierSideChanged(m_PierSide);
134 else if (prop.isNameMatch(
"TELESCOPE_PARK"))
136 else if (prop.isNameMatch(
"TELESCOPE_TRACK_STATE"))
137 m_canControlTrack =
true;
138 else if (prop.isNameMatch(
"TELESCOPE_TRACK_MODE"))
140 m_hasTrackModes =
true;
141 auto svp = prop.getSwitch();
142 for (
int i = 0; i < svp->count(); i++)
144 if (svp->at(i)->isNameMatch(
"TRACK_SIDEREAL"))
145 TrackMap[TRACK_SIDEREAL] = i;
146 else if (svp->at(i)->isNameMatch(
"TRACK_SOLAR"))
147 TrackMap[TRACK_SOLAR] = i;
148 else if (svp->at(i)->isNameMatch(
"TRACK_LUNAR"))
149 TrackMap[TRACK_LUNAR] = i;
150 else if (svp->at(i)->isNameMatch(
"TRACK_CUSTOM"))
151 TrackMap[TRACK_CUSTOM] = i;
154 else if (prop.isNameMatch(
"TELESCOPE_TRACK_RATE"))
155 m_hasCustomTrackRate =
true;
156 else if (prop.isNameMatch(
"TELESCOPE_ABORT_MOTION"))
158 else if (prop.isNameMatch(
"TELESCOPE_PARK_OPTION"))
159 m_hasCustomParking =
true;
160 else if (prop.isNameMatch(
"TELESCOPE_SLEW_RATE"))
162 m_hasSlewRates =
true;
163 auto svp = prop.getSwitch();
167 for (
const auto &it : *svp)
168 m_slewRates << it.getLabel();
171 else if (prop.isNameMatch(
"EQUATORIAL_EOD_COORD"))
174 m_hasEquatorialCoordProperty =
true;
176 else if (prop.isNameMatch(
"SAT_TRACKING_STAT"))
178 m_canTrackSatellite =
true;
180 else if (prop.isNameMatch(
"EQUATORIAL_COORD"))
183 m_hasEquatorialCoordProperty =
true;
187 void Mount::updateJ2000Coordinates(
SkyPoint *coords)
208 void Mount::processNumber(INDI::Property prop)
210 auto nvp = prop.getNumber();
211 if (nvp->isNameMatch(
"EQUATORIAL_EOD_COORD") || nvp->isNameMatch(
"EQUATORIAL_COORD"))
213 auto RA = nvp->findWidgetByName(
"RA");
214 auto DEC = nvp->findWidgetByName(
"DEC");
216 if (RA ==
nullptr || DEC ==
nullptr)
222 currentCoords.
setRA0(RA->value);
223 currentCoords.
setDec0(DEC->value);
228 currentCoords.
setRA(RA->value);
229 currentCoords.
setDec(DEC->value);
238 if (! updateCoordinatesTimer.
isActive())
239 updateCoordinatesTimer.
start();
241 auto currentStatus = status(nvp);
243 if (nvp->getState() == IPS_BUSY && EqCoordPreviousState != IPS_BUSY)
245 if (currentStatus == MOUNT_SLEWING)
246 KSNotification::event(
QLatin1String(
"SlewStarted"),
i18n(
"Mount is slewing to target location"), KSNotification::Mount);
249 else if (EqCoordPreviousState == IPS_BUSY && nvp->getState() == IPS_OK &&
slewDefined())
251 if (Options::useExternalSkyMap())
262 KSNotification::event(
QLatin1String(
"SlewCompleted"),
i18n(
"Mount arrived at target location"), KSNotification::Mount);
267 EqCoordPreviousState = nvp->getState();
275 else if (nvp->isNameMatch(
"HORIZONTAL_COORD") && m_hasEquatorialCoordProperty ==
false)
277 auto Az = nvp->findWidgetByName(
"AZ");
278 auto Alt = nvp->findWidgetByName(
"ALT");
280 if (Az ==
nullptr || Alt ==
nullptr)
283 currentCoords.
setAz(Az->value);
284 currentCoords.
setAlt(Alt->value);
292 if (! updateCoordinatesTimer.
isActive())
293 updateCoordinatesTimer.
start();
297 else if (nvp->isNameMatch(
"POLLING_PERIOD"))
300 auto period = nvp->findWidgetByName(
"PERIOD_MS");
301 if (period !=
nullptr)
302 updateCoordinatesTimer.
setInterval(
static_cast<int>(period->getValue()));
307 void Mount::processSwitch(INDI::Property prop)
309 bool manualMotionChanged =
false;
310 auto svp = prop.getSwitch();
312 if (svp->isNameMatch(
"CONNECTION"))
314 auto conSP = svp->findWidgetByName(
"CONNECT");
320 if (conSP->getState() == ISS_ON)
325 centerLockTimer.
stop();
329 else if (svp->isNameMatch(
"TELESCOPE_PARK"))
331 else if (svp->isNameMatch(
"TELESCOPE_ABORT_MOTION"))
333 if (svp->s == IPS_OK)
335 inCustomParking =
false;
336 KSNotification::event(
QLatin1String(
"MountAborted"),
i18n(
"Mount motion was aborted"), KSNotification::Mount,
337 KSNotification::Warn);
340 else if (svp->isNameMatch(
"TELESCOPE_PIER_SIDE"))
342 int currentSide = IUFindOnSwitchIndex(svp);
343 if (currentSide != m_PierSide)
345 m_PierSide =
static_cast<PierSide
>(currentSide);
346 emit pierSideChanged(m_PierSide);
349 else if (svp->isNameMatch(
"TELESCOPE_TRACK_MODE"))
351 auto sp = svp->findOnSwitch();
354 if (sp->isNameMatch(
"TRACK_SIDEREAL"))
355 currentTrackMode = TRACK_SIDEREAL;
356 else if (sp->isNameMatch(
"TRACK_SOLAR"))
357 currentTrackMode = TRACK_SOLAR;
358 else if (sp->isNameMatch(
"TRACK_LUNAR"))
359 currentTrackMode = TRACK_LUNAR;
361 currentTrackMode = TRACK_CUSTOM;
364 else if (svp->isNameMatch(
"TELESCOPE_MOTION_NS"))
365 manualMotionChanged =
true;
366 else if (svp->isNameMatch(
"TELESCOPE_MOTION_WE"))
367 manualMotionChanged =
true;
368 else if (svp->isNameMatch(
"TELESCOPE_REVERSE_MOTION"))
370 emit axisReversed(AXIS_DE, svp->at(0)->getState() == ISS_ON);
371 emit axisReversed(AXIS_RA, svp->at(1)->getState() == ISS_ON);
374 if (manualMotionChanged)
376 auto NSCurrentMotion =
getSwitch(
"TELESCOPE_MOTION_NS")->getState();
377 auto WECurrentMotion =
getSwitch(
"TELESCOPE_MOTION_WE")->getState();
378 inCustomParking =
false;
379 inManualMotion = (NSCurrentMotion == IPS_BUSY || WECurrentMotion == IPS_BUSY);
383 void Mount::processText(INDI::Property prop)
385 auto tvp = prop.getText();
386 if (tvp->isNameMatch(
"SAT_TLE_TEXT"))
388 if ((tvp->getState() == IPS_OK) && (m_TLEIsSetForTracking))
390 auto trajWindow =
getText(
"SAT_PASS_WINDOW");
393 qCDebug(KSTARS_INDI) <<
"Property SAT_PASS_WINDOW not found";
397 auto trajStart = trajWindow->findWidgetByName(
"SAT_PASS_WINDOW_START");
398 auto trajEnd = trajWindow->findWidgetByName(
"SAT_PASS_WINDOW_END");
400 if (!trajStart || !trajEnd)
402 qCDebug(KSTARS_INDI) <<
"Start or end in SAT_PASS_WINDOW not found";
410 m_windowIsSetForTracking =
true;
415 else if (tvp->isNameMatch(
"SAT_PASS_WINDOW"))
417 if ((tvp->getState() == IPS_OK) && (m_TLEIsSetForTracking) && (m_windowIsSetForTracking))
419 auto trackSwitchV =
getSwitch(
"SAT_TRACKING_STAT");
422 qCDebug(KSTARS_INDI) <<
"Property SAT_TRACKING_STAT not found";
426 auto trackSwitch = trackSwitchV->findWidgetByName(
"SAT_TRACK");
429 trackSwitchV->reset();
430 trackSwitch->setState(ISS_ON);
433 m_TLEIsSetForTracking =
false;
434 m_windowIsSetForTracking =
false;
447 auto sp = svp->findWidgetByName(
"PARK");
450 if (svp->getState() == IPS_ALERT)
453 emit newParkStatus(PARK_ERROR);
456 m_ParkStatus = (sp->getState() == ISS_ON) ? PARK_PARKED : PARK_UNPARKED;
457 KSNotification::event(
QLatin1String(
"MountParkingFailed"),
i18n(
"Mount parking failed"), KSNotification::Mount,
458 KSNotification::Alert);
460 else if (svp->getState() == IPS_BUSY && sp->s == ISS_ON && m_ParkStatus != PARK_PARKING)
462 m_ParkStatus = PARK_PARKING;
463 KSNotification::event(
QLatin1String(
"MountParking"),
i18n(
"Mount parking is in progress"), KSNotification::Mount);
464 currentObject =
nullptr;
466 emit newParkStatus(m_ParkStatus);
468 else if (svp->getState() == IPS_BUSY && sp->getState() == ISS_OFF && m_ParkStatus != PARK_UNPARKING)
470 m_ParkStatus = PARK_UNPARKING;
471 KSNotification::event(
QLatin1String(
"MountUnParking"),
i18n(
"Mount unparking is in progress"), KSNotification::Mount);
473 emit newParkStatus(m_ParkStatus);
475 else if (svp->getState() == IPS_OK && sp->getState() == ISS_ON && m_ParkStatus != PARK_PARKED)
477 m_ParkStatus = PARK_PARKED;
478 KSNotification::event(
QLatin1String(
"MountParked"),
i18n(
"Mount parked"), KSNotification::Mount);
479 currentObject =
nullptr;
481 emit newParkStatus(m_ParkStatus);
492 else if ( (svp->getState() == IPS_OK || svp->getState() == IPS_IDLE) && sp->getState() == ISS_OFF
493 && m_ParkStatus != PARK_UNPARKED)
495 m_ParkStatus = PARK_UNPARKED;
496 KSNotification::event(
QLatin1String(
"MountUnparked"),
i18n(
"Mount unparked"), KSNotification::Mount);
497 currentObject =
nullptr;
499 emit newParkStatus(m_ParkStatus);
510 bool Mount::canGuide()
512 auto raPulse = getNumber(
"TELESCOPE_TIMED_GUIDE_WE");
513 auto decPulse = getNumber(
"TELESCOPE_TIMED_GUIDE_NS");
515 return raPulse && decPulse;
518 bool Mount::canPark()
520 auto parkSP =
getSwitch(
"TELESCOPE_PARK");
525 auto parkSW = parkSP->findWidgetByName(
"PARK");
527 return (parkSW !=
nullptr);
530 bool Mount::isSlewing()
532 auto EqProp = getNumber(
"EQUATORIAL_EOD_COORD");
537 return (EqProp->getState() == IPS_BUSY);
540 bool Mount::isInMotion()
542 return (isSlewing() || inManualMotion);
545 bool Mount::doPulse(GuideDirection ra_dir,
int ra_msecs, GuideDirection dec_dir,
int dec_msecs)
547 if (canGuide() ==
false)
550 bool raOK = doPulse(ra_dir, ra_msecs);
551 bool decOK = doPulse(dec_dir, dec_msecs);
553 return raOK && decOK;
556 bool Mount::doPulse(GuideDirection dir,
int msecs)
558 auto raPulse = getNumber(
"TELESCOPE_TIMED_GUIDE_WE");
559 auto decPulse = getNumber(
"TELESCOPE_TIMED_GUIDE_NS");
560 INDI::PropertyView<INumber> *npulse =
nullptr;
561 INDI::WidgetView<INumber> *dirPulse =
nullptr;
563 if (!raPulse || !decPulse)
570 dirPulse = npulse->findWidgetByName(
"TIMED_GUIDE_W");
575 dirPulse = npulse->findWidgetByName(
"TIMED_GUIDE_E");
580 dirPulse = npulse->findWidgetByName(
"TIMED_GUIDE_N");
585 dirPulse = npulse->findWidgetByName(
"TIMED_GUIDE_S");
595 dirPulse->setValue(msecs);
603 void Mount::setCustomParking(
SkyPoint * coords)
606 if (coords ==
nullptr)
611 inCustomParking = rc;
617 double maxrad = 1000.0 / Options::zoomFactor();
622 void Mount::centerLock()
624 if (Options::isTracking() ==
false ||
631 Options::setIsTracking(
true);
633 centerLockTimer.
start();
636 void Mount::centerUnlock()
639 centerLockTimer.
stop();
644 INumber *RAEle =
nullptr;
645 INumber *DecEle =
nullptr;
646 INumber *AzEle =
nullptr;
647 INumber *AltEle =
nullptr;
648 double currentRA = 0, currentDEC = 0, currentAlt = 0, currentAz = 0;
649 bool useJ2000(
false);
651 auto EqProp = getNumber(
"EQUATORIAL_EOD_COORD");
655 EqProp = getNumber(
"EQUATORIAL_COORD");
660 auto HorProp = getNumber(
"HORIZONTAL_COORD");
662 if (EqProp && EqProp->getPermission() == IP_RO)
665 if (HorProp && HorProp->getPermission() == IP_RO)
672 RAEle = EqProp->findWidgetByName(
"RA");
676 DecEle = EqProp->findWidgetByName(
"DEC");
683 currentRA = RAEle->value;
684 currentDEC = DecEle->value;
691 AzEle = IUFindNumber(HorProp,
"AZ");
694 AltEle = IUFindNumber(HorProp,
"ALT");
698 currentAz = AzEle->value;
699 currentAlt = AltEle->value;
703 if (EqProp ==
nullptr && HorProp ==
nullptr)
708 auto sendToMountDevice = [ = ]()
731 ScopeTarget->
setRA0(ScopeTarget->
ra());
734 ra = ScopeTarget->
ra();
735 de = ScopeTarget->
dec();
739 ra = ScopeTarget->
ra0();
740 de = ScopeTarget->
dec0();
745 ra = ScopeTarget->
ra();
746 de = ScopeTarget->
dec();
749 RAEle->value = ra.
Hours();
753 qCDebug(KSTARS_INDI) <<
"ISD:Telescope sending coords RA:" << ra.
toHMSString() <<
754 "(" << RAEle->value <<
") DE:" << de.
toDMSString() <<
755 "(" << DecEle->value <<
")";
757 RAEle->value = currentRA;
758 DecEle->value = currentDEC;
763 AzEle->value = ScopeTarget->
az().
Degrees();
766 AzEle->value = currentAz;
767 AltEle->value = currentAlt;
776 auto checkObjectAndSend = [ = ]()
783 auto checkTrackModes = [ = ]()
788 if (currentObject->
type() == SkyObject::MOON)
790 if (currentTrackMode != TRACK_LUNAR && TrackMap.
contains(TRACK_LUNAR))
791 setTrackMode(TrackMap.
value(TRACK_LUNAR));
794 else if (currentObject->
name() ==
i18n(
"Sun"))
796 if (currentTrackMode != TRACK_SOLAR && TrackMap.
contains(TRACK_SOLAR))
797 setTrackMode(TrackMap.
value(TRACK_SOLAR));
802 else if (currentTrackMode == TRACK_SOLAR || currentTrackMode == TRACK_LUNAR)
803 setTrackMode(TRACK_SIDEREAL);
809 if (currentObject->
name() ==
i18n(
"Sun") && currentTrackMode != TRACK_SOLAR)
822 KSMessageBox::Instance()->questionYesNo(
823 i18n(
"Warning! Looking at the Sun without proper protection can lead to irreversible eye damage!"),
824 i18n(
"Sun Warning"));
839 if ((-90 <= minAlt && maxAlt <= 90) && (targetAlt < minAlt || targetAlt > maxAlt))
842 i18n(
"Requested altitude %1 is outside the specified altitude limit boundary (%2,%3).",
844 QString::number(maxAlt,
'g', 3)), KSNotification::Mount, KSNotification::Warn);
845 qCInfo(KSTARS_INDI) <<
"Requested altitude " <<
QString::number(targetAlt,
'g', 3)
846 <<
" is outside the specified altitude limit boundary ("
852 if (Options::confirmBelowHorizon() && targetAlt < 0 && minAlt == -1)
856 if (minAlt < -90 && +90 < maxAlt)
857 Options::setConfirmBelowHorizon(
false);
859 checkObjectAndSend();
866 RAEle->value = currentRA;
867 DecEle->value = currentDEC;
871 AzEle->value = currentAz;
872 AltEle->value = currentAlt;
876 KSMessageBox::Instance()->questionYesNo(
i18n(
"Requested altitude is below the horizon. Are you sure you want to proceed?"),
877 i18n(
"Telescope Motion"), 15,
false);
880 checkObjectAndSend();
887 auto motionSP =
getSwitch(
"ON_COORD_SET");
889 if (motionSP ==
nullptr)
893 auto sp = motionSP->findOnSwitch();
895 (sp->name == std::string(
"TRACK") ||
896 sp->name == std::string(
"SLEW") ||
897 sp->name == std::string(
"FLIP")))
907 bool Mount::Slew(
double ra,
double dec,
bool flip)
922 return Slew(&target, flip);
925 bool Mount::Slew(
SkyPoint * ScopeTarget,
bool flip)
927 auto motionSP =
getSwitch(
"ON_COORD_SET");
932 auto slewSW = flip ? motionSP->findWidgetByName(
"FLIP") : motionSP->findWidgetByName(
"TRACK");
934 if (flip && (!slewSW))
935 slewSW = motionSP->findWidgetByName(
"TRACK");
938 slewSW = motionSP->findWidgetByName(
"SLEW");
943 if (slewSW->getState() != ISS_ON)
946 slewSW->setState(ISS_ON);
949 qCDebug(KSTARS_INDI) <<
"ISD:Telescope: " << slewSW->getName();
955 bool Mount::Sync(
double ra,
double dec)
962 return Sync(&target);
965 bool Mount::Sync(
SkyPoint * ScopeTarget)
967 auto motionSP =
getSwitch(
"ON_COORD_SET");
972 auto syncSW = motionSP->findWidgetByName(
"SYNC");
977 if (syncSW->getState() != ISS_ON)
980 syncSW->setState(ISS_ON);
983 qCDebug(KSTARS_INDI) <<
"ISD:Telescope: Syncing...";
991 auto motionSP =
getSwitch(
"TELESCOPE_ABORT_MOTION");
996 auto abortSW = motionSP->findWidgetByName(
"ABORT");
1001 qCDebug(KSTARS_INDI) <<
"ISD:Telescope: Aborted." <<
Qt::endl;
1003 abortSW->setState(ISS_ON);
1006 inCustomParking =
false;
1013 auto parkSP =
getSwitch(
"TELESCOPE_PARK");
1018 auto parkSW = parkSP->findWidgetByName(
"PARK");
1023 qCDebug(KSTARS_INDI) <<
"ISD:Telescope: Parking..." <<
Qt::endl;
1026 parkSW->setState(ISS_ON);
1032 bool Mount::unpark()
1034 auto parkSP =
getSwitch(
"TELESCOPE_PARK");
1039 auto parkSW = parkSP->findWidgetByName(
"UNPARK");
1044 qCDebug(KSTARS_INDI) <<
"ISD:Telescope: UnParking..." <<
Qt::endl;
1047 parkSW->setState(ISS_ON);
1053 bool Mount::getEqCoords(
double * ra,
double * dec)
1055 auto EqProp = getNumber(
"EQUATORIAL_EOD_COORD");
1058 EqProp = getNumber(
"EQUATORIAL_COORD");
1063 auto RAEle = EqProp->findWidgetByName(
"RA");
1067 auto DecEle = EqProp->findWidgetByName(
"DEC");
1071 *ra = RAEle->getValue();
1072 *
dec = DecEle->getValue();
1077 bool Mount::MoveNS(VerticalMotion dir, MotionCommand cmd)
1079 auto motionSP =
getSwitch(
"TELESCOPE_MOTION_NS");
1084 auto motionNorth = motionSP->findWidgetByName(
"MOTION_NORTH");
1085 auto motionSouth = motionSP->findWidgetByName(
"MOTION_SOUTH");
1087 if (!motionNorth || !motionSouth)
1091 if (dir == MOTION_NORTH && motionNorth->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
1094 if (dir == MOTION_SOUTH && motionSouth->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
1099 if (cmd == MOTION_START)
1101 if (dir == MOTION_NORTH)
1102 motionNorth->setState(ISS_ON);
1104 motionSouth->setState(ISS_ON);
1112 bool Mount::StopWE()
1114 auto motionSP =
getSwitch(
"TELESCOPE_MOTION_WE");
1126 bool Mount::StopNS()
1128 auto motionSP =
getSwitch(
"TELESCOPE_MOTION_NS");
1140 bool Mount::MoveWE(HorizontalMotion dir, MotionCommand cmd)
1142 auto motionSP =
getSwitch(
"TELESCOPE_MOTION_WE");
1147 auto motionWest = motionSP->findWidgetByName(
"MOTION_WEST");
1148 auto motionEast = motionSP->findWidgetByName(
"MOTION_EAST");
1150 if (!motionWest || !motionEast)
1154 if (dir == MOTION_WEST && motionWest->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
1157 if (dir == MOTION_EAST && motionEast->getState() == ((cmd == MOTION_START) ? ISS_ON : ISS_OFF))
1162 if (cmd == MOTION_START)
1164 if (dir == MOTION_WEST)
1165 motionWest->setState(ISS_ON);
1167 motionEast->setState(ISS_ON);
1175 bool Mount::setSlewRate(
int index)
1177 auto slewRateSP =
getSwitch(
"TELESCOPE_SLEW_RATE");
1182 if (index < 0 || index > slewRateSP->count())
1184 else if (slewRateSP->findOnSwitchIndex() == index)
1187 slewRateSP->reset();
1189 slewRateSP->at(index)->setState(ISS_ON);
1193 emit slewRateChanged(index);
1198 int Mount::getSlewRate()
const
1200 auto slewRateSP =
getSwitch(
"TELESCOPE_SLEW_RATE");
1205 return slewRateSP->findOnSwitchIndex();
1208 void Mount::setAltLimits(
double minAltitude,
double maxAltitude)
1210 minAlt = minAltitude;
1211 maxAlt = maxAltitude;
1214 bool Mount::setAlignmentModelEnabled(
bool enable)
1216 bool wasExecuted =
false;
1219 auto alignSwitch =
getSwitch(
"ALIGNMENT_SUBSYSTEM_ACTIVE");
1222 alignSwitch->at(0)->setState(enable ? ISS_ON : ISS_OFF);
1231 alignSwitch->reset();
1234 alignSwitch->at(2)->setState(ISS_ON);
1237 alignSwitch->at(0)->setState(ISS_ON);
1248 auto tleTextVec =
getText(
"SAT_TLE_TEXT");
1251 qCDebug(KSTARS_INDI) <<
"Property SAT_TLE_TEXT not found";
1255 auto tleText = tleTextVec->findWidgetByName(
"TLE");
1262 m_TLEIsSetForTracking =
true;
1263 g_satPassStart = satPassStart;
1264 g_satPassEnd = satPassEnd;
1270 bool Mount::clearParking()
1272 auto parkSwitch =
getSwitch(
"TELESCOPE_PARK_OPTION");
1276 auto clearParkSW = parkSwitch->findWidgetByName(
"PARK_PURGE_DATA");
1280 parkSwitch->reset();
1281 clearParkSW->setState(ISS_ON);
1287 bool Mount::clearAlignmentModel()
1289 bool wasExecuted =
false;
1292 auto clearSwitch =
getSwitch(
"ALIGNMENT_POINTSET_ACTION");
1293 auto commitSwitch =
getSwitch(
"ALIGNMENT_POINTSET_COMMIT");
1294 if (clearSwitch && commitSwitch)
1296 clearSwitch->reset();
1298 clearSwitch->at(4)->setState(ISS_ON);
1300 commitSwitch->at(0)->setState(ISS_ON);
1310 clearSwitch->reset();
1311 clearSwitch->at(1)->setState(ISS_ON);
1319 Mount::Status Mount::status()
1321 auto EqProp = getNumber(
"EQUATORIAL_EOD_COORD");
1322 if (EqProp ==
nullptr)
1324 EqProp = getNumber(
"EQUATORIAL_COORD");
1325 if (EqProp ==
nullptr)
1329 return status(EqProp);
1332 const QString Mount::statusString(Mount::Status status,
bool translated)
const
1336 case ISD::Mount::MOUNT_MOVING:
1337 return (translated ?
i18n(mountStates[status]) : mountStates[status]) +
QString(
" %1").
arg(getManualMotionString());
1339 return translated ?
i18n(mountStates[status]) : mountStates[status];
1343 QString Mount::getManualMotionString()
const
1347 auto movementSP =
getSwitch(
"TELESCOPE_MOTION_NS");
1350 if (movementSP->at(MOTION_NORTH)->getState() == ISS_ON)
1352 else if (movementSP->at(MOTION_SOUTH)->getState() == ISS_ON)
1356 movementSP =
getSwitch(
"TELESCOPE_MOTION_WE");
1359 if (movementSP->at(MOTION_WEST)->getState() == ISS_ON)
1361 else if (movementSP->at(MOTION_EAST)->getState() == ISS_ON)
1365 return QString(
"%1%2").
arg(NSMotion, WEMotion);
1368 bool Mount::setTrackEnabled(
bool enable)
1370 auto trackSP =
getSwitch(
"TELESCOPE_TRACK_STATE");
1374 auto trackON = trackSP->findWidgetByName(
"TRACK_ON");
1375 auto trackOFF = trackSP->findWidgetByName(
"TRACK_OFF");
1377 if (!trackON || !trackOFF)
1380 trackON->setState(enable ? ISS_ON : ISS_OFF);
1381 trackOFF->setState(enable ? ISS_OFF : ISS_ON);
1388 bool Mount::isTracking()
1390 return (status() == MOUNT_TRACKING);
1393 bool Mount::setTrackMode(uint8_t index)
1395 auto trackModeSP =
getSwitch(
"TELESCOPE_TRACK_MODE");
1399 if (index >= trackModeSP->nsp)
1402 trackModeSP->reset();
1403 trackModeSP->at(index)->setState(ISS_ON);
1410 bool Mount::getTrackMode(uint8_t &index)
1412 auto trackModeSP =
getSwitch(
"TELESCOPE_TRACK_MODE");
1416 index = trackModeSP->findOnSwitchIndex();
1421 bool Mount::setCustomTrackRate(
double raRate,
double deRate)
1423 auto trackRateNP = getNumber(
"TELESCOPE_TRACK_RATE");
1427 auto raRateN = trackRateNP->findWidgetByName(
"TRACK_RATE_RA");
1428 auto deRateN = trackRateNP->findWidgetByName(
"TRACK_RATE_DE");
1430 if (!raRateN || !deRateN)
1433 raRateN->setValue(raRate);
1434 deRateN->setValue(deRate);
1441 bool Mount::getCustomTrackRate(
double &raRate,
double &deRate)
1443 auto trackRateNP = getNumber(
"TELESCOPE_TRACK_RATE");
1447 auto raRateN = trackRateNP->findWidgetByName(
"TRACK_RATE_RA");
1448 auto deRateN = trackRateNP->findWidgetByName(
"TRACK_RATE_DE");
1450 if (!raRateN || !deRateN)
1453 raRate = raRateN->getValue();
1454 deRate = deRateN->getValue();
1460 bool Mount::sendParkingOptionCommand(ParkOptionCommand command)
1462 auto parkOptionsSP =
getSwitch(
"TELESCOPE_PARK_OPTION");
1466 parkOptionsSP->reset();
1467 parkOptionsSP->at(command)->setState(ISS_ON);
1473 Mount::Status Mount::status(INumberVectorProperty * nvp)
1479 return MOUNT_MOVING;
1480 else if (isParked())
1481 return MOUNT_PARKED;
1487 return MOUNT_MOVING;
1488 else if (inCustomParking)
1490 inCustomParking =
false;
1492 sendParkingOptionCommand(PARK_OPTION_CURRENT);
1494 sendParkingOptionCommand(PARK_OPTION_WRITE_DATA);
1496 return MOUNT_TRACKING;
1499 return MOUNT_TRACKING;
1504 return MOUNT_MOVING;
1506 auto parkSP =
getSwitch(
"TELESCOPE_PARK");
1507 if (parkSP && parkSP->getState() == IPS_BUSY)
1508 return MOUNT_PARKING;
1510 return MOUNT_SLEWING;
1514 inCustomParking =
false;
1523 dms lst = KStarsData::Instance()->
geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst());
1527 bool Mount::isReversed(INDI_EQ_AXIS axis)
1529 auto reversed =
getSwitch(
"TELESCOPE_REVERSE_MOTION");
1533 return reversed->at(axis == AXIS_DE ? 0 : 1)->getState() == ISS_ON;
1536 bool Mount::setReversedEnabled(INDI_EQ_AXIS axis,
bool enabled)
1538 auto reversed =
getSwitch(
"TELESCOPE_REVERSE_MOTION");
1542 reversed->at(axis == AXIS_DE ? 0 : 1)->setState(enabled ? ISS_ON : ISS_OFF);
1549 updateCoordinatesTimer.
stop();
1550 centerLockTimer.
stop();
1558 argument << static_cast<int>(source);
1569 dest =
static_cast<ISD::Mount::Status
>(a);
1576 argument << static_cast<int>(source);
1587 dest =
static_cast<ISD::Mount::PierSide
>(a);