7#include "sequencejobstate.h"
10#include "kstarsdata.h"
12#include "ekos/auxiliary/rotatorutils.h"
18 m_CameraState = sharedState;
23 emit flatSyncFocus(targetFilterID);
27void SequenceJobState::setFrameType(CCDFrameType frameType)
30 m_frameType = frameType;
32 m_PreparationState = PREP_NONE;
35void SequenceJobState::initPreparation(
bool isPreview)
38 m_isPreview = isPreview;
39 wpScopeStatus = WP_NONE;
42void SequenceJobState::prepareLightFrameCapture(
bool enforceCCDTemp,
bool isPreview)
45 if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature)
49 initPreparation(isPreview);
55 emit setCCDBatchMode(!isPreview);
58 prepareTemperatureCheck(enforceCCDTemp);
61 prepareRotatorCheck();
66 m_PreparationState = PREP_BUSY;
68 checkAllActionsReady();
71void SequenceJobState::prepareFlatFrameCapture(
bool enforceCCDTemp,
bool isPreview)
74 if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature)
78 initPreparation(isPreview);
84 emit setCCDBatchMode(!isPreview);
87 prepareTemperatureCheck(enforceCCDTemp);
90 m_PreparationState = PREP_BUSY;
92 checkAllActionsReady();
95void SequenceJobState::prepareDarkFrameCapture(
bool enforceCCDTemp,
bool isPreview)
98 if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature)
102 initPreparation(isPreview);
105 setAllActionsReady();
108 emit setCCDBatchMode(!isPreview);
111 prepareTemperatureCheck(enforceCCDTemp);
114 m_PreparationState = PREP_BUSY;
116 checkAllActionsReady();
119void SequenceJobState::prepareBiasFrameCapture(
bool enforceCCDTemp,
bool isPreview)
121 prepareDarkFrameCapture(enforceCCDTemp, isPreview);
124bool SequenceJobState::initCapture(CCDFrameType frameType,
bool isPreview,
bool isAutofocusReady, FITSMode mode)
126 m_PreparationState = PREP_INIT_CAPTURE;
127 autoFocusReady = isAutofocusReady;
131 prepareTargetFilter(frameType, isPreview);
132 checkAllActionsReady();
134 return areActionsReady();
137bool SequenceJobState::areActionsReady()
139 for (
bool &ready : prepareActions.
values())
148void SequenceJobState::checkAllActionsReady()
151 if (preparationCompleted())
154 switch (m_PreparationState)
161 if (areActionsReady())
164 if (checkLightFrameScopeCoverOpen() != IPS_OK)
167 m_PreparationState = PREP_COMPLETED;
168 emit prepareComplete();
172 if (!areActionsReady())
176 if (checkFlatsCoverReady() != IPS_OK)
183 if (checkFlatSyncFocus() != IPS_OK)
187 if (m_PreparationState == PREP_BUSY)
189 m_PreparationState = PREP_COMPLETED;
190 emit prepareComplete();
196 if (!areActionsReady())
200 if (checkDarksCoverReady() != IPS_OK)
204 if (m_PreparationState == PREP_BUSY)
206 m_PreparationState = PREP_COMPLETED;
207 emit prepareComplete();
212 emit prepareComplete();
218 case PREP_INIT_CAPTURE:
219 if (areActionsReady())
222 m_PreparationState = PREP_NONE;
223 emit initCaptureComplete(m_fitsMode);
234void SequenceJobState::setAllActionsReady()
244 for (CaptureWorkflowActionType action :
246 CAPTURE_ACTION_FILTER, CAPTURE_ACTION_ROTATOR, CAPTURE_ACTION_TEMPERATURE
248 setInitialized(action,
false);
251void SequenceJobState::prepareTargetFilter(CCDFrameType frameType,
bool isPreview)
253 if (targetFilterID != INVALID_VALUE)
255 if (isInitialized(CAPTURE_ACTION_FILTER) ==
false)
257 prepareActions[CAPTURE_ACTION_FILTER] =
false;
260 if (isPreview || frameType != FRAME_LIGHT || autoFocusReady ==
false)
261 m_filterPolicy =
static_cast<FilterManager::FilterPolicy
>(m_filterPolicy & ~FilterManager::AUTOFOCUS_POLICY);
263 emit readFilterPosition();
265 else if (targetFilterID != m_CameraState->currentFilterID)
268 prepareActions[CAPTURE_ACTION_FILTER] =
false;
271 m_filterPolicy = FilterManager::ALL_POLICIES;
274 if (isPreview || frameType != FRAME_LIGHT || autoFocusReady ==
false)
275 m_filterPolicy =
static_cast<FilterManager::FilterPolicy
>(m_filterPolicy & ~FilterManager::AUTOFOCUS_POLICY);
277 emit changeFilterPosition(targetFilterID, m_filterPolicy);
283void SequenceJobState::prepareTemperatureCheck(
bool enforceCCDTemp)
286 m_enforceTemperature = enforceCCDTemp;
288 if (m_enforceTemperature)
290 prepareActions[CAPTURE_ACTION_TEMPERATURE] =
false;
291 if (isInitialized(CAPTURE_ACTION_TEMPERATURE))
295 ignoreNextValue[CAPTURE_ACTION_TEMPERATURE] =
true;
297 emit setCCDTemperature(targetTemperature);
307void SequenceJobState::prepareRotatorCheck()
309 if (targetPositionAngle > Ekos::INVALID_VALUE)
311 if (isInitialized(CAPTURE_ACTION_ROTATOR))
313 prepareActions[CAPTURE_ACTION_ROTATOR] =
false;
314 double rawAngle = RotatorUtils::Instance()->calcRotatorAngle(targetPositionAngle);
316 emit setRotatorAngle(rawAngle);
324IPState SequenceJobState::checkCalibrationPreActionsReady()
326 IPState result = IPS_OK;
328 if (m_CalibrationPreAction & CAPTURE_PREACTION_WALL)
329 result = checkWallPositionReady(FRAME_FLAT);
331 if (result != IPS_OK)
334 if (m_CalibrationPreAction & CAPTURE_PREACTION_PARK_MOUNT)
335 result = checkPreMountParkReady();
337 if (result != IPS_OK)
340 if (m_CalibrationPreAction & CAPTURE_PREACTION_PARK_DOME)
341 result = checkPreDomeParkReady();
346IPState SequenceJobState::checkFlatsCoverReady()
348 auto result = checkCalibrationPreActionsReady();
349 if (result == IPS_OK)
351 if (m_CameraState->hasDustCap && m_CameraState->hasLightBox)
352 return checkDustCapReady(FRAME_FLAT);
354 else if (m_CalibrationPreAction & CAPTURE_PREACTION_WALL)
359 if (m_CameraState->hasLightBox)
360 return checkDustCapReady(FRAME_FLAT);
362 return checkManualCoverReady(
true);
369IPState SequenceJobState::checkDarksCoverReady()
371 IPState result = checkCalibrationPreActionsReady();;
373 if (result == IPS_OK)
376 result = checkHasShutter();
377 if (result != IPS_OK)
380 if (m_CameraState->hasDustCap)
381 return checkDustCapReady(FRAME_DARK);
383 else if (m_CalibrationPreAction & CAPTURE_PREACTION_WALL)
386 return checkManualCoverReady(
false);
391IPState SequenceJobState::checkManualCoverReady(
bool lightSourceRequired)
394 if (lightSourceRequired && m_CameraState->m_ManualCoverState != CameraState::MANUAL_COVER_CLOSED_LIGHT)
396 if (coverQueryState == CAL_CHECK_CONFIRMATION)
400 emit askManualScopeCover(
i18n(
"Cover the telescope with an evenly illuminated light source."),
401 i18n(
"Flat Frame"),
true);
402 coverQueryState = CAL_CHECK_CONFIRMATION;
406 else if (!lightSourceRequired && m_CameraState->m_ManualCoverState != CameraState::MANUAL_COVER_CLOSED_DARK &&
407 m_CameraState->shutterStatus == SHUTTER_NO)
409 if (coverQueryState == CAL_CHECK_CONFIRMATION)
412 emit askManualScopeCover(
i18n(
"Cover the telescope in order to take a dark exposure."),
413 i18n(
"Dark Exposure"),
false);
415 coverQueryState = CAL_CHECK_CONFIRMATION;
422IPState SequenceJobState::checkDustCapReady(CCDFrameType frameType)
425 if (m_CameraState->getLightBoxLightState() == CAP_LIGHT_BUSY ||
426 m_CameraState->getDustCapState() == CAP_PARKING ||
427 m_CameraState->getDustCapState() == CAP_UNPARKING)
430 if (m_CameraState->getDustCapState() == CAP_ERROR)
433 auto captureLights = (frameType == FRAME_LIGHT);
436 CapState targetCapState = captureLights ? CAP_IDLE : CAP_PARKED;
438 if (m_CameraState->hasDustCap && m_CameraState->getDustCapState() != targetCapState)
440 m_CameraState->setDustCapState(captureLights ? CAP_UNPARKING : CAP_PARKING);
441 emit parkDustCap(!captureLights);
442 emit newLog(captureLights ?
i18n(
"Unparking dust cap...") :
i18n(
"Parking dust cap..."));
446 auto captureFlats = (frameType == FRAME_FLAT);
447 LightState targetLightBoxStatus = captureFlats ? CAP_LIGHT_ON :
450 if (m_CameraState->hasLightBox && m_CameraState->getLightBoxLightState() != targetLightBoxStatus)
452 m_CameraState->setLightBoxLightState(CAP_LIGHT_BUSY);
453 emit setLightBoxLight(captureFlats);
454 emit newLog(captureFlats ?
i18n(
"Turn light box light on...") :
i18n(
"Turn light box light off..."));
462IPState SequenceJobState::checkWallPositionReady(CCDFrameType frametype)
464 if (m_CameraState->hasTelescope)
466 if (wpScopeStatus < WP_SLEWING)
469 KStarsData::Instance()->
geo()->lat());
470 wpScopeStatus = WP_SLEWING;
471 emit slewTelescope(wallCoord);
472 emit newLog(
i18n(
"Mount slewing to wall position (az =%1 alt =%2)",
477 else if (wpScopeStatus == WP_SLEWING || wpScopeStatus == WP_TRACKING_BUSY)
480 else if (wpScopeStatus == WP_SLEW_COMPLETED)
482 wpScopeStatus = WP_TRACKING_BUSY;
483 emit setScopeTracking(
false);
484 emit newLog(
i18n(
"Slew to wall position complete, stop tracking."));
487 else if (wpScopeStatus == WP_TRACKING_OFF)
488 emit newLog(
i18n(
"Slew to wall position complete, tracking stopped."));
491 bool captureFlats = (frametype == FRAME_FLAT);
492 LightState targetLightState = (captureFlats ? CAP_LIGHT_ON :
495 if (m_CameraState->hasLightBox ==
true)
497 if (m_CameraState->getLightBoxLightState() != targetLightState)
499 m_CameraState->setLightBoxLightState(CAP_LIGHT_BUSY);
500 emit setLightBoxLight(captureFlats);
501 emit newLog(captureFlats ?
i18n(
"Turn light box light on...") :
i18n(
"Turn light box light off..."));
510IPState SequenceJobState::checkPreMountParkReady()
512 if (m_CameraState->hasTelescope)
514 switch (m_CameraState->getScopeParkState())
516 case ISD::PARK_PARKED:
518 case ISD::PARK_ERROR:
519 emit newLog(
i18n(
"Parking mount failed, aborting..."));
522 case ISD::PARK_PARKING:
524 case ISD::PARK_UNPARKED:
525 case ISD::PARK_UNPARKING:
527 emit setScopeParked(
true);
528 emit newLog(
i18n(
"Parking mount prior to calibration frames capture..."));
530 case ISD::PARK_UNKNOWN:
532 emit readCurrentMountParkState();
541IPState SequenceJobState::checkPreDomeParkReady()
543 if (m_CameraState->hasDome)
545 if (m_CameraState->getDomeState() == ISD::Dome::DOME_ERROR)
547 emit newLog(
i18n(
"Parking dome failed, aborting..."));
551 else if (m_CameraState->getDomeState() == ISD::Dome::DOME_PARKING)
553 else if (m_CameraState->getDomeState() != ISD::Dome::DOME_PARKED)
555 m_CameraState->setDomeState(ISD::Dome::DOME_PARKING);
556 emit setDomeParked(
true);
557 emit newLog(
i18n(
"Parking dome prior to calibration frames capture..."));
565IPState SequenceJobState::checkFlatSyncFocus()
568 if (flatSyncStatus == FS_BUSY)
570 m_FlatSyncCheck.
start();
574 if (m_frameType == FRAME_FLAT && Options::flatSyncFocus() && flatSyncStatus != FS_COMPLETED)
576 flatSyncStatus = FS_BUSY;
577 emit flatSyncFocus(targetFilterID);
584IPState SequenceJobState::checkHasShutter()
586 if (m_CameraState->shutterStatus == SHUTTER_BUSY)
588 if (m_CameraState->shutterStatus != SHUTTER_UNKNOWN)
591 m_CameraState->shutterStatus = SHUTTER_BUSY;
592 emit queryHasShutter();
596IPState SequenceJobState::checkLightFrameScopeCoverOpen()
599 if (m_CameraState->hasLightBox && m_CameraState->getLightBoxLightState() != CAP_LIGHT_OFF)
601 if (m_CameraState->getLightBoxLightState() != CAP_LIGHT_BUSY)
603 m_CameraState->setLightBoxLightState(CAP_LIGHT_BUSY);
604 emit setLightBoxLight(
false);
605 emit newLog(
i18n(
"Turn light box light off..."));
611 if (m_CameraState->hasDustCap)
613 if (m_CameraState->getDustCapState() != CAP_IDLE)
615 if (m_CameraState->getDustCapState() != CAP_UNPARKING)
617 m_CameraState->setDustCapState(CAP_UNPARKING);
618 emit parkDustCap(
false);
619 emit newLog(
i18n(
"Unparking dust cap..."));
629 if (m_CameraState->m_ManualCoverState != CameraState::MANAUL_COVER_OPEN)
634 if (coverQueryState == CAL_CHECK_CONFIRMATION)
637 emit askManualScopeOpen(m_CameraState->m_ManualCoverState == CameraState::MANUAL_COVER_CLOSED_LIGHT);
646bool SequenceJobState::isInitialized(CaptureWorkflowActionType action)
648 return m_CameraState.
data()->isInitialized[action];
651void SequenceJobState::setInitialized(CaptureWorkflowActionType action,
bool init)
653 m_CameraState.
data()->isInitialized[action] =
init;
656void SequenceJobState::setCurrentFilterID(
int value)
659 if (preparationCompleted())
662 m_CameraState->currentFilterID = value;
663 if (isInitialized(CAPTURE_ACTION_FILTER) ==
false && value != targetFilterID)
667 prepareActions[CAPTURE_ACTION_FILTER] =
false;
669 emit changeFilterPosition(targetFilterID, m_filterPolicy);
672 setInitialized(CAPTURE_ACTION_FILTER,
true);
674 if (value == targetFilterID)
675 prepareActions[CAPTURE_ACTION_FILTER] =
true;
678 m_PreparationState = PREP_NONE;
679 emit prepareComplete(
false);
683 checkAllActionsReady();
686void SequenceJobState::setCurrentCCDTemperature(
double currentTemperature)
689 if (preparationCompleted())
693 if (ignoreNextValue[CAPTURE_ACTION_TEMPERATURE])
695 ignoreNextValue[CAPTURE_ACTION_TEMPERATURE] =
false;
699 if (isInitialized(CAPTURE_ACTION_TEMPERATURE))
701 if (m_enforceTemperature ==
false
702 || fabs(targetTemperature - currentTemperature) <= Options::maxTemperatureDiff())
703 prepareActions[CAPTURE_ACTION_TEMPERATURE] =
true;
705 checkAllActionsReady();
709 setInitialized(CAPTURE_ACTION_TEMPERATURE,
true);
710 if (m_enforceTemperature ==
false
711 || fabs(targetTemperature - currentTemperature) <= Options::maxTemperatureDiff())
713 prepareActions[CAPTURE_ACTION_TEMPERATURE] =
true;
714 checkAllActionsReady();
718 prepareTemperatureCheck(m_enforceTemperature);
723void SequenceJobState::setCurrentRotatorPositionAngle(
double rotatorAngle, IPState state)
726 if (preparationCompleted())
729 double currentPositionAngle = RotatorUtils::Instance()->calcCameraAngle(rotatorAngle,
false);
731 if (isInitialized(CAPTURE_ACTION_ROTATOR))
735 if (fabs(currentPositionAngle - targetPositionAngle) * 60 <= Options::astrometryRotatorThreshold()
736 && state != IPS_BUSY)
737 prepareActions[CAPTURE_ACTION_ROTATOR] =
true;
739 checkAllActionsReady();
743 setInitialized(CAPTURE_ACTION_ROTATOR,
true);
744 if (fabs(currentPositionAngle - targetPositionAngle) * 60 <= Options::astrometryRotatorThreshold()
745 && state != IPS_BUSY)
747 prepareActions[CAPTURE_ACTION_ROTATOR] =
true;
748 checkAllActionsReady();
752 prepareRotatorCheck();
757void SequenceJobState::setFocusStatus(FocusState state)
760 if (preparationCompleted())
767 if (prepareActions[CAPTURE_ACTION_AUTOFOCUS] ==
false)
769 prepareActions[CAPTURE_ACTION_AUTOFOCUS] =
true;
770 checkAllActionsReady();
776 emit prepareComplete(
false);
784void SequenceJobState::updateManualScopeCover(
bool closed,
bool success,
bool light)
787 if (preparationCompleted())
794 m_CameraState->m_ManualCoverState = light ? CameraState::MANUAL_COVER_CLOSED_LIGHT :
795 CameraState::MANUAL_COVER_CLOSED_DARK;
797 m_CameraState->m_ManualCoverState = CameraState::MANAUL_COVER_OPEN;
798 coverQueryState = CAL_CHECK_TASK;
800 checkAllActionsReady();
805 m_CameraState->shutterStatus = SHUTTER_UNKNOWN;
806 coverQueryState = CAL_CHECK_TASK;
812void SequenceJobState::lightBoxLight(
bool on)
815 if (preparationCompleted())
818 m_CameraState->setLightBoxLightState(on ? CAP_LIGHT_ON : CAP_LIGHT_OFF);
819 emit newLog(
i18n(on ?
"Light box on." :
"Light box off."));
821 checkAllActionsReady();
824void SequenceJobState::dustCapStateChanged(ISD::DustCap::Status status)
827 if (preparationCompleted())
832 case ISD::DustCap::CAP_ERROR:
841 checkAllActionsReady();
844void SequenceJobState::scopeStatusChanged(ISD::Mount::Status status)
847 if (preparationCompleted())
853 case ISD::Mount::MOUNT_TRACKING:
854 if (wpScopeStatus == WP_SLEWING)
855 wpScopeStatus = WP_SLEW_COMPLETED;
857 case ISD::Mount::MOUNT_IDLE:
858 if (wpScopeStatus == WP_SLEWING || wpScopeStatus == WP_TRACKING_BUSY)
859 wpScopeStatus = WP_TRACKING_OFF;
861 case ISD::Mount::MOUNT_PARKING:
863 m_CameraState->setScopeParkState(ISD::PARK_PARKING);
870 checkAllActionsReady();
873void SequenceJobState::scopeParkStatusChanged(ISD::ParkStatus)
876 checkAllActionsReady();
879void SequenceJobState::domeStatusChanged(ISD::Dome::Status)
882 checkAllActionsReady();
885void SequenceJobState::flatSyncFocusChanged(
bool completed)
888 if (preparationCompleted())
891 flatSyncStatus = (completed ? FS_COMPLETED : FS_BUSY);
893 checkAllActionsReady();
896void SequenceJobState::hasShutter(
bool present)
899 if (preparationCompleted())
903 m_CameraState->shutterStatus = SHUTTER_YES;
905 m_CameraState->shutterStatus = SHUTTER_NO;
908 checkAllActionsReady();
911SequenceJobState::PreparationState SequenceJobState::getPreparationState()
const
913 return m_PreparationState;
916void SequenceJobState::setFilterStatus(FilterState filterState)
919 if (preparationCompleted())
924 case FILTER_AUTOFOCUS:
926 prepareActions[CAPTURE_ACTION_AUTOFOCUS] =
false;
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
QString i18n(const char *text, const TYPE &arg...)
Ekos is an advanced Astrophotography tool for Linux.
@ CAPTURE_SETTING_ROTATOR
@ CAPTURE_CHANGING_FILTER
@ CAPTURE_SETTING_TEMPERATURE
GeoCoordinates geo(const QVariant &location)
QList< T > values() const const
QMetaObject::Connection callOnTimeout(Functor &&slot)
void setInterval(int msec)
void setSingleShot(bool singleShot)