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 
28 #include <utils/math/angle.h>
29 
30 #include <termios.h>
31 #include <cstring>
32 #include <cstdlib>
33 
34 using namespace std;
35 using namespace fawkes;
36 
37 namespace firevision {
38 #if 0 /* just to make Emacs auto-indent happy */
39 }
40 #endif
41 
42 /** Maximum pan. */
43 const int SonyEviD100PControl::MAX_PAN = 1440;
44 /** Minimum pan. */
45 const int SonyEviD100PControl::MIN_PAN = -1439;
46 /** Max Tilt. */
47 const int SonyEviD100PControl::MAX_TILT = 360;
48 /** Min tilt .*/
49 const int SonyEviD100PControl::MIN_TILT = - 359;
50 
51 /** Max pan in degrees. */
52 const float SonyEviD100PControl::MAX_PAN_DEG = 100.f;
53 /** Min pan in degrees. */
54 const float SonyEviD100PControl::MIN_PAN_DEG = -100.f;
55 /** Max tilt in degrees. */
56 const float SonyEviD100PControl::MAX_TILT_DEG = 25.f;
57 /** Min tilt in degrees. */
58 const float SonyEviD100PControl::MIN_TILT_DEG = - 25.f;
59 
60 /** Max pan in rad. */
61 const float SonyEviD100PControl::MAX_PAN_RAD = deg2rad(MAX_PAN_DEG);
62 /** Min pan in rad. */
63 const float SonyEviD100PControl::MIN_PAN_RAD = deg2rad(MIN_PAN_DEG);
64 /** Max tilt in rad. */
65 const float SonyEviD100PControl::MAX_TILT_RAD = deg2rad(MAX_TILT_DEG);
66 /** Min tilt in rad. */
67 const float SonyEviD100PControl::MIN_TILT_RAD = deg2rad(MIN_TILT_DEG);
68 
69 /** Pan steps per degree */
70 const float SonyEviD100PControl::PAN_STEPS_PER_DEG = MAX_PAN / MAX_PAN_DEG;
71 /** Tilt steps per degree */
72 const float SonyEviD100PControl::TILT_STEPS_PER_DEG = MAX_TILT / MAX_TILT_DEG;
73 
74 /** Pan steps per rad */
75 const float SonyEviD100PControl::PAN_STEPS_PER_RAD = MAX_PAN / MAX_PAN_RAD;
76 /** Tilt steps per rad */
77 const float SonyEviD100PControl::TILT_STEPS_PER_RAD = MAX_TILT / MAX_TILT_RAD;
78 
79 /** Pastel effect. */
80 const unsigned int SonyEviD100PControl::EFFECT_PASTEL = 1;
81 /** Negative effect. */
82 const unsigned int SonyEviD100PControl::EFFECT_NEGATIVE = 2;
83 /** Sepia effect. */
84 const unsigned int SonyEviD100PControl::EFFECT_SEPIA = 3;
85 /** B/W effect. */
86 const unsigned int SonyEviD100PControl::EFFECT_BW = 4;
87 /** Solarize effect. */
88 const unsigned int SonyEviD100PControl::EFFECT_SOLARIZE = 5;
89 /** Mosaic effect. */
90 const unsigned int SonyEviD100PControl::EFFECT_MOSAIC = 6;
91 /** Slim effect. */
92 const unsigned int SonyEviD100PControl::EFFECT_SLIM = 7;
93 /** Stretch effect. */
94 const unsigned int SonyEviD100PControl::EFFECT_STRETCH = 8;
95 
96 
97 /** @class SonyEviD100PControl <fvcams/control/sony_evid100p.h>
98  * Sony Evi D100P pan/tilt control.
99  * Internally uses Visca.
100  * @author Tim Niemueller
101  */
102 
103 
104 /** Constructor.
105  * @param tty_port serial port (e.g. /dev/ttyS0)
106  */
107 SonyEviD100PControl::SonyEviD100PControl(const char *tty_port)
108 {
109  this->tty_port = strdup(tty_port);
110  visca = new ViscaControl( /* non-blocking */ false );
111  opened = false;
112  pan_target = 0;
113  tilt_target = 0;
114  _effect = EFFECT_NONE;
115 
116  open();
117 }
118 
119 
120 /** Constructor.
121  * Uses camera argument parser to gather arguments. The ID that the camera argument
122  * parser returns is used as the serial port (like /dev/ttyS0).
123  * @param cap camera argument parser
124  */
125 SonyEviD100PControl::SonyEviD100PControl(const CameraArgumentParser *cap)
126 {
127  tty_port = strdup(cap->cam_id().c_str());
128 
129  visca = new ViscaControl( /* non-blocking */ false );
130  opened = false;
131  pan_target = 0;
132  tilt_target = 0;
133  _effect = EFFECT_NONE;
134 
135  open();
136 }
137 
138 
139 /** Destructor. */
140 SonyEviD100PControl::~SonyEviD100PControl()
141 {
142  close();
143  delete visca;
144  free(tty_port);
145 }
146 
147 
148 /** Open visca device.
149  * @return true on success
150  */
151 void
152 SonyEviD100PControl::open()
153 {
154  if (opened) return;
155 
156  try {
157  visca->open(tty_port);
158  visca->set_address(1);
159  visca->clear();
160  } catch (ViscaControlException &e) {
161  visca->close();
162  e.append("Sony EviD100PControl failed");
163  throw;
164  }
165 
166  opened = true;
167 }
168 
169 
170 /** Close Visca device.
171  */
172 void
173 SonyEviD100PControl::close()
174 {
175  if ( ! opened ) return;
176  visca->close();
177 }
178 
179 
180 void
181 SonyEviD100PControl::process_pantilt()
182 {
183  visca->process();
184 }
185 
186 
187 bool
188 SonyEviD100PControl::supports_pan()
189 {
190  return true;
191 }
192 
193 
194 bool
195 SonyEviD100PControl::supports_tilt()
196 {
197  return true;
198 }
199 
200 
201 void
202 SonyEviD100PControl::set_pan(int pan)
203 {
204  pan_target = pan;
205  visca->setPanTilt(pan, tilt_target);
206 }
207 
208 
209 void
210 SonyEviD100PControl::set_tilt(int tilt)
211 {
212  tilt_target = tilt;
213  visca->setPanTilt(pan_target, tilt);
214 }
215 
216 
217 void
218 SonyEviD100PControl::set_pan_tilt(int pan, int tilt)
219 {
220  pan_target = pan;
221  tilt_target = tilt;
222  visca->setPanTilt(pan, tilt);
223 }
224 
225 
226 void
227 SonyEviD100PControl::set_pan_tilt_rad(float pan, float tilt)
228 {
229  int tpan = 0, ttilt = 0;
230 
231  tpan = (int)rint( pan * PAN_STEPS_PER_RAD );
232  ttilt = (int)rint( tilt * TILT_STEPS_PER_RAD );
233 
234  set_pan_tilt(tpan, ttilt);
235 }
236 
237 
238 void
239 SonyEviD100PControl::start_get_pan_tilt()
240 {
241  visca->startGetPanTilt();
242 }
243 
244 
245 void
246 SonyEviD100PControl::pan_tilt(int &pan, int &tilt)
247 {
248  int tpan, ttilt;
249  visca->getPanTilt(&tpan, &ttilt);
250  pan = tpan;
251  tilt = ttilt;
252 }
253 
254 
255 void
256 SonyEviD100PControl::pan_tilt_rad(float &pan, float &tilt)
257 {
258  int tpan = 0, ttilt = 0;
259  visca->getPanTilt(&tpan, &ttilt);
260 
261  pan = tpan / PAN_STEPS_PER_RAD;
262  tilt = ttilt / PAN_STEPS_PER_RAD;
263 }
264 
265 
266 int
267 SonyEviD100PControl::pan()
268 {
269  int pan = 0, tilt = 0;
270  visca->getPanTilt(&pan, &tilt);
271  return pan;
272 }
273 
274 
275 int
276 SonyEviD100PControl::tilt()
277 {
278  int pan = 0, tilt = 0;
279  visca->getPanTilt(&pan, &tilt);
280  return tilt;
281 }
282 
283 
284 int
285 SonyEviD100PControl::max_pan()
286 {
287  return MAX_PAN;
288 }
289 
290 
291 int
292 SonyEviD100PControl::min_pan()
293 {
294  return MIN_PAN;
295 }
296 
297 
298 int
299 SonyEviD100PControl::max_tilt()
300 {
301  return MAX_TILT;
302 }
303 
304 
305 int
306 SonyEviD100PControl::min_tilt()
307 {
308  return MIN_TILT;
309 }
310 
311 
312 void
313 SonyEviD100PControl::reset_pan_tilt()
314 {
315  visca->resetPanTilt();
316 }
317 
318 
319 void
320 SonyEviD100PControl::set_pan_tilt_limit(int pan_left, int pan_right,
321  int tilt_up, int tilt_down)
322 {
323  visca->setPanTiltLimit(pan_left, pan_right, tilt_up, tilt_down);
324 }
325 
326 
327 void
328 SonyEviD100PControl::reset_pan_tilt_limit()
329 {
330  visca->resetPanTiltLimit();
331 }
332 
333 
334 void
335 SonyEviD100PControl::reset_zoom()
336 {
337  visca->resetZoom();
338 }
339 
340 
341 void
342 SonyEviD100PControl::set_zoom(unsigned int zoom)
343 {
344  visca->setZoom(zoom);
345 }
346 
347 
348 unsigned int
349 SonyEviD100PControl::zoom()
350 {
351  unsigned int zoom;
352  visca->getZoom(&zoom);
353  return zoom;
354 }
355 
356 
357 unsigned int
358 SonyEviD100PControl::zoom_min()
359 {
360  return 0;
361 }
362 
363 
364 unsigned int
365 SonyEviD100PControl::zoom_max()
366 {
367  return 0x4000;
368 }
369 
370 
371 void
372 SonyEviD100PControl::set_zoom_speed_tele(unsigned int speed)
373 {
374  visca->setZoomSpeedTele(speed);
375 }
376 
377 
378 void
379 SonyEviD100PControl::set_zoom_speed_wide(unsigned int speed)
380 {
381  visca->setZoomSpeedWide(speed);
382 }
383 
384 
385 void
386 SonyEviD100PControl::set_zoom_digital_enabled(bool enabled)
387 {
388  visca->setZoomDigitalEnabled(enabled);
389 }
390 
391 
392 bool
393 SonyEviD100PControl::supports_effect(unsigned int __effect)
394 {
395  if ( __effect == EFFECT_NONE ) {
396  return true;
397  }
398 
399  switch (__effect) {
400  case EFFECT_PASTEL:
401  case EFFECT_NEGATIVE:
402  case EFFECT_SEPIA:
403  case EFFECT_BW:
404  case EFFECT_SOLARIZE:
405  case EFFECT_MOSAIC:
406  case EFFECT_SLIM:
407  case EFFECT_STRETCH:
408  return true;
409  break;
410  default:
411  return false;
412  }
413 }
414 
415 
416 void
417 SonyEviD100PControl::set_effect(unsigned int __effect)
418 {
419  this->_effect = __effect;
420  if ( __effect == EFFECT_NONE ) {
421  visca->resetEffect();
422  }
423  switch (__effect) {
424  case EFFECT_PASTEL:
425  visca->applyEffectPastel();
426  break;
427  case EFFECT_NEGATIVE:
428  visca->applyEffectNegArt();
429  break;
430  case EFFECT_SEPIA:
431  visca->applyEffectSepia();
432  break;
433  case EFFECT_BW:
434  visca->applyEffectBnW();
435  break;
436  case EFFECT_SOLARIZE:
437  visca->applyEffectSolarize();
438  break;
439  case EFFECT_MOSAIC:
440  visca->applyEffectMosaic();
441  break;
442  case EFFECT_SLIM:
443  visca->applyEffectSlim();
444  break;
445  case EFFECT_STRETCH:
446  visca->applyEffectStretch();
447  break;
448  default:
449  break;
450  }
451 
452 }
453 
454 
455 unsigned int
456 SonyEviD100PControl::effect()
457 {
458  return _effect;
459 }
460 
461 
462 void
463 SonyEviD100PControl::reset_effect()
464 {
465  visca->resetEffect();
466 }
467 
468 
469 /** Get current white balance mode.
470  * @return white balance mode
471  */
472 unsigned int
473 SonyEviD100PControl::white_balance_mode()
474 {
475  return visca->getWhiteBalanceMode();
476 }
477 
478 } // end namespace firevision
Fawkes library namespace.
STL namespace.
Camera argument parser.
Definition: camargp.h:38
std::string cam_id() const
Get camera ID.
Definition: camargp.cpp:139
Visca control protocol implementation over a serial line.
Definition: visca.h:56
Visca exception.
Definition: visca.h:42
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Definition: angle.h:37
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341