fotonic_grabber.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2011, Willow Garage, Inc.
00006  *  Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of the copyright holder(s) nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  */
00038 
00039 #include <pcl/pcl_config.h>
00040 #ifdef HAVE_FZAPI
00041 
00042 #include <pcl/io/fotonic_grabber.h>
00043 #include <pcl/point_cloud.h>
00044 #include <pcl/point_types.h>
00045 #include <pcl/common/time.h>
00046 #include <pcl/common/io.h>
00047 #include <pcl/console/print.h>
00048 #include <pcl/io/boost.h>
00049 #include <pcl/exceptions.h>
00050 
00051 #include <boost/thread.hpp>
00052 
00053 #include <iostream>
00054 
00056 pcl::FotonicGrabber::FotonicGrabber (const FZ_DEVICE_INFO& device_info, const Mode& depth_mode, const Mode& image_mode)
00057   : running_ (false)
00058 {
00059   // initialize device
00060   onInit (device_info, depth_mode, image_mode);
00061 
00062   point_cloud_signal_      = createSignal<sig_cb_fotonic_point_cloud> ();
00063   point_cloud_rgb_signal_  = createSignal<sig_cb_fotonic_point_cloud_rgb> ();
00064   point_cloud_rgba_signal_ = createSignal<sig_cb_fotonic_point_cloud_rgba> ();
00065 }
00066 
00068 pcl::FotonicGrabber::~FotonicGrabber () throw ()
00069 {
00070   stop ();
00071 
00072   disconnect_all_slots<sig_cb_fotonic_point_cloud> ();
00073   disconnect_all_slots<sig_cb_fotonic_point_cloud_rgb> ();
00074   disconnect_all_slots<sig_cb_fotonic_point_cloud_rgba> ();
00075 }
00076 
00078 void
00079 pcl::FotonicGrabber::initAPI ()
00080 {
00081   FZ_Init ();
00082 }
00083 
00085 void
00086 pcl::FotonicGrabber::exitAPI ()
00087 {
00088   FZ_Exit ();
00089 }
00090 
00092 std::vector<FZ_DEVICE_INFO>
00093 pcl::FotonicGrabber::enumDevices ()
00094 {
00095   // enumerate devices
00096   int num_of_devices = 32;
00097   FZ_DEVICE_INFO * device_infos = new FZ_DEVICE_INFO[num_of_devices];
00098   FZ_Result result = FZ_EnumDevices2 (device_infos, &num_of_devices);
00099 
00100   // put found devices into vector
00101   std::vector<FZ_DEVICE_INFO> devices;
00102   for (int index = 0; index < num_of_devices; ++index)
00103   {
00104     FZ_DEVICE_INFO device_info;
00105     device_info.iDeviceType = device_infos[index].iDeviceType;
00106     memcpy (device_info.iReserved, device_infos[index].iReserved, sizeof (device_infos[index].iReserved[0])*64);
00107     memcpy (device_info.szPath, device_infos[index].szPath, sizeof (device_infos[index].szPath[0])*512);
00108     memcpy (device_info.szSerial, device_infos[index].szSerial, sizeof (device_infos[index].szSerial[0])*16);
00109     memcpy (device_info.szShortName, device_infos[index].szShortName, sizeof (device_infos[index].szShortName[0])*32);
00110 
00111     devices.push_back (device_info);
00112   }
00113 
00114   return (devices);
00115 }
00116 
00118 void
00119 pcl::FotonicGrabber::start ()
00120 {
00121   FZ_CmdRespCode_t resp;
00122   FZ_Result res = FZ_IOCtl (*fotonic_device_handle_, CMD_DE_SENSOR_START, NULL, 0, &resp, NULL, NULL);
00123 
00124   running_ = true;
00125 
00126   grabber_thread_ = boost::thread(&pcl::FotonicGrabber::processGrabbing, this); 
00127 }
00128 
00130 void
00131 pcl::FotonicGrabber::stop ()
00132 {
00133   running_ = false;
00134   grabber_thread_.join ();
00135 
00136   FZ_Close (*fotonic_device_handle_);
00137 }
00138 
00140 bool
00141 pcl::FotonicGrabber::isRunning () const
00142 {
00143   return (running_);
00144 }
00145 
00147 std::string
00148 pcl::FotonicGrabber::getName () const
00149 {
00150   return std::string ("FotonicGrabber");
00151 }
00152 
00154 float
00155 pcl::FotonicGrabber::getFramesPerSecond () const
00156 {
00157   //return (static_cast<float> (device_->getDepthOutputMode ().nFPS));
00158   return 0.0f;
00159 }
00160 
00162 void
00163 pcl::FotonicGrabber::onInit (const FZ_DEVICE_INFO& device_info, const Mode& depth_mode, const Mode& image_mode)
00164 {
00165   setupDevice (device_info, depth_mode, image_mode);
00166 }
00167 
00169 void
00170 pcl::FotonicGrabber::setupDevice (const FZ_DEVICE_INFO& device_info, const Mode& depth_mode, const Mode& image_mode)
00171 {
00172   // Initialize device
00173   fotonic_device_handle_ = new FZ_Device_Handle_t ();
00174 
00175   unsigned int flags = 0;
00176 
00177   FZ_Result res;
00178 
00179   res = FZ_Open (device_info.szPath, flags, fotonic_device_handle_);
00180       
00181   // set mode (resolution, fps..)
00182         FZ_CmdRespCode_t resp;
00183   unsigned short mode = DE_MODE_640X480_30;
00184   res = FZ_IOCtl (*fotonic_device_handle_, CMD_DE_SET_MODE, &mode, sizeof(mode), &resp, NULL, NULL);
00185 
00186   res = FZ_SetFrameDataFmt (*fotonic_device_handle_, -1, -1, -1, -1, FZ_FMT_PIXEL_PER_PLANE+FZ_FMT_COMPONENT_Z+FZ_FMT_COMPONENT_XY+FZ_FMT_COMPONENT_B);
00187 }
00188 
00190 void
00191 pcl::FotonicGrabber::processGrabbing ()
00192 {
00193   char * frame_buffer = new char [640*480*8];
00194 
00195   bool continue_grabbing = running_;
00196   while (continue_grabbing)
00197   {
00198     FZ_Result result = FZ_FrameAvailable (*fotonic_device_handle_);
00199     //std::cerr << "FZ_FrameAvailable: " << result << std::endl;
00200 
00201     if (result == FZ_Success)
00202     {
00203       size_t length_in_byte = 640*480*10;
00204       FZ_FRAME_HEADER frame_header;
00205 
00206       result = FZ_GetFrame (*fotonic_device_handle_, &frame_header, frame_buffer, &length_in_byte);
00207 
00208       if (result == FZ_Success)
00209       {
00210         //std::cerr << "frame: " << frame_header.framecounter << std::endl;
00211         //std::cerr << "  timestamp: " << frame_header.timestamp << std::endl;
00212         //std::cerr << "  format: " << frame_header.format << std::endl;
00213         //std::cerr << "  cols: " << frame_header.ncols << std::endl;
00214         //std::cerr << "  rows: " << frame_header.nrows << std::endl;
00215         //std::cerr << "  reportedframerate: " << frame_header.reportedframerate << std::endl;
00216         //std::cerr << "  bytesperpixel: " << frame_header.bytesperpixel << std::endl;
00217 
00218         const int width = frame_header.ncols;
00219         const int height = frame_header.nrows;
00220 
00221         pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA> ());
00222         cloud->resize (width*height);
00223         cloud->width = width;
00224         cloud->height = height;
00225         cloud->is_dense = false;
00226 
00227         short * ptr = (short*) frame_buffer;
00228 
00229         for (int row_index = 0; row_index < height; ++row_index)
00230         {
00231           //if(pixelformat == FZ_PIXELFORMAT_YUV422) 
00232           {
00233             // YUV422
00234             FZ_YUV422_DOUBLE_PIXEL *p = (FZ_YUV422_DOUBLE_PIXEL*)ptr;
00235             int col = 0;
00236             for (int col_index = 0; col_index < width/2; ++col_index)
00237             {
00238               pcl::PointXYZRGBA & point0 = (*cloud) (col, row_index);
00239               ++col;
00240               pcl::PointXYZRGBA & point1 = (*cloud) (col, row_index);
00241               ++col;
00242 
00243               float r,g,b,u,v,u1,v1,uv1;
00244 
00245               u = p[col_index].u - 128.0f;
00246               v = p[col_index].v - 128.0f;
00247               v1 = 1.13983f*v;
00248               uv1 = -0.39465f*u - 0.58060f*v;
00249               u1 = 0.03211f*u;
00250 
00251               r = p[col_index].y1 + v1;
00252               g = p[col_index].y1 + uv1;
00253               b = p[col_index].y1 + u1;
00254 
00255               r = std::min (255.0f, std::max (0.0f, r));
00256               g = std::min (255.0f, std::max (0.0f, g));
00257               b = std::min (255.0f, std::max (0.0f, b));
00258 
00259               point0.r = unsigned(r);
00260               point0.g = unsigned(g);
00261               point0.b = unsigned(b);
00262                
00263               r = p[col_index].y2 + v1;
00264               g = p[col_index].y2 + uv1;
00265               b = p[col_index].y2 + u1;
00266 
00267               r = std::min (255.0f, std::max (0.0f, r));
00268               g = std::min (255.0f, std::max (0.0f, g));
00269               b = std::min (255.0f, std::max (0.0f, b));
00270                
00271               point1.r = unsigned(r);
00272               point1.g = unsigned(g);
00273               point1.b = unsigned(b);
00274             }
00275 
00276             ptr += width;
00277           } 
00278 
00279           for (int col_index = 0; col_index < width; ++col_index)
00280           {
00281             pcl::PointXYZRGBA & point = (*cloud) (col_index, row_index);
00282 
00283             short z = *ptr;
00284 
00285             point.z = static_cast<float> (z) / 1000.0f;
00286 
00287             ++ptr;
00288           }
00289 
00290           for (int col_index = 0; col_index < width; ++col_index)
00291           {
00292             pcl::PointXYZRGBA & point = (*cloud) (col_index, row_index);
00293 
00294             short x = *ptr;
00295             ++ptr;
00296 
00297             point.x = -static_cast<float> (x) / 1000.0f;
00298           }
00299 
00300           for (int col_index = 0; col_index < width; ++col_index)
00301           {
00302             pcl::PointXYZRGBA & point = (*cloud) (col_index, row_index);
00303 
00304             short y = *ptr;
00305             ++ptr;
00306 
00307             point.y = static_cast<float> (y) / 1000.0f;
00308           }
00309         }
00310 
00311         // publish cloud
00312         if (num_slots<sig_cb_fotonic_point_cloud_rgba> () > 0)
00313         {
00314           point_cloud_rgba_signal_->operator() (cloud);
00315         }
00316         if (num_slots<sig_cb_fotonic_point_cloud_rgb> () > 0)
00317         {
00318           pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB> ());
00319           cloud->resize (width*height);
00320           cloud->width = width;
00321           cloud->height = height;
00322           cloud->is_dense = false;
00323 
00324           pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZRGB> (*cloud, *tmp_cloud);
00325 
00326           point_cloud_rgb_signal_->operator() (tmp_cloud);
00327         }
00328         if (num_slots<sig_cb_fotonic_point_cloud> () > 0)
00329         {
00330           pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tmp (new pcl::PointCloud<pcl::PointXYZ> ());
00331           cloud->resize (width*height);
00332           cloud->width = width;
00333           cloud->height = height;
00334           cloud->is_dense = false;
00335 
00336           pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZ> (*cloud, *cloud_tmp);
00337 
00338           point_cloud_signal_->operator() (cloud_tmp);
00339         }
00340 
00341       }
00342     }
00343     else
00344       boost::this_thread::sleep (boost::posix_time::milliseconds(1));
00345 
00346     continue_grabbing = running_;
00347   }
00348 }
00349 
00350 
00351 #endif


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:24:11