Changeset View
Changeset View
Standalone View
Standalone View
kstars/ekos/scheduler/scheduler.h
1 | /* Ekos Scheduler Module | 1 | /* Ekos Scheduler Module | ||
---|---|---|---|---|---|
2 | Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com> | 2 | Copyright (C) 2015 Jasem Mutlaq <mutlaqja@ikarustech.com> | ||
3 | 3 | | |||
4 | DBus calls from GSoC 2015 Ekos Scheduler project by Daniel Leu <daniel_mihai.leu@cti.pub.ro> | 4 | DBus calls from GSoC 2015 Ekos Scheduler project by Daniel Leu <daniel_mihai.leu@cti.pub.ro> | ||
5 | 5 | | |||
6 | This application is free software; you can redistribute it and/or | 6 | This application is free software; you can redistribute it and/or | ||
7 | modify it under the terms of the GNU General Public | 7 | modify it under the terms of the GNU General Public | ||
8 | License as published by the Free Software Foundation; either | 8 | License as published by the Free Software Foundation; either | ||
9 | version 2 of the License, or (at your option) any later version. | 9 | version 2 of the License, or (at your option) any later version. | ||
10 | */ | 10 | */ | ||
11 | 11 | | |||
12 | #pragma once | 12 | #pragma once | ||
13 | 13 | | |||
14 | #include "ui_scheduler.h" | 14 | #include "ui_scheduler.h" | ||
15 | #include "schedulestrategy.h" | ||||
15 | #include "ekos/align/align.h" | 16 | #include "ekos/align/align.h" | ||
16 | 17 | | |||
17 | #include <lilxml.h> | 18 | #include <lilxml.h> | ||
18 | 19 | | |||
19 | #include <QProcess> | 20 | #include <QProcess> | ||
20 | #include <QTime> | 21 | #include <QTime> | ||
21 | #include <QTimer> | 22 | #include <QTimer> | ||
22 | #include <QUrl> | 23 | #include <QUrl> | ||
23 | #include <QtDBus> | 24 | #include <QtDBus> | ||
24 | 25 | | |||
25 | #include <cstdint> | 26 | #include <cstdint> | ||
26 | 27 | | |||
27 | class QProgressIndicator; | 28 | class QProgressIndicator; | ||
28 | 29 | | |||
29 | class GeoLocation; | 30 | class GeoLocation; | ||
30 | class KSMoon; | | |||
31 | class SchedulerJob; | 31 | class SchedulerJob; | ||
32 | class SkyObject; | 32 | class SkyObject; | ||
33 | 33 | | |||
34 | namespace Ekos | 34 | namespace Ekos | ||
35 | { | 35 | { | ||
36 | class SequenceJob; | 36 | class SequenceJob; | ||
37 | class ScheduleStrategy; | ||||
37 | 38 | | |||
38 | /** | 39 | /** | ||
39 | * @brief The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs. | 40 | * @brief The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs. | ||
40 | * @author Jasem Mutlaq | 41 | * @author Jasem Mutlaq | ||
41 | * @version 1.2 | 42 | * @version 1.2 | ||
42 | */ | 43 | */ | ||
43 | class Scheduler : public QWidget, public Ui::Scheduler | 44 | class Scheduler : public QWidget, public Ui::Scheduler | ||
44 | { | 45 | { | ||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Line(s) | 52 | public: | |||
162 | void stopGuiding(); | 163 | void stopGuiding(); | ||
163 | 164 | | |||
164 | /** | 165 | /** | ||
165 | * @brief setSolverAction set the GOTO mode for the solver | 166 | * @brief setSolverAction set the GOTO mode for the solver | ||
166 | * @param mode 0 For Sync, 1 for SlewToTarget, 2 for Nothing | 167 | * @param mode 0 For Sync, 1 for SlewToTarget, 2 for Nothing | ||
167 | */ | 168 | */ | ||
168 | void setSolverAction(Align::GotoMode mode); | 169 | void setSolverAction(Align::GotoMode mode); | ||
169 | 170 | | |||
170 | /** | | |||
171 | * @brief findAltitude Find altitude given a specific time | | |||
172 | * @param target Target | | |||
173 | * @param when date time to find altitude | | |||
174 | * @param is_setting whether target is setting at the argument time (optional). | | |||
175 | * @param debug outputs calculation to log file (optional). | | |||
176 | * @return Altitude of the target at the specific date and time given. | | |||
177 | * @warning This function uses the current KStars geolocation. | | |||
178 | */ | | |||
179 | static double findAltitude(const SkyPoint &target, const QDateTime &when, bool *is_setting = nullptr, bool debug = false); | | |||
180 | | ||||
181 | /** @defgroup SchedulerDBusInterface Ekos DBus Interface - Scheduler Module | 171 | /** @defgroup SchedulerDBusInterface Ekos DBus Interface - Scheduler Module | ||
182 | * Ekos::Align interface provides primary functions to run and stop the scheduler. | 172 | * Ekos::Align interface provides primary functions to run and stop the scheduler. | ||
183 | */ | 173 | */ | ||
184 | 174 | | |||
185 | /*@{*/ | 175 | /*@{*/ | ||
186 | 176 | | |||
187 | /** DBUS interface function. | 177 | /** DBUS interface function. | ||
188 | * @brief Start the scheduler main loop and evaluate jobs and execute them accordingly. | 178 | * @brief Start the scheduler main loop and evaluate jobs and execute them accordingly. | ||
▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Line(s) | 441 | /** | |||
453 | * checkJobStatus slot will be connected in order to figure the exact state of the current job each second | 443 | * checkJobStatus slot will be connected in order to figure the exact state of the current job each second | ||
454 | * @param value | 444 | * @param value | ||
455 | */ | 445 | */ | ||
456 | void executeJob(SchedulerJob *job); | 446 | void executeJob(SchedulerJob *job); | ||
457 | 447 | | |||
458 | void executeScript(const QString &filename); | 448 | void executeScript(const QString &filename); | ||
459 | 449 | | |||
460 | /** | 450 | /** | ||
461 | * @brief getDarkSkyScore Get the dark sky score of a date and time. The further from dawn the better. | | |||
462 | * @param when date and time to check the dark sky score, now if omitted | | |||
463 | * @return Dark sky score. Daylight get bad score, as well as pre-dawn to dawn. | | |||
464 | */ | | |||
465 | int16_t getDarkSkyScore(QDateTime const &when = QDateTime()) const; | | |||
466 | | ||||
467 | /** | | |||
468 | * @brief getAltitudeScore Get the altitude score of an object. The higher the better | | |||
469 | * @param job Target job | | |||
470 | * @param when date and time to check the target altitude, now if omitted. | | |||
471 | * @return Altitude score. Target altitude below minimum altitude required by job or setting target under 3 degrees below minimum altitude get bad score. | | |||
472 | */ | | |||
473 | int16_t getAltitudeScore(SchedulerJob const *job, QDateTime const &when = QDateTime()) const; | | |||
474 | | ||||
475 | /** | | |||
476 | * @brief getMoonSeparationScore Get moon separation score. The further apart, the better, up a maximum score of 20. | | |||
477 | * @param job Target job | | |||
478 | * @param when date and time to check the moon separation, now if omitted. | | |||
479 | * @return Moon separation score | | |||
480 | */ | | |||
481 | int16_t getMoonSeparationScore(SchedulerJob const *job, QDateTime const &when = QDateTime()) const; | | |||
482 | | ||||
483 | /** | | |||
484 | * @brief calculateJobScore Calculate job dark sky score, altitude score, and moon separation scores and returns the sum. | | |||
485 | * @param job Target | | |||
486 | * @param when date and time to evaluate constraints, now if omitted. | | |||
487 | * @return Total score | | |||
488 | */ | | |||
489 | int16_t calculateJobScore(SchedulerJob const *job, QDateTime const &when = QDateTime()) const; | | |||
490 | | ||||
491 | /** | | |||
492 | * @brief getWeatherScore Get current weather condition score. | | |||
493 | * @return If weather condition OK, return score 0, else bad score. | | |||
494 | */ | | |||
495 | int16_t getWeatherScore() const; | | |||
496 | | ||||
497 | /** | | |||
498 | * @brief calculateAltitudeTime calculate the altitude time given the minimum altitude given. | | |||
499 | * @param job active target | | |||
500 | * @param minAltitude minimum altitude required | | |||
501 | * @param minMoonAngle minimum separation from the moon. -1 to ignore. | | |||
502 | * @param when date and time to start searching from, now if omitted. | | |||
503 | * @return The date and time the target is at or above the argument altitude, valid if found, invalid if not achievable (always under altitude). | | |||
504 | */ | | |||
505 | QDateTime calculateAltitudeTime(SchedulerJob const *job, double minAltitude, double minMoonAngle = -1, QDateTime const &when = QDateTime()) const; | | |||
506 | | ||||
507 | /** | | |||
508 | * @brief calculateCulmination find culmination time adjust for the job offset | | |||
509 | * @param job active target | | |||
510 | * @param offset_minutes offset in minutes before culmination to search for. | | |||
511 | * @param when date and time to start searching from, now if omitted | | |||
512 | * @return The date and time the target is in entering the culmination interval, valid if found, invalid if not achievable (currently always valid). | | |||
513 | */ | | |||
514 | QDateTime calculateCulmination(SchedulerJob const *job, int offset_minutes, QDateTime const &when = QDateTime()) const; | | |||
515 | | ||||
516 | /** | | |||
517 | * @brief calculateDawnDusk Get dawn and dusk times for today | | |||
518 | */ | | |||
519 | void calculateDawnDusk(); | | |||
520 | | ||||
521 | /** | | |||
522 | * @brief checkEkosState Check ekos startup stages and take whatever action necessary to get Ekos up and running | 451 | * @brief checkEkosState Check ekos startup stages and take whatever action necessary to get Ekos up and running | ||
523 | * @return True if Ekos is running, false if Ekos start up is in progress. | 452 | * @return True if Ekos is running, false if Ekos start up is in progress. | ||
524 | */ | 453 | */ | ||
525 | bool checkEkosState(); | 454 | bool checkEkosState(); | ||
526 | 455 | | |||
527 | /** | 456 | /** | ||
528 | * @brief isINDIConnected Determines the status of the INDI connection. | 457 | * @brief isINDIConnected Determines the status of the INDI connection. | ||
529 | * @return True if INDI connection is up and usable, else false. | 458 | * @return True if INDI connection is up and usable, else false. | ||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Line(s) | |||||
619 | /** | 548 | /** | ||
620 | * @brief processJobInfo Process the job information from a scheduler file and populate jobs accordingly | 549 | * @brief processJobInfo Process the job information from a scheduler file and populate jobs accordingly | ||
621 | * @param root XML root element of JOB | 550 | * @param root XML root element of JOB | ||
622 | * @return true on success, false on failure. | 551 | * @return true on success, false on failure. | ||
623 | */ | 552 | */ | ||
624 | bool processJobInfo(XMLEle *root); | 553 | bool processJobInfo(XMLEle *root); | ||
625 | 554 | | |||
626 | /** | 555 | /** | ||
627 | * @brief getCurrentMoonSeparation Get current moon separation in degrees at current time for the given job | | |||
628 | * @param job scheduler job | | |||
629 | * @return Separation in degrees | | |||
630 | */ | | |||
631 | double getCurrentMoonSeparation(SchedulerJob const *job) const; | | |||
632 | | ||||
633 | /** | | |||
634 | * @brief updatePreDawn Update predawn time depending on current time and user offset | | |||
635 | */ | | |||
636 | void updatePreDawn(); | | |||
637 | | ||||
638 | /** | | |||
639 | * @brief estimateJobTime Estimates the time the job takes to complete based on the sequence file and what modules to utilize during the observation run. | 556 | * @brief estimateJobTime Estimates the time the job takes to complete based on the sequence file and what modules to utilize during the observation run. | ||
640 | * @param job target job | 557 | * @param job target job | ||
641 | * @return Estimated time in seconds. | 558 | * @return Estimated time in seconds. | ||
642 | */ | 559 | */ | ||
643 | bool estimateJobTime(SchedulerJob *schedJob); | 560 | bool estimateJobTime(SchedulerJob *schedJob); | ||
644 | 561 | | |||
645 | /** | 562 | /** | ||
646 | * @brief createJobSequence Creates a job sequence for the mosaic tool given the prefix and output dir. The currently selected sequence file is modified | 563 | * @brief createJobSequence Creates a job sequence for the mosaic tool given the prefix and output dir. The currently selected sequence file is modified | ||
647 | * and a new version given the supplied parameters are saved to the output directory | 564 | * and a new version given the supplied parameters are saved to the output directory | ||
648 | * @param prefix Prefix to set for the job sequence | 565 | * @param prefix Prefix to set for the job sequence | ||
649 | * @param outputDir Output dir to set for the job sequence | 566 | * @param outputDir Output dir to set for the job sequence | ||
650 | * @return True if new file is saved, false otherwise | 567 | * @return True if new file is saved, false otherwise | ||
651 | */ | 568 | */ | ||
652 | bool createJobSequence(XMLEle *root, const QString &prefix, const QString &outputDir); | 569 | bool createJobSequence(XMLEle *root, const QString &prefix, const QString &outputDir); | ||
653 | 570 | | |||
654 | /** @internal Change the current job, updating associated widgets. | 571 | /** @internal Change the current job, updating associated widgets. | ||
655 | * @param job is an existing SchedulerJob to set as current, or nullptr. | 572 | * @param job is an existing SchedulerJob to set as current, or nullptr. | ||
656 | */ | 573 | */ | ||
657 | void setCurrentJob(SchedulerJob *job); | 574 | void setCurrentJob(SchedulerJob *job); | ||
658 | 575 | | |||
659 | void loadProfiles(); | 576 | void loadProfiles(); | ||
660 | 577 | | |||
661 | XMLEle *getSequenceJobRoot(); | 578 | XMLEle *getSequenceJobRoot(); | ||
662 | 579 | | |||
663 | bool isWeatherOK(SchedulerJob *job); | | |||
664 | | ||||
665 | /** | 580 | /** | ||
666 | * @brief updateCompletedJobsCount For each scheduler job, examine sequence job storage and count captures. | 581 | * @brief updateCompletedJobsCount For each scheduler job, examine sequence job storage and count captures. | ||
667 | * @param forced forces recounting captures unconditionally if true, else only IDLE, EVALUATION or new jobs are examined. | 582 | * @param forced forces recounting captures unconditionally if true, else only IDLE, EVALUATION or new jobs are examined. | ||
668 | */ | 583 | */ | ||
669 | void updateCompletedJobsCount(bool forced = false); | 584 | void updateCompletedJobsCount(bool forced = false); | ||
670 | 585 | | |||
671 | SequenceJob *processJobInfo(XMLEle *root, SchedulerJob *schedJob); | 586 | SequenceJob *processJobInfo(XMLEle *root, SchedulerJob *schedJob); | ||
672 | bool loadSequenceQueue(const QString &fileURL, SchedulerJob *schedJob, QList<SequenceJob *> &jobs, | 587 | bool loadSequenceQueue(const QString &fileURL, SchedulerJob *schedJob, QList<SequenceJob *> &jobs, | ||
Show All 19 Lines | |||||
692 | ShutdownState shutdownState { SHUTDOWN_IDLE }; | 607 | ShutdownState shutdownState { SHUTDOWN_IDLE }; | ||
693 | ParkWaitStatus parkWaitState { PARKWAIT_IDLE }; | 608 | ParkWaitStatus parkWaitState { PARKWAIT_IDLE }; | ||
694 | Ekos::CommunicationStatus m_EkosCommunicationStatus { Ekos::Idle }; | 609 | Ekos::CommunicationStatus m_EkosCommunicationStatus { Ekos::Idle }; | ||
695 | Ekos::CommunicationStatus m_INDICommunicationStatus { Ekos::Idle }; | 610 | Ekos::CommunicationStatus m_INDICommunicationStatus { Ekos::Idle }; | ||
696 | /// List of all jobs as entered by the user or file | 611 | /// List of all jobs as entered by the user or file | ||
697 | QList<SchedulerJob *> jobs; | 612 | QList<SchedulerJob *> jobs; | ||
698 | /// Active job | 613 | /// Active job | ||
699 | SchedulerJob *currentJob { nullptr }; | 614 | SchedulerJob *currentJob { nullptr }; | ||
615 | /// scheduling strategy | ||||
616 | ScheduleStrategy *strategy { nullptr }; | ||||
700 | /// URL to store the scheduler file | 617 | /// URL to store the scheduler file | ||
701 | QUrl schedulerURL; | 618 | QUrl schedulerURL; | ||
702 | /// URL for Ekos Sequence | 619 | /// URL for Ekos Sequence | ||
703 | QUrl sequenceURL; | 620 | QUrl sequenceURL; | ||
704 | /// FITS URL to solve | 621 | /// FITS URL to solve | ||
705 | QUrl fitsURL; | 622 | QUrl fitsURL; | ||
706 | /// Startup script URL | 623 | /// Startup script URL | ||
707 | QUrl startupScriptURL; | 624 | QUrl startupScriptURL; | ||
708 | /// Shutdown script URL | 625 | /// Shutdown script URL | ||
709 | QUrl shutdownScriptURL; | 626 | QUrl shutdownScriptURL; | ||
710 | /// Store all log strings | 627 | /// Store all log strings | ||
711 | QStringList m_LogText; | 628 | QStringList m_LogText; | ||
712 | /// Busy indicator widget | 629 | /// Busy indicator widget | ||
713 | QProgressIndicator *pi { nullptr }; | 630 | QProgressIndicator *pi { nullptr }; | ||
714 | /// Are we editing a job right now? Job row index | 631 | /// Are we editing a job right now? Job row index | ||
715 | int jobUnderEdit { -1 }; | 632 | int jobUnderEdit { -1 }; | ||
716 | /// Pointer to Moon object | | |||
717 | KSMoon *moon { nullptr }; | | |||
718 | /// Pointer to Geograpic locatoin | 633 | /// Pointer to Geograpic locatoin | ||
719 | GeoLocation *geo { nullptr }; | 634 | GeoLocation *geo { nullptr }; | ||
720 | /// How many repeated job batches did we complete thus far? | 635 | /// How many repeated job batches did we complete thus far? | ||
721 | uint16_t captureBatch { 0 }; | 636 | uint16_t captureBatch { 0 }; | ||
722 | /// Startup and Shutdown scripts process | 637 | /// Startup and Shutdown scripts process | ||
723 | QProcess scriptProcess; | 638 | QProcess scriptProcess; | ||
724 | /// Store day fraction of dawn to calculate dark skies range | | |||
725 | double Dawn { -1 }; | | |||
726 | /// Store day fraction of dusk to calculate dark skies range | | |||
727 | double Dusk { -1 }; | | |||
728 | /// Pre-dawn is where we stop all jobs, it is a user-configurable value before Dawn. | | |||
729 | QDateTime preDawnDateTime; | | |||
730 | /// Dusk date time | | |||
731 | QDateTime duskDateTime; | | |||
732 | /// Was job modified and needs saving? | 639 | /// Was job modified and needs saving? | ||
733 | bool mDirty { false }; | 640 | bool mDirty { false }; | ||
734 | /// Keep watch of weather status | 641 | /// Keep watch of weather status | ||
735 | IPState weatherStatus { IPS_IDLE }; | 642 | IPState weatherStatus { IPS_IDLE }; | ||
736 | /// Keep track of how many times we didn't receive weather updates | 643 | /// Keep track of how many times we didn't receive weather updates | ||
737 | uint8_t noWeatherCounter { 0 }; | 644 | uint8_t noWeatherCounter { 0 }; | ||
738 | /// Are we shutting down until later? | 645 | /// Are we shutting down until later? | ||
739 | bool preemptiveShutdown { false }; | 646 | bool preemptiveShutdown { false }; | ||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |