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  * @return true on success
141  */
142 void
143 SonyEviD100PControl::open()
144 {
145  if (opened)
146  return;
147 
148  try {
149  visca->open(tty_port);
150  visca->set_address(1);
151  visca->clear();
152  } catch (ViscaControlException &e) {
153  visca->close();
154  e.append("Sony EviD100PControl failed");
155  throw;
156  }
157 
158  opened = true;
159 }
160 
161 /** Close Visca device.
162  */
163 void
164 SonyEviD100PControl::close()
165 {
166  if (!opened)
167  return;
168  visca->close();
169 }
170 
171 void
172 SonyEviD100PControl::process_pantilt()
173 {
174  visca->process();
175 }
176 
177 bool
178 SonyEviD100PControl::supports_pan()
179 {
180  return true;
181 }
182 
183 bool
184 SonyEviD100PControl::supports_tilt()
185 {
186  return true;
187 }
188 
189 void
190 SonyEviD100PControl::set_pan(int pan)
191 {
192  pan_target = pan;
193  visca->setPanTilt(pan, tilt_target);
194 }
195 
196 void
197 SonyEviD100PControl::set_tilt(int tilt)
198 {
199  tilt_target = tilt;
200  visca->setPanTilt(pan_target, tilt);
201 }
202 
203 void
204 SonyEviD100PControl::set_pan_tilt(int pan, int tilt)
205 {
206  pan_target = pan;
207  tilt_target = tilt;
208  visca->setPanTilt(pan, tilt);
209 }
210 
211 void
212 SonyEviD100PControl::set_pan_tilt_rad(float pan, float tilt)
213 {
214  int tpan = 0, ttilt = 0;
215 
216  tpan = (int)rint(pan * PAN_STEPS_PER_RAD);
217  ttilt = (int)rint(tilt * TILT_STEPS_PER_RAD);
218 
219  set_pan_tilt(tpan, ttilt);
220 }
221 
222 void
223 SonyEviD100PControl::start_get_pan_tilt()
224 {
225  visca->startGetPanTilt();
226 }
227 
228 void
229 SonyEviD100PControl::pan_tilt(int &pan, int &tilt)
230 {
231  int tpan, ttilt;
232  visca->getPanTilt(&tpan, &ttilt);
233  pan = tpan;
234  tilt = ttilt;
235 }
236 
237 void
238 SonyEviD100PControl::pan_tilt_rad(float &pan, float &tilt)
239 {
240  int tpan = 0, ttilt = 0;
241  visca->getPanTilt(&tpan, &ttilt);
242 
243  pan = tpan / PAN_STEPS_PER_RAD;
244  tilt = ttilt / PAN_STEPS_PER_RAD;
245 }
246 
247 int
248 SonyEviD100PControl::pan()
249 {
250  int pan = 0, tilt = 0;
251  visca->getPanTilt(&pan, &tilt);
252  return pan;
253 }
254 
255 int
256 SonyEviD100PControl::tilt()
257 {
258  int pan = 0, tilt = 0;
259  visca->getPanTilt(&pan, &tilt);
260  return tilt;
261 }
262 
263 int
264 SonyEviD100PControl::max_pan()
265 {
266  return MAX_PAN;
267 }
268 
269 int
270 SonyEviD100PControl::min_pan()
271 {
272  return MIN_PAN;
273 }
274 
275 int
276 SonyEviD100PControl::max_tilt()
277 {
278  return MAX_TILT;
279 }
280 
281 int
282 SonyEviD100PControl::min_tilt()
283 {
284  return MIN_TILT;
285 }
286 
287 void
288 SonyEviD100PControl::reset_pan_tilt()
289 {
290  visca->resetPanTilt();
291 }
292 
293 void
294 SonyEviD100PControl::set_pan_tilt_limit(int pan_left, int pan_right, int tilt_up, int tilt_down)
295 {
296  visca->setPanTiltLimit(pan_left, pan_right, tilt_up, tilt_down);
297 }
298 
299 void
300 SonyEviD100PControl::reset_pan_tilt_limit()
301 {
302  visca->resetPanTiltLimit();
303 }
304 
305 void
306 SonyEviD100PControl::reset_zoom()
307 {
308  visca->resetZoom();
309 }
310 
311 void
312 SonyEviD100PControl::set_zoom(unsigned int zoom)
313 {
314  visca->setZoom(zoom);
315 }
316 
317 unsigned int
318 SonyEviD100PControl::zoom()
319 {
320  unsigned int zoom;
321  visca->getZoom(&zoom);
322  return zoom;
323 }
324 
325 unsigned int
326 SonyEviD100PControl::zoom_min()
327 {
328  return 0;
329 }
330 
331 unsigned int
332 SonyEviD100PControl::zoom_max()
333 {
334  return 0x4000;
335 }
336 
337 void
338 SonyEviD100PControl::set_zoom_speed_tele(unsigned int speed)
339 {
340  visca->setZoomSpeedTele(speed);
341 }
342 
343 void
344 SonyEviD100PControl::set_zoom_speed_wide(unsigned int speed)
345 {
346  visca->setZoomSpeedWide(speed);
347 }
348 
349 void
350 SonyEviD100PControl::set_zoom_digital_enabled(bool enabled)
351 {
352  visca->setZoomDigitalEnabled(enabled);
353 }
354 
355 bool
356 SonyEviD100PControl::supports_effect(unsigned int effect_)
357 {
358  if (effect_ == EFFECT_NONE) {
359  return true;
360  }
361 
362  switch (effect_) {
363  case EFFECT_PASTEL:
364  case EFFECT_NEGATIVE:
365  case EFFECT_SEPIA:
366  case EFFECT_BW:
367  case EFFECT_SOLARIZE:
368  case EFFECT_MOSAIC:
369  case EFFECT_SLIM:
370  case EFFECT_STRETCH: return true; break;
371  default: return false;
372  }
373 }
374 
375 void
376 SonyEviD100PControl::set_effect(unsigned int effect_)
377 {
378  this->_effect = effect_;
379  if (effect_ == EFFECT_NONE) {
380  visca->resetEffect();
381  }
382  switch (effect_) {
383  case EFFECT_PASTEL: visca->applyEffectPastel(); break;
384  case EFFECT_NEGATIVE: visca->applyEffectNegArt(); break;
385  case EFFECT_SEPIA: visca->applyEffectSepia(); break;
386  case EFFECT_BW: visca->applyEffectBnW(); break;
387  case EFFECT_SOLARIZE: visca->applyEffectSolarize(); break;
388  case EFFECT_MOSAIC: visca->applyEffectMosaic(); break;
389  case EFFECT_SLIM: visca->applyEffectSlim(); break;
390  case EFFECT_STRETCH: visca->applyEffectStretch(); break;
391  default: break;
392  }
393 }
394 
395 unsigned int
396 SonyEviD100PControl::effect()
397 {
398  return _effect;
399 }
400 
401 void
402 SonyEviD100PControl::reset_effect()
403 {
404  visca->resetEffect();
405 }
406 
407 /** Get current white balance mode.
408  * @return white balance mode
409  */
410 unsigned int
411 SonyEviD100PControl::white_balance_mode()
412 {
413  return visca->getWhiteBalanceMode();
414 }
415 
416 } // end namespace firevision
firevision::CameraArgumentParser::cam_id
std::string cam_id() const
Get camera ID.
Definition: camargp.cpp:132
firevision::ViscaControl
Definition: visca.h:57
fawkes::Exception::append
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:332
fawkes
fawkes::deg2rad
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Definition: angle.h:40
firevision::CameraArgumentParser
Definition: camargp.h:39
firevision::ViscaControlException
Definition: visca.h:44