7#include "sequencejobstate.h"
10#include "kstarsdata.h"
12#include "ekos/auxiliary/rotatorutils.h"
18 m_CameraState = sharedState;
21void SequenceJobState::setFrameType(CCDFrameType frameType)
24 m_frameType = frameType;
26 m_PreparationState = PREP_NONE;
29void SequenceJobState::initPreparation(
bool isPreview)
32 m_isPreview = isPreview;
33 wpScopeStatus = WP_NONE;
36void SequenceJobState::prepareLightFrameCapture(
bool enforceCCDTemp,
bool isPreview)
39 if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature)
43 initPreparation(isPreview);
49 emit setCCDBatchMode(!isPreview);
52 prepareTemperatureCheck(enforceCCDTemp);
55 prepareRotatorCheck();
60 m_PreparationState = PREP_BUSY;
62 checkAllActionsReady();
65void SequenceJobState::prepareFlatFrameCapture(
bool enforceCCDTemp,
bool isPreview)
68 if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature)
72 initPreparation(isPreview);
78 emit setCCDBatchMode(!isPreview);
81 prepareTemperatureCheck(enforceCCDTemp);
84 m_PreparationState = PREP_BUSY;
86 checkAllActionsReady();
89void SequenceJobState::prepareDarkFrameCapture(
bool enforceCCDTemp,
bool isPreview)
92 if (m_status == JOB_BUSY && enforceCCDTemp == m_enforceTemperature)
96 initPreparation(isPreview);
102 emit setCCDBatchMode(!isPreview);
105 prepareTemperatureCheck(enforceCCDTemp);
108 m_PreparationState = PREP_BUSY;
110 checkAllActionsReady();
113void SequenceJobState::prepareBiasFrameCapture(
bool enforceCCDTemp,
bool isPreview)
115 prepareDarkFrameCapture(enforceCCDTemp, isPreview);
118bool SequenceJobState::initCapture(CCDFrameType frameType,
bool isPreview,
bool isAutofocusReady, FITSMode mode)
120 m_PreparationState = PREP_INIT_CAPTURE;
121 autoFocusReady = isAutofocusReady;
125 prepareTargetFilter(frameType, isPreview);
126 checkAllActionsReady();
128 return areActionsReady();
131bool SequenceJobState::areActionsReady()
133 for (
bool &ready : prepareActions.
values())
142void SequenceJobState::checkAllActionsReady()
145 if (preparationCompleted())
148 switch (m_PreparationState)
155 if (areActionsReady())
158 if (checkLightFrameScopeCoverOpen() != IPS_OK)
161 m_PreparationState = PREP_COMPLETED;
162 emit prepareComplete();
166 if (!areActionsReady())
170 if (checkFlatsCoverReady() != IPS_OK)
177 if (checkFlatSyncFocus() != IPS_OK)
181 if (m_PreparationState == PREP_BUSY)
183 m_PreparationState = PREP_COMPLETED;
184 emit prepareComplete();
190 if (!areActionsReady())
194 if (checkDarksCoverReady() != IPS_OK)
198 if (m_PreparationState == PREP_BUSY)
200 m_PreparationState = PREP_COMPLETED;
201 emit prepareComplete();
206 emit prepareComplete();
212 case PREP_INIT_CAPTURE:
213 if (areActionsReady())
216 m_PreparationState = PREP_NONE;
217 emit initCaptureComplete(m_fitsMode);
228void SequenceJobState::setAllActionsReady()
238 for (CaptureWorkflowActionType action :
240 CAPTURE_ACTION_FILTER, CAPTURE_ACTION_ROTATOR, CAPTURE_ACTION_TEMPERATURE
242 setInitialized(action,
false);
245void SequenceJobState::prepareTargetFilter(CCDFrameType frameType,
bool isPreview)
247 if (targetFilterID != INVALID_VALUE)
249 if (isInitialized(CAPTURE_ACTION_FILTER) ==
false)
251 prepareActions[CAPTURE_ACTION_FILTER] =
false;
254 if (isPreview || frameType != FRAME_LIGHT || autoFocusReady ==
false)
255 m_filterPolicy =
static_cast<FilterManager::FilterPolicy
>(m_filterPolicy & ~FilterManager::AUTOFOCUS_POLICY);
257 emit readFilterPosition();
259 else if (targetFilterID != m_CameraState->currentFilterID)
262 prepareActions[CAPTURE_ACTION_FILTER] =
false;
265 m_filterPolicy = FilterManager::ALL_POLICIES;
268 if (isPreview || frameType != FRAME_LIGHT || autoFocusReady ==
false)
269 m_filterPolicy =
static_cast<FilterManager::FilterPolicy
>(m_filterPolicy & ~FilterManager::AUTOFOCUS_POLICY);
271 emit changeFilterPosition(targetFilterID, m_filterPolicy);
277void SequenceJobState::prepareTemperatureCheck(
bool enforceCCDTemp)
280 m_enforceTemperature = enforceCCDTemp;
282 if (m_enforceTemperature)
284 prepareActions[CAPTURE_ACTION_TEMPERATURE] =
false;
285 if (isInitialized(CAPTURE_ACTION_TEMPERATURE))
289 ignoreNextValue[CAPTURE_ACTION_TEMPERATURE] =
true;
291 emit setCCDTemperature(targetTemperature);
301void SequenceJobState::prepareRotatorCheck()
303 if (targetPositionAngle > Ekos::INVALID_VALUE)
305 if (isInitialized(CAPTURE_ACTION_ROTATOR))
307 prepareActions[CAPTURE_ACTION_ROTATOR] =
false;
308 double rawAngle = RotatorUtils::Instance()->calcRotatorAngle(targetPositionAngle);
310 emit setRotatorAngle(rawAngle);
318IPState SequenceJobState::checkCalibrationPreActionsReady()
320 IPState result = IPS_OK;
322 if (m_CalibrationPreAction & CAPTURE_PREACTION_WALL)
323 result = checkWallPositionReady(FRAME_FLAT);
325 if (result != IPS_OK)
328 if (m_CalibrationPreAction & CAPTURE_PREACTION_PARK_MOUNT)
329 result = checkPreMountParkReady();
331 if (result != IPS_OK)
334 if (m_CalibrationPreAction & CAPTURE_PREACTION_PARK_DOME)
335 result = checkPreDomeParkReady();
340IPState SequenceJobState::checkFlatsCoverReady()
342 auto result = checkCalibrationPreActionsReady();
343 if (result == IPS_OK)
345 if (m_CameraState->hasDustCap && m_CameraState->hasLightBox)
346 return checkDustCapReady(FRAME_FLAT);
348 else if (m_CalibrationPreAction & CAPTURE_PREACTION_WALL)
353 if (m_CameraState->hasLightBox)
354 return checkDustCapReady(FRAME_FLAT);
356 return checkManualCoverReady(
true);
363IPState SequenceJobState::checkDarksCoverReady()
365 IPState result = checkCalibrationPreActionsReady();;
367 if (result == IPS_OK)
370 result = checkHasShutter();
371 if (result != IPS_OK)
374 if (m_CameraState->hasDustCap)
375 return checkDustCapReady(FRAME_DARK);
377 else if (m_CalibrationPreAction & CAPTURE_PREACTION_WALL)
380 return checkManualCoverReady(
false);
385IPState SequenceJobState::checkManualCoverReady(
bool lightSourceRequired)
388 if (lightSourceRequired && m_CameraState->m_ManualCoverState != CameraState::MANUAL_COVER_CLOSED_LIGHT)
390 if (coverQueryState == CAL_CHECK_CONFIRMATION)
394 emit askManualScopeCover(
i18n(
"Cover the telescope with an evenly illuminated light source."),
395 i18n(
"Flat Frame"),
true);
396 coverQueryState = CAL_CHECK_CONFIRMATION;
400 else if (!lightSourceRequired && m_CameraState->m_ManualCoverState != CameraState::MANUAL_COVER_CLOSED_DARK &&
401 m_CameraState->shutterStatus == SHUTTER_NO)
403 if (coverQueryState == CAL_CHECK_CONFIRMATION)
406 emit askManualScopeCover(
i18n(
"Cover the telescope in order to take a dark exposure."),
407 i18n(
"Dark Exposure"),
false);
409 coverQueryState = CAL_CHECK_CONFIRMATION;
416IPState SequenceJobState::checkDustCapReady(CCDFrameType frameType)
419 if (m_CameraState->getLightBoxLightState() == CAP_LIGHT_BUSY ||
420 m_CameraState->getDustCapState() == CAP_PARKING ||
421 m_CameraState->getDustCapState() == CAP_UNPARKING)
424 if (m_CameraState->getDustCapState() == CAP_ERROR)
427 auto captureLights = (frameType == FRAME_LIGHT);
430 CapState targetCapState = captureLights ? CAP_IDLE : CAP_PARKED;
432 if (m_CameraState->hasDustCap && m_CameraState->getDustCapState() != targetCapState)
434 m_CameraState->setDustCapState(captureLights ? CAP_UNPARKING : CAP_PARKING);
435 emit parkDustCap(!captureLights);
436 emit newLog(captureLights ?
i18n(
"Unparking dust cap...") :
i18n(
"Parking dust cap..."));
440 auto captureFlats = (frameType == FRAME_FLAT);
441 LightState targetLightBoxStatus = captureFlats ? CAP_LIGHT_ON :
444 if (m_CameraState->hasLightBox && m_CameraState->getLightBoxLightState() != targetLightBoxStatus)
446 m_CameraState->setLightBoxLightState(CAP_LIGHT_BUSY);
447 emit setLightBoxLight(captureFlats);
448 emit newLog(captureFlats ?
i18n(
"Turn light box light on...") :
i18n(
"Turn light box light off..."));
456IPState SequenceJobState::checkWallPositionReady(CCDFrameType frametype)
458 if (m_CameraState->hasTelescope)
460 if (wpScopeStatus < WP_SLEWING)
462 wallCoord.HorizontalToEquatorial(KStarsData::Instance()->lst(),
463 KStarsData::Instance()->
geo()->lat());
464 wpScopeStatus = WP_SLEWING;
465 emit slewTelescope(wallCoord);
466 emit newLog(
i18n(
"Mount slewing to wall position (az =%1 alt =%2)",
467 wallCoord.alt().toDMSString(), wallCoord.az().toDMSString()));
471 else if (wpScopeStatus == WP_SLEWING || wpScopeStatus == WP_TRACKING_BUSY)
474 else if (wpScopeStatus == WP_SLEW_COMPLETED)
476 wpScopeStatus = WP_TRACKING_BUSY;
477 emit setScopeTracking(
false);
478 emit newLog(
i18n(
"Slew to wall position complete, stop tracking."));
481 else if (wpScopeStatus == WP_TRACKING_OFF)
482 emit newLog(
i18n(
"Slew to wall position complete, tracking stopped."));
485 bool captureFlats = (frametype == FRAME_FLAT);
486 LightState targetLightState = (captureFlats ? CAP_LIGHT_ON :
489 if (m_CameraState->hasLightBox ==
true)
491 if (m_CameraState->getLightBoxLightState() != targetLightState)
493 m_CameraState->setLightBoxLightState(CAP_LIGHT_BUSY);
494 emit setLightBoxLight(captureFlats);
495 emit newLog(captureFlats ?
i18n(
"Turn light box light on...") :
i18n(
"Turn light box light off..."));
504IPState SequenceJobState::checkPreMountParkReady()
506 if (m_CameraState->hasTelescope)
508 switch (m_CameraState->getScopeParkState())
510 case ISD::PARK_PARKED:
512 case ISD::PARK_ERROR:
513 emit newLog(
i18n(
"Parking mount failed, aborting..."));
516 case ISD::PARK_PARKING:
518 case ISD::PARK_UNPARKED:
519 case ISD::PARK_UNPARKING:
521 emit setScopeParked(
true);
522 emit newLog(
i18n(
"Parking mount prior to calibration frames capture..."));
524 case ISD::PARK_UNKNOWN:
526 emit readCurrentMountParkState();
535IPState SequenceJobState::checkPreDomeParkReady()
537 if (m_CameraState->hasDome)
539 if (m_CameraState->getDomeState() == ISD::Dome::DOME_ERROR)
541 emit newLog(
i18n(
"Parking dome failed, aborting..."));
545 else if (m_CameraState->getDomeState() == ISD::Dome::DOME_PARKING)
547 else if (m_CameraState->getDomeState() != ISD::Dome::DOME_PARKED)
549 m_CameraState->setDomeState(ISD::Dome::DOME_PARKING);
550 emit setDomeParked(
true);
551 emit newLog(
i18n(
"Parking dome prior to calibration frames capture..."));
559IPState SequenceJobState::checkFlatSyncFocus()
562 if (flatSyncStatus == FS_BUSY)
567 emit flatSyncFocus(targetFilterID);
572 if (m_frameType == FRAME_FLAT && Options::flatSyncFocus() && flatSyncStatus != FS_COMPLETED)
574 flatSyncStatus = FS_BUSY;
575 emit flatSyncFocus(targetFilterID);
582IPState SequenceJobState::checkHasShutter()
584 if (m_CameraState->shutterStatus == SHUTTER_BUSY)
586 if (m_CameraState->shutterStatus != SHUTTER_UNKNOWN)
589 m_CameraState->shutterStatus = SHUTTER_BUSY;
590 emit queryHasShutter();
594IPState SequenceJobState::checkLightFrameScopeCoverOpen()
597 if (m_CameraState->hasLightBox && m_CameraState->getLightBoxLightState() != CAP_LIGHT_OFF)
599 if (m_CameraState->getLightBoxLightState() != CAP_LIGHT_BUSY)
601 m_CameraState->setLightBoxLightState(CAP_LIGHT_BUSY);
602 emit setLightBoxLight(
false);
603 emit newLog(
i18n(
"Turn light box light off..."));
609 if (m_CameraState->hasDustCap)
611 if (m_CameraState->getDustCapState() != CAP_IDLE)
613 if (m_CameraState->getDustCapState() != CAP_UNPARKING)
615 m_CameraState->setDustCapState(CAP_UNPARKING);
616 emit parkDustCap(
false);
617 emit newLog(
i18n(
"Unparking dust cap..."));
627 if (m_CameraState->m_ManualCoverState != CameraState::MANAUL_COVER_OPEN)
632 if (coverQueryState == CAL_CHECK_CONFIRMATION)
635 emit askManualScopeOpen(m_CameraState->m_ManualCoverState == CameraState::MANUAL_COVER_CLOSED_LIGHT);
644bool SequenceJobState::isInitialized(CaptureWorkflowActionType action)
646 return m_CameraState.
data()->isInitialized[action];
649void SequenceJobState::setInitialized(CaptureWorkflowActionType action,
bool init)
651 m_CameraState.
data()->isInitialized[action] =
init;
654void SequenceJobState::setCurrentFilterID(
int value)
657 if (preparationCompleted())
660 m_CameraState->currentFilterID = value;
661 if (isInitialized(CAPTURE_ACTION_FILTER) ==
false && value != targetFilterID)
665 prepareActions[CAPTURE_ACTION_FILTER] =
false;
667 emit changeFilterPosition(targetFilterID, m_filterPolicy);
670 setInitialized(CAPTURE_ACTION_FILTER,
true);
672 if (value == targetFilterID)
673 prepareActions[CAPTURE_ACTION_FILTER] =
true;
675 checkAllActionsReady();
678void SequenceJobState::setCurrentCCDTemperature(
double currentTemperature)
681 if (preparationCompleted())
685 if (ignoreNextValue[CAPTURE_ACTION_TEMPERATURE])
687 ignoreNextValue[CAPTURE_ACTION_TEMPERATURE] =
false;
691 if (isInitialized(CAPTURE_ACTION_TEMPERATURE))
693 if (m_enforceTemperature ==
false
694 || fabs(targetTemperature - currentTemperature) <= Options::maxTemperatureDiff())
695 prepareActions[CAPTURE_ACTION_TEMPERATURE] =
true;
697 checkAllActionsReady();
701 setInitialized(CAPTURE_ACTION_TEMPERATURE,
true);
702 if (m_enforceTemperature ==
false
703 || fabs(targetTemperature - currentTemperature) <= Options::maxTemperatureDiff())
705 prepareActions[CAPTURE_ACTION_TEMPERATURE] =
true;
706 checkAllActionsReady();
710 prepareTemperatureCheck(m_enforceTemperature);
715void SequenceJobState::setCurrentRotatorPositionAngle(
double rotatorAngle, IPState state)
718 if (preparationCompleted())
721 double currentPositionAngle = RotatorUtils::Instance()->calcCameraAngle(rotatorAngle,
false);
723 if (isInitialized(CAPTURE_ACTION_ROTATOR))
727 if (fabs(currentPositionAngle - targetPositionAngle) * 60 <= Options::astrometryRotatorThreshold()
728 && state != IPS_BUSY)
729 prepareActions[CAPTURE_ACTION_ROTATOR] =
true;
731 checkAllActionsReady();
735 setInitialized(CAPTURE_ACTION_ROTATOR,
true);
736 if (fabs(currentPositionAngle - targetPositionAngle) * 60 <= Options::astrometryRotatorThreshold()
737 && state != IPS_BUSY)
739 prepareActions[CAPTURE_ACTION_ROTATOR] =
true;
740 checkAllActionsReady();
744 prepareRotatorCheck();
749void SequenceJobState::setFocusStatus(FocusState state)
752 if (preparationCompleted())
759 if (prepareActions[CAPTURE_ACTION_AUTOFOCUS] ==
false)
761 prepareActions[CAPTURE_ACTION_AUTOFOCUS] =
true;
762 checkAllActionsReady();
768 emit prepareComplete(
false);
776void SequenceJobState::updateManualScopeCover(
bool closed,
bool success,
bool light)
779 if (preparationCompleted())
786 m_CameraState->m_ManualCoverState = light ? CameraState::MANUAL_COVER_CLOSED_LIGHT :
787 CameraState::MANUAL_COVER_CLOSED_DARK;
789 m_CameraState->m_ManualCoverState = CameraState::MANAUL_COVER_OPEN;
790 coverQueryState = CAL_CHECK_TASK;
792 checkAllActionsReady();
797 m_CameraState->shutterStatus = SHUTTER_UNKNOWN;
798 coverQueryState = CAL_CHECK_TASK;
804void SequenceJobState::lightBoxLight(
bool on)
807 if (preparationCompleted())
810 m_CameraState->setLightBoxLightState(on ? CAP_LIGHT_ON : CAP_LIGHT_OFF);
811 emit newLog(
i18n(on ?
"Light box on." :
"Light box off."));
813 checkAllActionsReady();
816void SequenceJobState::dustCapStateChanged(ISD::DustCap::Status status)
819 if (preparationCompleted())
824 case ISD::DustCap::CAP_ERROR:
833 checkAllActionsReady();
836void SequenceJobState::scopeStatusChanged(ISD::Mount::Status status)
839 if (preparationCompleted())
845 case ISD::Mount::MOUNT_TRACKING:
846 if (wpScopeStatus == WP_SLEWING)
847 wpScopeStatus = WP_SLEW_COMPLETED;
849 case ISD::Mount::MOUNT_IDLE:
850 if (wpScopeStatus == WP_SLEWING || wpScopeStatus == WP_TRACKING_BUSY)
851 wpScopeStatus = WP_TRACKING_OFF;
853 case ISD::Mount::MOUNT_PARKING:
855 m_CameraState->setScopeParkState(ISD::PARK_PARKING);
862 checkAllActionsReady();
865void SequenceJobState::scopeParkStatusChanged(ISD::ParkStatus)
868 checkAllActionsReady();
871void SequenceJobState::domeStatusChanged(ISD::Dome::Status)
874 checkAllActionsReady();
877void SequenceJobState::flatSyncFocusChanged(
bool completed)
880 if (preparationCompleted())
883 flatSyncStatus = (completed ? FS_COMPLETED : FS_BUSY);
885 checkAllActionsReady();
888void SequenceJobState::hasShutter(
bool present)
891 if (preparationCompleted())
895 m_CameraState->shutterStatus = SHUTTER_YES;
897 m_CameraState->shutterStatus = SHUTTER_NO;
900 checkAllActionsReady();
903SequenceJobState::PreparationState SequenceJobState::getPreparationState()
const
905 return m_PreparationState;
908void SequenceJobState::setFilterStatus(FilterState filterState)
911 if (preparationCompleted())
916 case FILTER_AUTOFOCUS:
918 prepareActions[CAPTURE_ACTION_AUTOFOCUS] =
false;
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
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
GeoCoordinates geo(const QVariant &location)
QList< T > values() const const