Kstars

schedulerjob.h
1 /* Ekos Scheduler Job
2  SPDX-FileCopyrightText: Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "skypoint.h"
10 
11 #include <QUrl>
12 #include <QMap>
13 #include "ksmoon.h"
14 #include "kstarsdatetime.h"
15 #include <QJsonObject>
16 
17 class ArtificialHorizon;
18 class QTableWidgetItem;
19 class QLabel;
20 class KSMoon;
21 class TestSchedulerUnit;
22 class TestEkosSchedulerOps;
23 class dms;
24 
25 class SchedulerJob
26 {
27  public:
28  SchedulerJob();
29 
30  QJsonObject toJson() const;
31 
32  /** @brief States of a SchedulerJob. */
33  typedef enum
34  {
35  JOB_IDLE, /**< Job was just created, and is not evaluated yet */
36  JOB_EVALUATION, /**< Job is being evaluated */
37  JOB_SCHEDULED, /**< Job was evaluated, and has a schedule */
38  JOB_BUSY, /**< Job is being processed */
39  JOB_ERROR, /**< Job encountered a fatal issue while processing, and must be reset manually */
40  JOB_ABORTED, /**< Job encountered a transitory issue while processing, and will be rescheduled */
41  JOB_INVALID, /**< Job has an incorrect configuration, and cannot proceed */
42  JOB_COMPLETE /**< Job finished all required captures */
43  } JOBStatus;
44 
45  /** @brief Running stages of a SchedulerJob. */
46  typedef enum
47  {
48  STAGE_IDLE,
49  STAGE_SLEWING,
50  STAGE_SLEW_COMPLETE,
51  STAGE_FOCUSING,
52  STAGE_FOCUS_COMPLETE,
53  STAGE_ALIGNING,
54  STAGE_ALIGN_COMPLETE,
55  STAGE_RESLEWING,
56  STAGE_RESLEWING_COMPLETE,
57  STAGE_POSTALIGN_FOCUSING,
58  STAGE_POSTALIGN_FOCUSING_COMPLETE,
59  STAGE_GUIDING,
60  STAGE_GUIDING_COMPLETE,
61  STAGE_CAPTURING,
62  STAGE_COMPLETE
63  } JOBStage;
64 
65  /** @brief Conditions under which a SchedulerJob may start. */
66  typedef enum
67  {
68  START_ASAP,
69  START_CULMINATION,
70  START_AT
71  } StartupCondition;
72 
73  /** @brief Conditions under which a SchedulerJob may complete. */
74  typedef enum
75  {
76  FINISH_SEQUENCE,
77  FINISH_REPEAT,
78  FINISH_LOOP,
79  FINISH_AT
80  } CompletionCondition;
81 
82  /** @brief Actions that may be processed when running a SchedulerJob.
83  * FIXME: StepPipeLine is actually a mask, change this into a bitfield.
84  */
85  typedef enum
86  {
87  USE_NONE = 0,
88  USE_TRACK = 1 << 0,
89  USE_FOCUS = 1 << 1,
90  USE_ALIGN = 1 << 2,
91  USE_GUIDE = 1 << 3
92  } StepPipeline;
93 
94  /** @brief Coordinates of the target of this job. */
95  /** @{ */
96  SkyPoint const &getTargetCoords() const
97  {
98  return targetCoords;
99  }
100  void setTargetCoords(const dms &ra, const dms &dec, double djd);
101  /** @} */
102 
103  double getPositionAngle()
104  {
105  return m_PositionAngle;
106  }
107  void setPositionAngle(double value);
108 
109  /** @brief Capture sequence this job uses while running. */
110  /** @{ */
111  QUrl getSequenceFile() const
112  {
113  return sequenceFile;
114  }
115  void setSequenceFile(const QUrl &value);
116  /** @} */
117 
118  /** @brief FITS file whose plate solve produces target coordinates. */
119  /** @{ */
120  QUrl getFITSFile() const
121  {
122  return fitsFile;
123  }
124  void setFITSFile(const QUrl &value);
125  /** @} */
126 
127  /** @brief Minimal target altitude to process this job */
128  /** @{ */
129  double getMinAltitude() const
130  {
131  return minAltitude;
132  }
133  void setMinAltitude(const double &value);
134  /** @} */
135 
136  /** @brief Does this job have a min-altitude parameter. */
137  /** @{ */
138  bool hasMinAltitude() const
139  {
140  return UNDEFINED_ALTITUDE < minAltitude;
141  }
142  static constexpr int UNDEFINED_ALTITUDE = -90;
143  /** @} */
144 
145  /** @brief Does this job have any altitude constraints. */
146  /** @{ */
147  bool hasAltitudeConstraint() const;
148  /** @} */
149 
150  /** @brief Minimal Moon separation to process this job. */
151  /** @{ */
152  double getMinMoonSeparation() const
153  {
154  return minMoonSeparation;
155  }
156  void setMinMoonSeparation(const double &value);
157  /** @} */
158 
159  /** @brief Whether to restrict this job to good weather. */
160  /** @{ */
161  bool getEnforceWeather() const
162  {
163  return enforceWeather;
164  }
165  void setEnforceWeather(bool value);
166  /** @} */
167 
168  /** @brief Mask of actions to process for this job. */
169  /** @{ */
170  StepPipeline getStepPipeline() const
171  {
172  return stepPipeline;
173  }
174  void setStepPipeline(const StepPipeline &value);
175  /** @} */
176 
177  /** @brief Condition under which this job starts. */
178  /** @{ */
179  StartupCondition getStartupCondition() const
180  {
181  return startupCondition;
182  }
183  void setStartupCondition(const StartupCondition &value);
184  /** @} */
185 
186  /** @brief Condition under which this job completes. */
187  /** @{ */
188  CompletionCondition getCompletionCondition() const
189  {
190  return completionCondition;
191  }
192  void setCompletionCondition(const CompletionCondition &value);
193  /** @} */
194 
195  /** @brief Target culmination proximity under which this job starts. */
196  /** @{ */
197  int16_t getCulminationOffset() const
198  {
199  return culminationOffset;
200  }
201  void setCulminationOffset(const int16_t &value);
202  /** @} */
203 
204  /** @brief Timestamp format to use when displaying information about this job. */
205  /** @{ */
206  QString const &getDateTimeDisplayFormat() const
207  {
208  return dateTimeDisplayFormat;
209  }
210  void setDateTimeDisplayFormat(const QString &value);
211  /** @} */
212 
213  /** @brief Original startup condition, as entered by the user. */
214  /** @{ */
215  StartupCondition getFileStartupCondition() const
216  {
217  return fileStartupCondition;
218  }
219  void setFileStartupCondition(const StartupCondition &value);
220  /** @} */
221 
222  /** @brief Original time at which the job must start, as entered by the user. */
223  /** @{ */
224  QDateTime getFileStartupTime() const
225  {
226  return fileStartupTime;
227  }
228  void setFileStartupTime(const QDateTime &value);
229  /** @} */
230 
231  /** @brief Whether this job requires re-focus while running its capture sequence. */
232  /** @{ */
233  bool getInSequenceFocus() const
234  {
235  return inSequenceFocus;
236  }
237  void setInSequenceFocus(bool value);
238  /** @} */
239 
240  /** @brief Job priority, low priority value means most prioritary. */
241  /** @{ */
242  uint8_t getPriority() const
243  {
244  return priority;
245  }
246  void setPriority(const uint8_t &value);
247  /** @} */
248 
249  /** @brief Whether to restrict job to night time. */
250  /** @{ */
251  bool getEnforceTwilight() const
252  {
253  return enforceTwilight;
254  }
255  void setEnforceTwilight(bool value);
256  /** @} */
257 
258  /** @brief Whether to restrict job to night time. */
259  /** @{ */
260  bool getEnforceArtificialHorizon() const
261  {
262  return enforceArtificialHorizon;
263  }
264  void setEnforceArtificialHorizon(bool value);
265  /** @} */
266 
267  /** @brief Current name of the scheduler job. */
268  /** @{ */
269  QString getName() const
270  {
271  return name;
272  }
273  void setName(const QString &value);
274  /** @} */
275 
276  /** @brief Shortcut to widget cell for job name in the job queue table. */
277  /** @{ */
278  QTableWidgetItem *getNameCell() const
279  {
280  return nameCell;
281  }
282  void setNameCell(QTableWidgetItem *cell);
283  /** @} */
284 
285  /** @brief Current state of the scheduler job.
286  * Setting state to JOB_ABORTED automatically resets the startup characteristics.
287  * Setting state to JOB_INVALID automatically resets the startup characteristics and the duration estimation.
288  * @see SchedulerJob::setStartupCondition, SchedulerJob::setFileStartupCondition, SchedulerJob::setStartupTime
289  * and SchedulerJob::setFileStartupTime.
290  */
291  /** @{ */
292  JOBStatus getState() const
293  {
294  return state;
295  }
296  QDateTime getStateTime() const
297  {
298  return stateTime;
299  }
300  QDateTime getLastAbortTime() const
301  {
302  return lastAbortTime;
303  }
304  QDateTime getLastErrorTime() const
305  {
306  return lastErrorTime;
307  }
308  void setState(const JOBStatus &value);
309  /** @} */
310 
311  /** @brief Shortcut to widget cell for job state in the job queue table. */
312  /** @{ */
313  QTableWidgetItem *getStatusCell() const
314  {
315  return statusCell;
316  }
317  void setStatusCell(QTableWidgetItem *cell);
318  /** @} */
319 
320  /** @brief Current stage of the scheduler job. */
321  /** @{ */
322  JOBStage getStage() const
323  {
324  return stage;
325  }
326  void setStage(const JOBStage &value);
327  /** @} */
328 
329  /** @brief Shortcut to widget cell for job stage in the job queue table. */
330  /** @{ */
331  QTableWidgetItem *getStageCell() const
332  {
333  return stageCell;
334  }
335  void setStageCell(QTableWidgetItem *cell);
336  QLabel *getStageLabel() const
337  {
338  return stageLabel;
339  }
340  void setStageLabel(QLabel *label);
341  /** @} */
342 
343  /** @brief Number of captures required in the associated sequence. */
344  /** @{ */
345  int getSequenceCount() const
346  {
347  return sequenceCount;
348  }
349  void setSequenceCount(const int count);
350  /** @} */
351 
352  /** @brief Number of captures completed in the associated sequence. */
353  /** @{ */
354  int getCompletedCount() const
355  {
356  return completedCount;
357  }
358  void setCompletedCount(const int count);
359  /** @} */
360 
361  /** @brief Shortcut to widget cell for captures in the job queue table. */
362  /** @{ */
363  QTableWidgetItem *getCaptureCountCell() const
364  {
365  return captureCountCell;
366  }
367  void setCaptureCountCell(QTableWidgetItem *value);
368  /** @} */
369 
370  /** @brief Time at which the job must start. */
371  /** @{ */
372  QDateTime getStartupTime() const
373  {
374  return startupTime;
375  }
376  void setStartupTime(const QDateTime &value);
377  /** @} */
378 
379  /** @brief Shortcut to widget cell for startup time in the job queue table. */
380  /** @{ */
381  QTableWidgetItem *getStartupCell() const
382  {
383  return startupCell;
384  }
385  void setStartupCell(QTableWidgetItem *value);
386  /** @} */
387 
388  /** @brief Shortcut to widget cell for altitude in the job queue table. */
389  /** @{ */
390  QTableWidgetItem *getAltitudeCell() const
391  {
392  return altitudeCell;
393  }
394  void setAltitudeCell(QTableWidgetItem *value);
395  /** @} */
396 
397  /** @brief Time after which the job is considered complete. */
398  /** @{ */
399  QDateTime getCompletionTime() const
400  {
401  return completionTime;
402  }
403  QDateTime getGreedyCompletionTime() const
404  {
405  return greedyCompletionTime;
406  }
407  const QString &getStopReason() const
408  {
409  return stopReason;
410  }
411  void setStopReason(const QString &reason)
412  {
413  stopReason = reason;
414  }
415  void setCompletionTime(const QDateTime &value);
416  /** @} */
417  void setGreedyCompletionTime(const QDateTime &value);
418 
419  /** @brief Shortcut to widget cell for completion time in the job queue table. */
420  /** @{ */
421  QTableWidgetItem *getCompletionCell() const
422  {
423  return completionCell;
424  }
425  void setCompletionCell(QTableWidgetItem *value);
426  /** @} */
427 
428  /** @brief Estimation of the time the job will take to process. */
429  /** @{ */
430  int64_t getEstimatedTime() const
431  {
432  return estimatedTime;
433  }
434  void setEstimatedTime(const int64_t &value);
435  /** @} */
436 
437  /** @brief Shortcut to widget cell for estimated time in the job queue table. */
438  /** @{ */
439  QTableWidgetItem *getEstimatedTimeCell() const
440  {
441  return estimatedTimeCell;
442  }
443  void setEstimatedTimeCell(QTableWidgetItem *value);
444  /** @} */
445 
446  /** @brief Estimation of the lead time the job will have to process. */
447  /** @{ */
448  int64_t getLeadTime() const
449  {
450  return leadTime;
451  }
452  void setLeadTime(const int64_t &value);
453  /** @} */
454 
455  /** @brief Shortcut to widget cell for estimated time in the job queue table. */
456  /** @{ */
457  QTableWidgetItem *getLeadTimeCell() const
458  {
459  return leadTimeCell;
460  }
461  void setLeadTimeCell(QTableWidgetItem *value);
462  /** @} */
463 
464  /** @brief Current score of the scheduler job. */
465  /** @{ */
466  int getScore() const
467  {
468  return score;
469  }
470  void setScore(int value);
471  /** @} */
472 
473  /** @brief Shortcut to widget cell for job score in the job queue table. */
474  /** @{ */
475  QTableWidgetItem *getScoreCell() const
476  {
477  return scoreCell;
478  }
479  void setScoreCell(QTableWidgetItem *value);
480  /** @} */
481 
482  /** @brief Whether this job requires light frames, or only calibration frames. */
483  /** @{ */
484  bool getLightFramesRequired() const
485  {
486  return lightFramesRequired;
487  }
488  void setLightFramesRequired(bool value);
489  /** @} */
490 
491  /** @brief Number of times this job must be repeated (in terms of capture count). */
492  /** @{ */
493  uint16_t getRepeatsRequired() const
494  {
495  return repeatsRequired;
496  }
497  void setRepeatsRequired(const uint16_t &value);
498  /** @} */
499 
500  /** @brief Number of times this job still has to be repeated (in terms of capture count). */
501  /** @{ */
502  uint16_t getRepeatsRemaining() const
503  {
504  return repeatsRemaining;
505  }
506  void setRepeatsRemaining(const uint16_t &value);
507  /** @} */
508 
509  /** @brief The map of capture counts for this job, keyed by its capture storage signatures. */
510  /** @{ */
511  typedef QMap<QString, uint16_t> CapturedFramesMap;
512  const CapturedFramesMap &getCapturedFramesMap() const
513  {
514  return capturedFramesMap;
515  }
516  void setCapturedFramesMap(const CapturedFramesMap &value);
517  /** @} */
518 
519  /** @brief Refresh all cells connected to this SchedulerJob. */
520  void updateJobCells();
521 
522  /** @brief Resetting a job to original values:
523  * - idle state and stage
524  * - original startup, none if asap, else user original setting
525  * - duration not estimated
526  * - full repeat count
527  */
528  void reset();
529 
530  /** @brief Determining whether a SchedulerJob is a duplicate of another.
531  * @param a_job is the other SchedulerJob to test duplication against.
532  * @return True if objects are different, but name and sequence file are identical, else false.
533  * @warning This is a weak comparison, but that's what the scheduler looks at to decide completion.
534  */
535  bool isDuplicateOf(SchedulerJob const *a_job) const
536  {
537  return this != a_job && name == a_job->name && sequenceFile == a_job->sequenceFile;
538  }
539 
540  /** @brief Compare ::SchedulerJob instances based on score.
541  * @todo This is a qSort predicate, deprecated in QT5.
542  * @arg a, b are ::SchedulerJob instances to compare.
543  * @return true if the score of b is lower than the score of a.
544  * @return false if the score of b is higher than or equal to the score of a.
545  */
546  static bool decreasingScoreOrder(SchedulerJob const *a, SchedulerJob const *b);
547 
548  /** @brief Compare ::SchedulerJob instances based on priority.
549  * @todo This is a qSort predicate, deprecated in QT5.
550  * @arg a, b are ::SchedulerJob instances to compare.
551  * @return true if the priority of a is lower than the priority of b.
552  * @return false if the priority of a is higher than or equal to the priority of b.
553  */
554  static bool increasingPriorityOrder(SchedulerJob const *a, SchedulerJob const *b);
555 
556  /** @brief Compare ::SchedulerJob instances based on altitude and movement in sky at startup time.
557  * @todo This is a qSort predicate, deprecated in QT5.
558  * @arg a, b are ::SchedulerJob instances to compare.
559  * @arg when is the date/time to use to calculate the altitude to sort with, defaulting to a's startup time.
560  * @note To obtain proper sort between several SchedulerJobs, all should have the same startup time.
561  * @note Use std:bind to bind a specific date/time to this predicate for altitude calculation.
562  * @return true is a is setting but not b.
563  * @return false if b is setting but not a.
564  * @return true otherwise, if the altitude of b is lower than the altitude of a.
565  * @return false otherwise, if the altitude of b is higher than or equal to the altitude of a.
566  */
567  static bool decreasingAltitudeOrder(SchedulerJob const *a, SchedulerJob const *b, QDateTime const &when = QDateTime());
568 
569  /** @brief Compare ::SchedulerJob instances based on startup time.
570  * @todo This is a qSort predicate, deprecated in QT5.
571  * @arg a, b are ::SchedulerJob instances to compare.
572  * @return true if the startup time of a is sooner than the priority of b.
573  * @return false if the startup time of a is later than or equal to the priority of b.
574  */
575  static bool increasingStartupTimeOrder(SchedulerJob const *a, SchedulerJob const *b);
576 
577  /**
578  * @brief getAltitudeScore Get the altitude score of an object. The higher the better
579  * @param when date and time to check the target altitude, now if omitted.
580  * @param altPtr returns the altitude in degrees if not a nullptr.
581  * @return Altitude score. Target altitude below minimum altitude required by job or setting target under 3 degrees below minimum altitude get bad score.
582  */
583  int16_t getAltitudeScore(QDateTime const &when = QDateTime(), double *altPtr = nullptr) const;
584 
585  /**
586  * @brief getMoonSeparationScore Get moon separation score. The further apart, the better, up a maximum score of 20.
587  * @param when date and time to check the moon separation, now if omitted.
588  * @return Moon separation score
589  */
590  int16_t getMoonSeparationScore(QDateTime const &when = QDateTime()) const;
591 
592  /**
593  * @brief getCurrentMoonSeparation Get current moon separation in degrees at current time for the given job
594  * @param job scheduler job
595  * @return Separation in degrees
596  */
597  double getCurrentMoonSeparation() const;
598 
599  /**
600  * @brief calculateNextTime calculate the next time constraints are met (or missed).
601  * @param when date and time to start searching from, now if omitted.
602  * @param constraintsAreMet if true, searches for the next time constrains are met, else missed.
603  * @return The date and time the target meets or misses constraints.
604  */
605  QDateTime calculateNextTime(QDateTime const &when, bool checkIfConstraintsAreMet = true, int increment = 1,
606  QString *reason = nullptr, bool runningJob = false, const QDateTime &until = QDateTime()) const;
607  QDateTime getNextPossibleStartTime(const QDateTime &when, int increment = 1, bool runningJob = false,
608  const QDateTime &until = QDateTime()) const;
609  QDateTime getNextEndTime(const QDateTime &start, int increment = 1, QString *reason = nullptr,
610  const QDateTime &until = QDateTime()) const;
611 
612  /**
613  * @brief calculateCulmination find culmination time adjust for the job offset
614  * @param when date and time to start searching from, now if omitted
615  * @return The date and time the target is in entering the culmination interval, valid if found, invalid if not achievable (currently always valid).
616  */
617  QDateTime calculateCulmination(QDateTime const &when = QDateTime()) const;
618 
619  /**
620  * @brief calculateDawnDusk find the next astronomical dawn and dusk after the current date and time of observation
621  */
622  static void calculateDawnDusk(QDateTime const &when, QDateTime &dawn, QDateTime &dusk);
623 
624  /**
625  * @brief getNextAstronomicalTwilightDawn
626  * @return a local time QDateTime locating the first astronomical dawn after this observation.
627  * @note The dawn time takes into account the Ekos dawn offset.
628  */
629  QDateTime getDawnAstronomicalTwilight() const
630  {
631  return nextDawn;
632  };
633 
634  /**
635  * @brief getDuskAstronomicalTwilight
636  * @return a local-time QDateTime locating the first astronomical dusk after this observation.
637  * @note The dusk time takes into account the Ekos dusk offset.
638  */
639  QDateTime getDuskAstronomicalTwilight() const
640  {
641  return nextDusk;
642  };
643 
644  /**
645  * @brief runsDuringAstronomicalNightTime
646  * @param time uses the time given for the check, or, if not valid (the default) uses the job's startup time.
647  * @return true if the next dawn/dusk event after this observation is the astronomical dawn, else false.
648  * @note This function relies on the guarantee that dawn and dusk are calculated to be the first events after this observation.
649  */
650  bool runsDuringAstronomicalNightTime(const QDateTime &time = QDateTime(), QDateTime *nextPossibleSuccess = nullptr) const;
651 
652  /**
653  * @brief findAltitude Find altitude given a specific time
654  * @param target Target
655  * @param when date time to find altitude
656  * @param is_setting whether target is setting at the argument time (optional).
657  * @param debug outputs calculation to log file (optional).
658  * @return Altitude of the target at the specific date and time given.
659  * @warning This function uses the current KStars geolocation.
660  */
661  static double findAltitude(const SkyPoint &target, const QDateTime &when, bool *is_setting = nullptr, bool debug = false);
662 
663  /**
664  * @brief getMinAltitudeConstraint Find minimum allowed altitude for this job at the given azimuth.
665  * @param azimuth Azimuth
666  * @return Minimum allowed altitude of the target at the specific azimuth.
667  */
668  double getMinAltitudeConstraint(double azimuth, bool *artificialHorizon = nullptr) const;
669 
670  /**
671  * @brief setInitialFilter Set initial filter used in the capture sequence. This is used to pass to focus module.
672  * @param value Filter name of FIRST LIGHT job in the sequence queue, if any.
673  */
674  void setInitialFilter(const QString &value);
675  const QString &getInitialFilter() const;
676 
677  // Convenience debugging methods.
678  static QString jobStatusString(JOBStatus status);
679  static QString jobStageString(JOBStage stage);
680  static QString startupConditionString(SchedulerJob::StartupCondition condition);
681  QString jobStartupConditionString(SchedulerJob::StartupCondition condition) const;
682  static QString completionConditionString(SchedulerJob::CompletionCondition condition);
683  QString jobCompletionConditionString(SchedulerJob::CompletionCondition condition) const;
684 
685  static void enableGraphicsUpdates(bool update)
686  {
687  m_UpdateGraphics = update;
688  }
689 
690  // Clear the cache that keeps results for getNextPossibleStartTime().
691  void clearCache()
692  {
693  startTimeCache.clear();
694  }
695  private:
696  bool runsDuringAstronomicalNightTimeInternal(const QDateTime &time, QDateTime *minDawnDusk,
697  QDateTime *nextPossibleSuccess = nullptr) const;
698 
699  // Private constructor for unit testing.
700  SchedulerJob(KSMoon *moonPtr);
701  friend TestSchedulerUnit;
702  friend TestEkosSchedulerOps;
703 
704  /** @brief Setter used in the unit test to fix the local time. Otherwise getter gets from KStars instance. */
705  /** @{ */
706  static KStarsDateTime getLocalTime();
707  /** @} */
708 
709  /** @brief Setter used in testing to fix the geo location. Otherwise getter gets from KStars instance. */
710  /** @{ */
711  static const GeoLocation *getGeo();
712  static void setGeo(GeoLocation *geo)
713  {
714  storedGeo = geo;
715  }
716  static bool hasGeo()
717  {
718  return storedGeo != nullptr;
719  }
720  /** @} */
721 
722  /** @brief Setter used in testing to fix the artificial horizon. Otherwise getter gets from KStars instance. */
723  /** @{ */
724  static const ArtificialHorizon *getHorizon();
725  static void setHorizon(ArtificialHorizon *horizon)
726  {
727  storedHorizon = horizon;
728  }
729  static bool hasHorizon()
730  {
731  return storedHorizon != nullptr;
732  }
733 
734  /** @} */
735 
736  QString name;
737  SkyPoint targetCoords;
738  double m_PositionAngle { -1 };
739  JOBStatus state { JOB_IDLE };
740  JOBStage stage { STAGE_IDLE };
741 
742  // The time that the job stage was set.
743  // Used by the Greedy Algorithm to decide when to run JOB_ABORTED jobs again.
744  QDateTime stateTime;
745  QDateTime lastAbortTime;
746  QDateTime lastErrorTime;
747 
748  StartupCondition fileStartupCondition { START_ASAP };
749  StartupCondition startupCondition { START_ASAP };
750  CompletionCondition completionCondition { FINISH_SEQUENCE };
751 
752  int sequenceCount { 0 };
753  int completedCount { 0 };
754 
755  QDateTime fileStartupTime;
756  QDateTime startupTime;
757  QDateTime completionTime;
758  // An alternative completionTime field used by the greedy scheduler algorithm.
759  QDateTime greedyCompletionTime;
760  // The reason this job is stopping/will-be stopped.
761  QString stopReason;
762 
763  /* @internal Caches to optimize cell rendering. */
764  /* @{ */
765  double altitudeAtStartup { 0 };
766  double altitudeAtCompletion { 0 };
767  bool isSettingAtStartup { false };
768  bool isSettingAtCompletion { false };
769  /* @} */
770 
771  QUrl sequenceFile;
772  QUrl fitsFile;
773 
774  double minAltitude { UNDEFINED_ALTITUDE };
775  double minMoonSeparation { -1 };
776 
777  bool enforceWeather { false };
778  bool enforceTwilight { false };
779  bool enforceArtificialHorizon { false };
780 
781  QDateTime nextDawn;
782  QDateTime nextDusk;
783 
784  StepPipeline stepPipeline { USE_NONE };
785 
786  /** @internal Widget cell/label shortcuts. */
787  /** @{ */
788  QTableWidgetItem *nameCell { nullptr };
789  QLabel *nameLabel { nullptr };
790  QTableWidgetItem *statusCell { nullptr };
791  QTableWidgetItem *stageCell { nullptr };
792  QLabel *stageLabel { nullptr };
793  QTableWidgetItem *altitudeCell { nullptr };
794  QTableWidgetItem *startupCell { nullptr };
795  QTableWidgetItem *completionCell { nullptr };
796  QTableWidgetItem *estimatedTimeCell { nullptr };
797  QTableWidgetItem *captureCountCell { nullptr };
798  QTableWidgetItem *scoreCell { nullptr };
799  QTableWidgetItem *leadTimeCell { nullptr };
800  /** @} */
801 
802  int score { 0 };
803  int16_t culminationOffset { 0 };
804  uint8_t priority { 10 };
805  int64_t estimatedTime { -1 };
806  int64_t leadTime { 0 };
807  uint16_t repeatsRequired { 1 };
808  uint16_t repeatsRemaining { 1 };
809  bool inSequenceFocus { false };
810  QString m_InitialFilter;
811 
812  QString dateTimeDisplayFormat;
813 
814  bool lightFramesRequired { false };
815 
816  QMap<QString, uint16_t> capturedFramesMap;
817 
818  /// Pointer to Moon object
819  KSMoon *moon { nullptr };
820 
821  // There are times when we pause graphics updates for all jobs.
822  static bool m_UpdateGraphics;
823 
824  // This class is used to cache the results computed in getNextPossibleStartTime()
825  // which is called repeatedly by the Greedy scheduler.
826  // The cache would need to be cleared if something changes that would affect the
827  // start time of jobs (geography, altitide constraints) so it is reset at the start
828  // of all schedule calculations--which does not impact its effectiveness.
829  class StartTimeCache
830  {
831  // Keep track of calls to getNextPossibleStartTime, storing the when, until and result.
832  struct StartTimeComputation
833  {
834  QDateTime from;
835  QDateTime until;
836  QDateTime result;
837  };
838  public:
839  StartTimeCache() {}
840  // Check if the computation has been done, and if so, return the previous result.
841  bool check(const QDateTime &from, const QDateTime &until,
842  QDateTime *result, QDateTime *newFrom) const;
843  // Add a result to the cache.
844  void add(const QDateTime &from, const QDateTime &until, const QDateTime &result) const;
845  // Clear the cache.
846  void clear() const;
847  private:
848  // Made this mutable and all methods const so that the cache could be
849  // used in SchedulerJob const methods.
850  mutable QList<StartTimeComputation> startComputations;
851  };
852  StartTimeCache startTimeCache;
853 
854  // These are used in testing, instead of KStars::Instance() resources
855  static KStarsDateTime *storedLocalTime;
856  static GeoLocation *storedGeo;
857  static ArtificialHorizon *storedHorizon;
858 };
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
Provides necessary information about the Moon. A subclass of SkyObject that provides information need...
Definition: ksmoon.h:25
GeoCoordinates geo(const QVariant &location)
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
QAction * clear(const QObject *recvr, const char *slot, QObject *parent)
KGuiItem add()
void update(Part *part, const QByteArray &data, qint64 dataSize)
const char * name(StandardAction id)
KGuiItem reset()
Relevant data about an observing location on Earth.
Definition: geolocation.h:27
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:58 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.