Warning, file /education/kstars/kstars/ekos/focus/focusalgorithms.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2019 Hy Murveit <hy-1@murveit.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QString>
0010 #include <QList>
0011 #include "focus.h"
0012 #include "curvefit.h"
0013 #include "../../auxiliary/robuststatistics.h"
0014 #include "../../auxiliary/gslhelpers.h"
0015 #include <gsl/gsl_sf_erf.h>
0016 
0017 class Edge;
0018 
0019 namespace Ekos
0020 {
0021 
0022 /**
0023  * @class FocusAlgorithmInterface
0024  * @short Interface intender for autofocus algorithms.
0025  *
0026  * @author Hy Murveit
0027  * @version 1.1
0028  */
0029 class FocusAlgorithmInterface
0030 {
0031     public:
0032         struct FocusParams
0033         {
0034             // Curve Fitting object ptr. Create object if nullptr passed in
0035             CurveFitting *curveFitting;
0036             // Maximum movement from current position allowed for the algorithm.
0037             int maxTravel;
0038             // Initial sampling interval for the algorithm.
0039             int initialStepSize;
0040             // Absolute position of the focuser when the algorithm starts.
0041             int startPosition;
0042             // Minimum position the focuser is allowed to reach.
0043             int minPositionAllowed;
0044             // Maximum position the focuser is allowed to reach.
0045             int maxPositionAllowed;
0046             // Maximum number of iterations (captures) the focuser may try.
0047             int maxIterations;
0048             // The focus algorithm may terminate if it gets within this fraction of the best focus, e.g. 0.10.
0049             double focusTolerance;
0050             // The name of the filter used, if any.
0051             QString filterName;
0052             // The temperature measured when starting the focus (from focuser or observatory).
0053             double temperature;
0054             // The number of outward steps taken at the start of the algorithm.
0055             double initialOutwardSteps;
0056             // The number of steps
0057             int numSteps;
0058             // The focus algo
0059             Focus::Algorithm focusAlgorithm;
0060             // The user defined focuser backlash value
0061             // The value does not need to be exact but needs to be >= focuser backlash
0062             int backlash;
0063             // Curve fit is the type of curve to fit to the data
0064             CurveFitting::CurveFit curveFit;
0065             // Whether we want to use weightings of datapoints in the curve fitting process
0066             bool useWeights;
0067             // Which star measure to use, e.g. HFR, FWHM, etc.
0068             Focus::StarMeasure starMeasure;
0069             // If using FWHM, which PSF to use.
0070             Focus::StarPSF starPSF;
0071             // After pass1 re-evaluate the curve fit to remove outliers
0072             bool refineCurveFit;
0073             // The type of focus walk
0074             Focus::FocusWalk focusWalk;
0075             // Whether to use donut busting functionality
0076             bool donutBuster;
0077             // Whether we want to minimise or maximise the focus measurement statistic
0078             CurveFitting::OptimisationDirection optimisationDirection;
0079             // How to assign weights to focus measurements
0080             Mathematics::RobustStatistics::ScaleCalculation scaleCalculation;
0081 
0082             FocusParams(CurveFitting *_curveFitting, int _maxTravel, int _initialStepSize, int _startPosition,
0083                         int _minPositionAllowed, int _maxPositionAllowed, int _maxIterations,
0084                         double _focusTolerance, const QString &filterName_, double _temperature,
0085                         double _initialOutwardSteps, int _numSteps, Focus::Algorithm _focusAlgorithm, int _backlash,
0086                         CurveFitting::CurveFit _curveFit, bool _useWeights, Focus::StarMeasure _starMeasure,
0087                         Focus::StarPSF _starPSF, bool _refineCurveFit, Focus::FocusWalk _focusWalk, bool _donutBuster,
0088                         CurveFitting::OptimisationDirection _optimisationDirection,
0089                         Mathematics::RobustStatistics::ScaleCalculation _scaleCalculation) :
0090                 curveFitting(_curveFitting), maxTravel(_maxTravel), initialStepSize(_initialStepSize),
0091                 startPosition(_startPosition), minPositionAllowed(_minPositionAllowed),
0092                 maxPositionAllowed(_maxPositionAllowed), maxIterations(_maxIterations),
0093                 focusTolerance(_focusTolerance), filterName(filterName_),
0094                 temperature(_temperature), initialOutwardSteps(_initialOutwardSteps), numSteps(_numSteps),
0095                 focusAlgorithm(_focusAlgorithm), backlash(_backlash), curveFit(_curveFit),
0096                 useWeights(_useWeights), starMeasure(_starMeasure), starPSF(_starPSF),
0097                 refineCurveFit(_refineCurveFit), focusWalk(_focusWalk), donutBuster(_donutBuster),
0098                 optimisationDirection(_optimisationDirection), scaleCalculation(_scaleCalculation) {}
0099         };
0100 
0101         // Constructor initializes an autofocus algorithm from the input params.
0102         FocusAlgorithmInterface(const FocusParams &_params) : params(_params)
0103         {
0104             // Either a curve fitting object ptr is passed in or the constructor will create its own
0105             if (params.curveFitting == nullptr)
0106                 params.curveFitting = new CurveFitting();
0107         }
0108         virtual ~FocusAlgorithmInterface() {}
0109 
0110         // After construction, this should be called to get the initial position desired by the
0111         // focus algorithm. It returns the start position passed to the constructor if
0112         // it has no movement request.
0113         virtual int initialPosition() = 0;
0114 
0115         // Pass in the recent measurement. Returns the position for the next measurement,
0116         // or -1 if the algorithms done or if there's an error.
0117         // If stars is not nullptr, then the they may be used to modify the HFR value.
0118         virtual int newMeasurement(int position, double value, const double starWeight, const QList<Edge*> *stars = nullptr) = 0;
0119 
0120         // Returns true if the algorithm has terminated either successfully or in error.
0121         bool isDone() const
0122         {
0123             return done;
0124         }
0125 
0126         // Returns the best position. Should be called after isDone() returns true.
0127         // Returns -1 if there's an error.
0128         int solution() const
0129         {
0130             return focusSolution;
0131         }
0132 
0133         // Returns the value for best solution. Should be called after isDone() returns true.
0134         // Returns -1 if there's an error.
0135         double solutionValue() const
0136         {
0137             return focusValue;
0138         }
0139 
0140         // Returns human-readable extra error information about why the algorithm is done.
0141         QString doneReason() const
0142         {
0143             return doneString;
0144         }
0145 
0146         // Returns the params used to construct this object.
0147         const FocusParams &getParams() const
0148         {
0149             return params;
0150         }
0151 
0152         virtual double latestValue() const = 0;
0153 
0154         virtual void getMeasurements(QVector<int> *positions, QVector<double> *values, QVector<double> *scale) const = 0;
0155         virtual void getPass1Measurements(QVector<int> *positions, QVector<double> *values, QVector<double> *scale,
0156                                           QVector<bool> *out) const = 0;
0157 
0158         virtual QString getTextStatus(double R2 = 0) const = 0;
0159 
0160         // For Linear and L1P returns whether focuser is inFirstPass, other algos return true
0161         virtual bool isInFirstPass() const = 0;
0162 
0163         // For Linear and L1P returns the focuser step
0164         virtual int currentStep() const = 0;
0165 
0166         // For testing.
0167         virtual FocusAlgorithmInterface *Copy() = 0;
0168 
0169     protected:
0170         FocusParams params;
0171         bool done = false;
0172         int focusSolution = -1;
0173         double focusValue = -1;
0174         QString doneString;
0175 };
0176 
0177 // Creates a LinearFocuser. Caller responsible for the memory.
0178 FocusAlgorithmInterface *MakeLinearFocuser(const FocusAlgorithmInterface::FocusParams &params);
0179 }
0180