vimba_ros.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #include <avt_vimba_camera/vimba_ros.h>
00034 
00035 #include <ros/console.h>
00036 #include <sensor_msgs/image_encodings.h>
00037 #include <sensor_msgs/fill_image.h>
00038 
00039 #include <boost/lexical_cast.hpp>
00040 #include <sstream>
00041 
00042 namespace avt_vimba_camera {
00043 
00044 static const char* AutoMode[] = {"Off", "Once", "Continuous"};
00045 static const char* TriggerMode[] = {
00046   "Freerun",
00047   "FixedRate",
00048   "Software",
00049   "SyncIn1",
00050   "SyncIn2",
00051   "SyncIn3",
00052   "SyncIn4" };
00053 static const char* AcquisitionMode[] = {
00054   "Continuous",
00055   "SingleFrame",
00056   "MultiFrame",
00057   "Recorder"};
00058 static const char* PixelFormatMode[] = {
00059   "Mono8",
00060   "Mono12",
00061   "Mono12Packed",
00062   "BayerRG8",
00063   "BayerRG12Packed",
00064   "BayerRG12",
00065   "RGB8Packed",
00066   "BGR8Packed"};
00067 static const char* BalanceRatioMode[] = {"Red", "Blue"};
00068 static const char* FeatureDataType[] = {"Unknown", "int", "float", "enum", "string", "bool"};
00069 
00070 
00071 VimbaROS::VimbaROS(ros::NodeHandle nh, ros::NodeHandle nhp)
00072 :vimba_system_(VimbaSystem::GetInstance()), it_(nhp), nh_(nh), nhp_(nhp) {
00073 
00074   // Vimba startup & list all available cameras
00075   initApi();
00076 
00077   cinfo_ = boost::shared_ptr<camera_info_manager::CameraInfoManager>(new camera_info_manager::CameraInfoManager(nhp_));
00078 
00079   // Init global variables
00080   running_ = false;
00081   first_run_ = true;
00082 
00083   // Service call for setting calibration.
00084   //set_camera_info_srv_ = nh_.advertiseService("set_camera_info",
00085   //                                            &VimbaROS::setCameraInfo,
00086   //                                            this);
00087 
00088   // Start dynamic_reconfigure & run configure()
00089   reconfigure_server_.setCallback(boost::bind(&VimbaROS::configure,
00090                                               this,
00091                                               _1,
00092                                               _2));
00093 }
00094 
00095 void VimbaROS::start(Config& config) {
00096   if (running_) return;
00097 
00098   std::string ip_str   = config.ip_address;
00099   std::string guid_str = config.guid;
00100 
00101   // Determine which camera to use. Try IP first
00102   if (!ip_str.empty()) {
00103     ROS_INFO_STREAM("Trying to open camera by IP: " << ip_str);
00104     vimba_camera_ptr_ = openCamera(ip_str);
00105     // If both guid and IP are available, open by IP and check guid
00106     if (!guid_str.empty()) {
00107       std::string cam_guid_str;
00108       vimba_camera_ptr_->GetSerialNumber(cam_guid_str);
00109       assert(cam_guid_str == guid_str);
00110       ROS_INFO_STREAM("GUID " << cam_guid_str << " matches for camera with IP: " << ip_str);
00111     }
00112   } else if (!guid_str.empty()) {
00113     // Only guid available
00114     ROS_INFO_STREAM("Trying to open camera by ID: " << guid_str);
00115     vimba_camera_ptr_ = openCamera(guid_str);
00116   }
00117 
00118   // Get all cam properties we need for initialization
00119   getFeatureValue("WidthMax",vimba_camera_max_width_);
00120   getFeatureValue("HeightMax",vimba_camera_max_height_);
00121 
00122   // Set all camera configurations
00123   FeaturePtrVector feature_ptr_vec;
00124   vimba_camera_ptr_->GetFeatures(feature_ptr_vec);
00125   updateAcquisitionConfig(config, feature_ptr_vec);
00126   updateExposureConfig(config, feature_ptr_vec);
00127   updateGainConfig(config, feature_ptr_vec);
00128   updateWhiteBalanceConfig(config, feature_ptr_vec);
00129   updateImageModeConfig(config, feature_ptr_vec);
00130   updateROIConfig(config, feature_ptr_vec);
00131   updateBandwidthConfig(config, feature_ptr_vec);
00132   updatePixelFormatConfig(config, feature_ptr_vec);
00133   updateCameraInfo(config);
00134 
00136   getFeatureValue("TriggerSource", trigger_mode_);
00137   ROS_INFO_STREAM("[AVT_Vimba_ROS]: Trigger mode is " << trigger_mode_);
00138 
00139   trigger_mode_int_ = getTriggerModeInt(trigger_mode_);
00140 
00141   if (trigger_mode_int_ == Freerun || trigger_mode_int_ == FixedRate || trigger_mode_int_ == SyncIn1) {
00142     // Create a frame observer for this camera
00143     vimba_frame_observer_ptr_ = new FrameObserver(vimba_camera_ptr_,
00144                     boost::bind(&VimbaROS::frameCallback, this, _1));
00145 
00146     // Setup the image publisher before the streaming
00147     streaming_pub_ = it_.advertiseCamera("image_raw", 1);
00148 
00149     // Start streaming
00150     VmbErrorType err =
00151       vimba_camera_ptr_->StartContinuousImageAcquisition(1,//num_frames_,
00152                                 IFrameObserverPtr(vimba_frame_observer_ptr_));
00153     if (VmbErrorSuccess == err){
00154       ROS_INFO_STREAM("[AVT_Vimba_ROS]: StartContinuousImageAcquisition");
00155     } else {
00156       ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not StartContinuousImageAcquisition. "
00157         << "\n Error: " << errorCodeToMessage(err));
00158     }
00159   } else if (trigger_mode_int_ == Software) {
00160     vimba_camera_ptr_->Close();
00161     poll_srv_ = polled_camera::advertise(nhp_, "request_image", &VimbaROS::pollCallback, this);
00162   } else {
00163     ROS_ERROR_STREAM("Trigger mode " <<
00164                        TriggerMode[trigger_mode_int_] <<
00165                        " not implemented.");
00166   }
00167 }
00168 
00169 void VimbaROS::stop() {
00170   if (!running_) return;
00171 
00172   vimba_camera_ptr_->Close();  // Must stop camera before streaming_pub_.
00173   poll_srv_.shutdown();
00174   //trigger_sub_.shutdown();
00175   streaming_pub_.shutdown();
00176 
00177   running_ = false;
00178 }
00179 
00180 void VimbaROS::pollCallback(polled_camera::GetPolledImage::Request& req,
00181                             polled_camera::GetPolledImage::Response& rsp,
00182                             sensor_msgs::Image& image,
00183                             sensor_msgs::CameraInfo& info) {
00184   if (trigger_mode_int_ != Software) {
00185     rsp.success = false;
00186     rsp.status_message = "Camera is not in software triggered mode";
00187     return;
00188   }
00189 
00190   // open the camera
00191   vimba_camera_ptr_ = openCamera(camera_config_.guid);
00192 
00193   // configure it
00194   configure(camera_config_,0);
00195 
00196   ROS_INFO_STREAM("POLL CALLBACK CALLED");
00197 
00198 
00199   FeaturePtrVector feature_ptr_vec;
00200   VmbErrorType err = vimba_camera_ptr_->GetFeatures(feature_ptr_vec);
00201   if (err == VmbErrorSuccess) {
00202     // Region of interest configuration
00203     // Make sure ROI fits in image
00204     if (req.roi.x_offset || req.roi.y_offset || req.roi.width || req.roi.height) {
00205       unsigned int left_x   = req.roi.x_offset / req.binning_x;
00206       unsigned int top_y    = req.roi.y_offset / req.binning_y;
00207       unsigned int right_x  = (req.roi.x_offset + req.roi.width  + req.binning_x - 1) / req.binning_x;
00208       unsigned int bottom_y = (req.roi.y_offset + req.roi.height + req.binning_y - 1) / req.binning_y;
00209       unsigned int width    = right_x - left_x;
00210       unsigned int height   = bottom_y - top_y;
00211       setFeatureValue("OffsetX", static_cast<VmbInt64_t>(left_x));
00212       setFeatureValue("OffsetY", static_cast<VmbInt64_t>(top_y));
00213       setFeatureValue("Width",   static_cast<VmbInt64_t>(width));
00214       setFeatureValue("Height",  static_cast<VmbInt64_t>(height));
00215     } else {
00216       setFeatureValue("OffsetX", static_cast<VmbInt64_t>(0));
00217       setFeatureValue("OffsetY", static_cast<VmbInt64_t>(0));
00218       setFeatureValue("Width",   static_cast<VmbInt64_t>(vimba_camera_max_width_));
00219       setFeatureValue("Height",  static_cast<VmbInt64_t>(vimba_camera_max_height_));
00220     }
00221   } else {
00222     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not GetFeatures. "
00223     << "\n Error: " << errorCodeToMessage(err));
00224   }
00225 
00226   ROS_INFO_STREAM("POLL CALLBACK CALLED: all features set");
00227 
00228   // Zero duration means "no timeout"
00229   VmbUint32_t VmbUint32_inf = 2e4-1;
00230   unsigned long timeout = req.timeout.isZero() ? VmbUint32_inf : req.timeout.toNSec() / 1e6;
00231   FramePtr frame;
00232   //runCommand("TriggerSoftware");
00233   err = vimba_camera_ptr_->AcquireSingleImage(frame, timeout);
00234   ROS_INFO_STREAM("POLL CALLBACK CALLED: acquire single image");
00235   if (err == VmbErrorSuccess) {
00236     if (!frame) {
00237       rsp.success = false;
00238       rsp.status_message = "Failed to capture frame, may have timed out";
00239       return;
00240     } else {
00241       //err = vimba_camera_ptr_->QueueFrame(frame);
00242       if (err == VmbErrorSuccess) {
00243         info = cinfo_->getCameraInfo();
00244         if (!frameToImage(frame, image)) {
00245           rsp.success = false;
00246           rsp.status_message = "Captured frame but failed to process it";
00247           return;
00248         }
00249         // do_rectify should be preserved from request
00250         info.roi.do_rectify = req.roi.do_rectify;
00251         rsp.success = true;
00252         ROS_INFO_STREAM("POLL CALLBACK CALLED: DONE!");
00253       }
00254     }
00255   }
00256 
00257   if (err != VmbErrorSuccess){
00258     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not AcquireSingleImage. "
00259     << "\n Error: " << errorCodeToMessage(err));
00260     rsp.success = false;
00261     rsp.status_message = "AVT_Vimba_ROS error";
00262     return;
00263   }
00264 
00265   // close the camera
00266   vimba_camera_ptr_->Close();
00267 }
00268 
00269 void VimbaROS::frameCallback(const FramePtr vimba_frame_ptr) {
00270 
00271   sensor_msgs::Image img;
00272 
00273   vimba_frame_ptr_ = vimba_frame_ptr;
00274 
00276   // if ( trigger_mode_ == SyncIn1  && !trig_time_.isZero() ) {
00277 
00278   img.header.stamp = cam_info_.header.stamp = ros::Time::now();
00279   //VmbUint64_t timestamp;
00280   //vimba_frame_ptr->GetTimestamp(timestamp);
00281   //ROS_INFO_STREAM("[AVT_Vimba_ROS]: NEW_FRAME Timestamp: " << timestamp);
00282 
00283   img.header.frame_id = frame_id_.c_str();
00284 
00285   if(streaming_pub_.getNumSubscribers() > 0){
00286     if (frameToImage(vimba_frame_ptr, img)){
00287       streaming_pub_.publish(img, cam_info_); // add timestamp
00288     }
00289   }
00290   // Queue the frame so that we can receive a new one.
00291   vimba_camera_ptr_->QueueFrame(vimba_frame_ptr);
00292 }
00293 
00294 bool VimbaROS::frameToImage(const FramePtr vimba_frame_ptr,
00295                             sensor_msgs::Image& image) {
00296   VmbPixelFormatType pixel_format;
00297   VmbUint32_t width  = camera_config_.width;
00298   VmbUint32_t height = camera_config_.height;
00299 
00300   vimba_frame_ptr->GetPixelFormat(pixel_format);
00301 
00302   // NOTE: YUV and ARGB formats not supported
00303   std::string encoding;
00304   if      (pixel_format == VmbPixelFormatMono8          ) encoding = sensor_msgs::image_encodings::MONO8;
00305   else if (pixel_format == VmbPixelFormatMono10         ) encoding = sensor_msgs::image_encodings::MONO16;
00306   else if (pixel_format == VmbPixelFormatMono12         ) encoding = sensor_msgs::image_encodings::MONO16;
00307   else if (pixel_format == VmbPixelFormatMono12Packed   ) encoding = sensor_msgs::image_encodings::MONO16;
00308   else if (pixel_format == VmbPixelFormatMono14         ) encoding = sensor_msgs::image_encodings::MONO16;
00309   else if (pixel_format == VmbPixelFormatMono16         ) encoding = sensor_msgs::image_encodings::MONO16;
00310   else if (pixel_format == VmbPixelFormatBayerGR8       ) encoding = sensor_msgs::image_encodings::BAYER_GRBG8;
00311   else if (pixel_format == VmbPixelFormatBayerRG8       ) encoding = sensor_msgs::image_encodings::BAYER_RGGB8;
00312   else if (pixel_format == VmbPixelFormatBayerGB8       ) encoding = sensor_msgs::image_encodings::BAYER_GBRG8;
00313   else if (pixel_format == VmbPixelFormatBayerBG8       ) encoding = sensor_msgs::image_encodings::BAYER_BGGR8;
00314   else if (pixel_format == VmbPixelFormatBayerGR10      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00315   else if (pixel_format == VmbPixelFormatBayerRG10      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00316   else if (pixel_format == VmbPixelFormatBayerGB10      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00317   else if (pixel_format == VmbPixelFormatBayerBG10      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00318   else if (pixel_format == VmbPixelFormatBayerGR12      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00319   else if (pixel_format == VmbPixelFormatBayerRG12      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00320   else if (pixel_format == VmbPixelFormatBayerGB12      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00321   else if (pixel_format == VmbPixelFormatBayerBG12      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00322   else if (pixel_format == VmbPixelFormatBayerGR12Packed) encoding = sensor_msgs::image_encodings::TYPE_32SC4;
00323   else if (pixel_format == VmbPixelFormatBayerRG12Packed) encoding = sensor_msgs::image_encodings::TYPE_32SC4;
00324   else if (pixel_format == VmbPixelFormatBayerGB12Packed) encoding = sensor_msgs::image_encodings::TYPE_32SC4;
00325   else if (pixel_format == VmbPixelFormatBayerBG12Packed) encoding = sensor_msgs::image_encodings::TYPE_32SC4;
00326   else if (pixel_format == VmbPixelFormatBayerGR16      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00327   else if (pixel_format == VmbPixelFormatBayerRG16      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00328   else if (pixel_format == VmbPixelFormatBayerGB16      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00329   else if (pixel_format == VmbPixelFormatBayerBG16      ) encoding = sensor_msgs::image_encodings::TYPE_16SC1;
00330   else if (pixel_format == VmbPixelFormatRgb8           ) encoding = sensor_msgs::image_encodings::RGB8;
00331   else if (pixel_format == VmbPixelFormatBgr8           ) encoding = sensor_msgs::image_encodings::BGR8;
00332   else if (pixel_format == VmbPixelFormatRgba8          ) encoding = sensor_msgs::image_encodings::RGBA8;
00333   else if (pixel_format == VmbPixelFormatBgra8          ) encoding = sensor_msgs::image_encodings::BGRA8;
00334   else if (pixel_format == VmbPixelFormatRgb12          ) encoding = sensor_msgs::image_encodings::TYPE_16UC3;
00335   else if (pixel_format == VmbPixelFormatRgb16          ) encoding = sensor_msgs::image_encodings::TYPE_16UC3;
00336   else
00337     ROS_WARN("Received frame with unsupported pixel format %d", pixel_format);
00338 
00339   if (encoding == "") return false;
00340 
00341   VmbUint32_t nSize;
00342   vimba_frame_ptr->GetImageSize(nSize);
00343   VmbUint32_t step = nSize / height;
00344 
00345   VmbUchar_t *buffer_ptr;
00346   VmbErrorType err = vimba_frame_ptr->GetImage(buffer_ptr);
00347   bool res = false;
00348 
00349   if ( VmbErrorSuccess == err ) {
00350     res = sensor_msgs::fillImage(image,
00351                                  encoding,
00352                                  height,
00353                                  width,
00354                                  step,
00355                                  buffer_ptr);
00356   } else {
00357     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not GetImage. "
00358       << "\n Error: " << errorCodeToMessage(err));
00359   }
00360   return res;
00361 }
00362 
00363 void VimbaROS::updateCameraInfo(const Config& config) {
00364   cam_info_.header.frame_id = config.frame_id;
00365 
00366   // Set the operational parameters in CameraInfo (binning, ROI)
00367   cam_info_.height    = config.height;
00368   cam_info_.width     = config.width;
00369   cam_info_.binning_x = config.binning_x;
00370   cam_info_.binning_y = config.binning_y;
00371   // ROI in CameraInfo is in unbinned coordinates, need to scale up
00372   cam_info_.roi.x_offset = config.roi_offset_x;
00373   cam_info_.roi.y_offset = config.roi_offset_y;
00374   cam_info_.roi.height   = config.roi_height;
00375   cam_info_.roi.width    = config.roi_width;
00376 
00377   // set the new URL and load CameraInfo (if any) from it
00378   if(config.camera_info_url != camera_config_.camera_info_url || first_run_) {
00379     cinfo_->setCameraName(config.frame_id);
00380     if (cinfo_->validateURL(config.camera_info_url)) {
00381       cinfo_->loadCameraInfo(config.camera_info_url);
00382       cam_info_ = cinfo_->getCameraInfo();
00383     } else {
00384       ROS_WARN_STREAM("Camera info URL not valid: " << config.camera_info_url);
00385     }
00386   }
00387 
00388   bool roiMatchesCalibration = (cam_info_.height == config.roi_height
00389                               && cam_info_.width == config.roi_width);
00390   bool resolutionMatchesCalibration = (cam_info_.width == config.width
00391                                    && cam_info_.height == config.height);
00392 
00393   cam_info_.roi.do_rectify = roiMatchesCalibration || resolutionMatchesCalibration;
00394 }
00395 
00405 void VimbaROS::configure(Config& newconfig, uint32_t level) {
00406   // TODO(m): Do not run concurrently with poll().  Tell it to stop running,
00407   // and wait on the lock until it does.
00408   //boost::mutex::scoped_lock lock(mutex_);
00409 
00410   try {
00411     ROS_INFO("dynamic reconfigure level 0x%x", level);
00412 
00413 
00414     // resolve frame ID using tf_prefix parameter
00415     if (newconfig.frame_id == "") {
00416       newconfig.frame_id = "camera";
00417     }
00418 
00419     if (running_ && (level & Levels::RECONFIGURE_CLOSE)) {
00420       // The device has to be closed to change these params
00421       stop();
00422       start(newconfig);
00423     } else if (running_ && (level & Levels::RECONFIGURE_STOP)) {
00424       // The device has to stop streaming to change these params
00425       stop();
00426       start(newconfig);
00427     } else if (!running_) {
00428       camera_config_ = newconfig;
00429       start(newconfig);
00430       first_run_ = false;
00431     } else if (running_) {
00432       // only change those params that can be changed while running
00433       FeaturePtrVector feature_ptr_vec;
00434       vimba_camera_ptr_->GetFeatures(feature_ptr_vec);
00435       updateExposureConfig(newconfig, feature_ptr_vec);
00436       updateGainConfig(newconfig, feature_ptr_vec);
00437       updateWhiteBalanceConfig(newconfig, feature_ptr_vec);
00438       updateImageModeConfig(newconfig, feature_ptr_vec);
00439       updateROIConfig(newconfig, feature_ptr_vec);
00440       updateBandwidthConfig(newconfig, feature_ptr_vec);
00441       updateGPIOConfig(newconfig, feature_ptr_vec);
00442       updateCameraInfo(newconfig);
00443     }
00444     camera_config_ = newconfig;
00445   } catch (const std::exception& e) {
00446     ROS_ERROR_STREAM("Error reconfiguring avt_vimba_camera node : " << e.what());
00447   }
00448 }
00449 
00451 void VimbaROS::updateAcquisitionConfig(const Config& config,
00452                                    FeaturePtrVector feature_ptr_vec) {
00453   bool changed = false;
00454   if (config.acquisition_mode != camera_config_.acquisition_mode || first_run_) {
00455     changed = true;
00456     setFeatureValue("AcquisitionMode", config.acquisition_mode.c_str());
00457   }
00458   if (config.acquisition_rate != camera_config_.acquisition_rate || first_run_) {
00459     changed = true;
00460     setFeatureValue("AcquisitionFrameRateAbs",
00461                     static_cast<float>(config.acquisition_rate));
00462   }
00463   if (config.trigger_mode != camera_config_.trigger_mode || first_run_) {
00464     changed = true;
00465     setFeatureValue("TriggerSource", config.trigger_mode.c_str());
00466   }
00467   if (config.trigger_activation != camera_config_.trigger_activation || first_run_) {
00468     changed = true;
00469     setFeatureValue("TriggerActivation", config.trigger_activation.c_str());
00470   }
00471   if (config.trigger_delay != camera_config_.trigger_delay || first_run_) {
00472     changed = true;
00473     setFeatureValue("TriggerDelayAbs", config.trigger_delay);
00474   }
00475   if(changed){
00476     ROS_INFO_STREAM("New Trigger config: "
00477       << "\n\tAcquisitionMode         : " << config.acquisition_mode   << " was " << camera_config_.acquisition_mode
00478       << "\n\tAcquisitionFrameRateAbs : " << config.acquisition_rate   << " was " << camera_config_.acquisition_rate
00479       << "\n\tTriggerSource           : " << config.trigger_mode       << " was " << camera_config_.trigger_mode
00480       << "\n\tTriggerActivation       : " << config.trigger_activation << " was " << camera_config_.trigger_activation
00481       << "\n\tTriggerDelayAbs            : " << config.trigger_delay      << " was " << camera_config_.trigger_delay);
00482   }
00483 }
00484 
00486 void VimbaROS::updateExposureConfig(const Config& config,
00487                                     FeaturePtrVector feature_ptr_vec) {
00488   bool changed = false;
00489   if (config.exposure != camera_config_.exposure || first_run_) {
00490     changed = true;
00491     setFeatureValue("ExposureTimeAbs", static_cast<float>(config.exposure));
00492   }
00493   if (config.exposure_auto != camera_config_.exposure_auto || first_run_) {
00494     changed = true;
00495     setFeatureValue("ExposureAuto", config.exposure_auto.c_str());
00496   }
00497   if (config.exposure_auto_tol != camera_config_.exposure_auto_tol || first_run_) {
00498     changed = true;
00499     setFeatureValue("ExposureAutoAdjustTol",
00500                     static_cast<VmbInt64_t>(config.exposure_auto_tol));
00501   }
00502   if (config.exposure_auto_max != camera_config_.exposure_auto_max || first_run_) {
00503     changed = true;
00504     setFeatureValue("ExposureAutoMax",
00505                     static_cast<VmbInt64_t>(config.exposure_auto_max));
00506   }
00507   if (config.exposure_auto_min != camera_config_.exposure_auto_min || first_run_) {
00508     changed = true;
00509     setFeatureValue("ExposureAutoMin",
00510                     static_cast<VmbInt64_t>(config.exposure_auto_min));
00511   }
00512   if (config.exposure_auto_outliers != camera_config_.exposure_auto_outliers || first_run_) {
00513     changed = true;
00514     setFeatureValue("ExposureAutoOutliers",
00515                     static_cast<VmbInt64_t>(config.exposure_auto_outliers));
00516   }
00517   if (config.exposure_auto_rate != camera_config_.exposure_auto_rate || first_run_) {
00518     changed = true;
00519     setFeatureValue("ExposureAutoRate",
00520                     static_cast<VmbInt64_t>(config.exposure_auto_rate));
00521   }
00522   if (config.exposure_auto_target != camera_config_.exposure_auto_target || first_run_) {
00523     changed = true;
00524     setFeatureValue("ExposureAutoTarget",
00525                     static_cast<VmbInt64_t>(config.exposure_auto_target));
00526   }
00527   if(changed){
00528     ROS_INFO_STREAM("New Exposure config: "
00529       << "\n\tExposureTimeAbs       : " << config.exposure               << " was " << camera_config_.exposure
00530       << "\n\tExposureAuto          : " << config.exposure_auto          << " was " << camera_config_.exposure_auto
00531       << "\n\tExposureAutoAdjustTol : " << config.exposure_auto_tol      << " was " << camera_config_.exposure_auto_tol
00532       << "\n\tExposureAutoMax       : " << config.exposure_auto_max      << " was " << camera_config_.exposure_auto_max
00533       << "\n\tExposureAutoMin       : " << config.exposure_auto_min      << " was " << camera_config_.exposure_auto_min
00534       << "\n\tExposureAutoOutliers  : " << config.exposure_auto_outliers << " was " << camera_config_.exposure_auto_outliers
00535       << "\n\tExposureAutoRate      : " << config.exposure_auto_rate     << " was " << camera_config_.exposure_auto_rate
00536       << "\n\tExposureAutoTarget    : " << config.exposure_auto_target   << " was " << camera_config_.exposure_auto_target);
00537   }
00538 }
00539 
00541 void VimbaROS::updateGainConfig(const Config& config,
00542                                 FeaturePtrVector feature_ptr_vec) {
00543   bool changed = false;
00544   if (config.gain != camera_config_.gain || first_run_) {
00545     changed = true;
00546     setFeatureValue("Gain", static_cast<float>(config.gain));
00547   }
00548   if (config.gain_auto != camera_config_.gain_auto || first_run_) {
00549     changed = true;
00550     setFeatureValue("GainAuto", config.gain_auto.c_str());
00551   }
00552   if (config.gain_auto_tol != camera_config_.gain_auto_tol || first_run_) {
00553     changed = true;
00554     setFeatureValue("GainAutoAdjustTol",
00555                     static_cast<VmbInt64_t>(config.gain_auto_tol));
00556   }
00557   if (config.gain_auto_max != camera_config_.gain_auto_max || first_run_) {
00558     changed = true;
00559     setFeatureValue("GainAutoMax", static_cast<float>(config.gain_auto_max));
00560   }
00561   if (config.gain_auto_min != camera_config_.gain_auto_min || first_run_) {
00562     changed = true;
00563     setFeatureValue("GainAutoMin",
00564                     static_cast<VmbInt64_t>(config.gain_auto_min));
00565   }
00566   if (config.gain_auto_outliers != camera_config_.gain_auto_outliers || first_run_) {
00567     changed = true;
00568     setFeatureValue("GainAutoMin",
00569                     static_cast<VmbInt64_t>(config.gain_auto_outliers));
00570   }
00571   if (config.gain_auto_rate != camera_config_.gain_auto_rate || first_run_) {
00572     changed = true;
00573     setFeatureValue("GainAutoOutliers",
00574                     static_cast<VmbInt64_t>(config.gain_auto_rate));
00575   }
00576   if (config.gain_auto_target != camera_config_.gain_auto_target || first_run_) {
00577     changed = true;
00578     setFeatureValue("GainAutoRate", static_cast<VmbInt64_t>(config.gain_auto_target));
00579   }
00580   if(changed){
00581     ROS_INFO_STREAM("New Exposure config: "
00582       << "\n\tGain              : " << config.gain               << " was " << camera_config_.gain
00583       << "\n\tGainAuto          : " << config.gain_auto          << " was " << camera_config_.gain_auto
00584       << "\n\tGainAutoAdjustTol : " << config.gain_auto_tol      << " was " << camera_config_.gain_auto_tol
00585       << "\n\tGainAutoMax       : " << config.gain_auto_max      << " was " << camera_config_.gain_auto_max
00586       << "\n\tGainAutoMin       : " << config.gain_auto_min      << " was " << camera_config_.gain_auto_min
00587       << "\n\tGainAutoOutliers  : " << config.gain_auto_outliers << " was " << camera_config_.gain_auto_outliers
00588       << "\n\tGainAutoRate      : " << config.gain_auto_rate     << " was " << camera_config_.gain_auto_rate
00589       << "\n\tGainAutoTarget    : " << config.gain_auto_target   << " was " << camera_config_.gain_auto_target);
00590   }
00591 }
00592 
00594 void VimbaROS::updateWhiteBalanceConfig(const Config& config,
00595                                         FeaturePtrVector feature_ptr_vec){
00596   bool changed = false;
00597   if (config.balance_ratio_abs != camera_config_.balance_ratio_abs || first_run_) {
00598     changed = true;
00599     setFeatureValue("BalanceRatioAbs", static_cast<float>(config.balance_ratio_abs));
00600   }
00601   if (config.balance_ratio_selector != camera_config_.balance_ratio_selector || first_run_) {
00602     changed = true;
00603     setFeatureValue("BalanceRatioSelector", config.balance_ratio_selector.c_str());
00604   }
00605   if (config.whitebalance_auto != camera_config_.whitebalance_auto || first_run_) {
00606     changed = true;
00607     setFeatureValue("BalanceWhiteAuto", config.whitebalance_auto.c_str());
00608   }
00609   if (config.whitebalance_auto_tol != camera_config_.whitebalance_auto_tol || first_run_) {
00610     changed = true;
00611     setFeatureValue("BalanceWhiteAutoAdjustTol", static_cast<VmbInt64_t>(config.whitebalance_auto_tol));
00612   }
00613   if (config.whitebalance_auto_rate != camera_config_.whitebalance_auto_rate || first_run_) {
00614     changed = true;
00615     setFeatureValue("BalanceWhiteAutoRate", static_cast<VmbInt64_t>(config.whitebalance_auto_rate));
00616   }
00617   if(changed){
00618     ROS_INFO_STREAM("New ROI config: "
00619       << "\n\tBalanceRatioAbs           : " << config.balance_ratio_abs      << " was " << camera_config_.balance_ratio_abs
00620       << "\n\tBalanceRatioSelector      : " << config.balance_ratio_selector << " was " << camera_config_.balance_ratio_selector
00621       << "\n\tBalanceWhiteAuto          : " << config.whitebalance_auto      << " was " << camera_config_.whitebalance_auto
00622       << "\n\tBalanceWhiteAutoAdjustTol : " << config.whitebalance_auto_tol  << " was " << camera_config_.whitebalance_auto_tol
00623       << "\n\tBalanceWhiteAutoRate      : " << config.whitebalance_auto_rate << " was " << camera_config_.whitebalance_auto_rate);
00624   }
00625 }
00626 
00628 void VimbaROS::updateImageModeConfig(const Config& config,
00629                                      FeaturePtrVector feature_ptr_vec) {
00630   bool changed = false;
00631   if (config.decimation_x != camera_config_.decimation_x || first_run_) {
00632     changed = true;
00633     setFeatureValue("DecimationHorizontal",
00634                     static_cast<VmbInt64_t>(config.decimation_x));
00635   }
00636   if (config.decimation_y != camera_config_.decimation_y || first_run_) {
00637     changed = true;
00638     setFeatureValue("DecimationVertical", static_cast<VmbInt64_t>(config.decimation_y));
00639   }
00640   if (config.binning_x != camera_config_.binning_x || first_run_) {
00641     changed = true;
00642     setFeatureValue("BinningHorizontal", static_cast<VmbInt64_t>(config.binning_x));
00643   }
00644   if (config.binning_y != camera_config_.binning_y || first_run_) {
00645     changed = true;
00646     setFeatureValue("BinningVertical", static_cast<VmbInt64_t>(config.binning_y));
00647   }
00648   if(changed){
00649     ROS_INFO_STREAM("New Image config: "
00650       << "\n\tDecimationHorizontal : " << config.decimation_x << " was " << camera_config_.decimation_x
00651       << "\n\tDecimationVertical   : " << config.decimation_y << " was " << camera_config_.decimation_y
00652       << "\n\tBinningHorizontal    : " << config.binning_x    << " was " << camera_config_.binning_x
00653       << "\n\tBinningVertical      : " << config.binning_y    << " was " << camera_config_.binning_y);
00654   }
00655 }
00656 
00658 void VimbaROS::updateROIConfig(Config& config,
00659                                FeaturePtrVector feature_ptr_vec) {
00660   bool changed = false;
00661 
00662   // Region of interest configuration
00663   // Make sure ROI fits in image
00664   config.width        = std::min(config.width,  (int)vimba_camera_max_width_);
00665   config.height       = std::min(config.height, (int)vimba_camera_max_height_);
00666   config.roi_offset_x = std::min(config.roi_offset_x, config.width - 1);
00667   config.roi_offset_y = std::min(config.roi_offset_y, config.height - 1);
00668   config.roi_width    = std::min(config.roi_width,  config.width  - config.roi_offset_x);
00669   config.roi_height   = std::min(config.roi_height, config.height - config.roi_offset_y);
00670   // If width or height is 0, set it as large as possible
00671   int width  = config.roi_width  ? config.roi_width  : vimba_camera_max_width_  - config.roi_offset_x;
00672   int height = config.roi_height ? config.roi_height : vimba_camera_max_height_ - config.roi_offset_y;
00673 
00674   // Adjust full-res ROI to binning ROI
00676   int offset_x = config.roi_offset_x / config.binning_x;
00677   int offset_y = config.roi_offset_y / config.binning_y;
00678   unsigned int right_x  = (config.roi_offset_x + width  + config.binning_x - 1) / config.binning_x;
00679   unsigned int bottom_y = (config.roi_offset_y + height + config.binning_y - 1) / config.binning_y;
00680   // Rounding up is bad when at max resolution which is not divisible by the amount of binning
00681   right_x  = std::min(right_x,  (unsigned)(config.width  / config.binning_x));
00682   bottom_y = std::min(bottom_y, (unsigned)(config.height / config.binning_y));
00683   width    = right_x  - offset_x;
00684   height   = bottom_y - offset_y;
00685 
00686   config.width  = width;
00687   config.height = height;
00688 
00689   if (config.roi_offset_x != camera_config_.roi_offset_x || first_run_) {
00690     changed = true;
00691     setFeatureValue("OffsetX", static_cast<VmbInt64_t>(config.roi_offset_x));
00692   }
00693   if (config.roi_offset_y != camera_config_.roi_offset_y || first_run_) {
00694     changed = true;
00695     setFeatureValue("OffsetY", static_cast<VmbInt64_t>(config.roi_offset_y));
00696   }
00697   if (config.width != camera_config_.width || first_run_) {
00698     changed = true;
00699     setFeatureValue("Width", static_cast<VmbInt64_t>(config.width));
00700   }
00701   if (config.height != camera_config_.height || first_run_) {
00702     changed = true;
00703     setFeatureValue("Height", static_cast<VmbInt64_t>(config.height));
00704   }
00705 
00706   if(changed){
00707     ROS_INFO_STREAM("New ROI config: "
00708       << "\n\tOffsetX : " << config.roi_offset_x << " was " << camera_config_.roi_offset_x
00709       << "\n\tOffsetY : " << config.roi_offset_y << " was " << camera_config_.roi_offset_y
00710       << "\n\tWidth   : " << config.width        << " was " << camera_config_.width
00711       << "\n\tHeight  : " << config.height   << " was " << camera_config_.height);
00712   }
00713 }
00714 
00716 void VimbaROS::updateBandwidthConfig(const Config& config,
00717                                      FeaturePtrVector feature_ptr_vec) {
00718   bool changed = false;
00719   if (config.stream_bytes_per_second
00720       != camera_config_.stream_bytes_per_second || first_run_) {
00721     changed = true;
00722     setFeatureValue("StreamBytesPerSecond",
00723                     static_cast<VmbInt64_t>(config.stream_bytes_per_second));
00724   }
00725   if(changed){
00726     ROS_INFO_STREAM("New Bandwidth config: "
00727       << "\n\tStreamBytesPerSecond : " << config.stream_bytes_per_second << " was " << camera_config_.stream_bytes_per_second);
00728   }
00729 }
00730 
00732 void VimbaROS::updatePixelFormatConfig(const Config& config,
00733                                        FeaturePtrVector feature_ptr_vec) {
00734   bool changed = false;
00735   if (config.pixel_format != camera_config_.pixel_format || first_run_) {
00736     changed = true;
00737     setFeatureValue("PixelFormat", config.pixel_format.c_str());
00738   }
00739   if(changed){
00740     ROS_INFO_STREAM("New PixelFormat config: "
00741       << "\n\tPixelFormat : " << config.pixel_format << " was " << camera_config_.pixel_format);
00742   }
00743 }
00744 
00746 void VimbaROS::updateGPIOConfig(const Config& config,
00747                                      FeaturePtrVector feature_ptr_vec) {
00748   bool changed = false;
00749   if (config.sync_in_selector
00750       != camera_config_.sync_in_selector || first_run_) {
00751     changed = true;
00752     setFeatureValue("SyncInSelector", config.sync_in_selector.c_str());
00753   }
00754   if (config.sync_out_polarity
00755       != camera_config_.sync_out_polarity || first_run_) {
00756     changed = true;
00757     setFeatureValue("SyncOutPolarity", config.sync_out_polarity.c_str());
00758   }
00759   if (config.sync_out_selector
00760       != camera_config_.sync_out_selector || first_run_) {
00761     changed = true;
00762     setFeatureValue("SyncOutSelector", config.sync_out_selector.c_str());
00763   }
00764   if (config.sync_out_source
00765       != camera_config_.sync_out_source || first_run_) {
00766     changed = true;
00767     setFeatureValue("SyncOutSource", config.sync_out_source.c_str());
00768   }
00769   if(changed){
00770     ROS_INFO_STREAM("New Bandwidth config: "
00771       << "\n\tSyncInSelector  : " << config.sync_in_selector  << " was " << camera_config_.sync_in_selector
00772       << "\n\tSyncOutPolarity : " << config.sync_out_polarity << " was " << camera_config_.sync_out_polarity
00773       << "\n\tSyncOutSelector : " << config.sync_out_selector << " was " << camera_config_.sync_out_selector
00774       << "\n\tSyncOutSource   : " << config.sync_out_source   << " was " << camera_config_.sync_out_source);
00775   }
00776 }
00777 
00778 // Template function to GET a feature value from the camera
00779 template<typename T>
00780 bool VimbaROS::getFeatureValue(const std::string& feature_str, T& val) {
00781   VmbErrorType err;
00782   FeaturePtr vimba_feature_ptr;
00783   VmbFeatureDataType data_type;
00784   err = vimba_camera_ptr_->GetFeatureByName(feature_str.c_str(),
00785                                             vimba_feature_ptr);
00786   if (VmbErrorSuccess == err) {
00787     bool readable;
00788     vimba_feature_ptr->IsReadable(readable);
00789     if (readable) {
00790       //VmbFeatureDataType data_type;
00791       vimba_feature_ptr->GetDataType(data_type);
00792       if ( VmbErrorSuccess != err ) {
00793         std::cout << "[Could not get feature Data Type. Error code: "
00794                   << err << "]" << std::endl;
00795       } else {
00796         std::string strValue;
00797         switch ( data_type ) {
00798           case VmbFeatureDataBool:
00799           bool bValue;
00800           err = vimba_feature_ptr->GetValue(bValue);
00801           if (VmbErrorSuccess == err) {
00802             val = static_cast<T>(bValue);
00803           }
00804           break;
00805           case VmbFeatureDataFloat:
00806           double fValue;
00807           err = vimba_feature_ptr->GetValue(fValue);
00808           if (VmbErrorSuccess == err) {
00809             val = static_cast<T>(fValue);
00810           }
00811           break;
00812           case VmbFeatureDataInt:
00813           VmbInt64_t  nValue;
00814           err = vimba_feature_ptr->GetValue(nValue);
00815           if (VmbErrorSuccess == err) {
00816             val = static_cast<T>(nValue);
00817           }
00818           break;
00819         }
00820         if (VmbErrorSuccess != err) {
00821           ROS_ERROR_STREAM("Could not get feature value. Error code: "
00822                     << errorCodeToMessage(err));
00823         }
00824       }
00825     } else {
00826       ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature "
00827                        << feature_str
00828                        << " is not readable.");
00829     }
00830   } else {
00831     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not get feature " << feature_str);
00832   }
00833   ROS_INFO_STREAM("Asking for feature " << feature_str << " with datatype " << FeatureDataType[data_type] << " and value " << val);
00834   return (VmbErrorSuccess == err);
00835 }
00836 
00837 // Function to GET a feature value from the camera, overloaded to strings
00838 bool VimbaROS::getFeatureValue(const std::string& feature_str, std::string& val) {
00839   VmbErrorType err;
00840   FeaturePtr vimba_feature_ptr;
00841   VmbFeatureDataType data_type;
00842   err = vimba_camera_ptr_->GetFeatureByName(feature_str.c_str(),
00843                                             vimba_feature_ptr);
00844   if (VmbErrorSuccess == err) {
00845     bool readable;
00846     vimba_feature_ptr->IsReadable(readable);
00847     if (readable) {
00848       //VmbFeatureDataType data_type;
00849       vimba_feature_ptr->GetDataType(data_type);
00850       if ( VmbErrorSuccess != err ) {
00851         std::cout << "[Could not get feature Data Type. Error code: "
00852                   << err << "]" << std::endl;
00853       } else {
00854         std::string strValue;
00855         switch ( data_type ) {
00856           case VmbFeatureDataEnum:
00857           err = vimba_feature_ptr->GetValue(strValue);
00858           if (VmbErrorSuccess == err) {
00859             val = strValue;
00860           }
00861           break;
00862           case VmbFeatureDataString:
00863           err = vimba_feature_ptr->GetValue(strValue);
00864           if (VmbErrorSuccess == err) {
00865             val = strValue;
00866           }
00867           break;
00868         }
00869         if (VmbErrorSuccess != err) {
00870           ROS_ERROR_STREAM("Could not get feature value. Error code: "
00871                     << errorCodeToMessage(err));
00872         }
00873       }
00874     } else {
00875       ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature "
00876                        << feature_str
00877                        << " is not readable.");
00878     }
00879   } else {
00880     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not get feature " << feature_str);
00881   }
00882   ROS_DEBUG_STREAM("Asking for feature " << feature_str << " with datatype " << FeatureDataType[data_type] << " and value " << val);
00883   return (VmbErrorSuccess == err);
00884 }
00885 
00886 // Template function to SET a feature value from the camera
00887 template<typename T>
00888 bool VimbaROS::setFeatureValue(const std::string& feature_str, const T& val) {
00889   VmbErrorType err;
00890   FeaturePtr vimba_feature_ptr;
00891   err = vimba_camera_ptr_->GetFeatureByName(feature_str.c_str(),
00892                                             vimba_feature_ptr);
00893   if (VmbErrorSuccess == err) {
00894     bool writable;
00895     err = vimba_feature_ptr->IsWritable(writable);
00896     if (VmbErrorSuccess == err) {
00897       if (writable) {
00898         ROS_DEBUG_STREAM("Setting feature " << feature_str << " value " << val);
00899         VmbFeatureDataType data_type;
00900         err == vimba_feature_ptr->GetDataType(data_type);
00901         if (VmbErrorSuccess == err) {
00902           if (data_type == VmbFeatureDataEnum) {
00903             bool available;
00904             err = vimba_feature_ptr->IsValueAvailable(val, available);
00905             if (VmbErrorSuccess == err) {
00906               if (available){
00907                 err = vimba_feature_ptr->SetValue(val);
00908               } else {
00909                 ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature "
00910                                  << feature_str
00911                                  << " is available now.");
00912               }
00913             } else {
00914               ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature " << feature_str <<
00915                 ": value unavailable\n\tERROR " << errorCodeToMessage(err));
00916             }
00917           } else {
00918             err = vimba_feature_ptr->SetValue(val);
00919           }
00920         } else {
00921           ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature " << feature_str <<
00922             ": Bad data type\n\tERROR " << errorCodeToMessage(err));
00923         }
00924       } else {
00925         ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature "
00926                          << feature_str
00927                          << " is not writable.");
00928       }
00929     } else {
00930       ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Feature " << feature_str << ": ERROR " 
00931                        << errorCodeToMessage(err));
00932     }
00933   } else {
00934     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not get feature " << feature_str
00935       << "\n Error: " << errorCodeToMessage(err));
00936   }
00937   return (VmbErrorSuccess == err);
00938 }
00939 
00940 
00941 // Template function to RUN a command
00942 bool VimbaROS::runCommand(const std::string& command_str) {
00943   FeaturePtr feature_ptr;
00944   if ( VmbErrorSuccess == vimba_camera_ptr_->GetFeatureByName( command_str.c_str(), feature_ptr ))
00945   {
00946     if ( VmbErrorSuccess == feature_ptr->RunCommand() )
00947     {
00948       bool is_command_done = false;
00949       do
00950       {
00951         if ( VmbErrorSuccess != feature_ptr->IsCommandDone(is_command_done) )
00952         {
00953           break;
00954         }
00955         ROS_INFO_STREAM_THROTTLE(1,"Waiting for command " << command_str.c_str() << "...");
00956       } while ( false == is_command_done );
00957       ROS_INFO_STREAM("Command " << command_str.c_str() << " done!");
00958     }
00959   }
00960 }
00961 
00962 
00969 std::string VimbaROS::errorCodeToMessage(VmbErrorType error) {
00970   std::map<VmbErrorType, std::string>::const_iterator iter =
00971     vimba_error_code_to_message_.find(error);
00972   if ( vimba_error_code_to_message_.end() != iter ) {
00973     return iter->second;
00974   }
00975   return "Unsupported error code passed.";
00976 }
00977 
00978 void VimbaROS::listAvailableCameras(void) {
00979   std::string name;
00980   CameraPtrVector cameras;
00981 
00982   if (VmbErrorSuccess == vimba_system_.Startup()) {
00983     if (VmbErrorSuccess == vimba_system_.GetCameras(cameras)) {
00984       for (CameraPtrVector::iterator iter = cameras.begin();
00985       cameras.end() != iter;
00986       ++iter) {
00987         if (VmbErrorSuccess == (*iter)->GetName(name)) {
00988           ROS_INFO_STREAM("[AVT_Vimba_ROS]: Found camera: ");
00989         }
00990         std::string strID;            // The ID of the cam
00991         std::string strName;          // The name of the cam
00992         std::string strModelname;     // The model name of the cam
00993         std::string strSerialNumber;  // The serial number of the cam
00994         std::string strInterfaceID;  // The ID of the interface the cam is connected to
00995         VmbErrorType err = (*iter)->GetID( strID );
00996         if ( VmbErrorSuccess != err )
00997         {
00998             ROS_ERROR_STREAM("[Could not get camera ID. Error code: " << err << "]");
00999         }
01000         err = (*iter)->GetName( strName );
01001         if ( VmbErrorSuccess != err )
01002         {
01003             ROS_ERROR_STREAM("[Could not get camera name. Error code: " << err << "]");
01004         }
01005 
01006         err = (*iter)->GetModel( strModelname );
01007         if ( VmbErrorSuccess != err )
01008         {
01009             ROS_ERROR_STREAM("[Could not get camera mode name. Error code: " << err << "]");
01010         }
01011 
01012         err = (*iter)->GetSerialNumber( strSerialNumber );
01013         if ( VmbErrorSuccess != err )
01014         {
01015             ROS_ERROR_STREAM("[Could not get camera serial number. Error code: " << err << "]");
01016         }
01017 
01018         err = (*iter)->GetInterfaceID( strInterfaceID );
01019         if ( VmbErrorSuccess != err )
01020         {
01021             ROS_ERROR_STREAM("[Could not get interface ID. Error code: " << err << "]");
01022         }
01023         ROS_INFO_STREAM("\t\t/// Camera Name: " << strName);
01024         ROS_INFO_STREAM("\t\t/// Model Name: " << strModelname);
01025         ROS_INFO_STREAM("\t\t/// Camera ID: " << strID);
01026         ROS_INFO_STREAM("\t\t/// Serial Number: " << strSerialNumber);
01027         ROS_INFO_STREAM("\t\t/// @ Interface ID: " << strInterfaceID);
01028 
01029       }
01030     }
01031   }
01032 }
01033 
01034 std::string VimbaROS::interfaceToString(VmbInterfaceType interfaceType) {
01035   switch ( interfaceType ) {
01036     case VmbInterfaceFirewire: return "FireWire";
01037       break;
01038     case VmbInterfaceEthernet: return "GigE";
01039       break;
01040     case VmbInterfaceUsb: return "USB";
01041       break;
01042     default: return "Unknown";
01043   }
01044 }
01045 
01046 std::string VimbaROS::accessModeToString(VmbAccessModeType modeType){
01047   std::string s;
01048   if (modeType & VmbAccessModeFull)        s = std::string("Read and write access");
01049   else if (modeType & VmbAccessModeRead)   s = std::string("Only read access");
01050   else if (modeType & VmbAccessModeConfig) s = std::string("Device configuration access");
01051   else if (modeType & VmbAccessModeLite)   s = std::string("Device read/write access without feature access (only addresses)");
01052   else if (modeType & VmbAccessModeNone)   s = std::string("No access");
01053   return s;
01054 }
01055 
01056 int VimbaROS::getTriggerModeInt(std::string mode_str){
01057   int mode;
01058   if (mode_str == TriggerMode[Freerun]){
01059     mode = Freerun;
01060   } else if (mode_str == TriggerMode[FixedRate]){
01061     mode = FixedRate;
01062   } else if (mode_str == TriggerMode[Software]){
01063     mode = Software;
01064   } else if (mode_str == TriggerMode[SyncIn1]){
01065     mode = SyncIn1;
01066   } else if (mode_str == TriggerMode[SyncIn2]){
01067     mode = SyncIn2;
01068   } else if (mode_str == TriggerMode[SyncIn3]){
01069     mode = SyncIn3;
01070   } else if (mode_str == TriggerMode[SyncIn4]){
01071     mode = SyncIn4;
01072   }
01073   return mode;
01074 }
01075 
01076 CameraPtr VimbaROS::openCamera(std::string id_str) {
01077   // Details:   The ID might be one of the following:
01078   //            "IP:169.254.12.13",
01079   //            "MAC:000f31000001",
01080   //            or a plain serial number: "1234567890".
01081 
01082   CameraPtr camera;
01083   VmbErrorType err = vimba_system_.GetCameraByID(id_str.c_str(), camera);
01084   if (VmbErrorSuccess == err) {
01085     std::string cam_id, cam_name, cam_model, cam_sn, cam_int_id;
01086     VmbInterfaceType cam_int_type;
01087     VmbAccessModeType accessMode;// = VmbAccessModeNone;
01088     camera->GetID(cam_id);
01089     camera->GetName(cam_name);
01090     camera->GetModel(cam_model);
01091     camera->GetSerialNumber(cam_sn);
01092     camera->GetInterfaceID(cam_int_id);
01093     camera->GetInterfaceType(cam_int_type);
01094     err = camera->GetPermittedAccess(accessMode);
01095 
01096     ROS_INFO_STREAM("[AVT_Vimba_ROS]: Opened camera with"
01097     << "\n\t\t * Name     : " << cam_name
01098     << "\n\t\t * Model    : " << cam_model
01099     << "\n\t\t * ID       : " << cam_id
01100     << "\n\t\t * S/N      : " << cam_sn
01101     << "\n\t\t * Itf. ID  : " << cam_int_id
01102     << "\n\t\t * Itf. Type: " << interfaceToString(cam_int_type)
01103     << "\n\t\t * Access   : " << accessModeToString(accessMode));
01104 
01105     err = camera->Open(VmbAccessModeFull);
01106     if (VmbErrorSuccess == err){
01107       printAllCameraFeatures(camera);
01108     } else {
01109       ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not get camera " << id_str
01110         << "\n Error: " << errorCodeToMessage(err));
01111     }
01112   } else {
01113     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not get camera " << id_str
01114       << "\n Error: " << errorCodeToMessage(err));
01115   }
01116   running_ = true;
01117   return camera;
01118 }
01119 
01120 void VimbaROS::printAllCameraFeatures(CameraPtr camera) {
01121   VmbErrorType err;
01122   FeaturePtrVector features;
01123 
01124   // The static details of a feature
01125   std::string strName;           // The name of the feature
01126   std::string strDisplayName;    // The display name of the feature
01127   std::string strTooltip;        // A short description of the feature
01128   std::string strDescription;    // A long description of the feature
01129   std::string strCategory;       // A category to group features
01130   std::string strSFNCNamespace;  // The Std Feature Naming Convention namespace
01131   std::string strUnit;           // The measurement unit of the value
01132   VmbFeatureDataType eType;      // The data type of the feature
01133 
01134   // The changeable value of a feature
01135   VmbInt64_t  nValue;
01136   std::string strValue;
01137 
01138   std::stringstream strError;
01139 
01140   // Fetch all features of our cam
01141   err = camera->GetFeatures(features);
01142   if ( VmbErrorSuccess == err ) {
01143     // Query all static details as well as the value of
01144     // all fetched features and print them out.
01145     for (   FeaturePtrVector::const_iterator iter = features.begin();
01146       features.end() != iter;
01147       ++iter ) {
01148       err = (*iter)->GetName(strName);
01149       if (VmbErrorSuccess != err) {
01150         strError << "[Could not get feature Name. Error code: " << err << "]";
01151         strName.assign(strError.str());
01152       }
01153 
01154       err = (*iter)->GetDisplayName(strDisplayName);
01155       if (VmbErrorSuccess != err) {
01156         strError << "[Could not get feature Display Name. Error code: "
01157                  << err << "]";
01158         strDisplayName.assign(strError.str());
01159       }
01160 
01161       err = (*iter)->GetToolTip(strTooltip);
01162       if (VmbErrorSuccess != err) {
01163         strError << "[Could not get feature Tooltip. Error code: "
01164                  << err << "]";
01165         strTooltip.assign(strError.str());
01166       }
01167 
01168       err = (*iter)->GetDescription(strDescription);
01169       if (VmbErrorSuccess != err) {
01170         strError << "[Could not get feature Description. Error code: "
01171                  << err << "]";
01172         strDescription.assign(strError.str());
01173       }
01174 
01175       err = (*iter)->GetCategory(strCategory);
01176       if (VmbErrorSuccess != err) {
01177         strError << "[Could not get feature Category. Error code: "
01178                  << err << "]";
01179         strCategory.assign(strError.str());
01180       }
01181 
01182       err = (*iter)->GetSFNCNamespace(strSFNCNamespace);
01183       if (VmbErrorSuccess != err) {
01184         strError << "[Could not get feature SNFC Namespace. Error code: "
01185                  << err << "]";
01186         strSFNCNamespace.assign(strError.str());
01187       }
01188 
01189       err = (*iter)->GetUnit(strUnit);
01190       if (VmbErrorSuccess != err) {
01191         strError << "[Could not get feature Unit. Error code: " << err << "]";
01192         strUnit.assign(strError.str());
01193       }
01194 
01195       std::cout << "/// Feature Name: " << strName << std::endl;
01196       std::cout << "/// Display Name: " << strDisplayName << std::endl;
01197       std::cout << "/// Tooltip: " << strTooltip << std::endl;
01198       std::cout << "/// Description: " << strDescription << std::endl;
01199       std::cout << "/// SNFC Namespace: " << strSFNCNamespace << std::endl;
01200       std::cout << "/// Unit: " << strUnit << std::endl;
01201       std::cout << "/// Value: ";
01202 
01203       err = (*iter)->GetDataType(eType);
01204       if ( VmbErrorSuccess != err ) {
01205         std::cout << "[Could not get feature Data Type. Error code: "
01206                   << err << "]" << std::endl;
01207       } else {
01208         switch ( eType ) {
01209           case VmbFeatureDataBool:
01210           bool bValue;
01211           err = (*iter)->GetValue(bValue);
01212           if (VmbErrorSuccess == err) {
01213             std::cout << bValue << " bool" << std::endl;
01214           }
01215           break;
01216           case VmbFeatureDataEnum:
01217           err = (*iter)->GetValue(strValue);
01218           if (VmbErrorSuccess == err) {
01219             std::cout << strValue << " str Enum" << std::endl;
01220           }
01221           break;
01222           case VmbFeatureDataFloat:
01223           double fValue;
01224           err = (*iter)->GetValue(fValue);
01225           {
01226             std::cout << fValue << " float" << std::endl;
01227           }
01228           break;
01229           case VmbFeatureDataInt:
01230           err = (*iter)->GetValue(nValue);
01231           {
01232             std::cout << nValue << " int" << std::endl;
01233           }
01234           break;
01235           case VmbFeatureDataString:
01236           err = (*iter)->GetValue(strValue);
01237           {
01238             std::cout << strValue << " str" << std::endl;
01239           }
01240           break;
01241           case VmbFeatureDataCommand:
01242           default:
01243           std::cout << "[None]" << std::endl;
01244           break;
01245         }
01246         if (VmbErrorSuccess != err) {
01247           std::cout << "Could not get feature value. Error code: "
01248                     << err << std::endl;
01249         }
01250       }
01251 
01252       std::cout << std::endl;
01253     }
01254   } else {
01255     std::cout << "Could not get features. Error code: " << err << std::endl;
01256   }
01257 }
01258 
01259 void VimbaROS::initApi(void) {
01260   vimba_error_code_to_message_[VmbErrorSuccess]        = "Success.";
01261   vimba_error_code_to_message_[VmbErrorApiNotStarted]  = "API not started.";
01262   vimba_error_code_to_message_[VmbErrorNotFound]       = "Not found.";
01263   vimba_error_code_to_message_[VmbErrorBadHandle]      = "Invalid handle ";
01264   vimba_error_code_to_message_[VmbErrorDeviceNotOpen]  = "Device not open.";
01265   vimba_error_code_to_message_[VmbErrorInvalidAccess]  = "Invalid access.";
01266   vimba_error_code_to_message_[VmbErrorBadParameter]   = "Bad parameter.";
01267   vimba_error_code_to_message_[VmbErrorStructSize]     = "Wrong DLL version.";
01268   vimba_error_code_to_message_[VmbErrorWrongType]      = "Wrong type.";
01269   vimba_error_code_to_message_[VmbErrorInvalidValue]   = "Invalid value.";
01270   vimba_error_code_to_message_[VmbErrorTimeout]        = "Timeout.";
01271   vimba_error_code_to_message_[VmbErrorOther]          = "TL error.";
01272   vimba_error_code_to_message_[VmbErrorInvalidCall]    = "Invalid call.";
01273   vimba_error_code_to_message_[VmbErrorNoTL]           = "TL not loaded.";
01274   vimba_error_code_to_message_[VmbErrorNotImplemented] = "Not implemented.";
01275   vimba_error_code_to_message_[VmbErrorNotSupported]   = "Not supported.";
01276   vimba_error_code_to_message_[VmbErrorResources]      = "Resource not available.";
01277   vimba_error_code_to_message_[VmbErrorInternalFault]  = "Unexpected fault in VmbApi or driver.";
01278   vimba_error_code_to_message_[VmbErrorMoreData]       = "More data returned than memory provided.";
01279 
01280   if (VmbErrorSuccess == vimba_system_.Startup()) {
01281     ROS_INFO_STREAM("[AVT_Vimba_ROS]: AVT Vimba System initialized successfully");
01282     listAvailableCameras();
01283   } else {
01284     ROS_ERROR_STREAM("[AVT_Vimba_ROS]: Could not start Vimba system: "
01285       << errorCodeToMessage(vimba_system_.Startup()) );
01286   }
01287 }
01288 };


avt_vimba_camera
Author(s): Miquel Massot , Allied Vision Technologies
autogenerated on Thu Aug 27 2015 12:29:49