File indexing completed on 2024-04-28 03:43:18
0001 /* 0002 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "sequencejobstate.h" 0010 #include "indi/indistd.h" 0011 #include "indi/indicamera.h" 0012 ////#include "ekos/auxiliary/filtermanager.h" 0013 0014 #include <QTableWidgetItem> 0015 0016 class SkyPoint; 0017 0018 /** 0019 * @class SequenceJob 0020 * @short Sequence Job is a container for the details required to capture a series of images. 0021 * 0022 * @author Jasem Mutlaq 0023 * @version 1.0 0024 */ 0025 namespace Ekos 0026 { 0027 0028 class CaptureDeviceAdaptor; 0029 0030 class SequenceJob : public QObject 0031 { 0032 Q_OBJECT 0033 0034 public: 0035 static QString const &ISOMarker; 0036 static const QStringList StatusStrings(); 0037 0038 // Core Properties 0039 typedef enum 0040 { 0041 // Bool 0042 SJ_EnforceTemperature, 0043 // Bool 0044 // SJ_EnforceStartGuiderDrift, // no specific option 0045 // Bool 0046 SJ_GuiderActive, 0047 // Double 0048 SJ_Exposure, 0049 // QString 0050 SJ_Filter, 0051 // QString 0052 SJ_Format, 0053 // QString 0054 SJ_Encoding, 0055 // QPoint 0056 SJ_Binning, 0057 // QRect 0058 SJ_ROI, 0059 // QString 0060 SJ_FullPrefix, 0061 // Int 0062 SJ_Count, 0063 // Int 0064 SJ_Delay, 0065 // QString 0066 SJ_ISO, 0067 // Int 0068 SJ_ISOIndex, 0069 // Double 0070 SJ_Gain, 0071 // Double 0072 SJ_Offset, 0073 // QString 0074 SJ_TargetName, 0075 //QString 0076 SJ_LocalDirectory, 0077 // QString 0078 SJ_PlaceholderFormat, 0079 // Uint 0080 SJ_PlaceholderSuffix, 0081 // QString 0082 SJ_RemoteDirectory, 0083 // QString 0084 SJ_RemoteFormatDirectory, 0085 // QString 0086 SJ_RemoteFormatFilename, 0087 // QString 0088 SJ_Filename, 0089 // Double 0090 SJ_TargetADU, 0091 // Double 0092 SJ_TargetADUTolerance, 0093 // QString 0094 SJ_Signature, 0095 // Int 0096 SJ_DitherPerJobFrequency 0097 } PropertyID; 0098 0099 typedef enum 0100 { 0101 JOBTYPE_BATCH, /* regular batch job */ 0102 JOBTYPE_PREVIEW, /* previews (single or looping) */ 0103 JOBTYPE_DARKFLAT /* capturing dark flats */ 0104 } SequenceJobType; 0105 0106 //////////////////////////////////////////////////////////////////////// 0107 /// Constructors 0108 //////////////////////////////////////////////////////////////////////// 0109 SequenceJob(const QSharedPointer<CaptureDeviceAdaptor> cp, 0110 const QSharedPointer<CaptureModuleState> sharedState, 0111 SequenceJobType jobType, XMLEle *root = nullptr, QString targetName = ""); 0112 SequenceJob(XMLEle *root, QString targetName); 0113 ~SequenceJob() = default; 0114 0115 //////////////////////////////////////////////////////////////////////// 0116 /// Capture Fuctions 0117 //////////////////////////////////////////////////////////////////////// 0118 /** 0119 * @brief startCapturing Initialize the camera and start capturing 0120 * 0121 * This step calls {@see SequenceJobState::initCapture()}, which triggers 0122 * all actions before the camera may start to capture. If the initialization 0123 * is completed, the sequence job state machine sends the signal 0124 * {@see SequenceJobState::initCaptureComplete()} which will trigger the 0125 * camera device to finally start capturing ({@see capture()}). 0126 * 0127 * @param autofocusReady was there a successful focus run previously? 0128 * @param mode what is the purpose of capturing? 0129 */ 0130 void startCapturing(bool autofocusReady, FITSMode mode); 0131 /** 0132 * @brief capture As soon as everything is ready for the camera to start 0133 * capturing, this method triggers the camera device to start capturing. 0134 * @param mode what is the purpose of capturing? 0135 */ 0136 void capture(FITSMode mode); 0137 void abort(); 0138 void done(); 0139 0140 //////////////////////////////////////////////////////////////////////// 0141 /// Core Properties 0142 //////////////////////////////////////////////////////////////////////// 0143 void setCoreProperty(PropertyID id, const QVariant &value); 0144 QVariant getCoreProperty(PropertyID id) const; 0145 0146 //////////////////////////////////////////////////////////////////////// 0147 /// Job Status Functions 0148 //////////////////////////////////////////////////////////////////////// 0149 const QString &getStatusString() 0150 { 0151 return StatusStrings()[getStatus()]; 0152 } 0153 // Setter: Set how many captures have completed thus far 0154 void setCompleted(int value) 0155 { 0156 m_Completed = value; 0157 } 0158 // Getter: How many captured have completed thus far. 0159 int getCompleted() const 0160 { 0161 return m_Completed; 0162 } 0163 // Setter: Set how many more seconds to expose in this job 0164 void setExposeLeft(double value); 0165 // Getter: Get how many more seconds are left to expose. 0166 double getExposeLeft() const; 0167 // Reset: Reset the job status 0168 void resetStatus(JOBStatus status = JOB_IDLE); 0169 // Setter: Set how many times we re-try this job. 0170 void setCaptureRetires(int value); 0171 // Getter: Get many timed we retried this job already. 0172 int getCaptureRetires() const; 0173 // Getter: How many more seconds are remaining in this job given the 0174 // estimated download time. 0175 int getJobRemainingTime(double estimatedDownloadTime); 0176 0177 //////////////////////////////////////////////////////////////////////// 0178 /// State Machine Functions 0179 //////////////////////////////////////////////////////////////////////// 0180 // Create all event connections between the state machine and the command processor 0181 void connectDeviceAdaptor(); 0182 // Disconnect all event connections between the state machine and the command processor 0183 void disconnectDeviceAdaptor(); 0184 // Setter: Set Target Filter Name 0185 void setTargetFilter(int pos, const QString &name); 0186 // Getter: Get Current Filter Slot 0187 int getCurrentFilter() const; 0188 // Retrieve the pier side from the state 0189 ISD::Mount::PierSide getPierSide() const; 0190 0191 //////////////////////////////////////////////////////////////////////// 0192 /// Job Attribute Functions 0193 //////////////////////////////////////////////////////////////////////// 0194 // job type 0195 SequenceJobType jobType() const 0196 { 0197 return m_jobType; 0198 } 0199 void setJobType(SequenceJobType newJobType) 0200 { 0201 m_jobType = newJobType; 0202 } 0203 QString getSignature() 0204 { 0205 return (getCoreProperty(SJ_Signature).toString()).remove(".fits"); 0206 } 0207 // Scripts 0208 const QMap<ScriptTypes, QString> &getScripts() const 0209 { 0210 return m_Scripts; 0211 } 0212 void setScripts(const QMap<ScriptTypes, QString> &scripts) 0213 { 0214 m_Scripts = scripts; 0215 } 0216 const QString getScript(ScriptTypes type) const 0217 { 0218 return m_Scripts[type]; 0219 } 0220 void setScript(ScriptTypes type, const QString &value) 0221 { 0222 m_Scripts[type] = value; 0223 } 0224 0225 // helper function setting both ISO index and ISO value 0226 void setISO(int index); 0227 0228 // Custom Properties 0229 const QMap<QString, QMap<QString, QVariant> > getCustomProperties() const 0230 { 0231 return m_CustomProperties; 0232 } 0233 void setCustomProperties(const QMap<QString, QMap<QString, QVariant> > &value) 0234 { 0235 m_CustomProperties = value; 0236 } 0237 0238 // Setter: Set upload mode 0239 void setUploadMode(ISD::Camera::UploadMode value); 0240 // Getter: get upload mode 0241 ISD::Camera::UploadMode getUploadMode() const; 0242 0243 // Setter: Set flat field source 0244 void setCalibrationPreAction(uint32_t value); 0245 // Getter: Get flat field source 0246 uint32_t getCalibrationPreAction() const; 0247 0248 // Setter: Set Wall SkyPoint Azimuth coords 0249 void setWallCoord(const SkyPoint &value); 0250 // Getter: Get Flat field source wall coords 0251 const SkyPoint &getWallCoord() const; 0252 0253 // Setter: Set flat field duration 0254 void setFlatFieldDuration(FlatFieldDuration value); 0255 // Getter: Get flat field duration 0256 FlatFieldDuration getFlatFieldDuration() const; 0257 0258 // Setter: Set job progress ignored flag 0259 void setJobProgressIgnored(bool value); 0260 bool getJobProgressIgnored() const; 0261 0262 /** 0263 * @brief updateDeviceStates Update for all used device types whether there 0264 * is one connected. 0265 */ 0266 void updateDeviceStates(); 0267 /** 0268 * @brief Set the light box device 0269 */ 0270 void setLightBox(ISD::LightBox *lightBox); 0271 0272 /** 0273 * @brief Set the dust cap device 0274 */ 0275 void setDustCap(ISD::DustCap *dustCap); 0276 0277 /** 0278 * @brief Set the telescope device 0279 */ 0280 void addMount(ISD::Mount *scope); 0281 0282 /** 0283 * @brief Set the dome device 0284 */ 0285 void setDome(ISD::Dome *dome); 0286 0287 0288 // //////////////////////////////////////////////////////////////////////////// 0289 // Facade to state machine 0290 // //////////////////////////////////////////////////////////////////////////// 0291 /** 0292 * @brief Retrieve the current status of the capture sequence job from the state machine 0293 */ 0294 JOBStatus getStatus() 0295 { 0296 return state->getStatus(); 0297 } 0298 0299 void setFrameType(CCDFrameType value) 0300 { 0301 state->setFrameType(value); 0302 } 0303 CCDFrameType getFrameType() const 0304 { 0305 return state->getFrameType(); 0306 } 0307 0308 int getTargetFilter() const 0309 { 0310 return state->targetFilterID; 0311 } 0312 0313 double getTargetTemperature() const 0314 { 0315 return state->targetTemperature; 0316 } 0317 void setTargetTemperature(double value) 0318 { 0319 state->targetTemperature = value; 0320 } 0321 0322 void setFocusStatus(FocusState value) 0323 { 0324 state->setFocusStatus(value); 0325 } 0326 0327 double getTargetRotation() const 0328 { 0329 return state->targetPositionAngle; 0330 } 0331 void setTargetRotation(double value) 0332 { 0333 state->targetPositionAngle = value; 0334 } 0335 0336 SequenceJobState::CalibrationStage getCalibrationStage() const 0337 { 0338 return state->calibrationStage; 0339 } 0340 void setCalibrationStage(SequenceJobState::CalibrationStage value) 0341 { 0342 state->calibrationStage = value; 0343 } 0344 0345 SequenceJobState::PreparationState getPreparationState() const 0346 { 0347 return state->m_PreparationState; 0348 } 0349 void setPreparationState(SequenceJobState::PreparationState value) 0350 { 0351 state->m_PreparationState = value; 0352 } 0353 0354 bool getAutoFocusReady() const 0355 { 0356 return state->autoFocusReady; 0357 } 0358 void setAutoFocusReady(bool value) 0359 { 0360 state->autoFocusReady = value; 0361 } 0362 0363 /** 0364 * @brief Central entry point to start all activities that are necessary 0365 * before capturing may start. Signals {@see prepareComplete()} as soon as 0366 * everything is ready. 0367 */ 0368 void prepareCapture(); 0369 /** 0370 * @brief processPrepareComplete All preparations necessary for capturing are completed 0371 * @param success true iff preparation succeeded 0372 */ 0373 void processPrepareComplete(bool success = true); 0374 /** 0375 * @brief Abort capturing 0376 */ 0377 void processAbortCapture(); 0378 0379 /** 0380 * @brief Check if all initial tasks are completed so that capturing 0381 * of flats may start. 0382 * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the 0383 * process should be aborted. 0384 */ 0385 IPState checkFlatFramePendingTasksCompleted(); 0386 0387 // current values 0388 double currentTemperature() const; 0389 double currentGain() const; 0390 double currentOffset() const; 0391 0392 void saveTo(QTextStream &outstream, const QLocale &cLocale) const; 0393 void loadFrom(XMLEle *root, const QString &targetName, SequenceJobType jobType, 0394 QSharedPointer<CaptureModuleState> sharedState); 0395 0396 signals: 0397 // All preparations necessary for capturing are completed 0398 void prepareComplete(bool success = true); 0399 // Manage the result when capturing has been started 0400 void captureStarted(CaptureModuleState::CAPTUREResult rc); 0401 // Abort capturing 0402 void abortCapture(); 0403 // log entry 0404 void newLog(QString); 0405 0406 void prepareState(CaptureState state); 0407 // signals to be forwarded to the state machine 0408 void prepareCapture(CCDFrameType frameType, bool enforceCCDTemp, bool enforceStartGuiderDrift, bool isPreview); 0409 // update the current guiding deviation 0410 void updateGuiderDrift(double deviation_rms); 0411 0412 private: 0413 /** 0414 * @brief init Initialize the sequence job from its XML representation 0415 */ 0416 void init(SequenceJobType jobType, XMLEle *root, QSharedPointer<CaptureModuleState> sharedState, const QString &targetName); 0417 0418 // job type (batch, preview, ...) 0419 SequenceJobType m_jobType; 0420 0421 void setStatus(JOBStatus const); 0422 0423 ////////////////////////////////////////////////////////////// 0424 /// Custom Types 0425 /// We save all core sequence properties in QVariant map 0426 ////////////////////////////////////////////////////////////// 0427 QMap<PropertyID, QVariant> m_CoreProperties; 0428 0429 ////////////////////////////////////////////////////////////// 0430 /// Custom Types 0431 /// We don't use Q_PROPERTY for these to simplify use 0432 ////////////////////////////////////////////////////////////// 0433 QMap<QString, QMap<QString, QVariant>> m_CustomProperties; 0434 FlatFieldDuration m_FlatFieldDuration { DURATION_MANUAL }; 0435 // Capture Scripts 0436 QMap<ScriptTypes, QString> m_Scripts; 0437 // Upload Mode 0438 ISD::Camera::UploadMode m_UploadMode { ISD::Camera::UPLOAD_CLIENT }; 0439 // Transfer Format 0440 QString m_TransferFormat { "FITS" }; 0441 0442 ////////////////////////////////////////////////////////////// 0443 /// Status Variables 0444 ////////////////////////////////////////////////////////////// 0445 int m_CaptureRetires { 0 }; 0446 uint32_t m_Completed { 0 }; 0447 double m_ExposeLeft { 0 }; 0448 bool m_JobProgressIgnored {false}; 0449 0450 ////////////////////////////////////////////////////////////// 0451 /// Device access 0452 ////////////////////////////////////////////////////////////// 0453 0454 /** 0455 * @brief frameTypes Retrieve the frame types from the active camera's primary chip. 0456 */ 0457 QStringList frameTypes() const; 0458 /** 0459 * @brief filterLabels list of currently available filter labels 0460 */ 0461 QStringList filterLabels() const; 0462 0463 ////////////////////////////////////////////////////////////// 0464 /// State machines encapsulating the state of this capture sequence job 0465 ////////////////////////////////////////////////////////////// 0466 QSharedPointer<CaptureDeviceAdaptor> devices; 0467 QSharedPointer<SequenceJobState> state; 0468 }; 0469 0470 }