dev_camera1394stereo.cpp
Go to the documentation of this file.
1 // Joan Pau Beltran
3 // Modificat per donar suport a les cameres Bumblebee2 de Pointgrey.
4 //
5 // Copyright (C) 2009, 2010 Patrick Beeson, Jack O'Quin, Ken Tossell
6 // ROS port of the Player 1394 camera driver.
7 //
8 // Copyright (C) 2004 Nate Koenig, Andrew Howard
9 // Player driver for IEEE 1394 digital camera capture
10 //
11 // Copyright (C) 2000-2003 Damien Douxchamps, Dan Dennedy
12 // Bayer filtering from libdc1394
13 //
14 // NOTE: On 4 Jan. 2011, this file was re-licensed under the GNU LGPL
15 // with permission of the original GPL authors: Nate Koenig, Andrew
16 // Howard, Damien Douxchamps and Dan Dennedy.
17 //
18 // This program is free software; you can redistribute it and/or
19 // modify it under the terms of the GNU Lesser General Public License
20 // as published by the Free Software Foundation; either version 2 of
21 // the License, or (at your option) any later version.
22 //
23 // This program is distributed in the hope that it will be useful, but
24 // WITHOUT ANY WARRANTY; without even the implied warranty of
25 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 // Lesser General Public License for more details.
27 //
28 // You should have received a copy of the GNU Lesser General Public
29 // License along with this program; if not, write to the Free Software
30 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 // 02111-1307, USA.
32 //
34 
35 // $Id: dev_camera1394.cpp 35607 2011-01-30 01:28:30Z joq $
36 
51 #include <stdint.h>
52 #include <cstdlib>
53 
54 #include "yuv.h"
56 #include "dev_camera1394stereo.h"
57 #include "featuresstereo.h"
58 #include "modes.h"
59 
60 #define NUM_DMA_BUFFERS 4
61 
62 // @todo eliminate these macros
64 #define CAM_EXCEPT(except, msg) \
65  { \
66  char buf[100]; \
67  snprintf(buf, 100, "[Camera1394Stereo::%s]: " msg, __FUNCTION__); \
68  throw except(buf); \
69  }
70 
72 #define CAM_EXCEPT_ARGS(except, msg, ...) \
73  { \
74  char buf[100]; \
75  snprintf(buf, 100, "[Camera1394Stereo::%s]: " msg, __FUNCTION__, __VA_ARGS__); \
76  throw except(buf); \
77  }
78 
79 
80 using namespace camera1394stereo;
81 
83 // Constructor
85  camera_(NULL)
86 {}
87 
89 {
90  SafeCleanup();
91 }
92 
93 void Camera1394Stereo::findBayerPattern(const char* bayer)
94 {
95  // determine Bayer color encoding pattern
96  // (default is different from any color filter provided by DC1394)
97  BayerPattern_ = (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM;
98  if (0 == strcmp(bayer, "bggr"))
99  {
100  BayerPattern_ = DC1394_COLOR_FILTER_BGGR;
101  }
102  else if (0 == strcmp(bayer, "grbg"))
103  {
104  BayerPattern_ = DC1394_COLOR_FILTER_GRBG;
105  }
106  else if (0 == strcmp(bayer, "rggb"))
107  {
108  BayerPattern_ = DC1394_COLOR_FILTER_RGGB;
109  }
110  else if (0 == strcmp(bayer, "gbrg"))
111  {
112  BayerPattern_ = DC1394_COLOR_FILTER_GBRG;
113  }
114  else if (0 != strcmp(bayer, ""))
115  {
116  ROS_ERROR("unknown bayer pattern [%s]", bayer);
117  }
118 }
119 
120 bool Camera1394Stereo::findBayerMethod(const char* method)
121 {
122  // Do Bayer conversion in the driver node?
123  bool DoBayer = false; // return value
124  if (0 != strcmp(method, "")
125  && BayerPattern_ != DC1394_COLOR_FILTER_NUM)
126  {
127  DoBayer = true; // decoding in driver
128  // add method name to message:
129  ROS_WARN("[%s] Bayer decoding in the driver is DEPRECATED;"
130  " image_proc decoding preferred.", method);
131 
132  // Set decoding method
133  if (!strcmp(method, "DownSample"))
134  BayerMethod_ = DC1394_BAYER_METHOD_DOWNSAMPLE;
135  else if (!strcmp(method, "Simple"))
136  BayerMethod_ = DC1394_BAYER_METHOD_SIMPLE;
137  else if (!strcmp(method, "Bilinear"))
138  BayerMethod_ = DC1394_BAYER_METHOD_BILINEAR;
139  else if (!strcmp(method, "HQ"))
140  BayerMethod_ = DC1394_BAYER_METHOD_HQLINEAR;
141  else if (!strcmp(method, "VNG"))
142  BayerMethod_ = DC1394_BAYER_METHOD_VNG;
143  else if (!strcmp(method, "AHD"))
144  BayerMethod_ = DC1394_BAYER_METHOD_AHD;
145  else
146  {
147  ROS_ERROR("Unknown Bayer method [%s]. Using ROS image_proc instead.",
148  method);
149  DoBayer = false;
150  }
151  }
152  return DoBayer;
153 }
154 
155 bool Camera1394Stereo::findStereoMethod(const char* method)
156 {
157  bool doStereo = true;
158  if (0 == strcmp(method, "Interlaced"))
159  {
160  stereoMethod_ = DC1394_STEREO_METHOD_INTERLACED;
161  }
162  else if (0 == strcmp(method, "Field"))
163  {
164  stereoMethod_ = DC1394_STEREO_METHOD_FIELD;
165  }
166  else
167  {
168  doStereo = false;
169  }
170 
171  return doStereo;
172 }
173 
184 int Camera1394Stereo::open(camera1394stereo::Camera1394StereoConfig &newconfig)
185 {
187  // First, look for the camera
189 
190  const char *guid = newconfig.guid.c_str(); // C-style GUID for libdc1394
191  int err;
192  dc1394_t *d;
193  dc1394camera_list_t *list;
194 
195  // TODO: make error exit paths clean up resources properly
196  d = dc1394_new ();
197  if (d == NULL)
198  {
199  CAM_EXCEPT(camera1394stereo::Exception,
200  "Could not initialize dc1394_context.\n"
201  "Make sure /dev/raw1394 exists, you have access permission,\n"
202  "and libraw1394 development package is installed.");
203  }
204 
205  err = dc1394_camera_enumerate(d, &list);
206  if (err != DC1394_SUCCESS)
207  {
208  CAM_EXCEPT(camera1394stereo::Exception, "Could not get camera list");
209  return -1;
210  }
211 
212  if (list->num == 0)
213  {
214  CAM_EXCEPT(camera1394stereo::Exception, "No cameras found");
215  return -1;
216  }
217 
218  char* temp=(char*)malloc(1024*sizeof(char));
219  for (unsigned i=0; i < list->num; i++)
220  {
221  // Create a camera
222  camera_ = dc1394_camera_new (d, list->ids[i].guid);
223  if (!camera_)
224  ROS_WARN_STREAM("Failed to initialize camera with GUID "
225  << std::hex << list->ids[i].guid);
226  else
227  ROS_INFO_STREAM("Found camera with GUID "
228  << std::hex << list->ids[i].guid);
229 
230  uint32_t value[3];
231 
232  value[0]= camera_->guid & 0xffffffff;
233  value[1]= (camera_->guid >>32) & 0x000000ff;
234  value[2]= (camera_->guid >>40) & 0xfffff;
235 
236  sprintf(temp,"%06x%02x%08x", value[2], value[1], value[0]);
237 
238  if (strcmp(guid,"")==0)
239  {
240  ROS_INFO_STREAM("No guid specified, using first camera found, GUID: "
241  << std::hex << camera_->guid);
242  device_id_ = std::string(temp);
243  break;
244  }
245 
246  ROS_DEBUG("Comparing %s to %s",guid,temp);
247  if (strcmp(temp,guid)==0)
248  {
249  device_id_=guid;
250  break;
251  }
252  SafeCleanup();
253  }
254  free (temp);
255  dc1394_camera_free_list (list);
256 
257  if (!camera_)
258  {
259  if (strcmp(guid,"")==0)
260  {
261  CAM_EXCEPT(camera1394stereo::Exception, "Could not find camera");
262  }
263  else
264  {
265  CAM_EXCEPT_ARGS(camera1394stereo::Exception,
266  "Could not find camera with guid %s", guid);
267  }
268  return -1;
269  }
270 
271  ROS_INFO_STREAM("camera model: " << camera_->vendor
272  << " " << camera_->model);
273 
275  // initialize camera
277 
278  // resetting some cameras is not a good idea
279  if (newconfig.reset_on_open
280  && DC1394_SUCCESS != dc1394_camera_reset(camera_))
281  {
282  // reset failed: log a warning, but continue
283  ROS_WARN("Unable to reset camera (continuing).");
284  }
285 
286  // first, set parameters that are common between Format7 and other modes
287  if (false == Modes::setIsoSpeed(camera_, newconfig.iso_speed))
288  {
289  SafeCleanup();
290  CAM_EXCEPT(camera1394stereo::Exception,
291  "Unable to set ISO speed; is the camera plugged in?");
292  return -1;
293  }
294 
295  // set video mode
296  videoMode_ = Modes::getVideoMode(camera_, newconfig.video_mode);
297  if (DC1394_SUCCESS != dc1394_video_set_mode(camera_, videoMode_))
298  {
299  SafeCleanup();
300  CAM_EXCEPT(camera1394stereo::Exception, "Failed to set video mode");
301  return -1;
302  }
303 
305  // special handling for Format7 modes
307 
308  findBayerPattern(newconfig.bayer_pattern.c_str());
309  DoBayerConversion_ = findBayerMethod(newconfig.bayer_method.c_str());
310  DoStereoExtract_ = findStereoMethod(newconfig.stereo_method.c_str());
311 
312  if (dc1394_is_video_mode_scalable(videoMode_) == DC1394_TRUE)
313  {
314  // set Format7 parameters
315  if (!format7_.start(camera_, videoMode_, newconfig))
316  {
317  SafeCleanup();
318  CAM_EXCEPT(camera1394stereo::Exception, "Format7 start failed");
319  return -1;
320  }
321  }
322  else
323  {
324  // Set frame rate and Bayer method (only valid for non-Format7 modes)
325  if (!Modes::setFrameRate(camera_, videoMode_, newconfig.frame_rate))
326  {
327  SafeCleanup();
328  CAM_EXCEPT(camera1394stereo::Exception, "Failed to set frame rate");
329  return -1;
330  }
331  }
332 
334  // get current color coding
336  if (DC1394_SUCCESS !=
337  dc1394_get_color_coding_from_video_mode(camera_, videoMode_, &colorCoding_) )
338  {
339  SafeCleanup();
340  CAM_EXCEPT(camera1394stereo::Exception, "Format7 start failed");
341  return -1;
342  }
343 
345  // start the device streaming data
347 
348  // Set camera to use DMA, improves performance.
349  if (DC1394_SUCCESS != dc1394_capture_setup(camera_, NUM_DMA_BUFFERS,
350  DC1394_CAPTURE_FLAGS_DEFAULT))
351  {
352  SafeCleanup();
353  CAM_EXCEPT(camera1394stereo::Exception, "Failed to open device!");
354  return -1;
355  }
356 
357  // Start transmitting camera data
358  if (DC1394_SUCCESS != dc1394_video_set_transmission(camera_, DC1394_ON))
359  {
360  SafeCleanup();
361  CAM_EXCEPT(camera1394stereo::Exception, "Failed to start device!");
362  return -1;
363  }
364 
366  // initialize feature settings
368 
369  // TODO: pass newconfig here and eliminate initialize() method
370  features_.reset(new Features(camera_));
371 
372  return 0;
373 }
374 
375 
378 {
379  if (camera_)
380  {
381  format7_.stop();
382  dc1394_capture_stop(camera_);
383  dc1394_camera_free(camera_);
384  camera_ = NULL;
385  }
386 }
387 
388 
391 {
392  if (camera_)
393  {
394  if (DC1394_SUCCESS != dc1394_video_set_transmission(camera_, DC1394_OFF)
395  || DC1394_SUCCESS != dc1394_capture_stop(camera_))
396  ROS_WARN("unable to stop camera");
397  }
398 
399  // Free resources
400  SafeCleanup();
401 
402  return 0;
403 }
404 
405 std::string bayer_string(dc1394color_filter_t pattern, unsigned int bits)
406 {
407  if (bits == 8)
408  {
409  switch (pattern)
410  {
411  case DC1394_COLOR_FILTER_RGGB:
413  case DC1394_COLOR_FILTER_GBRG:
415  case DC1394_COLOR_FILTER_GRBG:
417  case DC1394_COLOR_FILTER_BGGR:
419  default:
421  }
422  }
423  else if (bits == 16)
424  {
425  // FIXME: should add bayer_XXXX16 modes to sensor_msgs?
427  }
428 
430 }
431 
434  sensor_msgs::Image& image,
435  sensor_msgs::Image& image2)
436 {
437  ROS_ASSERT_MSG(camera_, "Attempt to read from camera that is not open.");
438 
439  dc1394video_frame_t * frame = NULL;
440  if (features_->isTriggerPowered())
441  {
442  ROS_DEBUG("[%016lx] polling camera", camera_->guid);
443  dc1394_capture_dequeue (camera_, DC1394_CAPTURE_POLICY_POLL, &frame);
444  if (!frame) return false;
445  }
446  else
447  {
448  ROS_DEBUG("[%016lx] waiting camera", camera_->guid);
449  dc1394_capture_dequeue (camera_, DC1394_CAPTURE_POLICY_WAIT, &frame);
450  if (!frame)
451  {
452  CAM_EXCEPT(camera1394stereo::Exception, "Unable to capture frame");
453  return false;
454  }
455 
456  }
457 
458  dc1394video_frame_t frame1 = *frame;
459 
460  if (DoStereoExtract_)
461  {
462  // deinterlace frame into two images one on top the other
463  size_t frame1_size = frame->total_bytes;
464  frame1.image = (unsigned char *) malloc(frame1_size);
465  frame1.allocated_image_bytes = frame1_size;
466  switch (frame->color_coding)
467  {
468  case DC1394_COLOR_CODING_MONO16:
469  frame1.color_coding = DC1394_COLOR_CODING_MONO8;
470  break;
471  case DC1394_COLOR_CODING_RAW16:
472  frame1.color_coding = DC1394_COLOR_CODING_RAW8;
473  break;
474  default:
475  ROS_WARN("Stereo extract in a non 16bit video mode");
476  };
477  int err = dc1394_deinterlace_stereo_frames(frame, &frame1, stereoMethod_);
478  if (err != DC1394_SUCCESS)
479  {
480  free(frame1.image);
481  dc1394_capture_enqueue(camera_, frame);
482  CAM_EXCEPT(camera1394stereo::Exception, "Could not extract stereo frames");
483  return false;
484  }
485  }
486 
487  uint8_t* capture_buffer = reinterpret_cast<uint8_t *>(frame1.image);
488 
489  if (DoBayerConversion_)
490  {
491  // debayer frame into RGB8
492  dc1394video_frame_t frame2;
493  size_t frame2_size = (frame1.size[0] * frame1.size[1]
494  * 3 * sizeof(unsigned char));
495  frame2.image = (unsigned char *) malloc(frame2_size);
496  frame2.allocated_image_bytes = frame2_size;
497  frame2.color_coding = DC1394_COLOR_CODING_RGB8;
498  frame1.color_filter = BayerPattern_;
499  int err = dc1394_debayer_frames(&frame1, &frame2, BayerMethod_);
500  if (err != DC1394_SUCCESS)
501  {
502  free(frame2.image);
503  dc1394_capture_enqueue(camera_, frame);
504  CAM_EXCEPT(camera1394stereo::Exception, "Could not convert/debayer frames");
505  return false;
506  }
507  capture_buffer = reinterpret_cast<uint8_t *>(frame2.image);
508  }
509 
510  ROS_ASSERT(capture_buffer);
511 
512  image.header.stamp = ros::Time( double(frame->timestamp) * 1.e-6 );
513  image.width = frame->size[0];
514  image.height = frame->size[1];
515  image2.header.stamp = image.header.stamp;
516  image2.width = 0;
517  image2.height = 0;
518  image2.step = 0;
519 
520  int image_size;
521  switch (colorCoding_)
522  {
523  case DC1394_COLOR_CODING_YUV444:
524  image.step=image.width*3;
525  image_size = image.height*image.step;
526  image.encoding = sensor_msgs::image_encodings::RGB8;
527  image.data.resize(image_size);
528  yuv::uyv2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
529  reinterpret_cast<unsigned char *> (&image.data[0]),
530  image.width * image.height);
531  break;
532  case DC1394_COLOR_CODING_YUV411:
533  image.step=image.width*3;
534  image_size = image.height*image.step;
535  image.encoding = sensor_msgs::image_encodings::RGB8;
536  image.data.resize(image_size);
537  yuv::uyyvyy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
538  reinterpret_cast<unsigned char *> (&image.data[0]),
539  image.width * image.height);
540  break;
541  case DC1394_COLOR_CODING_YUV422:
542  image.step=image.width*3;
543  image_size = image.height*image.step;
544  image.encoding = sensor_msgs::image_encodings::RGB8;
545  image.data.resize(image_size);
546  yuv::uyvy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
547  reinterpret_cast<unsigned char *> (&image.data[0]),
548  image.width * image.height);
549  break;
550  case DC1394_COLOR_CODING_RGB8:
551  image.step=image.width*3;
552  image_size = image.height*image.step;
553  image.encoding = sensor_msgs::image_encodings::RGB8;
554  image.data.resize(image_size);
555  memcpy(&image.data[0], capture_buffer, image_size);
556  break;
557  case DC1394_COLOR_CODING_MONO8:
558  case DC1394_COLOR_CODING_RAW8:
559  if (!DoBayerConversion_)
560  {
561  image.step=image.width;
562  image_size = image.height*image.step;
563  // set Bayer encoding in ROS Image message
564  image.encoding = bayer_string(BayerPattern_, 8);
565  image.data.resize(image_size);
566  memcpy(&image.data[0], capture_buffer, image_size);
567  }
568  else
569  {
570  image.step=image.width*3;
571  image_size = image.height*image.step;
572  image.encoding = sensor_msgs::image_encodings::RGB8;
573  image.data.resize(image_size);
574  memcpy(&image.data[0], capture_buffer, image_size);
575  }
576  break;
577  case DC1394_COLOR_CODING_MONO16:
578  case DC1394_COLOR_CODING_RAW16:
580  {
581  image2.width = image.width;
582  image2.height = image.height;
583  image2.step = image.step = image.width*3;
584  image_size = image.height*image.step;
585  image2.encoding = image.encoding = sensor_msgs::image_encodings::RGB8;
586  image.data.resize(image_size);
587  image2.data.resize(image_size);
588  memcpy(&image.data[0], capture_buffer, image_size);
589  memcpy(&image2.data[0], capture_buffer+image_size, image_size);
590  }
591  else if (DoStereoExtract_)
592  {
593  image2.width = image.width;
594  image2.height = image.height;
595  image.step = image.width;
596  image2.step = image.step;
597  image_size = image.height*image.step;
598  image.encoding = bayer_string(BayerPattern_, 8);
599  image2.encoding = image.encoding;
600  image.data.resize(image_size);
601  image2.data.resize(image_size);
602  memcpy(&image.data[0], capture_buffer, image_size);
603  memcpy(&image2.data[0], capture_buffer+image_size, image_size);
604  }
605  else if (DoBayerConversion_)
606  {
607  // @todo test Bayer conversions for mono16
608  image.step=image.width*3;
609  image_size = image.height*image.step;
610  image.encoding = sensor_msgs::image_encodings::RGB8;
611  image.data.resize(image_size);
612  memcpy(&image.data[0], capture_buffer, image_size);
613  }
614  else
615  {
616  image.step=image.width*2;
617  image_size = image.height*image.step;
618  image.encoding = bayer_string(BayerPattern_, 16);
619  image.is_bigendian = false; // check Bumblebee2 endianness
620  image.data.resize(image_size);
621  memcpy(&image.data[0], capture_buffer, image_size);
622  }
623  break;
624  default:
625  {
626  CAM_EXCEPT(camera1394stereo::Exception, "Unknown image mode and coding");
627  return false;
628  }
629  }
630 
631  dc1394_capture_enqueue(camera_, frame);
632 
634  {
635  free(capture_buffer);
637  free(frame1.image);
638  }
639  return true;
640 }
d
const std::string BAYER_GRBG8
void stop(void)
libdc1394 enumerated modes interface
boost::shared_ptr< Features > features_
bool readData(sensor_msgs::Image &image, sensor_msgs::Image &image2)
void uyvy2rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: yuv.h:70
#define ROS_WARN(...)
bool start(dc1394camera_t *camera, dc1394video_mode_t mode, Config &newconfig)
bool setIsoSpeed(dc1394camera_t *camera, int &iso_speed)
Definition: modes.cpp:360
const std::string BAYER_GBRG8
Camera1394 features interface.
std::string bayer_string(dc1394color_filter_t pattern, unsigned int bits)
IEEE 1394 digital camera library interface.
#define NUM_DMA_BUFFERS
#define ROS_ASSERT_MSG(cond,...)
YUV to RGB conversion functions.
const std::string MONO16
Camera1394 Features class.
#define ROS_WARN_STREAM(args)
#define CAM_EXCEPT(except, msg)
Macro for throwing an exception with a message.
const std::string BAYER_BGGR8
#define ROS_INFO_STREAM(args)
bool setFrameRate(dc1394camera_t *camera, dc1394video_mode_t video_mode, double &frame_rate)
Definition: modes.cpp:332
void uyyvyy2rgb(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: yuv.h:96
int open(camera1394stereo::Camera1394StereoConfig &newconfig)
const std::string BAYER_RGGB8
#define ROS_ASSERT(cond)
#define ROS_ERROR(...)
dc1394video_mode_t getVideoMode(dc1394camera_t *camera, std::string &video_mode)
Definition: modes.cpp:265
void uyv2rgb(const unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: yuv.h:50
#define CAM_EXCEPT_ARGS(except, msg,...)
Macro for throwing an exception with a message, passing args.
#define ROS_DEBUG(...)


camera1394stereo
Author(s): Joan Pau Beltran
autogenerated on Mon Jun 10 2019 12:52:45