1 /*
2 * cam_ioptron.cpp
3 * Open PHD Guiding
4 *
5 * Created by Andy Galasso
6 * Copyright (c) 2019 Andy Galasso.
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 openphdguiding.org 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 #include "phd.h"
36
37 #if defined(IOPTRON_CAMERA)
38
39 #include "cam_ioptron.h"
40 #include "cam_wdm_base.h"
41 #include "CVPlatform.h"
42
43 class IoptronCamera : public CameraWDM
44 {
45 public:
IoptronCamera()46 IoptronCamera()
47 {
48 m_rawYUY2 = true;
49 }
CanSelectCamera() const50 bool CanSelectCamera() const override
51 {
52 // TODO: we could probably hanlde multiple cameras, but would need 2 cameras to test
53 return false;
54 }
GetDevicePixelSize(double * devPixelSize)55 bool GetDevicePixelSize(double *devPixelSize) override
56 {
57 *devPixelSize = 3.75;
58 return false;
59 }
60
61 protected:
62 bool SelectDeviceAndMode(SelectionContext ctx) override;
63 };
64
65 struct AutoVidCap
66 {
67 CVVidCapture *m_vc = new CVVidCaptureDSWin32();
68 bool inited = false;
69 bool connected = false;
InitAutoVidCap70 bool Init()
71 {
72 if (CVFAILED(m_vc->Init()))
73 return false;
74 inited = true;
75 return true;
76 }
ConnectAutoVidCap77 bool Connect(int devnr)
78 {
79 if (CVFAILED(m_vc->Connect(devnr)))
80 return false;
81 connected = true;
82 return true;
83 }
getAutoVidCap84 CVVidCapture *get() const { return m_vc; }
~AutoVidCapAutoVidCap85 ~AutoVidCap()
86 {
87 if (connected)
88 m_vc->Disconnect();
89 if (inited)
90 m_vc->Uninit();
91 CVPlatform::GetPlatform()->Release(m_vc);
92 }
93 };
94
SelectDeviceAndMode(SelectionContext ctx)95 bool IoptronCamera::SelectDeviceAndMode(SelectionContext ctx)
96 {
97 assert(ctx == CTX_CONNECT); // no camera selection for now
98 if (ctx != CTX_CONNECT)
99 return true;
100
101 AutoVidCap vc;
102
103 if (!vc.Init())
104 {
105 wxMessageBox(_T("Error initializing WDM services"), _("Error"), wxOK | wxICON_ERROR);
106 return true;
107 }
108
109 int nr_devs;
110 if (CVFAILED(vc.get()->GetNumDevices(nr_devs)))
111 {
112 wxMessageBox(_T("Error detecting WDM devices"), _("Error"), wxOK | wxICON_ERROR);
113 return true;
114 }
115
116 Debug.Write(wxString::Format("IOPTRON: %d vidcap devices\n", nr_devs));
117 if (nr_devs == 0)
118 return true;
119
120 m_deviceNumber = -1;
121
122 for (int i = 0; i < nr_devs; i++)
123 {
124 CVVidCapture::VIDCAP_DEVICE dev;
125 if (!CVSUCCESS(vc.get()->GetDeviceInfo(i, dev)))
126 {
127 Debug.Write(wxString::Format("IOPTRON: GetDevice failed for VidCap device %d, skipping it\n", i));
128 continue;
129 }
130 if (strcmp(dev.DeviceString, "iOptron iGuider") == 0)
131 {
132 Debug.Write(wxString::Format("IOPTRON: found iGuider at index %d\n", i));
133 if (m_deviceNumber == -1)
134 m_deviceNumber = i;
135 }
136 }
137 if (m_deviceNumber == -1)
138 {
139 Debug.Write("IOPTRON: iGuider not found\n");
140 return true;
141 }
142 Debug.Write(wxString::Format("IOPTRON: using iGuider at index %d\n", m_deviceNumber));
143
144 // Connect to camera
145 if (!vc.Connect(m_deviceNumber))
146 {
147 wxMessageBox(wxString::Format("Error connecting to iOptron iGuider"), _("Error"), wxOK | wxICON_ERROR);
148 return true;
149 }
150
151 int nr_modes = 0;
152 vc.get()->GetNumSupportedModes(nr_modes);
153
154 m_deviceMode = -1;
155 for (int i = 0; i < nr_modes; i++)
156 {
157 CVVidCapture::VIDCAP_MODE modeInfo;
158 if (CVSUCCESS(vc.get()->GetModeInfo(i, modeInfo)))
159 {
160 if (modeInfo.XRes == 640 && modeInfo.YRes == 960 &&
161 modeInfo.InputFormat == VIDCAP_FORMAT_YUY2)
162 {
163 if (m_deviceMode == -1)
164 m_deviceMode = i;
165 }
166 Debug.Write(wxString::Format("IOPTRON: mode %d: %dx%d (%s) %d fps %s\n", i, modeInfo.XRes,
167 modeInfo.YRes, vc.get()->GetFormatModeName(modeInfo.InputFormat),
168 modeInfo.EstFrameRate, i == m_deviceMode ? "<<<<" : ""));
169 }
170 else
171 Debug.Write(wxString::Format("IOPTRON: mode %d: GetModeInfo failed, skipped\n", i));
172 }
173
174 if (m_deviceMode == -1)
175 {
176 Debug.Write("IOPTRON: iGuider required mode YUY2 640x960 not found\n");
177 return true;
178 }
179
180 return false;
181 }
182
MakeIoptronCamera()183 GuideCamera *IoptronCameraFactory::MakeIoptronCamera()
184 {
185 return new IoptronCamera();
186 }
187
188 #endif // IOPTRON_CAMERA
189