File indexing completed on 2024-05-12 15:23:40
0001 /* 0002 SPDX-FileCopyrightText: 2020 Hy Murveit <hy@murveit.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "matr.h" 0010 #include "vect.h" 0011 #include <QString> 0012 #include "ekos/ekos.h" 0013 #include "indi/indicommon.h" 0014 #include "indi/indimount.h" 0015 0016 class Calibration 0017 { 0018 public: 0019 Calibration(); 0020 ~Calibration() {} 0021 0022 // Initialize the parameters needed to convert from pixels to arc-seconds, 0023 // the current pier side, and the current pointing position. 0024 void setParameters(double ccd_pix_width, double ccd_pix_height, double focalLengthMm, 0025 int binX, int binY, ISD::Mount::PierSide pierSide, 0026 const dms &mountRA, const dms &mountDec); 0027 0028 // Set the current binning, which may be different from what was used during calibration. 0029 void setBinningUsed(int x, int y); 0030 0031 // Generate new calibrations according to the input parameters. 0032 bool calculate1D(double start_x, double start_y, 0033 double end_x, double end_y, int RATotalPulse); 0034 0035 bool calculate2D( 0036 double start_ra_x, double start_ra_y, double end_ra_x, double end_ra_y, 0037 double start_dec_x, double start_dec_y, double end_dec_x, double end_dec_y, 0038 bool *swap_dec, int RATotalPulse, int DETotalPulse); 0039 0040 // Computes the drift from the detection relative to the reference position. 0041 // If inputs are in pixels, then drift outputs are in pixels. 0042 // If inputs are in arcsecond coordinates then drifts are in arcseconds. 0043 void computeDrift(const GuiderUtils::Vector &detection, const GuiderUtils::Vector &reference, 0044 double *raDrift, double *decDrift) const; 0045 0046 double getFocalLength() const 0047 { 0048 return focalMm; 0049 } 0050 double getAngle() const 0051 { 0052 return angle; 0053 } 0054 double getRAAngle() const 0055 { 0056 return calibrationAngleRA; 0057 } 0058 double getDECAngle() const 0059 { 0060 return calibrationAngleDEC; 0061 } 0062 0063 // Converts the input x & y coordinates from pixels to arc-seconds. 0064 // Does not rotate the input into RA/DEC. 0065 GuiderUtils::Vector convertToArcseconds(const GuiderUtils::Vector &input) const; 0066 0067 // Converts the input x & y coordinates from arc-seconds to pixels. 0068 // Does not rotate the input into RA/DEC. 0069 GuiderUtils::Vector convertToPixels(const GuiderUtils::Vector &input) const; 0070 void convertToPixels(double xArcseconds, double yArcseconds, 0071 double *xPixel, double *yPixel) const; 0072 0073 // Given offsets, convert to RA and DEC coordinates 0074 // by rotating according to the calibration. 0075 // Also inverts the y-axis. Does not convert to arc-seconds. 0076 GuiderUtils::Vector rotateToRaDec(const GuiderUtils::Vector &input) const; 0077 void rotateToRaDec(double dx, double dy, double *ra, double *dec) const; 0078 0079 // Returns the number of milliseconds that should be pulsed to move 0080 // RA by one arcsecond. 0081 double raPulseMillisecondsPerArcsecond() const; 0082 0083 // Returns the number of milliseconds that should be pulsed to move 0084 // DEC by one arcsecond. 0085 double decPulseMillisecondsPerArcsecond() const; 0086 0087 // Returns the number of pixels per arc-second in X and Y and vica versa. 0088 double xPixelsPerArcsecond() const; 0089 double yPixelsPerArcsecond() const; 0090 double xArcsecondsPerPixel() const; 0091 double yArcsecondsPerPixel() const; 0092 0093 // Save the calibration to Options. 0094 void save() const; 0095 // Restore the saved calibration. If the pier side is different than 0096 // when was calibrated, adjust the angle accordingly. 0097 bool restore(ISD::Mount::PierSide currentPierSide, bool reverseDecOnPierChange, 0098 int currentBinX, int currentBinY, 0099 const dms *declination = nullptr); 0100 // As above, but for testing. 0101 bool restore(const QString &encoding, ISD::Mount::PierSide currentPierSide, 0102 bool reverseDecOnPierChange, int currentBinX, int currentBinY, 0103 const dms *declination = nullptr); 0104 0105 bool declinationSwapEnabled() const 0106 { 0107 return decSwap; 0108 } 0109 void setDeclinationSwapEnabled(bool value); 0110 0111 void reset() 0112 { 0113 initialized = false; 0114 } 0115 // Returns true if calculate1D, calculate2D or restore have been called. 0116 bool isInitialized() 0117 { 0118 return initialized; 0119 } 0120 // Prints the calibration parameters in the debug log. 0121 void logCalibration() const; 0122 0123 private: 0124 // Internal calibration methods. 0125 bool calculate1D(double dx, double dy, int RATotalPulse); 0126 bool calculate2D(double ra_dx, double ra_dy, double dec_dx, double dec_dy, 0127 bool *swap_dec, int RATotalPulse, int DETotalPulse); 0128 0129 // Serialize and restore the calibration state. 0130 QString serialize() const; 0131 bool restore(const QString &encoding); 0132 0133 // Adjusts the RA rate, according to the calibration and current declination values. 0134 double correctRA(double raMsPerPixel, const dms &calibrationDec, const dms ¤tDec); 0135 0136 // Compute a rotation angle given pixel change coordinates 0137 static double calculateRotation(double x, double y); 0138 0139 // Set the rotation angle and the rotation matrix. 0140 // The angles are in the arc-second coordinate system (not the pixels--though that would 0141 // be the same thing if the pixels were square). 0142 void setAngle(double rotationAngle); 0143 0144 // Set the calibrated ra and dec rates. 0145 void setRaPulseMsPerArcsecond(double rate); 0146 void setDecPulseMsPerArcsecond(double rate); 0147 0148 // computes the ratio of the binning currently used to the binning in use while calibrating. 0149 double binFactor() const; 0150 // Inverse of above. 0151 double inverseBinFactor() const; 0152 0153 // Sub-binning in X and Y. 0154 int subBinX { 1 }; 0155 int subBinY { 1 }; 0156 0157 // It is possible that this calibration was done with one binning, but is now 0158 // being used with another binning. This is the current binning (as opposed to the above 0159 // which is the binning that was in-place during calibration. 0160 int subBinXused { 1 }; 0161 int subBinYused { 1 }; 0162 0163 // Pixel width mm, for each pixel, 0164 // Binning does not affect this. 0165 double ccd_pixel_width { 0.003 }; 0166 double ccd_pixel_height { 0.003 }; 0167 0168 // Focal length in millimeters. 0169 double focalMm { 500 }; 0170 0171 // This angle is the one in use for calibrating. It may differ from the 0172 // calibrationAngle below if the pier side changes. 0173 double angle { 0 }; 0174 0175 // The rotation matrix that converts between pixel coordinates and RA/DEC. 0176 // This is derived from angle in setAngle(). 0177 GuiderUtils::Matrix ROT_Z; 0178 0179 // The angles associated with the calibration that was computed or 0180 // restored. They won't change as we change pier sides. 0181 double calibrationAngle { 0 }; 0182 double calibrationAngleRA = 0; 0183 double calibrationAngleDEC = 0; 0184 0185 // The calibrated values of how many pulse milliseconds are required to 0186 // move one arcsecond in RA and DEC. 0187 double raPulseMsPerArcsecond { 0 }; 0188 double decPulseMsPerArcsecond { 0 }; 0189 0190 // The decSwap that was computed in calibration. 0191 bool calibrationDecSwap { false }; 0192 0193 // The decSwap in use. May be the opposite of calibrationDecSwap if the calibration 0194 // is being used on the opposite pier side as the calibration pier side. 0195 bool decSwap { false }; 0196 0197 // The RA and DEC when calibration was performed. For reference. Not currently used. 0198 dms calibrationRA; 0199 dms calibrationDEC; 0200 0201 // The side of the pier where the current calibration was calculated. 0202 ISD::Mount::PierSide calibrationPierSide { ISD::Mount::PIER_UNKNOWN }; 0203 0204 bool initialized { false }; 0205 friend class TestGuideStars; 0206 }; 0207