ximea_ros_cluster.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 
00003 Copyright 2015  Abdelhamid El-Bably (University of Waterloo)
00004                       [ahelbably@uwaterloo.ca]
00005                 Arun Das (University of Waterloo)
00006                       [adas@uwaterloo.ca]
00007                 Michael Tribou (University of Waterloo)
00008                       [mjtribou@uwaterloo.ca]
00009 
00010 All rights reserved.
00011 
00012 ********************************************************************************/
00013 
00014 #include <ximea_camera/ximea_ros_cluster.h>
00015 #include <string>
00016 #include <vector>
00017 int serial_nos[3] = { 32300651 ,  33300151 , 32301251};
00018 std::string cam_names[3] = {std::string("camera1"), std::string("camera2"), std::string("camera3")};
00019 std::string calib_file_names[3] =
00020 {
00021   "package://mcptam/calibrations/camera1.yaml",
00022   "package://mcptam/calibrations/camera2.yaml",
00023   "package://mcptam/calibrations/camera3.yaml"
00024 };
00025 
00026 std::string getCamNameFromYaml(std::string file_name)
00027 {
00028   std::ifstream fin(file_name.c_str());
00029   if (fin.fail())
00030   {
00031     ROS_ERROR_STREAM("could not open file " << file_name.c_str() << std::endl);
00032     exit(-1);  // this has to be changed
00033   }
00034 
00035   YAML::Node doc = YAML::LoadFile(file_name);
00036   std::string ret;
00037   ret = doc["cam_name"].as<std::string>();
00038   return ret;
00039 }
00040 
00041 ximea_ros_cluster::ximea_ros_cluster(int num_cams) : USB_BUS_SAFETY_MARGIN(0), USB3_BANDWIDTH(2400)
00042 {
00043   num_cams_ = num_cams;
00044   devices_open_ = false;
00045   for (int i = 0 ; i < num_cams; i ++)
00046   {
00047     ros::NodeHandle nh(std::string("/") + cam_names[i]);
00048     add_camera(ximea_ros_driver(nh, cam_names[i], serial_nos[i], calib_file_names[i]));
00049   }
00050   // must limit the cluster usb bandwidth to support > 2 cameras
00051   xiSetParamInt(0, XI_PRM_AUTO_BANDWIDTH_CALCULATION, XI_OFF);
00052   fixed_init_ = true;
00053 }
00054 
00055 ximea_ros_cluster::ximea_ros_cluster(std::vector<std::string> filenames) : USB_BUS_SAFETY_MARGIN(0), USB3_BANDWIDTH(2400)
00056 {
00057   devices_open_ = false;
00058   for (int i = 0 ; i < filenames.size(); i ++)
00059   {
00060     std::string cam_name = getCamNameFromYaml(filenames[i]);
00061     ros::NodeHandle nh(std::string("/") + cam_name);
00062     add_camera(ximea_ros_driver(nh, filenames[i]));
00063   }
00064 
00065   // must limit the cluster usb bandwidth to support > 2 cameras
00066   xiSetParamInt(0, XI_PRM_AUTO_BANDWIDTH_CALCULATION, XI_OFF);
00067   fixed_init_ = false;
00068 }
00069 
00070 void ximea_ros_cluster::add_camera(ximea_ros_driver xd)
00071 {
00072   if (devices_open_)
00073   {
00074     clusterEnd();
00075   }
00076   cams_.push_back(xd);
00077   num_cams_++;
00078   threads_.resize(num_cams_);
00079   ROS_INFO_STREAM("done camera add");
00080 }
00081 
00082 void ximea_ros_cluster::remove_camera(int serial_no)
00083 {
00084   if (devices_open_)
00085   {
00086     clusterEnd();
00087   }
00088   for (int i = 0; i < cams_.size(); i++)
00089   {
00090     if (serial_no == cams_[i].getSerialNo())
00091     {
00092       cams_.erase(cams_.begin() + i);
00093       delete threads_[i];
00094       threads_.erase(threads_.begin() + i);
00095       break;
00096     }
00097   }
00098   num_cams_--;
00099 }
00100 
00101 void ximea_ros_cluster::clusterInit()
00102 {
00103   for (int i = 0; i < cams_.size(); i++)
00104   {
00105     ROS_INFO_STREAM("opening device " << cams_[i].getSerialNo());
00106     cams_[i].openDevice();
00107     if (fixed_init_)
00108     {
00109       cams_[i].setImageDataFormat("XI_MONO8");
00110       cams_[i].setROI(200, 200, 900, 600);
00111       cams_[i].setExposure(10000);
00112     }
00113     cams_[i].limitBandwidth((USB3_BANDWIDTH) - USB_BUS_SAFETY_MARGIN);
00114     cams_[i].startAcquisition();
00115     // TODO: remove this into constructor
00116   }
00117   devices_open_ = true;
00118 }
00119 
00120 void ximea_ros_cluster::clusterEnd()
00121 {
00122   for (int i = 0; i < cams_.size(); i  ++)
00123   {
00124     cams_[i].stopAcquisition();
00125     cams_[i].closeDevice();
00126   }
00127   devices_open_ = false;
00128 }
00129 
00130 // triggered_acquire
00131 void ximea_ros_cluster::clusterAcquire()
00132 {
00133   for (int i = 0; i < cams_.size(); i  ++)
00134   {
00135     threads_[i] = new boost::thread(&ximea_driver::acquireImage, &cams_[i]);
00136   }
00137   for (int i = 0; i < cams_.size(); i  ++)
00138   {
00139     threads_[i]->join();
00140     delete threads_[i];
00141   }
00142 }
00143 
00144 void ximea_ros_cluster::clusterPublishImages()
00145 {
00146   // TODO: might want to think as to how to multithread this
00147   for (int i = 0; i < cams_.size(); i  ++)
00148   {
00149     threads_[i] = new boost::thread(&ximea_ros_driver::publishImage, &cams_[i], ros::Time::now());
00150   }
00151   for (int i = 0; i < cams_.size(); i  ++)
00152   {
00153     threads_[i]->join();
00154     delete threads_[i];
00155   }
00156 }
00157 
00158 
00159 void ximea_ros_cluster::clusterPublishCamInfo()
00160 {
00161   for (int i = 0 ; i < cams_.size(); i ++)
00162   {
00163     cams_[i].publishCamInfo(ros::Time::now());
00164   }
00165 }
00166 
00167 void ximea_ros_cluster::clusterPublishImageAndCamInfo()
00168 {
00169   ros::Time curr_time = ros::Time::now();
00170   for (int i = 0; i < cams_.size(); i  ++)
00171   {
00172     threads_[i] = new boost::thread(&ximea_ros_driver::publishImage, &cams_[i], curr_time);
00173   }
00174   for (int i = 0; i < cams_.size(); i  ++)
00175   {
00176     threads_[i]->join();
00177     delete threads_[i];
00178   }
00179   for (int i = 0 ; i < cams_.size(); i ++)
00180   {
00181     cams_[i].publishCamInfo(curr_time);
00182   }
00183 }
00184 
00185 int ximea_ros_cluster::getCameraIndex(int serial_no)
00186 {
00187   for (int i = 0; i < cams_.size(); i++)
00188   {
00189     if (serial_no == cams_[i].getSerialNo())
00190     {
00191       return i;
00192     }
00193   }
00194   return -1;
00195 }
00196 
00197 void ximea_ros_cluster::setExposure(int serial_no, int time)
00198 {
00199   int idx = getCameraIndex(serial_no) ;
00200   if (idx != -1)
00201   {
00202     cams_[idx].setExposure(time);
00203   }
00204 }
00205 
00206 void ximea_ros_cluster::setImageDataFormat(int serial_no, std::string s)
00207 {
00208   int idx = getCameraIndex(serial_no) ;
00209   if (idx != -1)
00210   {
00211     cams_[idx].setImageDataFormat(s);
00212   }
00213 }
00214 
00215 void ximea_ros_cluster::setROI(int serial_no, int l, int t, int w, int h)
00216 {
00217   int idx = getCameraIndex(serial_no) ;
00218   if (idx != -1)
00219   {
00220     cams_[idx].setROI(l, t, w, h);
00221   }
00222 }


ximea_camera
Author(s): Abdelhamid El-Bably, Arun Das, Michael Tribou
autogenerated on Thu Jun 6 2019 21:17:12