Kstars

capture.h
1 /*
2  SPDX-FileCopyrightText: 2012 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "ui_capture.h"
10 #include "capturemodulestate.h"
11 #include "capturedeviceadaptor.h"
12 #include "sequencejobstate.h"
13 #include "ekos/manager/meridianflipstate.h"
14 #include "customproperties.h"
15 #include "ekos/ekos.h"
16 #include "ekos/mount/mount.h"
17 #include "indi/indicamera.h"
18 #include "indi/indidustcap.h"
19 #include "indi/indidome.h"
20 #include "indi/indilightbox.h"
21 #include "indi/indimount.h"
22 #include "ekos/scheduler/schedulerjob.h"
23 #include "ekos/auxiliary/darkprocessor.h"
24 #include "dslrinfodialog.h"
25 #include "ui_limits.h"
26 
27 #include <QTimer>
28 #include <QUrl>
29 #include <QtDBus>
30 
31 #include <memory>
32 
33 class QProgressIndicator;
34 class QTableWidgetItem;
35 class KDirWatch;
36 class RotatorSettings;
37 
38 /**
39  * @namespace Ekos
40  * @short Ekos is an advanced Astrophotography tool for Linux.
41  * It is based on a modular extensible framework to perform common astrophotography tasks. This includes highly accurate GOTOs using astrometry solver, ability to measure and correct polar alignment errors ,
42  * auto-focus & auto-guide capabilities, and capture of single or stack of images with filter wheel support.\n
43  * Features:
44  * - Control your telescope, CCD (& DSLRs), filter wheel, focuser, guider, adaptive optics unit, and any INDI-compatible auxiliary device from Ekos.
45  * - Extremely accurate GOTOs using astrometry.net solver (both Online and Offline solvers supported).
46  * - Load & Slew: Load a FITS image, slew to solved coordinates, and center the mount on the exact image coordinates in order to get the same desired frame.
47  * - Measure & Correct Polar Alignment errors using astrometry.net solver.
48  * - Auto and manual focus modes using Half-Flux-Radius (HFR) method.
49  * - Automated unattended meridian flip. Ekos performs post meridian flip alignment, calibration, and guiding to resume the capture session.
50  * - Automatic focus between exposures when a user-configurable HFR limit is exceeded.
51  * - Automatic focus between exposures when the temperature has changed a lot since last focus.
52  * - Auto guiding with support for automatic dithering between exposures and support for Adaptive Optics devices in addition to traditional guiders.
53  * - Powerful sequence queue for batch capture of images with optional prefixes, timestamps, filter wheel selection, and much more!
54  * - Export and import sequence queue sets as Ekos Sequence Queue (.esq) files.
55  * - Center the telescope anywhere in a captured FITS image or any FITS with World Coordinate System (WCS) header.
56  * - Automatic flat field capture, just set the desired ADU and let Ekos does the rest!
57  * - Automatic abort and resumption of exposure tasks if guiding errors exceed a user-configurable value.
58  * - Support for dome slaving.
59  * - Complete integration with KStars Observation Planner and SkyMap
60  * - Integrate with all INDI native devices.
61  * - Powerful scripting capabilities via \ref EkosDBusInterface "DBus."
62  *
63  * The primary class is Ekos::Manager. It handles startup and shutdown of local and remote INDI devices, manages and orchesterates the various Ekos modules, and provides advanced DBus
64  * interface to enable unattended scripting.
65  *
66  * @author Jasem Mutlaq
67  * @version 1.9
68  */
69 namespace Ekos
70 {
71 class SequenceJob;
72 
73 /**
74  *@class Capture
75  *@short Captures single or sequence of images from a CCD.
76  * The capture class support capturing single or multiple images from a CCD, it provides a powerful sequence queue with filter wheel selection. Any sequence queue can be saved as Ekos Sequence Queue (.esq).
77  * All image capture operations are saved as Sequence Jobs that encapsulate all the different options in a capture process. The user may select in sequence autofocusing by setting a maximum HFR limit. When the limit
78  * is exceeded, it automatically trigger autofocus operation. The capture process can also be linked with guide module. If guiding deviations exceed a certain threshold, the capture operation aborts until
79  * the guiding deviation resume to acceptable levels and the capture operation is resumed.
80  *@author Jasem Mutlaq
81  *@version 1.4
82  */
83 class Capture : public QWidget, public Ui::Capture
84 {
85  Q_OBJECT
86  Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Capture")
87  Q_PROPERTY(Ekos::CaptureState status READ status NOTIFY newStatus)
88  Q_PROPERTY(QString targetName READ getTargetName WRITE setTargetName)
89  Q_PROPERTY(QString observerName MEMBER m_ObserverName)
90  Q_PROPERTY(QString opticalTrain READ opticalTrain WRITE setOpticalTrain)
91  Q_PROPERTY(QString camera READ camera)
92  Q_PROPERTY(QString filterWheel READ filterWheel)
93  Q_PROPERTY(QString filter READ filter WRITE setFilter)
94  Q_PROPERTY(bool coolerControl READ hasCoolerControl WRITE setCoolerControl)
95  Q_PROPERTY(QStringList logText READ logText NOTIFY newLog)
96 
97  public:
98  typedef enum
99  {
100  ADU_LEAST_SQUARES,
101  ADU_POLYNOMIAL
102  } ADUAlgorithm;
103 
104  typedef enum
105  {
106  NOT_PREVIEW,
107  LOCAL_PREVIEW,
108  REMOTE_PREVIEW
109  } FilenamePreviewType;
110 
111  Capture();
112  ~Capture();
113 
114  /** @defgroup CaptureDBusInterface Ekos DBus Interface - Capture Module
115  * Ekos::Capture interface provides advanced scripting capabilities to capture image sequences.
116  * @{
117  */
118 
119 
120  /** DBUS interface function.
121  * select the CCD device from the available CCD drivers.
122  * @param device The CCD device name
123  */
124  Q_SCRIPTABLE QString camera();
125 
126  /** DBUS interface function.
127  * select the filter device from the available filter drivers. The filter device can be the same as the CCD driver if the filter functionality was embedded within the driver.
128  * @param device The filter device name
129  */
130  Q_SCRIPTABLE QString filterWheel();
131 
132  /** DBUS interface function.
133  * select the filter name from the available filters in case a filter device is active.
134  * @param filter The filter name
135  */
136  Q_SCRIPTABLE bool setFilter(const QString &filter);
137  Q_SCRIPTABLE QString filter();
138 
139  /** DBUS interface function.
140  * Aborts any current jobs and remove all sequence queue jobs.
141  */
142  Q_SCRIPTABLE Q_NOREPLY void clearSequenceQueue();
143 
144  /** DBUS interface function.
145  * Returns the overall sequence queue status. If there are no jobs pending, it returns "Invalid". If all jobs are idle, it returns "Idle". If all jobs are complete, it returns "Complete". If one or more jobs are aborted
146  * it returns "Aborted" unless it was temporarily aborted due to guiding deviations, then it would return "Suspended". If one or more jobs have errors, it returns "Error". If any jobs is under progress, returns "Running".
147  */
148  Q_SCRIPTABLE QString getSequenceQueueStatus();
149 
150  /** DBUS interface function.
151  * Loads the Ekos Sequence Queue file in the Sequence Queue. Jobs are appended to existing jobs.
152  * @param fileURL full URL of the filename
153  * @param ignoreTarget ignore target defined in the sequence queue file (necessary for using the target of the scheduler)
154  */
155  Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, bool ignoreTarget = false);
156 
157  /** DBUS interface function.
158  * Saves the Sequence Queue to the Ekos Sequence Queue file.
159  * @param fileURL full URL of the filename
160  */
161  Q_SCRIPTABLE bool saveSequenceQueue(const QString &path);
162 
163  /** DBUS interface function.
164  * Enables or disables the maximum guiding deviation and sets its value.
165  * @param enable If true, enable the guiding deviation check, otherwise, disable it.
166  * @param value if enable is true, it sets the maximum guiding deviation in arcsecs. If the value is exceeded, the capture operation is aborted until the value falls below the value threshold.
167  */
168  Q_SCRIPTABLE Q_NOREPLY void setMaximumGuidingDeviation(bool enable, double value);
169 
170  /** DBUS interface function.
171  * Enables or disables the in sequence focus and sets Half-Flux-Radius (HFR) limit.
172  * @param enable If true, enable the in sequence auto focus check, otherwise, disable it.
173  * @param HFR if enable is true, it sets HFR in pixels. After each exposure, the HFR is re-measured and if it exceeds the specified value, an autofocus operation will be commanded.
174  */
175  Q_SCRIPTABLE Q_NOREPLY void setInSequenceFocus(bool enable, double HFR);
176 
177  /** DBUS interface function.
178  * Does the CCD has a cooler control (On/Off) ?
179  */
180  Q_SCRIPTABLE bool hasCoolerControl();
181 
182  /** DBUS interface function.
183  * Set the CCD cooler ON/OFF
184  *
185  */
186  Q_SCRIPTABLE bool setCoolerControl(bool enable);
187 
188  /** DBUS interface function.
189  * @return Returns the percentage of completed captures in all active jobs
190  */
191  Q_SCRIPTABLE double getProgressPercentage();
192 
193  /** DBUS interface function.
194  * @return Returns the number of jobs in the sequence queue.
195  */
196  Q_SCRIPTABLE int getJobCount()
197  {
198  return m_captureModuleState->allJobs().count();
199  }
200 
201  /** DBUS interface function.
202  * @return Returns the number of pending uncompleted jobs in the sequence queue.
203  */
204  Q_SCRIPTABLE int getPendingJobCount();
205 
206  /** DBUS interface function.
207  * @return Returns ID of current active job if any, or -1 if there are no active jobs.
208  */
209  Q_SCRIPTABLE int getActiveJobID();
210 
211  /** DBUS interface function.
212  * @return Returns time left in seconds until active job is estimated to be complete.
213  */
214  Q_SCRIPTABLE int getActiveJobRemainingTime();
215 
216  /** DBUS interface function.
217  * @return Returns overall time left in seconds until all jobs are estimated to be complete
218  */
219  Q_SCRIPTABLE int getOverallRemainingTime();
220 
221  /** DBUS interface function.
222  * @param id job number. Job IDs start from 0 to N-1.
223  * @return Returns the job state (Idle, In Progress, Error, Aborted, Complete)
224  */
225  Q_SCRIPTABLE QString getJobState(int id);
226 
227  /** DBUS interface function.
228  * @param id job number. Job IDs start from 0 to N-1.
229  * @return Returns the job filter name.
230  */
231  Q_SCRIPTABLE QString getJobFilterName(int id);
232 
233  /** DBUS interface function.
234  * @param id job number. Job IDs start from 0 to N-1.
235  * @return Returns The number of images completed capture in the job.
236  */
237  Q_SCRIPTABLE int getJobImageProgress(int id);
238 
239  /** DBUS interface function.
240  * @param id job number. Job IDs start from 0 to N-1.
241  * @return Returns the total number of images to capture in the job.
242  */
243  Q_SCRIPTABLE int getJobImageCount(int id);
244 
245  /** DBUS interface function.
246  * @param id job number. Job IDs start from 0 to N-1.
247  * @return Returns the number of seconds left in an exposure operation.
248  */
249  Q_SCRIPTABLE double getJobExposureProgress(int id);
250 
251  /** DBUS interface function.
252  * @param id job number. Job IDs start from 0 to N-1.
253  * @return Returns the total requested exposure duration in the job.
254  */
255  Q_SCRIPTABLE double getJobExposureDuration(int id);
256 
257  /** DBUS interface function.
258  * @param id job number. Job IDs start from 0 to N-1.
259  * @return Returns the frame type (light, dark, ...) of the job.
260  */
261  Q_SCRIPTABLE CCDFrameType getJobFrameType(int id);
262 
263  /** DBUS interface function.
264  * Clear in-sequence focus settings. It sets the autofocus HFR to zero so that next autofocus value is remembered for the in-sequence focusing.
265  */
266  Q_SCRIPTABLE Q_NOREPLY void clearAutoFocusHFR();
267 
268  /** DBUS interface function.
269  * Jobs will NOT be checked for progress against the file system and will be always assumed as new jobs.
270  */
271  Q_SCRIPTABLE Q_NOREPLY void ignoreSequenceHistory();
272 
273  /** DBUS interface function.
274  * Set count of already completed frames. This is required when we have identical external jobs
275  * with identical paths, but we need to continue where we left off. For example, if we have 3 identical
276  * jobs, each capturing 5 images. Let's suppose 9 images were captured before. If the count for this signature
277  * is set to 1, then we continue to capture frame #2 even though the number of completed images is already
278  * larger than required count (5). It is mostly used in conjunction with Ekos Scheduler.
279  */
280  Q_SCRIPTABLE Q_NOREPLY void setCapturedFramesMap(const QString &signature, int count);
281 
282 
283  /** DBUS interface function.
284  * List of logging entries for the capture module.
285  */
286  Q_SCRIPTABLE QStringList logText()
287  {
288  return m_LogText;
289  }
290 
291  /** DBUS interface function.
292  * Single text string holding all log lines for the capture module.
293  */
294  Q_SCRIPTABLE QString getLogText()
295  {
296  return m_LogText.join("\n");
297  }
298 
299  /** DBUS interface function.
300  * Status of the capture module
301  */
302  Q_SCRIPTABLE CaptureState status()
303  {
304  return m_captureModuleState->getCaptureState();
305  }
306  /** @} end of group CaptureDBusInterface */
307 
308 
309  // ////////////////////////////////////////////////////////////////////
310  // Changing the devices used by Capture
311  // ////////////////////////////////////////////////////////////////////
312 
313  /**
314  * @brief Add new Camera
315  * @param device pointer to camera device.
316  * @return True if added successfully, false if duplicate or failed to add.
317  */
318  bool setCamera(ISD::Camera *device);
319 
320  // FIXME add support for guide head, not implemented yet
321  void addGuideHead(ISD::Camera *device);
322 
323  /**
324  * @brief Add new Filter Wheel
325  * @param device pointer to filter wheel device.
326  * @return True if added successfully, false if duplicate or failed to add.
327  */
328  bool setFilterWheel(ISD::FilterWheel *device);
329 
330  /**
331  * @brief Add new Dome
332  * @param device pointer to Dome device.
333  * @return True if added successfully, false if duplicate or failed to add.
334  */
335  bool setDome(ISD::Dome *device);
336 
337  /**
338  * @brief Add new Dust Cap
339  * @param device pointer to Dust Cap device.
340  * @return True if added successfully, false if duplicate or failed to add.
341  */
342  bool setDustCap(ISD::DustCap *device);
343 
344  /**
345  * @brief Add new Light Box
346  * @param device pointer to Light Box device.
347  * @return True if added successfully, false if duplicate or failed to add.
348  */
349  bool setLightBox(ISD::LightBox *device);
350 
351  /**
352  * @brief Add new Mount
353  * @param device pointer to Mount device.
354  * @return True if added successfully, false if duplicate or failed to add.
355  */
356  bool setMount(ISD::Mount *device);
357 
358  /**
359  * @brief Add new Rotator
360  * @param device pointer to rotator device.
361  * @return True if added successfully, false if duplicate or failed to add.
362  */
363  bool setRotator(ISD::Rotator *device);
364 
365  // Restart driver
366  void reconnectDriver(const QString &camera, const QString &filterWheel);
367 
368  /**
369  * @brief Generic method for removing any connected device.
370  */
372 
373  /**
374  * @brief registerNewModule Register an Ekos module as it arrives via DBus
375  * and create the appropriate DBus interface to communicate with it.
376  * @param name of module
377  */
378  void registerNewModule(const QString &name);
379 
380  // ////////////////////////////////////////////////////////////////////
381  // Synchronize UI with device parameters
382  // ////////////////////////////////////////////////////////////////////
383 
384  void syncFrameType(const QString &name);
385  void syncTelescopeInfo();
386  void syncCameraInfo();
387  void syncFilterInfo();
388 
389  // ////////////////////////////////////////////////////////////////////
390  // Optical Train handling
391  // ////////////////////////////////////////////////////////////////////
392  void setupOpticalTrainManager();
393  void refreshOpticalTrain();
394 
395  QString opticalTrain() const
396  {
397  return opticalTrainCombo->currentText();
398  }
399  void setOpticalTrain(const QString &value)
400  {
401  opticalTrainCombo->setCurrentText(value);
402  }
403 
404  // ////////////////////////////////////////////////////////////////////
405  // Filter Manager and filters
406  // ////////////////////////////////////////////////////////////////////
407  void setupFilterManager();
408 
409  const QSharedPointer<FilterManager> &filterManager() const
410  {
411  return m_FilterManager;
412  }
413 
414  /**
415  * @brief checkFilter Refreshes the filter wheel information in the capture module.
416  */
417  void checkFilter();
418 
419  /**
420  * @brief shortcut for updating the current filter information for the state machine
421  */
423 
424  // ////////////////////////////////////////////////////////////////////
425  // Read and write access for EkosLive
426  // ////////////////////////////////////////////////////////////////////
427 
428  /**
429  * @brief getSequence Return the JSON representation of the current sequeue queue
430  * @return Reference to JSON array containing sequence queue jobs.
431  */
432  const QJsonArray &getSequence() const
433  {
434  return m_SequenceArray;
435  }
436 
437  /**
438  * @brief setSettings Set capture settings
439  * @param settings list of settings
440  */
441  void setPresetSettings(const QJsonObject &settings);
442 
443  /**
444  * @brief getSettings get current capture settings as a JSON Object
445  * @return settings as JSON object
446  */
448 
449  /**
450  * @brief setFileSettings Set File Settings
451  * @param settings as JSON object
452  */
453  void setFileSettings(const QJsonObject &settings);
454  /**
455  * @brief getFileSettings Compile file setting
456  * @return File settings as JSON object
457  */
459 
460  /**
461  * @brief setCalibrationSettings Set Calibration settings
462  * @param settings as JSON object
463  */
464  void setCalibrationSettings(const QJsonObject &settings);
465  /**
466  * @brief getCalibrationSettings Get Calibration settings
467  * @return settings as JSON object
468  */
470 
471  /**
472  * @brief setLimitSettings Set limit settings
473  * @param settings as JSON Object
474  */
475  void setLimitSettings(const QJsonObject &settings);
476  /**
477  * @brief getLimitSettings Get Limit Settings
478  * @return settings as JSON Object
479  */
481 
482  /**
483  * @brief setVideoLimits sets the buffer size and max preview fps for live preview
484  * @param maxBufferSize in bytes
485  * @param maxPreviewFPS number of frames per second
486  * @return True if value is updated, false otherwise.
487  */
488  bool setVideoLimits(uint16_t maxBufferSize, uint16_t maxPreviewFPS);
489 
490  // ////////////////////////////////////////////////////////////////////
491  // DSLR handling
492  // ////////////////////////////////////////////////////////////////////
493 
494  /**
495  * @brief addDSLRInfo Save DSLR Info the in the database. If the interactive dialog was open, close it.
496  * @param model Camera name
497  * @param maxW Maximum width in pixels
498  * @param maxH Maximum height in pixels
499  * @param pixelW Pixel horizontal size in microns
500  * @param pixelH Pizel vertical size in microns
501  */
502  void addDSLRInfo(const QString &model, uint32_t maxW, uint32_t maxH, double pixelW, double pixelH);
503 
504  /**
505  * @brief syncDSLRToTargetChip Syncs INDI driver CCD_INFO property to the DSLR values.
506  * This include Max width, height, and pixel sizes.
507  * @param model Name of camera driver in the DSLR database.
508  */
509  void syncDSLRToTargetChip(const QString &model);
510 
511  public slots:
512  // ////////////////////////////////////////////////////////////////////
513  // Main capturing actions
514  // ////////////////////////////////////////////////////////////////////
515 
516  /** \addtogroup CaptureDBusInterface
517  * @{
518  */
519 
520  /** DBUS interface function.
521  * @brief Start the execution of the Capture::SequenceJob list #jobs.
522  *
523  * Starting the execution of the Capture::SequenceJob list selects the first job
524  * from the ist that may be executed and starts to prepare the job (@see prepareJob()).
525  *
526  * Several factors determine, which of the jobs will be selected:
527  * - First, the list is searched to find the first job that is marked as idle or aborted.
528  * - If none is found, it is checked whether ignoring job progress is set. If yes,
529  * all jobs are are reset (@see reset()) and the first one from the list is selected.
530  * If no, the user is asked whether the jobs should be reset. If the user declines,
531  * starting is aborted.
532  */
533  Q_SCRIPTABLE Q_NOREPLY void start();
534 
535  /** DBUS interface function.
536  * Stops currently running jobs:
537  * CAPTURE_IDLE: capture in idle state waiting for further action (e.g. single sequence
538  * is complete, next one starting)
539  * CAPTURE_COMPLETE: all capture sequences are complete
540  * CAPTURE_ABORT: capture aborted either by user interaction or by a technical error
541  * CAPTURE_SUSPEND: capture suspended and waiting to be restarted
542  * @param targetState status of the job after stop
543  */
544  Q_SCRIPTABLE Q_NOREPLY void stop(CaptureState targetState = CAPTURE_IDLE);
545 
546  /** DBUS interface function.
547  * Aborts all jobs and mark current state as ABORTED. It simply calls stop(CAPTURE_ABORTED)
548  */
549  Q_SCRIPTABLE Q_NOREPLY void abort()
550  {
552  }
553 
554  /** DBUS interface function.
555  * Aborts all jobs and mark current state as SUSPENDED. It simply calls stop(CAPTURE_SUSPENDED)
556  * The only difference between SUSPENDED and ABORTED it that capture module can automatically resume a suspended
557  * state on its own without external trigger once the right conditions are met. When whatever reason caused the module
558  * to go into suspended state ceases to exist, the capture module automatically resumes. On the other hand, ABORTED state
559  * must be started via an external programmatic or user trigger (e.g. click the start button again).
560  */
561  Q_SCRIPTABLE Q_NOREPLY void suspend()
562  {
564  }
565  /** DBUS interface function.
566  * @brief pause Pauses the Sequence Queue progress AFTER the current capture is complete.
567  */
568  Q_SCRIPTABLE Q_NOREPLY void pause();
569 
570  /** DBUS interface function.
571  * @brief toggleSequence Toggle sequence state depending on its current state.
572  * 1. If paused, then resume sequence.
573  * 2. If idle or completed, then start sequence.
574  * 3. Otherwise, abort current sequence.
575  */
576  Q_SCRIPTABLE Q_NOREPLY void toggleSequence();
577 
578 
579  /** DBUS interface function.
580  * Toggle video streaming if supported by the device.
581  * @param enabled Set to true to start video streaming, false to stop it if active.
582  */
583  Q_SCRIPTABLE Q_NOREPLY void toggleVideo(bool enabled);
584 
585 
586  /** DBus interface function
587  * @brief restartCamera Restarts the INDI driver associated with a camera. Remote and Local drivers are supported.
588  * @param name Name of camera to restart. If a driver defined multiple cameras, they would be removed and added again
589  * after driver restart.
590  * @note Restarting camera should only be used as a last resort when it comes completely unresponsive. Due the complex
591  * nature of driver interactions with Ekos, restarting cameras can lead to unexpected behavior.
592  */
593  Q_SCRIPTABLE Q_NOREPLY void restartCamera(const QString &name);
594 
595  /** DBus interface function
596  * @brief Set the name of the target to be captured.
597  */
598  Q_SCRIPTABLE Q_NOREPLY void setTargetName(const QString &newTargetName);
599  Q_SCRIPTABLE QString getTargetName()
600  {
601  return m_TargetName;
602  }
603 
604  /** @}*/
605 
606  // ////////////////////////////////////////////////////////////////////
607  // Capture actons
608  // ////////////////////////////////////////////////////////////////////
609  /**
610  * @brief captureOne Capture one preview image
611  */
612  void captureOne();
613 
614  /**
615  * @brief startFraming Like captureOne but repeating.
616  */
617  void startFraming();
618 
619  /**
620  * @brief generateDarkFlats Generate a list of dark flat jobs from available flat frames.
621  */
622  void generateDarkFlats();
623 
624  /**
625  * @brief addJob Add a new job to the sequence queue given the settings in the GUI.
626  * @param preview True if the job is a preview job, otherwise, it is added as a batch job.
627  * @param isDarkFlat True if the job is a dark flat job, false otherwise.
628  * @param filenamePreview if the job is to generate a preview filename
629  * @return True if job is added successfully, false otherwise.
630  */
631  bool addJob(bool preview = false, bool isDarkFlat = false, FilenamePreviewType filenamePreview = NOT_PREVIEW);
632 
633  // ////////////////////////////////////////////////////////////////////
634  // public capture settings
635  // ////////////////////////////////////////////////////////////////////
636  /**
637  * @brief seqCount Set required number of images to capture in one sequence job
638  * @param count number of images to capture
639  */
640  void setCount(uint16_t count)
641  {
642  captureCountN->setValue(count);
643  }
644 
645  /**
646  * @brief setDelay Set delay between capturing images within a sequence in seconds
647  * @param delay numbers of seconds to wait before starting the next image.
648  */
649  void setDelay(uint16_t delay)
650  {
651  captureDelayN->setValue(delay);
652  }
653 
654  /**
655  * @brief Slot receiving the update of the current target distance.
656  * @param targetDiff distance to the target in arcseconds.
657  */
658  void updateTargetDistance(double targetDiff);
659 
660  /**
661  * @brief checkCamera Refreshes the CCD information in the capture module.
662  */
663  void checkCamera();
664 
665 
666  /**
667  * @brief processCCDNumber Process number properties arriving from CCD. Currently, only CCD and Guider frames are processed.
668  * @param nvp pointer to number property.
669  */
670  void processCameraNumber(INDI::Property prop);
671 
672 
673  /**
674  * @brief removeJob Remove a job sequence from the queue
675  * @param index Row index for job to remove, if left as -1 (default), the currently selected row will be removed.
676  * if no row is selected, the last job shall be removed.
677  * @param true if sequence is removed. False otherwise.
678  */
679  bool removeJob(int index = -1);
680 
681  /**
682  * @brief MeridianFlipState Access to the meridian flip state machine
683  */
685  void setMeridianFlipState(QSharedPointer<MeridianFlipState> state);
686 
687  // ////////////////////////////////////////////////////////////////////
688  // UI controls
689  // ////////////////////////////////////////////////////////////////////
690  /**
691  * @brief addSequenceJob Add a sequence job. This simply calls addJob below with both preview and isDarkFlat set to false.
692  * @return return result of addJob(..)
693  */
694  bool addSequenceJob();
695 
696  void removeJobFromQueue();
697 
698  /**
699  * @brief moveJobUp Move the job in the sequence queue one place up.
700  */
701  void moveJobUp();
702 
703  /**
704  * @brief moveJobDown Move the job in the sequence queue one place down.
705  */
706  void moveJobDown();
707 
708  /**
709  * @brief setTemperature Set the target CCD temperature in the GUI settings.
710  */
711  void setTargetTemperature(double temperature)
712  {
713  cameraTemperatureN->setValue(temperature);
714  }
715 
716  void setForceTemperature(bool enabled)
717  {
718  cameraTemperatureS->setChecked(enabled);
719  }
720 
721  /**
722  * @brief showTemperatureRegulation Toggle temperature regulation dialog which sets temperature ramp and threshold
723  */
725 
726  // Clear Camera Configuration
727  void clearCameraConfiguration();
728 
729  // ////////////////////////////////////////////////////////////////////
730  // slots handling device and module events
731  // ////////////////////////////////////////////////////////////////////
732 
733  /**
734  * @brief captureStarted Manage the result when capturing has been started
735  */
736  void captureStarted(CAPTUREResult rc);
737 
738  /**
739  * @brief setGuideDeviation Set the guiding deviation as measured by the guiding module. Abort capture
740  * if deviation exceeds user value. Resume capture if capture was aborted and guiding
741  * deviations are below user value.
742  * @param delta_ra Deviation in RA in arcsecs from the selected guide star.
743  * @param delta_dec Deviation in DEC in arcsecs from the selected guide star.
744  */
745  void setGuideDeviation(double delta_ra, double delta_dec);
746 
747  void setGuideChip(ISD::CameraChip *guideChip);
748 
749  /**
750  * @brief updateCCDTemperature Update CCD temperature in capture module.
751  * @param value Temperature in celcius.
752  */
753  void updateCCDTemperature(double value);
754 
755  // Auto Focus
756  /**
757  * @brief setFocusStatus Forward the new focus state to the capture module state machine
758  */
759  void setFocusStatus(FocusState state);
760 
761  /**
762  * @brief updateFocusStatus Handle new focus state
763  */
764  void updateFocusStatus(FocusState state);
765 
766  void setFocusTemperatureDelta(double focusTemperatureDelta, double absTemperature);
767 
768  /**
769  * @brief setHFR Receive the measured HFR value of the latest frame
770  */
771  void setHFR(double newHFR, int)
772  {
773  m_captureModuleState->getRefocusState()->setFocusHFR(newHFR);
774  }
775 
776  // Filter
777  void setFilterStatus(FilterState filterState);
778 
779  // Guide
780  void setGuideStatus(GuideState state);
781 
782  // Align
783  void setAlignStatus(AlignState state);
784  void setAlignResults(double orientation, double ra, double de, double pixscale);
785 
786  // Update Mount module status
787  void setMountStatus(ISD::Mount::Status newState);
788 
789  // Meridian flip interface
790  void updateMFMountState(MeridianFlipState::MeridianFlipMountState status);
791 
792  // ////////////////////////////////////////////////////////////////////
793  // Module logging
794  // ////////////////////////////////////////////////////////////////////
795  void clearLog();
796  void appendLogText(const QString &);
797 
798 
799 private slots:
800 
801  // ////////////////////////////////////////////////////////////////////
802  // UI controls
803  // ////////////////////////////////////////////////////////////////////
804  void checkFrameType(int index);
805  void resetFrame();
806  void updateCaptureCountDown(int deltaMillis);
807  void saveFITSDirectory();
808 
809  // Sequence Queue
810  void loadSequenceQueue();
811  void saveSequenceQueue();
812  void saveSequenceQueueAs();
813 
814  // Jobs
815  void resetJobs();
816  bool selectJob(QModelIndex i);
817  void editJob(QModelIndex i);
818  void resetJobEdit();
819  /**
820  * @brief executeJob Start the execution of #activeJob by initiating updatePreCaptureCalibrationStatus().
821  */
822  void executeJob();
823 
824  // Flat field
825  void openCalibrationDialog();
826 
827  // Observer
828  void showObserverDialog();
829 
830  // Cooler
831  void setCoolerToggled(bool enabled);
832 
833  // ////////////////////////////////////////////////////////////////////
834  // slots handling device and module events
835  // ////////////////////////////////////////////////////////////////////
836  void setExposureProgress(ISD::CameraChip *tChip, double value, IPState state);
837 
838  /**
839  * @brief setNewRemoteFile Report a new remote file
840  */
841  void setNewRemoteFile(QString file);
842 
843  // AutoGuide
844  void checkGuideDeviationTimeout();
845 
846  // Script Manager
847  void handleScriptsManager();
848 
849  // capture scripts
850  void scriptFinished(int exitCode, QProcess::ExitStatus status);
851 
852  void setVideoStreamEnabled(bool enabled);
853 
854  /**
855  * @brief Listen to device property changes (temperature, rotator) that are triggered by
856  * SequenceJob.
857  */
858  void updatePrepareState(CaptureState prepareState);
859 
860  // Rotator
861  void updateRotatorAngle(double value);
862  void setRotatorReversed(bool toggled);
863 
864  /**
865  * @brief setDownloadProgress update the Capture Module and Summary
866  * Screen's estimate of how much time is left in the download
867  */
868  void setDownloadProgress();
869 
870  signals:
871  Q_SCRIPTABLE void newLog(const QString &text);
872  Q_SCRIPTABLE void meridianFlipStarted();
873  Q_SCRIPTABLE void guideAfterMeridianFlip();
874  Q_SCRIPTABLE void newStatus(CaptureState status);
875  Q_SCRIPTABLE void captureComplete(const QVariantMap &metadata);
876 
877  void newFilterStatus(FilterState state);
878 
879  void ready();
880 
881  // signals to the sequence job
882  void prepareCapture();
883 
884  // device status
885  void newGuiderDrift(double deviation_rms);
886 
887  // communication with other modules
888  void checkFocus(double);
889  void resetFocus();
890  void abortFocus();
891  void suspendGuiding();
892  void resumeGuiding();
893  void newImage(SequenceJob *job, const QSharedPointer<FITSData> &data);
894  void newExposureProgress(SequenceJob *job);
895  void newDownloadProgress(double);
896  void sequenceChanged(const QJsonArray &sequence);
897  void settingsUpdated(const QJsonObject &settings);
898  void newLocalPreview(const QString &preview);
899  void dslrInfoRequested(const QString &cameraName);
900  void driverTimedout(const QString &deviceName);
901 
902  // Signals for the Analyze tab.
903  void captureStarting(double exposureSeconds, const QString &filter);
904  void captureAborted(double exposureSeconds);
905 
906  // Filter Manager
907  void filterManagerUpdated(ISD::FilterWheel *device);
908 
909  void trainChanged();
910 
911  private:
912  // ////////////////////////////////////////////////////////////////////
913  // capture process steps
914  // ////////////////////////////////////////////////////////////////////
915  /**
916  * @brief captureImage Initiates image capture in the active job.
917  */
918  void captureImage();
919 
920  /**
921  * @brief newFITS process new FITS data received from camera. Update status of active job and overall sequence.
922  * @param bp pointer to blob containing FITS data
923  */
924  void processData(const QSharedPointer<FITSData> &data);
925 
926 
927  /**
928  * @brief Connect or disconnect the camera device
929  * @param connection flag if connect (=true) or disconnect (=false)
930  */
931  void connectCamera(bool connection);
932 
933  /**
934  * @brief processPreCaptureCalibrationStage Execute the tasks that need to be completed before capturing may start.
935  *
936  * For light frames, checkLightFramePendingTasks() is called.
937  *
938  * @return IPS_OK if all necessary tasks have been completed
939  */
940  IPState processPreCaptureCalibrationStage();
941  bool processPostCaptureCalibrationStage();
942 
943  /**
944  * @brief updatePreCaptureCalibrationStatusThis is a wrapping loop for processPreCaptureCalibrationStage(),
945  * which contains all checks before captureImage() may be called.
946  *
947  * If processPreCaptureCalibrationStage() returns IPS_OK (i.e. everything is ready so that
948  * capturing may be started), captureImage() is called. Otherwise, it waits for a second and
949  * calls itself again.
950  */
951  void updatePreCaptureCalibrationStatus();
952 
953  /**
954  * @brief prepareJob Update the counters of existing frames and continue with prepareActiveJob(), if there exist less
955  * images than targeted. If enough images exist, continue with processJobCompletion().
956  */
957  void prepareJob(SequenceJob *job);
958 
959  /**
960  * @brief prepareActiveJobStage1 Check for pre job script to execute. If none, move to stage 2
961  */
962  void prepareActiveJobStage1();
963  /**
964  * @brief prepareActiveJobStage2 Reset #calibrationStage and continue with preparePreCaptureActions().
965  */
966  void prepareActiveJobStage2();
967 
968  /**
969  * @brief preparePreCaptureActions Trigger setting the filter, temperature, (if existing) the rotator angle and
970  * let the #activeJob execute the preparation actions before a capture may
971  * take place (@see SequenceJob::prepareCapture()).
972  *
973  * After triggering the settings, this method returns. This mechanism is slightly tricky, since it
974  * asynchronous and event based and works as collaboration between Capture and SequenceJob. Capture has
975  * the connection to devices and SequenceJob knows the target values.
976  *
977  * Each time Capture receives an updated value - e.g. the current CCD temperature
978  * (@see updateCCDTemperature()) - it informs the #activeJob about the current CCD temperature.
979  * SequenceJob checks, if it has reached the target value and if yes, sets this action as as completed.
980  *
981  * As soon as all actions are completed, SequenceJob emits a prepareComplete() event, which triggers
982  * executeJob() from the Capture module.
983  */
984  void preparePreCaptureActions();
985 
986  /**
987  * @brief Check all tasks that might be pending before capturing may start.
988  *
989  * The following checks are executed:
990  * 1. Are there any pending jobs that failed? If yes, return with IPS_ALERT.
991  * 2. Has pausing been initiated (@see checkPausing()).
992  * 3. Is a meridian flip already running (@see m_MeridianFlipState->checkMeridianFlipRunning()) or ready
993  * for execution (@see m_captureModuleState->checkMeridianFlipReady()).
994  * 4. Is a post meridian flip alignment running (@see checkAlignmentAfterFlip()).
995  * 5. Is post flip guiding required or running (@see checkGuidingAfterFlip().
996  * 6. Is the guiding deviation below the expected limit (@see setGuideDeviation(double,double)).
997  * 7. Is dithering required or ongoing (@see checkDithering()).
998  * 8. Is re-focusing required or ongoing (@see startFocusIfRequired()).
999  * 9. Has guiding been resumed and needs to be restarted (@see resumeGuiding())
1000  *
1001  * If none of this is true, everything is ready and capturing may be started.
1002  *
1003  * @return IPS_OK iff no task is pending, IPS_BUSY otherwise (or IPS_ALERT if a problem occured)
1004  */
1005  IPState checkLightFramePendingTasks();
1006 
1007  /**
1008  * @brief Manage the capture process after a captured image has been successfully downloaded from the camera.
1009  *
1010  * When a image frame has been captured and downloaded successfully, send the image to the client (if configured)
1011  * and execute the book keeping for the captured frame. After this, either processJobCompletion() is executed
1012  * in case that the job is completed, and resumeSequence() otherwise.
1013  *
1014  * Book keeping means:
1015  * - increase / decrease the counters for focusing and dithering
1016  * - increase the frame counter
1017  * - update the average download time
1018  *
1019  * @return IPS_BUSY if pausing is requested, IPS_OK otherwise.
1020  */
1021  IPState setCaptureComplete();
1022 
1023  /**
1024  * @brief processJobCompletionStage1 Process job completion. In stage 1 when simply check if the is a post-job script to be running
1025  * if yes, we run it and wait until it is done before we move to stage2
1026  */
1027  void processJobCompletionStage1();
1028 
1029  /**
1030  * @brief processJobCompletionStage2 Stop execution of the current sequence and check whether there exists a next sequence
1031  * and start it, if there is a next one to be started (@see resumeSequence()).
1032  */
1033  void processJobCompletionStage2();
1034 
1035  /**
1036  * @brief checkNextExposure Try to start capturing the next exposure (@see startNextExposure()).
1037  * If startNextExposure() returns, that there are still some jobs pending,
1038  * we wait for 1 second and retry to start it again.
1039  * If one of the pending preparation jobs has problems, the looping stops.
1040  */
1041  void checkNextExposure();
1042 
1043  // check if a pause has been planned
1044  bool checkPausing();
1045 
1046  /**
1047  * @brief resumeSequence Try to continue capturing.
1048  *
1049  * Take the active job, if there is one, or search for the next one that is either
1050  * idle or aborted. If a new job is selected, call prepareJob(*SequenceJob) to prepare it and
1051  * resume guiding (TODO: is this not part of the preparation?). If the current job is still active,
1052  * initiate checkNextExposure().
1053  *
1054  * @return IPS_OK if there is a job that may be continued, IPS_BUSY otherwise.
1055  */
1056  IPState resumeSequence();
1057 
1058  /**
1059  * @brief startNextExposure Ensure that all pending preparation tasks are be completed (focusing, dithering, etc.)
1060  * and start the next exposure.
1061  *
1062  * Checks of pending preparations depends upon the frame type:
1063  *
1064  * - For light frames, pending preparations like focusing, dithering etc. needs
1065  * to be checked before each single frame capture. efore starting to capture the next light frame,
1066  * checkLightFramePendingTasks() is called to check if all pending preparation tasks have
1067  * been completed successfully. As soon as this is the case, the sequence timer
1068  * #seqTimer is started to wait the configured delay and starts capturing the next image.
1069  *
1070  * - For bias, dark and flat frames, preparation jobs are only executed when starting a sequence.
1071  * Hence, for these frames we directly start the sequence timer #seqTimer.
1072  *
1073  * @return IPS_OK, iff all pending preparation jobs are completed (@see checkLightFramePendingTasks()).
1074  * In that case, the #seqTimer is started to wait for the configured settling delay and then
1075  * capture the next image (@see Capture::captureImage). In case that a pending task aborted,
1076  * IPS_IDLE is returned.
1077  */
1078  IPState startNextExposure();
1079 
1080  // If exposure timed out, let's handle it.
1081  void processCaptureTimeout();
1082 
1083  /**
1084  * @brief processCaptureError Handle when image capture fails
1085  * @param type error type
1086  */
1087  void processCaptureError(ISD::Camera::ErrorType type);
1088 
1089  double setCurrentADU(double value);
1090 
1091  // Propagate meridian flip state changes to the UI
1092  void updateMeridianFlipStage(MeridianFlipState::MFStage stage);
1093 
1094  void processGuidingFailed();
1095 
1096  // ////////////////////////////////////////////////////////////////////
1097  // helper functions
1098  // ////////////////////////////////////////////////////////////////////
1099  /**
1100  * @brief checkSeqBoundary Determine the next file number sequence.
1101  * That is, if we have file1.png and file2.png, then the next
1102  * sequence should be file3.png.
1103  */
1104  void checkSeqBoundary();
1105 
1106  // Filename preview
1107  void generatePreviewFilename();
1108  QString previewFilename(FilenamePreviewType = LOCAL_PREVIEW);
1109 
1110  double getEstimatedDownloadTime();
1111 
1112  /**
1113  * @brief Set the currently active sequence job. Use this function to ensure
1114  * that everything is cleaned up properly.
1115  */
1116  void setActiveJob(SequenceJob *value);
1117 
1118  /**
1119  * @brief setDirty Set dirty bit to indicate sequence queue file was modified and needs saving.
1120  */
1121  void setDirty();
1122 
1123  void setBusy(bool enable);
1124 
1125  /* Capture */
1126  /**
1127  * @brief updateSequencePrefix Update the prefix for the sequence of images
1128  * to be captured.
1129  */
1130  void updateSequencePrefix(const QString &newPrefix);
1131 
1132  void llsq(QVector<double> x, QVector<double> y, double &a, double &b);
1133 
1134  bool isModelinDSLRInfo(const QString &model);
1135 
1136  void createDSLRDialog();
1137 
1138  void resetFrameToZero();
1139 
1140  // short cut for all guiding states that indicate guiding in state GUIDING
1141  bool isActivelyGuiding();
1142 
1143  /**
1144  * @brief generateScriptArguments Generate argument list to pass to capture script
1145  * @return generates argument list consisting of one argument -metadata followed by JSON-formatted key:value pair:
1146  * -ts UNIX timestamp
1147  * -image full path to captured image (if any)
1148  * -size size of file in bytes (if any)
1149  * -job {name, index}
1150  * -capture {name, index}
1151  * -filter
1152  * TODO depending on user feedback.
1153  */
1154  QStringList generateScriptArguments() const;
1155 
1156  /**
1157  * @brief Determine the overall number of target frames with the same signature.
1158  * Assume capturing RGBLRGB, where in each sequence job there is only one frame.
1159  * For "L" the result will be 1, for "R" it will be 2 etc.
1160  * @param frame signature (typically the filter name)
1161  * @return
1162  */
1163  int getTotalFramesCount(QString signature);
1164 
1165  /**
1166  * @brief setDarkFlatExposure Given a dark flat job, find the exposure suitable from it by searching for
1167  * completed flat frames.
1168  * @param job Dark flat job
1169  * @return True if a matching exposure is found and set, false otherwise.
1170  * @warning This only works if the flat frames were captured in the same live session.
1171  * If the flat frames were captured in another session (i.e. Ekos restarted), then all automatic exposure
1172  * calculation results are discarded since Ekos does not save this information to the sequene file.
1173  * Possible solution is to write to a local config file to keep this information persist between sessions.
1174  */
1175  bool setDarkFlatExposure(SequenceJob *job);
1176 
1177  /**
1178  * @brief Sync refocus options to the GUI settings
1179  */
1180  void syncRefocusOptionsFromGUI();
1181 
1182  // ////////////////////////////////////////////////////////////////////
1183  // UI controls
1184  // ////////////////////////////////////////////////////////////////////
1185  /**
1186  * @brief setBinning Set binning
1187  * @param horBin Horizontal binning
1188  * @param verBin Vertical binning
1189  */
1190  void setBinning(int horBin, int verBin)
1191  {
1192  captureBinHN->setValue(horBin);
1193  captureBinVN->setValue(verBin);
1194  }
1195 
1196  /**
1197  * @brief setISO Set index of ISO list.
1198  * @param index index of ISO list.
1199  */
1200  void setISO(int index)
1201  {
1202  captureISOS->setCurrentIndex(index);
1203  }
1204 
1205  // reset = 0 --> Do not reset
1206  // reset = 1 --> Full reset
1207  // reset = 2 --> Only update limits if needed
1208  void updateFrameProperties(int reset = 0);
1209  void syncGUIToJob(SequenceJob *job);
1210  // DSLR Info
1211  void cullToDSLRLimits();
1212  //void syncDriverToDSLRLimits();
1213 
1214  // selection of a job
1215  void selectedJobChanged(QModelIndex current, QModelIndex previous);
1216 
1217  // Change filter name in INDI
1218  void editFilterName();
1219 
1220  // ////////////////////////////////////////////////////////////////////
1221  // device control
1222  // ////////////////////////////////////////////////////////////////////
1223  // Gain
1224  // This sets and gets the custom properties target gain
1225  // it does not access the ccd gain property
1226  void setGain(double value);
1227  double getGain();
1228 
1229  void setOffset(double value);
1230  double getOffset();
1231 
1232  /**
1233  * @brief processCCDNumber Process number properties arriving from CCD. Currently, only CCD and Guider frames are processed.
1234  * @param nvp pointer to number property.
1235  */
1236  void processCCDNumber(INumberVectorProperty *nvp);
1237 
1238  // ////////////////////////////////////////////////////////////////////
1239  // XML capture sequence file handling
1240  // ////////////////////////////////////////////////////////////////////
1241  bool processJobInfo(XMLEle *root, bool ignoreTarget = false);
1242 
1243  // ////////////////////////////////////////////////////////////////////
1244  // Attributes
1245  // ////////////////////////////////////////////////////////////////////
1246  double seqExpose { 0 };
1247  int seqTotalCount;
1248  int seqCurrentCount { 0 };
1249  // time left of the current exposure
1250  QTime imageCountDown;
1251  double lastRemainingFrameTimeMS;
1252  // time left for the current sequence
1253  QTime sequenceCountDown;
1254 
1255  // Timer for starting the next capture sequence with delay
1256  // @see startNextExposure()
1257  QTimer *seqDelayTimer { nullptr };
1258  QString seqPrefix;
1259  int nextSequenceID { 0 };
1260  int seqFileCount { 0 };
1261  bool isBusy { false };
1262  bool m_isFraming { false };
1263 
1264  // Capture timeout timer
1265  QTimer captureTimeout;
1266  uint8_t m_CaptureTimeoutCounter { 0 };
1267  uint8_t m_DeviceRestartCounter { 0 };
1268 
1269  bool useGuideHead { false };
1270  bool autoGuideReady { false};
1271 
1272  QString m_TargetName;
1273  QString m_ObserverName;
1274 
1275  // Currently active sequence job.
1276  // DO NOT SET IT MANUALLY, USE {@see setActiveJob()} INSTEAD!
1277  SequenceJob *activeJob { nullptr };
1278  QSharedPointer<CaptureDeviceAdaptor> m_captureDeviceAdaptor;
1279  QSharedPointer<CaptureModuleState> m_captureModuleState;
1280 
1281  QPointer<QDBusInterface> mountInterface;
1282 
1283  QSharedPointer<FITSData> m_ImageData;
1284 
1285  QStringList m_LogText;
1286  QUrl m_SequenceURL;
1287  bool m_Dirty { false };
1288  bool m_JobUnderEdit { false };
1289 
1290  // Fast Exposure
1291  bool m_RememberFastExposure {false};
1292 
1293  // Flat field automation
1294  QVector<double> ExpRaw, ADURaw;
1295  double targetADU { 0 };
1296  double targetADUTolerance { 1000 };
1297  ADUAlgorithm targetADUAlgorithm { ADU_LEAST_SQUARES};
1298  SkyPoint wallCoord;
1299  bool preMountPark { false };
1300  bool preDomePark { false };
1301  FlatFieldDuration flatFieldDuration { DURATION_MANUAL };
1302  FlatFieldSource flatFieldSource { SOURCE_MANUAL };
1303  bool lightBoxLightEnabled { false };
1304  QMap<ScriptTypes, QString> m_Scripts;
1305 
1306  QUrl dirPath;
1307 
1308  // Misc
1309  bool ignoreJobProgress { true };
1310  bool suspendGuideOnDownload { false };
1311  QJsonArray m_SequenceArray;
1312 
1313  // CCD Chip frame settings
1315 
1316  /// CCD device needed for focus operation
1317  ISD::Camera *m_Camera { nullptr };
1318  /// Optional device filter
1319  ISD::FilterWheel *m_FilterWheel { nullptr };
1320  /// Dust Cap
1321  ISD::DustCap *m_DustCap { nullptr };
1322  /// LightBox
1323  ISD::LightBox *m_LightBox { nullptr };
1324  /// Rotator
1325  ISD::Rotator *m_Rotator { nullptr };
1326  /// Dome
1327  ISD::Dome *m_Dome { nullptr };
1328  /// Mount
1329  ISD::Mount *m_Mount { nullptr };
1330 
1331  // Post capture script
1332  QProcess m_CaptureScript;
1333  uint8_t m_CaptureScriptType {0};
1334 
1335  // Rotator Settings
1336  std::unique_ptr<RotatorSettings> m_RotatorControlPanel;
1337 
1338  std::unique_ptr<CustomProperties> customPropertiesDialog;
1339  std::unique_ptr<DSLRInfo> dslrInfoDialog;
1340 
1341  // DSLR Infos
1342  QList<QMap<QString, QVariant>> DSLRInfos;
1343 
1344  // Captured Frames Map
1345  SchedulerJob::CapturedFramesMap capturedFramesMap;
1346 
1347  // Controls
1348  double GainSpinSpecialValue { INVALID_VALUE };
1349  double OffsetSpinSpecialValue { INVALID_VALUE };
1350 
1351  // Dark Processor
1352  QPointer<DarkProcessor> m_DarkProcessor;
1353  std::unique_ptr<Ui::Limits> m_LimitsUI;
1354  QPointer<QDialog> m_LimitsDialog;
1355 
1356  QList<double> downloadTimes;
1357  QElapsedTimer m_DownloadTimer;
1358  QTimer downloadProgressTimer;
1359  QVariantMap m_Metadata;
1360 
1361  QSharedPointer<FilterManager> m_FilterManager;
1362 
1363  bool FilterEnabled {false};
1364  bool ExpEnabled {false};
1365  bool TimeStampEnabled {false};
1366 };
1367 }
Q_OBJECTQ_OBJECT
bool addJob(bool preview=false, bool isDarkFlat=false, FilenamePreviewType filenamePreview=NOT_PREVIEW)
addJob Add a new job to the sequence queue given the settings in the GUI.
Definition: capture.cpp:2749
const QJsonArray & getSequence() const
getSequence Return the JSON representation of the current sequeue queue
Definition: capture.h:432
Q_SCRIPTABLE int getOverallRemainingTime()
DBUS interface function.
Definition: capture.cpp:4673
Q_SCRIPTABLE Q_NOREPLY void setCapturedFramesMap(const QString &signature, int count)
DBUS interface function.
Definition: capture.cpp:5906
void setTargetTemperature(double temperature)
setTemperature Set the target CCD temperature in the GUI settings.
Definition: capture.h:711
void captureOne()
captureOne Capture one preview image
Definition: capture.cpp:2285
Q_PROPERTY(...)
void setFocusStatus(FocusState state)
setFocusStatus Forward the new focus state to the capture module state machine
Definition: capture.cpp:3539
void processCameraNumber(INDI::Property prop)
processCCDNumber Process number properties arriving from CCD.
Definition: capture.cpp:1617
Q_SCRIPTABLE Q_NOREPLY void ignoreSequenceHistory()
DBUS interface function.
Definition: capture.cpp:4350
Q_SCRIPTABLE int getJobImageCount(int id)
DBUS interface function.
Definition: capture.cpp:4629
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:69
Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, bool ignoreTarget=false)
DBUS interface function.
Definition: capture.cpp:3695
void generateDarkFlats()
generateDarkFlats Generate a list of dark flat jobs from available flat frames.
Definition: capture.cpp:6583
Q_SCRIPTABLE Q_NOREPLY void stop(CaptureState targetState=CAPTURE_IDLE)
DBUS interface function.
Definition: capture.cpp:949
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
Q_SCRIPTABLE QStringList logText()
DBUS interface function.
Definition: capture.h:286
Q_CLASSINFO(Name, Value)
void setDelay(uint16_t delay)
setDelay Set delay between capturing images within a sequence in seconds
Definition: capture.h:649
void captureStarted(CAPTUREResult rc)
captureStarted Manage the result when capturing has been started
Definition: capture.cpp:2440
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS interface function.
Definition: capture.cpp:834
Q_SCRIPTABLE QString getLogText()
DBUS interface function.
Definition: capture.h:294
bool setMount(ISD::Mount *device)
Add new Mount.
Definition: capture.cpp:688
Q_SCRIPTABLE double getJobExposureProgress(int id)
DBUS interface function.
Definition: capture.cpp:4640
bool setLightBox(ISD::LightBox *device)
Add new Light Box.
Definition: capture.cpp:745
void updateCCDTemperature(double value)
updateCCDTemperature Update CCD temperature in capture module.
Definition: capture.cpp:2724
Q_SCRIPTABLE Q_NOREPLY void setInSequenceFocus(bool enable, double HFR)
DBUS interface function.
Definition: capture.cpp:4699
Q_SCRIPTABLE Q_NOREPLY void toggleVideo(bool enabled)
DBUS interface function.
Definition: capture.cpp:5584
Q_SCRIPTABLE bool setFilter(const QString &filter)
DBUS interface function.
Definition: capture.cpp:1688
Q_SCRIPTABLE bool setCoolerControl(bool enable)
DBUS interface function.
Definition: capture.cpp:5141
Q_SCRIPTABLE Q_NOREPLY void setMaximumGuidingDeviation(bool enable, double value)
DBUS interface function.
Definition: capture.cpp:4692
Q_SCRIPTABLE CCDFrameType getJobFrameType(int id)
DBUS interface function.
Definition: capture.cpp:4662
Q_SCRIPTABLE Q_NOREPLY void clearSequenceQueue()
DBUS interface function.
Definition: capture.cpp:4708
bool setDome(ISD::Dome *device)
Add new Dome.
Definition: capture.cpp:655
Q_SCRIPTABLE int getPendingJobCount()
DBUS interface function.
Definition: capture.cpp:4583
The QProgressIndicator class lets an application display a progress indicator to show that a long tas...
void showTemperatureRegulation()
showTemperatureRegulation Toggle temperature regulation dialog which sets temperature ramp and thresh...
Definition: capture.cpp:6532
Q_SCRIPTABLE Q_NOREPLY void restartCamera(const QString &name)
DBus interface function.
Definition: capture.cpp:6497
void checkCamera()
checkCamera Refreshes the CCD information in the capture module.
Definition: capture.cpp:1083
QJsonObject getCalibrationSettings()
getCalibrationSettings Get Calibration settings
Definition: capture.cpp:6031
Sequence Job is a container for the details required to capture a series of images.
Definition: sequencejob.h:18
void moveJobDown()
moveJobDown Move the job in the sequence queue one place down.
Definition: capture.cpp:3113
Q_SCRIPTABLE int getJobImageProgress(int id)
DBUS interface function.
Definition: capture.cpp:4618
void setCount(uint16_t count)
seqCount Set required number of images to capture in one sequence job
Definition: capture.h:640
bool setFilterWheel(ISD::FilterWheel *device)
Add new Filter Wheel.
Definition: capture.cpp:612
QSharedPointer< MeridianFlipState > getMeridianFlipState()
MeridianFlipState Access to the meridian flip state machine.
Definition: capture.cpp:6606
void checkFilter()
checkFilter Refreshes the filter wheel information in the capture module.
Definition: capture.cpp:1712
Q_SCRIPTABLE QString getJobFilterName(int id)
DBUS interface function.
Definition: capture.cpp:4607
void setLimitSettings(const QJsonObject &settings)
setLimitSettings Set limit settings
Definition: capture.cpp:6048
bool addSequenceJob()
addSequenceJob Add a sequence job.
Definition: capture.cpp:2744
Q_SCRIPTABLE int getActiveJobRemainingTime()
DBUS interface function.
Definition: capture.cpp:4684
@ CAPTURE_IDLE
Definition: ekos.h:93
Q_SCRIPTABLE CaptureState status()
DBUS interface function.
Definition: capture.h:302
CaptureState
Capture states.
Definition: ekos.h:91
Q_SCRIPTABLE int getJobCount()
DBUS interface function.
Definition: capture.h:196
Q_SCRIPTABLE Q_NOREPLY void pause()
DBUS interface function.
Definition: capture.cpp:761
Q_SCRIPTABLE Q_NOREPLY void suspend()
DBUS interface function.
Definition: capture.h:561
void removeDevice(const QSharedPointer< ISD::GenericDevice > &device)
Generic method for removing any connected device.
Definition: capture.cpp:6229
QJsonObject getPresetSettings()
getSettings get current capture settings as a JSON Object
Definition: capture.cpp:4448
void setHFR(double newHFR, int)
setHFR Receive the measured HFR value of the latest frame
Definition: capture.h:771
QString join(const QString &separator) const const
void startFraming()
startFraming Like captureOne but repeating.
Definition: capture.cpp:2302
Q_SCRIPTABLE bool hasCoolerControl()
DBUS interface function.
Definition: capture.cpp:5133
Q_SCRIPTABLE QString getSequenceQueueStatus()
DBUS interface function.
Definition: capture.cpp:4721
@ CAPTURE_ABORTED
Definition: ekos.h:99
void setPresetSettings(const QJsonObject &settings)
setSettings Set capture settings
Definition: capture.cpp:5915
Q_SCRIPTABLE QString getJobState(int id)
DBUS interface function.
Definition: capture.cpp:4596
bool setVideoLimits(uint16_t maxBufferSize, uint16_t maxPreviewFPS)
setVideoLimits sets the buffer size and max preview fps for live preview
Definition: capture.cpp:5612
Captures single or sequence of images from a CCD. The capture class support capturing single or multi...
Definition: capture.h:83
void updateCurrentFilterPosition()
shortcut for updating the current filter information for the state machine
Definition: capture.cpp:1704
Q_SCRIPTABLE Q_NOREPLY void toggleSequence()
DBUS interface function.
Definition: capture.cpp:782
void syncDSLRToTargetChip(const QString &model)
syncDSLRToTargetChip Syncs INDI driver CCD_INFO property to the DSLR values.
Definition: capture.cpp:6443
Q_SCRIPTABLE Q_NOREPLY void abort()
DBUS interface function.
Definition: capture.h:549
QJsonObject getLimitSettings()
getLimitSettings Get Limit Settings
Definition: capture.cpp:6094
Q_SCRIPTABLE int getActiveJobID()
DBUS interface function.
Definition: capture.cpp:4569
Q_SCRIPTABLE Q_NOREPLY void setTargetName(const QString &newTargetName)
DBus interface function.
Definition: capture.cpp:3636
bool setDustCap(ISD::DustCap *device)
Add new Dust Cap.
Definition: capture.cpp:671
@ CAPTURE_SUSPENDED
Definition: ekos.h:98
Q_SCRIPTABLE double getJobExposureDuration(int id)
DBUS interface function.
Definition: capture.cpp:4651
Q_SCRIPTABLE Q_NOREPLY void clearAutoFocusHFR()
DBUS interface function.
Definition: capture.cpp:5149
Q_SCRIPTABLE double getProgressPercentage()
DBUS interface function.
Definition: capture.cpp:4552
void updateTargetDistance(double targetDiff)
Slot receiving the update of the current target distance.
Definition: capture.cpp:2316
bool setRotator(ISD::Rotator *device)
Add new Rotator.
Definition: capture.cpp:717
void registerNewModule(const QString &name)
registerNewModule Register an Ekos module as it arrives via DBus and create the appropriate DBus inte...
Definition: capture.cpp:823
void setFileSettings(const QJsonObject &settings)
setFileSettings Set File Settings
Definition: capture.cpp:5978
void setCalibrationSettings(const QJsonObject &settings)
setCalibrationSettings Set Calibration settings
Definition: capture.cpp:6010
bool removeJob(int index=-1)
removeJob Remove a job sequence from the queue
Definition: capture.cpp:3016
void updateFocusStatus(FocusState state)
updateFocusStatus Handle new focus state
Definition: capture.cpp:3547
void addDSLRInfo(const QString &model, uint32_t maxW, uint32_t maxH, double pixelW, double pixelH)
addDSLRInfo Save DSLR Info the in the database.
Definition: capture.cpp:5837
AlignState
Definition: ekos.h:144
void moveJobUp()
moveJobUp Move the job in the sequence queue one place up.
Definition: capture.cpp:3075
QJsonObject getFileSettings()
getFileSettings Compile file setting
Definition: capture.cpp:5995
void setGuideDeviation(double delta_ra, double delta_dec)
setGuideDeviation Set the guiding deviation as measured by the guiding module.
Definition: capture.cpp:3528
bool setCamera(ISD::Camera *device)
Add new Camera.
Definition: capture.cpp:538
Q_SCRIPTABLE bool saveSequenceQueue(const QString &path)
DBUS interface function.
Definition: capture.cpp:4133
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Mar 27 2023 04:16:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.