File indexing completed on 2024-05-12 15:23:41

0001 /*
0002     SPDX-FileCopyrightText: 2012 Andrew Stepanenko
0003 
0004     Modified by Jasem Mutlaq <mutlaqja@ikarustech.com> for KStars:
0005     SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "vect.h"
0013 #include "indi/indicommon.h"
0014 
0015 #include <QObject>
0016 #include <QPointer>
0017 #include <QTime>
0018 #include <QVector>
0019 #include <QFile>
0020 #include <QElapsedTimer>
0021 
0022 #include <cstdint>
0023 #include <sys/types.h>
0024 #include "guidestars.h"
0025 #include "calibration.h"
0026 
0027 #include "gpg.h"
0028 
0029 class FITSData;
0030 class Edge;
0031 class GuideLog;
0032 
0033 // For now also copied in guidealgorithms.cpp
0034 #define SMART_THRESHOLD    0
0035 #define SEP_THRESHOLD      1
0036 #define CENTROID_THRESHOLD 2
0037 #define AUTO_THRESHOLD     3
0038 #define NO_THRESHOLD       4
0039 #define SEP_MULTISTAR      5
0040 
0041 #define GUIDE_RA    0
0042 #define GUIDE_DEC   1
0043 #define CHANNEL_CNT 2
0044 
0045 // input params
0046 class cproc_in_params
0047 {
0048     public:
0049         cproc_in_params();
0050         void reset(void);
0051 
0052         bool enabled[CHANNEL_CNT];
0053         bool enabled_axis1[CHANNEL_CNT];
0054         bool enabled_axis2[CHANNEL_CNT];
0055         bool average;
0056         double proportional_gain[CHANNEL_CNT];
0057         double integral_gain[CHANNEL_CNT];
0058         int max_pulse_arcsec[CHANNEL_CNT];
0059         double min_pulse_arcsec[CHANNEL_CNT];
0060 };
0061 
0062 //output params
0063 class cproc_out_params
0064 {
0065     public:
0066         cproc_out_params();
0067         void reset(void);
0068 
0069         double delta[2];
0070         GuideDirection pulse_dir[2];
0071         int pulse_length[2];
0072         double sigma[2];
0073 };
0074 
0075 typedef struct
0076 {
0077     double focal_ratio;
0078     double fov_wd, fov_ht;
0079     double focal, aperture;
0080 } info_params_t;
0081 
0082 class cgmath : public QObject
0083 {
0084         Q_OBJECT
0085 
0086     public:
0087         cgmath();
0088         virtual ~cgmath();
0089 
0090         // functions
0091         bool setVideoParameters(int vid_wd, int vid_ht, int binX, int binY);
0092         bool setGuiderParameters(double ccd_pix_wd, double ccd_pix_ht, double guider_aperture, double guider_focal);
0093 
0094         bool setTargetPosition(double x, double y);
0095         bool getTargetPosition(double *x, double *y) const;
0096 
0097         int getAlgorithmIndex(void) const;
0098         void setAlgorithmIndex(int algorithmIndex);
0099         bool usingSEPMultiStar() const;
0100 
0101         GPG &getGPG()
0102         {
0103             return *gpg;
0104         }
0105         const cproc_out_params *getOutputParameters() const
0106         {
0107             return &out_params;
0108         }
0109 
0110         // Operations
0111         void start();
0112         bool reset();
0113         // Currently only relevant to SEP MultiStar.
0114         void abort();
0115         void suspend(bool mode);
0116         bool isSuspended() const;
0117 
0118         // Star tracking
0119         void getStarScreenPosition(double *dx, double *dy) const;
0120         GuiderUtils::Vector findLocalStarPosition(QSharedPointer<FITSData> &imageData,
0121                 QSharedPointer<GuideView> &guideView, bool firstFrame);
0122         bool isStarLost() const;
0123         void setLostStar(bool is_lost);
0124 
0125         // Main processing function
0126         void performProcessing(Ekos::GuideState state,
0127                                QSharedPointer<FITSData> &imageData,
0128                                QSharedPointer<GuideView> &guideView,
0129                                const std::pair<Seconds, Seconds> &timeStep,
0130                                GuideLog *logger = nullptr);
0131 
0132         void performDarkGuiding(Ekos::GuideState state, const std::pair<Seconds, Seconds> &timeStep);
0133 
0134         bool calibrate1D(double start_x, double start_y, double end_x, double end_y, int RATotalPulse);
0135         bool calibrate2D(double start_ra_x, double start_ra_y, double end_ra_x, double end_ra_y,
0136                          double start_dec_x, double start_dec_y, double end_dec_x, double end_dec_y,
0137                          bool *swap_dec, int RATotalPulse, int DETotalPulse);
0138 
0139         const Calibration &getCalibration()
0140         {
0141             return calibration;
0142         }
0143         Calibration *getMutableCalibration()
0144         {
0145             return &calibration;
0146         }
0147         QVector3D selectGuideStar(const QSharedPointer<FITSData> &imageData);
0148         double getGuideStarSNR();
0149 
0150         const GuideStars &getGuideStars()
0151         {
0152             return guideStars;
0153         }
0154 
0155     signals:
0156         void newAxisDelta(double delta_ra, double delta_dec);
0157         void newStarPosition(QVector3D, bool);
0158 
0159         // For Analyze.
0160         void guideStats(double raError, double decError, int raPulse, int decPulse,
0161                         double snr, double skyBg, int numStars);
0162 
0163     private:
0164         // Templated functions
0165         template <typename T>
0166         GuiderUtils::Vector findLocalStarPosition(void) const;
0167 
0168         void updateCircularBuffers(void);
0169         GuiderUtils::Vector point2arcsec(const GuiderUtils::Vector &p) const;
0170         void calculatePulses(Ekos::GuideState state, const std::pair<Seconds, Seconds> &timeStep);
0171         void calculateRmsError(void);
0172 
0173         // Old-stye Logging--deprecate.
0174         void createGuideLog();
0175 
0176         // For Analyze.
0177         void emitStats();
0178 
0179         uint32_t iterationCounter { 0 };
0180 
0181         /// Video frame width
0182         int video_width { -1 };
0183         /// Video frame height
0184         int video_height { -1 };
0185         double aperture { 0 };
0186         bool suspended { false };
0187         bool lost_star { false };
0188 
0189         /// Index of algorithm used
0190         int algorithm { SMART_THRESHOLD };
0191 
0192         // The latest guide star position (x,y on the image),
0193         // and target position we're trying to keep it aligned to.
0194         GuiderUtils::Vector starPosition;
0195         GuiderUtils::Vector targetPosition;
0196 
0197         // processing
0198         // Drift is a circular buffer of the arcsecond drift for the 2 channels.
0199         // It will be initialized with a double array of size 50.
0200         // driftUpto points to the index of the next value to be written.
0201         static constexpr int CIRCULAR_BUFFER_SIZE = 50;
0202         double *drift[2];
0203         uint32_t driftUpto[2];
0204 
0205         double drift_integral[2];
0206 
0207         // overlays...
0208         cproc_in_params in_params;
0209         cproc_out_params out_params;
0210 
0211         // stat math...
0212         bool do_statistics { true };
0213 
0214         QFile logFile;
0215         QElapsedTimer logTime;
0216 
0217         GuideStars guideStars;
0218 
0219         std::unique_ptr<GPG> gpg;
0220         Calibration calibration;
0221         bool configureInParams(Ekos::GuideState state);
0222         void updateOutParams(int k, const double arcsecDrift, int pulseLength, GuideDirection pulseDirection);
0223         void outputGuideLog();
0224         void processAxis(const int k, const bool dithering, const bool darkGuiding, const Seconds &timeStep, const QString &label);
0225 };