File indexing completed on 2024-04-28 03:43:17

0001 /*  Ekos state machine for refocusing
0002     SPDX-FileCopyrightText: 2022 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "refocusstate.h"
0008 #include "klocalizedstring.h"
0009 
0010 #include <ekos_capture_debug.h>
0011 
0012 namespace Ekos
0013 {
0014 
0015 int RefocusState::getRefocusEveryNTimerElapsedSec()
0016 {
0017     /* If timer isn't valid, consider there is no focus to be done, that is, that focus was just done */
0018     return m_refocusEveryNTimer.isValid() ? static_cast<int>(m_refocusEveryNTimer.elapsed() / 1000) : 0;
0019 }
0020 
0021 RefocusState::RefocusReason RefocusState::checkFocusRequired()
0022 {
0023     setRefocusing(false);
0024     setInSequenceFocus(isAutoFocusReady() && Options::enforceAutofocusHFR());
0025 
0026     // 1. check if time limit based refocusing is necessary
0027     if (Options::enforceRefocusEveryN())
0028     {
0029         qCDebug(KSTARS_EKOS_CAPTURE) << "Focus elapsed time (secs): " << getRefocusEveryNTimerElapsedSec() <<
0030                                      ". Requested Interval (secs): " << Options::refocusEveryN() * 60;
0031 
0032         if (getRefocusEveryNTimerElapsedSec() >= Options::refocusEveryN() * 60)
0033         {
0034             setRefocusing(true);
0035             appendLogText(i18n("Scheduled refocus starting after %1 seconds...", getRefocusEveryNTimerElapsedSec()));
0036             return REFOCUS_TIME_ELAPSED;
0037         }
0038     }
0039 
0040     // 2. check if temperature based refocusing is necessary
0041     if (!isRefocusing() && Options::enforceAutofocusOnTemperature())
0042     {
0043         qCDebug(KSTARS_EKOS_CAPTURE) << "Focus temperature delta (°C): " << getFocusTemperatureDelta() <<
0044                                      ". Requested maximum delta (°C): " << Options::maxFocusTemperatureDelta();
0045 
0046         if (getFocusTemperatureDelta() > Options::maxFocusTemperatureDelta())
0047         {
0048             setRefocusing(true);
0049             appendLogText(i18n("Refocus starting because of temperature change of %1 °C...", getFocusTemperatureDelta()));
0050             return REFOCUS_TEMPERATURE;
0051         }
0052     }
0053 
0054     // 3. check if post meridian flip refocusing is necessary
0055     if (!isRefocusing() && isRefocusAfterMeridianFlip())
0056     {
0057         setRefocusing(true);
0058         appendLogText(i18n("Refocus after meridian flip"));
0059         return REFOCUS_POST_MF;
0060     }
0061 
0062     // 4. check if HFR based in sequence focusing is necessary
0063     if (!isRefocusing() && isInSequenceFocus() && getInSequenceFocusCounter() == 0)
0064     {
0065         setRefocusing(true);
0066         appendLogText(i18n("In sequence HFR based refocus starting..."));
0067         return REFOCUS_HFR;
0068     }
0069 
0070     // 5. no full refocus required so check if adaptive focus is necessary - no need to do both
0071     if (!isRefocusing() && Options::focusAdaptive() && !isAdaptiveFocusDone())
0072     {
0073         setRefocusing(true);
0074         appendLogText(i18n("Adaptive focus starting..."));
0075         return REFOCUS_ADAPTIVE;
0076     }
0077     // no refocusing necessary
0078     return REFOCUS_NONE;
0079 }
0080 
0081 void RefocusState::startRefocusTimer(bool forced)
0082 {
0083     /* If refocus is requested, only restart timer if not already running in order to keep current elapsed time since last refocus */
0084     if (Options::enforceRefocusEveryN())
0085     {
0086         // How much time passed since we last started the time
0087         long elapsedSecs = getRefocusEveryNTimer().elapsed() / 1000;
0088         // How many seconds do we wait for between focusing (60 mins ==> 3600 secs)
0089         int totalSecs   = Options::refocusEveryN() * 60;
0090 
0091         if (!getRefocusEveryNTimer().isValid() || forced)
0092         {
0093             appendLogText(i18n("Ekos will refocus in %1 seconds.", totalSecs));
0094             restartRefocusEveryNTimer();
0095         }
0096         else if (elapsedSecs < totalSecs)
0097         {
0098             appendLogText(i18n("Ekos will refocus in %1 seconds, last procedure was %2 seconds ago.", totalSecs - elapsedSecs,
0099                                elapsedSecs));
0100         }
0101         else
0102         {
0103             appendLogText(i18n("Ekos will refocus as soon as possible, last procedure was %1 seconds ago.", elapsedSecs));
0104         }
0105     }
0106 }
0107 
0108 void RefocusState::decreaseInSequenceFocusCounter()
0109 {
0110     if (inSequenceFocusCounter > 0)
0111         --inSequenceFocusCounter;
0112 }
0113 
0114 void RefocusState::addHFRValue(const QString &filter)
0115 {
0116     QList<double> filterHFRList = m_HFRMap[filter];
0117     filterHFRList.append(getFocusHFR());
0118     m_HFRMap[filter] = filterHFRList;
0119 }
0120 
0121 
0122 
0123 
0124 
0125 void RefocusState::appendLogText(const QString &message)
0126 {
0127     qCInfo(KSTARS_EKOS_CAPTURE()) << message;
0128     emit newLog(message);
0129 }
0130 
0131 
0132 } // namespace