Kstars

polaralign.h
1/*
2 SPDX-FileCopyrightText: 2021 Hy Murveit <hy@murveit.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#pragma once
8
9#include <dms.h>
10#include <skypoint.h>
11
12class FITSData;
13class TestPolarAlign;
14
15/*********************************************************************
16 Polar alignment support class. Note, the telescope can be pointing anywhere.
17 It doesn't need to point at the pole.
18
19 Use this class as follows:
20 1) Construct with the geo information.
21 PolarAlign polarAlign(geoLocation);
22 2) Start the polar align procedure. Capture, solve and add wcs from the
23 solve to the FITSData image. Then:
24 polarAlign.addPoint(image);
25 3) Rotate the mount in RA ~30 degrees (could be less or more) east (or west)
26 and capture, solve and add wcs from the solve to the new image. Then:
27 polarAlign.addPoint(image);
28 4) Rotate the mount in RA another ~30 degrees east (or west)
29 and capture, solve and add wcs from the solve to the new image. Then:
30 polarAlign.addPoint(image);
31 5) Find the mount's axis of rotation as follows:
32 if (!polarAlign.findAxis())
33 error();
34 6) Compute the azimuth and altitude offset for the mount.
35 double altitudeError = axisAlt - latitudeDegrees;
36 double azimuthError = axisAz - 0;
37 7) Compute the overall error
38 dms polarError(hypot(azimuthError, altitudeError));
39
40Using the "move star" correction scheme:
41
42 8a) Compute a target correction
43 int correctedX, correctedY;
44 if (!polarAlign.findCorrectedPixel(
45 imageData, x, y, altitudeError, azimuthError, &correctedX, &correctedY))
46 error();
47 9a) The user uses the GEM azimuth and altitude adjustments to move the
48 object at position x,y in the image to position correctedX, correctedY.
49
50Using the plate solve correction scheme:
51
52 8b) Compute the remaining axis error (after partial correction)
53 SkyPoint coords, solution;
54 coords = [coordinates from plate-solving a refresh image]
55 // The signs of the error indicate the correction direction
56 processRefreshCoords(coords, currentTime, &azError, &altError);
57 9b) The user uses the GEM azimuth and altitude adjustments to move the telescope.
58 positive altitude error: reduce altitide.
59 positive azimuth error: point telescope more to the left.
60 *********************************************************************/
61
62class PolarAlign
63{
64 public:
65
66 // The polealignment scheme requires the GeoLocation to operate properly.
67 // Certain aspects can be tested without it.
68 PolarAlign(const GeoLocation *geo = nullptr);
69
70 // Add a sample point.
71 bool addPoint(const QSharedPointer<FITSData> &image);
72
73 // Returns the i-th point (zero based).
74 const SkyPoint getPoint(int index)
75 {
76 if (index >= 0 && index < points.size())
77 return points[index];
78 return SkyPoint();
79 }
80
81 // Finds the mount's axis of rotation. Three points must have been added.
82 // Returns false if the axis can't be found.
83 bool findAxis();
84
85 // Returns the image coordinate that pixel x,y should be moved to to correct
86 // the mount's axis. Image is usually the 3rd PAA image. x,y are image coordinates.
87 // 3 Points must have been added and findAxis() must have been called.
88 // Uses the axis determined by findAxis(). Returns correctedX and correctedY,
89 // the target position that the x,y pixel should move to.
90 bool findCorrectedPixel(const QSharedPointer<FITSData> &image, const QPointF &pixel,
91 QPointF *corrected, bool altOnly = false);
92
93 // Returns the mount's azimuth and altitude error given the known geographic location
94 // and the azimuth center and altitude center computed in findAxis().
95 // The first version uses the internal variables azimuthCenter & altitudeCenter as the
96 // calculated axis, and the 2nd takes new values as inputs.
97 void calculateAzAltError(double *azError, double *altError) const;
98 void calculateAzAltErrorFromAzAlt(double *azError, double *altError, double az, double alt) const;
99
100 // Given the current axis, fill in azError and altError with the polar alignment
101 // error, if a star at location pixel were move in the camera view to pixel2.
102 // image would be the 3rd PAA image.
103 // Returns false if the paa error couldn't be computer.
104 bool pixelError(const QSharedPointer<FITSData> &image, const QPointF &pixel, const QPointF &pixel2,
105 double *azError, double *altError);
106
107 /// reset starts the process over, removing the points.
108 void reset();
109
110 // Returns the mount's axis--for debugging.
111 void getAxis(double *azAxis, double *altAxis) const;
112
113 // This is not required, and is a hint as to how far the pixelError method should search
114 // for a solution. The suggestion may be ignored if it is too large or small, but in
115 // general this should be a degree or so larger than the polar alignment error in degrees.
116 void setMaxPixelSearchRange(double degrees);
117
118 // Compute the remaining polar-alignment azimuth and altitude error from a new image's coordinates
119 // as compared with the coordinates from the last polar-align measurement image.
120 // The differences between the two coordinates is a measure of the rotation that has been
121 // applied during the polar-align correction phase.
122 bool processRefreshCoords(const SkyPoint &coords, const KStarsDateTime &time,
123 double *azError, double *altError,
124 double *azAdjustment = nullptr, double *altAdjustment = nullptr) const;
125
126 // Find the skypoints where the telescope needs to point (rotated there by adjusting az and alt)
127 // in order for the mount to be properly polar aligned.
128 bool refreshSolution(SkyPoint *solution, SkyPoint *altOnlySolution) const;
129
130 private:
131 // returns true in the northern hemisphere.
132 // if no geo location available, defaults to northern.
133 bool northernHemisphere() const;
134
135 // These internal methods find the pixel with the desired azimuth and altitude.
136 bool findAzAlt(const QSharedPointer<FITSData> &image, double azimuth, double altitude, QPointF *pixel) const;
137
138 // Does the necessary processing so that azimuth and altitude values
139 // can be retrieved for the x,y pixel in image.
140 bool prepareAzAlt(const QSharedPointer<FITSData> &image, const QPointF &pixel, SkyPoint *point) const;
141
142
143 // Internal utility used by the external findCorrectedPixel and by pixelError().
144 // Similar args as the public findCorrectedPixel().
145 bool findCorrectedPixel(const QSharedPointer<FITSData> &image, const QPointF &pixel,
146 QPointF *corrected, double azError, double altError);
147
148 // Internal utility used by the public pixelError, which iterates at different
149 // resolutions passed in to this method. As the resoltion can be coarse, actualPixel
150 // is the one used (as opposed to pixel2) for the error returned.
151 void pixelError(const QSharedPointer<FITSData> &image, const QPointF &pixel, const QPointF &pixel2,
152 double minAz, double maxAz, double azInc,
153 double minAlt, double maxAlt, double altInc,
154 double *azError, double *altError, QPointF *actualPixel);
155
156 // These three positions are used to estimate the polar alignment error.
157 QVector<SkyPoint> points;
158 QVector<KStarsDateTime> times;
159
160 // The geographic location used to compute azimuth and altitude.
161 const GeoLocation *geoLocation;
162
163 // Values set by the last call to findAxis() that correspond to the mount's axis.
164 double azimuthCenter { 0 };
165 double altitudeCenter { 0 };
166
167 // Constrains the search for the correction pixel. Units are degrees.
168 double maxPixelSearchRange { 2 };
169
170 friend TestPolarAlign;
171};
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 28 2025 11:55:58 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.