features.cpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*********************************************************************
00004 * Software License Agreement (BSD License)
00005 *
00006 *  Copyright (c) 2010 Jack O'Quin
00007 *  All rights reserved.
00008 *
00009 *  Redistribution and use in source and binary forms, with or without
00010 *  modification, are permitted provided that the following conditions
00011 *  are met:
00012 *
00013 *   * Redistributions of source code must retain the above copyright
00014 *     notice, this list of conditions and the following disclaimer.
00015 *   * Redistributions in binary form must reproduce the above
00016 *     copyright notice, this list of conditions and the following
00017 *     disclaimer in the documentation and/or other materials provided
00018 *     with the distribution.
00019 *   * Neither the name of the author nor other contributors may be
00020 *     used to endorse or promote products derived from this software
00021 *     without specific prior written permission.
00022 *
00023 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034 *  POSSIBILITY OF SUCH DAMAGE.
00035 *********************************************************************/
00036 
00037 #include <cmath>
00038 #include "features.h"
00039 #include "trigger.h"
00040 
00049 
00050 // static data and functions:
00052 namespace
00053 {
00054   // driver feature parameter names, corresponding to DC1394 modes
00055   // (not all currently supported by the driver)
00056   static const char *feature_names_[DC1394_FEATURE_NUM] =
00057     {
00058       "brightness",
00059       "exposure",
00060       "sharpness",
00061       "whitebalance",
00062       "hue",
00063       "saturation",
00064       "gamma",
00065       "shutter",
00066       "gain",
00067       "iris",
00068       "focus",
00069       "temperature",
00070       "trigger",
00071       "trigger_delay",
00072       "white_shading",
00073       "frame_rate",
00074       "zoom",
00075       "pan",
00076       "tilt",
00077       "optical_filter",
00078       "capture_size",
00079       "capture_quality"
00080     };
00081 
00087   inline const char *featureName(dc1394feature_t feature)
00088   {
00089     if (feature >= DC1394_FEATURE_MIN && feature <= DC1394_FEATURE_MAX)
00090       return feature_names_[feature - DC1394_FEATURE_MIN];
00091     else
00092       return "(unknown)";
00093   }
00094 
00095   // driver mode parameter names, corresponding to DC1394 modes
00096   static const char *mode_names_[DC1394_FEATURE_MODE_NUM] =
00097     {
00098       "Manual",
00099       "Auto",
00100       "OnePush",
00101     };
00102 
00108   inline const char *modeName(dc1394feature_mode_t mode)
00109   {
00110     if (mode >= DC1394_FEATURE_MODE_MIN && mode <= DC1394_FEATURE_MODE_MAX)
00111       return mode_names_[mode - DC1394_FEATURE_MODE_MIN];
00112     else
00113       return "(unknown)";
00114   }
00115 }
00116 
00118 // public methods:
00120 
00125 Features::Features(dc1394camera_t *camera):
00126   camera_(camera)
00127 {
00128   trigger_.reset(new Trigger(camera));
00129 }
00130 
00140 bool Features::initialize(Config *newconfig)
00141 {
00142   bool retval = true;
00143 
00144   // query all features for this device
00145   if (DC1394_SUCCESS != dc1394_feature_get_all(camera_, &feature_set_))
00146     {
00147       ROS_ERROR("could not get camera feature information");
00148       return false;
00149     }
00150 
00151   // validate and set configured value of each supported feature
00152   configure(DC1394_FEATURE_BRIGHTNESS,
00153             &newconfig->auto_brightness, &newconfig->brightness);
00154   configure(DC1394_FEATURE_EXPOSURE,
00155             &newconfig->auto_exposure, &newconfig->exposure);
00156   configure(DC1394_FEATURE_FOCUS,
00157             &newconfig->auto_focus, &newconfig->focus);
00158   configure(DC1394_FEATURE_GAIN,
00159             &newconfig->auto_gain, &newconfig->gain);
00160   configure(DC1394_FEATURE_GAMMA,
00161             &newconfig->auto_gamma, &newconfig->gamma);
00162   configure(DC1394_FEATURE_HUE,
00163             &newconfig->auto_hue, &newconfig->hue);
00164   configure(DC1394_FEATURE_IRIS,
00165             &newconfig->auto_iris, &newconfig->iris);
00166   configure(DC1394_FEATURE_PAN,
00167             &newconfig->auto_pan, &newconfig->pan);
00168   configure(DC1394_FEATURE_SATURATION,
00169             &newconfig->auto_saturation, &newconfig->saturation);
00170   configure(DC1394_FEATURE_SHARPNESS,
00171             &newconfig->auto_sharpness, &newconfig->sharpness);
00172   configure(DC1394_FEATURE_SHUTTER,
00173             &newconfig->auto_shutter, &newconfig->shutter);
00174   configure(DC1394_FEATURE_TRIGGER,
00175             &newconfig->auto_trigger, &newconfig->trigger);
00176   configure(DC1394_FEATURE_WHITE_BALANCE, &newconfig->auto_white_balance,
00177             &newconfig->white_balance_BU, &newconfig->white_balance_RV);
00178   configure(DC1394_FEATURE_ZOOM,
00179             &newconfig->auto_zoom, &newconfig->zoom);
00180 
00181   // set up trigger class, if supported by this camera
00182   if (hasTrigger())
00183     retval = trigger_->initialize(newconfig);
00184 
00185   // save configured values
00186   oldconfig_ = *newconfig;
00187   return retval;
00188 }
00189 
00202 void Features::reconfigure(Config *newconfig)
00203 {
00204   updateIfChanged(DC1394_FEATURE_BRIGHTNESS,
00205                   oldconfig_.auto_brightness, &newconfig->auto_brightness,
00206                   oldconfig_.brightness, &newconfig->brightness);
00207   updateIfChanged(DC1394_FEATURE_EXPOSURE,
00208                   oldconfig_.auto_exposure, &newconfig->auto_exposure,
00209                   oldconfig_.exposure, &newconfig->exposure);
00210   updateIfChanged(DC1394_FEATURE_FOCUS,
00211                   oldconfig_.auto_focus, &newconfig->auto_focus,
00212                   oldconfig_.focus, &newconfig->focus);
00213   updateIfChanged(DC1394_FEATURE_GAIN,
00214                   oldconfig_.auto_gain, &newconfig->auto_gain,
00215                   oldconfig_.gain, &newconfig->gain);
00216   updateIfChanged(DC1394_FEATURE_GAMMA,
00217                   oldconfig_.auto_gamma, &newconfig->auto_gamma,
00218                   oldconfig_.gamma, &newconfig->gamma);
00219   updateIfChanged(DC1394_FEATURE_HUE,
00220                   oldconfig_.auto_hue, &newconfig->auto_hue,
00221                   oldconfig_.hue, &newconfig->hue);
00222   updateIfChanged(DC1394_FEATURE_IRIS,
00223                   oldconfig_.auto_iris, &newconfig->auto_iris,
00224                   oldconfig_.iris, &newconfig->iris);
00225   updateIfChanged(DC1394_FEATURE_PAN,
00226                   oldconfig_.auto_pan, &newconfig->auto_pan,
00227                   oldconfig_.pan, &newconfig->pan);
00228   updateIfChanged(DC1394_FEATURE_SATURATION,
00229                   oldconfig_.auto_saturation, &newconfig->auto_saturation,
00230                   oldconfig_.saturation, &newconfig->saturation);
00231   updateIfChanged(DC1394_FEATURE_SHARPNESS,
00232                   oldconfig_.auto_sharpness, &newconfig->auto_sharpness,
00233                   oldconfig_.sharpness, &newconfig->sharpness);
00234   updateIfChanged(DC1394_FEATURE_SHUTTER,
00235                   oldconfig_.auto_shutter, &newconfig->auto_shutter,
00236                   oldconfig_.shutter, &newconfig->shutter);
00237   updateIfChanged(DC1394_FEATURE_TRIGGER,
00238                   oldconfig_.auto_trigger, &newconfig->auto_trigger,
00239                   oldconfig_.trigger, &newconfig->trigger);
00240   // White balance has two component parameters: Blue/U and Red/V.
00241   updateIfChanged(DC1394_FEATURE_WHITE_BALANCE,
00242                   oldconfig_.auto_white_balance,
00243                   &newconfig->auto_white_balance,
00244                   oldconfig_.white_balance_BU, &newconfig->white_balance_BU,
00245                   oldconfig_.white_balance_RV, &newconfig->white_balance_RV);
00246   updateIfChanged(DC1394_FEATURE_ZOOM,
00247                   oldconfig_.auto_zoom, &newconfig->auto_zoom,
00248                   oldconfig_.zoom, &newconfig->zoom);
00249 
00250   // reconfigure trigger class, if supported by this camera
00251   if (hasTrigger())
00252     trigger_->reconfigure(newconfig);
00253 
00254   // save modified values
00255   oldconfig_ = *newconfig;
00256 }
00257 
00259 // private methods:
00261 
00280 void Features::configure(dc1394feature_t feature, int *control,
00281                          double *value, double *value2)
00282 {
00283   // device-relevant information for this feature
00284   dc1394feature_info_t *finfo =
00285     &feature_set_.feature[feature - DC1394_FEATURE_MIN];
00286 
00287   if (!finfo->available)                // feature not available?
00288     {
00289       *control = camera1394::Camera1394_None;
00290       return;
00291     }
00292 
00293   switch (*control)
00294     {
00295     case camera1394::Camera1394_Off:
00296       setPower(finfo, DC1394_OFF);
00297       break;
00298 
00299     case camera1394::Camera1394_Query:
00300       getValues(finfo, value, value2);
00301       break;
00302 
00303     case camera1394::Camera1394_Auto:
00304       if (!setMode(finfo, DC1394_FEATURE_MODE_AUTO))
00305         {
00306           setPower(finfo, DC1394_OFF);
00307         }
00308       break;
00309 
00310     case camera1394::Camera1394_Manual:
00311       if (!setMode(finfo, DC1394_FEATURE_MODE_MANUAL))
00312         {
00313           setPower(finfo, DC1394_OFF);
00314           break;
00315         }
00316 
00317       // TODO: break this into some internal methods
00318       if (finfo->absolute_capable && finfo->abs_control)
00319         {
00320           // supports reading and setting float value
00321           float fmin, fmax;
00322           if (DC1394_SUCCESS ==
00323               dc1394_feature_get_absolute_boundaries(camera_, feature,
00324                                                      &fmin, &fmax))
00325             {
00326               // clamp *value between minimum and maximum
00327               if (*value < fmin)
00328                 *value = (double) fmin;
00329               else if (*value > fmax)
00330                 *value = (double) fmax;
00331             }
00332           else
00333             {
00334               ROS_WARN_STREAM("failed to get feature "
00335                               << featureName(feature) << " boundaries ");
00336             }
00337 
00338           // @todo handle absolute White Balance values
00339           float fval = *value;
00340           if (DC1394_SUCCESS !=
00341               dc1394_feature_set_absolute_value(camera_, feature, fval))
00342             {
00343               ROS_WARN_STREAM("failed to set feature "
00344                               << featureName(feature) << " to " << fval);
00345             }
00346         }
00347       else // no float representation
00348         {
00349           // round requested value to nearest integer
00350           *value = rint(*value);
00351 
00352           // clamp *value between minimum and maximum
00353           if (*value < finfo->min)
00354             *value = (double) finfo->min;
00355           else if (*value > finfo->max)
00356             *value = (double) finfo->max;
00357 
00358           dc1394error_t rc;
00359           uint32_t ival = (uint32_t) *value;
00360 
00361           // handle White Balance, which has two components
00362           if (feature == DC1394_FEATURE_WHITE_BALANCE)
00363             {
00364               *value2 = rint(*value2);
00365 
00366               // clamp *value2 between same minimum and maximum
00367               if (*value2 < finfo->min)
00368                 *value2 = (double) finfo->min;
00369               else if (*value2 > finfo->max)
00370                 *value2 = (double) finfo->max;
00371 
00372               uint32_t ival2 = (uint32_t) *value2;
00373               rc = dc1394_feature_whitebalance_set_value(camera_, ival, ival2);
00374             }
00375           else
00376             {
00377               // other features only have one component
00378               rc = dc1394_feature_set_value(camera_, feature, ival);
00379             }
00380           if (rc != DC1394_SUCCESS)
00381             {
00382               ROS_WARN_STREAM("failed to set feature "
00383                               << featureName(feature) << " to " << ival);
00384             }
00385         }
00386       break;
00387 
00388     case camera1394::Camera1394_OnePush:
00389       // Try to set OnePush mode
00390       setMode(finfo, DC1394_FEATURE_MODE_ONE_PUSH_AUTO);
00391 
00392       // Now turn the control off, so camera does not continue adjusting
00393       setPower(finfo, DC1394_OFF);
00394       break;
00395 
00396     case camera1394::Camera1394_None:
00397       // Invalid user input, because this feature actually does exist.
00398       ROS_INFO_STREAM("feature " << featureName(feature)
00399                       << " exists, cannot set to None");
00400       break;
00401 
00402     default:
00403       ROS_WARN_STREAM("unknown state (" << *control
00404                       <<") for feature " << featureName(feature));
00405     }
00406 
00407   // return actual state reported by the device
00408   *control = getState(finfo);
00409   ROS_DEBUG_STREAM("feature " << featureName(feature)
00410                    << " now in state " << *control);
00411 }
00412 
00420 Features::state_t Features::getState(dc1394feature_info_t *finfo)
00421 {
00422   dc1394feature_t feature = finfo->id;
00423   dc1394error_t rc;
00424 
00425   if (!finfo->available)
00426     {
00427       // not available: nothing more to do
00428       return camera1394::Camera1394_None;
00429     }
00430 
00431   if (finfo->on_off_capable)
00432     {
00433       // get On/Off state
00434       dc1394switch_t pwr;
00435       rc = dc1394_feature_get_power(camera_, feature, &pwr);
00436       if (rc != DC1394_SUCCESS)
00437         {
00438           ROS_WARN_STREAM("failed to get feature " << featureName(feature)
00439                           << " Power setting ");
00440         }
00441       else if (pwr == DC1394_OFF)
00442         {
00443           // Off overrides mode settings
00444           return camera1394::Camera1394_Off;
00445         }
00446     }
00447 
00448   // not off, so get mode
00449   dc1394feature_mode_t mode;
00450   rc = dc1394_feature_get_mode(camera_, feature, &mode);
00451   if (rc != DC1394_SUCCESS)
00452     {
00453       ROS_WARN_STREAM("failed to get current mode of feature "
00454                       << featureName(feature));
00455       // treat unavailable mode as Off
00456       return camera1394::Camera1394_Off;
00457     }
00458 
00459   switch (mode)
00460     {
00461     case DC1394_FEATURE_MODE_MANUAL:
00462       return camera1394::Camera1394_Manual;
00463     case DC1394_FEATURE_MODE_AUTO:
00464       return camera1394::Camera1394_Auto;
00465     case DC1394_FEATURE_MODE_ONE_PUSH_AUTO:
00466       return camera1394::Camera1394_OnePush;
00467     default:
00468       return camera1394::Camera1394_Off;
00469     }
00470 }
00471 
00481 void Features::getValues(dc1394feature_info_t *finfo,
00482                            double *value, double *value2)
00483 {
00484   dc1394feature_t feature = finfo->id;
00485   dc1394error_t rc;
00486 
00487   if (!finfo->readout_capable)
00488     {
00489       ROS_INFO_STREAM("feature " << featureName(feature)
00490                       << " value not available from device");
00491       return;
00492     }
00493 
00494   if (feature == DC1394_FEATURE_WHITE_BALANCE)
00495     {
00496       // handle White Balance separately, it has two components
00497       if (finfo->absolute_capable && finfo->abs_control)
00498         {
00499           // supports reading and setting float value
00500           // @todo get absolute White Balance values
00501           rc = DC1394_FUNCTION_NOT_SUPPORTED;
00502         }
00503       else
00504         {
00505           // get integer White Balance values
00506           uint32_t bu_val;
00507           uint32_t rv_val;
00508           rc = dc1394_feature_whitebalance_get_value(camera_, &bu_val, &rv_val);
00509           if (DC1394_SUCCESS == rc)
00510             {
00511               // convert to double
00512               *value = bu_val;
00513               *value2 = rv_val;
00514             }
00515         }
00516       if (DC1394_SUCCESS == rc)
00517         {
00518           ROS_DEBUG_STREAM("feature " << featureName(feature)
00519                            << " Blue/U: " << *value
00520                            << " Red/V: " << *value2);
00521         }
00522       else
00523         {
00524           ROS_WARN_STREAM("failed to get values for feature "
00525                           << featureName(feature));
00526         }
00527     }
00528   else
00529     {
00530       // other features only have one component
00531       if (finfo->absolute_capable && finfo->abs_control)
00532         {
00533           // supports reading and setting float value
00534           float fval;
00535           rc = dc1394_feature_get_absolute_value(camera_, feature, &fval);
00536           if (DC1394_SUCCESS == rc)
00537             {
00538               *value = fval;                // convert to double
00539             }
00540         }
00541       else // no float representation
00542         {
00543           uint32_t ival;
00544           rc = dc1394_feature_get_value(camera_, feature, &ival);
00545           if (DC1394_SUCCESS == rc)
00546             {
00547               *value = ival;                // convert to double
00548             }
00549         }
00550       if (DC1394_SUCCESS == rc)
00551         {
00552           ROS_DEBUG_STREAM("feature " << featureName(feature)
00553                            << " has value " << *value);
00554         }
00555       else
00556         {
00557           ROS_WARN_STREAM("failed to get value of feature "
00558                           << featureName(feature));
00559         }
00560     }
00561 }
00562 
00571 bool Features::setMode(dc1394feature_info_t *finfo, dc1394feature_mode_t mode)
00572 {
00573   dc1394feature_t feature = finfo->id;
00574   if (hasMode(finfo, mode))
00575     {
00576       // first, make sure the feature is powered on
00577       setPower(finfo, DC1394_ON);
00578 
00579       ROS_DEBUG_STREAM("setting feature " << featureName(feature)
00580                        << " mode to " << modeName(mode));
00581       if (DC1394_SUCCESS !=
00582           dc1394_feature_set_mode(camera_, feature, mode))
00583         {
00584           ROS_WARN_STREAM("failed to set feature " << featureName(feature)
00585                           << " mode to " << modeName(mode));
00586           return false;
00587         }
00588     }
00589   else
00590     {
00591       // device does not support this mode for this feature
00592       ROS_DEBUG_STREAM("no " << modeName(mode)
00593                        << " mode for feature " << featureName(feature));
00594       return false;
00595     }
00596   return true;
00597 }
00598 
00606 void Features::setPower(dc1394feature_info_t *finfo, dc1394switch_t on_off)
00607 {
00608   dc1394feature_t feature = finfo->id;
00609   if (finfo->on_off_capable)
00610     {
00611       ROS_DEBUG_STREAM("Setting power for feature " << featureName(feature)
00612                        << " to " << on_off);
00613       if (DC1394_SUCCESS !=
00614           dc1394_feature_set_power(camera_, feature, on_off))
00615         {
00616           ROS_WARN_STREAM("failed to set feature " << featureName(feature)
00617                           << " power to " << on_off);
00618         }
00619     }
00620   else
00621     {
00622       // This device does not support turning this feature on or off.
00623       // That's OK.
00624       ROS_DEBUG_STREAM("no power control for feature " << featureName(feature));
00625     }
00626 }
00627 
00642 void Features::updateIfChanged(dc1394feature_t feature,
00643                                int old_control, int *control,
00644                                double old_value, double *value)
00645 {
00646   if ((old_control != *control) || (old_value != *value))
00647     {
00648       configure(feature, control, value);
00649     }
00650 }
00651 
00669 void Features::updateIfChanged(dc1394feature_t feature,
00670                                int old_control, int *control,
00671                                double old_value, double *value,
00672                                double old_value2, double *value2)
00673 {
00674   if ((old_control != *control)
00675       || (old_value != *value)
00676       || (old_value2 != *value2))
00677     {
00678       configure(feature, control, value, value2);
00679     }
00680 }


camera1394
Author(s): Jack O'Quin, Ken Tossell, Patrick Beeson, Nate Koenig, Andrew Howard, Damien Douxchamps, Dan Dennedy
autogenerated on Thu Jun 6 2019 19:34:17