CameraNode.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012-2016, Kevin Hallenbeck
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Kevin Hallenbeck nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 #include <ueye/CameraNode.h>
36 #include <boost/format.hpp>
37 
38 namespace ueye
39 {
40 
42  srv_(priv_nh), it_(node)
43 {
44  running_ = false;
45  configured_ = false;
46  force_streaming_ = false;
47  auto_exposure_ = false;
48  auto_gain_ = false;
49  trigger_mode_ = zoom_ = -1;
50 
51  // Check for a valid uEye installation and supported version
52  const char *version;
53  int major, minor, build;
54  if (cam_.checkVersion(major, minor, build, version)) {
55  ROS_INFO("Loaded uEye SDK %s.", version);
56  } else {
57  ROS_WARN("Loaded uEye SDK %d.%d.%d. Expecting %s.", major, minor, build, version);
58  }
59 
60  // Make sure there is at least one camera available
61  int num_cameras = cam_.getNumberOfCameras();
62  if (num_cameras > 0) {
63  if (num_cameras == 1) {
64  ROS_INFO("Found 1 uEye camera.");
65  } else {
66  ROS_INFO("Found %d uEye cameras.", num_cameras);
67  }
68  } else {
69  ROS_ERROR("Found 0 uEye cameras.");
70  ros::shutdown();
71  return;
72  }
73 
74  // Open camera with either serialNo, deviceId, or cameraId
75  int id = 0;
76  if (priv_nh.getParam("serialNo", id)) {
77  if (!cam_.openCameraSerNo(id)) {
78  ROS_ERROR("Failed to open uEye camera with serialNo: %u.", id);
79  ros::shutdown();
80  return;
81  }
82  } else if (priv_nh.getParam("deviceId", id)) {
83  if (!cam_.openCameraDevId(id)) {
84  ROS_ERROR("Failed to open uEye camera with deviceId: %u.", id);
85  ros::shutdown();
86  return;
87  }
88  } else {
89  priv_nh.getParam("cameraId", id);
90  if (!cam_.openCameraCamId(id)) {
91  ROS_ERROR("Failed to open uEye camera with cameraId: %u.", id);
92  ros::shutdown();
93  return;
94  }
95  }
96  ROS_INFO("Opened camera %s %u", cam_.getCameraName(), cam_.getCameraSerialNo());
97 
98  // Setup Dynamic Reconfigure
99  dynamic_reconfigure::Server<monoConfig>::CallbackType f = boost::bind(&CameraNode::reconfig, this, _1, _2);
100  srv_.setCallback(f); //start dynamic reconfigure
101 
102  // Service call for setting calibration.
103  srv_cam_info_ = node.advertiseService("set_camera_info", &CameraNode::setCameraInfo, this);
104 
105  // Special publisher for images to support compression
106  pub_stream_ = it_.advertiseCamera("image_raw", 0);
107 
108  // Set up Timer
110 }
111 
113 {
114  closeCamera();
115 }
116 
117 void CameraNode::handlePath(std::string &path)
118 {
119  // Set default path if not present
120  if (path.length() == 0) {
121  path = ros::package::getPath("ueye");
122  }
123 
124  // Remove trailing "/" from folder path
125  unsigned int length = path.length();
126  if (length > 0) {
127  if (path.c_str()[length - 1] == '/') {
128  path = path.substr(0, length - 1);
129  }
130  }
131  config_path_ = path;
132 }
133 void CameraNode::reconfig(monoConfig &config, uint32_t level)
134 {
135  force_streaming_ = config.force_streaming;
136  handlePath(config.config_path);
137 
138  // Trigger
139  if (trigger_mode_ != config.trigger) {
140  stopCamera();
141  TriggerMode mode;
142  switch (config.trigger) {
143  case mono_TGR_HARDWARE_RISING:
144  mode = TRIGGER_LO_HI;
145  break;
146  case mono_TGR_HARDWARE_FALLING:
147  mode = TRIGGER_HI_LO;
148  break;
149  case mono_TGR_AUTO:
150  default:
151  mode = TRIGGER_OFF;
152  break;
153  }
154  if (!cam_.setTriggerMode(mode)) {
156  config.trigger = mono_TGR_AUTO;
157  }
158  }
159  trigger_mode_ = config.trigger;
160 
161  // Color Mode
162  uEyeColor color;
163  switch (config.color) {
164  default:
165  case mono_COLOR_MONO8:
166  color = MONO8;
167  break;
168  case mono_COLOR_MONO16:
169  color = MONO16;
170  break;
171  case mono_COLOR_YUV:
172  color = YUV;
173  break;
174  case mono_COLOR_YCbCr:
175  color = YCbCr;
176  break;
177  case mono_COLOR_BGR5:
178  color = BGR5;
179  break;
180  case mono_COLOR_BGR565:
181  color = BGR565;
182  break;
183  case mono_COLOR_BGR8:
184  color = BGR8;
185  break;
186  case mono_COLOR_BGRA8:
187  color = BGRA8;
188  break;
189  case mono_COLOR_BGRY8:
190  color = BGRY8;
191  break;
192  case mono_COLOR_RGB8:
193  color = RGB8;
194  break;
195  case mono_COLOR_RGBA8:
196  color = RGBA8;
197  break;
198  case mono_COLOR_RGBY8:
199  color = RGBY8;
200  break;
201  }
202  if (cam_.getColorMode() != color) {
203  cam_.setColorMode(color);
204  }
205 
206  // Latch Auto Parameters
207  if (auto_gain_ && !config.auto_gain) {
208  config.gain = cam_.getHardwareGain();
209  }
210  auto_gain_ = config.auto_gain;
211  if (auto_exposure_ && !config.auto_exposure) {
212  config.exposure_time = cam_.getExposure();
213  }
214  auto_exposure_ = config.auto_exposure;
215 
216  // Hardware Gamma Correction
217  if (cam_.getHardwareGamma() != config.hardware_gamma) {
218  cam_.setHardwareGamma(&config.hardware_gamma);
219  }
220 
221  // Gain Boost
222  if (cam_.getGainBoost() != config.gain_boost) {
223  cam_.setGainBoost(&config.gain_boost);
224  }
225 
226  // Hardware Gain
227  if (cam_.getAutoGain() != config.auto_gain) {
228  cam_.setAutoGain(&config.auto_gain);
229  }
230  if (!config.auto_gain) {
231  cam_.setHardwareGain(&config.gain);
232  }
233 
234  // Zoom
235  if (cam_.getZoom() != config.zoom) {
236  cam_.setZoom(&config.zoom);
237  }
238 
239  // Pixel Clock
240  if (cam_.getPixelClock() != config.pixel_clock) {
241  cam_.setPixelClock(&config.pixel_clock);
242  }
243 
244  // Frame Rate
245  cam_.setFrameRate(&config.frame_rate);
246 
247  // Exposure
248  if (cam_.getAutoExposure() != config.auto_exposure) {
249  cam_.setAutoExposure(&config.auto_exposure);
250  }
251  if (!config.auto_exposure) {
252  cam_.setExposure(&config.exposure_time);
253  }
254 
255  // Zoom
256  if (zoom_ != config.zoom) {
257  zoom_ = config.zoom;
258  loadIntrinsics();
259  }
260 
261  msg_camera_info_.header.frame_id = config.frame_id;
262  configured_ = true;
263 }
264 
266 {
268  startCamera();
269  } else {
270  stopCamera();
271  }
272 }
273 
274 // Support camera calibration requests
275 // http://www.ros.org/wiki/camera_calibration/Tutorials/MonocularCalibration
276 bool CameraNode::setCameraInfo(sensor_msgs::SetCameraInfo::Request& req, sensor_msgs::SetCameraInfo::Response& rsp)
277 {
278  ROS_INFO("New camera info received");
279  sensor_msgs::CameraInfo &info = req.camera_info;
280  info.header.frame_id = msg_camera_info_.header.frame_id;
281 
282  // Sanity check: the image dimensions should match the resolution of the sensor.
283  unsigned int height = cam_.getHeight();
284  unsigned int width = cam_.getWidth();
285 
286  if (info.width != width || info.height != height) {
287  rsp.success = false;
288  rsp.status_message = (boost::format("Camera_info resolution %ix%i does not match current video "
289  "setting, camera running at resolution %ix%i.") % info.width % info.height
290  % width % height).str();
291  ROS_ERROR("%s", rsp.status_message.c_str());
292  return true;
293  }
294 
295  std::string camname = cam_.getCameraName();
296  std::stringstream ini_stream;
297  if (!camera_calibration_parsers::writeCalibrationIni(ini_stream, camname, info)) {
298  rsp.status_message = "Error formatting camera_info for storage.";
299  rsp.success = false;
300  } else {
301  std::string ini = ini_stream.str();
302  std::fstream param_file;
303  std::string filename = config_path_ + "/" + configFileName(cam_);
304  param_file.open(filename.c_str(), std::ios::in | std::ios::out | std::ios::trunc);
305 
306  if (param_file.is_open()) {
307  param_file << ini.c_str();
308  param_file.close();
309 
310  msg_camera_info_ = info;
311  rsp.success = true;
312  } else {
313  rsp.success = false;
314  rsp.status_message = "file write failed";
315  }
316  }
317  if (!rsp.success) {
318  ROS_ERROR("%s", rsp.status_message.c_str());
319  }
320  return true;
321 }
322 
323 // Try to load previously saved camera calibration from a file.
325 {
326  char buffer[12800];
327 
328  std::string MyPath = config_path_ + "/" + configFileName(cam_);
329  std::fstream param_file;
330  param_file.open(MyPath.c_str(), std::ios::in);
331 
332  if (param_file.is_open()) {
333  param_file.read(buffer, 12800);
334  param_file.close();
335  }
336 
337  // Parse calibration file
338  std::string camera_name;
340  ROS_INFO("Loaded calibration for camera '%s'", camera_name.c_str());
341  } else {
342  ROS_WARN("Failed to load intrinsics for camera from file");
343  }
344 }
345 
346 // Add properties to image message
347 sensor_msgs::ImagePtr CameraNode::processFrame(const char *frame, size_t size, sensor_msgs::CameraInfoPtr &info)
348 {
349  msg_camera_info_.header.stamp = ros::Time::now();
350  msg_camera_info_.roi.x_offset = 0;
351  msg_camera_info_.roi.y_offset = 0;
352  msg_camera_info_.height = cam_.getHeight();
353  msg_camera_info_.width = cam_.getWidth();
354  msg_camera_info_.roi.width = 0;
355  msg_camera_info_.roi.height = 0;
356  sensor_msgs::CameraInfoPtr msg(new sensor_msgs::CameraInfo(msg_camera_info_));
357  info = msg;
358 
359  sensor_msgs::ImagePtr msg_image(new sensor_msgs::Image());
360  msg_image->header = msg_camera_info_.header;
361  msg_image->height = msg_camera_info_.height;
362  msg_image->width = msg_camera_info_.width;
363  msg_image->encoding = Camera::colorModeToString(cam_.getColorMode());
364  msg_image->is_bigendian = false;
365  msg_image->step = size / msg_image->height;
366  msg_image->data.resize(size);
367  memcpy(msg_image->data.data(), frame, size);
368  return msg_image;
369 }
370 
371 // Timestamp and publish the image. Called by the streaming thread.
372 void CameraNode::publishImage(const char *frame, size_t size)
373 {
374  sensor_msgs::CameraInfoPtr info;
375  sensor_msgs::ImagePtr img = processFrame(frame, size, info);
376  pub_stream_.publish(img, info);
377 }
378 
380 {
381  if (running_ || !configured_)
382  return;
383  cam_.startVideoCapture(boost::bind(&CameraNode::publishImage, this, _1, _2));
384  ROS_INFO("Started video stream.");
385  running_ = true;
386 }
387 
389 {
390  if (!running_)
391  return;
393  ROS_INFO("Stopped video stream.");
394  running_ = false;
395 }
396 
398 {
399  stopCamera();
400  cam_.closeCamera();
401 }
402 
403 } // namespace ueye
ros::Timer timer_
Definition: CameraNode.h:88
image_transport::ImageTransport it_
Definition: CameraNode.h:102
unsigned int getHardwareGain()
Definition: Camera.cpp:235
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
void setHardwareGain(int *gain)
Definition: Camera.cpp:378
Definition: Camera.h:44
bool getAutoGain() const
Definition: Camera.h:121
f
std::string config_path_
Definition: CameraNode.h:95
static const char * colorModeToString(uEyeColor mode)
Definition: Camera.cpp:200
sensor_msgs::ImagePtr processFrame(const char *frame, size_t size, sensor_msgs::CameraInfoPtr &info)
Definition: CameraNode.cpp:347
unsigned int getCameraSerialNo() const
Definition: Camera.h:109
uint32_t getNumSubscribers() const
void setAutoGain(bool *enable)
Definition: Camera.cpp:367
void timerCallback(const ros::TimerEvent &event)
Definition: CameraNode.cpp:265
const char * getCameraName() const
Definition: Camera.h:108
bool setTriggerMode(TriggerMode mode)
Definition: Camera.cpp:389
void setZoom(int *zoom)
Definition: Camera.cpp:293
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool force_streaming_
Definition: CameraNode.h:94
#define ROS_WARN(...)
bool setCameraInfo(sensor_msgs::SetCameraInfo::Request &req, sensor_msgs::SetCameraInfo::Response &rsp)
Definition: CameraNode.cpp:276
void stopVideoCapture()
Definition: Camera.cpp:696
bool getGainBoost() const
Definition: Camera.h:120
void setHardwareGamma(bool *enable)
Definition: Camera.cpp:281
CameraPublisher advertiseCamera(const std::string &base_topic, uint32_t queue_size, bool latch=false)
ueye::Camera cam_
Definition: CameraNode.h:91
bool getAutoExposure() const
Definition: Camera.h:116
int getWidth() const
Definition: Camera.h:112
dynamic_reconfigure::Server< monoConfig > srv_
Definition: CameraNode.h:87
image_transport::CameraPublisher pub_stream_
Definition: CameraNode.h:103
void setAutoExposure(bool *enable)
Definition: Camera.cpp:262
void closeCamera()
Definition: Camera.cpp:552
#define ROS_INFO(...)
bool openCameraDevId(unsigned int id)
Definition: Camera.cpp:183
TriggerMode
Definition: Camera.h:71
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
void setGainBoost(bool *enable)
Definition: Camera.cpp:354
bool writeCalibrationIni(std::ostream &out, const std::string &camera_name, const sensor_msgs::CameraInfo &cam_info)
int getNumberOfCameras() const
Definition: Camera.cpp:123
uEyeColor
Definition: Camera.h:56
void startVideoCapture(CamCaptureCB)
Definition: Camera.cpp:691
void handlePath(std::string &path)
Definition: CameraNode.cpp:117
int getPixelClock() const
Definition: Camera.h:119
void publishImage(const char *frame, size_t size)
Definition: CameraNode.cpp:372
void setPixelClock(int *MHz)
Definition: Camera.cpp:316
CameraNode(ros::NodeHandle node, ros::NodeHandle private_nh)
Definition: CameraNode.cpp:41
ROSLIB_DECL std::string getPath(const std::string &package_name)
sensor_msgs::CameraInfo msg_camera_info_
Definition: CameraNode.h:89
void setColorMode(uEyeColor mode)
Definition: Camera.cpp:249
bool getParam(const std::string &key, std::string &s) const
void setFrameRate(double *rate)
Definition: Camera.cpp:348
void reconfig(monoConfig &config, uint32_t level)
Definition: CameraNode.cpp:133
double getExposure()
Definition: Camera.cpp:229
bool openCameraSerNo(unsigned int serial_number)
Definition: Camera.cpp:187
static Time now()
static std::string configFileName(const Camera &cam)
Definition: CameraNode.h:61
ROSCPP_DECL void shutdown()
void setExposure(double *time_ms)
Definition: Camera.cpp:273
bool parseCalibrationIni(const std::string &buffer, std::string &camera_name, sensor_msgs::CameraInfo &cam_info)
uEyeColor getColorMode() const
Definition: Camera.h:115
static bool checkVersion(int &major, int &minor, int &build, const char *&expected)
Definition: Camera.cpp:108
int getZoom() const
Definition: Camera.h:114
bool getHardwareGamma() const
Definition: Camera.h:118
ros::ServiceServer srv_cam_info_
Definition: CameraNode.h:104
#define ROS_ERROR(...)
int getHeight() const
Definition: Camera.h:113
bool openCameraCamId(unsigned int id)
Definition: Camera.cpp:153


ueye
Author(s): Kevin Hallenbeck
autogenerated on Sun Oct 6 2019 03:35:25