features.cpp
Go to the documentation of this file.
1 /* $Id$ */
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 "features.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 
144  // query all features for this device
145  if (DC1394_SUCCESS != dc1394_feature_get_all(camera_, &feature_set_))
146  {
147  ROS_ERROR("could not get camera feature information");
148  return false;
149  }
150 
151  // validate and set configured value of each supported feature
152  configure(DC1394_FEATURE_BRIGHTNESS,
153  &newconfig->auto_brightness, &newconfig->brightness);
154  configure(DC1394_FEATURE_EXPOSURE,
155  &newconfig->auto_exposure, &newconfig->exposure);
156  configure(DC1394_FEATURE_FOCUS,
157  &newconfig->auto_focus, &newconfig->focus);
158  configure(DC1394_FEATURE_GAIN,
159  &newconfig->auto_gain, &newconfig->gain);
160  configure(DC1394_FEATURE_GAMMA,
161  &newconfig->auto_gamma, &newconfig->gamma);
162  configure(DC1394_FEATURE_HUE,
163  &newconfig->auto_hue, &newconfig->hue);
164  configure(DC1394_FEATURE_IRIS,
165  &newconfig->auto_iris, &newconfig->iris);
166  configure(DC1394_FEATURE_PAN,
167  &newconfig->auto_pan, &newconfig->pan);
168  configure(DC1394_FEATURE_SATURATION,
169  &newconfig->auto_saturation, &newconfig->saturation);
170  configure(DC1394_FEATURE_SHARPNESS,
171  &newconfig->auto_sharpness, &newconfig->sharpness);
172  configure(DC1394_FEATURE_SHUTTER,
173  &newconfig->auto_shutter, &newconfig->shutter);
174  configure(DC1394_FEATURE_TRIGGER,
175  &newconfig->auto_trigger, &newconfig->trigger);
176  configure(DC1394_FEATURE_WHITE_BALANCE, &newconfig->auto_white_balance,
177  &newconfig->white_balance_BU, &newconfig->white_balance_RV);
178  configure(DC1394_FEATURE_ZOOM,
179  &newconfig->auto_zoom, &newconfig->zoom);
180 
181  // set up trigger class, if supported by this camera
182  if (hasTrigger())
183  retval = trigger_->initialize(newconfig);
184 
185  // save configured values
186  oldconfig_ = *newconfig;
187  return retval;
188 }
189 
203 {
204  updateIfChanged(DC1394_FEATURE_BRIGHTNESS,
205  oldconfig_.auto_brightness, &newconfig->auto_brightness,
206  oldconfig_.brightness, &newconfig->brightness);
207  updateIfChanged(DC1394_FEATURE_EXPOSURE,
208  oldconfig_.auto_exposure, &newconfig->auto_exposure,
209  oldconfig_.exposure, &newconfig->exposure);
210  updateIfChanged(DC1394_FEATURE_FOCUS,
211  oldconfig_.auto_focus, &newconfig->auto_focus,
212  oldconfig_.focus, &newconfig->focus);
213  updateIfChanged(DC1394_FEATURE_GAIN,
214  oldconfig_.auto_gain, &newconfig->auto_gain,
215  oldconfig_.gain, &newconfig->gain);
216  updateIfChanged(DC1394_FEATURE_GAMMA,
217  oldconfig_.auto_gamma, &newconfig->auto_gamma,
218  oldconfig_.gamma, &newconfig->gamma);
219  updateIfChanged(DC1394_FEATURE_HUE,
220  oldconfig_.auto_hue, &newconfig->auto_hue,
221  oldconfig_.hue, &newconfig->hue);
222  updateIfChanged(DC1394_FEATURE_IRIS,
223  oldconfig_.auto_iris, &newconfig->auto_iris,
224  oldconfig_.iris, &newconfig->iris);
225  updateIfChanged(DC1394_FEATURE_PAN,
226  oldconfig_.auto_pan, &newconfig->auto_pan,
227  oldconfig_.pan, &newconfig->pan);
228  updateIfChanged(DC1394_FEATURE_SATURATION,
229  oldconfig_.auto_saturation, &newconfig->auto_saturation,
230  oldconfig_.saturation, &newconfig->saturation);
231  updateIfChanged(DC1394_FEATURE_SHARPNESS,
232  oldconfig_.auto_sharpness, &newconfig->auto_sharpness,
233  oldconfig_.sharpness, &newconfig->sharpness);
234  updateIfChanged(DC1394_FEATURE_SHUTTER,
235  oldconfig_.auto_shutter, &newconfig->auto_shutter,
236  oldconfig_.shutter, &newconfig->shutter);
237  updateIfChanged(DC1394_FEATURE_TRIGGER,
238  oldconfig_.auto_trigger, &newconfig->auto_trigger,
239  oldconfig_.trigger, &newconfig->trigger);
240  // White balance has two component parameters: Blue/U and Red/V.
241  updateIfChanged(DC1394_FEATURE_WHITE_BALANCE,
242  oldconfig_.auto_white_balance,
243  &newconfig->auto_white_balance,
244  oldconfig_.white_balance_BU, &newconfig->white_balance_BU,
245  oldconfig_.white_balance_RV, &newconfig->white_balance_RV);
246  updateIfChanged(DC1394_FEATURE_ZOOM,
247  oldconfig_.auto_zoom, &newconfig->auto_zoom,
248  oldconfig_.zoom, &newconfig->zoom);
249 
250  // reconfigure trigger class, if supported by this camera
251  if (hasTrigger())
252  trigger_->reconfigure(newconfig);
253 
254  // save modified values
255  oldconfig_ = *newconfig;
256 }
257 
259 // private methods:
261 
280 void Features::configure(dc1394feature_t feature, int *control,
281  double *value, double *value2)
282 {
283  // device-relevant information for this feature
284  dc1394feature_info_t *finfo =
285  &feature_set_.feature[feature - DC1394_FEATURE_MIN];
286 
287  if (!finfo->available) // feature not available?
288  {
289  *control = camera1394::Camera1394_None;
290  return;
291  }
292 
293  switch (*control)
294  {
295  case camera1394::Camera1394_Off:
296  setPower(finfo, DC1394_OFF);
297  break;
298 
299  case camera1394::Camera1394_Query:
300  getValues(finfo, value, value2);
301  break;
302 
303  case camera1394::Camera1394_Auto:
304  if (!setMode(finfo, DC1394_FEATURE_MODE_AUTO))
305  {
306  setPower(finfo, DC1394_OFF);
307  }
308  break;
309 
310  case camera1394::Camera1394_Manual:
311  if (!setMode(finfo, DC1394_FEATURE_MODE_MANUAL))
312  {
313  setPower(finfo, DC1394_OFF);
314  break;
315  }
316 
317  // TODO: break this into some internal methods
318  if (finfo->absolute_capable && finfo->abs_control)
319  {
320  // supports reading and setting float value
321  float fmin, fmax;
322  if (DC1394_SUCCESS ==
323  dc1394_feature_get_absolute_boundaries(camera_, feature,
324  &fmin, &fmax))
325  {
326  // clamp *value between minimum and maximum
327  if (*value < fmin)
328  *value = (double) fmin;
329  else if (*value > fmax)
330  *value = (double) fmax;
331  }
332  else
333  {
334  ROS_WARN_STREAM("failed to get feature "
335  << featureName(feature) << " boundaries ");
336  }
337 
338  // @todo handle absolute White Balance values
339  float fval = *value;
340  if (DC1394_SUCCESS !=
341  dc1394_feature_set_absolute_value(camera_, feature, fval))
342  {
343  ROS_WARN_STREAM("failed to set feature "
344  << featureName(feature) << " to " << fval);
345  }
346  }
347  else // no float representation
348  {
349  // round requested value to nearest integer
350  *value = rint(*value);
351 
352  // clamp *value between minimum and maximum
353  if (*value < finfo->min)
354  *value = (double) finfo->min;
355  else if (*value > finfo->max)
356  *value = (double) finfo->max;
357 
358  dc1394error_t rc;
359  uint32_t ival = (uint32_t) *value;
360 
361  // handle White Balance, which has two components
362  if (feature == DC1394_FEATURE_WHITE_BALANCE)
363  {
364  *value2 = rint(*value2);
365 
366  // clamp *value2 between same minimum and maximum
367  if (*value2 < finfo->min)
368  *value2 = (double) finfo->min;
369  else if (*value2 > finfo->max)
370  *value2 = (double) finfo->max;
371 
372  uint32_t ival2 = (uint32_t) *value2;
373  rc = dc1394_feature_whitebalance_set_value(camera_, ival, ival2);
374  }
375  else
376  {
377  // other features only have one component
378  rc = dc1394_feature_set_value(camera_, feature, ival);
379  }
380  if (rc != DC1394_SUCCESS)
381  {
382  ROS_WARN_STREAM("failed to set feature "
383  << featureName(feature) << " to " << ival);
384  }
385  }
386  break;
387 
388  case camera1394::Camera1394_OnePush:
389  // Try to set OnePush mode
390  setMode(finfo, DC1394_FEATURE_MODE_ONE_PUSH_AUTO);
391 
392  // Now turn the control off, so camera does not continue adjusting
393  setPower(finfo, DC1394_OFF);
394  break;
395 
396  case camera1394::Camera1394_None:
397  // Invalid user input, because this feature actually does exist.
398  ROS_INFO_STREAM("feature " << featureName(feature)
399  << " exists, cannot set to None");
400  break;
401 
402  default:
403  ROS_WARN_STREAM("unknown state (" << *control
404  <<") for feature " << featureName(feature));
405  }
406 
407  // return actual state reported by the device
408  *control = getState(finfo);
409  ROS_DEBUG_STREAM("feature " << featureName(feature)
410  << " now in state " << *control);
411 }
412 
420 Features::state_t Features::getState(dc1394feature_info_t *finfo)
421 {
422  dc1394feature_t feature = finfo->id;
423  dc1394error_t rc;
424 
425  if (!finfo->available)
426  {
427  // not available: nothing more to do
428  return camera1394::Camera1394_None;
429  }
430 
431  if (finfo->on_off_capable)
432  {
433  // get On/Off state
434  dc1394switch_t pwr;
435  rc = dc1394_feature_get_power(camera_, feature, &pwr);
436  if (rc != DC1394_SUCCESS)
437  {
438  ROS_WARN_STREAM("failed to get feature " << featureName(feature)
439  << " Power setting ");
440  }
441  else if (pwr == DC1394_OFF)
442  {
443  // Off overrides mode settings
444  return camera1394::Camera1394_Off;
445  }
446  }
447 
448  // not off, so get mode
449  dc1394feature_mode_t mode;
450  rc = dc1394_feature_get_mode(camera_, feature, &mode);
451  if (rc != DC1394_SUCCESS)
452  {
453  ROS_WARN_STREAM("failed to get current mode of feature "
454  << featureName(feature));
455  // treat unavailable mode as Off
456  return camera1394::Camera1394_Off;
457  }
458 
459  switch (mode)
460  {
461  case DC1394_FEATURE_MODE_MANUAL:
462  return camera1394::Camera1394_Manual;
463  case DC1394_FEATURE_MODE_AUTO:
464  return camera1394::Camera1394_Auto;
465  case DC1394_FEATURE_MODE_ONE_PUSH_AUTO:
466  return camera1394::Camera1394_OnePush;
467  default:
468  return camera1394::Camera1394_Off;
469  }
470 }
471 
481 void Features::getValues(dc1394feature_info_t *finfo,
482  double *value, double *value2)
483 {
484  dc1394feature_t feature = finfo->id;
485  dc1394error_t rc;
486 
487  if (!finfo->readout_capable)
488  {
489  ROS_INFO_STREAM("feature " << featureName(feature)
490  << " value not available from device");
491  return;
492  }
493 
494  if (feature == DC1394_FEATURE_WHITE_BALANCE)
495  {
496  // handle White Balance separately, it has two components
497  if (finfo->absolute_capable && finfo->abs_control)
498  {
499  // supports reading and setting float value
500  // @todo get absolute White Balance values
501  rc = DC1394_FUNCTION_NOT_SUPPORTED;
502  }
503  else
504  {
505  // get integer White Balance values
506  uint32_t bu_val;
507  uint32_t rv_val;
508  rc = dc1394_feature_whitebalance_get_value(camera_, &bu_val, &rv_val);
509  if (DC1394_SUCCESS == rc)
510  {
511  // convert to double
512  *value = bu_val;
513  *value2 = rv_val;
514  }
515  }
516  if (DC1394_SUCCESS == rc)
517  {
518  ROS_DEBUG_STREAM("feature " << featureName(feature)
519  << " Blue/U: " << *value
520  << " Red/V: " << *value2);
521  }
522  else
523  {
524  ROS_WARN_STREAM("failed to get values for feature "
525  << featureName(feature));
526  }
527  }
528  else
529  {
530  // other features only have one component
531  if (finfo->absolute_capable && finfo->abs_control)
532  {
533  // supports reading and setting float value
534  float fval;
535  rc = dc1394_feature_get_absolute_value(camera_, feature, &fval);
536  if (DC1394_SUCCESS == rc)
537  {
538  *value = fval; // convert to double
539  }
540  }
541  else // no float representation
542  {
543  uint32_t ival;
544  rc = dc1394_feature_get_value(camera_, feature, &ival);
545  if (DC1394_SUCCESS == rc)
546  {
547  *value = ival; // convert to double
548  }
549  }
550  if (DC1394_SUCCESS == rc)
551  {
552  ROS_DEBUG_STREAM("feature " << featureName(feature)
553  << " has value " << *value);
554  }
555  else
556  {
557  ROS_WARN_STREAM("failed to get value of feature "
558  << featureName(feature));
559  }
560  }
561 }
562 
571 bool Features::setMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
572 {
573  dc1394feature_t feature = finfo->id;
574  if (hasMode(finfo, mode))
575  {
576  // first, make sure the feature is powered on
577  setPower(finfo, DC1394_ON);
578 
579  ROS_DEBUG_STREAM("setting feature " << featureName(feature)
580  << " mode to " << modeName(mode));
581  if (DC1394_SUCCESS !=
582  dc1394_feature_set_mode(camera_, feature, mode))
583  {
584  ROS_WARN_STREAM("failed to set feature " << featureName(feature)
585  << " mode to " << modeName(mode));
586  return false;
587  }
588  }
589  else
590  {
591  // device does not support this mode for this feature
592  ROS_DEBUG_STREAM("no " << modeName(mode)
593  << " mode for feature " << featureName(feature));
594  return false;
595  }
596  return true;
597 }
598 
606 void Features::setPower(dc1394feature_info_t *finfo, dc1394switch_t on_off)
607 {
608  dc1394feature_t feature = finfo->id;
609  if (finfo->on_off_capable)
610  {
611  ROS_DEBUG_STREAM("Setting power for feature " << featureName(feature)
612  << " to " << on_off);
613  if (DC1394_SUCCESS !=
614  dc1394_feature_set_power(camera_, feature, on_off))
615  {
616  ROS_WARN_STREAM("failed to set feature " << featureName(feature)
617  << " power to " << on_off);
618  }
619  }
620  else
621  {
622  // This device does not support turning this feature on or off.
623  // That's OK.
624  ROS_DEBUG_STREAM("no power control 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_
Definition: features.h:114
void setPower(dc1394feature_info_t *finfo, dc1394switch_t on_off)
Definition: features.cpp:606
state_t getState(dc1394feature_info_t *finfo)
Definition: features.cpp:420
dc1394featureset_t feature_set_
that camera&#39;s feature set
Definition: features.h:127
dc1394camera_t * camera_
current camera
Definition: features.h:126
void reconfigure(Config *newconfig)
Definition: features.cpp:202
void updateIfChanged(dc1394feature_t feature, int old_control, int *control, double old_value, double *value)
Definition: features.cpp:642
bool setMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
Definition: features.cpp:571
void getValues(dc1394feature_info_t *finfo, double *value, double *value2)
Definition: features.cpp:481
void configure(dc1394feature_t feature, int *control, double *value, double *value2=NULL)
Definition: features.cpp:280
bool initialize(Config *newconfig)
Definition: features.cpp:140
bool hasMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
Definition: features.h:92
libdc1394 triggering modes interface
bool hasTrigger(void)
Definition: features.h:107
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
Features(dc1394camera_t *camera)
Definition: features.cpp:125
int state_t
camera1394::Camera1394_* state values
Definition: features.h:76
#define ROS_INFO_STREAM(args)
int min(int a, int b)
Config oldconfig_
previous Config settings
Definition: features.h:128
camera1394::Camera1394Config Config
Definition: driver1394.h:53
Camera1394 features interface.
#define ROS_ERROR(...)


camera1394
Author(s): Jack O'Quin, Ken Tossell, Patrick Beeson, Nate Koenig, Andrew Howard, Damien Douxchamps, Dan Dennedy
autogenerated on Mon Jun 10 2019 12:52:31