Kstars

polaralignmentassistant.h
1 /* Ekos Polar Alignment Assistant Tool
2  SPDX-FileCopyrightText: 2018-2021 Jasem Mutlaq
3  SPDX-FileCopyrightText: 2020-2021 Hy Murveit
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6  */
7 
8 #pragma once
9 
10 #include "ui_polaralignmentassistant.h"
11 #include "ekos/ekos.h"
12 #include "ekos/guide/internalguide/starcorrespondence.h"
13 #include "polaralign.h"
14 #include "alignview.h"
15 #include "align.h"
16 #include "indi/indimount.h"
17 
18 class QProgressIndicator;
19 class SolverUtils;
20 
21 namespace Ekos
22 {
23 
24 class PolarAlignWidget;
25 
26 /**
27  * @brief The PolarAlignmentAssistant class
28  *
29  * Captures three images rotated by a set number of degrees decided by the user (default 30).
30  * Each image is plate solver to find the center RA,DE coordinates. The three points are then
31  * used to generate a unique circle with its center as the RA axis. As the mount rotated around
32  * these point, we can identify the RA rotational axis. From there, we compare the distance from RA axis
33  * to the celestial pole axis. For a perfectly aligned mount, the two points would overlap exactly.
34  * In reality, there is also some differences due to the mount mechanical limitations and measurements
35  * errors.
36  *
37  * The user is then presented with a triangle that couples the corrections required in Altitude and Azimuth
38  * knobs to move the RA axis to the celestial pole. An optional feature is available the calculates the error
39  * in real time as the user move the mount around during refresh, but this feature is computationally intensive
40  * as we need to extract stars from each frame.
41  *
42  * @author Jasem Mutlaq
43  * @author Hy Murveit
44  */
45 class PolarAlignmentAssistant : public QWidget, public Ui::PolarAlignmentAssistant
46 {
47  Q_OBJECT
48 
49  public:
52 
53  typedef enum
54  {
55  PAH_IDLE,
56  PAH_FIRST_CAPTURE,
57  PAH_FIRST_SOLVE,
58  PAH_FIND_CP,
59  PAH_FIRST_ROTATE,
60  PAH_FIRST_SETTLE,
61  PAH_SECOND_CAPTURE,
62  PAH_SECOND_SOLVE,
63  PAH_SECOND_ROTATE,
64  PAH_SECOND_SETTLE,
65  PAH_THIRD_CAPTURE,
66  PAH_THIRD_SOLVE,
67  PAH_STAR_SELECT,
68  PAH_REFRESH,
69  PAH_POST_REFRESH
70  } PAHStage;
71 
72  // Algorithm choice in UI
73  typedef enum
74  {
75  PLATE_SOLVE_ALGORITHM,
76  MOVE_STAR_ALGORITHM,
77  MOVE_STAR_UPDATE_ERR_ALGORITHM
78  } PAHRefreshAlgorithm;
79 
80  enum CircleSolution
81  {
82  NO_CIRCLE_SOLUTION,
83  ONE_CIRCLE_SOLUTION,
84  TWO_CIRCLE_SOLUTION,
85  INFINITE_CIRCLE_SOLUTION
86  };
87  typedef enum { NORTH_HEMISPHERE, SOUTH_HEMISPHERE } HemisphereType;
88 
89  // Set the mount used in Align class.
90  void setCurrentTelescope(ISD::Mount *scope)
91  {
92  m_CurrentTelescope = scope;
93  }
94  // Sync mount slew speed and available rates from the telescope object
95  void syncMountSpeed();
96  // Enable PAA if the FOV is sufficient
97  void setEnabled(bool enabled);
98  // Return the exposure used in the refresh phase.
99  double getPAHExposureDuration() const
100  {
101  return PAHExposure->value();
102  }
103  // Handle updates during the refresh phase such as error estimation.
104  void processPAHRefresh();
105  // Handle solver failure and retry to capture until a preset number of retries is met.
106  bool processSolverFailure();
107  // Handle both automated and manual mount rotations.
108  void processMountRotation(const dms &ra, double settleDuration);
109  // After solver is complete, handle PAH Stage processing
110  void processPAHStage(double orientation, double ra, double dec, double pixscale, bool eastToTheRight);
111  // Return current PAH stage
112  PAHStage getPAHStage() const
113  {
114  return m_PAHStage;
115  }
116  // Set active stage.
117  void setPAHStage(PAHStage stage);
118  // Start the polar alignment process.
119  void startPAHProcess();
120  // Stops the polar alignment process.
121  void stopPAHProcess();
122  // Process the results of WCS from the solving process. If the results are good, we continue to the next phase.
123  // Otherwise, we abort the operation.
124  void setWCSToggled(bool result);
125  // Update GUI to reflect mount status.
126  void setMountStatus(ISD::Mount::Status newState);
127  // Update the correction offset by this percentage in order to move the triangle around when clicking on
128  // for example.
129  void setPAHCorrectionOffsetPercentage(double dx, double dy);
130  // Update the PAH refresh duration
131  void setPAHRefreshDuration(double value)
132  {
133  PAHExposure->setValue(value);
134  }
135  // Start the refresh process.
136  void startPAHRefreshProcess();
137  // This should be called when manual slewing is complete.
138  void setPAHSlewDone();
139  // PAH Settings. PAH should be in separate class
140  QJsonObject getPAHSettings() const;
141  // Update the setting
142  void setPAHSettings(const QJsonObject &settings);
143  // Return current active stage label
144  QString getPAHStageString(bool translated = true) const
145  {
146  return translated ? i18n(PAHStages[m_PAHStage]) : PAHStages[m_PAHStage];
147  }
148  // Return last message
149  QString getPAHMessage() const;
150  // Set image data from align class
151  void setImageData(const QSharedPointer<FITSData> &image);
152 
153  void setPAHRefreshAlgorithm(PAHRefreshAlgorithm value);
154 
155  protected:
156  // Polar Alignment Helper slots
157  void rotatePAH();
158  void setPAHCorrectionOffset(int x, int y);
159 
160  private:
161  /**
162  * @brief Warns the user if the polar alignment might cross the meridian.
163  */
164  bool checkPAHForMeridianCrossing();
165 
166  /**
167  * @brief calculatePAHError Calculate polar alignment error in the Polar Alignment Helper (PAH) method
168  * @return True if calculation is successsful, false otherwise.
169  */
170  bool calculatePAHError();
171 
172  /**
173  * @brief syncCorrectionVector Flip correction vector based on user settings.
174  */
175  void syncCorrectionVector();
176 
177  /**
178  * @brief setupCorrectionGraphics Update align view correction graphics.
179  * @param pixel
180  */
181  void setupCorrectionGraphics(const QPointF &pixel);
182 
183  /**
184  * @brief supdateRefreshDisplay Updates the UI's refresh error stats.
185  * @param azError the azimuth error in degrees
186  * @param altError the altitude error in degrees
187  */
188  void updateRefreshDisplay(double azError, double altError);
189 
190  signals:
191  // Report new log
192  void newLog(const QString &);
193  // Request new capture and solve
194  void captureAndSolve();
195  // Report correction vector and original errors
196  void polarResultUpdated(QLineF correctionVector, double polarError, double azError, double altError);
197  // Report updated errors
198  void updatedErrorsChanged(double total, double az, double alt);
199  // Report new correction vector
200  void newCorrectionVector(QLineF correctionVector);
201  // Report new PAH stage
202  void newPAHStage(PAHStage stage);
203  // Report new PAH message
204  void newPAHMessage(const QString &message);
205  // Report whether the tool is enabled or not
206  void PAHEnabled(bool);
207  // Request to set alignment table result
208  void newAlignTableResult(Align::AlignResult result);
209  // Report that the align view was updated.
210  void newFrame(const QSharedPointer<FITSView> &view);
211 
212  private:
213  void updateDisplay(PAHStage stage, const QString &message);
214  void drawArrows(double altError, double azError);
215  void showUpdatedError(bool show);
216  // These are only used in the plate-solve refresh scheme.
217  void solverDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds);
218  void startSolver();
219  void updatePlateSolveTriangle(const QSharedPointer<FITSData> &image);
220 
221  // Polar Alignment Helper
222  PAHStage m_PAHStage { PAH_IDLE };
223 
224  SkyPoint targetPAH;
225 
226  // Which hemisphere are we located on?
227  HemisphereType hemisphere;
228 
229  // Polar alignment will retry capture & solve a few times if solve fails.
230  int m_PAHRetrySolveCounter { 0 };
231 
232  // Points on the image to correct mount's ra axis.
233  // correctionFrom is the star the user selected (or center of the image at start).
234  // correctionTo is where theuser should move that star.
235  // correctionAltTo is where the use should move that star to only fix altitude.
236  QPointF correctionFrom, correctionTo, correctionAltTo;
237 
238  // RA/DEC coordinates where the image center needs to be move to to correct the RA axis.
239  SkyPoint refreshSolution, altOnlyRefreshSolution;
240 
241 
242  bool detectStarsPAHRefresh(QList<Edge> *stars, int num, int x, int y, int *xyIndex);
243 
244  // Incremented every time sufficient # of stars are detected (for move-star refresh) or
245  // when solver is successful (for plate-solve refresh).
246  int refreshIteration { 0 };
247  // Incremented on every image received.
248  int imageNumber { 0 };
249  StarCorrespondence starCorrespondencePAH;
250 
251  // Class used to estimate alignment error.
252  PolarAlign polarAlign;
253 
254  // Pointer to image data
255  QSharedPointer<FITSData> m_ImageData;
256 
257  // Reference to parent
258  Align *m_AlignInstance {nullptr};
259 
260  // Reference to current active telescope
261  ISD::Mount *m_CurrentTelescope { nullptr };
262 
263  // Reference to align view
264  QSharedPointer<AlignView> m_AlignView;
265 
266  // PAH Stage Map
267  static const QMap<PAHStage, const char *> PAHStages;
268 
269  // Threshold to stop PAH rotation in degrees
270  static constexpr uint8_t PAH_ROTATION_THRESHOLD { 5 };
271 
272  PolarAlignWidget *polarAlignWidget {nullptr};
273 
274  // Used in the refresh part of polar alignment.
276  double m_LastRa {0};
277  double m_LastDec {0};
278  double m_LastOrientation {0};
279  double m_LastPixscale {0};
280 
281  // Restricts (the internal solver) to using the index and healpix
282  // from the previous solve, if that solve was successful.
283  int m_IndexToUse { -1 };
284  int m_HealpixToUse { -1 };
285  int m_NumHealpixFailures { 0 };
286 };
287 }
Q_OBJECTQ_OBJECT
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:70
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
The QProgressIndicator class lets an application display a progress indicator to show that a long tas...
QString i18n(const char *text, const TYPE &arg...)
The PolarAlignmentAssistant class.
void show()
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
Align class handles plate-solving and polar alignment measurement and correction using astrometry....
Definition: align.h:73
QObject * parent() const const
QString message
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:56 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.