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
00034
00035 #include <ueye/CameraNode.h>
00036
00037 namespace ueye {
00038
00039 const std::string configFileName(Camera &cam){
00040 stringstream ss;
00041 ss << "Cal-" << cam.getCameraName() << "-" << cam.getZoom() << "-" << cam.getCameraSerialNo() << ".txt";
00042 return ss.str();
00043 }
00044
00045 CameraNode::CameraNode(ros::NodeHandle node, ros::NodeHandle priv_nh)
00046 : it_(node)
00047 {
00048 running_ = false;
00049 configured_ = false;
00050 force_streaming_ = false;
00051 auto_exposure_ = false;
00052 auto_gain_ = false;
00053 trigger_mode_ = zoom_ = -1;
00054
00055
00056 char *Version;
00057 int Major, Minor, Build;
00058 if(cam_.checkVersion(Major, Minor, Build, Version)){
00059 ROS_INFO("Loaded uEye SDK %s.", Version);
00060 }else{
00061 ROS_WARN("Loaded uEye SDK %d.%d.%d. Expecting %s.", Major, Minor, Build, Version);
00062 }
00063
00064
00065 int NumberOfCameras = cam_.getNumberOfCameras();
00066 if(NumberOfCameras > 0){
00067 if(NumberOfCameras == 1){
00068 ROS_INFO("Found 1 uEye camera.");
00069 }else{
00070 ROS_INFO("Found %d uEye cameras.", NumberOfCameras);
00071 }
00072 }else{
00073 ROS_ERROR("Found 0 uEye cameras.");
00074 ros::shutdown();
00075 return;
00076 }
00077
00078
00079 int id = 0;
00080 if(priv_nh.getParam("serialNo", id)){
00081 if(!cam_.openCameraSerNo(id)){
00082 ROS_ERROR("Failed to open uEye camera with serialNo: %u.", id);
00083 ros::shutdown();
00084 return;
00085 }
00086 }else if(priv_nh.getParam("deviceId", id)){
00087 if(!cam_.openCameraDevId(id)){
00088 ROS_ERROR("Failed to open uEye camera with deviceId: %u.", id);
00089 ros::shutdown();
00090 return;
00091 }
00092 }else{
00093 priv_nh.getParam("cameraId", id);
00094 if(!cam_.openCameraCamId(id)){
00095 ROS_ERROR("Failed to open uEye camera with cameraId: %u.", id);
00096 ros::shutdown();
00097 return;
00098 }
00099 }
00100 ROS_INFO("Opened camera %s %u", cam_.getCameraName(), cam_.getCameraSerialNo());
00101
00102
00103 dynamic_reconfigure::Server<monoConfig>::CallbackType f = boost::bind(&CameraNode::reconfig, this, _1, _2);
00104 srv_.setCallback(f);
00105
00106
00107 srv_cam_info_ = node.advertiseService("set_camera_info", &CameraNode::setCameraInfo, this);
00108
00109
00110 pub_stream_ = it_.advertiseCamera("image_raw", 0);
00111
00112
00113 timer_ = node.createTimer(ros::Duration(1/5.0), &CameraNode::timerCallback, this);
00114 }
00115
00116 CameraNode::~CameraNode()
00117 {
00118 closeCamera();
00119 }
00120
00121 void CameraNode::handlePath(std::string &path)
00122 {
00123
00124 if(path.length() == 0){
00125 path = ros::package::getPath("ueye");
00126 }
00127
00128
00129 unsigned int length = path.length();
00130 if(length > 0){
00131 if(path.c_str()[length-1] == '/'){
00132 path = path.substr(0, length-1);
00133 }
00134 }
00135 config_path_ = path;
00136 }
00137 void CameraNode::reconfig(monoConfig &config, uint32_t level)
00138 {
00139 force_streaming_ = config.force_streaming;
00140 handlePath(config.config_path);
00141
00142
00143 if (trigger_mode_ != config.trigger){
00144 stopCamera();
00145 TriggerMode mode;
00146 switch(config.trigger){
00147 case mono_TGR_HARDWARE_RISING:
00148 mode = TRIGGER_LO_HI;
00149 break;
00150 case mono_TGR_HARDWARE_FALLING:
00151 mode = TRIGGER_HI_LO;
00152 break;
00153 case mono_TGR_AUTO:
00154 default:
00155 mode = TRIGGER_OFF;
00156 break;
00157 }
00158 if(!cam_.setTriggerMode(mode)){
00159 cam_.setTriggerMode(TRIGGER_OFF);
00160 config.trigger = mono_TGR_AUTO;
00161 }
00162 }
00163 trigger_mode_ = config.trigger;
00164
00165
00166 if(auto_gain_ && !config.auto_gain){
00167 config.gain = cam_.getHardwareGain();
00168 }
00169 auto_gain_ = config.auto_gain;
00170 if(auto_exposure_ && !config.auto_exposure){
00171 config.exposure_time = cam_.getExposure();
00172 }
00173 auto_exposure_ = config.auto_exposure;
00174
00175
00176 if (cam_.getHardwareGamma() != config.hardware_gamma){
00177 cam_.setHardwareGamma(&config.hardware_gamma);
00178 }
00179
00180
00181 if (cam_.getGainBoost() != config.gain_boost){
00182 cam_.setGainBoost(&config.gain_boost);
00183 }
00184
00185
00186 if (cam_.getAutoGain() != config.auto_gain){
00187 cam_.setAutoGain(&config.auto_gain);
00188 }
00189 if (!config.auto_gain){
00190 cam_.setHardwareGain(&config.gain);
00191 }
00192
00193
00194 if (cam_.getZoom() != config.zoom){
00195 cam_.setZoom(&config.zoom);
00196 }
00197
00198
00199 if (cam_.getPixelClock() != config.pixel_clock){
00200 cam_.setPixelClock(&config.pixel_clock);
00201 }
00202
00203
00204 cam_.setFrameRate(&config.frame_rate);
00205
00206
00207 if (cam_.getAutoExposure() != config.auto_exposure){
00208 cam_.setAutoExposure(&config.auto_exposure);
00209 }
00210 if (!config.auto_exposure){
00211 cam_.setExposure(&config.exposure_time);
00212 }
00213
00214
00215 if(zoom_ != config.zoom){
00216 zoom_ = config.zoom;
00217 loadIntrinsics();
00218 }
00219
00220 msg_camera_info_.header.frame_id = config.frame_id;
00221 configured_ = true;
00222 }
00223
00224 void CameraNode::timerCallback(const ros::TimerEvent& event)
00225 {
00226 if((pub_stream_.getNumSubscribers() > 0) || force_streaming_){
00227 startCamera();
00228 }else{
00229 stopCamera();
00230 }
00231 }
00232
00233
00234
00235 bool CameraNode::setCameraInfo(sensor_msgs::SetCameraInfo::Request& req, sensor_msgs::SetCameraInfo::Response& rsp)
00236 {
00237 ROS_INFO("New camera info received");
00238 sensor_msgs::CameraInfo &info = req.camera_info;
00239 info.header.frame_id = msg_camera_info_.header.frame_id;
00240
00241
00242 unsigned int height = cam_.getHeight();
00243 unsigned int width = cam_.getWidth();
00244
00245 if (info.width != width || info.height != height) {
00246 rsp.success = false;
00247 rsp.status_message = (boost::format("Camera_info resolution %ix%i does not match current video "
00248 "setting, camera running at resolution %ix%i.")
00249 % info.width % info.height % width % height).str();
00250 ROS_ERROR("%s", rsp.status_message.c_str());
00251 return true;
00252 }
00253
00254 std::string camname = cam_.getCameraName();
00255 std::stringstream ini_stream;
00256 if (!camera_calibration_parsers::writeCalibrationIni(ini_stream, camname, info)) {
00257 rsp.status_message = "Error formatting camera_info for storage.";
00258 rsp.success = false;
00259 }else{
00260 std::string ini = ini_stream.str();
00261 fstream param_file;
00262 std::string filename = config_path_ + "/" + configFileName(cam_);
00263 param_file.open(filename.c_str(), ios::in | ios::out | ios::trunc);
00264
00265 if (param_file.is_open()) {
00266 param_file<< ini.c_str();
00267 param_file.close();
00268
00269 msg_camera_info_ = info;
00270 rsp.success = true;
00271 }else{
00272 rsp.success = false;
00273 rsp.status_message = "file write failed";
00274 }
00275 }
00276 if (!rsp.success){
00277 ROS_ERROR("%s", rsp.status_message.c_str());
00278 }
00279 return true;
00280 }
00281
00282
00283 void CameraNode::loadIntrinsics()
00284 {
00285 char buffer[12800];
00286
00287 std::string MyPath = config_path_ + "/" + configFileName(cam_);
00288 fstream param_file;
00289 param_file.open(MyPath.c_str(), ios::out | ios::in);
00290
00291 if (param_file.is_open()) {
00292 param_file.read(buffer, 12800);
00293 param_file.close();
00294 }
00295
00296
00297 std::string camera_name;
00298 if (camera_calibration_parsers::parseCalibrationIni(buffer, camera_name, msg_camera_info_)){
00299 ROS_INFO("Loaded calibration for camera '%s'", camera_name.c_str());
00300 }else{
00301 ROS_WARN("Failed to load intrinsics for camera from file");
00302 }
00303 }
00304
00305
00306 sensor_msgs::ImagePtr CameraNode::processFrame(IplImage* frame, sensor_msgs::CameraInfoPtr &info)
00307 {
00308 msg_camera_info_.header.stamp = ros::Time::now();
00309 msg_camera_info_.header.seq++;
00310 msg_camera_info_.roi.x_offset = 0;
00311 msg_camera_info_.roi.y_offset = 0;
00312 msg_camera_info_.height = cam_.getHeight();
00313 msg_camera_info_.width = cam_.getWidth();
00314 msg_camera_info_.roi.width = 0;
00315 msg_camera_info_.roi.height = 0;
00316 sensor_msgs::CameraInfoPtr msg(new sensor_msgs::CameraInfo(msg_camera_info_));
00317 info = msg;
00318
00319 converter_.header = msg_camera_info_.header;
00320 converter_.encoding = "bgr8";
00321 converter_.image = frame;
00322 return converter_.toImageMsg();
00323 }
00324
00325
00326 void CameraNode::publishImage(IplImage * frame)
00327 {
00328 sensor_msgs::CameraInfoPtr info;
00329 sensor_msgs::ImagePtr img = processFrame(frame, info);
00330 pub_stream_.publish(img, info);
00331 }
00332
00333 void CameraNode::startCamera()
00334 {
00335 if(running_ || !configured_)
00336 return;
00337 cam_.startVideoCapture(boost::bind(&CameraNode::publishImage, this, _1));
00338 ROS_INFO("Started video stream.");
00339 running_ = true;
00340 }
00341
00342 void CameraNode::stopCamera()
00343 {
00344 if(!running_)
00345 return;
00346 cam_.stopVideoCapture();
00347 ROS_INFO("Stopped video stream.");
00348 running_ = false;
00349 }
00350
00351 void CameraNode::closeCamera(){
00352 stopCamera();
00353 cam_.closeCamera();
00354 }
00355
00356 }