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 &currentLocation) = 0;
315     virtual bool UpdateCalibrationState(const PHD_Point &currentLocation) = 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