uvc_ros.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2012 by Markus Bader *
3  * markus.bader@tuwien.ac.at *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
21 
23 #include <tuw_uvc/uvc_defaults.h>
24 #include <tuw_uvc/uvc_ros.h>
25 
26 #include <boost/interprocess/sync/scoped_lock.hpp>
27 #include "luvcview/v4l2uvc.h"
28 #include <cv_bridge/cv_bridge.h>
29 
30 typedef boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> Lock;
31 
32 extern "C" {
33  unsigned int Pyuv422torgb24(unsigned char *input_ptr, unsigned char *output_ptr, unsigned int image_width, unsigned int image_height);
34  unsigned int Pyuv422tobgr24(unsigned char *input_ptr, unsigned char *output_ptr, unsigned int image_width, unsigned int image_height);
35  unsigned int Pyuv422togray8(unsigned char *input_ptr, unsigned char *output_ptr, unsigned int image_width, unsigned int image_height);
36 }
37 
38 
40 {
41  show_camera_image_ = false;
42  boost::this_thread::sleep(boost::posix_time::milliseconds(100));
43 }
44 
47 {
48 
49  //n_param_.setParam("show_camera_image", show_camera_image_);
51  cameraThumbnailPublisher_ = imageTransport_.advertise("image_thumbnail", 1);
53  //subSphere_ = n_param_.subscribe("sphere", 1000, &V4RCamNode::callbackSphere, this);
55  initCamera();
58  for(unsigned int i = 0; i < controlEntries_.size(); i++) {
59  ROS_INFO_STREAM(controlEntries_[i]->getQueryCtrlInfo());
60  }
61 }
62 
64 {
65  if((!queueRosParamToV4LCommit_) && (!force)) return;
66  bool tmp;
67  n_param_.getParam("show_camera_image", tmp);
68  if(show_camera_image_ != tmp) {
69  show_camera_image_ = tmp;
70  if(show_camera_image_) {
72  ROS_INFO("start show camera image thread");
73  }
74  }
75  for(unsigned int i = 0; i < controlEntries_.size(); i++) {
76  const std::string &name = controlEntries_[i]->varName;
77  int default_value = controlEntries_[i]->queryctrl->default_value;
78  int &target_value = controlEntries_[i]->targetValue;
79  if(controlEntries_[i]->queryctrl->type == V4L2_CTRL_TYPE_BOOLEAN) {
80  n_param_.param<bool>(name, tmp, (bool) default_value);
81  target_value = tmp;
82  } else {
83  n_param_.param<int>(name, target_value, default_value);
84  }
88  }
89  //commitV4LToRosParams();
91 }
93 {
94  for(unsigned int i = 0; i < controlEntries_.size(); i++) {
96  if(controlEntries_[i]->queryctrl->type == V4L2_CTRL_TYPE_BOOLEAN) {
97  n_param_.setParam(controlEntries_[i]->varName, (bool) controlEntries_[i]->currentValue);
98  std::cout << controlEntries_[i]->varName << ": bool " << controlEntries_[i]->currentValue << std::endl;
99  } else {
100  n_param_.setParam(controlEntries_[i]->varName, (int) controlEntries_[i]->currentValue);
101  std::cout << controlEntries_[i]->varName << ": int " << controlEntries_[i]->currentValue << std::endl;
102  }
105  }
106 }
108 {
109  double tmp;
110  ROS_INFO("V4RCamNode::readParams()");
111  n_param_.param<bool>("show_camera_image", show_camera_image_, DEFAULT_SHOW_CAMERA_IMAGE);
112  ROS_INFO("show_camera_image: %s", ((show_camera_image_) ? "true" : "false"));
113  n_param_.param<bool>("camera_freeze", camera_freeze_, DEFAULT_CAMERA_FREEZE);
114  ROS_INFO("camera_freeze: %s", ((camera_freeze_) ? "true" : "false"));
115 
116  n_param_.param<std::string>("video_device", videoDevice_, DEFAULT_VIDEODEVICE);
117  ROS_INFO("video_device: %s", videoDevice_.c_str());
118  n_param_.param<std::string>("avi_filename", aviFilename_, DEFAULT_AVIFILENAME);
119  ROS_INFO("avi_filename: %s", aviFilename_.c_str());
120  n_param_.param<int>("convert_image_", convert_image_, DEFAULT_CONVERT_IMAGE);
121  ROS_INFO("convert_image: %i", convert_image_);
122  n_param_.param<int>("ratioThumbnail", ratioThumbnail_, DEFAULT_RATIO_THUMBNAIL);
123  ROS_INFO("ratioThumbnail: %i", ratioThumbnail_);
124  n_param_.param<int>("width", width_, DEFAULT_WIDTH);
125  ROS_INFO("width: %i", width_);
126  n_param_.param<int>("height", height_, DEFAULT_HEIGHT);
127  ROS_INFO("height: %i", height_);
128  n_param_.param<double>("fps", tmp, DEFAULT_FPS);
129  fps_ = tmp;
130  ROS_INFO("fps: %4.3f", fps_);
131 
132  std::string camera_info_url;
133  if(n_param_.getParam("camera_info_url", camera_info_url)) {
135  if(cinfo.validateURL(camera_info_url)) {
136  cinfo.loadCameraInfo(camera_info_url);
137  cameraInfo_ = cinfo.getCameraInfo();
138  } else {
139  ROS_FATAL("camera_info_url not valid.");
140  n_param_.shutdown();
141  return;
142  }
143  } else {
144  XmlRpc::XmlRpcValue double_list;
145  n_param_.getParam("K", double_list);
146  if((double_list.getType() == XmlRpc::XmlRpcValue::TypeArray) && (double_list.size() == 9)) {
147  for(int i = 0; i < 9; i++) {
148  ROS_ASSERT(double_list[0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
149  cameraInfo_.K[i] = double_list[i];
150  }
151  }
152 
153  n_param_.getParam("D", double_list);
154  if((double_list.getType() == XmlRpc::XmlRpcValue::TypeArray) && (double_list.size() == 5)) {
155  for(int i = 0; i < 5; i++) {
156  ROS_ASSERT(double_list[0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
157  cameraInfo_.D[i] = double_list[i];
158  }
159  }
160 
161  n_param_.getParam("R", double_list);
162  if((double_list.getType() == XmlRpc::XmlRpcValue::TypeArray) && (double_list.size() == 9)) {
163  for(int i = 0; i < 9; i++) {
164  ROS_ASSERT(double_list[0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
165  cameraInfo_.R[i] = double_list[i];
166  }
167  }
168 
169  n_param_.getParam("P", double_list);
170  if((double_list.getType() == XmlRpc::XmlRpcValue::TypeArray) && (double_list.size() == 12)) {
171  for(int i = 0; i < 12; i++) {
172  ROS_ASSERT(double_list[0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
173  cameraInfo_.P[i] = double_list[i];
174  }
175  }
176  }
177  ROS_INFO("tf_camera_id: %s", cameraInfo_.header.frame_id.c_str());
178  n_param_.param<std::string>("frame_id", cameraInfo_.header.frame_id, DEFAULT_FRAME_ID);
179  ROS_INFO("frame_id: %s", cameraInfo_.header.frame_id.c_str());
180  cameraInfo_.header.seq = 0;
181 }
182 
184 {
185  bool freeze = camera_freeze_ && (cameraImage_.header.seq > 100);
186  cameraInfo_.header.stamp.sec = timeLastFrame_.tv_sec;
187  cameraInfo_.header.stamp.nsec = timeLastFrame_.tv_usec * 1000;
188  cameraImage_.header = cameraInfo_.header;
189  if( !freeze) {
190  cameraImage_.height = cameraInfo_.height = pVideoIn_->height;
191  cameraImage_.width = cameraInfo_.width = pVideoIn_->width;
192  cameraImage_.is_bigendian = true;
193  cameraImage_.step = cameraInfo_.width * 2;
194  switch(convert_image_) {
195  case CONVERT_RAW:
196  cameraImage_.encoding = "yuvu";
197  cameraImage_.data.resize(pVideoIn_->framesizeIn);
198  memcpy(&cameraImage_.data[0], pVideoIn_->framebuffer, cameraImage_.data.size());
199  break;
200  case CONVERT_YUV422toRGB:
201  cameraImage_.encoding = "rgb8";
202  cameraImage_.data.resize(width_ * height_ * 3);
203  cameraImage_.step = cameraInfo_.width * 3;
205  break;
206  case CONVERT_YUV422toBGR:
207  cameraImage_.encoding = "bgr8";
208  cameraImage_.data.resize(width_ * height_ * 3);
209  cameraImage_.step = cameraInfo_.width * 3;
211  break;
213  cameraImage_.encoding = "mono8";
214  cameraImage_.data.resize(width_ * height_);
215  cameraImage_.step = cameraInfo_.width * 1;
217  break;
218  default:
219  cameraImage_.encoding = "yuv422";
220  cameraImage_.data.resize(width_ * height_ * 2);
221  memcpy(&cameraImage_.data[0], pVideoIn_->framebuffer, cameraImage_.data.size());
222  }
223  }
225 
227  cameraThumbnail_.header = cameraInfo_.header;
228  if( !freeze) {
231  cameraThumbnail_.is_bigendian = true;
232  cameraThumbnail_.step = cameraInfo_.width;
233  cameraThumbnail_.encoding = "mono8";
234  cameraThumbnail_.data.resize(cameraThumbnail_.width * cameraThumbnail_.height);
235  unsigned char *des = (unsigned char *) &cameraThumbnail_.data[0];
236  for(unsigned int h = 0; h < cameraThumbnail_.height; h++) {
237  unsigned char *src = (unsigned char *) pVideoIn_->framebuffer + h*ratioThumbnail_ * pVideoIn_->width*2;
238  for(unsigned int w = 0; w < cameraThumbnail_.width; w++) {
239  *des++ = src[w * 2*ratioThumbnail_];
240  }
241  }
243  }
244  }
245 
247  cameraInfo_.header.seq ++;
249  showCameraImageThread_ = boost::thread(&V4RCamNode::showCameraImage, this);
250  }
251 }
252 
253 
255 {
256  std::string window_name = ros::NodeHandle ( "~" ).getNamespace();
257  timeval lastShownFrame = timeLastFrame_;
258  double lastDuration = durationLastFrame_;
259  cv::Mat img;
260  int key = -1;
262  do {
263  if((lastShownFrame.tv_sec != timeLastFrame_.tv_sec) || (lastShownFrame.tv_usec != timeLastFrame_.tv_usec)) {
264  img.create(height_, width_, CV_8UC3);
265  lastShownFrame = timeLastFrame_;
266  std::stringstream ss;
267  ss << 1000.0 / ((durationLastFrame_ + lastDuration) / 2.0);
268  lastDuration = durationLastFrame_;
269  Lock myLock(mutexImage_);
270  if(!camera_freeze_){
272  cv::putText(img, ss.str(), cv::Point(10, 15), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar::all(0), 1, CV_AA);
273  }
274  cv::imshow(window_name, img);
275  }
276  key = cv::waitKey(50);
277  } while((key == -1) && show_camera_image_ && showCameraImageThreadActive_);
278 
279  cv::putText(img, "OFFLINE", cv::Point(img.cols/4, img.rows/4), cv::FONT_HERSHEY_PLAIN, 5, cv::Scalar::all(0), 3, CV_AA);
280  cv::imshow(window_name, img);
281  cv::waitKey(50);
282  cv::destroyWindow(window_name);
283  cv::waitKey(50);
285  if(key != -1) {
286  pVideoIn_->signalquit = 0;
287  }
288 }
289 
290 void V4RCamNode::callbackSphere (const tuw_uvc::SphereConstPtr& msg){
291 
292  ROS_INFO("action %s, pitch = %4.2f, yaw = %4.2f", msg->action.c_str(), msg->pitch, msg->yaw);
293 
294 }
295 
296 
297 bool V4RCamNode::setCameraInfo(sensor_msgs::SetCameraInfoRequest &req, sensor_msgs::SetCameraInfoResponse &rsp){
298  ROS_INFO("New camera info received");
299  sensor_msgs::CameraInfo &info = req.camera_info;
300 
301  if (info.width != cameraInfo_.width || info.height != cameraInfo_.height)
302  {
303  rsp.success = false;
304  rsp.status_message = (boost::format("Camera_info resolution %ix%i does not match current video "
305  "setting, camera running at resolution %ix%i.")
306  % info.width % info.height % cameraInfo_.width % cameraInfo_.height).str();
307  ROS_ERROR("%s", rsp.status_message.c_str());
308  return true;
309  }
310 
311  cameraInfo_ = info;
312 
313  return true;
314 }
#define DEFAULT_AVIFILENAME
Definition: uvc_defaults.h:31
#define DEFAULT_SHOW_CAMERA_IMAGE
Definition: uvc_defaults.h:26
bool queueRosParamToV4LCommit_
Definition: uvc_ros.h:61
std::string pullInfoMsg()
Definition: uvc.cpp:338
#define DEFAULT_HEIGHT
Definition: uvc_defaults.h:35
int v4lset(ControlEntryPtr entry)
Definition: uvc.cpp:181
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
image_transport::ImageTransport imageTransport_
Definition: uvc_ros.h:48
#define ROS_FATAL(...)
sensor_msgs::Image cameraImage_
Definition: uvc_ros.h:52
boost::interprocess::scoped_lock< boost::interprocess::interprocess_mutex > Lock
Definition: uvc.cpp:45
void showCameraImage()
Definition: uvc_ros.cpp:254
#define DEFAULT_FPS
Definition: uvc_defaults.h:36
#define DEFAULT_VIDEODEVICE
Definition: uvc_defaults.h:30
const std::vector< ControlEntryPtr > & detectControlEnties()
Definition: uvc.cpp:352
void readInitParams()
Definition: uvc_ros.cpp:107
sensor_msgs::CameraInfo getCameraInfo(void)
int signalquit
Definition: v4l2uvc.h:63
bool camera_freeze_
Definition: uvc_ros.h:60
int height_
image width
Definition: uvc.h:86
bool loadCameraInfo(const std::string &url)
ros::ServiceServer set_camera_info_srv_
Definition: uvc_ros.h:54
image_transport::CameraPublisher cameraPublisher_
Definition: uvc_ros.h:49
int size() const
boost::interprocess::scoped_lock< boost::interprocess::interprocess_mutex > Lock
Definition: uvc_ros.cpp:30
std::string videoDevice_
pointer to the v4l2 device
Definition: uvc.h:81
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
std::string aviFilename_
device name /dev/videoX
Definition: uvc.h:82
bool hasErrorMsg() const
Definition: uvc.cpp:344
boost::thread showCameraImageThread_
Definition: uvc_ros.h:63
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
unsigned int Pyuv422togray8(unsigned char *input_ptr, unsigned char *output_ptr, unsigned int image_width, unsigned int image_height)
Definition: utils.c:968
Type const & getType() const
bool setCameraInfo(sensor_msgs::SetCameraInfoRequest &req, sensor_msgs::SetCameraInfoResponse &rsp)
Definition: uvc_ros.cpp:297
#define DEFAULT_CAMERA_FREEZE
Definition: uvc_defaults.h:27
uint32_t getNumSubscribers() const
static struct jpginfo info
Definition: utils.c:164
ros::NodeHandle n_
Definition: uvc_ros.h:46
bool validateURL(const std::string &url)
#define DEFAULT_WIDTH
Definition: uvc_defaults.h:34
static const int CONVERT_YUV422toBGR
Definition: uvc_ros.h:38
unsigned int Pyuv422torgb24(unsigned char *input_ptr, unsigned char *output_ptr, unsigned int image_width, unsigned int image_height)
Definition: utils.c:982
sensor_msgs::CameraInfo cameraInfo_
Definition: uvc_ros.h:51
static const int CONVERT_YUV422toGray
Definition: uvc_ros.h:39
CameraPublisher advertiseCamera(const std::string &base_topic, uint32_t queue_size, bool latch=false)
~V4RCamNode()
Definition: uvc_ros.cpp:39
image_transport::Publisher cameraThumbnailPublisher_
Definition: uvc_ros.h:50
bool showCameraImageThreadActive_
Definition: uvc_ros.h:62
void publish(const sensor_msgs::Image &message) const
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
def default_value(type)
ros::NodeHandle n_param_
Definition: uvc_ros.h:47
static const int CONVERT_RAW
Definition: uvc_ros.h:36
timeval timeLastFrame_
frames per second
Definition: uvc.h:88
int height
Definition: v4l2uvc.h:58
int width
Definition: v4l2uvc.h:57
void commitV4LToRosParams()
Definition: uvc_ros.cpp:92
int width_
Definition: uvc.h:85
bool generate_dynamic_reconfigure_
Definition: uvc_ros.h:58
bool show_camera_image_
Definition: uvc_ros.h:59
int convert_image_
Definition: uvc_ros.h:69
#define DEFAULT_CONVERT_IMAGE
Definition: uvc_defaults.h:28
#define ROS_INFO_STREAM(args)
boost::interprocess::interprocess_mutex mutexImage_
duration between last and the frame before the last one
Definition: uvc.h:90
void callbackSphere(const tuw_uvc::SphereConstPtr &msg)
Definition: uvc_ros.cpp:290
vdIn * pVideoIn_
Definition: uvc.h:80
void commitRosParamsToV4L(bool force=false)
Definition: uvc_ros.cpp:63
bool getParam(const std::string &key, std::string &s) const
unsigned int Pyuv422tobgr24(unsigned char *input_ptr, unsigned char *output_ptr, unsigned int image_width, unsigned int image_height)
Definition: utils.c:1008
std::vector< ControlEntryPtr > controlEntries_
mutex to secure critical sections
Definition: uvc.h:91
unsigned char * framebuffer
Definition: v4l2uvc.h:54
sensor_msgs::Image cameraThumbnail_
Definition: uvc_ros.h:53
double durationLastFrame_
time stamp of the last frame
Definition: uvc.h:89
static const int CONVERT_YUV422toRGB
Definition: uvc_ros.h:37
int v4lget(ControlEntryPtr entry)
Definition: uvc.cpp:161
#define ROS_ERROR_STREAM(args)
void publishCamera()
Definition: uvc_ros.cpp:183
#define ROS_ASSERT(cond)
int framesizeIn
Definition: v4l2uvc.h:62
V4RCamNode(ros::NodeHandle &n)
Definition: uvc_ros.cpp:45
#define ROS_ERROR(...)
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
FD initCamera(const std::string &videoDevice="")
vector of the current supported control entries
Definition: uvc.cpp:80
bool hasInfoMsg() const
Definition: uvc.cpp:348
#define DEFAULT_RATIO_THUMBNAIL
Definition: uvc_defaults.h:37
#define DEFAULT_FRAME_ID
Definition: uvc_defaults.h:29
std::string pullErrorMsg()
Definition: uvc.cpp:332
float fps_
image height
Definition: uvc.h:87
int ratioThumbnail_
Definition: uvc_ros.h:70


tuw_uvc
Author(s): Markus Bader
autogenerated on Mon Jun 10 2019 15:39:24