1 /*
2  *  camera.h
3  *  PHD Guiding
4  *
5  *  Created by Craig Stark.
6  *  Copyright (c) 2006-2010 Craig Stark.
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 Craig Stark, Stark Labs nor the names of its
18  *     contributors may be used to endorse or promote products derived from
19  *     this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  *  POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 #ifndef CAMERA_H_INCLUDED
36 #define CAMERA_H_INCLUDED
37 
38 typedef std::map<int, usImage *> ExposureImgMap; // map exposure to image
39 class DefectMap;
40 
41 enum PropDlgType
42 {
43     PROPDLG_NONE = 0,
44     PROPDLG_WHEN_CONNECTED = (1 << 0),    // property dialog available when connected
45     PROPDLG_WHEN_DISCONNECTED = (1 << 1), // property dialog available when disconnected
46     PROPDLG_ANY = (PROPDLG_WHEN_CONNECTED | PROPDLG_WHEN_DISCONNECTED),
47 };
48 
49 extern wxSize UNDEFINED_FRAME_SIZE;
50 
51 class GuideCamera;
52 
53 class CameraConfigDialogPane : public ConfigDialogPane
54 {
55 public:
56     CameraConfigDialogPane(wxWindow *pParent, GuideCamera *pCamera);
~CameraConfigDialogPane()57     virtual ~CameraConfigDialogPane() {};
58 
59     void LayoutControls(GuideCamera *pCamera, BrainCtrlIdMap& CtrlMap);
LoadValues()60     virtual void LoadValues() {};
UnloadValues()61     virtual void UnloadValues() {};
62 };
63 
64 class CameraConfigDialogCtrlSet : public ConfigDialogCtrlSet
65 {
66     GuideCamera *m_pCamera;
67     wxCheckBox *m_pUseSubframes;
68     wxSpinCtrl *m_pCameraGain;
69     wxButton *m_resetGain;
70     wxSpinCtrl *m_timeoutVal;
71     wxChoice   *m_pPortNum;
72     wxSpinCtrl *m_pDelay;
73     wxSpinCtrlDouble *m_pPixelSize;
74     wxChoice *m_binning;
75     wxCheckBox *m_coolerOn;
76     wxSpinCtrl *m_coolerSetpt;
77     wxTextCtrl *m_camSaturationADU;
78     wxRadioButton *m_SaturationByProfile;
79     wxRadioButton *m_SaturationByADU;
80 
81     int m_prevBinning;
82 
83 public:
84     CameraConfigDialogCtrlSet(wxWindow *pParent, GuideCamera *pCamera, AdvancedDialog *pAdvancedDialog, BrainCtrlIdMap& CtrlMap);
~CameraConfigDialogCtrlSet()85     virtual ~CameraConfigDialogCtrlSet() {};
86     virtual void LoadValues();
87     virtual void UnloadValues();
88 
89     double GetPixelSize();
90     void SetPixelSize(double val);
91     int GetBinning();
92     void SetBinning(int val);
93     void OnSaturationChoiceChanged(wxCommandEvent& event);
94 };
95 
96 enum CaptureOptionBits
97 {
98     CAPTURE_SUBTRACT_DARK = 1 << 0,
99     CAPTURE_RECON         = 1 << 1,    // debayer and/or deinterlace as required
100 
101     CAPTURE_LIGHT = CAPTURE_SUBTRACT_DARK | CAPTURE_RECON,
102     CAPTURE_DARK = 0,
103     CAPTURE_BPM_REVIEW = CAPTURE_SUBTRACT_DARK,
104 };
105 
106 class GuideCamera : public wxMessageBoxProxy, public OnboardST4
107 {
108     friend class CameraConfigDialogPane;
109     friend class CameraConfigDialogCtrlSet;
110 
111     double          m_pixelSize;
112 
113 protected:
114     bool            m_hasGuideOutput;
115     int             m_timeoutMs;
116     bool            m_saturationByADU;
117     unsigned short  m_saturationADU;
118 
119 public:
120 
121     static const double UnknownPixelSize;
122 
123     int             GuideCameraGain;
124     wxString        Name;                   // User-friendly name
125     wxSize          FullSize;           // Size of current image
126     bool            Connected;
127     PropDlgType     PropertyDialogType;
128     bool            HasPortNum;
129     bool            HasDelayParam;
130     bool            HasGainControl;
131     bool            HasShutter;
132     bool            HasSubframes;
133     wxByte          MaxBinning;
134     wxByte          Binning;
135     short           Port;
136     int             ReadDelay;
137     bool            ShutterClosed;  // false=light, true=dark
138     bool            UseSubframes;
139     bool            HasCooler;
140 
141     wxCriticalSection DarkFrameLock; // dark frames can be accessed in the main thread or the camera worker thread
142     usImage        *CurrentDarkFrame;
143     ExposureImgMap  Darks; // map exposure => dark frame
144     DefectMap      *CurrentDefectMap;
145 
146     static wxArrayString GuideCameraList();
147     static GuideCamera *Factory(const wxString& choice);
148 
149     GuideCamera();
150     virtual ~GuideCamera();
151 
152     virtual bool HasNonGuiCapture() = 0;
153     virtual wxByte BitsPerPixel() = 0;
154 
155     static bool Capture(GuideCamera *camera, int duration, usImage& img, int captureOptions, const wxRect& subframe);
Capture(GuideCamera * camera,int duration,usImage & img,int captureOptions)156     static bool Capture(GuideCamera *camera, int duration, usImage& img, int captureOptions) { return Capture(camera, duration, img, captureOptions, wxRect(0, 0, 0, 0)); }
157 
CanSelectCamera()158     virtual bool CanSelectCamera() const { return false; }
159     virtual bool HandleSelectCameraButtonClick(wxCommandEvent& evt);
160     static const wxString DEFAULT_CAMERA_ID;
161     virtual bool EnumCameras(wxArrayString& names, wxArrayString& ids);
162 
163     // Opens up and connects to camera. cameraId identifies which camera to connect to if
164     // there is more than one camera present
165     virtual bool    Connect(const wxString& cameraId) = 0;
166     virtual bool    Disconnect() = 0;               // Disconnects, unloading any DLLs loaded by Connect
167     virtual void    InitCapture();                  // Gets run at the start of any loop (e.g., reset stream, set gain, etc).
168 
169     virtual bool    ST4HasGuideOutput();
170     virtual bool    ST4HostConnected();
171     virtual bool    ST4HasNonGuiMove();
172     virtual bool    ST4PulseGuideScope(int direction, int duration);
173 
174     CameraConfigDialogPane *GetConfigDialogPane(wxWindow *pParent);
175     CameraConfigDialogCtrlSet *GetConfigDlgCtrlSet(wxWindow *pParent, GuideCamera *pCamera, AdvancedDialog *pAdvancedDialog, BrainCtrlIdMap& CtrlMap);
176 
177     static void GetBinningOpts(int maxBin, wxArrayString *opts);
178     void GetBinningOpts(wxArrayString *opts);
179     bool SetBinning(int binning);
180 
ShowPropertyDialog()181     virtual void    ShowPropertyDialog() { return; }
182     bool            SetCameraPixelSize(double pixel_size);
183     double          GetCameraPixelSize() const;
184     virtual bool    GetDevicePixelSize(double *devPixelSize);           // Value from device/driver or error return
185 
186     virtual bool    SetCoolerOn(bool on);
187     virtual bool    SetCoolerSetpoint(double temperature);
188     virtual bool    GetCoolerStatus(bool *on, double *setpoint, double *power, double *temperature);
189     virtual bool    GetSensorTemperature(double *temperature);
190 
191     virtual wxString GetSettingsSummary();
192     void            AddDark(usImage *dark);
193     void            SelectDark(int exposureDuration);
194     void            SetDefectMap(DefectMap *newMap);
195     void            ClearDefectMap();
196     void            ClearDarks();
197 
198     void            SubtractDark(usImage& img);
199     void            GetDarklibProperties(int *pNumDarks, double *pMinExp, double *pMaxExp);
200 
DarkFrameSize()201     virtual const wxSize& DarkFrameSize() { return FullSize; }
202 
203     static double GetProfilePixelSize();
204 
205     unsigned short GetSaturationADU() const;
206     bool IsSaturationByADU() const;
207     void SetSaturationByADU(bool saturationByADU, unsigned short saturationVal);
208 
209     int GetCameraGain() const;
210     bool SetCameraGain(int cameraGain);
211     virtual int GetDefaultCameraGain();
212 
213     virtual bool Capture(int duration, usImage& img, int captureOptions, const wxRect& subframe) = 0;
214 
215 protected:
216 
217     int GetTimeoutMs() const;
218     void SetTimeoutMs(int timeoutMs);
219 
220     static bool CamConnectFailed(const wxString& errorMessage);
221 
222     enum CaptureFailType {
223         CAPT_FAIL_MEMORY,
224         CAPT_FAIL_TIMEOUT,
225     };
226     enum ReconnectType {
227         NO_RECONNECT,
228         RECONNECT,
229     };
230     void DisconnectWithAlert(CaptureFailType type);
231     void DisconnectWithAlert(const wxString& msg, ReconnectType reconnect);
232 };
233 
GetTimeoutMs()234 inline int GuideCamera::GetTimeoutMs() const
235 {
236     return m_timeoutMs;
237 }
238 
GetBinningOpts(wxArrayString * opts)239 inline void GuideCamera::GetBinningOpts(wxArrayString *opts)
240 {
241     GetBinningOpts(MaxBinning, opts);
242 }
243 
GetCameraPixelSize()244 inline double GuideCamera::GetCameraPixelSize() const
245 {
246     return m_pixelSize;
247 }
248 
GetDevicePixelSize(double * devPixelSize)249 inline bool GuideCamera::GetDevicePixelSize(double *devPixelSize)
250 {
251     return true;                // Return an error, the device/driver can't report pixel size
252 }
253 
IsSaturationByADU()254 inline bool GuideCamera::IsSaturationByADU() const
255 {
256     return m_saturationByADU;
257 }
258 
GetSaturationADU()259 inline unsigned short GuideCamera::GetSaturationADU() const
260 {
261     return m_saturationByADU ? m_saturationADU : 0;
262 }
263 
GetCameraGain()264 inline int GuideCamera::GetCameraGain() const
265 {
266     return GuideCameraGain;
267 }
268 
269 #endif /* CAMERA_H_INCLUDED */
270