Kstars

sequencejobstate.h
1 /* Ekos state machine for a single capture job sequence.
2  SPDX-FileCopyrightText: Wolfgang Reissenberger <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "ekos/ekos.h"
10 #include "indi/indistd.h"
11 #include "indi/indicommon.h"
12 #include "indiapi.h"
13 #include "indi/indidustcap.h"
14 #include "indi/indimount.h"
15 #include "indi/indidome.h"
16 #include "skypoint.h"
17 
18 #include <QWidget>
19 #include <QVector>
20 #include <QMap>
21 
22 namespace Ekos
23 {
24 /* Status of a single {@see SequenceJob}. */
25 typedef enum {
26  JOB_IDLE, /* Initial state, nothing happens. */
27  JOB_BUSY, /* Job is running. */
28  JOB_ERROR, /* Error occured, unresolved. */
29  JOB_ABORTED, /* Job stopped before completion. */
30  JOB_DONE /* Job completed. */
31 } JOBStatus;
32 
33 /* Result when starting to capture {@see SequenceJob::capture(bool, FITSMode)}. */
34 typedef enum
35 {
36  CAPTURE_OK, /* Starting a new capture succeeded. */
37  CAPTURE_FRAME_ERROR, /* Setting frame parameters failed, capture not started. */
38  CAPTURE_BIN_ERROR, /* Setting binning parameters failed, capture not started. */
39  CAPTURE_FILTER_BUSY, /* Filter change needed and not completed, capture not started yet. */
40  CAPTURE_FOCUS_ERROR, /* NOT USED. */
41  CAPTURE_GUIDER_DRIFT_WAIT /* Waiting until guide drift is below the threshold, capture not started yet. */
42 } CAPTUREResult;
43 
44 class SequenceJobState: public QObject
45 {
46  Q_OBJECT
47 
48  friend class SequenceJob;
49  friend class CaptureDeviceAdaptor;
50  // Fixme: too many friends
51  friend class Capture;
52 
53 public:
54  typedef enum
55  {
56  CAL_NONE, /* initial state */
57  CAL_DUSTCAP_PARKING, /* unused */
58  CAL_DUSTCAP_PARKED, /* unused */
59  CAL_LIGHTBOX_ON, /* unused */
60  CAL_SLEWING, /* unused */
61  CAL_SLEWING_COMPLETE, /* unused */
62  CAL_MOUNT_PARKING, /* unused */
63  CAL_MOUNT_PARKED, /* unused */
64  CAL_DOME_PARKING, /* unused */
65  CAL_DOME_PARKED, /* unused */
66  CAL_PRECAPTURE_COMPLETE, /* unused */
67  CAL_CALIBRATION,
68  CAL_CALIBRATION_COMPLETE,
69  CAL_CAPTURING
70  } CalibrationStage;
71 
72  typedef enum {
73  PREP_NONE, /* preparation has not been executed */
74  PREP_BUSY, /* preparation started */
75  PREP_COMPLETED, /* preparation completed */
76  PREP_ABORTED /* preparation aborted (UNUSED) */
77  } PreparationState;
78 
79  typedef enum
80  {
81  CAL_CHECK_TASK,
82  CAL_CHECK_CONFIRMATION,
83  } CalibrationCheckType;
84 
85  typedef enum
86  {
87  CAP_IDLE,
88  CAP_PARKING,
89  CAP_UNPARKING,
90  CAP_PARKED,
91  CAP_ERROR,
92  CAP_UNKNOWN
93  } CapState;
94 
95  typedef enum {
96  CAP_LIGHT_OFF, /* light is on */
97  CAP_LIGHT_ON, /* light is off */
98  CAP_LIGHT_UNKNOWN, /* unknown whether on or off */
99  CAP_LIGHT_BUSY /* light status changing */
100  } LightStatus;
101 
102  typedef enum {
103  WP_NONE, /* slewing to wall position not started */
104  WP_SLEWING, /* slewing to wall position started */
105  WP_SLEW_COMPLETED, /* wall position reached */
106  WP_TRACKING_BUSY, /* turning tracking off running */
107  WP_TRACKING_OFF /* wall position reached, tracking off */
108  } ScopeWallPositionStatus;
109 
110  typedef enum { /* synching the focuser to the focus position */
111  FS_NONE, /* not started */
112  FS_BUSY, /* running */
113  FS_COMPLETED /* completed */
114  } FlatSyncStatus;
115 
116  typedef enum {
117  SHUTTER_YES, /* the CCD has a shutter */
118  SHUTTER_NO, /* the CCD has no shutter */
119  SHUTTER_BUSY, /* determining whether the CCD has a shutter running */
120  SHUTTER_UNKNOWN /* unknown whether the CCD has a shutter */
121  } ShutterStatus;
122 
123  /* Action types to be executed before capturing may start. */
124  typedef enum
125  {
126  ACTION_FILTER, /* Change the filter and wait until the correct filter is set. */
127  ACTION_TEMPERATURE, /* Set the camera chip target temperature and wait until the target temperature has been reached. */
128  ACTION_ROTATOR, /* Set the camera rotator target angle and wait until the target angle has been reached. */
129  ACTION_GUIDER_DRIFT, /* Wait until the guiding deviation is below the configured threshold. */
130  ACTION_PREPARE_LIGHTSOURCE, /* Setup the selected flat lights source. */
131  ACTION_MOUNT_PARK, /* Park the mount. */
132  ACTION_DOME_PARK, /* Park the dome. */
133  ACTION_FLAT_SYNC_FOCUS, /* Move the focuser to the focus position for the selected filter. */
134  ACTION_SCOPE_COVER /* Ensure that the scope cover (if present) is opened. */
135  } PrepareActions;
136 
137  /* State shared across all sequence jobs */
138  class CaptureState: public QObject
139  {
140  public:
141  CaptureState() {};
142  // ////////////////////////////////////////////////////////////////////
143  // capture attributes
144  // ////////////////////////////////////////////////////////////////////
145  // current filter ID
146  int currentFilterID { Ekos::INVALID_VALUE };
147  // Map tracking whether the current value has been initialized.
148  // With this construct we could do a lazy initialization of current values if setCurrent...()
149  // sets this flag to true. This is necessary since we listen to the events, but as long as
150  // the value does not change, there won't be an event.
151  QMap<PrepareActions, bool> isInitialized;
152 
153  // ////////////////////////////////////////////////////////////////////
154  // flat preparation attributes
155  // ////////////////////////////////////////////////////////////////////
156  // flag if telescope has been covered
157  bool telescopeCovered { false };
158  // flag if there is a light box device
159  bool hasLightBox { false };
160  // flag if there is a dust cap device
161  bool hasDustCap { false };
162  // flag if there is a telescope device
163  bool hasTelescope { false };
164  // flag if there is a dome device
165  bool hasDome { false };
166 
167  // ////////////////////////////////////////////////////////////////////
168  // dark preparation attributes
169  // ////////////////////////////////////////////////////////////////////
170  ShutterStatus shutterStatus { SHUTTER_UNKNOWN };
171  };
172 
173  SequenceJobState(const QSharedPointer<CaptureState> &sharedState);
174 
175  /**
176  * @brief Initialize the state machine.
177  * @param frameType frame type for which the preparation should be done
178  */
179  void setFrameType(CCDFrameType frameType);
180 
181  /**
182  * @brief Trigger all peparation actions before a capture may be started.
183  * @param enforceCCDTemp flag if the CCD temperature should be set to the target value.
184  * @param enforceInitialGuidingDrift flag if the initial guiding drift must be below the target value.
185  * @param isPreview flag if the captures are in the preview mode
186  */
187  void prepareLightFrameCapture(bool enforceCCDTemp, bool enforceInitialGuidingDrift, bool isPreview);
188 
189  /**
190  * @brief Initiate tasks required so that capturing of flats may start.
191  * @param enforceCCDTemp flag if the CCD temperature should be set to the target value.
192  * @param isPreview flag if the captures are in the preview mode
193  */
194  void prepareFlatFrameCapture(bool enforceCCDTemp, bool isPreview);
195 
196  /**
197  * @brief Initiate tasks required so that capturing of darks may start.
198  * @param enforceCCDTemp flag if the CCD temperature should be set to the target value.
199  * @param isPreview flag if the captures are in the preview mode
200  */
201  void prepareDarkFrameCapture(bool enforceCCDTemp, bool isPreview);
202 
203  /**
204  * @brief Initiate tasks required so that capturing of bias may start.
205  * @param enforceCCDTemp flag if the CCD temperature should be set to the target value.
206  * @param isPreview flag if the captures are in the preview mode
207  */
208  void prepareBiasFrameCapture(bool enforceCCDTemp, bool isPreview);
209 
210  /**
211  * @brief Set the flag if a maximal initial guiding deviation is required
212  */
213  void setEnforceInitialGuidingDrift(bool enforceInitialGuidingDrift);
214 
215  /**
216  * @brief The current capture sequence job status
217  */
218  JOBStatus getStatus() { return m_status; }
219 
220  /**
221  * @brief Preparation state of the sequence job
222  */
223  PreparationState getPreparationState() const;
224 
225  /**
226  * @brief Reset the status to a dedicated value.
227  * @param status new status, by default {@see JOB_IDLE}
228  */
229  void reset(JOBStatus status = JOB_IDLE) { m_status = status; }
230 
231 public slots:
232  //////////////////////////////////////////////////////////////////////
233  // Slots for device events that change the state.
234  //////////////////////////////////////////////////////////////////////
235 
236  /**
237  * @brief Update the currently active filter ID
238  */
239  void setCurrentFilterID(int value);
240 
241  /**
242  * @brief Update the current CCD temperature
243  */
244  void setCurrentCCDTemperature(double value);
245  /**
246  * @brief Set the target CCD temperature
247  */
248  void setTargetCCDTemperature(double value) { targetTemperature = value; }
249  /**
250  * @brief Update the current guiding deviation.
251  */
252  void setCurrentGuiderDrift(double value);
253  /**
254  * @brief Set the target guiding deviation when capture starts
255  */
256  void setTargetStartGuiderDrift(double value) { targetStartGuiderDrift = value; }
257 
258  /**
259  * @brief Update the current rotator position (calculated from the rotator angle)
260  */
261  void setCurrentRotatorPositionAngle(double currentRotation, IPState state);
262  /**
263  * @brief Set the target rotation angle
264  */
265  void setTargetRotatorAngle(double value) { targetPositionAngle = value; }
266 
267  /**
268  * @brief Cover for the scope with a flats light source done
269  */
270  void manualScopeLightCover(bool closed, bool success);
271  /**
272  * @brief Light box light is on.
273  */
274  void lightBoxLight(bool on);
275  /**
276  * @brief dust cap status change
277  */
278  void dustCapStatusChanged(ISD::DustCap::Status status);
279  /**
280  * @brief telescope status change
281  */
282  void scopeStatusChanged(ISD::Mount::Status status);
283  /**
284  * @brief telescope status change
285  */
286  void scopeParkStatusChanged(ISD::ParkStatus status);
287  /**
288  * @brief dome status change
289  */
290  void domeStatusChanged(ISD::Dome::Status status);
291  /**
292  * @brief flat sync focus status change
293  */
294  void flatSyncFocusChanged(bool completed);
295  /**
296  * @brief CCD has a shutter
297  */
298  void hasShutter(bool present);
299 
300 signals:
301  // communicate that a preparation step needs to be executed
302  void prepareState(Ekos::CaptureState state);
303  // ask for the current device state
304  void readCurrentState(Ekos::CaptureState state);
305  // Capture preparation complete(d)
306  void prepareComplete();
307  // change the rotator angle
308  void setRotatorAngle(double *rawAngle);
309  // set the CCD target temperature
310  void setCCDTemperature(double temp);
311  // set CCD to preview mode
312  void setCCDBatchMode(bool m_preview);
313  // ask for manually covering the scope with a flat light source
314  void askManualScopeLightCover(QString question, QString title);
315  // ask for manually opening the scope cover
316  void askManualScopeLightOpen();
317  // turn light on in the light box
318  void setLightBoxLight(bool on);
319  // turn light on in the dust cap
320  void setDustCapLight(bool on);
321  // park the dust cap
322  void parkDustCap(bool park);
323  // slew the telescope to a target
324  void slewTelescope(SkyPoint &target);
325  // turn scope tracking on and off
326  void setScopeTracking(bool on);
327  // park / unpark telescope
328  void setScopeParked(bool parked);
329  // park / unpark dome
330  void setDomeParked(bool parked);
331  // check if the the focuser needs to be moved to the focus position.
332  void flatSyncFocus(int targetFilterID);
333  // ask whether the CCD has a shutter
334  void queryHasShutter();
335  // abort capturing
336  void abortCapture();
337  // log entry
338  void newLog(QString);
339 
340 private:
341  // current status of the capture sequence job
342  JOBStatus m_status { JOB_IDLE };
343 
344  // Is the capture preparation ready?
345  PreparationState m_PreparationState { PREP_NONE };
346 
347  // ////////////////////////////////////////////////////////////////////
348  // capture preparation relevant flags
349  // ////////////////////////////////////////////////////////////////////
350 
351  // Mapping PrepareActions --> bool marks whether a certain action is completed (=true) or not (=false)
352  QMap<PrepareActions, bool> prepareActions;
353  // This is a workaround for a specific INDI behaviour. If a INDI property is set, it sends this value
354  // back to the clients. If the value does not immediately change to the target value (like e.g. the CCD
355  // temperature), the first value after setting a property must be ignored.
356  QMap<PrepareActions, bool> ignoreNextValue;
357 
358  // capture frame type (light, flat, dark, bias)
359  CCDFrameType m_frameType { FRAME_NONE };
360  // do we shoot a preview?
361  bool m_isPreview { false };
362  // should a certain temperature should be enforced?
363  bool m_enforceTemperature { false };
364  // should the a certain maximal initial guiding drift should be enforced?
365  bool m_enforceInitialGuiding { false };
366 
367  // ////////////////////////////////////////////////////////////////////
368  // flat preparation attributes
369  // ////////////////////////////////////////////////////////////////////
370  // light box light status
371  LightStatus lightBoxLightStatus { CAP_LIGHT_UNKNOWN };
372  // dust cap status
373  CapState dustCapStatus { CAP_UNKNOWN };
374  // telescope status
375  ISD::Mount::Status scopeStatus { ISD::Mount::MOUNT_IDLE };
376  ISD::ParkStatus scopeParkStatus { ISD::PARK_UNKNOWN };
377  // status of the focuser synchronisation
378  FlatSyncStatus flatSyncStatus { FS_NONE };
379  // light source for flat capturing
380  FlatFieldSource flatFieldSource { SOURCE_MANUAL };
381  // wall coordinates for capturing flats with the wall as light source
382  SkyPoint wallCoord;
383  // telescope status for flats using the wall position
384  ScopeWallPositionStatus wpScopeStatus { WP_NONE };
385  // flag if the mount should be parking before capturing
386  bool preMountPark;
387  // dome status
388  ISD::Dome::Status domeStatus { ISD::Dome::DOME_IDLE };
389  // flag if the dome should be parking before capturing
390  bool preDomePark;
391  // flag if auto focus has been completed for the selected filter
392  bool autoFocusReady;
393 
394  // ////////////////////////////////////////////////////////////////////
395  // capture preparation state
396  // ////////////////////////////////////////////////////////////////////
397  /**
398  * @brief Check if all actions are ready and emit {@see prepareComplete()} if all are ready.
399  */
400  void checkAllActionsReady();
401 
402  /**
403  * @brief Check if all preparation actions are completed
404  * @return true if all preparation actions are completed
405  */
406  bool areActionsReady();
407 
408  /**
409  * @brief Clear all actions required for preparation
410  */
411  void setAllActionsReady();
412 
413  /**
414  * @brief Prepare CCD temperature checks
415  */
416  void prepareTemperatureCheck(bool enforceCCDTemp);
417 
418  /**
419  * @brief Before capturing light frames check, if the scope cover is open.
420  * @return IPS_OK if cover closed, IPS_BUSY if not and IPS_ALERT if the
421  * process should be aborted.
422  */
423  IPState checkLightFrameScopeCoverOpen();
424 
425  /**
426  * @brief Check if a certain action has already been initialized
427  */
428  bool isInitialized(PrepareActions action);
429  /**
430  * @brief Set a certain action as initialized
431  */
432  void setInitialized(PrepareActions action, bool init);
433 
434  // ////////////////////////////////////////////////////////////////////
435  // flats preparation state
436  // ////////////////////////////////////////////////////////////////////
437 
438  /**
439  * @brief Check if the selected flats light source is ready.
440  * @return IPS_OK if cover closed, IPS_BUSY if not and IPS_ALERT if the
441  * process should be aborted.
442  */
443  IPState checkFlatsLightSourceReady();
444 
445  /**
446  * @brief Ask the user to place a flat screen onto the telescope
447  * @return IPS_OK if cover closed, IPS_BUSY if not and IPS_ALERT if the
448  * process should be aborted.
449  */
450  IPState checkManualFlatsCoverReady();
451 
452  /**
453  * @brief Check if the telescope cap with internal light source is ready
454  * for capturing flats.
455  * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the
456  * process should be aborted.
457  */
458  IPState checkFlatCapReady();
459 
460  /**
461  * @brief Check if the telescope dust cap is ready for capturing flats or darks.
462  * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the
463  * process should be aborted.
464  */
465  IPState checkDustCapReady(CCDFrameType frameType);
466 
467  /**
468  * @brief Check if the telescope is pointing to the desired position on the wall
469  * for capturing flats.
470  * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the
471  * process should be aborted.
472  */
473  IPState checkWallPositionReady(CCDFrameType frametype);
474 
475  /**
476  * @brief Check mount parking before capturing flats.
477  * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the
478  * process should be aborted.
479  */
480  IPState checkPreMountParkReady();
481 
482  /**
483  * @brief Check dome parking before capturing flats.
484  * @return IPS_OK if cap is closed, IPS_BUSY if not and IPS_ALERT if the
485  * process should be aborted.
486  */
487  IPState checkPreDomeParkReady();
488 
489  /**
490  * @brief Check if the the focuser needs to be moved to the focus position.
491  * @return IPS_OK if cover closed, IPS_BUSY if not and IPS_ALERT if the
492  * process should be aborted.
493  */
494  IPState checkFlatSyncFocus();
495 
496  // ////////////////////////////////////////////////////////////////////
497  // darks preparation state
498  // ////////////////////////////////////////////////////////////////////
499 
500  /**
501  * @brief Check if the CCD has a shutter or not.
502  * @return IPS_OK if ready, IPS_BUSY if running and IPS_ALERT if the
503  * process should be aborted.
504  */
505  IPState checkHasShutter();
506  /**
507  * @brief Check if the scope is covered manually.
508  * @return IPS_OK if ready, IPS_BUSY if running and IPS_ALERT if the
509  * process should be aborted.
510  */
511  IPState checkManualCover();
512 
513  // ////////////////////////////////////////////////////////////////////
514  // Attributes shared across all sequence jobs
515  // ////////////////////////////////////////////////////////////////////
516  QSharedPointer<CaptureState> m_CaptureState;
517 
518  // ////////////////////////////////////////////////////////////////////
519  // sequence job specific states
520  // ////////////////////////////////////////////////////////////////////
521  // target filter ID
522  int targetFilterID { Ekos::INVALID_VALUE };
523  // target temperature
524  double targetTemperature { Ekos::INVALID_VALUE };
525  // target rotation in absolute ticks, NOT angle
526  double targetPositionAngle { Ekos::INVALID_VALUE };
527  // target guiding deviation at start time
528  double targetStartGuiderDrift { 0.0 };
529  // calibration state
530  CalibrationStage calibrationStage { CAL_NONE };
531  // query state for (un)covering the scope
532  CalibrationCheckType coverQueryState { CAL_CHECK_TASK };
533  void prepareRotatorCheck();
534 };
535 
536 }; // namespace
Q_OBJECTQ_OBJECT
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:66
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
Sequence Job is a container for the details required to capture a series of images.
Definition: sequencejob.h:18
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
CaptureState
Capture states.
Definition: ekos.h:91
KGuiItem reset()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:55 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.