dev_camera1394.cpp
Go to the documentation of this file.
00001 
00002 //
00003 // Copyright (C) 2009, 2010, 2012 Patrick Beeson, Jack O'Quin, Ken Tossell
00004 //  ROS port of the Player 1394 camera driver.
00005 //
00006 // Copyright (C) 2004 Nate Koenig, Andrew Howard
00007 //  Player driver for IEEE 1394 digital camera capture
00008 //
00009 // Copyright (C) 2000-2003 Damien Douxchamps, Dan Dennedy
00010 //  Bayer filtering from libdc1394
00011 //
00012 // NOTE: On 4 Jan. 2011, this file was re-licensed under the GNU LGPL
00013 // with permission of the original GPL authors: Nate Koenig, Andrew
00014 // Howard, Damien Douxchamps and Dan Dennedy.
00015 //
00016 // This program is free software; you can redistribute it and/or
00017 // modify it under the terms of the GNU Lesser General Public License
00018 // as published by the Free Software Foundation; either version 2 of
00019 // the License, or (at your option) any later version.
00020 // 
00021 // This program is distributed in the hope that it will be useful, but
00022 // WITHOUT ANY WARRANTY; without even the implied warranty of
00023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024 // Lesser General Public License for more details.
00025 // 
00026 // You should have received a copy of the GNU Lesser General Public
00027 // License along with this program; if not, write to the Free Software
00028 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00029 // 02111-1307, USA.
00030 //
00032 
00033 // $Id: dev_camera1394.cpp 38791 2012-02-04 14:35:23Z joq $
00034 
00049 #include <stdint.h>
00050 
00051 #include "yuv.h"
00052 #include <sensor_msgs/image_encodings.h>
00053 #include "dev_camera1394.h"
00054 #include "features.h"
00055 #include "modes.h"
00056 
00057 // @todo eliminate these macros
00059 #define CAM_EXCEPT(except, msg)                                 \
00060   {                                                             \
00061     char buf[100];                                              \
00062     snprintf(buf, 100, "[Camera1394::%s]: " msg, __FUNCTION__); \
00063     throw except(buf);                                          \
00064   }
00065 
00067 #define CAM_EXCEPT_ARGS(except, msg, ...)                               \
00068   {                                                                     \
00069     char buf[100];                                                      \
00070     snprintf(buf, 100, "[Camera1394::%s]: " msg, __FUNCTION__, __VA_ARGS__); \
00071     throw except(buf);                                                  \
00072   }
00073 
00074 
00075 using namespace camera1394;
00076 
00078 // Constructor
00079 Camera1394::Camera1394():
00080   camera_(NULL)
00081 {}
00082 
00083 Camera1394::~Camera1394() 
00084 {
00085   SafeCleanup();
00086 }
00087 
00088 void Camera1394::findBayerPattern(const char* bayer)
00089 {
00090   // determine Bayer color encoding pattern
00091   // (default is different from any color filter provided by DC1394)
00092   BayerPattern_ = (dc1394color_filter_t) DC1394_COLOR_FILTER_NUM;
00093   if (0 == strcmp(bayer, "bggr"))
00094     {
00095       BayerPattern_ = DC1394_COLOR_FILTER_BGGR;
00096     }
00097   else if (0 == strcmp(bayer, "grbg"))
00098     {
00099       BayerPattern_ = DC1394_COLOR_FILTER_GRBG;
00100     }
00101   else if (0 == strcmp(bayer, "rggb"))
00102     {
00103       BayerPattern_ = DC1394_COLOR_FILTER_RGGB;
00104     }
00105   else if (0 == strcmp(bayer, "gbrg"))
00106     {
00107       BayerPattern_ = DC1394_COLOR_FILTER_GBRG;
00108     }
00109   else if (0 != strcmp(bayer, ""))
00110     {
00111       ROS_ERROR("unknown bayer pattern [%s]", bayer);
00112     }
00113 }
00114 
00115 bool Camera1394::findBayerMethod(const char* method)
00116 {
00117   // Do Bayer conversion in the driver node?
00118   bool DoBayer = false;                 // return value
00119   if (0 != strcmp(method, "")
00120       && BayerPattern_ != DC1394_COLOR_FILTER_NUM)
00121     {
00122       DoBayer = true;                   // decoding in driver
00123       // add method name to message:
00124       ROS_WARN("[%s] Bayer decoding in the driver is DEPRECATED;"
00125                " image_proc decoding preferred.", method);
00126 
00127       // Set decoding method
00128       if (!strcmp(method, "DownSample"))
00129         BayerMethod_ = DC1394_BAYER_METHOD_DOWNSAMPLE;
00130       else if (!strcmp(method, "Simple"))
00131         BayerMethod_ = DC1394_BAYER_METHOD_SIMPLE;
00132       else if (!strcmp(method, "Bilinear"))
00133         BayerMethod_ = DC1394_BAYER_METHOD_BILINEAR;
00134       else if (!strcmp(method, "HQ"))
00135         BayerMethod_ = DC1394_BAYER_METHOD_HQLINEAR;
00136       else if (!strcmp(method, "VNG"))
00137         BayerMethod_ = DC1394_BAYER_METHOD_VNG;
00138       else if (!strcmp(method, "AHD"))
00139         BayerMethod_ = DC1394_BAYER_METHOD_AHD;
00140       else
00141         {
00142           ROS_ERROR("Unknown Bayer method [%s]. Using ROS image_proc instead.",
00143                     method);
00144           DoBayer = false;
00145         }
00146     }
00147   return DoBayer;
00148 }
00149 
00160 int Camera1394::open(camera1394::Camera1394Config &newconfig)
00161 {
00163   // Pad GUID (if specified) with leading zeros
00165 
00166   const static size_t exact_guid_length = 16;
00167   size_t guid_length = newconfig.guid.length();
00168   if (guid_length != 0 && guid_length != exact_guid_length)
00169       {
00170         if (guid_length < exact_guid_length)
00171           {
00172             // pad string with leading zeros
00173             newconfig.guid.insert(0, exact_guid_length - guid_length, '0');
00174           }
00175         else
00176           {
00177             ROS_ERROR_STREAM_THROTTLE(3, "Invalid GUID [" << newconfig.guid
00178                                       << "] specified: " << guid_length
00179                                       << " characters long.");
00180           }
00181       }
00182 
00184   // First, look for the camera
00186       
00187   const char *guid = newconfig.guid.c_str();  // C-style GUID for libdc1394
00188   int err;
00189   dc1394_t *d;
00190   dc1394camera_list_t *list;
00191 
00192   // TODO: make error exit paths clean up resources properly
00193   d = dc1394_new ();
00194   if (d == NULL)
00195     {
00196       CAM_EXCEPT(camera1394::Exception,
00197                  "Could not initialize dc1394_context.\n"
00198                  "Make sure /dev/raw1394 exists, you have access permission,\n"
00199                  "and libraw1394 development package is installed.");
00200     }
00201 
00202   err = dc1394_camera_enumerate(d, &list);
00203   if (err != DC1394_SUCCESS)
00204     {
00205       CAM_EXCEPT(camera1394::Exception, "Could not get camera list");
00206       return -1;
00207     }
00208   
00209   if (list->num == 0)
00210     {
00211       CAM_EXCEPT(camera1394::Exception, "No cameras found");
00212       return -1;
00213     }
00214   
00215   char* temp=(char*)malloc(1024*sizeof(char));
00216   for (unsigned i=0; i < list->num; i++)
00217     {
00218       // Create a camera
00219       camera_ = dc1394_camera_new (d, list->ids[i].guid);
00220       if (!camera_)
00221         ROS_WARN_STREAM("Failed to initialize camera with GUID "
00222                         << std::setw(16) << std::setfill('0') << std::hex
00223                         << list->ids[i].guid);
00224       else
00225         ROS_INFO_STREAM("Found camera with GUID "
00226                         << std::setw(16) << std::setfill('0') << std::hex
00227                         << list->ids[i].guid);
00228 
00229       uint32_t value[3];
00230       
00231       value[0]= camera_->guid & 0xffffffff;
00232       value[1]= (camera_->guid >>32) & 0x000000ff;
00233       value[2]= (camera_->guid >>40) & 0xfffff;
00234       
00235       sprintf(temp,"%06x%02x%08x", value[2], value[1], value[0]);
00236 
00237       if (strcmp(guid,"")==0)
00238         {
00239           // pad GUID with leading zeros in message
00240           ROS_INFO_STREAM("No GUID specified, using first camera found, GUID: "
00241                           << std::setw(16) << std::setfill('0') << std::hex
00242                           << camera_->guid);
00243           device_id_ = std::string(temp);
00244           break;
00245         }
00246 
00247       ROS_DEBUG("Comparing %s to %s",guid,temp);
00248       if (strcmp(temp,guid)==0)
00249         {
00250           device_id_=guid;
00251           break;
00252         }
00253       SafeCleanup();
00254     }
00255   free (temp);
00256   dc1394_camera_free_list (list);
00257   
00258   if (!camera_)
00259     {
00260       if (strcmp(guid,"")==0)
00261         { 
00262           CAM_EXCEPT(camera1394::Exception, "Could not find camera");
00263         }
00264       else
00265         {
00266           CAM_EXCEPT_ARGS(camera1394::Exception,
00267                           "Could not find camera with guid %s", guid);
00268         }
00269       return -1;
00270     }
00271 
00272   ROS_INFO_STREAM("camera model: " << camera_->vendor
00273                   << " " << camera_->model);
00274 
00276   // initialize camera
00278 
00279   // TP: Reset bus to free previously allocated resources.
00280   // And wait till the bus recovers.
00281   // This seems to be needed if the nodelet camera1394 driver is
00282   // used since it doesn't free all resources on return.
00283   if (newconfig.reset_bus_on_open)
00284     {
00285       ROS_INFO("Resetting IEEE1394 bus...");
00286       if (DC1394_SUCCESS != dc1394_reset_bus(camera_))
00287         {
00288           // bus reset failed: log a warning, but continue
00289           ROS_WARN("Unable to reset bus (continuing).");
00290         }
00291       sleep(3);
00292     }
00293   
00294   // resetting some cameras is not a good idea
00295   if (newconfig.reset_on_open)
00296     {
00297       ROS_INFO("Resetting camera...");
00298       if (DC1394_SUCCESS != dc1394_camera_reset(camera_))
00299         {
00300           // reset failed: log a warning, but continue
00301           ROS_WARN("Unable to reset camera (continuing).");
00302         }
00303       sleep(3);
00304     }
00305 
00306   // first, set parameters that are common between Format7 and other modes
00307   if (false == Modes::setIsoSpeed(camera_, newconfig.iso_speed))
00308     {
00309       SafeCleanup();
00310       CAM_EXCEPT(camera1394::Exception,
00311                  "Unable to set ISO speed; is the camera plugged in?");
00312       return -1;
00313     }
00314 
00315   // set video mode
00316   videoMode_ = Modes::getVideoMode(camera_, newconfig.video_mode);
00317   if (DC1394_SUCCESS != dc1394_video_set_mode(camera_, videoMode_))
00318     {
00319       SafeCleanup();
00320       CAM_EXCEPT(camera1394::Exception, "Failed to set video mode");
00321       return -1;
00322     }
00323 
00325   // special handling for Format7 modes
00327 
00328   DoBayerConversion_ = false;
00329 
00330   if (dc1394_is_video_mode_scalable(videoMode_) == DC1394_TRUE)
00331     {
00332       // set Format7 parameters
00333       if (!format7_.start(camera_, videoMode_, newconfig))
00334         {
00335           SafeCleanup();
00336           CAM_EXCEPT(camera1394::Exception, "Format7 start failed");
00337           return -1;
00338         }
00339     }
00340   else
00341     {
00342       // Set frame rate and Bayer method (only valid for non-Format7 modes)
00343       DoBayerConversion_ = findBayerMethod(newconfig.bayer_method.c_str());
00344       if (!Modes::setFrameRate(camera_, videoMode_, newconfig.frame_rate))
00345         {
00346           SafeCleanup();
00347           CAM_EXCEPT(camera1394::Exception, "Failed to set frame rate");
00348           return -1;
00349         }
00350     }
00351 
00352   findBayerPattern(newconfig.bayer_pattern.c_str());
00353 
00354   use_ros_time_ = newconfig.use_ros_time;
00355 
00357   // start the device streaming data
00359 
00360   // TP: Setup capture using a number of DMA buffers specified..
00361   ROS_INFO("Setup capture using %i DMA buffers.", newconfig.num_dma_buffers);
00362 
00363   // Set camera to use DMA, improves performance.
00364   if (DC1394_SUCCESS != dc1394_capture_setup(camera_, newconfig.num_dma_buffers,
00365                                              DC1394_CAPTURE_FLAGS_DEFAULT))
00366     {
00367       SafeCleanup();
00368       CAM_EXCEPT(camera1394::Exception, "Failed to open device!");
00369       return -1;
00370     }
00371   
00372   // Start transmitting camera data
00373   if (DC1394_SUCCESS != dc1394_video_set_transmission(camera_, DC1394_ON))
00374     {
00375       SafeCleanup();
00376       CAM_EXCEPT(camera1394::Exception, "Failed to start device!");
00377       return -1;
00378     }
00379 
00381   // initialize feature settings
00383 
00384   // TODO: pass newconfig here and eliminate initialize() method
00385   features_.reset(new Features(camera_));
00386  
00387   // TP: Exclude the top camera from auto exposure.
00388   const uint64_t AE_STATS_MASK_REGISTER = 0x1E90ul;
00389   const uint32_t AE_STATS_MASK_CAMS = 1u << 5 | 1u << 4 | 1u << 3 | 1u << 2 | 1u << 1;
00390   ROS_INFO("Setting AE_STATS_MASK register to %X...", AE_STATS_MASK_CAMS);
00391   if (DC1394_SUCCESS != dc1394_set_control_register(camera_, AE_STATS_MASK_REGISTER, AE_STATS_MASK_CAMS)) {
00392     ROS_WARN("Unable to set AE_STATS_MASK register to %X (continuing).", AE_STATS_MASK_CAMS);
00393   }
00394   
00395   return 0;
00396 }
00397 
00398 
00400 void Camera1394::SafeCleanup()
00401 {
00402   if (camera_)
00403     {
00404       format7_.stop();
00405       dc1394_capture_stop(camera_);
00406       // try to power off the device (#5322):
00407       dc1394_camera_set_power(camera_, DC1394_OFF);
00408       dc1394_camera_free(camera_);
00409       camera_ = NULL;
00410     }
00411 }
00412 
00413 
00415 int Camera1394::close()
00416 {
00417   if (camera_)
00418     {
00419       if (DC1394_SUCCESS != dc1394_video_set_transmission(camera_, DC1394_OFF)
00420           || DC1394_SUCCESS != dc1394_capture_stop(camera_))
00421         ROS_WARN("unable to stop camera");
00422     }
00423 
00424   // Free resources
00425   SafeCleanup();
00426 
00427   return 0;
00428 }
00429 
00430 std::string bayer_string(dc1394color_filter_t pattern, unsigned int bits)
00431 {
00432   if (bits == 8)
00433     {
00434       switch (pattern)
00435         {
00436         case DC1394_COLOR_FILTER_RGGB:
00437           return sensor_msgs::image_encodings::BAYER_RGGB8;
00438         case DC1394_COLOR_FILTER_GBRG:
00439           return sensor_msgs::image_encodings::BAYER_GBRG8;
00440         case DC1394_COLOR_FILTER_GRBG:
00441           return sensor_msgs::image_encodings::BAYER_GRBG8;
00442         case DC1394_COLOR_FILTER_BGGR:
00443           return sensor_msgs::image_encodings::BAYER_BGGR8;
00444         default:
00445           return sensor_msgs::image_encodings::MONO8;
00446         }
00447     }
00448   else if (bits == 16)
00449     {
00450       switch (pattern)
00451         {
00452         case DC1394_COLOR_FILTER_RGGB:
00453           return sensor_msgs::image_encodings::BAYER_RGGB16;
00454         case DC1394_COLOR_FILTER_GBRG:
00455           return sensor_msgs::image_encodings::BAYER_GBRG16;
00456         case DC1394_COLOR_FILTER_GRBG:
00457           return sensor_msgs::image_encodings::BAYER_GRBG16;
00458         case DC1394_COLOR_FILTER_BGGR:
00459           return sensor_msgs::image_encodings::BAYER_BGGR16;
00460         default:
00461           return sensor_msgs::image_encodings::MONO16;
00462         }
00463     }
00464 
00465   // bits should always be 8 or 16, but if not MONO8 is a good default
00466   return sensor_msgs::image_encodings::MONO8;
00467 }
00468 
00470 void Camera1394::readData(sensor_msgs::Image& image)
00471 {
00472   ROS_ASSERT_MSG(camera_, "Attempt to read from camera that is not open.");
00473 
00474   dc1394video_frame_t * frame = NULL;
00475   dc1394_capture_dequeue (camera_, DC1394_CAPTURE_POLICY_WAIT, &frame);
00476   if (!frame)
00477     {
00478       CAM_EXCEPT(camera1394::Exception, "Unable to capture frame");
00479       return;
00480     }
00481   
00482   uint8_t* capture_buffer;
00483 
00484   if (use_ros_time_)
00485     image.header.stamp = ros::Time::now();
00486   else
00487     image.header.stamp = ros::Time((double) frame->timestamp / 1000000.0);
00488 
00489   dc1394video_frame_t frame2;
00490 
00491   if (DoBayerConversion_)
00492     {
00493       // debayer frame into RGB8
00494       size_t frame2_size = (frame->size[0] * frame->size[1]
00495                             * 3 * sizeof(unsigned char));
00496       frame2.image = (unsigned char *) malloc(frame2_size);
00497       frame2.allocated_image_bytes = frame2_size;
00498       frame2.color_coding = DC1394_COLOR_CODING_RGB8;
00499 
00500       frame->color_filter = BayerPattern_;
00501       int err = dc1394_debayer_frames(frame, &frame2, BayerMethod_);
00502       if (err != DC1394_SUCCESS)
00503         {
00504           free(frame2.image);
00505           dc1394_capture_enqueue(camera_, frame);
00506           CAM_EXCEPT(camera1394::Exception, "Could not convert/debayer frames");
00507           return;
00508         }
00509 
00510       capture_buffer = reinterpret_cast<uint8_t *>(frame2.image);
00511 
00512       image.width = frame2.size[0];
00513       image.height = frame2.size[1];
00514     }
00515   else
00516     {
00517       image.width = frame->size[0];
00518       image.height = frame->size[1];
00519       capture_buffer = reinterpret_cast<uint8_t *>(frame->image);
00520     }
00521 
00522   ROS_ASSERT(capture_buffer);   
00523 
00524   int image_size;  
00525   switch (videoMode_)
00526     {
00527     case DC1394_VIDEO_MODE_160x120_YUV444:
00528       image.step=image.width*3;
00529       image_size = image.height*image.step;
00530       image.encoding = sensor_msgs::image_encodings::RGB8;
00531       image.data.resize(image_size);
00532       yuv::uyv2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
00533                    reinterpret_cast<unsigned char *> (&image.data[0]),
00534                    image.width * image.height);
00535       break;
00536     case DC1394_VIDEO_MODE_640x480_YUV411:
00537       image.step=image.width*3;
00538       image_size = image.height*image.step;
00539       image.encoding = sensor_msgs::image_encodings::RGB8;
00540       image.data.resize(image_size);
00541       yuv::uyyvyy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
00542                       reinterpret_cast<unsigned char *> (&image.data[0]),
00543                       image.width * image.height);
00544       break;
00545     case DC1394_VIDEO_MODE_320x240_YUV422:
00546     case DC1394_VIDEO_MODE_640x480_YUV422:
00547     case DC1394_VIDEO_MODE_800x600_YUV422:
00548     case DC1394_VIDEO_MODE_1024x768_YUV422:
00549     case DC1394_VIDEO_MODE_1280x960_YUV422:
00550     case DC1394_VIDEO_MODE_1600x1200_YUV422:
00551       image.step=image.width*3;
00552       image_size = image.height*image.step;
00553       image.encoding = sensor_msgs::image_encodings::RGB8;
00554       image.data.resize(image_size);
00555       yuv::uyvy2rgb(reinterpret_cast<unsigned char *> (capture_buffer),
00556                     reinterpret_cast<unsigned char *> (&image.data[0]),
00557                     image.width * image.height);
00558       break;
00559     case DC1394_VIDEO_MODE_640x480_RGB8:
00560     case DC1394_VIDEO_MODE_800x600_RGB8:
00561     case DC1394_VIDEO_MODE_1024x768_RGB8:
00562     case DC1394_VIDEO_MODE_1280x960_RGB8:
00563     case DC1394_VIDEO_MODE_1600x1200_RGB8:
00564       image.step=image.width*3;
00565       image_size = image.height*image.step;
00566       image.encoding = sensor_msgs::image_encodings::RGB8;
00567       image.data.resize(image_size);
00568       memcpy(&image.data[0], capture_buffer, image_size);
00569       break;
00570     case DC1394_VIDEO_MODE_640x480_MONO8:
00571     case DC1394_VIDEO_MODE_800x600_MONO8:
00572     case DC1394_VIDEO_MODE_1024x768_MONO8:
00573     case DC1394_VIDEO_MODE_1280x960_MONO8:
00574     case DC1394_VIDEO_MODE_1600x1200_MONO8:
00575       if (!DoBayerConversion_)
00576         {
00577           image.step=image.width;
00578           image_size = image.height*image.step;
00579           // set Bayer encoding in ROS Image message
00580           image.encoding = bayer_string(BayerPattern_, 8);
00581           image.data.resize(image_size);
00582           memcpy(&image.data[0], capture_buffer, image_size);
00583         }
00584       else
00585         {
00586           image.step=image.width*3;
00587           image_size = image.height*image.step;
00588           image.encoding = sensor_msgs::image_encodings::RGB8;
00589           image.data.resize(image_size);
00590           memcpy(&image.data[0], capture_buffer, image_size);
00591         } 
00592       break;
00593     case DC1394_VIDEO_MODE_640x480_MONO16:
00594     case DC1394_VIDEO_MODE_800x600_MONO16:
00595     case DC1394_VIDEO_MODE_1024x768_MONO16:
00596     case DC1394_VIDEO_MODE_1280x960_MONO16:
00597     case DC1394_VIDEO_MODE_1600x1200_MONO16:
00598       if (!DoBayerConversion_)
00599         {
00600           image.step=image.width*2;
00601           image_size = image.height*image.step;
00602           image.encoding = bayer_string(BayerPattern_, 16);
00603           image.is_bigendian = true;
00604           image.data.resize(image_size);
00605           memcpy(&image.data[0], capture_buffer, image_size);
00606         }
00607       else
00608         {
00609           // @todo test Bayer conversions for mono16
00610           image.step=image.width*3;
00611           image_size = image.height*image.step;
00612           image.encoding = sensor_msgs::image_encodings::RGB8;
00613           image.data.resize(image_size);
00614           memcpy(&image.data[0], capture_buffer, image_size);
00615         } 
00616       break;
00617     default:
00618       if (dc1394_is_video_mode_scalable(videoMode_))
00619         {
00620           format7_.unpackData(image, capture_buffer);
00621         }
00622       else
00623         {
00624           CAM_EXCEPT(camera1394::Exception, "Unknown image mode");
00625           return;
00626         }
00627     }
00628   dc1394_capture_enqueue(camera_, frame);
00629 
00630   if (DoBayerConversion_) 
00631     free(capture_buffer);
00632 }
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines


camera1394
Author(s): Jack O'Quin, Ken Tossell, Patrick Beeson, Nate Koenig, Andrew Howard, Damien Douxchamps, Dan Dennedy Tomas Petricek / petrito1@cmp.felk.cvut.cz
autogenerated on Tue Dec 10 2013 14:25:10