# Kstars

polaralign.h
1/*
2 SPDX-FileCopyrightText: 2021 Hy Murveit <hy@murveit.com>
3
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:
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:
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:
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.
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 void calculateAzAltError(double *azError, double *altError) const;
96
97 // Given the current axis, fill in azError and altError with the polar alignment
98 // error, if a star at location pixel were move in the camera view to pixel2.
99 // image would be the 3rd PAA image.
100 // Returns false if the paa error couldn't be computer.
101 bool pixelError(const QSharedPointer<FITSData> &image, const QPointF &pixel, const QPointF &pixel2,
102 double *azError, double *altError);
103
104 /// reset starts the process over, removing the points.
105 void reset();
106
107 // Returns the mount's axis--for debugging.
108 void getAxis(double *azAxis, double *altAxis) const;
109
110 // This is not required, and is a hint as to how far the pixelError method should search
111 // for a solution. The suggestion may be ignored if it is too large or small, but in
112 // general this should be a degree or so larger than the polar alignment error in degrees.
113 void setMaxPixelSearchRange(double degrees);
114
115 // Compute the remaining polar-alignment azimuth and altitude error from a new image's coordinates
116 // as compared with the coordinates from the last polar-align measurement image.
117 // The differences between the two coordinates is a measure of the rotation that has been
118 // applied during the polar-align correction phase.
119 bool processRefreshCoords(const SkyPoint &coords, const KStarsDateTime &time,
120 double *azError, double *altError,
122
123 // Find the skypoints where the telescope needs to point (rotated there by adjusting az and alt)
124 // in order for the mount to be properly polar aligned.
125 bool refreshSolution(SkyPoint *solution, SkyPoint *altOnlySolution) const;
126
127 private:
128 // returns true in the northern hemisphere.
129 // if no geo location available, defaults to northern.
130 bool northernHemisphere() const;
131
132 // These internal methods find the pixel with the desired azimuth and altitude.
133 bool findAzAlt(const QSharedPointer<FITSData> &image, double azimuth, double altitude, QPointF *pixel) const;
134
135 // Does the necessary processing so that azimuth and altitude values
136 // can be retrieved for the x,y pixel in image.
137 bool prepareAzAlt(const QSharedPointer<FITSData> &image, const QPointF &pixel, SkyPoint *point) const;
138
139
140 // Internal utility used by the external findCorrectedPixel and by pixelError().
141 // Similar args as the public findCorrectedPixel().
142 bool findCorrectedPixel(const QSharedPointer<FITSData> &image, const QPointF &pixel,
143 QPointF *corrected, double azError, double altError);
144
145 // Internal utility used by the public pixelError, which iterates at different
146 // resolutions passed in to this method. As the resoltion can be coarse, actualPixel
147 // is the one used (as opposed to pixel2) for the error returned.
148 void pixelError(const QSharedPointer<FITSData> &image, const QPointF &pixel, const QPointF &pixel2,
149 double minAz, double maxAz, double azInc,
150 double minAlt, double maxAlt, double altInc,
151 double *azError, double *altError, QPointF *actualPixel);
152
153 // These three positions are used to estimate the polar alignment error.
154 QVector<SkyPoint> points;
156
157 // The geographic location used to compute azimuth and altitude.
158 const GeoLocation *geoLocation;
159
160 // Values set by the last call to findAxis() that correspond to the mount's axis.
161 double azimuthCenter { 0 };
162 double altitudeCenter { 0 };
163
164 // Constrains the search for the correction pixel. Units are degrees.
165 double maxPixelSearchRange { 2 };
166
167 friend TestPolarAlign;
168};
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
The sky coordinates of a point in the sky.
Definition skypoint.h:45
This file is part of the KDE documentation.