7#include "adaptivefocus.h"
8#include "focusadvisor.h"
9#include "focusadaptor.h"
10#include "focusalgorithms.h"
12#if defined(HAVE_OPENCV)
13#include "focusblurriness.h"
15#include "aberrationinspector.h"
16#include "aberrationinspectorutils.h"
18#include "kstarsdata.h"
20#include "stellarsolver.h"
23#include "ekos/guide/guide.h"
24#include "ekos/manager.h"
27#include "auxiliary/kspaths.h"
28#include "auxiliary/ksmessagebox.h"
31#include "ekos/auxiliary/darklibrary.h"
32#include "ekos/auxiliary/darkprocessor.h"
33#include "ekos/auxiliary/profilesettings.h"
34#include "ekos/auxiliary/opticaltrainmanager.h"
35#include "ekos/auxiliary/opticaltrainsettings.h"
36#include "ekos/auxiliary/filtermanager.h"
37#include "ekos/auxiliary/stellarsolverprofileeditor.h"
40#include "fitsviewer/fitsdata.h"
41#include "fitsviewer/fitsview.h"
42#include "fitsviewer/fitsviewer.h"
45#include "indi/indifilterwheel.h"
46#include "ksnotification.h"
47#include "kconfigdialog.h"
49#include <basedevice.h>
50#include <gsl/gsl_fit.h>
51#include <gsl/gsl_vector.h>
52#include <gsl/gsl_min.h>
54#include <ekos_focus_debug.h>
55#include <config-kstars.h>
59#ifdef HAVE_DATAVISUALIZATION
60#include "aberrationinspector.h"
61#include "aberrationinspectorutils.h"
64#define MAXIMUM_ABS_ITERATIONS 51
65#define MAXIMUM_RESET_ITERATIONS 3
66#define MAXIMUM_RESTART_ITERATIONS 3
67#define AUTO_STAR_TIMEOUT 45000
68#define MINIMUM_PULSE_TIMER 32
69#define MAX_RECAPTURE_RETRIES 3
70#define MINIMUM_POLY_SOLUTIONS 2
74Focus::Focus(
int id) : QWidget()
80 m_opsDialogName =
QString(
"focussettings %1").
arg(
id);
101 loadGlobalSettings();
104 connectSyncSettings();
106 connect(focusAdvisor.get(), &FocusAdvisor::newStage,
this, &Focus::newFocusAdvisorStage);
107 connect(focusAdvisor.get(), &FocusAdvisor::newMessage,
this, &Focus::newFocusAdvisorMessage);
114 for (
auto &button : qButtons)
115 button->setAutoDefault(
false);
117 appendLogText(
i18n(
"Idle."));
120 m_FocusMotionTimer.setInterval(m_OpsFocusMechanics->focusMotionTimeout->value() * 1000);
121 m_FocusMotionTimer.setSingleShot(
true);
124 m_OpsFocusProcess->editFocusProfile->setIcon(
QIcon::fromTheme(
"document-edit"));
129 KConfigDialog *optionsEditor = new KConfigDialog(this,
"OptionsProfileEditor", Options::self());
130 optionsProfileEditor = new StellarSolverProfileEditor(this, Ekos::FocusProfiles, optionsEditor);
132 optionsEditor->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
134 KPageWidgetItem *mainPage = optionsEditor->addPage(optionsProfileEditor, i18n(
"Focus Options Profile Editor"));
135 mainPage->setIcon(QIcon::fromTheme(
"configure"));
136 connect(optionsProfileEditor, &StellarSolverProfileEditor::optionsProfilesUpdated, this, &Focus::loadStellarSolverProfiles);
137 optionsProfileEditor->loadProfile(m_OpsFocusProcess->focusSEPProfile->currentText());
138 optionsEditor->show();
141 loadStellarSolverProfiles();
155 m_DarkProcessor =
new DarkProcessor(
this);
157 connect(m_DarkProcessor, &DarkProcessor::darkFrameCompleted,
this, [
this](
bool completed)
159 m_OpsFocusSettings->useFocusDarkFrame->setChecked(completed);
160 m_FocusView->setProperty(
"suspended",
false);
163 m_FocusView->rescale(ZOOM_KEEP_LEVEL);
164 m_FocusView->updateFrame();
166 setCaptureComplete();
170 setupOpticalTrainManager();
171 refreshOpticalTrain();
174 connectFilterManager();
178void Focus::prepareGUI()
188 m_OpsFocusSettings =
new OpsFocusSettings(opsDialogName());
196 m_OpsFocusProcess =
new OpsFocusProcess(opsDialogName());
197 page = dialog->
addPage(m_OpsFocusProcess,
i18n(
"Process"),
nullptr,
i18n(
"Focus Process"),
false);
200 m_OpsFocusMechanics =
new OpsFocusMechanics(opsDialogName());
201 page = dialog->
addPage(m_OpsFocusMechanics,
i18n(
"Mechanics"),
nullptr,
i18n(
"Focus Mechanics"),
false);
205 m_CFZDialog =
new QDialog(
this);
206 m_CFZUI.reset(
new Ui::focusCFZDialog());
207 m_CFZUI->setupUi(m_CFZDialog);
213 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
214 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
215 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
216 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
217 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
218 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusThreshold);
219 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
220 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
221 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
222 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusTolerance);
223 delete m_OpsFocusProcess->gridLayoutProcessBucket;
226 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutStepsLabel,
227 m_OpsFocusMechanics->focusNumStepsLabel);
228 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutSteps,
229 m_OpsFocusMechanics->focusNumSteps);
233 for (
int i = 0; i < m_OpsFocusProcess->focusStarMeasure->count(); i++)
234 m_StarMeasureText.append(m_OpsFocusProcess->focusStarMeasure->itemText(i));
235 for (
int i = 0; i < m_OpsFocusProcess->focusCurveFit->count(); i++)
236 m_CurveFitText.append(m_OpsFocusProcess->focusCurveFit->itemText(i));
237 for (
int i = 0; i < m_OpsFocusMechanics->focusWalk->count(); i++)
238 m_FocusWalkText.append(m_OpsFocusMechanics->focusWalk->itemText(i));
243 QString savedOptionsProfiles =
QDir(KSPaths::writableLocation(
247 m_StellarSolverProfiles = StellarSolver::loadSavedOptionsProfiles(savedOptionsProfiles);
248 addMissingStellarSolverProfile(savedOptionsProfiles, FOCUS_DEFAULT_NAME);
249 addMissingStellarSolverProfile(savedOptionsProfiles, FOCUS_DEFAULT_DONUT_NAME);
252 m_StellarSolverProfiles = getDefaultFocusOptionsProfiles();
253 m_OpsFocusProcess->focusSEPProfile->clear();
254 for(
auto ¶m : m_StellarSolverProfiles)
255 m_OpsFocusProcess->focusSEPProfile->addItem(param.listName);
256 auto profile = m_Settings[
"focusSEPProfile"];
257 if (profile.isValid())
258 m_OpsFocusProcess->focusSEPProfile->setCurrentText(profile.toString());
261void Focus::addMissingStellarSolverProfile(
const QString profilePath,
const QString profile)
263 for(
auto params : m_StellarSolverProfiles)
265 if (params.listName == profile)
271 SSolver::Parameters params;
272 if (profile == FOCUS_DEFAULT_DONUT_NAME)
273 params = getFocusOptionsProfileDefaultDonut();
274 else if (profile == FOCUS_DEFAULT_NAME)
275 params = getFocusOptionsProfileDefault();
279 settings.beginGroup(params.listName);
285 settings.setValue(it.key(), it.value());
289 m_StellarSolverProfiles.append(params);
295 for (
auto param : m_StellarSolverProfiles)
296 profiles << param.listName;
304 if (focusingWidget->parent() ==
nullptr)
305 toggleFocusingWidgetFullScreen();
310 if (m_Camera && m_Camera->isConnected())
312 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
317 targetChip->resetFrame();
320 targetChip->getFrame(&
x, &
y, &w, &h);
322 qCDebug(KSTARS_EKOS_FOCUS) <<
"Frame is reset. X:" <<
x <<
"Y:" <<
y <<
"W:" << w <<
"H:" << h <<
"binX:" << 1 <<
"binY:" <<
325 QVariantMap settings;
330 settings[
"binx"] = 1;
331 settings[
"biny"] = 1;
332 frameSettings[targetChip] = settings;
334 starSelected =
false;
338 m_FocusView->setTrackingBox(
QRect());
339 checkMosaicMaskLimits();
347 return m_Camera->getDeviceName();
372 case FOCUS_CHANGING_FILTER:
377 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
378 if (targetChip && targetChip->isCapturing())
383 focusBinning->setEnabled(targetChip->canBin());
384 m_OpsFocusSettings->focusSubFrame->setEnabled(targetChip->canSubframe());
385 if (targetChip->canBin())
387 int subBinX = 1, subBinY = 1;
388 focusBinning->clear();
389 targetChip->getMaxBin(&subBinX, &subBinY);
390 for (
int i = 1; i <= subBinX; i++)
391 focusBinning->addItem(
QString(
"%1x%2").arg(i).arg(i));
393 auto binning = m_Settings[
"focusBinning"];
394 if (binning.isValid())
395 focusBinning->setCurrentText(binning.toString());
399 liveVideoB->setEnabled(m_Camera->hasVideoStream());
400 if (m_Camera->hasVideoStream())
401 setVideoStreamEnabled(m_Camera->isStreamingEnabled());
413 if (m_Camera ==
nullptr)
416 auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
417 if (targetChip ==
nullptr || (targetChip && targetChip->isCapturing()))
420 auto isoList = targetChip->getISOList();
423 if (isoList.isEmpty())
425 focusISO->setEnabled(
false);
426 ISOLabel->setEnabled(
false);
430 focusISO->setEnabled(
true);
431 ISOLabel->setEnabled(
true);
432 focusISO->addItems(isoList);
433 focusISO->setCurrentIndex(targetChip->getISOIndex());
436 bool hasGain = m_Camera->hasGain();
437 gainLabel->setEnabled(hasGain);
438 focusGain->setEnabled(hasGain && m_Camera->getGainPermission() != IP_RO);
441 double gain = 0, min = 0, max = 0, step = 1;
442 m_Camera->getGainMinMaxStep(&min, &max, &step);
443 if (m_Camera->getGain(&gain))
446 GainSpinSpecialValue = min - step;
447 focusGain->setRange(GainSpinSpecialValue, max);
448 focusGain->setSpecialValueText(
i18n(
"--"));
450 focusGain->setSingleStep(step);
452 auto defaultGain = m_Settings[
"focusGain"];
453 if (defaultGain.isValid())
454 focusGain->setValue(defaultGain.toDouble());
456 focusGain->setValue(GainSpinSpecialValue);
465 if (m_Camera ==
nullptr)
468 auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
469 if (targetChip ==
nullptr || (targetChip && targetChip->isCapturing()))
472 m_OpsFocusSettings->focusSubFrame->setEnabled(targetChip->canSubframe());
474 if (frameSettings.contains(targetChip) ==
false)
477 if (targetChip->getFrame(&
x, &
y, &w, &h))
479 int binx = 1, biny = 1;
480 targetChip->getBinning(&binx, &biny);
483 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
484 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
486 QVariantMap settings;
488 settings[
"x"] = m_OpsFocusSettings->focusSubFrame->isChecked() ?
x : minX;
489 settings[
"y"] = m_OpsFocusSettings->focusSubFrame->isChecked() ?
y : minY;
490 settings[
"w"] = m_OpsFocusSettings->focusSubFrame->isChecked() ? w : maxW;
491 settings[
"h"] = m_OpsFocusSettings->focusSubFrame->isChecked() ? h : maxH;
492 settings[
"binx"] = binx;
493 settings[
"biny"] = biny;
495 frameSettings[targetChip] = settings;
503 if (m_FilterWheel && m_FilterWheel == device)
510 m_FilterWheel->disconnect(
this);
512 m_FilterWheel = device;
516 connect(m_FilterWheel, &ISD::ConcreteDevice::Connected,
this, [
this]()
518 FilterPosLabel->setEnabled(
true);
519 focusFilter->setEnabled(
true);
520 filterManagerB->setEnabled(
true);
522 connect(m_FilterWheel, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
524 FilterPosLabel->setEnabled(
false);
525 focusFilter->setEnabled(
false);
526 filterManagerB->setEnabled(
false);
530 auto isConnected = m_FilterWheel && m_FilterWheel->isConnected();
531 FilterPosLabel->setEnabled(isConnected);
532 focusFilter->setEnabled(isConnected);
533 filterManagerB->setEnabled(isConnected);
535 FilterPosLabel->setEnabled(
true);
536 focusFilter->setEnabled(
true);
544 defaultFocusTemperatureSource->blockSignals(
true);
545 m_TemperatureSources = temperatureSources;
547 defaultFocusTemperatureSource->clear();
548 for (
auto device : temperatureSources)
552 defaultFocusTemperatureSource->addItem(device->getDeviceName());
554 defaultFocusTemperatureSource->blockSignals(
false);
556 auto targetSource = m_Settings[
"defaultFocusTemperatureSource"];
557 if (targetSource.isValid())
566 source = defaultFocusTemperatureSource->currentText();
567 if (source.isEmpty())
573 for (
auto &oneSource : m_TemperatureSources)
575 if (oneSource->getDeviceName() == source)
577 currentSource = oneSource;
582 m_LastSourceDeviceAutofocusTemperature = currentSource;
589 for (
const auto &oneSource : m_TemperatureSources)
593 if (findTemperatureElement(currentSource))
595 defaultFocusTemperatureSource->setCurrentText(name);
596 m_LastSourceAutofocusTemperature = currentTemperatureSourceElement->value;
597 absoluteTemperatureLabel->setText(
QString(
"%1 °C").arg(currentTemperatureSourceElement->value, 0,
'f', 2));
598 deltaTemperatureLabel->setText(
QString(
"%1 °C").arg(0.0, 0,
'f', 2));
602 m_LastSourceAutofocusTemperature = INVALID_VALUE;
615 auto temperatureProperty = device->getProperty(
"FOCUS_TEMPERATURE");
616 if (!temperatureProperty)
617 temperatureProperty = device->getProperty(
"CCD_TEMPERATURE");
618 if (temperatureProperty)
620 currentTemperatureSourceElement = temperatureProperty.getNumber()->at(0);
624 temperatureProperty = device->getProperty(
"WEATHER_PARAMETERS");
625 if (temperatureProperty)
627 for (
int i = 0; i < temperatureProperty.getNumber()->count(); i++)
629 if (strstr(temperatureProperty.getNumber()->at(i)->getName(),
"_TEMPERATURE"))
631 currentTemperatureSourceElement = temperatureProperty.getNumber()->at(i);
643 return m_FilterWheel->getDeviceName();
653 focusFilter->setCurrentText(filter);
662 return focusFilter->currentText();
667 focusFilter->clear();
671 FilterPosLabel->setEnabled(
false);
672 focusFilter->setEnabled(
false);
673 filterManagerB->setEnabled(
false);
677 m_FilterManager->disconnect(
this);
679 m_FilterManager.reset();
684 FilterPosLabel->setEnabled(
true);
685 focusFilter->setEnabled(
true);
686 filterManagerB->setEnabled(
true);
688 setupFilterManager();
690 focusFilter->addItems(m_FilterManager->getFilterLabels());
692 currentFilterPosition = m_FilterManager->getFilterPosition();
694 focusFilter->setCurrentIndex(currentFilterPosition - 1);
696 focusExposure->setValue(m_FilterManager->getFilterExposure());
701 if (m_Focuser && m_Focuser == device)
708 m_Focuser->disconnect(
this);
714 connect(m_Focuser, &ISD::ConcreteDevice::Connected,
this, [
this]()
718 connect(m_Focuser, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
725 emit focuserChanged(m_focuserId, device !=
nullptr);
732 return m_Focuser->getDeviceName();
742 m_FilterManager->setFocusReady(
false);
743 canAbsMove = canRelMove = canTimerMove =
false;
745 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
750 m_FilterManager->setFocusReady(m_Focuser->isConnected());
752 hasDeviation = m_Focuser->hasDeviation();
754 canAbsMove = m_Focuser->canAbsMove();
758 getAbsFocusPosition();
760 absTicksSpin->setEnabled(
true);
761 absTicksLabel->setEnabled(
true);
762 startGotoB->setEnabled(
true);
765 if (absTicksSpin->value() <= 0)
766 absTicksSpin->setValue(currentPosition);
770 absTicksSpin->setEnabled(
false);
771 absTicksLabel->setEnabled(
false);
772 startGotoB->setEnabled(
false);
775 canRelMove = m_Focuser->canRelMove();
780 if (canAbsMove ==
false && canRelMove ==
true)
782 currentPosition = 50000;
783 absMotionMax = 100000;
787 canTimerMove = m_Focuser->canTimerMove();
793 if (!canAbsMove && !canRelMove && canTimerMove)
795 currentPosition = 50000;
796 absMotionMax = 100000;
800 m_FocusType = (canRelMove || canAbsMove || canTimerMove) ? FOCUS_AUTO : FOCUS_MANUAL;
801 profilePlot->setFocusAuto(m_FocusType == FOCUS_AUTO);
803 bool hasBacklash = m_Focuser->hasBacklash();
804 m_OpsFocusMechanics->focusBacklash->setEnabled(hasBacklash);
805 m_OpsFocusMechanics->focusBacklash->disconnect(
this);
808 double min = 0, max = 0, step = 0;
809 m_Focuser->getMinMaxStep(
"FOCUS_BACKLASH_STEPS",
"FOCUS_BACKLASH_VALUE", &min, &max, &step);
810 m_OpsFocusMechanics->focusBacklash->setMinimum(min);
811 m_OpsFocusMechanics->focusBacklash->setMaximum(max);
812 m_OpsFocusMechanics->focusBacklash->setSingleStep(step);
813 m_OpsFocusMechanics->focusBacklash->setValue(m_Focuser->getBacklash());
815 this, [
this](
int value)
819 if (m_Focuser->getBacklash() == value)
825 m_Focuser->setBacklash(value);
834 m_OpsFocusMechanics->focusBacklash->setValue(0);
840 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
845 if (m_Camera && m_Camera == device)
851 m_captureInProgress =
false;
854 m_Camera->disconnect(
this);
860 connect(m_Camera, &ISD::ConcreteDevice::Connected,
this, [
this]()
864 connect(m_Camera, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
870 auto isConnected = m_Camera && m_Camera->isConnected();
871 focuserGroup->setEnabled(isConnected || (m_Focuser && m_Focuser->isConnected()));
872 ccdGroup->setEnabled(isConnected);
873 toolsGroup->setEnabled(isConnected);
881 checkMosaicMaskLimits();
885void Focus::getAbsFocusPosition()
890 auto absMove = m_Focuser->getNumber(
"ABS_FOCUS_POSITION");
894 const auto &it = absMove->at(0);
895 currentPosition =
static_cast<int>(it->getValue());
896 absMotionMax = it->getMax();
897 absMotionMin = it->getMin();
899 absTicksSpin->setMinimum(it->getMin());
900 absTicksSpin->setMaximum(it->getMax());
901 absTicksSpin->setSingleStep(it->getStep());
904 double const travel = std::abs(it->getMax() - it->getMin());
905 m_OpsFocusMechanics->focusMaxTravel->setMaximum(travel);;
909 m_OpsFocusMechanics->focusTicks->setMaximum(it->getMax() / 2);
915 if (m_LastSourceAutofocusTemperature == INVALID_VALUE && m_LastSourceDeviceAutofocusTemperature
916 && !currentTemperatureSourceElement )
918 if( findTemperatureElement( m_LastSourceDeviceAutofocusTemperature ) )
921 m_LastSourceAutofocusTemperature = currentTemperatureSourceElement->value;
926 if (currentTemperatureSourceElement && currentTemperatureSourceElement->nvp->name == prop.getName())
928 if (m_LastSourceAutofocusTemperature != INVALID_VALUE)
930 delta = currentTemperatureSourceElement->value - m_LastSourceAutofocusTemperature;
931 emit newFocusTemperatureDelta(abs(delta), currentTemperatureSourceElement->value, opticalTrain());
935 emit newFocusTemperatureDelta(0, currentTemperatureSourceElement->value, opticalTrain());
938 absoluteTemperatureLabel->setText(
QString(
"%1 °C").arg(currentTemperatureSourceElement->value, 0,
'f', 2));
939 deltaTemperatureLabel->setText(
QString(
"%1%2 °C").arg((delta > 0.0 ?
"+" :
"")).arg(delta, 0,
'f', 2));
941 deltaTemperatureLabel->setStyleSheet(
"color: lightgreen");
943 deltaTemperatureLabel->setStyleSheet(
"color: lightcoral");
945 deltaTemperatureLabel->setStyleSheet(
"color: lightblue");
949void Focus::setLastFocusTemperature()
951 m_LastSourceAutofocusTemperature = currentTemperatureSourceElement ? currentTemperatureSourceElement->value : INVALID_VALUE;
954 deltaTemperatureLabel->setText(
QString(
"0 °C"));
955 deltaTemperatureLabel->setStyleSheet(
"color: lightgreen");
957 emit newFocusTemperatureDelta(0, -1e6, opticalTrain());
960void Focus::setLastFocusAlt()
962 if (mountAlt < 0.0 || mountAlt > 90.0)
963 m_LastSourceAutofocusAlt = INVALID_VALUE;
965 m_LastSourceAutofocusAlt = mountAlt;
969void Focus::resetAdaptiveFocus(
bool enabled)
972 Options::setFocusAdaptive(enabled);
975 adaptFocus.reset(
new AdaptiveFocus(
this));
976 adaptFocus->resetAdaptiveFocusCounters();
983 adaptFocus->runAdaptiveFocus(currentPosition, filter());
987void Focus::startAbIns()
989 m_abInsOn = canAbInsStart();
990 runAutoFocus(AutofocusReason::FOCUS_ABERRATION_INSPECTOR,
"");
994void Focus::manualStart()
996 runAutoFocus(AutofocusReason::FOCUS_MANUAL,
"");
1008 m_AutofocusReason = autofocusReason;
1009 m_AutofocusReasonInfo = reasonInfo;
1010 if (m_Focuser ==
nullptr)
1013 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_FOCUSER);
1017 if (m_Camera ==
nullptr)
1020 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_CAMERA);
1024 if (!canAbsMove && !canRelMove && m_OpsFocusMechanics->focusTicks->value() <= MINIMUM_PULSE_TIMER)
1026 appendLogText(
i18n(
"Starting pulse step is too low. Increase the step size to %1 or higher...",
1027 MINIMUM_PULSE_TIMER * 5));
1028 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_LOW_PULSE);
1045 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
1053 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
1057 if (inAdjustFocus || adaptFocus->inAdaptiveFocus())
1059 QString str = inAdjustFocus ?
i18n(
"Adjust Focus") :
i18n(
"Adaptive Focus");
1060 if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
1062 appendLogText(
i18n(
"Autofocus start request - Waiting 10sec for %1 to complete.", str));
1065 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
1070 appendLogText(
i18n(
"Discarding Autofocus start request - %1 in progress.", str));
1071 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
1075 inBuildOffsets = (autofocusReason == AutofocusReason::FOCUS_FILTER_OFFSETS);
1076 if (autofocusReason == AutofocusReason::FOCUS_USER_REQUEST)
1078 forceInSeqAF->setChecked(
false);
1079 emit inSequenceAF(
false, opticalTrain());
1088 if ((m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS) && checkAFOptimisation(autofocusReason))
1092 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_OPTIMISED_OUT);
1098 m_LastFocusDirection = FOCUS_NONE;
1100 waitStarSelectTimer.stop();
1103 m_FocusMotionTimerCounter = 0;
1104 m_FocusMotionTimer.stop();
1105 m_FocusMotionTimer.setInterval(m_OpsFocusMechanics->focusMotionTimeout->value() * 1000);
1108 m_FocuserReconnectCounter = 0;
1111 m_FocuserReconnectCounter = 0;
1112 m_DebugFocuserCounter = 0;
1119 m_RestartState = RESTART_NONE;
1127 getAbsFocusPosition();
1128 pulseDuration = m_OpsFocusMechanics->focusTicks->value();
1130 else if (canRelMove)
1134 pulseDuration = m_OpsFocusMechanics->focusTicks->value();
1136 absMotionMax = 100000;
1141 pulseDuration = m_OpsFocusMechanics->focusTicks->value();
1143 absMotionMax = 100000;
1147 focuserAdditionalMovement = 0;
1148 starMeasureFrames.clear();
1160 profilePlot->clear();
1161 FWHMOut->setText(
"");
1163 qCInfo(KSTARS_EKOS_FOCUS) <<
"Starting Autofocus " << m_AFRun
1164 <<
" on" << opticalTrain()
1165 <<
" Reason: " << AutofocusReasonStr[m_AutofocusReason]
1166 <<
" Reason Info: " << m_AutofocusReasonInfo
1167 <<
" CanAbsMove: " << (canAbsMove ?
"yes" :
"no" )
1168 <<
" CanRelMove: " << (canRelMove ?
"yes" :
"no" )
1169 <<
" CanTimerMove: " << (canTimerMove ?
"yes" :
"no" )
1170 <<
" Position:" << currentPosition
1171 <<
" Filter:" << filter()
1172 <<
" Exp:" << focusExposure->value()
1173 <<
" Bin:" << focusBinning->currentText()
1174 <<
" Gain:" << focusGain->value()
1175 <<
" ISO:" << focusISO->currentText();
1176 qCInfo(KSTARS_EKOS_FOCUS) <<
"Settings Tab."
1177 <<
" Auto Select Star:" << ( m_OpsFocusSettings->focusAutoStarEnabled->isChecked() ?
"yes" :
"no" )
1178 <<
" Dark Frame:" << ( m_OpsFocusSettings->useFocusDarkFrame->isChecked() ?
"yes" :
"no" )
1179 <<
" Sub Frame:" << ( m_OpsFocusSettings->focusSubFrame->isChecked() ?
"yes" :
"no" )
1180 <<
" Box:" << m_OpsFocusSettings->focusBoxSize->value()
1181 <<
" Full frame:" << ( m_OpsFocusSettings->focusUseFullField->isChecked() ?
"yes" :
"no " )
1182 <<
" Focus Mask: " << (m_OpsFocusSettings->focusNoMaskRB->isChecked() ?
"Use all stars" :
1183 (m_OpsFocusSettings->focusRingMaskRB->isChecked() ?
QString(
"Ring Mask: [%1%, %2%]").
1184 arg(m_OpsFocusSettings->focusFullFieldInnerRadius->value()).
arg(m_OpsFocusSettings->focusFullFieldOuterRadius->value()) :
1185 QString(
"Mosaic Mask: [%1%, space=%2px]").
1186 arg(m_OpsFocusSettings->focusMosaicTileWidth->value()).
arg(m_OpsFocusSettings->focusMosaicSpace->value())))
1187 <<
" Suspend Guiding:" << ( m_OpsFocusSettings->focusSuspendGuiding->isChecked() ?
"yes" :
"no " )
1188 <<
" Guide Settle:" << m_OpsFocusSettings->focusGuideSettleTime->value()
1189 <<
" Display Units:" << m_OpsFocusSettings->focusUnits->currentText()
1190 <<
" AF Optimize:" << m_OpsFocusSettings->focusAFOptimize->value()
1191 <<
" Adaptive Focus:" << ( m_OpsFocusSettings->focusAdaptive->isChecked() ?
"yes" :
"no" )
1192 <<
" Min Move:" << m_OpsFocusSettings->focusAdaptiveMinMove->value()
1193 <<
" Adapt Start:" << ( m_OpsFocusSettings->focusAdaptStart->isChecked() ?
"yes" :
"no" )
1194 <<
" Max Total Move:" << m_OpsFocusSettings->focusAdaptiveMaxMove->value();
1195 qCInfo(KSTARS_EKOS_FOCUS) <<
"Process Tab."
1196 <<
" Detection:" << m_OpsFocusProcess->focusDetection->currentText()
1197 <<
" SEP Profile:" << m_OpsFocusProcess->focusSEPProfile->currentText()
1198 <<
" Algorithm:" << m_OpsFocusProcess->focusAlgorithm->currentText()
1199 <<
" Curve Fit:" << m_OpsFocusProcess->focusCurveFit->currentText()
1200 <<
" Measure:" << m_OpsFocusProcess->focusStarMeasure->currentText()
1201 <<
" PSF:" << m_OpsFocusProcess->focusStarPSF->currentText()
1202 <<
" Use Weights:" << ( m_OpsFocusProcess->focusUseWeights->isChecked() ?
"yes" :
"no" )
1203 <<
" R2 Limit:" << m_OpsFocusProcess->focusR2Limit->value()
1204 <<
" Refine Curve Fit:" << ( m_OpsFocusProcess->focusRefineCurveFit->isChecked() ?
"yes" :
"no" )
1205 <<
" Average Over:" << m_OpsFocusProcess->focusFramesCount->value()
1206 <<
" Average HFR Check Over:" << m_OpsFocusProcess->focusHFRFramesCount->value()
1207 <<
" Num.of Rows:" << m_OpsFocusProcess->focusMultiRowAverage->value()
1208 <<
" Sigma:" << m_OpsFocusProcess->focusGaussianSigma->value()
1209 <<
" Threshold:" << m_OpsFocusProcess->focusThreshold->value()
1210 <<
" Kernel size:" << m_OpsFocusProcess->focusGaussianKernelSize->value()
1211 <<
" Tolerance:" << m_OpsFocusProcess->focusTolerance->value()
1212 <<
" Denoise:" << ( m_OpsFocusProcess->focusDenoise->isChecked() ?
"yes" :
"no" )
1213 <<
" Donut Buster:" << ( m_OpsFocusProcess->focusDonut->isChecked() ?
"yes" :
"no" )
1214 <<
" Donut Time Dilation:" << m_OpsFocusProcess->focusTimeDilation->value()
1215 <<
" Outlier Rejection:" << m_OpsFocusProcess->focusOutlierRejection->value()
1216 <<
" Scan Start Pos:" << ( m_OpsFocusProcess->focusScanStartPos->isChecked() ?
"yes" :
"no" )
1217 <<
" Scan Always On:" << ( m_OpsFocusProcess->focusScanAlwaysOn->isChecked() ?
"yes" :
"no" )
1218 <<
" Num Datapoints:" << m_OpsFocusProcess->focusScanDatapoints->value()
1219 <<
" Scan Step Factor:" << m_OpsFocusProcess->focusScanStepSizeFactor->value();
1220 qCInfo(KSTARS_EKOS_FOCUS) <<
"Mechanics Tab."
1221 <<
" Initial Step Size:" << m_OpsFocusMechanics->focusTicks->value()
1222 <<
" Out Step Multiple:" << m_OpsFocusMechanics->focusOutSteps->value()
1223 <<
" Number Steps:" << m_OpsFocusMechanics->focusNumSteps->value()
1224 <<
" Max Travel:" << m_OpsFocusMechanics->focusMaxTravel->value()
1225 <<
" Max Step Size:" << m_OpsFocusMechanics->focusMaxSingleStep->value()
1226 <<
" Driver Backlash:" << m_OpsFocusMechanics->focusBacklash->value()
1227 <<
" AF Overscan:" << m_OpsFocusMechanics->focusAFOverscan->value()
1228 <<
" Overscan Delay:" << m_OpsFocusMechanics->focusOverscanDelay->value()
1229 <<
" Focuser Settle:" << m_OpsFocusMechanics->focusSettleTime->value()
1230 <<
" Walk:" << m_OpsFocusMechanics->focusWalk->currentText()
1231 <<
" Capture Timeout:" << m_OpsFocusMechanics->focusCaptureTimeout->value()
1232 <<
" Motion Timeout:" << m_OpsFocusMechanics->focusMotionTimeout->value();
1233 qCInfo(KSTARS_EKOS_FOCUS) <<
"CFZ Tab."
1234 <<
" Algorithm:" << m_CFZUI->focusCFZAlgorithm->currentText()
1235 <<
" Tolerance:" << m_CFZUI->focusCFZTolerance->value()
1236 <<
" Tolerance (Ï„):" << m_CFZUI->focusCFZTau->value()
1237 <<
" Display:" << ( m_CFZUI->focusCFZDisplayVCurve->isChecked() ?
"yes" :
"no" )
1238 <<
" Wavelength (λ):" << m_CFZUI->focusCFZWavelength->value()
1239 <<
" Aperture (A):" << m_CFZUI->focusCFZAperture->value()
1240 <<
" Focal Ratio (f):" << m_CFZUI->focusCFZFNumber->value()
1241 <<
" Step Size:" << m_CFZUI->focusCFZStepSize->value()
1242 <<
" FWHM (θ):" << m_CFZUI->focusCFZSeeing->value();
1244 const double temperature = (currentTemperatureSourceElement) ? currentTemperatureSourceElement->value : INVALID_VALUE;
1245 emit autofocusStarting(temperature, filter(), m_AutofocusReason, m_AutofocusReasonInfo);
1252 if (m_GuidingSuspended ==
false && m_OpsFocusSettings->focusSuspendGuiding->isChecked())
1254 m_GuidingSuspended =
true;
1255 emit suspendGuiding();
1259 setState(Ekos::FOCUS_PROGRESS);
1261 KSNotification::event(
QLatin1String(
"FocusStarted"),
i18n(
"Autofocus operation started"), KSNotification::Focus);
1264 if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
1266 m_AFfilter = filter();
1267 int position = adaptFocus->adaptStartPosition(currentPosition, m_AFfilter);
1269 curveFitting.reset(
new CurveFitting());
1271 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS)
1274 starFitting.reset(
new CurveFitting());
1275 focusFWHM.reset(
new FocusFWHM(m_ScaleCalc));
1276 focusFourierPower.reset(
new FocusFourierPower(m_ScaleCalc));
1277#if defined(HAVE_OPENCV)
1278 focusBlurriness.reset(
new FocusBlurriness());
1281 initDonutProcessing();
1283 if (initScanStartPos(
false, currentPosition))
1286 if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
1288 focusAdvisor->initControl();
1294 setupLinearFocuser(position);
1295 if (!changeFocus(linearRequestedPosition - currentPosition))
1296 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
1304bool Focus::checkAFOptimisation(
const AutofocusReason autofocusReason)
1306 bool dontRunAF =
false;
1307 inAFOptimise =
false;
1310 if (!m_FilterManager || m_OpsFocusSettings->focusAFOptimize->value() <= 0)
1315 if (autofocusReason != FOCUS_FILTER &&
1316 autofocusReason != FOCUS_TIME &&
1317 autofocusReason != FOCUS_TEMPERATURE &&
1318 autofocusReason != FOCUS_HFR_CHECK &&
1319 autofocusReason != FOCUS_SCHEDULER)
1323 QString filterToUse = filter();
1324 QString lockFilter = m_FilterManager->getFilterLock(filterToUse);
1325 if (lockFilter != NULL_FILTER && lockFilter != filterToUse)
1326 filterToUse = lockFilter;
1330 if (!m_FilterManager->getAFDatetime(filterToUse, lastAFDatetime))
1332 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"%1 unable to get last Autofocus run timestamp on %2")
1333 .
arg(__FUNCTION__).
arg(filterToUse);
1338 QDateTime now = KStarsData::Instance()->lt();
1339 auto lastAFDelta = lastAFDatetime.
secsTo(now);
1340 if (lastAFDelta > m_OpsFocusSettings->focusAFOptimize->value())
1344 int position = currentPosition;
1345 if (m_OpsFocusSettings->focusAdaptStart->isChecked())
1346 position = adaptFocus->adaptStartPosition(currentPosition, filterToUse);
1350 double lastTemp, lastAlt;
1351 if(!m_FilterManager->getFilterAbsoluteFocusDetails(filterToUse, position, lastTemp, lastAlt))
1354 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"%1 unable to get last Autofocus info on %2")
1355 .
arg(__FUNCTION__).
arg(filterToUse);
1359 int minTravelLimit = qMax(0.0, currentPosition - m_OpsFocusMechanics->focusMaxTravel->value());
1360 int maxTravelLimit = qMin(absMotionMax, currentPosition + m_OpsFocusMechanics->focusMaxTravel->value());
1361 if (position < minTravelLimit || position > maxTravelLimit)
1363 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"%1 Bad last Autofocus solution found on %2")
1364 .
arg(__FUNCTION__).
arg(position);
1371 if (filterToUse !=
filter())
1373 int filterOffset = m_FilterManager->getFilterOffset(
filter());
1374 int filterToUseOffset = m_FilterManager->getFilterOffset(filterToUse);
1375 if (filterOffset != INVALID_VALUE && filterToUseOffset != INVALID_VALUE)
1376 position += filterOffset - filterToUseOffset;
1379 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"%1 unable to calculate filter offsets").
arg(__FUNCTION__);
1385 if (abs(position - currentPosition) <= 1)
1389 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Autofocus (%1) on %2 optimised out by Autofocus at %3")
1390 .
arg(AutofocusReasonStr[autofocusReason]).
arg(filterToUse).
arg(lastAFDatetime.
toString());
1395 if (changeFocus(position - currentPosition))
1397 inAFOptimise = dontRunAF =
true;
1398 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Autofocus (%1) on %2 optimised out by Autofocus at %3."
1399 " Current Position %4, Target Position %5")
1400 .
arg(AutofocusReasonStr[autofocusReason]).
arg(filterToUse)
1404 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"%1 unable to move focuser... trying full Autofocus").
arg(__FUNCTION__);
1409void Focus::setupLinearFocuser(
int initialPosition)
1411 FocusAlgorithmInterface::FocusParams params(curveFitting.get(),
1412 m_OpsFocusMechanics->focusMaxTravel->value(), m_OpsFocusMechanics->focusTicks->value(), initialPosition, absMotionMin,
1413 absMotionMax, MAXIMUM_ABS_ITERATIONS, m_OpsFocusProcess->focusTolerance->value() / 100.0, m_AFfilter,
1414 currentTemperatureSourceElement ? currentTemperatureSourceElement->value : INVALID_VALUE,
1415 m_OpsFocusMechanics->focusOutSteps->value(), m_OpsFocusMechanics->focusNumSteps->value(),
1416 m_FocusAlgorithm, m_OpsFocusMechanics->focusBacklash->value(), m_CurveFit, m_OpsFocusProcess->focusUseWeights->isChecked(),
1417 m_StarMeasure, m_StarPSF, m_OpsFocusProcess->focusRefineCurveFit->isChecked(), m_FocusWalk,
1418 m_OpsFocusProcess->focusDonut->isChecked(), m_OpsFocusProcess->focusOutlierRejection->value(), m_OptDir, m_ScaleCalc);
1421 initialFocuserAbsPosition = initialPosition;
1422 linearFocuser.reset(MakeLinearFocuser(params));
1423 linearRequestedPosition = linearFocuser->initialPosition();
1427void Focus::initDonutProcessing()
1429 if (!m_OpsFocusProcess->focusDonut->isChecked())
1432 m_donutOrigExposure = focusExposure->value();
1436void Focus::resetDonutProcessing()
1439 if (m_OpsFocusProcess->focusDonut->isChecked() && inAutoFocus)
1440 focusExposure->setValue(m_donutOrigExposure);
1443int Focus::adjustLinearPosition(
int position,
int newPosition,
int overscan,
bool updateDir)
1445 if (overscan > 0 && newPosition > position)
1448 int adjustment = overscan;
1449 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Linear: extending outward movement by overscan %1").
arg(adjustment);
1451 if (newPosition + adjustment > absMotionMax)
1452 adjustment =
static_cast<int>(absMotionMax) - newPosition;
1454 focuserAdditionalMovement = adjustment;
1455 focuserAdditionalMovementUpdateDir = updateDir;
1457 return newPosition + adjustment;
1467 m_abortInProgress =
true;
1470 resetFocusIteration = MAXIMUM_RESET_ITERATIONS + 1;
1472 if (captureTimer.isActive())
1474 captureTimer.stop();
1476 if (m_captureInProgress)
1478 if (inAutoFocus ==
false && inFocusLoop ==
false)
1480 captureB->setEnabled(
true);
1481 stopFocusB->setEnabled(
false);
1485 else if (inAutoFocus)
1487 stopFocusB->setEnabled(
false);
1497 if (m_starDetectInProgress)
1499 stopFocusB->setEnabled(
false);
1508 completeFocusProcedure(
abort ? Ekos::FOCUS_ABORTED : Ekos::FOCUS_FAILED, Ekos::FOCUS_FAIL_ABORT);
1514 if (state() == FOCUS_IDLE || state() == FOCUS_COMPLETE || state() == FOCUS_FAILED || state() == FOCUS_ABORTED)
1518 int old = resetFocusIteration;
1522 resetFocusIteration = old;
1528 if (state() <= FOCUS_ABORTED)
1532 if (focusAdvisor->inFocusAdvisor())
1534 focusAdvisor->stop();
1540void Focus::processAbort()
1542 bool focusLoop = inFocusLoop;
1543 checkStopFocus(
true);
1544 appendLogText(
i18n(
"Autofocus aborted."));
1551void Focus::stop(Ekos::FocusState completionState)
1553 Q_UNUSED(completionState);
1554 qCDebug(KSTARS_EKOS_FOCUS) <<
"Stopping Focus";
1556 captureTimeout.stop();
1557 m_FocusMotionTimer.stop();
1558 m_FocusMotionTimerCounter = 0;
1559 m_FocuserReconnectCounter = 0;
1561 opticalTrainCombo->setEnabled(
true);
1562 trainB->setEnabled(
true);
1563 resetDonutProcessing();
1564 inAutoFocus =
false;
1565 inAdjustFocus =
false;
1566 adaptFocus->setInAdaptiveFocus(
false);
1567 inBuildOffsets =
false;
1568 inAFOptimise =
false;
1569 inScanStartPos =
false;
1570 focusAdvisor->reset();
1571 m_AutofocusReason = AutofocusReason::FOCUS_NONE;
1572 m_AutofocusReasonInfo =
"";
1573 focuserAdditionalMovement = 0;
1574 focuserAdditionalMovementUpdateDir =
true;
1575 inFocusLoop =
false;
1576 m_captureInProgress =
false;
1577 m_abortInProgress =
false;
1578 m_starDetectInProgress =
false;
1579 isVShapeSolution =
false;
1580 captureFailureCounter = 0;
1581 minimumRequiredHFR = INVALID_STAR_MEASURE;
1583 starMeasureFrames.clear();
1593 disconnect(m_Camera, &ISD::Camera::error,
this, &Ekos::Focus::processCaptureError);
1595 if (rememberUploadMode != m_Camera->getUploadMode())
1596 m_Camera->setUploadMode(rememberUploadMode);
1599 if (m_RememberCameraFastExposure)
1601 m_RememberCameraFastExposure =
false;
1602 m_Camera->setFastExposureEnabled(
true);
1605 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
1606 targetChip->abortExposure();
1615 if (m_GuidingSuspended)
1617 emit resumeGuiding();
1618 m_GuidingSuspended =
false;
1624 if (m_abortInProgress)
1627 m_captureInProgress =
false;
1628 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding capture request.";
1634 if (settleTime > 0 && m_captureInProgress ==
false)
1636 captureTimer.start(
static_cast<int>(settleTime * 1000));
1640 if (m_captureInProgress)
1642 qCWarning(KSTARS_EKOS_FOCUS) <<
"Capture called while already in progress. Capture is ignored.";
1646 if (m_Camera ==
nullptr)
1653 if (m_Camera->isConnected() ==
false)
1661 captureTimeout.stop();
1663 waitStarSelectTimer.stop();
1665 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
1667 if (m_Camera->isBLOBEnabled() ==
false)
1669 m_Camera->setBLOBEnabled(
true);
1672 if (focusFilter->currentIndex() != -1)
1674 if (m_FilterWheel ==
nullptr)
1680 if (m_FilterWheel->isConnected() ==
false)
1690 int targetPosition = focusFilter->currentIndex() + 1;
1691 if (!inBuildOffsets)
1693 QString lockedFilter = m_FilterManager->getFilterLock(filter());
1698 if (lockedFilter !=
"--" && lockedFilter != filter())
1700 int lockedFilterIndex = focusFilter->findText(lockedFilter);
1701 if (lockedFilterIndex >= 0)
1704 fallbackFilterPending =
true;
1705 fallbackFilterPosition = targetPosition;
1706 targetPosition = lockedFilterIndex + 1;
1711 filterPositionPending = (targetPosition != currentFilterPosition);
1712 if (filterPositionPending)
1717 FilterManager::FilterPolicy policy = (inAutoFocus) ?
1718 static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY) :
1719 static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY | FilterManager::OFFSET_POLICY);
1720 m_FilterManager->setFilterPosition(targetPosition, policy);
1723 else if (targetPosition != focusFilter->currentIndex() + 1)
1724 focusFilter->setCurrentIndex(targetPosition - 1);
1727 m_FocusView->setProperty(
"suspended", m_OpsFocusSettings->useFocusDarkFrame->isChecked());
1728 prepareCapture(targetChip);
1733 if (frameSettings.contains(targetChip))
1735 QVariantMap settings = frameSettings[targetChip];
1736 targetChip->setFrame(settings[
"x"].toInt(), settings[
"y"].toInt(), settings[
"w"].toInt(),
1737 settings[
"h"].toInt());
1738 settings[
"binx"] = (focusBinning->currentIndex() + 1);
1739 settings[
"biny"] = (focusBinning->currentIndex() + 1);
1740 frameSettings[targetChip] = settings;
1743 m_captureInProgress =
true;
1744 if (state() != FOCUS_PROGRESS)
1745 setState(FOCUS_PROGRESS);
1747 m_FocusView->setBaseSize(focusingWidget->size());
1749 if (targetChip->capture(focusExposure->value()))
1753 captureTimeout.start( (focusExposure->value() + m_OpsFocusMechanics->focusCaptureTimeout->value()) * 1000);
1755 if (inFocusLoop ==
false)
1760 else if (inAutoFocus)
1762 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
1768 if (m_Camera->getUploadMode() == ISD::Camera::UPLOAD_REMOTE)
1770 rememberUploadMode = ISD::Camera::UPLOAD_REMOTE;
1771 m_Camera->setUploadMode(ISD::Camera::UPLOAD_CLIENT);
1775 if (m_Camera->isFastExposureEnabled())
1777 m_RememberCameraFastExposure =
true;
1778 m_Camera->setFastExposureEnabled(
false);
1781 m_Camera->setEncodingFormat(
"FITS");
1782 targetChip->setBatchMode(
false);
1783 targetChip->setBinning((focusBinning->currentIndex() + 1), (focusBinning->currentIndex() + 1));
1784 targetChip->setCaptureMode(FITS_FOCUS);
1785 targetChip->setFrameType(FRAME_LIGHT);
1786 targetChip->setCaptureFilter(FITS_NONE);
1788 if (isFocusISOEnabled() && focusISO->currentIndex() != -1 &&
1789 targetChip->getISOIndex() != focusISO->currentIndex())
1790 targetChip->setISOIndex(focusISO->currentIndex());
1792 if (isFocusGainEnabled() && focusGain->value() != GainSpinSpecialValue)
1793 m_Camera->setGain(focusGain->value());
1798 if (currentPosition == absMotionMin)
1803 focusInB->setEnabled(
false);
1804 focusOutB->setEnabled(
false);
1805 startGotoB->setEnabled(
false);
1807 ms = m_OpsFocusMechanics->focusTicks->value();
1812 if (currentPosition - ms <= absMotionMin)
1814 ms = currentPosition - absMotionMin;
1817 return changeFocus(-ms);
1822 if (currentPosition == absMotionMax)
1827 focusInB->setEnabled(
false);
1828 focusOutB->setEnabled(
false);
1829 startGotoB->setEnabled(
false);
1831 ms = m_OpsFocusMechanics->focusTicks->value();
1832 ms = m_OpsFocusMechanics->focusTicks->value();
1837 if (currentPosition + ms >= absMotionMax)
1839 ms = absMotionMax - currentPosition;
1842 return changeFocus(ms);
1847bool Focus::changeFocus(
int amount,
bool updateDir)
1851 if (inAutoFocus && abs(amount) <= 1)
1853 if (m_RestartState == RESTART_NOW)
1860 capture(m_OpsFocusMechanics->focusSettleTime->value());
1865 if (m_Focuser ==
nullptr)
1867 appendLogText(
i18n(
"Error: No Focuser detected."));
1868 checkStopFocus(
true);
1872 if (m_Focuser->isConnected() ==
false)
1874 appendLogText(
i18n(
"Error: Lost connection to Focuser."));
1875 checkStopFocus(
true);
1879 const int newPosition = adjustLinearPosition(currentPosition, currentPosition + amount,
1880 m_OpsFocusMechanics->focusAFOverscan->value(),
1882 if (newPosition == currentPosition)
1885 const int newAmount = newPosition - currentPosition;
1886 const int absNewAmount = abs(newAmount);
1887 const bool focusingOut = newAmount > 0;
1888 const QString dirStr = focusingOut ?
i18n(
"outward") :
i18n(
"inward");
1891 m_LastFocusDirection = (focusingOut) ? FOCUS_OUT : FOCUS_IN;
1894 m_Focuser->focusOut();
1896 m_Focuser->focusIn();
1899 m_FocusMotionTimer.start();
1903 m_LastFocusSteps = newPosition;
1904 m_Focuser->moveAbs(newPosition);
1905 appendLogText(
i18n(
"Focusing %2 by %1 steps...", abs(absNewAmount), dirStr));
1907 else if (canRelMove)
1909 m_LastFocusSteps = absNewAmount;
1910 m_Focuser->moveRel(absNewAmount);
1911 appendLogText(
i18np(
"Focusing %2 by %1 step...",
"Focusing %2 by %1 steps...", absNewAmount, dirStr));
1915 m_LastFocusSteps = absNewAmount;
1916 m_Focuser->moveByTimer(absNewAmount);
1917 appendLogText(
i18n(
"Focusing %2 by %1 ms...", absNewAmount, dirStr));
1923void Focus::handleFocusMotionTimeout()
1943 qCDebug(KSTARS_EKOS_FOCUS) <<
"handleFocusMotionTimeout() called while not in AutoFocus";
1947 m_FocusMotionTimerCounter++;
1949 if (m_FocusMotionTimerCounter > 4)
1952 appendLogText(
i18n(
"Focuser is still timing out. Aborting..."));
1953 stop(Ekos::FOCUS_ABORTED);
1956 else if (m_FocusMotionTimerCounter > 2)
1958 QString focuser = m_Focuser->getDeviceName();
1959 appendLogText(
i18n(
"Focus motion timed out (%1). Restarting focus driver %2", m_FocusMotionTimerCounter, focuser));
1960 emit focuserTimedout(focuser);
1964 Focus::reconnectFocuser(focuser);
1969 if (!changeFocus(m_LastFocusSteps - currentPosition))
1970 appendLogText(
i18n(
"Focus motion timed out (%1). Focusing to %2 steps...", m_FocusMotionTimerCounter, m_LastFocusSteps));
1975 const bool useFullField = m_OpsFocusSettings->focusUseFullField->isChecked();
1976 ImageMaskType masktype;
1977 if (m_OpsFocusSettings->focusRingMaskRB->isChecked())
1978 masktype = FOCUS_MASK_RING;
1979 else if (m_OpsFocusSettings->focusMosaicMaskRB->isChecked())
1980 masktype = FOCUS_MASK_MOSAIC;
1982 masktype = FOCUS_MASK_NONE;
1985 m_OpsFocusSettings->focusRingMaskRB->setEnabled(
useFullField);
1986 m_OpsFocusSettings->focusMosaicMaskRB->setEnabled(
useFullField);
1988 m_OpsFocusSettings->focusFullFieldInnerRadius->setEnabled(
useFullField && masktype == FOCUS_MASK_RING);
1989 m_OpsFocusSettings->focusFullFieldOuterRadius->setEnabled(
useFullField && masktype == FOCUS_MASK_RING);
1991 m_OpsFocusSettings->focusMosaicTileWidth->setEnabled(
useFullField && masktype == FOCUS_MASK_MOSAIC);
1992 m_OpsFocusSettings->focusSpacerLabel->setEnabled(
useFullField && masktype == FOCUS_MASK_MOSAIC);
1993 m_OpsFocusSettings->focusMosaicSpace->setEnabled(
useFullField && masktype == FOCUS_MASK_MOSAIC);
1996 if (masktype == FOCUS_MASK_RING)
1997 m_FocusView->setImageMask(
new ImageRingMask(m_OpsFocusSettings->focusFullFieldInnerRadius->value() / 100.0,
1998 m_OpsFocusSettings->focusFullFieldOuterRadius->value() / 100.0));
1999 else if (masktype == FOCUS_MASK_MOSAIC)
2000 m_FocusView->setImageMask(
new ImageMosaicMask(m_OpsFocusSettings->focusMosaicTileWidth->value(),
2001 m_OpsFocusSettings->focusMosaicSpace->value()));
2003 m_FocusView->setImageMask(
nullptr);
2005 checkMosaicMaskLimits();
2006 m_currentImageMask = masktype;
2007 startAbInsB->setEnabled(canAbInsStart());
2012 m_FocuserReconnectCounter++;
2014 if (m_Focuser && m_Focuser->getDeviceName() ==
focuser)
2017 refreshOpticalTrain();
2018 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_ERROR);
2022 if (m_FocuserReconnectCounter > 12)
2026 stop(Ekos::FOCUS_ABORTED);
2039 if (data->property(
"chip").toInt() == ISD::CameraChip::GUIDE_CCD)
2044 m_FocusView->loadData(data);
2048 m_ImageData.reset();
2050 captureTimeout.stop();
2051 captureTimeoutCounter = 0;
2052 m_MissingCameraCounter = 0;
2054 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
2056 disconnect(m_Camera, &ISD::Camera::error,
this, &Ekos::Focus::processCaptureError);
2058 if (m_ImageData && m_OpsFocusSettings->useFocusDarkFrame->isChecked())
2060 QVariantMap settings = frameSettings[targetChip];
2061 uint16_t offsetX = settings[
"x"].toInt() / settings[
"binx"].toInt();
2062 uint16_t offsetY = settings[
"y"].toInt() / settings[
"biny"].toInt();
2064 m_DarkProcessor->denoise(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()),
2065 targetChip, m_ImageData, focusExposure->value(), offsetX, offsetY);
2069 setCaptureComplete();
2073void Focus::starDetectionFinished()
2075 m_starDetectInProgress =
false;
2076 if (m_abortInProgress)
2079 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding results from " << __FUNCTION__;
2083 appendLogText(
i18n(
"Detection complete."));
2086 double hfr = INVALID_STAR_MEASURE;
2088 if (isStarMeasureStarBased())
2090 appendLogText(
i18n(
"Detection complete."));
2092 if (m_StarFinderWatcher.result() ==
false)
2094 qCWarning(KSTARS_EKOS_FOCUS) <<
"Failed to extract any stars.";
2098 if (m_OpsFocusSettings->focusUseFullField->isChecked())
2100 m_FocusView->filterStars();
2103 hfr = m_ImageData->getHFR(m_StarMeasure == FOCUS_STAR_HFR_ADJ ? HFR_ADJ_AVERAGE : HFR_AVERAGE);
2107 m_FocusView->setTrackingBoxEnabled(
true);
2112 if (starCenter.isNull() ==
false)
2113 hfr = m_ImageData->getHFR(starCenter.x(), starCenter.y());
2117 hfr = m_ImageData->getHFR(m_FocusDetection == ALGORITHM_SEP ? HFR_HIGH : HFR_MAX);
2123 currentNumStars = m_ImageData->getDetectedStars();
2126 if (m_StarMeasure == FOCUS_STAR_NUM_STARS)
2128 currentMeasure = currentNumStars;
2129 currentWeight = 1.0;
2131 else if (m_StarMeasure == FOCUS_STAR_FWHM)
2133 getFWHM(m_ImageData->getStarCenters(), ¤tFWHM, ¤tWeight);
2134 currentMeasure = currentFWHM;
2136 else if (m_StarMeasure == FOCUS_STAR_FOURIER_POWER)
2138 getFourierPower(¤tFourierPower, ¤tWeight);
2139 currentMeasure = currentFourierPower;
2141 else if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
2142 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
2145 if (m_OpsFocusSettings->focusSubFrame->isChecked())
2146 roi = m_FocusView->isTrackingBoxEnabled() ? m_FocusView->getTrackingBox() :
QRect();
2147 getBlurriness(m_StarMeasure, m_OpsFocusProcess->focusDenoise->isChecked(), ¤tBlurriness, ¤tWeight, roi);
2148 currentMeasure = currentBlurriness;
2152 currentMeasure = currentHFR;
2154 std::vector<double> hfrs(stars.
size());
2159 currentWeight = calculateStarWeight(m_OpsFocusProcess->focusUseWeights->isChecked(), hfrs);
2161 setCurrentMeasure();
2167bool Focus::isStarMeasureStarBased()
2169 if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL || m_StarMeasure == FOCUS_STAR_LAPLASSIAN
2170 || m_StarMeasure == FOCUS_STAR_CANNY)
2176void Focus::getFWHM(
const QList<Edge *> &stars,
double *FWHM,
double *weight)
2178 *FWHM = INVALID_STAR_MEASURE;
2181 auto imageBuffer = m_ImageData->getImageBuffer();
2183 switch (m_ImageData->getStatistics().dataType)
2186 focusFWHM->processFWHM(
reinterpret_cast<uint8_t
const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2190 focusFWHM->processFWHM(
reinterpret_cast<short const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2194 focusFWHM->processFWHM(
reinterpret_cast<unsigned short const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM,
2199 focusFWHM->processFWHM(
reinterpret_cast<long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2203 focusFWHM->processFWHM(
reinterpret_cast<unsigned long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2207 focusFWHM->processFWHM(
reinterpret_cast<float const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2211 focusFWHM->processFWHM(
reinterpret_cast<long long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2215 focusFWHM->processFWHM(
reinterpret_cast<double const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2219 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
2220 " Cannot calc FWHM";
2226void Focus::getFourierPower(
double *fourierPower,
double *weight,
const int mosaicTile)
2228 *fourierPower = INVALID_STAR_MEASURE;
2231 auto imageBuffer = m_ImageData->getImageBuffer();
2233 switch (m_ImageData->getStatistics().dataType)
2236 focusFourierPower->processFourierPower(
reinterpret_cast<uint8_t
const *
>(imageBuffer), m_ImageData,
2237 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2241 focusFourierPower->processFourierPower(
reinterpret_cast<short const *
>(imageBuffer), m_ImageData,
2242 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2246 focusFourierPower->processFourierPower(
reinterpret_cast<unsigned short const *
>(imageBuffer), m_ImageData,
2247 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2251 focusFourierPower->processFourierPower(
reinterpret_cast<long const *
>(imageBuffer), m_ImageData,
2252 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2256 focusFourierPower->processFourierPower(
reinterpret_cast<unsigned long const *
>(imageBuffer), m_ImageData,
2257 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2261 focusFourierPower->processFourierPower(
reinterpret_cast<float const *
>(imageBuffer), m_ImageData,
2262 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2266 focusFourierPower->processFourierPower(
reinterpret_cast<long long const *
>(imageBuffer), m_ImageData,
2267 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2271 focusFourierPower->processFourierPower(
reinterpret_cast<double const *
>(imageBuffer), m_ImageData,
2272 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2276 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
2277 " Cannot calc Fourier Power";
2283void Focus::getBlurriness(
const StarMeasure starMeasure,
const bool denoise,
double *blurriness,
double *weight,
2284 const QRect &roi,
const int mosaicTile)
2286 *blurriness = INVALID_STAR_MEASURE;
2289#if defined(HAVE_OPENCV)
2291 auto imageBuffer = m_ImageData->getImageBuffer();
2293 switch (m_ImageData->getStatistics().dataType)
2296 focusBlurriness->processBlurriness(
reinterpret_cast<uint8_t
const *
>(imageBuffer), m_ImageData, denoise,
2297 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2301 focusBlurriness->processBlurriness(
reinterpret_cast<short const *
>(imageBuffer), m_ImageData, denoise,
2302 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2306 focusBlurriness->processBlurriness(
reinterpret_cast<unsigned short const *
>(imageBuffer), m_ImageData, denoise,
2307 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2311 focusBlurriness->processBlurriness(
reinterpret_cast<long const *
>(imageBuffer), m_ImageData, denoise,
2312 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2316 focusBlurriness->processBlurriness(
reinterpret_cast<unsigned long const *
>(imageBuffer), m_ImageData, denoise,
2317 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2321 focusBlurriness->processBlurriness(
reinterpret_cast<float const *
>(imageBuffer), m_ImageData, denoise,
2322 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2326 focusBlurriness->processBlurriness(
reinterpret_cast<long long const *
>(imageBuffer), m_ImageData, denoise,
2327 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2331 focusBlurriness->processBlurriness(
reinterpret_cast<double const *
>(imageBuffer), m_ImageData, denoise,
2332 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2336 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
2337 " Cannot calc Blurriness";
2341 Q_UNUSED(starMeasure);
2344 Q_UNUSED(mosaicTile);
2346 qCDebug(KSTARS_EKOS_FOCUS) <<
"getBlurriness called when openCV not installed";
2350double Focus::calculateStarWeight(
const bool useWeights,
const std::vector<double> values)
2352 if (!useWeights || values.size() <= 0)
2357 return Mathematics::RobustStatistics::ComputeWeight(m_ScaleCalc, values);
2360void Focus::analyzeSources()
2362 appendLogText(
i18n(
"Detecting sources..."));
2363 m_starDetectInProgress =
true;
2365 QVariantMap extractionSettings;
2366 extractionSettings[
"optionsProfileIndex"] = m_OpsFocusProcess->focusSEPProfile->currentIndex();
2367 extractionSettings[
"optionsProfileGroup"] =
static_cast<int>(Ekos::FocusProfiles);
2368 m_ImageData->setSourceExtractorSettings(extractionSettings);
2372 if (m_OpsFocusSettings->focusUseFullField->isChecked())
2374 m_FocusView->setTrackingBoxEnabled(
false);
2376 if (m_FocusDetection != ALGORITHM_CENTROID && m_FocusDetection != ALGORITHM_SEP)
2377 m_StarFinderWatcher.setFuture(m_ImageData->findStars(ALGORITHM_CENTROID));
2379 m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection));
2383 QRect searchBox = m_FocusView->isTrackingBoxEnabled() ? m_FocusView->getTrackingBox() :
QRect();
2387 m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection, searchBox));
2392 m_FocusView->setTrackingBoxEnabled(
false);
2396 if (m_FocusDetection != ALGORITHM_CENTROID && m_FocusDetection != ALGORITHM_SEP)
2397 m_StarFinderWatcher.setFuture(m_ImageData->findStars(ALGORITHM_CENTROID));
2400 m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection, searchBox));
2405bool Focus::appendMeasure(
double newMeasure)
2408 starMeasureFrames.append(newMeasure);
2411 QVector <double> samples(starMeasureFrames);
2412 samples.erase(std::remove_if(samples.begin(), samples.end(), [](
const double measure)
2414 return measure == INVALID_STAR_MEASURE;
2418 if (!samples.isEmpty())
2420 currentMeasure = Mathematics::RobustStatistics::ComputeLocation(
2421 Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, std::vector<double>(samples.begin(), samples.end()));
2423 switch(m_StarMeasure)
2425 case FOCUS_STAR_HFR:
2426 case FOCUS_STAR_HFR_ADJ:
2427 currentHFR = currentMeasure;
2429 case FOCUS_STAR_FWHM:
2430 currentFWHM = currentMeasure;
2432 case FOCUS_STAR_NUM_STARS:
2433 currentNumStars = currentMeasure;
2435 case FOCUS_STAR_FOURIER_POWER:
2436 currentFourierPower = currentMeasure;
2438 case FOCUS_STAR_STDDEV:
2439 case FOCUS_STAR_SOBEL:
2440 case FOCUS_STAR_LAPLASSIAN:
2441 case FOCUS_STAR_CANNY:
2442 currentBlurriness = currentMeasure;
2453 int framesCount = m_OpsFocusProcess->focusFramesCount->value();
2454 if ((minimumRequiredHFR > 0) || (inAutoFocus && !inBuildOffsets && !inScanStartPos && !focusAdvisor->inFocusAdvisor()
2455 && m_FocusAlgorithm == FOCUS_LINEAR1PASS
2456 && linearFocuser && !linearFocuser->isInFirstPass()))
2458 framesCount = m_OpsFocusProcess->focusHFRFramesCount->value();
2460 return starMeasureFrames.count() < framesCount;
2463void Focus::settle(
const FocusState completionState,
const bool autoFocusUsed,
const bool buildOffsetsUsed,
2464 const AutofocusFailReason failCode,
const QString failCodeInfo)
2466 if (autoFocusUsed && failCode != FOCUS_FAIL_OPTIMISED_OUT)
2468 if (completionState == Ekos::FOCUS_COMPLETE)
2470 if (failCode != FOCUS_FAIL_ADVISOR_COMPLETE)
2471 KSNotification::event(
QLatin1String(
"FocusSuccessful"),
i18n(
"Autofocus operation completed successfully"),
2472 KSNotification::Focus);
2474 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && curveFitting !=
nullptr)
2475 emit autofocusComplete(m_LastSourceAutofocusTemperature,
filter(), getAnalyzeData(),
2476 m_OpsFocusProcess->focusUseWeights->isChecked(),
2477 curveFitting->serialize(), linearFocuser->getTextStatus(R2));
2479 emit autofocusComplete(m_LastSourceAutofocusTemperature,
filter(), getAnalyzeData(),
2480 m_OpsFocusProcess->focusUseWeights->isChecked());
2484 if (failCode != FOCUS_FAIL_ADVISOR_COMPLETE)
2485 KSNotification::event(
QLatin1String(
"FocusFailed"),
i18n(
"Autofocus operation failed"),
2486 KSNotification::Focus, KSNotification::Alert);
2487 emit autofocusAborted(
filter(), getAnalyzeData(), m_OpsFocusProcess->focusUseWeights->isChecked(), failCode, failCodeInfo);
2491 if (completionState == Ekos::FOCUS_COMPLETE)
2493 if (autoFocusUsed && fallbackFilterPending)
2498 m_FilterManager->setFilterAbsoluteFocusDetails(focusFilter->currentIndex(), currentPosition,
2499 m_LastSourceAutofocusTemperature, m_LastSourceAutofocusAlt);
2504 if (fallbackFilterPending)
2506 m_pendingState = completionState;
2507 FilterManager::FilterPolicy policy =
static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY |
2508 FilterManager::OFFSET_POLICY);
2509 m_FilterManager->setFilterPosition(fallbackFilterPosition, policy);
2512 setState(completionState, failCode != FOCUS_FAIL_OPTIMISED_OUT);
2514 if (autoFocusUsed && buildOffsetsUsed)
2516 m_FilterManager->autoFocusComplete(completionState, currentPosition, m_LastSourceAutofocusTemperature,
2517 m_LastSourceAutofocusAlt);
2522QString Focus::getAnalyzeData()
2524 QString analysis_results =
"";
2526 for (
int i = 0; i < plot_position.size(); ++i)
2529 .arg(i == 0 ?
"" :
"|" )
2535 return analysis_results;
2538void Focus::completeFocusProcedure(FocusState completionState, AutofocusFailReason failCode,
QString failCodeInfo,
2542 if (inAutoFocus && failCode != FOCUS_FAIL_ADVISOR_COMPLETE && failCode != FOCUS_FAIL_OPTIMISED_OUT)
2545 updatePlotPosition();
2547 if (completionState == Ekos::FOCUS_COMPLETE)
2551 emit redrawHFRPlot(polynomialFit.get(), currentPosition, currentHFR);
2553 appendLogText(
i18np(
"Focus procedure completed after %1 iteration.",
2554 "Focus procedure completed after %1 iterations.", plot_position.count()));
2556 setLastFocusTemperature();
2558 resetAdaptiveFocus(m_OpsFocusSettings->focusAdaptive->isChecked());
2562 qCInfo(KSTARS_EKOS_FOCUS) <<
"Autofocus values: position," << currentPosition <<
", temperature,"
2563 << m_LastSourceAutofocusTemperature <<
", filter," <<
filter()
2564 <<
", HFR," << currentHFR <<
", altitude," << m_LastSourceAutofocusAlt;
2566 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL)
2569 plot_position.append(currentPosition);
2570 plot_value.append(currentHFR);
2571 plot_weight.append(1.0);
2572 plot_outlier.append(
false);
2575 appendFocusLogText(
QString(
"%1, %2, %3, %4, %5\n")
2582 absTicksSpin->setValue(currentPosition);
2585 else if (canAbsMove && initialFocuserAbsPosition >= 0 && resetFocusIteration <= MAXIMUM_RESET_ITERATIONS &&
2586 m_RestartState != RESTART_ABORT)
2589 bool const retry_focusing = m_RestartState == RESTART_NONE &&
2590 (failCode == Ekos::FOCUS_FAIL_ADVISOR_RERUN || ++resetFocusIteration < MAXIMUM_RESET_ITERATIONS);
2595 m_RestartState = RESTART_NOW;
2604 emit autofocusAborted(
filter(), getAnalyzeData(), m_OpsFocusProcess->focusUseWeights->isChecked(), failCode, failCodeInfo);
2616 m_RestartState = RESTART_ABORT;
2622 resetFocusIteration = 0;
2625 const bool autoFocusUsed = inAutoFocus;
2626 const bool inBuildOffsetsUsed = inBuildOffsets;
2629 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot)
2630 emit drawPolynomial(polynomialFit.get(), isVShapeSolution,
true);
2633 int const settleTime = m_GuidingSuspended ? m_OpsFocusSettings->focusGuideSettleTime->value() : 0;
2636 stop(completionState);
2639 appendLogText(
i18n(
"Settling for %1s...", settleTime));
2641 QTimer::singleShot(settleTime * 1000,
this, [ &, settleTime, completionState, autoFocusUsed, inBuildOffsetsUsed, failCode,
2644 settle(completionState, autoFocusUsed, inBuildOffsetsUsed, failCode, failCodeInfo);
2647 appendLogText(
i18n(
"Settling complete."));
2654 if (m_Focuser && m_Focuser->isConnected() && initialFocuserAbsPosition >= 0)
2657 if (currentPosition == initialFocuserAbsPosition)
2660 appendLogText(
i18n(
"Autofocus failed, moving back to initial focus position %1.", initialFocuserAbsPosition));
2661 changeFocus(initialFocuserAbsPosition - currentPosition);
2666void Focus::setCurrentMeasure()
2669 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focus newFITS #" << starMeasureFrames.count() + 1 <<
": Current HFR " << currentHFR <<
2671 << (starSelected ? 1 : currentNumStars);
2674 if (appendMeasure(currentMeasure))
2679 else starMeasureFrames.clear();
2684 emit newHFR(currentHFR, currentPosition, inAutoFocus, opticalTrain());
2686 emit newHFR(currentHFR, -1, inAutoFocus, opticalTrain());
2689 HFROut->setText(
QString(
"%1").arg(currentHFR * getStarUnits(m_StarMeasure, m_StarUnits), 0,
'f', 2));
2690 if (m_StarMeasure == FOCUS_STAR_FWHM)
2691 FWHMOut->setText(
QString(
"%1").arg(currentFWHM * getStarUnits(m_StarMeasure, m_StarUnits), 0,
'f', 2));
2692 starsOut->setText(
QString(
"%1").arg(m_ImageData->getDetectedStars()));
2693 iterOut->setText(
QString(
"%1").arg(absIterations + 1));
2696 if (lastHFR == INVALID_STAR_MEASURE)
2697 appendLogText(
i18n(
"FITS received. No stars detected."));
2700 if (!isStarMeasureStarBased() || currentHFR > 0)
2703 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && isVShapeSolution)
2705 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
2709 Edge selectedHFRStarHFR = m_ImageData->getSelectedHFRStar();
2716 if (starCenter.isNull() ==
false && (inAutoFocus || minimumRequiredHFR >= 0))
2719 starSelected =
true;
2720 starCenter.setX(qMax(0,
static_cast<int>(selectedHFRStarHFR.x)));
2721 starCenter.setY(qMax(0,
static_cast<int>(selectedHFRStarHFR.y)));
2723 syncTrackingBoxPosition();
2727 oneStar.
setZ(currentHFR);
2728 starsHFR.append(oneStar);
2733 QVector3D oneStar(starCenter.x(), starCenter.y(), currentHFR);
2734 starsHFR.append(oneStar);
2737 if (currentHFR > maxHFR)
2738 maxHFR = currentHFR;
2746 if (inFocusLoop || (inAutoFocus && ! isPositionBased()))
2748 int pos = plot_position.empty() ? 1 : plot_position.last() + 1;
2749 addPlotPosition(pos, currentMeasure);
2755 QVector3D oneStar(starCenter.x(), starCenter.y(), INVALID_STAR_MEASURE);
2756 starsHFR.append(oneStar);
2761 m_FocusView->updateFrame();
2765 if (m_abInsOn && !inScanStartPos && !focusAdvisor->inFocusAdvisor())
2766 calculateAbInsData();
2770void Focus::saveFocusFrame()
2772 if (inAutoFocus && Options::focusLogging() && Options::saveFocusImages())
2775 QDateTime now = KStarsData::Instance()->lt();
2783 if (focusAdvisor->inFocusAdvisor())
2784 prefix = focusAdvisor->getFocusFramePrefix();
2785 else if (inScanStartPos)
2786 prefix =
QString(
"_ssp_%1_%2").
arg(m_AFRun).
arg(absIterations + 1);
2787 else if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser)
2789 const int currentStep = linearFocuser->currentStep() + 1;
2795 prefix.
append(
QString(
"_%1").arg(starMeasureFrames.count()));
2801 m_ImageData->saveImage(filename);
2805void Focus::calculateAbInsData()
2807 ImageMosaicMask *mosaicmask =
dynamic_cast<ImageMosaicMask *
>(m_FocusView->imageMask().
get());
2809 auto stars = m_ImageData->getStarCenters();
2812 for (
int star = 0; star < stars.
count(); star++)
2814 const int x = stars[star]->x;
2815 const int y = stars[star]->y;
2816 for (
int tile = 0; tile < NUM_TILES; tile++)
2818 QRect thisTile = tiles[tile];
2821 tileStars[tile].append(stars[star]);
2828 for (
int tile = 0; tile < tileStars.count(); tile++)
2830 double measure, weight;
2831 std::vector<double> HFRs;
2833 switch (m_StarMeasure)
2835 case FOCUS_STAR_HFR:
2836 case FOCUS_STAR_HFR_ADJ:
2837 for (
int star = 0; star < tileStars[tile].count(); star++)
2839 HFRs.push_back(tileStars[tile][star]->HFR);
2841 measure = Mathematics::RobustStatistics::ComputeLocation(Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, HFRs, 2);
2842 weight = calculateStarWeight(m_OpsFocusProcess->focusUseWeights->isChecked(), HFRs);
2844 case FOCUS_STAR_FWHM:
2845 getFWHM(tileStars[tile], &measure, &weight);
2847 case FOCUS_STAR_NUM_STARS:
2848 measure = tileStars[tile].count();
2851 case FOCUS_STAR_FOURIER_POWER:
2852 getFourierPower(&measure, &weight, tile);
2854 case FOCUS_STAR_STDDEV:
2855 case FOCUS_STAR_SOBEL:
2856 case FOCUS_STAR_LAPLASSIAN:
2857 case FOCUS_STAR_CANNY:
2858 getBlurriness(m_StarMeasure, m_OpsFocusProcess->focusDenoise->isChecked(), &measure, &weight,
QRect(), tile);
2861 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unable to calculate Aberration Inspector data";
2865 m_abInsMeasure[tile].append(measure);
2866 m_abInsWeight[tile].append(weight);
2867 m_abInsNumStars[tile].append(tileStars[tile].count());
2869 if (!linearFocuser->isInFirstPass())
2874 int xAv = 0, yAv = 0;
2875 if (m_StarMeasure != FOCUS_STAR_FOURIER_POWER)
2877 QPoint tileCenter = tiles[tile].center();
2878 int xSum = 0.0, ySum = 0.0;
2879 for (
int star = 0; star < tileStars[tile].count(); star++)
2881 xSum += tileStars[tile][star]->x - tileCenter.
x();
2882 ySum += tileStars[tile][star]->y - tileCenter.
y();
2885 xAv = (tileStars[tile].count() <= 0) ? 0 : xSum / tileStars[tile].count();
2886 yAv = (tileStars[tile].count() <= 0) ? 0 : ySum / tileStars[tile].count();
2888 m_abInsTileCenterOffset.append(
QPoint(xAv, yAv));
2891 m_abInsPosition.append(currentPosition);
2894void Focus::setCaptureComplete()
2896 DarkLibrary::Instance()->disconnect(
this);
2899 syncTrackingBoxPosition();
2902 if (inFocusLoop ==
false)
2903 appendLogText(
i18n(
"Image received."));
2905 if (m_captureInProgress && inFocusLoop ==
false && inAutoFocus ==
false)
2906 m_Camera->setUploadMode(rememberUploadMode);
2908 if (m_RememberCameraFastExposure && inFocusLoop ==
false && inAutoFocus ==
false)
2910 m_RememberCameraFastExposure =
false;
2911 m_Camera->setFastExposureEnabled(
true);
2914 m_captureInProgress =
false;
2915 if (m_abortInProgress)
2919 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding frame results in " << __FUNCTION__;
2924 checkMosaicMaskLimits();
2927 emit newImage(m_FocusView);
2929 emit newStarPixmap(m_FocusView->getTrackingBoxPixmap(10));
2937 if (!isStarMeasureStarBased())
2938 starDetectionFinished();
2939 else if (inFocusLoop ==
false || (inFocusLoop && (m_FocusView->isTrackingBoxEnabled()
2940 || m_OpsFocusSettings->focusUseFullField->isChecked())))
2946void Focus::setHFRComplete()
2956 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
2959 int subBinX = 1, subBinY = 1;
2960 if (!targetChip->getBinning(&subBinX, &subBinY))
2961 qCDebug(KSTARS_EKOS_FOCUS) <<
"Warning: target chip is reporting no binning property, using 1x1.";
2963 if (m_OpsFocusSettings->focusSubFrame->isChecked() && !isStarMeasureStarBased() && !starSelected)
2965 appendLogText(
i18n(
"Capture complete. Select a region of interest."));
2967 syncTrackingBoxPosition();
2970 setState(Ekos::FOCUS_WAITING);
2973 waitStarSelectTimer.start();
2976 else if (m_OpsFocusSettings->focusSubFrame->isChecked() && isStarMeasureStarBased() && starCenter.isNull())
2983 int x = 0, y = 0, w = 0, h = 0;
2986 if (frameSettings.contains(targetChip))
2988 QVariantMap settings = frameSettings[targetChip];
2989 x = settings[
"x"].toInt();
2990 y = settings[
"y"].toInt();
2991 w = settings[
"w"].toInt();
2992 h = settings[
"h"].toInt();
2996 targetChip->getFrame(&x, &y, &w, &h);
2999 if (m_OpsFocusSettings->focusAutoStarEnabled->isChecked())
3002 const Edge selectedHFRStar = m_ImageData->getSelectedHFRStar();
3004 if (selectedHFRStar.x == -1)
3006 appendLogText(
i18n(
"Failed to automatically select a star. Please select a star manually."));
3009 m_FocusView->setTrackingBox(
QRect(w - m_OpsFocusSettings->focusBoxSize->value() / (subBinX * 2),
3010 h - m_OpsFocusSettings->focusBoxSize->value() / (subBinY * 2),
3011 m_OpsFocusSettings->focusBoxSize->value() / subBinX, m_OpsFocusSettings->focusBoxSize->value() / subBinY));
3012 m_FocusView->setTrackingBoxEnabled(
true);
3015 setState(Ekos::FOCUS_WAITING);
3018 waitStarSelectTimer.start();
3024 starCenter.setX(selectedHFRStar.x);
3025 starCenter.setY(selectedHFRStar.y);
3026 starCenter.setZ(subBinX);
3027 starSelected =
true;
3028 syncTrackingBoxPosition();
3031 if (subFramed ==
false && isFocusSubFrameEnabled() && m_OpsFocusSettings->focusSubFrame->isChecked())
3033 int offset = (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX) * 1.5;
3034 int subX = (selectedHFRStar.x - offset) * subBinX;
3035 int subY = (selectedHFRStar.y - offset) * subBinY;
3036 int subW = offset * 2 * subBinX;
3037 int subH = offset * 2 * subBinY;
3039 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
3040 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
3047 if ((subW + subX) > maxW)
3049 if ((subH + subY) > maxH)
3054 QVariantMap settings = frameSettings[targetChip];
3055 settings[
"x"] = subX;
3056 settings[
"y"] = subY;
3057 settings[
"w"] = subW;
3058 settings[
"h"] = subH;
3059 settings[
"binx"] = subBinX;
3060 settings[
"biny"] = subBinY;
3062 qCDebug(KSTARS_EKOS_FOCUS) <<
"Frame is subframed. X:" << subX <<
"Y:" << subY <<
"W:" << subW <<
"H:" << subH <<
"binX:" <<
3063 subBinX <<
"binY:" << subBinY;
3067 frameSettings[targetChip] = settings;
3070 starCenter.setX(subW / (2 * subBinX));
3071 starCenter.setY(subH / (2 * subBinY));
3072 starCenter.setZ(subBinX);
3076 m_FocusView->setFirstLoad(
true);
3085 starCenter.setX(selectedHFRStar.x);
3086 starCenter.setY(selectedHFRStar.y);
3087 starCenter.setZ(subBinX);
3100 appendLogText(
i18n(
"Capture complete. Select a star to focus."));
3102 starSelected =
false;
3106 int subBinX = 1, subBinY = 1;
3107 targetChip->getBinning(&subBinX, &subBinY);
3109 m_FocusView->setTrackingBox(
QRect((w - m_OpsFocusSettings->focusBoxSize->value()) / (subBinX * 2),
3110 (h - m_OpsFocusSettings->focusBoxSize->value()) / (2 * subBinY),
3111 m_OpsFocusSettings->focusBoxSize->value() / subBinX, m_OpsFocusSettings->focusBoxSize->value() / subBinY));
3112 m_FocusView->setTrackingBoxEnabled(
true);
3115 setState(Ekos::FOCUS_WAITING);
3118 waitStarSelectTimer.start();
3124 if (minimumRequiredHFR >= 0)
3127 if (currentHFR == INVALID_STAR_MEASURE)
3129 if (noStarCount++ < MAX_RECAPTURE_RETRIES)
3131 appendLogText(
i18n(
"No stars detected while testing HFR, capturing again..."));
3133 if (noStarCount == MAX_RECAPTURE_RETRIES)
3142 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3147 else if (currentHFR > minimumRequiredHFR)
3149 qCDebug(KSTARS_EKOS_FOCUS) <<
"Current HFR:" << currentHFR <<
"is above required minimum HFR:" << minimumRequiredHFR <<
3150 ". Starting AutoFocus...";
3153 minimumRequiredHFR = INVALID_STAR_MEASURE;
3154 runAutoFocus(AutofocusReason::FOCUS_HFR_CHECK, reasonInfo);
3159 qCDebug(KSTARS_EKOS_FOCUS) <<
"Current HFR:" << currentHFR <<
"is below required minimum HFR:" << minimumRequiredHFR <<
3160 ". Autofocus successful.";
3161 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
3169 if (inAutoFocus ==
false)
3173 if (state() != Ekos::FOCUS_IDLE)
3174 setState(Ekos::FOCUS_IDLE);
3181 if (state() != Ekos::FOCUS_PROGRESS)
3182 setState(Ekos::FOCUS_PROGRESS);
3187 else if(focusAdvisor->inFocusAdvisor())
3188 focusAdvisor->control();
3189 else if(m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
3191 else if (canAbsMove || canRelMove)
3199QString Focus::getyAxisLabel(StarMeasure starMeasure)
3202 m_StarUnits == FOCUS_UNITS_ARCSEC ? str +=
" (\")" : str +=
" (pix)";
3204 switch (starMeasure)
3206 case FOCUS_STAR_HFR:
3208 case FOCUS_STAR_HFR_ADJ:
3210 m_StarUnits == FOCUS_UNITS_ARCSEC ? str +=
" (\")" : str +=
" (pix)";
3212 case FOCUS_STAR_FWHM:
3214 m_StarUnits == FOCUS_UNITS_ARCSEC ? str +=
" (\")" : str +=
" (pix)";
3216 case FOCUS_STAR_NUM_STARS:
3219 case FOCUS_STAR_FOURIER_POWER:
3220 str =
"Fourier Power";
3222 case FOCUS_STAR_STDDEV:
3225 case FOCUS_STAR_SOBEL:
3226 str =
"Sobel Factor";
3228 case FOCUS_STAR_LAPLASSIAN:
3229 str =
"Laplassian Factor";
3231 case FOCUS_STAR_CANNY:
3232 str =
"Canny Factor";
3243 polynomialFit.reset();
3244 plot_position.clear();
3246 plot_weight.clear();
3247 plot_outlier.clear();
3248 isVShapeSolution =
false;
3249 m_abInsPosition.clear();
3250 m_abInsTileCenterOffset.clear();
3251 if (m_abInsMeasure.count() != NUM_TILES)
3253 m_abInsMeasure.resize(NUM_TILES);
3254 m_abInsWeight.resize(NUM_TILES);
3255 m_abInsNumStars.resize(NUM_TILES);
3259 for (
int i = 0; i < m_abInsMeasure.count(); i++)
3261 m_abInsMeasure[i].clear();
3262 m_abInsWeight[i].clear();
3263 m_abInsNumStars[i].clear();
3267 emit
initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
3268 m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, m_OpsFocusProcess->focusUseWeights->isChecked(),
3269 inFocusLoop ==
false && isPositionBased());
3272bool Focus::autoFocusChecks()
3274 if (++absIterations > MAXIMUM_ABS_ITERATIONS)
3276 appendLogText(
i18n(
"Autofocus failed: exceeded max iterations %1", MAXIMUM_ABS_ITERATIONS));
3277 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_MAX_ITERS);
3282 if (isStarMeasureStarBased() && currentHFR == INVALID_STAR_MEASURE)
3284 if (noStarCount < MAX_RECAPTURE_RETRIES)
3287 appendLogText(
i18n(
"No stars detected, capturing again..."));
3291 else if (m_FocusAlgorithm == FOCUS_LINEAR)
3293 appendLogText(
i18n(
"Failed to detect any stars at position %1. Continuing...", currentPosition));
3296 else if(!m_OpsFocusProcess->focusDonut->isChecked())
3299 appendLogText(
i18n(
"Failed to detect any stars. Reset frame and try again."));
3300 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3310void Focus::plotLinearFocus()
3319 linearFocuser->getMeasurements(&positions, &values, &weights);
3320 const FocusAlgorithmInterface::FocusParams ¶ms = linearFocuser->getParams();
3327 bool incrementalChange =
false;
3328 if (positions.
size() > 1 && positions.
size() == lastPositions.
size() + 1)
3331 for (
int i = 0; i < positions.
size() - 1; ++i)
3332 if (positions[i] != lastPositions[i] || values[i] != lastValues[i])
3337 incrementalChange =
ok;
3339 lastPositions = positions;
3340 lastValues = values;
3342 const bool outlier =
false;
3343 if (incrementalChange)
3344 emit newHFRPlotPosition(
static_cast<double>(positions.
last()), values.
last(), (pow(weights.
last(), -0.5)),
3345 outlier, params.initialStepSize, plt);
3348 emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
3349 m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, params.useWeights, plt);
3350 for (
int i = 0; i < positions.
size(); ++i)
3351 emit newHFRPlotPosition(
static_cast<double>(positions[i]), values[i], (pow(weights.
last(), -0.5)),
3352 outlier, params.initialStepSize, plt);
3356 if (values.
size() > 3)
3362 double minPosition, minValue;
3363 double searchMin = std::max(params.minPositionAllowed, params.startPosition - params.maxTravel);
3364 double searchMax = std::min(params.maxPositionAllowed, params.startPosition + params.maxTravel);
3366 linearFocuser->getPass1Measurements(&pass1Positions, &pass1Values, &pass1Weights, &pass1Outliers);
3367 if (m_FocusAlgorithm == FOCUS_LINEAR || m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
3371 polynomialFit.reset(
new PolynomialFit(2, pass1Positions, pass1Values));
3373 if (polynomialFit->findMinimum(params.startPosition, searchMin, searchMax, &minPosition, &minValue))
3375 emit drawPolynomial(polynomialFit.get(),
true,
true, plt);
3379 if (linearFocuser->isDone())
3380 emit minimumFound(-1, -1, plt);
3382 emit minimumFound(minPosition, minValue, plt);
3387 emit drawPolynomial(polynomialFit.get(),
false,
false, plt);
3388 emit minimumFound(-1, -1, plt);
3394 if (curveFitting->findMinMax(params.startPosition, searchMin, searchMax, &minPosition, &minValue, params.curveFit,
3395 params.optimisationDirection))
3397 R2 = curveFitting->calculateR2(
static_cast<CurveFitting::CurveFit
>(params.curveFit));
3398 emit drawCurve(curveFitting.get(),
true,
true, plt);
3401 emit minimumFound(minPosition, minValue, plt);
3406 emit drawCurve(curveFitting.get(),
false,
false, plt);
3407 emit minimumFound(-1, -1, plt);
3413 HFROut->setText(
QString(
"%1").arg(currentHFR * getStarUnits(m_StarMeasure, m_StarUnits), 0,
'f', 2));
3415 emit setTitle(linearFocuser->getTextStatus(R2));
3417 if (!plt) HFRPlot->replot();
3421CurveFitting::FittingGoal Focus::getGoal(
int numSteps)
3424 if (m_FocusWalk == FOCUS_WALK_CLASSIC)
3425 return CurveFitting::FittingGoal::STANDARD;
3428 return (numSteps >= m_OpsFocusMechanics->focusNumSteps->value()) ? CurveFitting::FittingGoal::BEST :
3429 CurveFitting::FittingGoal::STANDARD;
3435void Focus::plotLinearFinalUpdates()
3438 if (!m_OpsFocusProcess->focusRefineCurveFit->isChecked())
3441 emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
3442 m_CFZUI->focusCFZDisplayVCurve->isChecked());
3444 emit finalUpdates(linearFocuser->getTextStatus(R2), plt);
3454 linearFocuser->getPass1Measurements(&pass1Positions, &pass1Values, &pass1Weights, &pass1Outliers);
3455 const FocusAlgorithmInterface::FocusParams ¶ms = linearFocuser->getParams();
3457 emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
3458 m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, m_OpsFocusProcess->focusUseWeights->isChecked(), plt);
3460 for (
int i = 0; i < pass1Positions.
size(); ++i)
3461 emit newHFRPlotPosition(
static_cast<double>(pass1Positions[i]), pass1Values[i], (pow(pass1Weights[i], -0.5)),
3462 pass1Outliers[i], params.initialStepSize, plt);
3464 R2 = curveFitting->calculateR2(
static_cast<CurveFitting::CurveFit
>(params.curveFit));
3465 emit drawCurve(curveFitting.get(),
true,
true,
false);
3468 emit minimumFound(linearFocuser->solution(), linearFocuser->solutionValue(), plt);
3470 emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
3471 m_CFZUI->focusCFZDisplayVCurve->isChecked());
3473 emit setTitle(linearFocuser->getTextStatus(R2), plt);
3477void Focus::startAberrationInspector()
3479#ifdef HAVE_DATAVISUALIZATION
3481 AberrationInspector::abInsData data;
3483 ImageMosaicMask *mosaicmask =
dynamic_cast<ImageMosaicMask *
>(m_FocusView->imageMask().
get());
3486 appendLogText(
i18n(
"Unable to launch Aberration Inspector run %1...", m_abInsRun));
3491 data.run = ++m_abInsRun;
3492 data.curveFit = m_CurveFit;
3493 data.useWeights = m_OpsFocusProcess->focusUseWeights->isChecked();
3494 data.optDir = m_OptDir;
3495 data.sensorWidth = m_CcdWidth;
3496 data.sensorHeight = m_CcdHeight;
3497 data.pixelSize = m_CcdPixelSizeX;
3498 data.tileWidth = mosaicmask->tiles()[0].width();
3499 data.focuserStepMicrons = m_CFZUI->focusCFZStepSize->value();
3500 data.yAxisLabel = getyAxisLabel(m_StarMeasure);
3501 data.starUnits = getStarUnits(m_StarMeasure, m_StarUnits);
3502 data.cfzSteps = m_cfzSteps;
3503 data.isPositionBased = isPositionBased();
3506 appendLogText(
i18n(
"Launching Aberration Inspector run %1...", m_abInsRun));
3508 m_abInsNumStars, m_abInsTileCenterOffset));
3515bool Focus::initScanStartPos(
const bool force,
const int initialPosition)
3519 if (!m_OpsFocusProcess->focusScanStartPos->isChecked())
3522 if (!m_OpsFocusProcess->focusScanAlwaysOn->isChecked() && !m_AFRerun)
3527 inScanStartPos =
true;
3528 initialFocuserAbsPosition = initialPosition;
3529 m_scanMeasure.clear();
3530 m_scanPosition.clear();
3532 appendLogText(
i18n(
"Starting scan for initial focuser position."));
3533 emit setTitle(
QString(
i18n(
"Scanning for starting position...")),
true);
3535 if (!changeFocus(initialPosition - currentPosition))
3536 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3541void Focus::scanStartPos()
3544 if (currentHFR == INVALID_STAR_MEASURE)
3546 if (noStarCount < MAX_RECAPTURE_RETRIES)
3549 appendLogText(
i18n(
"No stars detected, capturing again..."));
3555 appendLogText(
i18n(
"Failed to detect any stars. Aborting..."));
3556 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3562 if (++absIterations > MAXIMUM_ABS_ITERATIONS)
3564 appendLogText(
i18n(
"Scan Start Pos: exceeded max iterations %1", MAXIMUM_ABS_ITERATIONS));
3565 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_MAX_ITERS);
3570 m_scanPosition.push_back(currentPosition);
3571 m_scanMeasure.push_back(currentMeasure);
3574 const int step = m_scanPosition.size();
3575 const int maxSteps = m_OpsFocusProcess->focusScanDatapoints->value();
3576 const int stepSize = m_OpsFocusMechanics->focusTicks->value() * m_OpsFocusProcess->focusScanStepSizeFactor->value();
3577 emit newHFRPlotPosition(
static_cast<double>(currentPosition), currentMeasure, pow(currentWeight, -0.5),
false, stepSize,
3579 if (step < maxSteps)
3582 emit setTitle(
QString(
i18n(
"Scanning for starting position %1/%2", step, maxSteps)),
true);
3583 deltaPos = step * stepSize * std::pow(-1, step + 1);
3588 auto it = std::min_element(std::begin(m_scanMeasure), std::end(m_scanMeasure));
3589 auto min = std::distance(std::begin(m_scanMeasure), it);
3590 if (min >= m_OpsFocusProcess->focusScanDatapoints->value() - 2)
3593 deltaPos = m_scanPosition[min] - currentPosition;
3594 m_scanPosition.clear();
3595 m_scanMeasure.clear();
3596 emit setTitle(
QString(
i18n(
"No scan minimum - widening search...")),
true);
3601 if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
3602 focusAdvisor->setInFocusAdvisor(
false);
3604 const int initialPosition = m_scanPosition[min];
3605 setupLinearFocuser(initialPosition);
3606 inScanStartPos =
false;
3608 deltaPos = linearRequestedPosition - currentPosition;
3609 emit setTitle(
QString(
i18n(
"Scan Start Position %1 Found", initialPosition)),
true);
3610 appendLogText(
i18n(
"Scan Start Position %1 found", initialPosition));
3613 if (!changeFocus(deltaPos))
3614 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3617void Focus::autoFocusLinear()
3619 if (!autoFocusChecks())
3622 if (!canAbsMove && !canRelMove && canTimerMove)
3625 if (linearRequestedPosition != currentPosition)
3628 qCDebug(KSTARS_EKOS_FOCUS) <<
"Linear: warning, changing position " << currentPosition <<
" to "
3629 << linearRequestedPosition;
3631 currentPosition = linearRequestedPosition;
3636 bool useFocusStarsHFR = m_OpsFocusSettings->focusUseFullField->isChecked()
3637 && m_OpsFocusProcess->focusFramesCount->value() == 1;
3638 auto focusStars = useFocusStarsHFR || (m_FocusAlgorithm == FOCUS_LINEAR1PASS) ? &(m_ImageData->getStarCenters()) :
nullptr;
3640 linearRequestedPosition = linearFocuser->newMeasurement(currentPosition, currentMeasure, currentWeight, focusStars);
3641 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser->isDone() && linearFocuser->solution() != -1)
3644 plotLinearFinalUpdates();
3646 startAberrationInspector();
3652 if (linearFocuser->isDone())
3654 if (linearFocuser->solution() != -1)
3657 if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
3659 if (focusAdvisor->analyseAF())
3660 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_ADVISOR_RERUN,
"",
false);
3662 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE,
"",
false);
3664 else if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
3666 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE,
"",
false);
3667 else if (R2 >= m_OpsFocusProcess->focusR2Limit->value())
3671 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Linear Curve Fit check passed R2=%1 focusR2Limit=%2").
arg(R2).
arg(
3672 m_OpsFocusProcess->focusR2Limit->value());
3673 completeFocusProcedure(Ekos::FOCUS_COMPLETE, FOCUS_FAIL_NONE,
"",
false);
3676 else if (m_R2Retries == 0)
3679 appendLogText(
i18n(
"Curve Fit check failed R2=%1 focusR2Limit=%2 retrying...", R2,
3680 m_OpsFocusProcess->focusR2Limit->value()));
3683 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_R2, failCodeInfo,
false);
3689 appendLogText(
i18n(
"Curve Fit check failed again R2=%1 focusR2Limit=%2 but continuing...", R2,
3690 m_OpsFocusProcess->focusR2Limit->value()));
3691 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE,
"",
false);
3697 qCDebug(KSTARS_EKOS_FOCUS) << linearFocuser->doneReason();
3698 AutofocusFailReason failCode = linearFocuser->getFailCode();
3699 appendLogText(
i18n(
"Linear autofocus algorithm aborted: %1", AutofocusFailReasonStr[failCode]));
3700 completeFocusProcedure(Ekos::FOCUS_ABORTED, failCode,
"",
false);
3706 const int delta = linearRequestedPosition - currentPosition;
3708 if (!changeFocus(delta))
3709 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE,
"",
false);
3715void Focus::autoFocusAbs()
3719 static int minHFRPos = 0, focusOutLimit = 0, focusInLimit = 0, lastHFRPos = 0, fluctuations = 0;
3720 static double minHFR = 0, lastDelta = 0;
3721 double targetPosition = 0;
3722 bool ignoreLimitedDelta =
false;
3724 QString deltaTxt =
QString(
"%1").
arg(fabs(currentHFR - minHFR) * 100.0, 0,
'g', 3);
3727 qCDebug(KSTARS_EKOS_FOCUS) <<
"===============================";
3728 qCDebug(KSTARS_EKOS_FOCUS) <<
"Current HFR: " << currentHFR <<
" Current Position: " << currentPosition;
3729 qCDebug(KSTARS_EKOS_FOCUS) <<
"Last minHFR: " << minHFR <<
" Last MinHFR Pos: " << minHFRPos;
3730 qCDebug(KSTARS_EKOS_FOCUS) <<
"Delta: " << deltaTxt <<
"%";
3731 qCDebug(KSTARS_EKOS_FOCUS) <<
"========================================";
3734 appendLogText(
i18n(
"FITS received. HFR %1 @ %2. Delta (%3%)", HFRText, currentPosition, deltaTxt));
3736 appendLogText(
i18n(
"FITS received. HFR %1 @ %2.", HFRText, currentPosition));
3738 if (!autoFocusChecks())
3741 addPlotPosition(currentPosition, currentHFR);
3743 switch (m_LastFocusDirection)
3746 lastHFR = currentHFR;
3747 initialFocuserAbsPosition = currentPosition;
3748 minHFR = currentHFR;
3749 minHFRPos = currentPosition;
3759 if (absMotionMax < currentPosition + pulseDuration)
3761 if (currentPosition < absMotionMax)
3763 pulseDuration = absMotionMax - currentPosition;
3768 m_LastFocusDirection = FOCUS_IN;
3771 else if (currentPosition + pulseDuration < absMotionMin)
3773 if (absMotionMin < currentPosition)
3775 pulseDuration = currentPosition - absMotionMin;
3780 m_LastFocusDirection = FOCUS_OUT;
3784 m_LastFocusDirection = (pulseDuration > 0) ? FOCUS_OUT : FOCUS_IN;
3785 if (!changeFocus(pulseDuration,
false))
3786 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3792 if (reverseDir && focusInLimit && focusOutLimit &&
3793 fabs(currentHFR - minHFR) < (m_OpsFocusProcess->focusTolerance->value() / 100.0) && HFRInc == 0)
3795 if (absIterations <= 2)
3797 QString message =
i18n(
"Change in HFR is too small. Try increasing the step size or decreasing the tolerance.");
3798 appendLogText(message);
3799 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3800 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_SMALL_HFR);
3802 else if (noStarCount > 0)
3804 QString message =
i18n(
"Failed to detect focus star in frame. Capture and select a focus star.");
3805 appendLogText(message);
3806 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3807 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3811 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
3815 else if (currentHFR < lastHFR)
3818 if (HFRInc >= 1 && m_LastFocusDirection == FOCUS_OUT && lastHFRPos < focusInLimit && fabs(currentHFR - lastHFR) > 0.1)
3820 focusInLimit = lastHFRPos;
3821 qCDebug(KSTARS_EKOS_FOCUS) <<
"New FocusInLimit " << focusInLimit;
3823 else if (HFRInc >= 1 && m_LastFocusDirection == FOCUS_IN && lastHFRPos > focusOutLimit &&
3824 fabs(currentHFR - lastHFR) > 0.1)
3826 focusOutLimit = lastHFRPos;
3827 qCDebug(KSTARS_EKOS_FOCUS) <<
"New FocusOutLimit " << focusOutLimit;
3830 double factor = std::max(1.0, HFRDec / 2.0);
3831 if (m_LastFocusDirection == FOCUS_IN)
3832 targetPosition = currentPosition - (pulseDuration * factor);
3834 targetPosition = currentPosition + (pulseDuration * factor);
3836 qCDebug(KSTARS_EKOS_FOCUS) <<
"current Position" << currentPosition <<
" targetPosition " << targetPosition;
3838 lastHFR = currentHFR;
3841 if (lastHFR < minHFR)
3844 minHFRPos = currentPosition;
3845 qCDebug(KSTARS_EKOS_FOCUS) <<
"new minHFR " << minHFR <<
" @ position " << minHFRPos;
3848 lastHFRPos = currentPosition;
3855 if (plot_position.count() >= 2)
3857 plot_position.remove(plot_position.count() - 2);
3858 plot_value.remove(plot_value.count() - 2);
3872 lastHFR = currentHFR;
3873 lastHFRPos = currentPosition;
3882 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focus is moving away from optimal HFR.";
3885 if (m_LastFocusDirection == FOCUS_IN)
3887 focusInLimit = currentPosition;
3888 qCDebug(KSTARS_EKOS_FOCUS) <<
"Setting focus IN limit to " << focusInLimit;
3892 focusOutLimit = currentPosition;
3893 qCDebug(KSTARS_EKOS_FOCUS) <<
"Setting focus OUT limit to " << focusOutLimit;
3896 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot_position.count() > 4)
3898 polynomialFit.reset(
new PolynomialFit(2, 5, plot_position, plot_value));
3899 double a = *std::min_element(plot_position.constBegin(), plot_position.constEnd());
3900 double b = *std::max_element(plot_position.constBegin(), plot_position.constEnd());
3901 double min_position = 0, min_hfr = 0;
3902 isVShapeSolution = polynomialFit->findMinimum(minHFRPos, a, b, &min_position, &min_hfr);
3903 qCDebug(KSTARS_EKOS_FOCUS) <<
"Found Minimum?" << (isVShapeSolution ?
"Yes" :
"No");
3904 if (isVShapeSolution)
3906 ignoreLimitedDelta =
true;
3907 qCDebug(KSTARS_EKOS_FOCUS) <<
"Minimum Solution:" << min_hfr <<
"@" << min_position;
3908 targetPosition = round(min_position);
3909 appendLogText(
i18n(
"Found polynomial solution @ %1",
QString::number(min_position,
'f', 0)));
3911 emit drawPolynomial(polynomialFit.get(), isVShapeSolution,
true);
3912 emit minimumFound(min_position, min_hfr);
3916 emit drawPolynomial(polynomialFit.get(), isVShapeSolution,
false);
3925 if (std::abs(lastDelta) > 0)
3926 targetPosition = currentPosition + lastDelta;
3928 targetPosition = currentPosition + pulseDuration;
3930 else if (isVShapeSolution ==
false)
3932 ignoreLimitedDelta =
true;
3934 if (m_LastFocusDirection == FOCUS_OUT)
3935 targetPosition = minHFRPos - pulseDuration / 2;
3937 targetPosition = minHFRPos + pulseDuration / 2;
3940 qCDebug(KSTARS_EKOS_FOCUS) <<
"new targetPosition " << targetPosition;
3944 if (focusInLimit != 0 && m_LastFocusDirection == FOCUS_IN && targetPosition < focusInLimit)
3946 targetPosition = focusInLimit;
3947 qCDebug(KSTARS_EKOS_FOCUS) <<
"Limiting target pulse to focus in limit " << targetPosition;
3949 else if (focusOutLimit != 0 && m_LastFocusDirection == FOCUS_OUT && targetPosition > focusOutLimit)
3951 targetPosition = focusOutLimit;
3952 qCDebug(KSTARS_EKOS_FOCUS) <<
"Limiting target pulse to focus out limit " << targetPosition;
3956 if (targetPosition < absMotionMin)
3957 targetPosition = absMotionMin;
3958 else if (targetPosition > absMotionMax)
3959 targetPosition = absMotionMax;
3962 if (targetPosition == currentPosition)
3966 if (targetPosition == minHFRPos || isVShapeSolution)
3968 appendLogText(
"Stopping at minimum recorded HFR position.");
3969 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
3973 QString message =
i18n(
"Focuser cannot move further, device limits reached. Autofocus aborted.");
3974 appendLogText(message);
3975 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3976 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_OOB);
3982 if (fluctuations >= MAXIMUM_FLUCTUATIONS)
3984 QString message =
i18n(
"Unstable fluctuations. Try increasing initial step size or exposure time.");
3985 appendLogText(message);
3986 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3987 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FLUCTUATIONS);
3992 if (focusOutLimit && focusOutLimit == focusInLimit)
3994 QString message =
i18n(
"Deadlock reached. Please try again with different settings.");
3995 appendLogText(message);
3996 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3997 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_DEADLOCK);
4002 if (fabs(targetPosition - initialFocuserAbsPosition) > m_OpsFocusMechanics->focusMaxTravel->value())
4004 int minTravelLimit = qMax(0.0, initialFocuserAbsPosition - m_OpsFocusMechanics->focusMaxTravel->value());
4005 int maxTravelLimit = qMin(absMotionMax, initialFocuserAbsPosition + m_OpsFocusMechanics->focusMaxTravel->value());
4009 if (fabs(currentPosition - minTravelLimit) > 10 && targetPosition < minTravelLimit)
4011 targetPosition = minTravelLimit;
4014 else if (fabs(currentPosition - maxTravelLimit) > 10 && targetPosition > maxTravelLimit)
4016 targetPosition = maxTravelLimit;
4020 qCDebug(KSTARS_EKOS_FOCUS) <<
"targetPosition (" << targetPosition <<
") - initHFRAbsPos ("
4021 << initialFocuserAbsPosition <<
") exceeds maxTravel distance of " << m_OpsFocusMechanics->focusMaxTravel->value();
4023 QString message =
i18n(
"Maximum travel limit reached. Autofocus aborted.");
4024 appendLogText(message);
4025 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
4026 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_OOB);
4032 lastDelta = (targetPosition - currentPosition);
4034 qCDebug(KSTARS_EKOS_FOCUS) <<
"delta (targetPosition - currentPosition) " << lastDelta;
4037 if (ignoreLimitedDelta ==
false)
4039 double limitedDelta = qMax(-1.0 * m_OpsFocusMechanics->focusMaxSingleStep->value(),
4040 qMin(1.0 * m_OpsFocusMechanics->focusMaxSingleStep->value(), lastDelta));
4041 if (std::fabs(limitedDelta - lastDelta) > 0)
4043 qCDebug(KSTARS_EKOS_FOCUS) <<
"Limited delta to maximum permitted single step " <<
4044 m_OpsFocusMechanics->focusMaxSingleStep->value();
4045 lastDelta = limitedDelta;
4049 m_LastFocusDirection = (lastDelta > 0) ? FOCUS_OUT : FOCUS_IN;
4050 if (!changeFocus(lastDelta,
false))
4051 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
4057void Focus::addPlotPosition(
int pos,
double value,
bool plot)
4059 plot_position.append(pos);
4060 plot_value.append(value);
4062 emit newHFRPlotPosition(
static_cast<double>(pos), value, 1.0,
false, pulseDuration);
4068void Focus::updatePlotPosition()
4070 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS)
4073 if (inScanStartPos || focusAdvisor->inFocusAdvisor())
4076 plot_position.clear();
4078 plot_weight.clear();
4079 plot_outlier.clear();
4083 linearFocuser->getPass1Measurements(&positions, &plot_value, &plot_weight, &plot_outlier);
4084 plot_position.clear();
4085 for (
int i = 0; i < positions.
count(); i++)
4086 plot_position.append(positions[i]);
4089 if (linearFocuser && linearFocuser->isDone() && linearFocuser->solution() != -1)
4091 plot_position.append(linearFocuser->solution());
4092 plot_value.append(linearFocuser->solutionValue());
4093 plot_weight.append(linearFocuser->solutionWeight());
4094 plot_outlier.append(
false);
4098 else if (m_FocusAlgorithm == FOCUS_LINEAR)
4101 linearFocuser->getMeasurements(&positions, &plot_value, &plot_weight);
4102 plot_position.
clear();
4103 plot_outlier.clear();
4104 for (
int i = 0; i < positions.
count(); i++)
4106 plot_position.append(positions[i]);
4108 plot_outlier.append(
false);
4114 for (
int i = 0; i < plot_position.count(); i++)
4116 plot_weight.append(1.0);
4117 plot_outlier.append(
false);
4122void Focus::autoFocusRel()
4124 static int noStarCount = 0;
4125 static double minHFR = 1e6;
4126 QString deltaTxt =
QString(
"%1").
arg(fabs(currentHFR - minHFR) * 100.0, 0,
'g', 2);
4130 appendLogText(
i18n(
"FITS received. HFR %1. Delta (%2%) Min HFR (%3)", HFRText, deltaTxt, minHFRText));
4132 if (pulseDuration <= MINIMUM_PULSE_TIMER)
4134 appendLogText(
i18n(
"Autofocus failed to reach proper focus. Try adjusting the tolerance value."));
4135 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_TOLERANCE);
4140 if (currentHFR == INVALID_STAR_MEASURE)
4142 if (noStarCount < MAX_RECAPTURE_RETRIES)
4145 appendLogText(
i18n(
"No stars detected, capturing again..."));
4149 else if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
4151 appendLogText(
i18n(
"Failed to detect any stars at position %1. Continuing...", currentPosition));
4154 else if(!m_OpsFocusProcess->focusDonut->isChecked())
4157 appendLogText(
i18n(
"Failed to detect any stars. Reset frame and try again."));
4158 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
4165 switch (m_LastFocusDirection)
4168 lastHFR = currentHFR;
4170 m_LastFocusDirection = FOCUS_IN;
4171 changeFocus(-pulseDuration,
false);
4176 if (fabs(currentHFR - minHFR) < (m_OpsFocusProcess->focusTolerance->value() / 100.0) && HFRInc == 0)
4178 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
4180 else if (currentHFR < lastHFR)
4182 if (currentHFR < minHFR)
4183 minHFR = currentHFR;
4185 lastHFR = currentHFR;
4186 changeFocus(m_LastFocusDirection == FOCUS_IN ? -pulseDuration : pulseDuration,
false);
4193 lastHFR = currentHFR;
4197 pulseDuration *= 0.75;
4199 if (!changeFocus(m_LastFocusDirection == FOCUS_IN ? pulseDuration : -pulseDuration,
false))
4200 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
4203 m_LastFocusDirection = (m_LastFocusDirection == FOCUS_IN) ? FOCUS_OUT : FOCUS_IN;
4209void Focus::handleFocusButtonEvent()
4211 bool inward = (sender() == focusInB);
4215 updateButtonColors(inward ? focusInB : focusOutB, shift, ctrl);
4218 speedup *= m_OpsFocusMechanics->speedupShift->value();
4220 speedup *= m_OpsFocusMechanics->speedupCtrl->value();
4223 focusIn(-1, speedup);
4225 focusOut(-1, speedup);
4228void Focus::autoFocusProcessPositionChange(IPState state)
4230 if (state == IPS_OK)
4236 if (focuserAdditionalMovement > 0)
4238 int temp = focuserAdditionalMovement;
4239 focuserAdditionalMovement = 0;
4241 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Undoing overscan extension. Moving back in by %1 ticks in %2s")
4242 .
arg(temp).
arg(m_OpsFocusMechanics->focusOverscanDelay->value());
4244 QTimer::singleShot(m_OpsFocusMechanics->focusOverscanDelay->value() * 1000,
this, [
this, temp]()
4246 if (!changeFocus(-temp, focuserAdditionalMovementUpdateDir))
4248 appendLogText(i18n(
"Focuser error, check INDI panel."));
4249 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
4253 else if (inAutoFocus && !inAFOptimise)
4256 if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
4257 if (abs(linearRequestedPosition - currentPosition) > m_OpsFocusMechanics->focusTicks->value())
4258 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Focus positioning error: requested position %1, current position %2")
4259 .
arg(linearRequestedPosition).
arg(currentPosition);
4261 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Focus position reached at %1, starting capture in %2 seconds.").
arg(
4262 currentPosition).
arg(m_OpsFocusMechanics->focusSettleTime->value());
4264 if (m_OpsFocusProcess->focusDonut->isChecked())
4265 donutTimeDilation();
4266 capture(m_OpsFocusMechanics->focusSettleTime->value());
4269 else if (state == IPS_ALERT)
4271 appendLogText(
i18n(
"Focuser error, check INDI panel."));
4272 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_ERROR);
4275 qCDebug(KSTARS_EKOS_FOCUS) <<
4276 QString(
"autoFocusProcessPositionChange called with state %1 (%2), focuserAdditionalMovement=%3, inAutoFocus=%4, m_captureInProgress=%5, currentPosition=%6")
4277 .
arg(state).
arg(pstateStr(state)).
arg(focuserAdditionalMovement).
arg(inAutoFocus).
arg(m_captureInProgress)
4278 .
arg(currentPosition);
4282void Focus::donutTimeDilation()
4284 if (m_OpsFocusProcess->focusTimeDilation->value() == 1.0 || inScanStartPos || focusAdvisor->inFocusAdvisor())
4288 const double centre = (m_OpsFocusMechanics->focusNumSteps->value() + 1.0) / 2.0;
4290 const int currentStep = linearFocuser->currentStep() + 1;
4292 if (currentStep <= m_OpsFocusMechanics->focusNumSteps->value())
4293 distance = std::abs(centre - currentStep);
4297 double multiplier =
distance / (centre - 1.0) * m_OpsFocusProcess->focusTimeDilation->value();
4298 multiplier = std::max(multiplier, 1.0);
4299 const double exposure = multiplier * m_donutOrigExposure;
4300 focusExposure->setValue(exposure);
4301 qCDebug(KSTARS_EKOS_FOCUS) <<
"Donut time dilation for point " << currentStep <<
" from " << m_donutOrigExposure <<
" to "
4308 if (m_Focuser ==
nullptr || prop.getType() != INDI_NUMBER || prop.getDeviceName() != m_Focuser->getDeviceName())
4311 auto nvp = prop.getNumber();
4317 if (nvp->isNameMatch(
"FOCUS_BACKLASH_STEPS"))
4319 m_OpsFocusMechanics->focusBacklash->setValue(nvp->np[0].value);
4323 if (nvp->isNameMatch(
"ABS_FOCUS_POSITION"))
4328 if (m_DebugFocuserCounter++ >= 10 && m_DebugFocuserCounter <= 14)
4330 if (m_DebugFocuserCounter == 14)
4331 m_DebugFocuserCounter = 0;
4337 m_FocusMotionTimer.stop();
4338 INumber *
pos = IUFindNumber(nvp,
"FOCUS_ABSOLUTE_POSITION");
4339 IPState newState = nvp->s;
4344 int newPosition =
static_cast<int>(
pos->value);
4349 if (currentPosition == newPosition && currentPositionState == newState)
4351 if (logPositionAndState)
4353 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focuser position " << currentPosition <<
" and state:"
4354 << pstateStr(currentPositionState) <<
" unchanged";
4355 logPositionAndState =
false;
4361 logPositionAndState =
true;
4364 currentPositionState = newState;
4366 if (currentPosition != newPosition)
4368 currentPosition = newPosition;
4369 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abs Focuser position changed to " << currentPosition <<
"State:" << pstateStr(
4370 currentPositionState);
4372 emit absolutePositionChanged(currentPosition);
4376 qCDebug(KSTARS_EKOS_FOCUS) <<
"Can't access FOCUS_ABSOLUTE_POSITION. Current state:"
4377 << pstateStr(currentPositionState) <<
" New state:" << pstateStr(newState);
4379 if (newState != IPS_OK)
4381 if (inAutoFocus || inAdjustFocus || adaptFocus->inAdaptiveFocus())
4385 qCDebug(KSTARS_EKOS_FOCUS) <<
"Restarting focus motion timer, state " << pstateStr(newState);
4386 m_FocusMotionTimer.start();
4392 if (focuserAdditionalMovement == 0)
4397 if (focuserAdditionalMovement == 0)
4399 inAdjustFocus =
false;
4400 emit focusPositionAdjusted();
4407 if (focuserAdditionalMovement == 0)
4409 inAFOptimise =
false;
4410 emit focusAFOptimise();
4415 if (adaptFocus->inAdaptiveFocus())
4417 if (focuserAdditionalMovement == 0)
4419 adaptFocus->adaptiveFocusAdmin(currentPosition,
true,
true);
4424 if (m_RestartState == RESTART_NOW &&
status() != Ekos::FOCUS_ABORTED)
4426 if (focuserAdditionalMovement == 0)
4428 m_RestartState = RESTART_NONE;
4430 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4431 adaptFocus->setInAdaptiveFocus(
false);
4432 focusAdvisor->setInFocusAdvisor(
false);
4434 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4438 else if (m_RestartState == RESTART_ABORT && focuserAdditionalMovement == 0)
4444 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4445 m_RestartState = RESTART_NONE;
4446 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4447 adaptFocus->setInAdaptiveFocus(
false);
4448 focusAdvisor->setInFocusAdvisor(
false);
4454 autoFocusProcessPositionChange(newState);
4455 else if (newState == IPS_ALERT)
4463 if (nvp->isNameMatch(
"manualfocusdrive"))
4468 if (m_DebugFocuserCounter++ >= 10 && m_DebugFocuserCounter <= 14)
4470 if (m_DebugFocuserCounter == 14)
4471 m_DebugFocuserCounter = 0;
4477 m_FocusMotionTimer.stop();
4479 INumber *
pos = IUFindNumber(nvp,
"manualfocusdrive");
4480 IPState newState = nvp->s;
4481 if (
pos && newState == IPS_OK)
4483 if (focuserAdditionalMovement == 0)
4486 currentPosition +=
pos->value;
4487 absTicksLabel->setText(
QString::number(
static_cast<int>(currentPosition)));
4488 emit absolutePositionChanged(currentPosition);
4491 if (inAdjustFocus && newState == IPS_OK)
4493 if (focuserAdditionalMovement == 0)
4495 inAdjustFocus =
false;
4496 emit focusPositionAdjusted();
4501 if (inAFOptimise && newState == IPS_OK)
4503 if (focuserAdditionalMovement == 0)
4505 inAFOptimise =
false;
4506 emit focusAFOptimise();
4511 if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
4513 if (focuserAdditionalMovement == 0)
4515 adaptFocus->adaptiveFocusAdmin(currentPosition,
true,
true);
4521 if (m_RestartState == RESTART_NOW && newState == IPS_OK &&
status() != Ekos::FOCUS_ABORTED)
4523 if (focuserAdditionalMovement == 0)
4525 m_RestartState = RESTART_NONE;
4527 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4528 adaptFocus->setInAdaptiveFocus(
false);
4529 focusAdvisor->setInFocusAdvisor(
false);
4531 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4535 else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
4538 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4539 m_RestartState = RESTART_NONE;
4540 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4541 adaptFocus->setInAdaptiveFocus(
false);
4542 focusAdvisor->setInFocusAdvisor(
false);
4547 autoFocusProcessPositionChange(newState);
4548 else if (newState == IPS_ALERT)
4554 if (nvp->isNameMatch(
"REL_FOCUS_POSITION"))
4556 m_FocusMotionTimer.stop();
4558 INumber *
pos = IUFindNumber(nvp,
"FOCUS_RELATIVE_POSITION");
4559 IPState newState = nvp->s;
4560 if (
pos && newState == IPS_OK)
4562 if (focuserAdditionalMovement == 0)
4565 currentPosition +=
pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1);
4566 qCDebug(KSTARS_EKOS_FOCUS)
4567 <<
QString(
"Rel Focuser position moved %1 by %2 to %3")
4568 .
arg((m_LastFocusDirection == FOCUS_IN) ?
"in" :
"out").
arg(
pos->value).
arg(currentPosition);
4569 absTicksLabel->setText(
QString::number(
static_cast<int>(currentPosition)));
4570 emit absolutePositionChanged(currentPosition);
4573 if (inAdjustFocus && newState == IPS_OK)
4575 if (focuserAdditionalMovement == 0)
4577 inAdjustFocus =
false;
4578 emit focusPositionAdjusted();
4583 if (inAFOptimise && newState == IPS_OK)
4585 if (focuserAdditionalMovement == 0)
4587 inAFOptimise =
false;
4588 emit focusAFOptimise();
4593 if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
4595 if (focuserAdditionalMovement == 0)
4597 adaptFocus->adaptiveFocusAdmin(currentPosition,
true,
true);
4603 if (m_RestartState == RESTART_NOW && newState == IPS_OK &&
status() != Ekos::FOCUS_ABORTED)
4605 if (focuserAdditionalMovement == 0)
4607 m_RestartState = RESTART_NONE;
4609 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4610 adaptFocus->setInAdaptiveFocus(
false);
4611 focusAdvisor->setInFocusAdvisor(
false);
4613 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4617 else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
4620 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4621 m_RestartState = RESTART_NONE;
4622 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4623 adaptFocus->setInAdaptiveFocus(
false);
4624 focusAdvisor->setInFocusAdvisor(
false);
4629 autoFocusProcessPositionChange(newState);
4630 else if (newState == IPS_ALERT)
4639 if (nvp->isNameMatch(
"FOCUS_TIMER"))
4641 IPState newState = nvp->s;
4642 m_FocusMotionTimer.stop();
4644 if (m_RestartState == RESTART_NOW && newState == IPS_OK &&
status() != Ekos::FOCUS_ABORTED)
4646 if (focuserAdditionalMovement == 0)
4648 m_RestartState = RESTART_NONE;
4650 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4651 adaptFocus->setInAdaptiveFocus(
false);
4652 focusAdvisor->setInFocusAdvisor(
false);
4654 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4658 else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
4661 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4662 m_RestartState = RESTART_NONE;
4663 inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos =
false;
4664 adaptFocus->setInAdaptiveFocus(
false);
4665 focusAdvisor->setInFocusAdvisor(
false);
4669 if (canAbsMove ==
false && canRelMove ==
false)
4672 INumber *
pos = IUFindNumber(nvp,
"FOCUS_TIMER_VALUE");
4675 currentPosition +=
pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1);
4676 qCDebug(KSTARS_EKOS_FOCUS)
4677 <<
QString(
"Timer Focuser position moved %1 by %2 to %3")
4678 .
arg((m_LastFocusDirection == FOCUS_IN) ?
"in" :
"out").
arg(
pos->value).
arg(currentPosition);
4681 if (
pos && newState == IPS_OK && focuserAdditionalMovement == 0)
4684 if (inAdjustFocus && newState == IPS_OK)
4686 if (focuserAdditionalMovement == 0)
4688 inAdjustFocus =
false;
4689 emit focusPositionAdjusted();
4694 if (inAFOptimise && newState == IPS_OK)
4696 if (focuserAdditionalMovement == 0)
4698 inAFOptimise =
false;
4699 emit focusAFOptimise();
4704 if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
4706 if (focuserAdditionalMovement == 0)
4708 adaptFocus->adaptiveFocusAdmin(
true,
true,
true);
4713 autoFocusProcessPositionChange(newState);
4715 else if (newState == IPS_ALERT)
4724 const QString logtext(m_Focuser ==
nullptr ? text :
QString(
"[%1] %2").arg(m_Focuser->getDeviceName()).
arg(text));
4725 emit newLog(logtext);
4728void Focus::appendFocusLogText(
const QString &text)
4730 if (Options::focusLogging())
4732 const QString logtext(m_Focuser ==
nullptr ? text :
QString(
"[%1] %2").arg(m_Focuser->getDeviceName()).
arg(text));
4733 emit newFocusLog(logtext);
4739 if (m_Camera ==
nullptr)
4745 waitStarSelectTimer.stop();
4748 starMeasureFrames.clear();
4753 setState(Ekos::FOCUS_FRAMING);
4762void Focus::resetButtons()
4765 updateButtonColors(focusInB,
false,
false);
4766 updateButtonColors(focusOutB,
false,
false);
4770 startFocusB->setEnabled(
false);
4771 startAbInsB->setEnabled(
false);
4772 startLoopB->setEnabled(
false);
4773 focusOutB->setEnabled(
true);
4774 focusInB->setEnabled(
true);
4775 startGotoB->setEnabled(canAbsMove);
4776 stopFocusB->setEnabled(
true);
4777 captureB->setEnabled(
false);
4778 opticalTrainCombo->setEnabled(
false);
4779 trainB->setEnabled(
false);
4793 if (disabledWidgets.empty())
4795 AFDisable(trainLabel,
false);
4796 AFDisable(opticalTrainCombo,
false);
4797 AFDisable(trainB,
false);
4798 AFDisable(focuserGroup,
true);
4799 AFDisable(clearDataB,
false);
4802 m_FocusGainAFEnabled = focusGain->isEnabled();
4803 m_FocusISOAFEnabled = focusISO->isEnabled();
4804 AFDisable(ccdGroup,
false);
4806 AFDisable(toolsGroup,
false);
4809 m_FocusSubFrameAFEnabled = m_OpsFocusSettings->focusSubFrame->isEnabled();
4812 AFDisable(m_OpsFocusSettings,
false);
4813 AFDisable(m_OpsFocusProcess,
false);
4814 AFDisable(m_OpsFocusMechanics,
false);
4815 AFDisable(focusAdvisor->focusAdvGroupBox,
false);
4816 AFDisable(m_CFZDialog,
false);
4819 stopFocusB->setEnabled(
true);
4825 for(
int i = 0 ; i < disabledWidgets.size() ; i++)
4826 disabledWidgets[i]->setEnabled(
true);
4827 disabledWidgets.clear();
4829 bool cameraConnected = m_Camera && m_Camera->isConnected();
4830 bool enableCaptureButtons = cameraConnected && (!m_captureInProgress && !m_starDetectInProgress);
4832 captureB->setEnabled(enableCaptureButtons);
4833 resetFrameB->setEnabled(enableCaptureButtons);
4834 startLoopB->setEnabled(enableCaptureButtons);
4835 startFocusB->setEnabled(enableCaptureButtons);
4838 if (cameraConnected)
4840 ccdGroup->setEnabled(
true);
4841 toolsGroup->setEnabled(
true);
4845 ccdGroup->setEnabled(
false);
4846 toolsGroup->setEnabled(
false);
4849 if (m_Focuser && m_Focuser->isConnected())
4851 focusOutB->setEnabled(
true);
4852 focusInB->setEnabled(
true);
4853 startAbInsB->setEnabled(canAbInsStart());
4854 stopFocusB->setEnabled(!enableCaptureButtons);
4855 startGotoB->setEnabled(canAbsMove);
4856 stopGotoB->setEnabled(
true);
4857 focuserGroup->setEnabled(
true);
4861 focusOutB->setEnabled(
false);
4862 focusInB->setEnabled(
false);
4863 startAbInsB->setEnabled(
false);
4864 stopFocusB->setEnabled(
false);
4865 startGotoB->setEnabled(
false);
4866 stopGotoB->setEnabled(
false);
4867 focuserGroup->setEnabled(cameraConnected);
4871void Focus::updateButtonColors(
QPushButton *button,
bool shift,
bool ctrl)
4876 stylesheet =
"background-color: #D32F2F";
4878 stylesheet =
"background-color: #FFC107";
4880 stylesheet =
"background-color: #FF5722";
4890bool Focus::canAbInsStart()
4892 return canAbsMove && m_FocusAlgorithm == FOCUS_LINEAR1PASS && m_currentImageMask == FOCUS_MASK_MOSAIC
4893 && m_CurveFit != CurveFitting::FOCUS_QUADRATIC;
4897void Focus::AFDisable(
QWidget * widget,
const bool children)
4904 if (wid->isEnabled())
4906 wid->setEnabled(
false);
4907 disabledWidgets.push_back(wid);
4916 disabledWidgets.push_back(widget);
4920bool Focus::isFocusGainEnabled()
4922 return (inAutoFocus) ? m_FocusGainAFEnabled : focusGain->isEnabled();
4925bool Focus::isFocusISOEnabled()
4927 return (inAutoFocus) ? m_FocusISOAFEnabled : focusISO->isEnabled();
4930bool Focus::isFocusSubFrameEnabled()
4932 return (inAutoFocus) ? m_FocusSubFrameAFEnabled : m_OpsFocusSettings->focusSubFrame->isEnabled();
4935void Focus::updateBoxSize(
int value)
4937 if (m_Camera ==
nullptr)
4940 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
4942 if (targetChip ==
nullptr)
4945 int subBinX, subBinY;
4946 targetChip->getBinning(&subBinX, &subBinY);
4948 QRect trackBox = m_FocusView->getTrackingBox();
4952 QRect(
center.x() - value / (2 * subBinX),
center.y() - value / (2 * subBinY), value / subBinX, value / subBinY);
4954 m_FocusView->setTrackingBox(trackBox);
4959 if (m_ImageData.isNull())
4966 emit newImage(m_FocusView);
4972 if (state() == Ekos::FOCUS_PROGRESS)
4975 if (subFramed ==
false)
4977 rememberStarCenter.setX(
x);
4978 rememberStarCenter.setY(
y);
4981 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
4983 int subBinX, subBinY;
4984 targetChip->getBinning(&subBinX, &subBinY);
4987 if (subBinX != (focusBinning->currentIndex() + 1))
4993 int offset = (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX) * 1.5;
4997 bool squareMovedOutside =
false;
4999 if (subFramed ==
false && m_OpsFocusSettings->focusSubFrame->isChecked() && targetChip->canSubframe())
5002 if (!isStarMeasureStarBased())
5008 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
5010 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
5013 x = (
x - offset) * subBinX;
5014 y = (
y - offset) * subBinY;
5015 int w = offset * 2 * subBinX;
5016 int h = offset * 2 * subBinY;
5035 QVariantMap settings = frameSettings[targetChip];
5040 settings[
"binx"] = subBinX;
5041 settings[
"biny"] = subBinY;
5043 frameSettings[targetChip] = settings;
5047 qCDebug(KSTARS_EKOS_FOCUS) <<
"Frame is subframed. X:" <<
x <<
"Y:" <<
y <<
"W:" << w <<
"H:" << h <<
"binX:" << subBinX <<
5050 m_FocusView->setFirstLoad(
true);
5054 if (isStarMeasureStarBased())
5056 starCenter.setX(w / (2 * subBinX));
5057 starCenter.setY(h / (2 * subBinY));
5064 double dist = sqrt((starCenter.x() -
x) * (starCenter.x() -
x) + (starCenter.y() -
y) * (starCenter.y() -
y));
5066 squareMovedOutside = (dist > (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX));
5070 starRect =
QRect(starCenter.x() - m_OpsFocusSettings->focusBoxSize->value() / (2 * subBinX),
5071 starCenter.y() - m_OpsFocusSettings->focusBoxSize->value() / (2 * subBinY),
5072 m_OpsFocusSettings->focusBoxSize->value() / subBinX,
5073 m_OpsFocusSettings->focusBoxSize->value() / subBinY);
5074 m_FocusView->setTrackingBox(starRect);
5079 starCenter.setZ(subBinX);
5081 if (squareMovedOutside && inAutoFocus ==
false && m_OpsFocusSettings->focusAutoStarEnabled->isChecked())
5083 m_OpsFocusSettings->focusAutoStarEnabled->blockSignals(
true);
5084 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
5085 m_OpsFocusSettings->focusAutoStarEnabled->blockSignals(
false);
5086 appendLogText(
i18n(
"Disabling Auto Star Selection as star selection box was moved manually."));
5087 starSelected =
false;
5089 else if (starSelected ==
false)
5091 if (isStarMeasureStarBased())
5096 starSelected =
true;
5100 waitStarSelectTimer.stop();
5101 FocusState nextState = inAutoFocus ? FOCUS_PROGRESS : FOCUS_IDLE;
5102 if (nextState != state())
5104 setState(nextState);
5110 if (inAutoFocus || inAdjustFocus || adaptFocus->inAdaptiveFocus())
5114 str =
i18n(
"Autofocus");
5115 else if (inAdjustFocus)
5116 str =
i18n(
"Adjust Focus");
5118 str =
i18n(
"Adaptive Focus");
5120 if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
5122 appendLogText(
i18n(
"Check focus request - Waiting 10sec for %1 to complete.", str));
5131 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
5137 if (inFocusLoop || inBuildOffsets)
5139 QString str = inFocusLoop ?
"Focus Looping" :
" Build Offsets";
5140 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Check Focus rejected, %1 is already running.").
arg(str);
5142 else if (!isStarMeasureStarBased())
5146 qCDebug(KSTARS_EKOS_FOCUS) <<
"Check Focus requested with minimum required HFR" << requiredHFR;
5147 minimumRequiredHFR = requiredHFR;
5153void Focus::toggleSubframe(
bool enable)
5155 if (enable ==
false)
5158 m_FocusView->setTrackingBoxEnabled(enable);
5159 starSelected =
false;
5164 m_OpsFocusSettings->focusNoMaskRB->setChecked(
true);
5169 m_OpsFocusSettings->focusRingMaskRB->setEnabled(!enable);
5170 m_OpsFocusSettings->focusMosaicMaskRB->setEnabled(!enable);
5174 setAutoStarAndBox();
5181void Focus::setUseWeights()
5183 if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC || !m_OpsFocusSettings->focusUseFullField->isChecked()
5184 || m_StarMeasure == FOCUS_STAR_NUM_STARS || m_StarMeasure == FOCUS_STAR_FOURIER_POWER ||
5185 m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
5186 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
5188 m_OpsFocusProcess->focusUseWeights->setEnabled(
false);
5189 m_OpsFocusProcess->focusUseWeights->setChecked(
false);
5192 m_OpsFocusProcess->focusUseWeights->setEnabled(
true);
5199void Focus::setDenoise()
5201 if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
5202 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
5203 m_OpsFocusProcess->focusDenoise->setEnabled(
true);
5206 m_OpsFocusProcess->focusDenoise->setEnabled(
false);
5207 m_OpsFocusProcess->focusDenoise->setChecked(
false);
5216void Focus::setDonutBuster()
5218 if (m_FocusAlgorithm != FOCUS_LINEAR1PASS)
5220 m_OpsFocusProcess->focusDonut->hide();
5221 m_OpsFocusProcess->focusDonut->setEnabled(
false);
5222 m_OpsFocusProcess->focusDonut->setChecked(
false);
5226 m_OpsFocusProcess->focusDonut->show();
5227 if ((m_StarMeasure == FOCUS_STAR_HFR || m_StarMeasure == FOCUS_STAR_HFR_ADJ || m_StarMeasure == FOCUS_STAR_FWHM) &&
5228 (m_FocusWalk == FOCUS_WALK_FIXED_STEPS || m_FocusWalk == FOCUS_WALK_CFZ_SHUFFLE) &&
5229 (m_CurveFit != CurveFitting::FOCUS_QUADRATIC))
5230 m_OpsFocusProcess->focusDonut->setEnabled(
true);
5233 m_OpsFocusProcess->focusDonut->setEnabled(
false);
5234 m_OpsFocusProcess->focusDonut->setChecked(
false);
5241 focusExposure->setValue(value);
5246 INDI_UNUSED(subBinY);
5247 focusBinning->setCurrentIndex(subBinX - 1);
5252 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(enable);
5257 m_OpsFocusSettings->focusSubFrame->setChecked(enable);
5262 m_OpsFocusSettings->focusBoxSize->setValue(boxSize);
5263 m_OpsFocusMechanics->focusTicks->setValue(stepSize);
5264 m_OpsFocusMechanics->focusMaxTravel->setValue(maxTravel);
5265 m_OpsFocusProcess->focusTolerance->setValue(tolerance);
5268void Focus::checkAutoStarTimeout()
5271 if (starCenter.isNull() && (inAutoFocus || minimumRequiredHFR > 0))
5275 if (rememberStarCenter.isNull() ==
false)
5277 focusStarSelected(rememberStarCenter.x(), rememberStarCenter.y());
5278 appendLogText(
i18n(
"No star was selected. Using last known position..."));
5283 initialFocuserAbsPosition = -1;
5284 appendLogText(
i18n(
"No star was selected. Aborting..."));
5285 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
5287 else if (state() == FOCUS_WAITING)
5288 setState(FOCUS_IDLE);
5291void Focus::setAbsoluteFocusTicks()
5293 if (absTicksSpin->value() == currentPosition)
5295 appendLogText(
i18n(
"Focuser already at %1...", currentPosition));
5298 focusInB->setEnabled(
false);
5299 focusOutB->setEnabled(
false);
5300 startGotoB->setEnabled(
false);
5301 if (!changeFocus(absTicksSpin->value() - currentPosition))
5302 qCDebug(KSTARS_EKOS_FOCUS) <<
"setAbsoluteFocusTicks unable to move focuser.";
5305void Focus::syncTrackingBoxPosition()
5307 if (m_OpsFocusSettings->focusUseFullField->isChecked() || starCenter.isNull())
5310 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5311 Q_ASSERT(targetChip);
5313 int subBinX = 1, subBinY = 1;
5314 targetChip->getBinning(&subBinX, &subBinY);
5316 double boxSize = m_OpsFocusSettings->focusBoxSize->value();
5318 targetChip->getFrame(&x, &y, &w, &h);
5320 if (boxSize / subBinX >= w || boxSize / subBinY >= h)
5322 m_OpsFocusSettings->focusBoxSize->setValue((boxSize / subBinX >= w) ? w : h);
5327 if (subBinX != starCenter.z())
5329 if (starCenter.z() > 0)
5331 starCenter.setX(starCenter.x() * (starCenter.z() / subBinX));
5332 starCenter.setY(starCenter.y() * (starCenter.z() / subBinY));
5335 starCenter.setZ(subBinX);
5339 if (isStarMeasureStarBased())
5340 starRect =
QRect(starCenter.x() - boxSize / (2 * subBinX), starCenter.y() - boxSize / (2 * subBinY),
5341 boxSize / subBinX, boxSize / subBinY);
5345 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
5346 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
5347 int boxTLX = starCenter.x() - boxSize / (2 * subBinX);
5348 boxTLX = std::max(boxTLX, minX);
5349 int boxTLY = starCenter.y() - boxSize / (2 * subBinY);
5350 boxTLY = std::max(boxTLY, minY);
5351 const int boxBRX = boxTLX + (boxSize / subBinX);
5353 boxTLX -= boxBRX - maxX;
5354 const int boxBRY = boxTLY + (boxSize / subBinY);
5356 boxTLY -= boxBRY - maxY;
5358 starRect =
QRect(boxTLX, boxTLY, boxSize / subBinX, boxSize / subBinY);
5360 m_FocusView->setTrackingBoxEnabled(
true);
5361 m_FocusView->setTrackingBox(starRect);
5364void Focus::showFITSViewer()
5366 static int lastFVTabID = -1;
5373 fv->loadData(m_ImageData, url, &lastFVTabID);
5374 connect(fv.get(), &FITSViewer::terminated,
this, [
this]()
5379 else if (fv->updateData(m_ImageData, url, lastFVTabID, &lastFVTabID) ==
false)
5380 fv->loadData(m_ImageData, url, &lastFVTabID);
5386void Focus::adjustFocusOffset(
int value,
bool useAbsoluteOffset)
5389 if (inAdjustFocus || adaptFocus->inAdaptiveFocus())
5391 QString str = inAdjustFocus ?
i18n(
"Adjust Focus") :
i18n(
"Adaptive Focus");
5392 if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
5394 appendLogText(
i18n(
"Adjust focus request - Waiting 10sec for %1 to complete.", str));
5397 adjustFocusOffset(value, useAbsoluteOffset);
5402 qCDebug(KSTARS_EKOS_FOCUS) <<
"adjustFocusOffset called whilst" << str <<
"in progress. Ignoring...";
5403 emit focusPositionAdjusted();
5408 inAdjustFocus =
true;
5411 int newPosition = (useAbsoluteOffset) ? value : value + currentPosition;
5413 if (!changeFocus(newPosition - currentPosition))
5414 qCDebug(KSTARS_EKOS_FOCUS) <<
"adjustFocusOffset unable to move focuser";
5417void Focus::toggleFocusingWidgetFullScreen()
5419 if (focusingWidget->parent() ==
nullptr)
5421 focusingWidget->setParent(
this);
5422 rightLayout->insertWidget(0, focusingWidget);
5423 focusingWidget->showNormal();
5427 focusingWidget->setParent(
nullptr);
5428 focusingWidget->setWindowTitle(
i18nc(
"@title:window",
"Focus Frame"));
5430 focusingWidget->showMaximized();
5431 focusingWidget->show();
5435void Focus::setMountStatus(ISD::Mount::Status newState)
5439 case ISD::Mount::MOUNT_PARKING:
5440 case ISD::Mount::MOUNT_SLEWING:
5441 case ISD::Mount::MOUNT_MOVING:
5442 captureB->setEnabled(
false);
5443 startFocusB->setEnabled(
false);
5444 startAbInsB->setEnabled(
false);
5445 startLoopB->setEnabled(
false);
5460void Focus::setMountCoords(
const SkyPoint &position, ISD::Mount::PierSide pierSide,
const dms &ha)
5469 auto name = deviceRemoved->getDeviceName();
5473 if (m_Focuser && m_Focuser->getDeviceName() == name)
5475 m_Focuser->disconnect(
this);
5476 m_Focuser =
nullptr;
5485 for (
auto &oneSource : m_TemperatureSources)
5487 if (oneSource->getDeviceName() == name)
5490 if (m_LastSourceDeviceAutofocusTemperature && m_LastSourceDeviceAutofocusTemperature->getDeviceName() == name)
5491 m_LastSourceDeviceAutofocusTemperature.reset(
nullptr);
5493 m_TemperatureSources.removeAll(oneSource);
5496 defaultFocusTemperatureSource->removeItem(defaultFocusTemperatureSource->findText(name));
5503 if (m_Camera && m_Camera->getDeviceName() == name)
5505 m_Camera->disconnect(
this);
5516 if (m_FilterWheel && m_FilterWheel->getDeviceName() == name)
5518 m_FilterWheel->disconnect(
this);
5519 m_FilterWheel =
nullptr;
5529void Focus::setupFilterManager()
5532 if (m_FilterManager)
5533 m_FilterManager->disconnect(
this);
5536 Ekos::Manager::Instance()->createFilterManager(m_FilterWheel);
5539 Ekos::Manager::Instance()->getFilterManager(m_FilterWheel->getDeviceName(), m_FilterManager);
5544 connect(
this, &Focus::absolutePositionChanged, m_FilterManager.get(), &FilterManager::setFocusAbsolutePosition);
5547 connect(
this, &Focus::newStatus,
this, [
this](Ekos::FocusState state,
const QString trainname,
const bool update)
5549 Q_UNUSED(trainname);
5550 if (m_FilterManager)
5552 m_FilterManager->setFocusStatus(state);
5553 if (update && focusFilter->currentIndex() != -1 && canAbsMove && state == Ekos::FOCUS_COMPLETE)
5555 m_FilterManager->setFilterAbsoluteFocusDetails(focusFilter->currentIndex(), currentPosition,
5556 m_LastSourceAutofocusTemperature, m_LastSourceAutofocusAlt);
5564 connect(m_FilterManager.get(), &FilterManager::newStatus,
this, [
this](Ekos::FilterState filterState)
5567 if (filterState == FILTER_OFFSET && state() != Ekos::FOCUS_PROGRESS)
5569 if (m_GuidingSuspended == false && m_OpsFocusSettings->focusSuspendGuiding->isChecked())
5571 m_GuidingSuspended = true;
5572 emit suspendGuiding();
5578 connect(m_FilterManager.get(), &FilterManager::ready,
this, [
this]()
5581 if (focusFilter->currentIndex() != currentFilterPosition - 1)
5582 focusFilter->setCurrentIndex(currentFilterPosition - 1);
5584 if (filterPositionPending)
5586 filterPositionPending = false;
5589 else if (fallbackFilterPending)
5591 fallbackFilterPending =
false;
5592 setState(m_pendingState);
5593 m_pendingState = FOCUS_IDLE;
5598 connect(m_FilterManager.get(), &FilterManager::failed,
this, [
this]()
5600 if (filterPositionPending)
5602 appendLogText(i18n(
"Filter operation failed."));
5603 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FILTER_MANAGER);
5608 connect(m_FilterManager.get(), &FilterManager::runAutoFocus,
this, &Focus::runAutoFocus);
5611 connect(m_FilterManager.get(), &FilterManager::abortAutoFocus,
this, &Focus::abort);
5614 connect(m_FilterManager.get(), &FilterManager::newFocusOffset,
this, &Focus::adjustFocusOffset);
5617 connect(m_FilterManager.get(), &FilterManager::labelsChanged,
this, [
this]()
5619 focusFilter->clear();
5620 focusFilter->addItems(m_FilterManager->getFilterLabels());
5621 currentFilterPosition = m_FilterManager->getFilterPosition();
5622 focusFilter->setCurrentIndex(currentFilterPosition - 1);
5626 connect(m_FilterManager.get(), &FilterManager::positionChanged,
this, [
this]()
5628 currentFilterPosition = m_FilterManager->getFilterPosition();
5629 focusFilter->setCurrentIndex(currentFilterPosition - 1);
5633 connect(m_FilterManager.get(), &FilterManager::exposureChanged,
this, [
this]()
5635 focusExposure->setValue(m_FilterManager->getFilterExposure());
5639 connect(m_FilterManager.get(), &FilterManager::wavelengthChanged,
this, [
this]()
5641 wavelengthChanged();
5645void Focus::connectFilterManager()
5650 if (m_FilterManager)
5652 m_FilterManager->refreshFilterModel();
5653 m_FilterManager->show();
5654 m_FilterManager->raise();
5659 connect(
this, &Focus::focusPositionAdjusted,
this, [
this]()
5661 if (m_FilterManager)
5662 m_FilterManager->setFocusOffsetComplete();
5663 if (m_GuidingSuspended && state() != Ekos::FOCUS_PROGRESS)
5665 QTimer::singleShot(m_OpsFocusMechanics->focusSettleTime->value() * 1000,
this, [
this]()
5667 m_GuidingSuspended = false;
5668 emit resumeGuiding();
5674 connect(
this, &Focus::focusAFOptimise,
this, [
this]()
5676 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_OPTIMISED_OUT);
5683 if (inAutoFocus && m_OpsFocusProcess->focusDonut->isEnabled())
5686 if (m_FilterManager)
5687 m_FilterManager->setFilterExposure(focusFilter->currentIndex(), focusExposure->value());
5693 if (m_FilterManager)
5695 focusExposure->setValue(m_FilterManager->getFilterExposure(text));
5705 if (m_Camera ==
nullptr)
5708 if (m_Camera->isBLOBEnabled() ==
false)
5711 if (Options::guiderType() != Ekos::Guide::GUIDE_INTERNAL)
5712 m_Camera->setBLOBEnabled(
true);
5718 KSMessageBox::Instance()->disconnect(
this);
5719 m_Camera->setVideoStreamEnabled(
enabled);
5721 KSMessageBox::Instance()->questionYesNo(
i18n(
"Image transfer is disabled for this camera. Would you like to enable it?"));
5725 m_Camera->setVideoStreamEnabled(
enabled);
5741void Focus::setVideoStreamEnabled(
bool enabled)
5745 liveVideoB->setChecked(
true);
5750 liveVideoB->setChecked(
false);
5755void Focus::processCaptureTimeout()
5757 m_captureInProgress =
false;
5759 if (m_abortInProgress)
5762 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding frame in " << __FUNCTION__;
5766 captureTimeoutCounter++;
5768 if (captureTimeoutCounter >= 3)
5770 captureTimeoutCounter = 0;
5771 m_MissingCameraCounter = 0;
5772 captureTimeout.stop();
5773 appendLogText(
i18n(
"Exposure timeout. Aborting..."));
5774 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_TIMEOUT);
5778 appendLogText(
i18n(
"Exposure timeout. Restarting exposure..."));
5779 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5780 targetChip->abortExposure();
5782 capture(focusExposure->value());
5786 else if (m_MissingCameraCounter < 40)
5788 m_MissingCameraCounter++;
5789 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unable to restart focus exposure as camera is missing, trying again in 5 seconds...";
5794 m_MissingCameraCounter = 0;
5795 captureTimeoutCounter = 0;
5796 captureTimeout.stop();
5797 appendLogText(
i18n(
"Exposure timeout. Aborting..."));
5798 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_TIMEOUT);
5803void Focus::processCaptureErrorDefault()
5805 processCaptureError(ISD::Camera::ERROR_CAPTURE);
5810 m_captureInProgress =
false;
5811 captureTimeout.stop();
5813 if (m_abortInProgress)
5815 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding frame in " << __FUNCTION__;
5821 appendLogText(
i18n(
"Failed to save image. Aborting..."));
5822 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
5829 captureFailureCounter++;
5831 if (captureFailureCounter >= 3)
5833 captureFailureCounter = 0;
5834 captureTimeoutCounter = 0;
5835 m_MissingCameraCounter = 0;
5836 appendLogText(
i18n(
"Exposure failure. Aborting..."));
5837 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
5841 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5842 targetChip->abortExposure();
5843 capture(focusExposure->value());
5847 else if (m_MissingCameraCounter < 40)
5849 m_MissingCameraCounter++;
5850 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unable to restart focus exposure as camera is missing, trying again in 5 seconds...";
5857 m_MissingCameraCounter = 0;
5858 captureFailureCounter = 0;
5859 captureTimeoutCounter = 0;
5860 captureTimeout.stop();
5861 appendLogText(
i18n(
"Exposure failure. Aborting..."));
5862 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
5866void Focus::syncSettings()
5879 if ( (dsb = qobject_cast<QDoubleSpinBox*>(sender())))
5882 value = dsb->
value();
5885 else if ( (sb = qobject_cast<QSpinBox*>(sender())))
5888 value = sb->
value();
5890 else if ( (cb = qobject_cast<QCheckBox*>(sender())))
5895 else if ( (gb = qobject_cast<QGroupBox*>(sender())))
5900 else if ( (rb = qobject_cast<QRadioButton*>(sender())))
5906 m_Settings.remove(key);
5911 else if ( (cbox = qobject_cast<QComboBox*>(sender())))
5916 else if ( (s = qobject_cast<QSplitter*>(sender())))
5924 Options::self()->setProperty(key.
toLatin1(), value);
5926 m_Settings[key] = value;
5927 m_GlobalSettings[key] = value;
5931 m_DebounceTimer.start();
5937void Focus::settleSettings()
5939 emit settingsUpdated(getAllSettings());
5941 OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()));
5942 OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Focus, m_Settings);
5945void Focus::loadGlobalSettings()
5950 QVariantMap settings;
5952 for (
auto &oneWidget : findChildren<QComboBox*>())
5954 if (oneWidget->objectName() ==
"opticalTrainCombo")
5957 key = oneWidget->objectName();
5958 value = Options::self()->property(key.
toLatin1());
5959 if (value.
isValid() && oneWidget->count() > 0)
5961 oneWidget->setCurrentText(value.
toString());
5962 settings[key] = value;
5965 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5969 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
5971 key = oneWidget->objectName();
5972 value = Options::self()->property(key.
toLatin1());
5975 oneWidget->setValue(value.
toDouble());
5976 settings[key] = value;
5979 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5983 for (
auto &oneWidget : findChildren<QSpinBox*>())
5985 key = oneWidget->objectName();
5986 value = Options::self()->property(key.
toLatin1());
5989 oneWidget->setValue(value.
toInt());
5990 settings[key] = value;
5993 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5997 for (
auto &oneWidget : findChildren<QCheckBox*>())
5999 key = oneWidget->objectName();
6000 value = Options::self()->property(key.
toLatin1());
6003 oneWidget->setChecked(value.
toBool());
6004 settings[key] = value;
6006 else if (key != forceInSeqAF->objectName())
6007 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
6011 for (
auto &oneWidget : findChildren<QGroupBox*>())
6013 if (oneWidget->isCheckable())
6015 key = oneWidget->objectName();
6016 value = Options::self()->property(key.
toLatin1());
6019 oneWidget->setChecked(value.
toBool());
6020 settings[key] = value;
6023 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
6028 for (
auto &oneWidget : findChildren<QSplitter*>())
6030 key = oneWidget->objectName();
6031 value = Options::self()->property(key.
toLatin1());
6036 oneWidget->restoreState(valueBA);
6037 settings[key] = valueBA;
6040 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
6044 for (
auto &oneWidget : findChildren<QRadioButton*>())
6046 key = oneWidget->objectName();
6047 value = Options::self()->property(key.
toLatin1());
6050 oneWidget->setChecked(value.
toBool());
6051 settings[key] = value;
6056 m_GlobalSettings = m_Settings = settings;
6059void Focus::checkMosaicMaskLimits()
6061 if (m_Camera ==
nullptr || m_Camera->isConnected() ==
false)
6063 auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
6064 if (targetChip ==
nullptr || frameSettings.contains(targetChip) ==
false)
6066 auto settings = frameSettings[targetChip];
6069 auto width = settings[
"w"].toInt();
6070 auto height = settings[
"h"].toInt();
6071 if (width == 0 || height == 0)
6075 auto min = std::min(width, height);
6077 m_OpsFocusSettings->focusMosaicTileWidth->setMaximum(100 * min / (3 * width));
6080void Focus::connectSyncSettings()
6083 for (
auto &oneWidget : findChildren<QComboBox*>())
6085 if (oneWidget != opticalTrainCombo)
6089 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
6093 for (
auto &oneWidget : findChildren<QSpinBox*>())
6097 for (
auto &oneWidget : findChildren<QCheckBox*>())
6101 for (
auto &oneWidget : findChildren<QGroupBox*>())
6102 if (oneWidget->isCheckable())
6106 for (
auto &oneWidget : findChildren<QSplitter*>())
6110 for (
auto &oneWidget : findChildren<QRadioButton*>())
6114void Focus::disconnectSyncSettings()
6117 for (
auto &oneWidget : findChildren<QComboBox*>())
6118 disconnect(oneWidget, QOverload<int>::of(&
QComboBox::activated),
this, &Ekos::Focus::syncSettings);
6121 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
6125 for (
auto &oneWidget : findChildren<QSpinBox*>())
6129 for (
auto &oneWidget : findChildren<QCheckBox*>())
6133 for (
auto &oneWidget : findChildren<QGroupBox*>())
6134 if (oneWidget->isCheckable())
6138 for (
auto &oneWidget : findChildren<QSplitter*>())
6142 for (
auto &oneWidget : findChildren<QRadioButton*>())
6146void Focus::initPlots()
6150 profileDialog =
new QDialog(
this);
6153 profileDialog->setWindowTitle(
i18nc(
"@title:window",
"Relative Profile"));
6154 profilePlot =
new FocusProfilePlot(profileDialog);
6157 profileDialog->setLayout(profileLayout);
6158 profileDialog->resize(400, 300);
6161 connect(
this, &Ekos::Focus::newHFR, [
this](
double currentHFR,
int pos)
6163 Q_UNUSED(pos) profilePlot->drawProfilePlot(currentHFR);
6167void Focus::initConnections()
6170 waitStarSelectTimer.setInterval(AUTO_STAR_TIMEOUT);
6175 m_DebounceTimer.setInterval(500);
6176 m_DebounceTimer.setSingleShot(
true);
6191 captureTimer.setSingleShot(
true);
6198 captureTimeout.setSingleShot(
true);
6233 &Ekos::Focus::updateBoxSize);
6239 m_CFZDialog->show();
6240 m_CFZDialog->raise();
6246 focusAdvisor->setButtons(
false);
6247 focusAdvisor->show();
6248 focusAdvisor->raise();
6254 emit inSequenceAF(enabled, opticalTrain());
6260 setFocusDetection(static_cast<StarAlgorithm>(index));
6266 setFocusAlgorithm(static_cast<Algorithm>(index));
6272 this, [&](
int index)
6274 setCurveFit(static_cast<CurveFitting::CurveFit>(index));
6279 this, [&](
int index)
6281 setStarMeasure(static_cast<StarMeasure>(index));
6286 this, [&](
int index)
6288 setStarPSF(static_cast<StarPSF>(index));
6293 this, [&](
int index)
6295 setStarUnits(static_cast<StarUnits>(index));
6300 this, [&](
int index)
6302 setWalk(static_cast<FocusWalk>(index));
6313 starCenter = QVector3D();
6314 starSelected = false;
6315 m_FocusView->setTrackingBox(QRect());
6323 &Ekos::Focus::calcCFZ);
6326 &Ekos::Focus::calcCFZ);
6367void Focus::setFocusDetection(StarAlgorithm starAlgorithm)
6369 static bool first =
true;
6370 if (!first && m_FocusDetection == starAlgorithm)
6375 m_FocusDetection = starAlgorithm;
6378 setFocusAlgorithm(m_FocusAlgorithm);
6379 setAutoStarAndBox();
6387void Focus::setAutoStarAndBox()
6389 if (m_FocusDetection == ALGORITHM_BAHTINOV)
6391 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
6392 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
6393 m_OpsFocusSettings->focusBoxSize->setEnabled(m_OpsFocusSettings->focusSubFrame->isChecked());
6394 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(m_OpsFocusSettings->focusSubFrame->isChecked());
6395 m_OpsFocusSettings->focusBoxSize->setMaximum(512);
6396 if (m_OpsFocusSettings->focusBoxSize->value() > 512)
6397 m_OpsFocusSettings->focusBoxSize->setValue(m_OpsFocusSettings->focusBoxSize->value());
6399 else if(m_OpsFocusSettings->focusSubFrame->isChecked())
6401 if(isStarMeasureStarBased())
6403 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
true);
6405 m_OpsFocusSettings->focusBoxSize->setEnabled(
true);
6406 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
true);
6407 if (m_OpsFocusSettings->focusBoxSize->value() > 256)
6408 m_OpsFocusSettings->focusBoxSize->setValue(m_OpsFocusSettings->focusBoxSize->value());
6409 m_OpsFocusSettings->focusBoxSize->setMaximum(256);
6413 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
6414 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
6417 m_OpsFocusSettings->focusBoxSize->setEnabled(
true);
6418 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
true);
6419 int maxSize = std::min(m_CcdWidth, m_CcdHeight);
6420 int step = m_OpsFocusSettings->focusBoxSize->singleStep();
6421 maxSize = std::max(256, (maxSize / step) * step);
6422 m_OpsFocusSettings->focusBoxSize->setMaximum(maxSize);
6428 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
6429 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
6430 m_OpsFocusSettings->focusBoxSize->setEnabled(
false);
6431 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
false);
6436void Focus::setFocusAlgorithm(Algorithm algorithm)
6438 m_FocusAlgorithm = algorithm;
6441 case FOCUS_ITERATIVE:
6443 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6444 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6445 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6446 m_OpsFocusProcess->focusMultiRowAverage->hide();
6448 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6449 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6450 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6451 m_OpsFocusProcess->focusGaussianSigma->hide();
6453 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6454 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6455 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6456 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6458 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarMeasureLabel);
6459 m_OpsFocusProcess->focusStarMeasureLabel->hide();
6460 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarMeasure);
6461 m_OpsFocusProcess->focusStarMeasure->hide();
6463 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6464 m_OpsFocusProcess->focusStarPSFLabel->hide();
6465 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6466 m_OpsFocusProcess->focusStarPSF->hide();
6468 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6469 m_OpsFocusProcess->focusUseWeights->hide();
6471 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
6472 m_OpsFocusProcess->focusR2LimitLabel->hide();
6473 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
6474 m_OpsFocusProcess->focusR2Limit->hide();
6476 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
6477 m_OpsFocusProcess->focusRefineCurveFit->hide();
6478 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6480 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
6481 m_OpsFocusProcess->focusToleranceLabel->hide();
6482 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
6483 m_OpsFocusProcess->focusTolerance->hide();
6485 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6486 m_OpsFocusProcess->focusThresholdLabel->hide();
6487 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6488 m_OpsFocusProcess->focusThreshold->hide();
6490 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusCurveFitLabel);
6491 m_OpsFocusProcess->focusCurveFitLabel->hide();
6492 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusCurveFit);
6493 m_OpsFocusProcess->focusCurveFit->hide();
6495 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6496 m_OpsFocusProcess->focusDenoise->hide();
6499 m_OpsFocusProcess->focusDonut->hide();
6500 m_OpsFocusProcess->focusDonut->setChecked(
false);
6503 m_OpsFocusProcess->focusScanStartPos->hide();
6504 m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
6507 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
6510 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6512 m_OpsFocusProcess->focusStarMeasure->clear();
6513 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6514 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6518 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
6519 m_OpsFocusProcess->focusToleranceLabel->show();
6520 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
6521 m_OpsFocusProcess->focusTolerance->show();
6523 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
6524 m_OpsFocusProcess->focusFramesCountLabel->show();
6525 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
6526 m_OpsFocusProcess->focusFramesCount->show();
6528 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
6529 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6530 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
6531 m_OpsFocusProcess->focusHFRFramesCount->show();
6533 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6535 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
6536 m_OpsFocusProcess->focusThresholdLabel->show();
6537 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
6538 m_OpsFocusProcess->focusThreshold->show();
6540 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6542 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
6543 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6544 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
6545 m_OpsFocusProcess->focusMultiRowAverage->show();
6547 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
6548 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6549 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
6550 m_OpsFocusProcess->focusGaussianSigma->show();
6552 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
6553 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6554 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
6555 m_OpsFocusProcess->focusGaussianKernelSize->show();
6559 startAbInsB->setEnabled(canAbInsStart());
6563 m_OpsFocusSettings->focusAdaptive->setChecked(
false);
6564 m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
6565 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
6567 m_OpsFocusSettings->focusAFOptimize->setValue(0);
6568 m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
6571 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
true);
6572 m_OpsFocusMechanics->focusOutSteps->setEnabled(
false);
6575 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6577 m_OpsFocusMechanics->focusWalk->clear();
6578 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6579 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6583 case FOCUS_POLYNOMIAL:
6585 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6586 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6587 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6588 m_OpsFocusProcess->focusMultiRowAverage->hide();
6590 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6591 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6592 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6593 m_OpsFocusProcess->focusGaussianSigma->hide();
6595 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6596 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6597 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6598 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6600 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6601 m_OpsFocusProcess->focusStarPSFLabel->hide();
6602 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6603 m_OpsFocusProcess->focusStarPSF->hide();
6605 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6606 m_OpsFocusProcess->focusUseWeights->hide();
6608 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
6609 m_OpsFocusProcess->focusR2LimitLabel->hide();
6610 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
6611 m_OpsFocusProcess->focusR2Limit->hide();
6613 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
6614 m_OpsFocusProcess->focusRefineCurveFit->hide();
6615 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6617 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
6618 m_OpsFocusProcess->focusToleranceLabel->hide();
6619 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
6620 m_OpsFocusProcess->focusTolerance->hide();
6622 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6623 m_OpsFocusProcess->focusThresholdLabel->hide();
6624 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6625 m_OpsFocusProcess->focusThreshold->hide();
6627 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6628 m_OpsFocusProcess->focusDenoise->hide();
6631 m_OpsFocusProcess->focusDonut->hide();
6632 m_OpsFocusProcess->focusDonut->setChecked(
false);
6635 m_OpsFocusProcess->focusScanStartPos->hide();
6636 m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
6639 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6641 m_OpsFocusProcess->focusStarMeasure->clear();
6642 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6643 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6648 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
6649 m_OpsFocusProcess->focusCurveFitLabel->show();
6650 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
6651 m_OpsFocusProcess->focusCurveFit->show();
6652 if (m_OpsFocusProcess->focusCurveFit->count() != 1)
6654 m_OpsFocusProcess->focusCurveFit->clear();
6655 m_OpsFocusProcess->focusCurveFit->addItem(m_CurveFitText.at(CurveFitting::FOCUS_QUADRATIC));
6656 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
6659 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
6660 m_OpsFocusProcess->focusToleranceLabel->show();
6661 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
6662 m_OpsFocusProcess->focusTolerance->show();
6664 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
6665 m_OpsFocusProcess->focusFramesCountLabel->show();
6666 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
6667 m_OpsFocusProcess->focusFramesCount->show();
6669 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
6670 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6671 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
6672 m_OpsFocusProcess->focusHFRFramesCount->show();
6674 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6676 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
6677 m_OpsFocusProcess->focusThresholdLabel->show();
6678 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
6679 m_OpsFocusProcess->focusThreshold->show();
6681 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6683 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
6684 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6685 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
6686 m_OpsFocusProcess->focusMultiRowAverage->show();
6688 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
6689 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6690 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
6691 m_OpsFocusProcess->focusGaussianSigma->show();
6693 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
6694 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6695 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
6696 m_OpsFocusProcess->focusGaussianKernelSize->show();
6700 startAbInsB->setEnabled(canAbInsStart());
6704 m_OpsFocusSettings->focusAdaptive->setChecked(
false);
6705 m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
6706 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
6708 m_OpsFocusSettings->focusAFOptimize->setValue(0);
6709 m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
6712 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
true);
6713 m_OpsFocusMechanics->focusOutSteps->setEnabled(
false);
6716 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6718 m_OpsFocusMechanics->focusWalk->clear();
6719 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6720 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6726 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6727 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6728 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6729 m_OpsFocusProcess->focusMultiRowAverage->hide();
6731 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6732 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6733 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6734 m_OpsFocusProcess->focusGaussianSigma->hide();
6736 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6737 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6738 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6739 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6741 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6742 m_OpsFocusProcess->focusThresholdLabel->hide();
6743 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6744 m_OpsFocusProcess->focusThreshold->hide();
6746 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6747 m_OpsFocusProcess->focusStarPSFLabel->hide();
6748 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6749 m_OpsFocusProcess->focusStarPSF->hide();
6751 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6752 m_OpsFocusProcess->focusUseWeights->hide();
6754 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
6755 m_OpsFocusProcess->focusR2LimitLabel->hide();
6756 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
6757 m_OpsFocusProcess->focusR2Limit->hide();
6759 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
6760 m_OpsFocusProcess->focusRefineCurveFit->hide();
6761 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6763 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6764 m_OpsFocusProcess->focusDenoise->hide();
6767 m_OpsFocusProcess->focusDonut->hide();
6768 m_OpsFocusProcess->focusDonut->setChecked(
false);
6771 m_OpsFocusProcess->focusScanStartPos->hide();
6772 m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
6775 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6777 m_OpsFocusProcess->focusStarMeasure->clear();
6778 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6779 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6784 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
6785 m_OpsFocusProcess->focusCurveFitLabel->show();
6786 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
6787 m_OpsFocusProcess->focusCurveFit->show();
6788 if (m_OpsFocusProcess->focusCurveFit->count() != 1)
6790 m_OpsFocusProcess->focusCurveFit->clear();
6791 m_OpsFocusProcess->focusCurveFit->addItem(m_CurveFitText.at(CurveFitting::FOCUS_QUADRATIC));
6792 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
6795 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
6796 m_OpsFocusProcess->focusToleranceLabel->show();
6797 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
6798 m_OpsFocusProcess->focusTolerance->show();
6800 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
6801 m_OpsFocusProcess->focusFramesCountLabel->show();
6802 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
6803 m_OpsFocusProcess->focusFramesCount->show();
6805 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
6806 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6807 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
6808 m_OpsFocusProcess->focusHFRFramesCount->show();
6810 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6812 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
6813 m_OpsFocusProcess->focusThresholdLabel->show();
6814 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
6815 m_OpsFocusProcess->focusThreshold->show();
6817 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6819 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
6820 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6821 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
6822 m_OpsFocusProcess->focusMultiRowAverage->show();
6824 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
6825 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6826 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
6827 m_OpsFocusProcess->focusGaussianSigma->show();
6829 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
6830 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6831 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
6832 m_OpsFocusProcess->focusGaussianKernelSize->show();
6836 startAbInsB->setEnabled(canAbInsStart());
6840 m_OpsFocusSettings->focusAdaptive->setChecked(
false);
6841 m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
6842 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
6844 if (m_FilterManager)
6845 m_OpsFocusSettings->focusAFOptimize->setEnabled(
true);
6848 m_OpsFocusSettings->focusAFOptimize->setValue(0);
6849 m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
6853 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
false);
6854 m_OpsFocusMechanics->focusOutSteps->setEnabled(
true);
6857 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6859 m_OpsFocusMechanics->focusWalk->clear();
6860 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6861 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6865 case FOCUS_LINEAR1PASS:
6867 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6868 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6869 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6870 m_OpsFocusProcess->focusMultiRowAverage->hide();
6872 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6873 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6874 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6875 m_OpsFocusProcess->focusGaussianSigma->hide();
6877 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6878 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6879 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6880 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6882 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6883 m_OpsFocusProcess->focusThresholdLabel->hide();
6884 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6885 m_OpsFocusProcess->focusThreshold->hide();
6887 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
6888 m_OpsFocusProcess->focusToleranceLabel->hide();
6889 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
6890 m_OpsFocusProcess->focusTolerance->hide();
6894 if (m_FocusDetection == ALGORITHM_SEP && m_CurveFit != CurveFitting::FOCUS_QUADRATIC)
6896 if (m_OpsFocusProcess->focusStarMeasure->count() != m_StarMeasureText.count())
6898 m_OpsFocusProcess->focusStarMeasure->clear();
6899 m_OpsFocusProcess->focusStarMeasure->addItems(m_StarMeasureText);
6900 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6904#if !defined(HAVE_OPENCV)
6912 else if (m_FocusDetection != ALGORITHM_SEP || m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
6914 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6916 m_OpsFocusProcess->focusStarMeasure->clear();
6917 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6918 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6924 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
6925 m_OpsFocusProcess->focusCurveFitLabel->show();
6926 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
6927 m_OpsFocusProcess->focusCurveFit->show();
6928 if (m_OpsFocusProcess->focusCurveFit->count() != m_CurveFitText.count())
6930 m_OpsFocusProcess->focusCurveFit->clear();
6931 m_OpsFocusProcess->focusCurveFit->addItems(m_CurveFitText);
6932 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_HYPERBOLA);
6935 if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
6936 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
6938 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6939 m_OpsFocusProcess->focusUseWeights->hide();
6940 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusDenoise, 3, 0, 1, 2);
6941 m_OpsFocusProcess->focusDenoise->show();
6945 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6946 m_OpsFocusProcess->focusDenoise->hide();
6947 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusUseWeights, 3, 0, 1, 2);
6948 m_OpsFocusProcess->focusUseWeights->show();
6951 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusR2LimitLabel, 3, 2);
6952 m_OpsFocusProcess->focusR2LimitLabel->show();
6953 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusR2Limit, 3, 3);
6954 m_OpsFocusProcess->focusR2Limit->show();
6956 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusRefineCurveFit, 4, 0, 1, 2);
6957 m_OpsFocusProcess->focusRefineCurveFit->show();
6959 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 4, 2);
6960 m_OpsFocusProcess->focusFramesCountLabel->show();
6961 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 4, 3);
6962 m_OpsFocusProcess->focusFramesCount->show();
6964 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 5, 2);
6965 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6966 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 5, 3);
6967 m_OpsFocusProcess->focusHFRFramesCount->show();
6969 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6971 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 6, 0);
6972 m_OpsFocusProcess->focusThresholdLabel->show();
6973 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 6, 1);
6974 m_OpsFocusProcess->focusThreshold->show();
6976 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6978 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 6, 0);
6979 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6980 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 6, 1);
6981 m_OpsFocusProcess->focusMultiRowAverage->show();
6983 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 6, 2);
6984 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6985 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 6, 3);
6986 m_OpsFocusProcess->focusGaussianSigma->show();
6988 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 7, 0);
6989 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6990 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 7, 1);
6991 m_OpsFocusProcess->focusGaussianKernelSize->show();
6995 m_OpsFocusProcess->focusDonut->show();
6996 m_OpsFocusProcess->focusDonut->setEnabled(
true);
6999 m_OpsFocusProcess->focusScanStartPos->show();
7000 m_OpsFocusProcess->focusScanStartPos->setEnabled(
true);
7003 startAbInsB->setEnabled(canAbInsStart());
7007 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(canAbsMove);
7009 if (m_FilterManager)
7010 m_OpsFocusSettings->focusAFOptimize->setEnabled(
true);
7013 m_OpsFocusSettings->focusAFOptimize->setValue(0);
7014 m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
7019 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
false);
7020 m_OpsFocusMechanics->focusOutSteps->setEnabled(
true);
7023 if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
7025 if (m_OpsFocusMechanics->focusWalk->count() != 1)
7027 m_OpsFocusMechanics->focusWalk->clear();
7028 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
7029 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
7034 if (m_OpsFocusMechanics->focusWalk->count() != m_FocusWalkText.count())
7036 m_OpsFocusMechanics->focusWalk->clear();
7037 m_OpsFocusMechanics->focusWalk->addItems(m_FocusWalkText);
7038 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
7045void Focus::setCurveFit(CurveFitting::CurveFit curve)
7047 if (m_OpsFocusProcess->focusCurveFit->currentIndex() == -1)
7050 static bool first =
true;
7051 if (!first && m_CurveFit == curve)
7057 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
7064 case CurveFitting::FOCUS_QUADRATIC:
7065 m_OpsFocusProcess->focusR2Limit->setEnabled(
false);
7066 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
7067 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
false);
7070 case CurveFitting::FOCUS_HYPERBOLA:
7071 m_OpsFocusProcess->focusR2Limit->setEnabled(
true);
7072 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
7075 case CurveFitting::FOCUS_PARABOLA:
7076 m_OpsFocusProcess->focusR2Limit->setEnabled(
true);
7077 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
7080 case CurveFitting::FOCUS_2DGAUSSIAN:
7081 m_OpsFocusProcess->focusR2Limit->setEnabled(
true);
7082 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
7090void Focus::setStarMeasure(StarMeasure starMeasure)
7092 if (m_OpsFocusProcess->focusStarMeasure->currentIndex() == -1)
7095 static bool first =
true;
7096 if (!first && m_StarMeasure == starMeasure)
7101 m_StarMeasure = starMeasure;
7102 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
7106 setAutoStarAndBox();
7112 switch(m_StarMeasure)
7114 case FOCUS_STAR_HFR:
7115 m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
7116 m_FocusView->setStarsHFREnabled(
true);
7119 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
7120 m_OpsFocusProcess->focusStarPSFLabel->hide();
7121 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
7122 m_OpsFocusProcess->focusStarPSF->hide();
7125 case FOCUS_STAR_HFR_ADJ:
7126 m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
7127 m_FocusView->setStarsHFREnabled(
false);
7130 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
7131 m_OpsFocusProcess->focusStarPSFLabel->hide();
7132 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
7133 m_OpsFocusProcess->focusStarPSF->hide();
7136 case FOCUS_STAR_FWHM:
7137 m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
7139 m_FocusView->setStarsHFREnabled(
false);
7142 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusStarPSFLabel, 2, 2);
7143 m_OpsFocusProcess->focusStarPSFLabel->show();
7144 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusStarPSF, 2, 3);
7145 m_OpsFocusProcess->focusStarPSF->show();
7148 case FOCUS_STAR_NUM_STARS:
7149 m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
7150 m_FocusView->setStarsHFREnabled(
true);
7153 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
7154 m_OpsFocusProcess->focusStarPSFLabel->hide();
7155 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
7156 m_OpsFocusProcess->focusStarPSF->hide();
7159 case FOCUS_STAR_FOURIER_POWER:
7160 m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
7161 m_FocusView->setStarsHFREnabled(
true);
7164 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
7165 m_OpsFocusProcess->focusStarPSFLabel->hide();
7166 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
7167 m_OpsFocusProcess->focusStarPSF->hide();
7170 case FOCUS_STAR_STDDEV:
7171 case FOCUS_STAR_SOBEL:
7172 case FOCUS_STAR_LAPLASSIAN:
7173 case FOCUS_STAR_CANNY:
7174 m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
7175 m_FocusView->setStarsHFREnabled(
true);
7178 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
7179 m_OpsFocusProcess->focusStarPSFLabel->hide();
7180 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
7181 m_OpsFocusProcess->focusStarPSF->hide();
7189void Focus::setStarPSF(StarPSF starPSF)
7191 m_StarPSF = starPSF;
7194void Focus::setStarUnits(StarUnits starUnits)
7196 m_StarUnits = starUnits;
7199void Focus::setWalk(FocusWalk walk)
7201 if (m_OpsFocusMechanics->focusWalk->currentIndex() == -1)
7204 static bool first =
true;
7205 if (!first && m_FocusWalk == walk)
7214 case FOCUS_WALK_CLASSIC:
7215 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusNumStepsLabel,
7216 m_OpsFocusMechanics->focusOutStepsLabel);
7217 m_OpsFocusMechanics->focusNumStepsLabel->hide();
7218 m_OpsFocusMechanics->focusOutStepsLabel->show();
7219 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusNumSteps,
7220 m_OpsFocusMechanics->focusOutSteps);
7221 m_OpsFocusMechanics->focusNumSteps->hide();
7222 m_OpsFocusMechanics->focusOutSteps->show();
7225 case FOCUS_WALK_FIXED_STEPS:
7226 case FOCUS_WALK_CFZ_SHUFFLE:
7227 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutStepsLabel,
7228 m_OpsFocusMechanics->focusNumStepsLabel);
7229 m_OpsFocusMechanics->focusOutStepsLabel->hide();
7230 m_OpsFocusMechanics->focusNumStepsLabel->show();
7231 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutSteps,
7232 m_OpsFocusMechanics->focusNumSteps);
7233 m_OpsFocusMechanics->focusOutSteps->hide();
7234 m_OpsFocusMechanics->focusNumSteps->show();
7243double Focus::getStarUnits(
const StarMeasure starMeasure,
const StarUnits starUnits)
7245 if (starUnits == FOCUS_UNITS_PIXEL || starMeasure == FOCUS_STAR_NUM_STARS || starMeasure == FOCUS_STAR_FOURIER_POWER
7246 || starMeasure == FOCUS_STAR_STDDEV || starMeasure == FOCUS_STAR_SOBEL || starMeasure == FOCUS_STAR_LAPLASSIAN
7247 || starMeasure == FOCUS_STAR_CANNY)
7249 if (m_CcdPixelSizeX <= 0.0 || m_FocalLength <= 0.0)
7253 return m_CcdPixelSizeX / m_FocalLength * 206.265;
7256void Focus::calcCFZ()
7258 double cfzMicrons, cfzSteps;
7259 double cfzCameraSteps = calcCameraCFZ() / m_CFZUI->focusCFZStepSize->value();
7261 switch(
static_cast<Focus::CFZAlgorithm
> (m_CFZUI->focusCFZAlgorithm->currentIndex()))
7263 case Focus::FOCUS_CFZ_CLASSIC:
7265 cfzMicrons = 4.88f * m_CFZUI->focusCFZTolerance->value() * m_CFZUI->focusCFZWavelength->value() / 1000.0f *
7266 pow(m_CFZUI->focusCFZFNumber->value(), 2.0f);
7267 cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
7268 m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
7269 m_CFZUI->focusCFZFormula->setText(
"CFZ = 4.88 t λ f²");
7270 m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0,
'f', 0));
7271 m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0,
'f', 0));
7272 m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0,
'f', 0));
7273 m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0,
'f', 0));
7276 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTauLabel);
7277 m_CFZUI->focusCFZTauLabel->hide();
7278 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTau);
7279 m_CFZUI->focusCFZTau->hide();
7280 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeingLabel);
7281 m_CFZUI->focusCFZSeeingLabel->hide();
7282 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeing);
7283 m_CFZUI->focusCFZSeeing->hide();
7286 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZToleranceLabel, 1, 0);
7287 m_CFZUI->focusCFZToleranceLabel->show();
7288 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTolerance, 1, 1);
7289 m_CFZUI->focusCFZTolerance->show();
7290 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelengthLabel, 2, 0);
7291 m_CFZUI->focusCFZWavelengthLabel->show();
7292 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelength, 2, 1);
7293 m_CFZUI->focusCFZWavelength->show();
7296 case Focus::FOCUS_CFZ_WAVEFRONT:
7298 cfzMicrons = 4.0f * m_CFZUI->focusCFZTolerance->value() * m_CFZUI->focusCFZWavelength->value() / 1000.0f * pow(
7299 m_CFZUI->focusCFZFNumber->value(),
7301 cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
7302 m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
7303 m_CFZUI->focusCFZFormula->setText(
"CFZ = 4 t λ f²");
7304 m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0,
'f', 0));
7305 m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0,
'f', 0));
7306 m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0,
'f', 0));
7307 m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0,
'f', 0));
7310 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTauLabel);
7311 m_CFZUI->focusCFZTauLabel->hide();
7312 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTau);
7313 m_CFZUI->focusCFZTau->hide();
7314 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeingLabel);
7315 m_CFZUI->focusCFZSeeingLabel->hide();
7316 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeing);
7317 m_CFZUI->focusCFZSeeing->hide();
7320 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZToleranceLabel, 1, 0);
7321 m_CFZUI->focusCFZToleranceLabel->show();
7322 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTolerance, 1, 1);
7323 m_CFZUI->focusCFZTolerance->show();
7324 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelengthLabel, 2, 0);
7325 m_CFZUI->focusCFZWavelengthLabel->show();
7326 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelength, 2, 1);
7327 m_CFZUI->focusCFZWavelength->show();
7330 case Focus::FOCUS_CFZ_GOLD:
7332 cfzMicrons = 0.00225f * pow(m_CFZUI->focusCFZTau->value(), 0.5f) * m_CFZUI->focusCFZSeeing->value()
7333 * pow(m_CFZUI->focusCFZFNumber->value(), 2.0f) * m_CFZUI->focusCFZAperture->value();
7334 cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
7335 m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
7336 m_CFZUI->focusCFZFormula->setText(
"CFZ = 0.00225 √τ θ f² A");
7337 m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0,
'f', 0));
7338 m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0,
'f', 0));
7339 m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0,
'f', 0));
7340 m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0,
'f', 0));
7343 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZToleranceLabel);
7344 m_CFZUI->focusCFZToleranceLabel->hide();
7345 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTolerance);
7346 m_CFZUI->focusCFZTolerance->hide();
7347 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZWavelengthLabel);
7348 m_CFZUI->focusCFZWavelengthLabel->hide();
7349 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZWavelength);
7350 m_CFZUI->focusCFZWavelength->hide();
7353 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTauLabel, 1, 0);
7354 m_CFZUI->focusCFZTauLabel->show();
7355 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTau, 1, 1);
7356 m_CFZUI->focusCFZTau->show();
7357 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZSeeingLabel, 2, 0);
7358 m_CFZUI->focusCFZSeeingLabel->show();
7359 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZSeeing, 2, 1);
7360 m_CFZUI->focusCFZSeeing->show();
7363 if (linearFocuser !=
nullptr && linearFocuser->isDone())
7364 emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
7365 m_CFZUI->focusCFZDisplayVCurve->isChecked());
7371double Focus::calcCameraCFZ()
7373 return m_CcdPixelSizeX * pow(m_CFZUI->focusCFZFNumber->value(), 2.0) * m_CFZUI->focusCFZAperture->value() / 1000.0;
7376void Focus::wavelengthChanged()
7379 if (m_FilterManager)
7381 m_CFZUI->focusCFZWavelength->setValue(m_FilterManager->getFilterWavelength(
filter()));
7386void Focus::resetCFZToOT()
7389 m_CFZUI->focusCFZFNumber->setValue(m_FocalRatio);
7390 m_CFZUI->focusCFZAperture->setValue(m_Aperture);
7393 if (m_FilterManager)
7395 if (m_CFZUI->focusCFZWavelength->value() != m_FilterManager->getFilterWavelength(
filter()))
7396 m_CFZUI->focusCFZWavelength->setValue(m_FilterManager->getFilterWavelength(
filter()));
7401void Focus::setState(FocusState newState,
const bool update)
7403 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focus State changes from" << getFocusStatusString(m_state) <<
"to" << getFocusStatusString(
7406 emit newStatus(m_state, opticalTrain(), update);
7409void Focus::initView()
7411 m_FocusView.reset(
new FITSView(focusingWidget, FITS_FOCUS));
7413 m_FocusView->setBaseSize(focusingWidget->size());
7414 m_FocusView->createFloatingToolBar();
7417 focusingWidget->setLayout(vlayout);
7419 m_FocusView->setStarsEnabled(
true);
7420 m_FocusView->setStarsHFREnabled(
true);
7423void Focus::initHelperObjects()
7426 starFitting.reset(
new CurveFitting());
7427 focusFWHM.reset(
new FocusFWHM(m_ScaleCalc));
7428 focusFourierPower.reset(
new FocusFourierPower(m_ScaleCalc));
7429#if defined(HAVE_OPENCV)
7430 focusBlurriness.reset(
new FocusBlurriness());
7434 adaptFocus.reset(
new AdaptiveFocus(
this));
7437 focusAdvisor.reset(
new FocusAdvisor(
this));
7440QVariantMap Focus::getAllSettings()
const
7442 QVariantMap settings;
7445 for (
auto &oneWidget : findChildren<QComboBox*>())
7446 settings.insert(oneWidget->objectName(), oneWidget->currentText());
7449 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
7450 settings.insert(oneWidget->objectName(), oneWidget->value());
7453 for (
auto &oneWidget : findChildren<QSpinBox*>())
7454 settings.insert(oneWidget->objectName(), oneWidget->value());
7457 for (
auto &oneWidget : findChildren<QCheckBox*>())
7458 settings.insert(oneWidget->objectName(), oneWidget->isChecked());
7461 for (
auto &oneWidget : findChildren<QGroupBox*>())
7462 if (oneWidget->isCheckable())
7463 settings.insert(oneWidget->objectName(), oneWidget->isChecked());
7466 for (
auto &oneWidget : findChildren<QSplitter*>())
7467 settings.insert(oneWidget->objectName(),
QString::fromUtf8(oneWidget->saveState().toBase64()));
7470 for (
auto &oneWidget : findChildren<QRadioButton*>())
7471 settings.insert(oneWidget->objectName(), oneWidget->isChecked());
7476void Focus::setAllSettings(
const QVariantMap &settings)
7480 disconnectSyncSettings();
7482 for (
auto &name : settings.keys())
7485 auto comboBox = findChild<QComboBox*>(name);
7488 syncControl(settings, name, comboBox);
7493 auto doubleSpinBox = findChild<QDoubleSpinBox*>(name);
7496 syncControl(settings, name, doubleSpinBox);
7501 auto spinBox = findChild<QSpinBox*>(name);
7504 syncControl(settings, name, spinBox);
7509 auto checkbox = findChild<QCheckBox*>(name);
7512 syncControl(settings, name, checkbox);
7517 auto groupbox = findChild<QGroupBox*>(name);
7518 if (groupbox && groupbox->isCheckable())
7520 syncControl(settings, name, groupbox);
7525 auto splitter = findChild<QSplitter*>(name);
7528 syncControl(settings, name, splitter);
7533 auto radioButton = findChild<QRadioButton*>(name);
7536 syncControl(settings, name, radioButton);
7542 for (
auto &key : settings.keys())
7544 auto value = settings[key];
7546 Options::self()->setProperty(key.
toLatin1(), value);
7548 m_Settings[key] = value;
7549 m_GlobalSettings[key] = value;
7552 emit settingsUpdated(getAllSettings());
7555 OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()));
7556 OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Focus, m_Settings);
7559 connectSyncSettings();
7562 m_CurveFit =
static_cast<CurveFitting::CurveFit
> (m_OpsFocusProcess->focusCurveFit->currentIndex());
7563 setFocusDetection(
static_cast<StarAlgorithm
> (m_OpsFocusProcess->focusDetection->currentIndex()));
7564 setCurveFit(
static_cast<CurveFitting::CurveFit
>(m_OpsFocusProcess->focusCurveFit->currentIndex()));
7565 setStarMeasure(
static_cast<StarMeasure
>(m_OpsFocusProcess->focusStarMeasure->currentIndex()));
7566 setWalk(
static_cast<FocusWalk
>(m_OpsFocusMechanics->focusWalk->currentIndex()));
7570bool Focus::syncControl(
const QVariantMap &settings,
const QString &key,
QWidget * widget)
7581 if ((pSB = qobject_cast<QSpinBox *>(widget)))
7583 const int value = settings[key].
toInt(&ok);
7590 else if ((pDSB = qobject_cast<QDoubleSpinBox *>(widget)))
7592 const double value = settings[key].toDouble(&ok);
7599 else if ((pCB = qobject_cast<QCheckBox *>(widget)))
7601 const bool value = settings[key].toBool();
7606 else if ((pGB = qobject_cast<QGroupBox *>(widget)))
7608 const bool value = settings[key].toBool();
7613 else if ((pRadioButton = qobject_cast<QRadioButton *>(widget)))
7615 const bool value = settings[key].toBool();
7621 else if ((pComboBox = qobject_cast<QComboBox *>(widget)))
7623 const QString value = settings[key].toString();
7627 else if ((pSplitter = qobject_cast<QSplitter *>(widget)))
7637void Focus::setupOpticalTrainManager()
7639 connect(OpticalTrainManager::Instance(), &OpticalTrainManager::updated,
this, &Focus::refreshOpticalTrain);
7642 OpticalTrainManager::Instance()->openEditor(opticalTrainCombo->currentText());
7646 ProfileSettings::Instance()->setOneSetting(ProfileSettings::FocusOpticalTrain,
7647 OpticalTrainManager::Instance()->
id(opticalTrainCombo->itemText(index)));
7648 refreshOpticalTrain();
7649 emit trainChanged();
7653void Focus::refreshOpticalTrain()
7655 bool validSettings =
false;
7656 opticalTrainCombo->blockSignals(
true);
7657 opticalTrainCombo->clear();
7658 opticalTrainCombo->addItems(OpticalTrainManager::Instance()->getTrainNames());
7659 trainB->setEnabled(
true);
7661 QVariant trainID = ProfileSettings::Instance()->getOneSetting(ProfileSettings::FocusOpticalTrain);
7665 auto id = trainID.
toUInt();
7668 if (OpticalTrainManager::Instance()->exists(
id) ==
false)
7670 qCWarning(KSTARS_EKOS_FOCUS) <<
"Optical train doesn't exist for id" << id;
7671 id = OpticalTrainManager::Instance()->id(opticalTrainCombo->itemText(0));
7674 auto name = OpticalTrainManager::Instance()->name(
id);
7676 opticalTrainCombo->setCurrentText(name);
7682 OpticalTrainSettings::Instance()->setOpticalTrainID(
id);
7684 auto focuser = OpticalTrainManager::Instance()->getFocuser(name);
7685 setFocuser(focuser);
7687 auto scope = OpticalTrainManager::Instance()->getScope(name);
7688 double reducer = OpticalTrainManager::Instance()->getReducer(name);
7689 setScopeDetails(scope, reducer);
7691 auto settings = OpticalTrainSettings::Instance()->getOneSetting(OpticalTrainSettings::Focus);
7692 if (settings.isValid())
7694 validSettings =
true;
7695 auto map = settings.toJsonObject().toVariantMap();
7696 if (map != m_Settings)
7699 setAllSettings(map);
7703 auto camera = OpticalTrainManager::Instance()->getCamera(name);
7706 opticalTrainCombo->setToolTip(
QString(
"%1 @ %2").arg(camera->getDeviceName(), scope[
"name"].toString()));
7709 auto nvp = camera->getNumber(
"CCD_INFO");
7712 m_CcdPixelSizeX = 0.0;
7713 m_CcdWidth = m_CcdHeight = 0;
7717 auto np = nvp->findWidgetByName(
"CCD_PIXEL_SIZE_X");
7719 m_CcdPixelSizeX = np->getValue();
7720 np = nvp->findWidgetByName(
"CCD_MAX_X");
7722 m_CcdWidth = np->getValue();
7723 np = nvp->findWidgetByName(
"CCD_MAX_Y");
7725 m_CcdHeight = np->getValue();
7730 auto filterWheel = OpticalTrainManager::Instance()->getFilterWheel(name);
7731 setFilterWheel(filterWheel);
7739 focusAdvisor->setupParams(name);
7740 focusAdvisor->updateParams();
7744 opticalTrainCombo->blockSignals(
false);
7749void Focus::setScopeDetails(
const QJsonObject &scope,
const double reducer)
7751 m_Aperture = scope[
"aperture"].toDouble(-1);
7752 m_FocalLength = scope[
"focal_length"].toDouble(-1);
7753 m_FocalRatio = scope[
"focal_ratio"].toDouble(-1);
7754 m_ScopeType = scope[
"type"].toString();
7755 m_Reducer = reducer;
7758 if (m_Reducer > 0.0)
7759 m_FocalLength *= m_Reducer;
7762 if (m_FocalRatio <= 0.0)
7764 m_FocalRatio = (m_Aperture > 0.001) ? m_FocalLength / m_Aperture : 0.0f;
7765 else if (m_Aperture < 0.0)
7767 m_Aperture = m_FocalLength / m_FocalRatio;
void drawPolynomial(PolynomialFit *poly, bool isVShape, bool activate, bool plot=true)
draw the approximating polynomial into the HFR V-graph
void toggleVideo(bool enabled)
toggleVideo Turn on and off video streaming if supported by the camera.
void checkTemperatureSource(const QString &name=QString())
Check temperature source and make sure information is updated accordingly.
Q_SCRIPTABLE bool setFilter(const QString &filter)
DBUS interface function.
void startFraming()
startFraming Begins continuous capture of the CCD and calculates HFR every frame.
void newHFRPlotPosition(double pos, double hfr, double sigma, bool outlier, int pulseDuration, bool plot=true)
new HFR plot position with sigma
void redrawHFRPlot(PolynomialFit *poly, double solutionPosition, double solutionValue)
redraw the entire HFR plot
void loadStellarSolverProfiles()
setWeatherData Updates weather data that could be used to extract focus temperature from observatory ...
Q_SCRIPTABLE Q_NOREPLY void setBinning(int binX, int binY)
DBUS interface function.
void clearDataPoints()
clearDataPoints Remove all data points from HFR plots
Q_SCRIPTABLE QString camera()
DBUS interface function.
Q_SCRIPTABLE QString focuser()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void setAutoStarEnabled(bool enable)
DBUS interface function.
void runAutoFocus(const AutofocusReason autofocusReason, const QString &reasonInfo)
Run the autofocus process for the currently selected filter.
Q_SCRIPTABLE QString filterWheel()
DBUS interface function.
void updateProperty(INDI::Property prop)
updateProperty Read focus number properties of interest as they arrive from the focuser driver and pr...
void focusStarSelected(int x, int y)
focusStarSelected The user selected a focus star, save its coordinates and subframe it if subframing ...
void reconnectFocuser(const QString &focuser)
reconnectFocuser Add focuser to the list of available focusers.
bool setFocuser(ISD::Focuser *device)
addFocuser Add focuser to the list of available focusers.
void resetFocuser()
Move the focuser to the initial focus position.
void processData(const QSharedPointer< FITSData > &data)
newFITS A new FITS blob is received by the CCD driver.
void initHFRPlot(QString str, double starUnits, bool minimum, bool useWeights, bool showPosition)
initialize the HFR V plot
void selectFocusStarFraction(double x, double y)
selectFocusStarFraction Select the focus star based by fraction of the overall size.
void appendLogText(const QString &logtext)
setFocusStatus Upon completion of the focusing process, set its status (fail or pass) and reset focus...
Q_SCRIPTABLE bool useFullField()
DBUS interface function.
void adaptiveFocus()
adaptiveFocus moves the focuser between subframes to stay at focus
Q_SCRIPTABLE Q_NOREPLY void resetFrame()
DBUS interface function.
void meridianFlipStarted()
React when a meridian flip has been started.
void processTemperatureSource(INDI::Property prop)
processTemperatureSource Updates focus temperature source.
void removeDevice(const QSharedPointer< ISD::GenericDevice > &deviceRemoved)
removeDevice Remove device from Focus module
void syncCameraInfo()
syncCameraInfo Read current CCD information and update settings accordingly.
void checkFilter()
Check Filter and make sure information is updated accordingly.
void drawCFZ(double minPosition, double minValue, int m_cfzSteps, bool plt)
Draw Critical Focus Zone on graph.
void finalUpdates(const QString &title, bool plot=true)
final updates after focus run comopletes on the focus plot
void minimumFound(double solutionPosition, double solutionValue, bool plot=true)
Focus solution with minimal HFR found.
void checkStopFocus(bool abort)
checkStopFocus Perform checks before stopping the autofocus operation.
void checkFocuser()
Check Focuser and make sure information is updated accordingly.
Q_SCRIPTABLE Q_NOREPLY void setExposure(double value)
DBUS interface function.
void setTitle(const QString &title, bool plot=true)
draw a title on the focus plot
void drawCurve(CurveFitting *curve, bool isVShape, bool activate, bool plot=true)
draw the curve into the HFR V-graph
QStringList getStellarSolverProfiles()
getStellarSolverProfiles
Q_SCRIPTABLE Q_NOREPLY void setAutoFocusParameters(int boxSize, int stepSize, int maxTravel, double tolerance)
DBUS interface function.
Q_SCRIPTABLE Ekos::FocusState status()
DBUS interface function.
bool setFilterWheel(ISD::FilterWheel *device)
addFilter Add filter to the list of available filters.
void updateTemperatureSources(const QList< QSharedPointer< ISD::GenericDevice > > &temperatureSources)
updateTemperatureSources Update list of available temperature sources.
Q_SCRIPTABLE Q_NOREPLY void setAutoSubFrameEnabled(bool enable)
DBUS interface function.
bool setCamera(ISD::Camera *device)
Add CCD to the list of available CCD.
void syncCCDControls()
Update camera controls like Gain, ISO, Offset...etc.
void checkCamera()
Check CCD and make sure information is updated accordingly.
void selectImageMask()
setImageMask Select the currently active image mask filtering the stars relevant for focusing
CameraChip class controls a particular chip in camera.
Camera class controls an INDI Camera device.
@ ERROR_SAVE
INDI Camera error.
Focuser class handles control of INDI focuser devices.
KPageWidgetItem * addPage(QWidget *page, const QString &itemName, const QString &pixmapName=QString(), const QString &header=QString(), bool manage=true)
void setIcon(const QIcon &icon)
static KStars * Instance()
The sky coordinates of a point in the sky.
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
Q_SCRIPTABLE Q_NOREPLY void checkFocus(double requiredHFR)
checkFocus Given the minimum required HFR, check focus and calculate HFR.
Q_SCRIPTABLE bool focusOut(int ms=-1, int speedFactor=1)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void capture(double settleTime=0.0)
DBUS interface function.
Q_SCRIPTABLE bool focusIn(int ms=-1, int speedFactor=1)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void abort()
DBUS interface function.
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
Ekos is an advanced Astrophotography tool for Linux.
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
QString name(const QVariant &location)
int distance(const GeoCoordinates &coord1, const GeoCoordinates &coord2)
QString path(const QString &relativePath)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
QByteArray toBase64(Base64Options options) const const
void stateChanged(int state)
void activated(int index)
void currentIndexChanged(int index)
void currentTextChanged(const QString &text)
qint64 secsTo(const QDateTime &other) const const
QString toString(QStringView format, QCalendar cal) const const
QString filePath(const QString &fileName) const const
void valueChanged(double d)
bool exists(const QString &path)
bool isChecked() const const
Qt::KeyboardModifiers keyboardModifiers()
QIcon fromTheme(const QString &name)
const_iterator constBegin() const const
const_iterator constEnd() const const
qsizetype count() const const
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QList< T > findChildren(Qt::FindChildOptions options) const const
bool contains(const QPoint &point, bool proper) const const
bool isNull() const const
bool restoreState(const QByteArray &state)
QByteArray saveState() const const
void splitterMoved(int pos, int index)
void setEnabled(bool enabled)
QStandardItem * item(int row, int column) const const
QString & append(QChar ch)
QString arg(Args &&... args) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
QString number(double n, char format, int precision)
QByteArray toLatin1() const const
QByteArray toUtf8() const const
QTextStream & center(QTextStream &stream)
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromLocalFile(const QString &localFile)
bool isValid() const const
bool toBool() const const
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
QString toString() const const
uint toUInt(bool *ok) const const