1 /*
2  *  guider.h
3  *  PHD Guiding
4  *
5  *  Created by Bret McKee
6  *  Copyright (c) 2012 Bret McKee
7  *  All rights reserved.
8  *
9  *  Based upon work by Craig Stark.
10  *  Copyright (c) 2006-2010 Craig Stark.
11  *  All rights reserved.
12  *
13  *  This source code is distributed under the following "BSD" license
14  *  Redistribution and use in source and binary forms, with or without
15  *  modification, are permitted provided that the following conditions are met:
16  *    Redistributions of source code must retain the above copyright notice,
17  *     this list of conditions and the following disclaimer.
18  *    Redistributions in binary form must reproduce the above copyright notice,
19  *     this list of conditions and the following disclaimer in the
20  *     documentation and/or other materials provided with the distribution.
21  *    Neither the name of Bret McKee, Dad Dog Development,
22  *     Craig Stark, Stark Labs nor the names of its
23  *     contributors may be used to endorse or promote products derived from
24  *     this software without specific prior written permission.
25  *
26  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  *  POSSIBILITY OF SUCH DAMAGE.
37  *
38  */
39 
40 #ifndef GUIDER_H_INCLUDED
41 #define GUIDER_H_INCLUDED
42 
43 enum GUIDER_STATE
44 {
45     STATE_UNINITIALIZED = 0,
46     STATE_SELECTING,
47     STATE_SELECTED,
48     STATE_CALIBRATING_PRIMARY,
49     STATE_CALIBRATING_SECONDARY,
50     STATE_CALIBRATED,
51     STATE_GUIDING,
52     STATE_STOP, // This is a pseudo state
53 };
54 
55 enum EXPOSED_STATE
56 {
57     EXPOSED_STATE_NONE = 0,
58     EXPOSED_STATE_SELECTED,
59     EXPOSED_STATE_CALIBRATING,
60     EXPOSED_STATE_GUIDING_LOCKED,
61     EXPOSED_STATE_GUIDING_LOST,
62 
63     EXPOSED_STATE_PAUSED = 100,
64     EXPOSED_STATE_LOOPING,
65 };
66 
67 enum DEC_GUDING_ALGORITHM
68 {
69     DEC_LOWPASS = 0,
70     DEC_RESISTSWITCH,
71     DEC_LOWPASS2,
72 };
73 
74 enum OVERLAY_MODE
75 {
76     OVERLAY_NONE = 0,
77     OVERLAY_BULLSEYE,
78     OVERLAY_GRID_FINE,
79     OVERLAY_GRID_COARSE,
80     OVERLAY_RADEC,
81     OVERLAY_SLIT,
82 };
83 
84 struct OverlaySlitCoords
85 {
86     wxPoint center;
87     wxSize size;
88     int angle;
89     wxPoint corners[5];
90 };
91 
92 enum PauseType
93 {
94     PAUSE_NONE,     // not paused
95     PAUSE_GUIDING,  // pause guide corrections but continue looping exposures
96     PAUSE_FULL,     // pause guide corrections and pause looping exposures
97 };
98 
99 struct LockPosShiftParams
100 {
101     bool shiftEnabled;
102     PHD_Point shiftRate;
103     GRAPH_UNITS shiftUnits;
104     bool shiftIsMountCoords;
105 };
106 
107 class DefectMap;
108 
109 /*
110  * The Guider class is responsible for running the state machine
111  * associated with the GUIDER_STATES enumerated type.
112  *
113  * It is also responsible for drawing and decorating the acquired
114  * image in a way that makes sense for its type.
115  *
116  */
117 
118 class GuiderConfigDialogCtrlSet : public ConfigDialogCtrlSet
119 {
120     Guider *m_pGuider;
121     wxCheckBox *m_pEnableFastRecenter;
122     wxCheckBox *m_pScaleImage;
123 
124 public:
125     GuiderConfigDialogCtrlSet(wxWindow *pParent, Guider *pGuider, AdvancedDialog* pAdvancedDialog, BrainCtrlIdMap& CtrlMap);
~GuiderConfigDialogCtrlSet()126     virtual ~GuiderConfigDialogCtrlSet() {};
127     virtual void LoadValues();
128     virtual void UnloadValues();
129 
130 };
131 
132 struct GuiderOffset
133 {
134     PHD_Point cameraOfs;
135     PHD_Point mountOfs;
136 };
137 
138 class Guider : public wxWindow
139 {
140     wxImage *m_displayedImage;
141     OVERLAY_MODE m_overlayMode;
142     OverlaySlitCoords m_overlaySlitCoords;
143     const DefectMap *m_defectMapPreview;
144     double m_polarAlignCircleRadius;
145     double m_polarAlignCircleCorrection;
146     PHD_Point m_polarAlignCircleCenter;
147     PauseType m_paused;
148     ShiftPoint m_lockPosition;
149     PHD_Point m_ditherRecenterStep;
150     wxPoint m_ditherRecenterDir;
151     PHD_Point m_ditherRecenterRemaining;
152     time_t m_starFoundTimestamp;  // timestamp when star was last found
153     double m_avgDistance;         // averaged distance for distance reporting
154     double m_avgDistanceRA;       // averaged distance, RA only
155     double m_avgDistanceLong;     // averaged distance, more smoothed
156     double m_avgDistanceLongRA;   // averaged distance, more smoothed, RA only
157     unsigned int m_avgDistanceCnt;
158     bool m_avgDistanceNeedReset;
159     GUIDER_STATE m_state;
160     usImage *m_pCurrentImage;
161     bool m_scaleImage;
162     bool m_lockPosIsSticky;
163     bool m_ignoreLostStarLooping;
164     bool m_fastRecenterEnabled;
165     LockPosShiftParams m_lockPosShift;
166     bool m_measurementMode;
167     double m_minStarHFD;
168     double m_minStarSNR;
169     unsigned int m_autoSelDownsample;  // downsample factor for star auto-selection, 0=Auto
170 
171 protected:
172     int m_searchRegion; // how far u/d/l/r do we do the initial search for a star
173     bool m_forceFullFrame;
174     double m_scaleFactor;
175     bool m_showBookmarks;
176     std::vector<wxRealPoint> m_bookmarks;
177 
178     // Things related to the Advanced Config Dialog
179 public:
180     class GuiderConfigDialogPane : public ConfigDialogPane
181     {
182         Guider *m_pGuider;
183 
184     public:
185         GuiderConfigDialogPane(wxWindow *pParent, Guider *pGuider);
~GuiderConfigDialogPane()186         ~GuiderConfigDialogPane() {};
187 
LoadValues()188         void LoadValues() {};
UnloadValues()189         void UnloadValues() {};
190         virtual void LayoutControls(Guider *pGuider, BrainCtrlIdMap& CtrlMap);
191     };
192 
193 
194     OVERLAY_MODE GetOverlayMode() const;
195 
196 public:
197     virtual GuiderConfigDialogPane *GetConfigDialogPane(wxWindow *pParent)= 0;
198     virtual GuiderConfigDialogCtrlSet *GetConfigDialogCtrlSet(wxWindow *pParent, Guider *pGuider, AdvancedDialog *pAdvancedDialog, BrainCtrlIdMap& CtrlMap);
199 
200 protected:
201     Guider(wxWindow *parent, int xSize, int ySize);
202     virtual ~Guider();
203 
204     bool PaintHelper(wxAutoBufferedPaintDCBase& dc, wxMemoryDC& memDC);
205     void SetState(GUIDER_STATE newState);
206     void UpdateCurrentDistance(double distance, double distanceRA);
207 
208     void ToggleBookmark(const wxRealPoint& pt);
209 
210 public:
211     bool IsPaused() const;
212     PauseType GetPauseType() const;
213     PauseType SetPaused(PauseType pause);
214     GUIDER_STATE GetState() const;
215     static EXPOSED_STATE GetExposedState();
216     bool IsCalibratingOrGuiding() const;
217     bool IsCalibrating() const;
218     bool IsGuiding() const;
219     void OnClose(wxCloseEvent& evt);
220     void OnErase(wxEraseEvent& evt);
221     void UpdateImageDisplay(usImage *pImage = nullptr);
222 
223     bool MoveLockPosition(const PHD_Point& mountDelta);
224     virtual bool SetLockPosition(const PHD_Point& position);
225     bool SetLockPosToStarAtPosition(const PHD_Point& starPositionHint);
226     bool ShiftLockPosition();
227     void EnableLockPosShift(bool enable);
228     void SetLockPosShiftRate(const PHD_Point& rate, GRAPH_UNITS units, bool isMountCoords, bool updateToolWin);
LockPosShiftEnabled()229     bool LockPosShiftEnabled() const { return m_lockPosShift.shiftEnabled; }
SetLockPosIsSticky(bool isSticky)230     void SetLockPosIsSticky(bool isSticky) { m_lockPosIsSticky = isSticky; }
LockPosIsSticky()231     bool LockPosIsSticky() const { return m_lockPosIsSticky; }
232     void SetIgnoreLostStarLooping(bool ignore);
233     const ShiftPoint& LockPosition() const;
GetLockPosShiftParams()234     const LockPosShiftParams& GetLockPosShiftParams() const { return m_lockPosShift; }
235     void ForceFullFrame();
236 
237     bool SetOverlayMode(int newMode);
238     void GetOverlaySlitCoords(wxPoint *center, wxSize *size, int *angle);
239     void SetOverlaySlitCoords(const wxPoint& center, const wxSize& size, int angle);
240     void SetDefectMapPreview(const DefectMap *preview);
241     void SetPolarAlignCircle(const PHD_Point& center, double radius);
242     void SetPolarAlignCircleCorrection(double val);
243     double GetPolarAlignCircleCorrection() const;
244     bool SaveCurrentImage(const wxString& fileName);
245 
246     void StartGuiding();
247     void StopGuiding();
248     void UpdateGuideState(usImage *pImage, bool bStopping=false);
249     void DisplayImage(usImage *img);
250 
251     bool SetScaleImage(bool newScaleValue);
252     bool GetScaleImage() const;
253 
254     int GetSearchRegion() const;
255     double CurrentError(bool raOnly);
256     double CurrentErrorSmoothed(bool raOnly);
CurrentErrorFrameCount()257     unsigned int CurrentErrorFrameCount() const { return m_avgDistanceCnt; }
258 
259     bool GetBookmarksShown() const;
260     void SetBookmarksShown(bool show);
261     void ToggleShowBookmarks();
262     void DeleteAllBookmarks();
263     void BookmarkLockPosition();
264     void BookmarkCurPosition();
265 
266     void Reset(bool fullReset);
267     void EnableMeasurementMode(bool enabled);
268     void SetMinStarHFD(double val);
269     double GetMinStarHFD() const;
270     void SetMinStarSNR(double val);
271     double getMinStarSNR() const;
272     void SetAutoSelDownsample(unsigned int val);
273     unsigned int GetAutoSelDownsample() const;
274 
275     // virtual functions -- these CAN be overridden by a subclass, which should
276     // consider whether they need to call the base class functions as part of
277     // their operation
278 private:
279     virtual void InvalidateLockPosition();
280 public:
281     virtual void LoadProfileSettings();
282 
283     // pure virtual functions -- these MUST be overridden by a subclass
284 public:
285     virtual bool IsValidLockPosition(const PHD_Point& pt) = 0;
286     virtual void InvalidateCurrentPosition(bool fullReset = false) = 0;
287 private:
288     virtual bool UpdateCurrentPosition(const usImage *pImage, GuiderOffset *ofs, FrameDroppedInfo *errorInfo) = 0;
289     virtual bool SetCurrentPosition(const usImage *pImage, const PHD_Point& position) = 0;
290 
291 public:
292     virtual void OnPaint(wxPaintEvent& evt) = 0;
293 
294     virtual bool IsLocked() const = 0;
295     virtual bool AutoSelect(const wxRect& roi = wxRect()) = 0;
296 
297     virtual const PHD_Point& CurrentPosition() const = 0;
298     virtual wxRect GetBoundingBox() const = 0;
299     virtual int GetMaxMovePixels() const = 0;
300 
301     virtual const Star& PrimaryStar() const = 0;
302 
GetMultiStarMode()303     virtual bool GetMultiStarMode() const { return false; }
SetMultiStarMode(bool On)304     virtual void SetMultiStarMode(bool On) {};
GetStarCount()305     virtual wxString GetStarCount() const { return wxEmptyString; }
306 
307     usImage *CurrentImage() const;
308     wxImage *DisplayedImage() const;
309     double ScaleFactor() const;
310 
311     virtual wxString GetSettingsSummary() const;
312 
313     bool IsFastRecenterEnabled() const;
314     void EnableFastRecenter(bool enable);
315 
316 private:
317     void UpdateLockPosShiftCameraCoords();
318     DECLARE_EVENT_TABLE()
319 };
320 
IsPaused()321 inline bool Guider::IsPaused() const
322 {
323     return m_paused != PAUSE_NONE;
324 }
325 
GetPauseType()326 inline PauseType Guider::GetPauseType() const
327 {
328     return m_paused;
329 }
330 
GetOverlayMode()331 inline OVERLAY_MODE Guider::GetOverlayMode() const
332 {
333     return m_overlayMode;
334 }
335 
GetScaleImage()336 inline bool Guider::GetScaleImage() const
337 {
338     return m_scaleImage;
339 }
340 
LockPosition()341 inline const ShiftPoint& Guider::LockPosition() const
342 {
343     return m_lockPosition;
344 }
345 
GetState()346 inline GUIDER_STATE Guider::GetState() const
347 {
348     return m_state;
349 }
350 
IsGuiding()351 inline bool Guider::IsGuiding() const
352 {
353     return m_state == STATE_GUIDING;
354 }
355 
IsCalibratingOrGuiding()356 inline bool Guider::IsCalibratingOrGuiding() const
357 {
358     return m_state >= STATE_CALIBRATING_PRIMARY && m_state <= STATE_GUIDING;
359 }
360 
IsCalibrating()361 inline bool Guider::IsCalibrating() const
362 {
363     return m_state >= STATE_CALIBRATING_PRIMARY && m_state < STATE_CALIBRATED;
364 }
365 
GetSearchRegion()366 inline int Guider::GetSearchRegion() const
367 {
368     return m_searchRegion;
369 }
370 
IsFastRecenterEnabled()371 inline bool Guider::IsFastRecenterEnabled() const
372 {
373     return m_fastRecenterEnabled;
374 }
375 
GetPolarAlignCircleCorrection()376 inline double Guider::GetPolarAlignCircleCorrection() const
377 {
378     return m_polarAlignCircleCorrection;
379 }
380 
SetPolarAlignCircleCorrection(double val)381 inline void Guider::SetPolarAlignCircleCorrection(double val)
382 {
383     m_polarAlignCircleCorrection = val;
384 }
385 
CurrentImage()386 inline usImage *Guider::CurrentImage() const
387 {
388     return m_pCurrentImage;
389 }
390 
DisplayedImage()391 inline wxImage *Guider::DisplayedImage() const
392 {
393     return m_displayedImage;
394 }
395 
ScaleFactor()396 inline double Guider::ScaleFactor() const
397 {
398     return m_scaleFactor;
399 }
400 
GetBookmarksShown()401 inline bool Guider::GetBookmarksShown() const
402 {
403     return m_showBookmarks;
404 }
405 
GetMinStarHFD()406 inline double Guider::GetMinStarHFD() const
407 {
408     return m_minStarHFD;
409 }
410 
getMinStarSNR()411 inline double Guider::getMinStarSNR() const
412 {
413     return m_minStarSNR;
414 }
415 
GetAutoSelDownsample()416 inline unsigned int Guider::GetAutoSelDownsample() const
417 {
418     return m_autoSelDownsample;
419 }
420 
421 #endif /* GUIDER_H_INCLUDED */
422