Fawkes API  Fawkes Development Version
sony_evid100p.cpp
1 
2 /***************************************************************************
3  * sony_evid100p_control.cpp - Controller for Sony EVI-D100P
4  *
5  * Created: Tue Jun 07 19:27:20 2005
6  * Copyright 2005-2009 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <fvcams/control/sony_evid100p.h>
25 #include <fvcams/control/visca.h>
26 #include <fvutils/system/camargp.h>
27 #include <utils/math/angle.h>
28 
29 #include <cstdlib>
30 #include <cstring>
31 #include <termios.h>
32 
33 using namespace std;
34 using namespace fawkes;
35 
36 namespace firevision {
37 
38 /** Maximum pan. */
39 const int SonyEviD100PControl::MAX_PAN = 1440;
40 /** Minimum pan. */
41 const int SonyEviD100PControl::MIN_PAN = -1439;
42 /** Max Tilt. */
43 const int SonyEviD100PControl::MAX_TILT = 360;
44 /** Min tilt .*/
45 const int SonyEviD100PControl::MIN_TILT = -359;
46 
47 /** Max pan in degrees. */
48 const float SonyEviD100PControl::MAX_PAN_DEG = 100.f;
49 /** Min pan in degrees. */
50 const float SonyEviD100PControl::MIN_PAN_DEG = -100.f;
51 /** Max tilt in degrees. */
52 const float SonyEviD100PControl::MAX_TILT_DEG = 25.f;
53 /** Min tilt in degrees. */
54 const float SonyEviD100PControl::MIN_TILT_DEG = -25.f;
55 
56 /** Max pan in rad. */
57 const float SonyEviD100PControl::MAX_PAN_RAD = deg2rad(MAX_PAN_DEG);
58 /** Min pan in rad. */
59 const float SonyEviD100PControl::MIN_PAN_RAD = deg2rad(MIN_PAN_DEG);
60 /** Max tilt in rad. */
61 const float SonyEviD100PControl::MAX_TILT_RAD = deg2rad(MAX_TILT_DEG);
62 /** Min tilt in rad. */
63 const float SonyEviD100PControl::MIN_TILT_RAD = deg2rad(MIN_TILT_DEG);
64 
65 /** Pan steps per degree */
66 const float SonyEviD100PControl::PAN_STEPS_PER_DEG = MAX_PAN / MAX_PAN_DEG;
67 /** Tilt steps per degree */
68 const float SonyEviD100PControl::TILT_STEPS_PER_DEG = MAX_TILT / MAX_TILT_DEG;
69 
70 /** Pan steps per rad */
71 const float SonyEviD100PControl::PAN_STEPS_PER_RAD = MAX_PAN / MAX_PAN_RAD;
72 /** Tilt steps per rad */
73 const float SonyEviD100PControl::TILT_STEPS_PER_RAD = MAX_TILT / MAX_TILT_RAD;
74 
75 /** Pastel effect. */
76 const unsigned int SonyEviD100PControl::EFFECT_PASTEL = 1;
77 /** Negative effect. */
78 const unsigned int SonyEviD100PControl::EFFECT_NEGATIVE = 2;
79 /** Sepia effect. */
80 const unsigned int SonyEviD100PControl::EFFECT_SEPIA = 3;
81 /** B/W effect. */
82 const unsigned int SonyEviD100PControl::EFFECT_BW = 4;
83 /** Solarize effect. */
84 const unsigned int SonyEviD100PControl::EFFECT_SOLARIZE = 5;
85 /** Mosaic effect. */
86 const unsigned int SonyEviD100PControl::EFFECT_MOSAIC = 6;
87 /** Slim effect. */
88 const unsigned int SonyEviD100PControl::EFFECT_SLIM = 7;
89 /** Stretch effect. */
90 const unsigned int SonyEviD100PControl::EFFECT_STRETCH = 8;
91 
92 /** @class SonyEviD100PControl <fvcams/control/sony_evid100p.h>
93  * Sony Evi D100P pan/tilt control.
94  * Internally uses Visca.
95  * @author Tim Niemueller
96  */
97 
98 /** Constructor.
99  * @param tty_port serial port (e.g. /dev/ttyS0)
100  */
101 SonyEviD100PControl::SonyEviD100PControl(const char *tty_port)
102 {
103  this->tty_port = strdup(tty_port);
104  visca = new ViscaControl(/* non-blocking */ false);
105  opened = false;
106  pan_target = 0;
107  tilt_target = 0;
108  _effect = EFFECT_NONE;
109 
110  open();
111 }
112 
113 /** Constructor.
114  * Uses camera argument parser to gather arguments. The ID that the camera argument
115  * parser returns is used as the serial port (like /dev/ttyS0).
116  * @param cap camera argument parser
117  */
118 SonyEviD100PControl::SonyEviD100PControl(const CameraArgumentParser *cap)
119 {
120  tty_port = strdup(cap->cam_id().c_str());
121 
122  visca = new ViscaControl(/* non-blocking */ false);
123  opened = false;
124  pan_target = 0;
125  tilt_target = 0;
126  _effect = EFFECT_NONE;
127 
128  open();
129 }
130 
131 /** Destructor. */
132 SonyEviD100PControl::~SonyEviD100PControl()
133 {
134  close();
135  delete visca;
136  free(tty_port);
137 }
138 
139 /** Open visca device.
140  */
141 void
142 SonyEviD100PControl::open()
143 {
144  if (opened)
145  return;
146 
147  try {
148  visca->open(tty_port);
149  visca->set_address(1);
150  visca->clear();
151  } catch (ViscaControlException &e) {
152  visca->close();
153  e.append("Sony EviD100PControl failed");
154  throw;
155  }
156 
157  opened = true;
158 }
159 
160 /** Close Visca device.
161  */
162 void
163 SonyEviD100PControl::close()
164 {
165  if (!opened)
166  return;
167  visca->close();
168 }
169 
170 void
171 SonyEviD100PControl::process_pantilt()
172 {
173  visca->process();
174 }
175 
176 bool
177 SonyEviD100PControl::supports_pan()
178 {
179  return true;
180 }
181 
182 bool
183 SonyEviD100PControl::supports_tilt()
184 {
185  return true;
186 }
187 
188 void
189 SonyEviD100PControl::set_pan(int pan)
190 {
191  pan_target = pan;
192  visca->setPanTilt(pan, tilt_target);
193 }
194 
195 void
196 SonyEviD100PControl::set_tilt(int tilt)
197 {
198  tilt_target = tilt;
199  visca->setPanTilt(pan_target, tilt);
200 }
201 
202 void
203 SonyEviD100PControl::set_pan_tilt(int pan, int tilt)
204 {
205  pan_target = pan;
206  tilt_target = tilt;
207  visca->setPanTilt(pan, tilt);
208 }
209 
210 void
211 SonyEviD100PControl::set_pan_tilt_rad(float pan, float tilt)
212 {
213  int tpan = 0, ttilt = 0;
214 
215  tpan = (int)rint(pan * PAN_STEPS_PER_RAD);
216  ttilt = (int)rint(tilt * TILT_STEPS_PER_RAD);
217 
218  set_pan_tilt(tpan, ttilt);
219 }
220 
221 void
222 SonyEviD100PControl::start_get_pan_tilt()
223 {
224  visca->startGetPanTilt();
225 }
226 
227 void
228 SonyEviD100PControl::pan_tilt(int &pan, int &tilt)
229 {
230  int tpan, ttilt;
231  visca->getPanTilt(&tpan, &ttilt);
232  pan = tpan;
233  tilt = ttilt;
234 }
235 
236 void
237 SonyEviD100PControl::pan_tilt_rad(float &pan, float &tilt)
238 {
239  int tpan = 0, ttilt = 0;
240  visca->getPanTilt(&tpan, &ttilt);
241 
242  pan = tpan / PAN_STEPS_PER_RAD;
243  tilt = ttilt / PAN_STEPS_PER_RAD;
244 }
245 
246 int
247 SonyEviD100PControl::pan()
248 {
249  int pan = 0, tilt = 0;
250  visca->getPanTilt(&pan, &tilt);
251  return pan;
252 }
253 
254 int
255 SonyEviD100PControl::tilt()
256 {
257  int pan = 0, tilt = 0;
258  visca->getPanTilt(&pan, &tilt);
259  return tilt;
260 }
261 
262 int
263 SonyEviD100PControl::max_pan()
264 {
265  return MAX_PAN;
266 }
267 
268 int
269 SonyEviD100PControl::min_pan()
270 {
271  return MIN_PAN;
272 }
273 
274 int
275 SonyEviD100PControl::max_tilt()
276 {
277  return MAX_TILT;
278 }
279 
280 int
281 SonyEviD100PControl::min_tilt()
282 {
283  return MIN_TILT;
284 }
285 
286 void
287 SonyEviD100PControl::reset_pan_tilt()
288 {
289  visca->resetPanTilt();
290 }
291 
292 void
293 SonyEviD100PControl::set_pan_tilt_limit(int pan_left, int pan_right, int tilt_up, int tilt_down)
294 {
295  visca->setPanTiltLimit(pan_left, pan_right, tilt_up, tilt_down);
296 }
297 
298 void
299 SonyEviD100PControl::reset_pan_tilt_limit()
300 {
301  visca->resetPanTiltLimit();
302 }
303 
304 void
305 SonyEviD100PControl::reset_zoom()
306 {
307  visca->resetZoom();
308 }
309 
310 void
311 SonyEviD100PControl::set_zoom(unsigned int zoom)
312 {
313  visca->setZoom(zoom);
314 }
315 
316 unsigned int
317 SonyEviD100PControl::zoom()
318 {
319  unsigned int zoom;
320  visca->getZoom(&zoom);
321  return zoom;
322 }
323 
324 unsigned int
325 SonyEviD100PControl::zoom_min()
326 {
327  return 0;
328 }
329 
330 unsigned int
331 SonyEviD100PControl::zoom_max()
332 {
333  return 0x4000;
334 }
335 
336 void
337 SonyEviD100PControl::set_zoom_speed_tele(unsigned int speed)
338 {
339  visca->setZoomSpeedTele(speed);
340 }
341 
342 void
343 SonyEviD100PControl::set_zoom_speed_wide(unsigned int speed)
344 {
345  visca->setZoomSpeedWide(speed);
346 }
347 
348 void
349 SonyEviD100PControl::set_zoom_digital_enabled(bool enabled)
350 {
351  visca->setZoomDigitalEnabled(enabled);
352 }
353 
354 bool
355 SonyEviD100PControl::supports_effect(unsigned int effect_)
356 {
357  if (effect_ == EFFECT_NONE) {
358  return true;
359  }
360 
361  switch (effect_) {
362  case EFFECT_PASTEL:
363  case EFFECT_NEGATIVE:
364  case EFFECT_SEPIA:
365  case EFFECT_BW:
366  case EFFECT_SOLARIZE:
367  case EFFECT_MOSAIC:
368  case EFFECT_SLIM:
369  case EFFECT_STRETCH: return true; break;
370  default: return false;
371  }
372 }
373 
374 void
375 SonyEviD100PControl::set_effect(unsigned int effect_)
376 {
377  this->_effect = effect_;
378  if (effect_ == EFFECT_NONE) {
379  visca->resetEffect();
380  }
381  switch (effect_) {
382  case EFFECT_PASTEL: visca->applyEffectPastel(); break;
383  case EFFECT_NEGATIVE: visca->applyEffectNegArt(); break;
384  case EFFECT_SEPIA: visca->applyEffectSepia(); break;
385  case EFFECT_BW: visca->applyEffectBnW(); break;
386  case EFFECT_SOLARIZE: visca->applyEffectSolarize(); break;
387  case EFFECT_MOSAIC: visca->applyEffectMosaic(); break;
388  case EFFECT_SLIM: visca->applyEffectSlim(); break;
389  case EFFECT_STRETCH: visca->applyEffectStretch(); break;
390  default: break;
391  }
392 }
393 
394 unsigned int
395 SonyEviD100PControl::effect()
396 {
397  return _effect;
398 }
399 
400 void
401 SonyEviD100PControl::reset_effect()
402 {
403  visca->resetEffect();
404 }
405 
406 /** Get current white balance mode.
407  * @return white balance mode
408  */
409 unsigned int
410 SonyEviD100PControl::white_balance_mode()
411 {
412  return visca->getWhiteBalanceMode();
413 }
414 
415 } // end namespace firevision
firevision::CameraArgumentParser::cam_id
std::string cam_id() const
Get camera ID.
Definition: camargp.cpp:133
firevision::ViscaControl
Visca control protocol implementation over a serial line.
Definition: visca.h:54
fawkes::Exception::append
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:333
fawkes
Fawkes library namespace.
fawkes::deg2rad
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Definition: angle.h:36
firevision::CameraArgumentParser
Camera argument parser.
Definition: camargp.h:36
firevision::ViscaControlException
Visca exception.
Definition: visca.h:41