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