featuresstereo.cpp
Go to the documentation of this file.
1 /* $Id: features.cpp 35412 2011-01-23 17:49:15Z joq $ */
2 
3 /*********************************************************************
4 * Software License Agreement (BSD License)
5 *
6 * Copyright (c) 2010 Jack O'Quin
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of the author nor other contributors may be
20 * used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *********************************************************************/
36 
37 #include <cmath>
38 #include "featuresstereo.h"
39 #include "trigger.h"
40 
49 // static data and functions:
52 namespace
53 {
54  // driver feature parameter names, corresponding to DC1394 modes
55  // (not all currently supported by the driver)
56  static const char *feature_names_[DC1394_FEATURE_NUM] =
57  {
58  "brightness",
59  "exposure",
60  "sharpness",
61  "whitebalance",
62  "hue",
63  "saturation",
64  "gamma",
65  "shutter",
66  "gain",
67  "iris",
68  "focus",
69  "temperature",
70  "trigger",
71  "trigger_delay",
72  "white_shading",
73  "frame_rate",
74  "zoom",
75  "pan",
76  "tilt",
77  "optical_filter",
78  "capture_size",
79  "capture_quality"
80  };
81 
87  inline const char *featureName(dc1394feature_t feature)
88  {
89  if (feature >= DC1394_FEATURE_MIN && feature <= DC1394_FEATURE_MAX)
90  return feature_names_[feature - DC1394_FEATURE_MIN];
91  else
92  return "(unknown)";
93  }
94 
95  // driver mode parameter names, corresponding to DC1394 modes
96  static const char *mode_names_[DC1394_FEATURE_MODE_NUM] =
97  {
98  "Manual",
99  "Auto",
100  "OnePush",
101  };
102 
108  inline const char *modeName(dc1394feature_mode_t mode)
109  {
110  if (mode >= DC1394_FEATURE_MODE_MIN && mode <= DC1394_FEATURE_MODE_MAX)
111  return mode_names_[mode - DC1394_FEATURE_MODE_MIN];
112  else
113  return "(unknown)";
114  }
115 }
116 
118 // public methods:
120 
125 Features::Features(dc1394camera_t *camera):
126  camera_(camera)
127 {
128  trigger_.reset(new Trigger(camera));
129 }
130 
140 bool Features::initialize(Config *newconfig)
141 {
142  bool retval = true;
143  // query all features for this device
144  if (DC1394_SUCCESS != dc1394_feature_get_all(camera_, &feature_set_))
145  {
146  ROS_ERROR("could not get camera feature information");
147  return false;
148  }
149 
150  // validate and set configured value of each supported feature
151  configure(DC1394_FEATURE_BRIGHTNESS,
152  &newconfig->auto_brightness, &newconfig->brightness);
153  configure(DC1394_FEATURE_EXPOSURE,
154  &newconfig->auto_exposure, &newconfig->exposure);
155  configure(DC1394_FEATURE_FOCUS,
156  &newconfig->auto_focus, &newconfig->focus);
157  configure(DC1394_FEATURE_GAIN,
158  &newconfig->auto_gain, &newconfig->gain);
159  configure(DC1394_FEATURE_GAMMA,
160  &newconfig->auto_gamma, &newconfig->gamma);
161  configure(DC1394_FEATURE_HUE,
162  &newconfig->auto_hue, &newconfig->hue);
163  configure(DC1394_FEATURE_IRIS,
164  &newconfig->auto_iris, &newconfig->iris);
165  configure(DC1394_FEATURE_SATURATION,
166  &newconfig->auto_saturation, &newconfig->saturation);
167  configure(DC1394_FEATURE_SHARPNESS,
168  &newconfig->auto_sharpness, &newconfig->sharpness);
169  configure(DC1394_FEATURE_SHUTTER,
170  &newconfig->auto_shutter, &newconfig->shutter);
171  configure(DC1394_FEATURE_TRIGGER,
172  &newconfig->auto_trigger, &newconfig->trigger);
173  configure(DC1394_FEATURE_PAN,
174  &newconfig->auto_pan, &newconfig->pan);
175  configure(DC1394_FEATURE_FRAME_RATE,
176  &newconfig->auto_frame_rate_feature, &newconfig->frame_rate_feature);
177  configure(DC1394_FEATURE_WHITE_BALANCE, &newconfig->auto_white_balance,
178  &newconfig->white_balance_BU, &newconfig->white_balance_RV);
179  configure(DC1394_FEATURE_ZOOM,
180  &newconfig->auto_zoom, &newconfig->zoom);
181 
182  // set up trigger class, if supported by this camera
183  if (hasTrigger())
184  retval = trigger_->initialize(newconfig);
185 
186  // save configured values
187  oldconfig_ = *newconfig;
188  return retval;
189 }
190 
204 {
205  updateIfChanged(DC1394_FEATURE_BRIGHTNESS,
206  oldconfig_.auto_brightness, &newconfig->auto_brightness,
207  oldconfig_.brightness, &newconfig->brightness);
208  updateIfChanged(DC1394_FEATURE_EXPOSURE,
209  oldconfig_.auto_exposure, &newconfig->auto_exposure,
210  oldconfig_.exposure, &newconfig->exposure);
211  updateIfChanged(DC1394_FEATURE_FOCUS,
212  oldconfig_.auto_focus, &newconfig->auto_focus,
213  oldconfig_.focus, &newconfig->focus);
214  updateIfChanged(DC1394_FEATURE_GAIN,
215  oldconfig_.auto_gain, &newconfig->auto_gain,
216  oldconfig_.gain, &newconfig->gain);
217  updateIfChanged(DC1394_FEATURE_GAMMA,
218  oldconfig_.auto_gamma, &newconfig->auto_gamma,
219  oldconfig_.gamma, &newconfig->gamma);
220  updateIfChanged(DC1394_FEATURE_HUE,
221  oldconfig_.auto_hue, &newconfig->auto_hue,
222  oldconfig_.hue, &newconfig->hue);
223  updateIfChanged(DC1394_FEATURE_IRIS,
224  oldconfig_.auto_iris, &newconfig->auto_iris,
225  oldconfig_.iris, &newconfig->iris);
226  updateIfChanged(DC1394_FEATURE_SATURATION,
227  oldconfig_.auto_saturation, &newconfig->auto_saturation,
228  oldconfig_.saturation, &newconfig->saturation);
229  updateIfChanged(DC1394_FEATURE_SHARPNESS,
230  oldconfig_.auto_sharpness, &newconfig->auto_sharpness,
231  oldconfig_.sharpness, &newconfig->sharpness);
232  updateIfChanged(DC1394_FEATURE_SHUTTER,
233  oldconfig_.auto_shutter, &newconfig->auto_shutter,
234  oldconfig_.shutter, &newconfig->shutter);
235  updateIfChanged(DC1394_FEATURE_PAN,
236  oldconfig_.auto_pan, &newconfig->auto_pan,
237  oldconfig_.pan, &newconfig->pan);
238  updateIfChanged(DC1394_FEATURE_FRAME_RATE,
239  oldconfig_.auto_frame_rate_feature, &newconfig->auto_frame_rate_feature,
240  oldconfig_.frame_rate_feature, &newconfig->frame_rate_feature);
241  updateIfChanged(DC1394_FEATURE_TRIGGER,
242  oldconfig_.auto_trigger, &newconfig->auto_trigger,
243  oldconfig_.trigger, &newconfig->trigger);
244 
245  // White balance has two component parameters: Blue/U and Red/V.
246  updateIfChanged(DC1394_FEATURE_WHITE_BALANCE,
247  oldconfig_.auto_white_balance,
248  &newconfig->auto_white_balance,
249  oldconfig_.white_balance_BU, &newconfig->white_balance_BU,
250  oldconfig_.white_balance_RV, &newconfig->white_balance_RV);
251  updateIfChanged(DC1394_FEATURE_ZOOM,
252  oldconfig_.auto_zoom, &newconfig->auto_zoom,
253  oldconfig_.zoom, &newconfig->zoom);
254 
255  // reconfigure trigger class, if supported by this camera
256  if (hasTrigger())
257  trigger_->reconfigure(newconfig);
258 
259  // save modified values
260  oldconfig_ = *newconfig;
261 }
262 
264 // private methods:
266 
285 void Features::configure(dc1394feature_t feature, int *control,
286  double *value, double *value2)
287 {
288  // device-relevant information for this feature
289  dc1394feature_info_t *finfo =
290  &feature_set_.feature[feature - DC1394_FEATURE_MIN];
291 
292  if (!finfo->available) // feature not available?
293  {
294  *control = camera1394stereo::Camera1394Stereo_None;
295  return;
296  }
297 
298  switch (*control)
299  {
300  case camera1394stereo::Camera1394Stereo_Off:
301  setOff(finfo);
302  break;
303 
304  case camera1394stereo::Camera1394Stereo_Query:
305  getValues(finfo, value, value2);
306  break;
307 
308  case camera1394stereo::Camera1394Stereo_Auto:
309  if (!setMode(finfo, DC1394_FEATURE_MODE_AUTO))
310  {
311  setOff(finfo);
312  }
313  break;
314 
315  case camera1394stereo::Camera1394Stereo_Manual:
316  if (!setMode(finfo, DC1394_FEATURE_MODE_MANUAL))
317  {
318  setOff(finfo);
319  break;
320  }
321 
322  // TODO: break this into some internal methods
323  if (finfo->absolute_capable && finfo->abs_control)
324  {
325  // supports reading and setting float value
326  float fmin, fmax;
327  if (DC1394_SUCCESS ==
328  dc1394_feature_get_absolute_boundaries(camera_, feature,
329  &fmin, &fmax))
330  {
331  // clamp *value between minimum and maximum
332  if (*value < fmin)
333  *value = (double) fmin;
334  else if (*value > fmax)
335  *value = (double) fmax;
336  }
337  else
338  {
339  ROS_WARN_STREAM("failed to get feature "
340  << featureName(feature) << " boundaries ");
341  }
342 
343  // @todo handle absolute White Balance values
344  float fval = *value;
345  if (DC1394_SUCCESS !=
346  dc1394_feature_set_absolute_value(camera_, feature, fval))
347  {
348  ROS_WARN_STREAM("failed to set feature "
349  << featureName(feature) << " to " << fval);
350  }
351  }
352  else // no float representation
353  {
354  // round requested value to nearest integer
355  *value = rint(*value);
356 
357  // clamp *value between minimum and maximum
358  if (*value < finfo->min)
359  *value = (double) finfo->min;
360  else if (*value > finfo->max)
361  *value = (double) finfo->max;
362 
363  dc1394error_t rc;
364  uint32_t ival = (uint32_t) *value;
365 
366  // handle White Balance, which has two components
367  if (feature == DC1394_FEATURE_WHITE_BALANCE)
368  {
369  *value2 = rint(*value2);
370 
371  // clamp *value2 between same minimum and maximum
372  if (*value2 < finfo->min)
373  *value2 = (double) finfo->min;
374  else if (*value2 > finfo->max)
375  *value2 = (double) finfo->max;
376 
377  uint32_t ival2 = (uint32_t) *value2;
378  rc = dc1394_feature_whitebalance_set_value(camera_, ival, ival2);
379  }
380  else
381  {
382  // other features only have one component
383  rc = dc1394_feature_set_value(camera_, feature, ival);
384  }
385  if (rc != DC1394_SUCCESS)
386  {
387  ROS_WARN_STREAM("failed to set feature "
388  << featureName(feature) << " to " << ival);
389  }
390  }
391  break;
392 
393  case camera1394stereo::Camera1394Stereo_OnePush:
394  // Try to set OnePush mode
395  setMode(finfo, DC1394_FEATURE_MODE_ONE_PUSH_AUTO);
396 
397  // Now turn the control off, so camera does not continue adjusting
398  setOff(finfo);
399  break;
400 
401  case camera1394stereo::Camera1394Stereo_None:
402  // Invalid user input, because this feature actually does exist.
403  ROS_INFO_STREAM("feature " << featureName(feature)
404  << " exists, cannot set to None");
405  break;
406 
407  default:
408  ROS_WARN_STREAM("unknown state (" << *control
409  <<") for feature " << featureName(feature));
410  }
411 
412  // return actual state reported by the device
413  *control = getState(finfo);
414  ROS_DEBUG_STREAM("feature " << featureName(feature)
415  << " now in state " << *control);
416 }
417 
425 Features::state_t Features::getState(dc1394feature_info_t *finfo)
426 {
427  dc1394feature_t feature = finfo->id;
428  dc1394error_t rc;
429 
430  if (!finfo->available)
431  {
432  // not available: nothing more to do
433  return camera1394stereo::Camera1394Stereo_None;
434  }
435 
436  if (finfo->on_off_capable)
437  {
438  // get On/Off state
439  dc1394switch_t pwr;
440  rc = dc1394_feature_get_power(camera_, feature, &pwr);
441  if (rc != DC1394_SUCCESS)
442  {
443  ROS_WARN_STREAM("failed to get feature " << featureName(feature)
444  << " Power setting ");
445  }
446  else if (pwr == DC1394_OFF)
447  {
448  // Off overrides mode settings
449  return camera1394stereo::Camera1394Stereo_Off;
450  }
451  }
452 
453  // not off, so get mode
454  dc1394feature_mode_t mode;
455  rc = dc1394_feature_get_mode(camera_, feature, &mode);
456  if (rc != DC1394_SUCCESS)
457  {
458  ROS_WARN_STREAM("failed to get current mode of feature "
459  << featureName(feature));
460  // treat unavailable mode as Off
461  return camera1394stereo::Camera1394Stereo_Off;
462  }
463 
464  switch (mode)
465  {
466  case DC1394_FEATURE_MODE_MANUAL:
467  return camera1394stereo::Camera1394Stereo_Manual;
468  case DC1394_FEATURE_MODE_AUTO:
469  return camera1394stereo::Camera1394Stereo_Auto;
470  case DC1394_FEATURE_MODE_ONE_PUSH_AUTO:
471  return camera1394stereo::Camera1394Stereo_OnePush;
472  default:
473  return camera1394stereo::Camera1394Stereo_Off;
474  }
475 }
476 
486 void Features::getValues(dc1394feature_info_t *finfo,
487  double *value, double *value2)
488 {
489  dc1394feature_t feature = finfo->id;
490  dc1394error_t rc;
491 
492  if (!finfo->readout_capable)
493  {
494  ROS_INFO_STREAM("feature " << featureName(feature)
495  << " value not available from device");
496  return;
497  }
498 
499  if (feature == DC1394_FEATURE_WHITE_BALANCE)
500  {
501  // handle White Balance separately, it has two components
502  if (finfo->absolute_capable && finfo->abs_control)
503  {
504  // supports reading and setting float value
505  // @todo get absolute White Balance values
506  rc = DC1394_FUNCTION_NOT_SUPPORTED;
507  }
508  else
509  {
510  // get integer White Balance values
511  uint32_t bu_val;
512  uint32_t rv_val;
513  rc = dc1394_feature_whitebalance_get_value(camera_, &bu_val, &rv_val);
514  if (DC1394_SUCCESS == rc)
515  {
516  // convert to double
517  *value = bu_val;
518  *value2 = rv_val;
519  }
520  }
521  if (DC1394_SUCCESS == rc)
522  {
523  ROS_DEBUG_STREAM("feature " << featureName(feature)
524  << " Blue/U: " << *value
525  << " Red/V: " << *value2);
526  }
527  else
528  {
529  ROS_WARN_STREAM("failed to get values for feature "
530  << featureName(feature));
531  }
532  }
533  else
534  {
535  // other features only have one component
536  if (finfo->absolute_capable && finfo->abs_control)
537  {
538  // supports reading and setting float value
539  float fval;
540  rc = dc1394_feature_get_absolute_value(camera_, feature, &fval);
541  if (DC1394_SUCCESS == rc)
542  {
543  *value = fval; // convert to double
544  }
545  }
546  else // no float representation
547  {
548  uint32_t ival;
549  rc = dc1394_feature_get_value(camera_, feature, &ival);
550  if (DC1394_SUCCESS == rc)
551  {
552  *value = ival; // convert to double
553  }
554  }
555  if (DC1394_SUCCESS == rc)
556  {
557  ROS_DEBUG_STREAM("feature " << featureName(feature)
558  << " has value " << *value);
559  }
560  else
561  {
562  ROS_WARN_STREAM("failed to get value of feature "
563  << featureName(feature));
564  }
565  }
566 }
567 
576 bool Features::setMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
577 {
578  dc1394feature_t feature = finfo->id;
579  if (hasMode(finfo, mode))
580  {
581  ROS_DEBUG_STREAM("setting feature " << featureName(feature)
582  << " mode to " << modeName(mode));
583  if (DC1394_SUCCESS !=
584  dc1394_feature_set_mode(camera_, feature, mode))
585  {
586  ROS_WARN_STREAM("failed to set feature " << featureName(feature)
587  << " mode to " << modeName(mode));
588  return false;
589  }
590  }
591  else
592  {
593  // device does not support this mode for this feature
594  ROS_DEBUG_STREAM("no " << modeName(mode)
595  << " mode for feature " << featureName(feature));
596  return false;
597  }
598  return true;
599 }
600 
607 void Features::setOff(dc1394feature_info_t *finfo)
608 {
609  dc1394feature_t feature = finfo->id;
610  if (finfo->on_off_capable)
611  {
612  ROS_DEBUG_STREAM("setting feature " << featureName(feature) << " Off");
613  if (DC1394_SUCCESS !=
614  dc1394_feature_set_power(camera_, feature, DC1394_OFF))
615  {
616  ROS_WARN_STREAM("failed to set feature " << featureName(feature)
617  << " Off ");
618  }
619  }
620  else
621  {
622  // This device does not support turning this feature off.
623  // Inform the user, but pretend it worked.
624  ROS_DEBUG_STREAM("no Off mode for feature " << featureName(feature));
625  }
626 }
627 
642 void Features::updateIfChanged(dc1394feature_t feature,
643  int old_control, int *control,
644  double old_value, double *value)
645 {
646  if ((old_control != *control) || (old_value != *value))
647  {
648  configure(feature, control, value);
649  }
650 }
651 
669 void Features::updateIfChanged(dc1394feature_t feature,
670  int old_control, int *control,
671  double old_value, double *value,
672  double old_value2, double *value2)
673 {
674  if ((old_control != *control)
675  || (old_value != *value)
676  || (old_value2 != *value2))
677  {
678  configure(feature, control, value, value2);
679  }
680 }
boost::shared_ptr< Trigger > trigger_
state_t getState(dc1394feature_info_t *finfo)
dc1394featureset_t feature_set_
that camera&#39;s feature set
camera1394stereo::Camera1394StereoConfig Config
dc1394camera_t * camera_
current camera
void reconfigure(Config *newconfig)
void updateIfChanged(dc1394feature_t feature, int old_control, int *control, double old_value, double *value)
bool setMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
void getValues(dc1394feature_info_t *finfo, double *value, double *value2)
void configure(dc1394feature_t feature, int *control, double *value, double *value2=NULL)
Camera1394 features interface.
bool initialize(Config *newconfig)
bool hasMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
libdc1394 triggering modes interface
bool hasTrigger(void)
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
Features(dc1394camera_t *camera)
void setOff(dc1394feature_info_t *finfo)
int state_t
camera1394::Camera1394_* state values
#define ROS_INFO_STREAM(args)
int min(int a, int b)
Config oldconfig_
previous Config settings
#define ROS_ERROR(...)


camera1394stereo
Author(s): Joan Pau Beltran
autogenerated on Mon Jun 10 2019 12:52:45