7#include "meridianflipstate.h"
8#include "ekos/mount/mount.h"
11#include "kstarsdata.h"
14#include <ekos_capture_debug.h>
18MeridianFlipState::MeridianFlipState(
QObject *parent) :
QObject(parent)
22QString MeridianFlipState::MFStageString(MFStage stage)
29 return "MF_REQUESTED";
33 return "MF_INITIATED";
37 return "MF_COMPLETED";
43 return "MFStage unknown.";
46void MeridianFlipState::setEnabled(
bool value)
50 if (m_enabled ==
false)
51 updateMFMountState(MOUNT_FLIP_NONE);
54void MeridianFlipState::connectMount(Mount *mount)
60void MeridianFlipState::updateMeridianFlipStage(
const MFStage &stage)
62 qCDebug(
KSTARS_EKOS_CAPTURE) <<
"updateMeridianFlipStage: " << MeridianFlipState::MFStageString(stage);
64 if (meridianFlipStage != stage)
68 case MeridianFlipState::MF_NONE:
69 meridianFlipStage = stage;
72 case MeridianFlipState::MF_READY:
73 if (getMeridianFlipStage() == MeridianFlipState::MF_REQUESTED)
76 updateMFMountState(MeridianFlipState::MOUNT_FLIP_ACCEPTED);
78 else if (m_CaptureState == CAPTURE_PAUSED)
81 meridianFlipStage = stage;
82 updateMFMountState(MeridianFlipState::MOUNT_FLIP_ACCEPTED);
84 else if (!(checkMeridianFlipRunning()
85 || getMeridianFlipStage() == MeridianFlipState::MF_COMPLETED))
90 meridianFlipStage = MeridianFlipState::MF_NONE;
96 case MeridianFlipState::MF_INITIATED:
97 meridianFlipStage = MeridianFlipState::MF_INITIATED;
100 case MeridianFlipState::MF_REQUESTED:
101 if (m_CaptureState == CAPTURE_PAUSED)
103 updateMFMountState(MeridianFlipState::MOUNT_FLIP_ACCEPTED);
105 updateMFMountState(MeridianFlipState::MOUNT_FLIP_WAITING);
106 meridianFlipStage = stage;
109 case MeridianFlipState::MF_COMPLETED:
110 meridianFlipStage = MeridianFlipState::MF_COMPLETED;
114 meridianFlipStage = stage;
122bool MeridianFlipState::checkMeridianFlip(
dms lst)
125 if (m_hasMount ==
false)
127 publishMFMountStatusText(
i18n(
"Meridian flip inactive (no scope connected)"));
128 updateMFMountState(MOUNT_FLIP_NONE);
132 if (isEnabled() ==
false)
134 publishMFMountStatusText(
i18n(
"Meridian flip inactive (flip not requested)"));
139 if (m_MountParkStatus == ISD::PARK_PARKED)
141 publishMFMountStatusText(
i18n(
"Meridian flip inactive (parked)"));
145 if (targetPosition.valid ==
false || isEnabled() ==
false)
147 publishMFMountStatusText(
i18n(
"Meridian flip inactive (no target set)"));
152 double offset =
rangeHA(m_offset / 15.0);
156 double ha = currentPosition.ha.HoursHa();
170 switch (currentPosition.pierSide)
172 case ISD::Mount::PierSide::PIER_WEST:
175 case ISD::Mount::PierSide::PIER_EAST:
184 if (initialPositionHA() >= 0)
186 publishMFMountStatusText(
i18n(
"Meridian flip inactive (slew after meridian)"));
187 if (getMeridianFlipMountState() == MOUNT_FLIP_NONE)
197 hrsToFlip = offset + getFlipDelayHrs() - ha;
205 switch (getMeridianFlipMountState())
207 case MOUNT_FLIP_NONE:
208 publishMFMountStatusText(message);
215 " scope RA=" << currentPosition.position.ra().toHMSString() <<
217 ", meridian diff=" << offset <<
219 ", flipDelayHrs=" << getFlipDelayHrs() <<
220 ", " << ISD::Mount::pierSideStateString(currentPosition.pierSide);
223 updateMFMountState(MOUNT_FLIP_PLANNED);
227 case MOUNT_FLIP_PLANNED:
229 if (m_hasCaptureInterface ==
false)
232 updateMFMountState(MOUNT_FLIP_ACCEPTED);
237 case MOUNT_FLIP_ACCEPTED:
241 case MOUNT_FLIP_RUNNING:
242 if (m_MountStatus == ISD::Mount::MOUNT_TRACKING)
244 if (minMeridianFlipEndTime <= KStarsData::Instance()->clock()->utc())
251 if (currentPosition.pierSide == ISD::Mount::PIER_UNKNOWN)
253 appendLogText(
i18n(
"Assuming meridian flip completed, but pier side unknown."));
255 updateMFMountState(MOUNT_FLIP_COMPLETED);
266 if (getFlipDelayHrs() <= 1.0)
271 if (currentPosition.pierSide == ISD::Mount::PierSide::PIER_EAST)
277 appendLogText(
i18n(
"meridian flip failed, retrying in 4 minutes"));
281 appendLogText(
i18n(
"No successful Meridian Flip done, delay too long"));
283 updateMFMountState(MOUNT_FLIP_COMPLETED);
288 appendLogText(
i18n(
"Meridian flip completed OK."));
290 updateMFMountState(MOUNT_FLIP_COMPLETED);
294 qCInfo(
KSTARS_EKOS_MOUNT) <<
"Tracking state during meridian flip reached too early, ignored.";
298 case MOUNT_FLIP_COMPLETED:
299 updateMFMountState(MOUNT_FLIP_NONE);
308void MeridianFlipState::startMeridianFlip()
310 if ( targetPosition.valid ==
false)
317 if (m_MountStatus != ISD::Mount::MOUNT_TRACKING)
320 if (m_hasMount ==
false)
324 qCInfo(
KSTARS_EKOS_MOUNT) <<
"No meridian flip: mount not tracking, current state:" <<
325 ISD::Mount::mountStates[m_MountStatus];
329 dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst());
330 double HA =
rangeHA(lst.
Hours() - targetPosition.position.ra().Hours());
334 targetPosition.position.ra().toHMSString() <<
335 "DEC=" << targetPosition.position.dec().toDMSString() <<
338 updateMinMeridianFlipEndTime();
339 updateMFMountState(MeridianFlipState::MOUNT_FLIP_RUNNING);
342 emit slewTelescope(targetPosition.position);
345bool MeridianFlipState::resetMeridianFlip()
349 if (meridianFlipMountState != MOUNT_FLIP_RUNNING)
351 updateMFMountState(MOUNT_FLIP_NONE);
354 meridianFlipStatusString(meridianFlipMountState);
362void MeridianFlipState::processFlipCompleted()
364 appendLogText(
i18n(
"Telescope completed the meridian flip."));
365 if (m_CaptureState == CAPTURE_IDLE || m_CaptureState == CAPTURE_ABORTED || m_CaptureState == CAPTURE_COMPLETE)
369 updateMeridianFlipStage(MeridianFlipState::MF_NONE);
383void MeridianFlipState::appendLogText(
QString message)
386 emit newLog(message);
389void MeridianFlipState::updateMinMeridianFlipEndTime()
391 minMeridianFlipEndTime = KStarsData::Instance()->clock()->utc().addSecs(Options::minFlipDuration());
394void MeridianFlipState::updateMFMountState(MeridianFlipMountState status)
396 if (getMeridianFlipMountState() != status)
398 if (status == MOUNT_FLIP_ACCEPTED)
401 if (meridianFlipStage != MF_REQUESTED)
405 setMeridianFlipMountState(status);
406 emit newMountMFStatus(status);
410void MeridianFlipState::publishMFMountStatus(MeridianFlipMountState status)
413 if (status == meridianFlipMountState)
418 case MOUNT_FLIP_NONE:
419 publishMFMountStatusText(
i18n(
"Status: inactive"));
422 case MOUNT_FLIP_PLANNED:
423 publishMFMountStatusText(
i18n(
"Meridian flip planned..."));
426 case MOUNT_FLIP_WAITING:
427 publishMFMountStatusText(
i18n(
"Meridian flip waiting..."));
430 case MOUNT_FLIP_ACCEPTED:
431 publishMFMountStatusText(
i18n(
"Meridian flip ready to start..."));
434 case MOUNT_FLIP_RUNNING:
435 publishMFMountStatusText(
i18n(
"Meridian flip running..."));
438 case MOUNT_FLIP_COMPLETED:
439 publishMFMountStatusText(
i18n(
"Meridian flip completed."));
448void MeridianFlipState::publishMFMountStatusText(
QString text)
451 if (text != m_lastStatusText)
453 emit newMeridianFlipMountStatusText(text);
454 m_lastStatusText = text;
458QString MeridianFlipState::meridianFlipStatusString(MeridianFlipMountState status)
462 case MOUNT_FLIP_NONE:
463 return "MOUNT_FLIP_NONE";
464 case MOUNT_FLIP_PLANNED:
465 return "MOUNT_FLIP_PLANNED";
466 case MOUNT_FLIP_WAITING:
467 return "MOUNT_FLIP_WAITING";
468 case MOUNT_FLIP_ACCEPTED:
469 return "MOUNT_FLIP_ACCEPTED";
470 case MOUNT_FLIP_RUNNING:
471 return "MOUNT_FLIP_RUNNING";
472 case MOUNT_FLIP_COMPLETED:
473 return "MOUNT_FLIP_COMPLETED";
474 case MOUNT_FLIP_ERROR:
475 return "MOUNT_FLIP_ERROR";
477 return "not possible";
484void MeridianFlipState::setMountStatus(ISD::Mount::Status status)
487 m_PrevMountStatus = m_MountStatus;
491void MeridianFlipState::setMountParkStatus(ISD::ParkStatus status)
494 if (status == ISD::PARK_PARKING || status == ISD::PARK_PARKED)
495 updateMFMountState(MOUNT_FLIP_NONE);
497 m_MountParkStatus =
status;
501void MeridianFlipState::updatePosition(MountPosition &pos,
const SkyPoint &position, ISD::Mount::PierSide pierSide,
502 const dms &ha,
const bool isValid)
504 pos.position = position;
505 pos.pierSide = pierSide;
510void MeridianFlipState::updateTelescopeCoord(
const SkyPoint &position, ISD::Mount::PierSide pierSide,
const dms &ha)
512 updatePosition(currentPosition, position, pierSide, ha,
true);
516 if (m_MountStatus == ISD::Mount::MOUNT_TRACKING && m_PrevMountStatus == ISD::Mount::MOUNT_SLEWING
519 if (meridianFlipMountState == MOUNT_FLIP_NONE)
524 updatePosition(targetPosition, currentPosition.position, currentPosition.pierSide, currentPosition.ha,
true);
526 meridianFlipStatusString(meridianFlipMountState);
528 m_PrevMountStatus = m_MountStatus;
533 dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst());
536 bool inMotion = (m_MountStatus == ISD::Mount::MOUNT_SLEWING || m_MountStatus == ISD::Mount::MOUNT_MOVING
537 || m_MountStatus == ISD::Mount::MOUNT_PARKING);
538 if ((
inMotion ==
false) && checkMeridianFlip(lst))
542 const QString message(
i18n(
"Meridian flip inactive (parked)"));
543 if (m_MountParkStatus == ISD::PARK_PARKED )
545 publishMFMountStatusText(message);
550void MeridianFlipState::setTargetPosition(
SkyPoint *pos)
554 dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst());
557 qCDebug(
KSTARS_EKOS_MOUNT) <<
"Setting target RA=" << pos->
ra().toHMSString() <<
"DEC=" << pos->
dec().toDMSString();
558 updatePosition(targetPosition, *pos, ISD::Mount::PIER_UNKNOWN, ha,
true);
562 clearTargetPosition();
566double MeridianFlipState::initialPositionHA()
const
568 double HA = targetPosition.ha.HoursHa();
The sky coordinates of a point in the sky.
const CachingDms & dec() const
const CachingDms & ra() const
An angle, stored as degrees, but expressible in many ways.
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
const double & Degrees() const
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
Ekos is an advanced Astrophotography tool for Linux.
bool isValid(QStringView ifopt)
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)