1 /*
2 * mount.h
3 * PHD Guiding
4 *
5 * Created by Bret McKee
6 * Copyright (c) 2012 Bret McKee
7 * All rights reserved.
8 *
9 * This source code is distributed under the following "BSD" license
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * Neither the name of Bret McKee, Dad Dog Development,
18 * Craig Stark, Stark Labs nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
35
36 #ifndef MOUNT_H_INCLUDED
37 #define MOUNT_H_INCLUDED
38
39 #include "guide_algorithms.h"
40 #include "image_math.h"
41 #include "messagebox_proxy.h"
42
43 class BacklashComp;
44 struct GuiderOffset;
45
46 enum GUIDE_DIRECTION
47 {
48 NONE = -1,
49 UP = 0,
50 NORTH = UP, // Dec + for eq mounts
51 DOWN,
52 SOUTH = DOWN, // Dec-
53 RIGHT,
54 EAST = RIGHT, // RA-
55 LEFT,
56 WEST = LEFT // RA+
57 };
58
59 enum PierSide
60 {
61 PIER_SIDE_UNKNOWN = -1,
62 PIER_SIDE_EAST = 0,
63 PIER_SIDE_WEST = 1,
64 };
65
66 enum GuideParity
67 {
68 GUIDE_PARITY_EVEN = 1, // Guide(NORTH) moves scope north
69 GUIDE_PARITY_ODD = -1, // Guide(NORTH) moves scope south
70 GUIDE_PARITY_UNKNOWN = 0, // we don't know or care
71 GUIDE_PARITY_UNCHANGED = -5, // special case for SetCalibration, leave value unchanged
72 };
73
74 #define UNKNOWN_DECLINATION 997.0
75
76 struct Calibration
77 {
78 double xRate;
79 double yRate;
80 double xAngle;
81 double yAngle;
82 double declination; // radians, or UNKNOWN_DECLINATION
83 double rotatorAngle;
84 unsigned short binning;
85 PierSide pierSide;
86 GuideParity raGuideParity;
87 GuideParity decGuideParity;
88 bool isValid;
89 wxString timestamp;
90
CalibrationCalibration91 Calibration() : isValid(false) { }
92 };
93
94 enum CalibrationIssueType
95 {
96 CI_None,
97 CI_Steps,
98 CI_Angle,
99 CI_Rates,
100 CI_Different
101 };
102
103 static const wxString CalibrationIssueString[] = { "None", "Steps", "Orthogonality", "Rates", "Difference" };
104
105 struct CalibrationDetails
106 {
107 int focalLength;
108 double imageScale;
109 double raGuideSpeed;
110 double decGuideSpeed;
111 double orthoError;
112 double origBinning;
113 std::vector<wxRealPoint> raSteps;
114 std::vector<wxRealPoint> decSteps;
115 int raStepCount;
116 int decStepCount;
117 CalibrationIssueType lastIssue;
118 wxString origTimestamp;
119 PierSide origPierSide;
120
CalibrationDetailsCalibrationDetails121 CalibrationDetails() : raStepCount(0) { }
IsValidCalibrationDetails122 bool IsValid() const { return raStepCount > 0; }
123 };
124
125 enum MountMoveOptionBits
126 {
127 MOVEOPT_ALGO_RESULT = (1<<0), // filter move through guide algorithm
128 MOVEOPT_ALGO_DEDUCE = (1<<1), // use guide algorithm to deduce the move amount (when paused or star lost)
129 MOVEOPT_USE_BLC = (1<<2), // use backlash comp for this move
130 MOVEOPT_GRAPH = (1<<3), // display the move on the graphs
131 MOVEOPT_MANUAL = (1<<4), // manual move - allow even when guiding disabled
132 };
133
134 enum
135 {
136 MOVEOPTS_CALIBRATION_MOVE = 0,
137 MOVEOPTS_GUIDE_STEP = MOVEOPT_ALGO_RESULT | MOVEOPT_USE_BLC | MOVEOPT_GRAPH,
138 MOVEOPTS_DEDUCED_MOVE = MOVEOPT_ALGO_DEDUCE | MOVEOPT_USE_BLC | MOVEOPT_GRAPH,
139 MOVEOPTS_RECOVERY_MOVE = MOVEOPT_USE_BLC,
140 MOVEOPTS_AO_BUMP = MOVEOPT_USE_BLC,
141 };
142
143 extern wxString DumpMoveOptionBits(unsigned int moveOptions);
144
145 struct MoveResultInfo
146 {
147 int amountMoved;
148 bool limited;
149
MoveResultInfoMoveResultInfo150 MoveResultInfo() : amountMoved(0), limited(false) { }
151 };
152
153 class MountConfigDialogCtrlSet : public ConfigDialogCtrlSet
154 {
155 Mount* m_pMount;
156 wxCheckBox *m_pClearCalibration;
157 wxCheckBox *m_pEnableGuide;
158
159 public:
160 MountConfigDialogCtrlSet(wxWindow *pParent, Mount *pMount, AdvancedDialog* pAdvancedDialog, BrainCtrlIdMap& CtrlMap);
~MountConfigDialogCtrlSet()161 virtual ~MountConfigDialogCtrlSet() {};
162 virtual void LoadValues();
163 virtual void UnloadValues();
164 };
165
166 class Mount : public wxMessageBoxProxy
167 {
168 bool m_connected;
169 int m_requestCount;
170 int m_errorCount;
171
172 bool m_calibrated;
173 Calibration m_cal;
174 double m_xRate; // rate adjusted for declination
175 double m_yAngleError;
176
177 protected:
178 bool m_guidingEnabled;
179
180 GuideAlgorithm *m_pXGuideAlgorithm;
181 GuideAlgorithm *m_pYGuideAlgorithm;
182
183 wxString m_Name;
184 BacklashComp *m_backlashComp;
185 GuideStepInfo m_lastStep;
186
187 // Things related to the Advanced Config Dialog
188 public:
189 class MountConfigDialogPane : public wxEvtHandler, public ConfigDialogPane
190 {
191 protected:
192 Mount *m_pMount;
193 wxWindow* m_pParent;
194 wxChoice *m_pXGuideAlgorithmChoice;
195 wxChoice *m_pYGuideAlgorithmChoice;
196 int m_initXGuideAlgorithmSelection;
197 int m_initYGuideAlgorithmSelection;
198 ConfigDialogPane *m_pXGuideAlgorithmConfigDialogPane;
199 ConfigDialogPane *m_pYGuideAlgorithmConfigDialogPane;
200 wxStaticBoxSizer* m_pAlgoBox;
201 wxStaticBoxSizer* m_pRABox;
202 wxStaticBoxSizer* m_pDecBox;
203 wxButton* m_pResetRAParams;
204 wxButton* m_pResetDecParams;
205 void OnResetRAParams(wxCommandEvent& evt);
206 void OnResetDecParams(wxCommandEvent& evt);
207
208 public:
209 MountConfigDialogPane(wxWindow *pParent, const wxString& title, Mount *pMount);
210 ~MountConfigDialogPane();
211
212 virtual void LoadValues();
213 virtual void UnloadValues();
214 virtual void LayoutControls(wxPanel *pParent, BrainCtrlIdMap& CtrlMap);
215 virtual void OnImageScaleChange();
IsValid()216 bool IsValid() { return m_pMount != nullptr; }
217
218 virtual void Undo();
219
220 void OnXAlgorithmSelected(wxCommandEvent& evt);
221 void OnYAlgorithmSelected(wxCommandEvent& evt);
222 void ChangeYAlgorithm(const wxString& algoName);
223 void ResetRAGuidingParams();
224 void ResetDecGuidingParams();
225 void EnableDecControls(bool enable);
226 };
227
228 GUIDE_ALGORITHM GetXGuideAlgorithmSelection() const;
229 GUIDE_ALGORITHM GetYGuideAlgorithmSelection() const;
230
231 void SetXGuideAlgorithm(int guideAlgorithm);
232 void SetYGuideAlgorithm(int guideAlgorithm);
233
234 virtual GUIDE_ALGORITHM DefaultXGuideAlgorithm() const = 0;
235 virtual GUIDE_ALGORITHM DefaultYGuideAlgorithm() const = 0;
236
237 static GUIDE_ALGORITHM GetGuideAlgorithm(const GuideAlgorithm *pAlgorithm);
238 static bool CreateGuideAlgorithm(int guideAlgorithm, Mount *mount, GuideAxis axis, GuideAlgorithm **ppAlgorithm);
239
240 #ifdef TEST_TRANSFORMS
241 void Mount::TestTransforms();
242 #endif
243
244 // functions with an implementation in Mount that cannot be over-ridden
245 // by a subclass
246 public:
247
248 enum MOVE_RESULT {
249 MOVE_OK = 0, // move succeeded
250 MOVE_ERROR, // move failed for unspecified reason
251 MOVE_ERROR_SLEWING, // move failed due to scope slewing
252 MOVE_ERROR_AO_LIMIT_REACHED, // move failed due to AO limit
253 };
254
255 Mount();
256 virtual ~Mount();
257
GetIssueString(CalibrationIssueType issue)258 static const wxString& GetIssueString(CalibrationIssueType issue) { return CalibrationIssueString[issue]; };
259
260 double yAngle() const;
261 double yRate() const;
262 double xAngle() const;
263 double xRate() const;
264 GuideParity RAParity() const;
265 GuideParity DecParity() const;
266 double GetCalibrationDeclination() const; // in radians
267
268 bool FlipCalibration();
269 bool GetGuidingEnabled() const;
270 void SetGuidingEnabled(bool guidingEnabled);
271 virtual void DeferPulseLimitAlertCheck();
272
273 virtual MOVE_RESULT MoveOffset(GuiderOffset *guiderOffset, unsigned int moveOptions);
274
275 bool TransformCameraCoordinatesToMountCoordinates(const PHD_Point& cameraVectorEndpoint,
276 PHD_Point& mountVectorEndpoint, bool logged = true);
277
278 bool TransformMountCoordinatesToCameraCoordinates(const PHD_Point& mountVectorEndpoint,
279 PHD_Point& cameraVectorEndpoint, bool logged = true);
280
281 void LogGuideStepInfo();
282
283 GraphControlPane *GetXGuideAlgorithmControlPane(wxWindow *pParent);
284 GraphControlPane *GetYGuideAlgorithmControlPane(wxWindow *pParent);
285 virtual GraphControlPane *GetGraphControlPane(wxWindow *pParent, const wxString& label);
286
287 virtual bool DecCompensationEnabled() const;
288 virtual void AdjustCalibrationForScopePointing();
289
290 // untranslated strings for logging
291 static wxString DeclinationStr(double dec, const wxString& numFormatStr = "%.1f");
292 static wxString PierSideStr(PierSide side);
293 // translated strings for UI
294 static wxString DeclinationStrTr(double dec, const wxString& numFormatStr = "%.1f");
295 static wxString PierSideStrTr(PierSide side);
296
297 bool IsBusy() const;
298 void IncrementRequestCount();
299 void DecrementRequestCount();
300
301 int ErrorCount() const;
302 void IncrementErrorCount();
303 void ResetErrorCount();
304
305 // pure virtual functions -- these MUST be overridden by a subclass
306 public:
307 // move the requested direction, return the actual amount of the move
308 virtual MOVE_RESULT MoveAxis(GUIDE_DIRECTION direction, int amount, unsigned int moveOptions, MoveResultInfo *moveResultInfo) = 0;
309 virtual MOVE_RESULT MoveAxis(GUIDE_DIRECTION direction, int duration, unsigned int moveOptions) = 0;
310 virtual int CalibrationMoveSize() = 0;
311 virtual int CalibrationTotDistance() = 0;
312
313 // Calibration related routines
314 virtual bool BeginCalibration(const PHD_Point ¤tLocation) = 0;
315 virtual bool UpdateCalibrationState(const PHD_Point ¤tLocation) = 0;
316
317 virtual void NotifyGuidingStarted();
318 virtual void NotifyGuidingStopped();
319 virtual void NotifyGuidingPaused();
320 virtual void NotifyGuidingResumed();
321 virtual void NotifyGuidingDithered(double dx, double dy, bool mountCoords);
322 virtual void NotifyGuidingDitherSettleDone(bool success);
323 virtual void NotifyDirectMove(const PHD_Point& dist);
324
325 virtual MountConfigDialogPane *GetConfigDialogPane(wxWindow *pParent) = 0;
326 virtual MountConfigDialogCtrlSet *GetConfigDialogCtrlSet(wxWindow *pParent, Mount *pMount, AdvancedDialog *pAdvancedDialog, BrainCtrlIdMap& CtrlMap) = 0;
327 ConfigDialogCtrlSet* currConfigDialogCtrlSet; // instance currently in-use by AD
328
329 virtual wxString GetMountClassName() const = 0;
330
331 GuideAlgorithm *GetXGuideAlgorithm() const;
332 GuideAlgorithm *GetYGuideAlgorithm() const;
333
334 void GetLastCalibration(Calibration *cal) const;
GetBacklashComp()335 BacklashComp *GetBacklashComp() const { return m_backlashComp; }
336
337 // virtual functions -- these CAN be overridden by a subclass, which should
338 // consider whether they need to call the base class functions as part of
339 // their operation
340 public:
341
342 virtual bool HasNonGuiMove();
343 virtual bool SynchronousOnly();
344 virtual bool HasSetupDialog() const;
345 virtual void SetupDialog();
346
347 virtual const wxString& Name() const;
348 virtual bool IsStepGuider() const;
349 virtual wxPoint GetAoPos() const;
350 virtual wxPoint GetAoMaxPos() const;
351 virtual const char *DirectionStr(GUIDE_DIRECTION d) const;
352 virtual const char *DirectionChar(GUIDE_DIRECTION d) const;
353
354 virtual bool IsCalibrated() const;
355 virtual void ClearCalibration();
356 virtual void SetCalibration(const Calibration& cal);
357
358 void SaveCalibrationDetails(const CalibrationDetails& calDetails) const;
359 void LoadCalibrationDetails(CalibrationDetails *calDetails) const;
360
361 virtual bool IsConnected() const;
362 virtual bool Connect();
363 virtual bool Disconnect();
364
365 virtual wxString GetSettingsSummary() const;
CalibrationSettingsSummary()366 virtual wxString CalibrationSettingsSummary() const { return wxEmptyString; }
367
368 virtual bool CalibrationFlipRequiresDecFlip();
HasHPDecEncoder()369 virtual bool HasHPDecEncoder() { return false; }
370
371 virtual void StartDecDrift();
372 virtual void EndDecDrift();
373 virtual bool IsDecDrifting() const;
374
MountIsCalibrated()375 bool MountIsCalibrated() const { return m_calibrated; }
MountCal()376 const Calibration& MountCal() const { return m_cal; }
377 };
378
xRate()379 inline double Mount::xRate() const
380 {
381 return m_xRate;
382 }
383
yRate()384 inline double Mount::yRate() const
385 {
386 return m_cal.yRate;
387 }
388
xAngle()389 inline double Mount::xAngle() const
390 {
391 return m_cal.xAngle;
392 }
393
GetGuidingEnabled()394 inline bool Mount::GetGuidingEnabled() const
395 {
396 return m_guidingEnabled;
397 }
398
IsBusy()399 inline bool Mount::IsBusy() const
400 {
401 return m_requestCount > 0;
402 }
403
ErrorCount()404 inline int Mount::ErrorCount() const
405 {
406 return m_errorCount;
407 }
408
IncrementErrorCount()409 inline void Mount::IncrementErrorCount()
410 {
411 ++m_errorCount;
412 }
413
ResetErrorCount()414 inline void Mount::ResetErrorCount()
415 {
416 m_errorCount = 0;
417 }
418
GetXGuideAlgorithm()419 inline GuideAlgorithm *Mount::GetXGuideAlgorithm() const
420 {
421 return m_pXGuideAlgorithm;
422 }
423
GetYGuideAlgorithm()424 inline GuideAlgorithm *Mount::GetYGuideAlgorithm() const
425 {
426 return m_pYGuideAlgorithm;
427 }
428
IsConnected()429 inline bool Mount::IsConnected() const
430 {
431 return m_connected;
432 }
433
RAParity()434 inline GuideParity Mount::RAParity() const
435 {
436 return m_calibrated ? m_cal.raGuideParity : GUIDE_PARITY_UNKNOWN;
437 }
438
DecParity()439 inline GuideParity Mount::DecParity() const
440 {
441 return m_calibrated ? m_cal.decGuideParity : GUIDE_PARITY_UNKNOWN;
442 }
443
GetCalibrationDeclination()444 inline double Mount::GetCalibrationDeclination() const
445 {
446 return m_calibrated ? m_cal.declination : UNKNOWN_DECLINATION;
447 }
448
449 #endif /* MOUNT_H_INCLUDED */
450