openni_device.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) 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 #include <pcl/pcl_config.h>
00039 #ifdef HAVE_OPENNI
00040 
00041 #ifdef __GNUC__
00042 #pragma GCC diagnostic ignored "-Wold-style-cast"
00043 #endif
00044 
00045 #include <pcl/io/openni_camera/openni_driver.h>
00046 #include <pcl/io/openni_camera/openni_device.h>
00047 #include <pcl/io/openni_camera/openni_depth_image.h>
00048 #include <pcl/io/openni_camera/openni_ir_image.h>
00049 #include <iostream>
00050 #include <limits>
00051 #include <sstream>
00052 #include <map>
00053 #include <vector>
00054 #include "XnVersion.h"
00055 
00057 openni_wrapper::OpenNIDevice::OpenNIDevice (
00058     xn::Context& context, 
00059     const xn::NodeInfo& device_node, 
00060 #ifdef __APPLE__
00061     const xn::NodeInfo&, 
00062     const xn::NodeInfo&, 
00063     const xn::NodeInfo&
00064 #else
00065     const xn::NodeInfo& image_node, 
00066     const xn::NodeInfo& depth_node, 
00067     const xn::NodeInfo& ir_node
00068 #endif
00069   )
00070   : image_callback_ (),
00071     depth_callback_ (),
00072     ir_callback_ (),
00073     available_image_modes_ (),
00074     available_depth_modes_ (),
00075     context_ (context),
00076     device_node_info_ (device_node),
00077     depth_generator_ (),
00078     image_generator_ (),
00079     ir_generator_ (),
00080     depth_callback_handle_ (),
00081     image_callback_handle_ (),
00082     ir_callback_handle_ (),
00083     depth_focal_length_SXGA_ (),
00084     baseline_ (),
00085     // This magic value is taken from a calibration routine.
00086     rgb_focal_length_SXGA_ (1050),
00087     shadow_value_ (),
00088     no_sample_value_ (),
00089     image_callback_handle_counter_ (),
00090     depth_callback_handle_counter_ (),
00091     ir_callback_handle_counter_ (),
00092     quit_ (),
00093     image_mutex_ (), depth_mutex_ (), ir_mutex_ (),
00094     image_condition_ (), depth_condition_ (), ir_condition_ (), 
00095     image_thread_ (), depth_thread_ (), ir_thread_ ()
00096 {
00097 // workaround for MAC from Alex Ichim
00098 #ifdef __APPLE__
00099   XnStatus rc;
00100 
00101   std::string config ("/etc/openni/SamplesConfig.xml");
00102   xn::EnumerationErrors errors;
00103   rc = context_.InitFromXmlFile (config.c_str (), &errors);
00104   if (rc == XN_STATUS_NO_NODE_PRESENT)
00105   {
00106     XnChar str_error[1024];
00107     errors.ToString (str_error, 1024);
00108     THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] %s\n", str_error);
00109   }
00110   else if (rc != XN_STATUS_OK)
00111     THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot open %s! (OpenNI: %s)\n", config.c_str (), xnGetStatusString (rc));
00112 
00113   XnStatus status = context_.FindExistingNode (XN_NODE_TYPE_DEPTH, depth_generator_);
00114   //if (status != XN_STATUS_OK)
00115   //  THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot find any depth nodes!\n");
00116   status = context_.FindExistingNode (XN_NODE_TYPE_IMAGE, image_generator_);
00117   //if (status != XN_STATUS_OK)
00118   //  THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot find any image nodes!\n");
00119   status = context_.FindExistingNode (XN_NODE_TYPE_IR, ir_generator_);
00120   //if (status != XN_STATUS_OK)
00121   //  THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot find any IR nodes!\n");
00122 
00123 #else
00124 
00125 #if (XN_MINOR_VERSION >= 3)
00126 // create the production nodes
00127   XnStatus status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(depth_node), depth_generator_);
00128   if (status != XN_STATUS_OK)
00129     THROW_OPENNI_EXCEPTION ("creating depth generator failed. Reason: %s", xnGetStatusString (status));
00130 
00131   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(image_node), image_generator_);
00132   if (status != XN_STATUS_OK)
00133     THROW_OPENNI_EXCEPTION ("creating image generator failed. Reason: %s", xnGetStatusString (status));
00134 
00135   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(ir_node), ir_generator_);
00136   if (status != XN_STATUS_OK)
00137     THROW_OPENNI_EXCEPTION ("creating IR generator failed. Reason: %s", xnGetStatusString (status));
00138 #else
00139   XnStatus status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(depth_node));
00140   if (status != XN_STATUS_OK)
00141     THROW_OPENNI_EXCEPTION ("creating depth generator failed. Reason: %s", xnGetStatusString (status));
00142 
00143   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(image_node));
00144   if (status != XN_STATUS_OK)
00145     THROW_OPENNI_EXCEPTION ("creating image generator failed. Reason: %s", xnGetStatusString (status));
00146 
00147   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(ir_node));
00148   if (status != XN_STATUS_OK)
00149     THROW_OPENNI_EXCEPTION ("creating IR generator failed. Reason: %s", xnGetStatusString (status));
00150 
00151   // get production node instances
00152   status = depth_node.GetInstance (depth_generator_);
00153   if (status != XN_STATUS_OK)
00154     THROW_OPENNI_EXCEPTION ("creating depth generator instance failed. Reason: %s", xnGetStatusString (status));
00155 
00156   status = image_node.GetInstance (image_generator_);
00157   if (status != XN_STATUS_OK)
00158     THROW_OPENNI_EXCEPTION ("creating image generator instance failed. Reason: %s", xnGetStatusString (status));
00159 
00160   status = ir_node.GetInstance (ir_generator_);
00161   if (status != XN_STATUS_OK)
00162     THROW_OPENNI_EXCEPTION ("creating IR generator instance failed. Reason: %s", xnGetStatusString (status));
00163 #endif // (XN_MINOR_VERSION >= 3)
00164   ir_generator_.RegisterToNewDataAvailable (static_cast<xn::StateChangedHandler> (NewIRDataAvailable), this, ir_callback_handle_);
00165 #endif // __APPLE__
00166 
00167   depth_generator_.RegisterToNewDataAvailable (static_cast<xn::StateChangedHandler> (NewDepthDataAvailable), this, depth_callback_handle_);
00168   image_generator_.RegisterToNewDataAvailable (static_cast<xn::StateChangedHandler> (NewImageDataAvailable), this, image_callback_handle_);
00169 
00170   Init ();
00171 
00172   // read sensor configuration from device
00173   InitShiftToDepthConversion();
00174 }
00175 
00177 openni_wrapper::OpenNIDevice::OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, 
00178 #ifdef __APPLE__
00179     const xn::NodeInfo&, 
00180     const xn::NodeInfo&
00181 #else
00182     const xn::NodeInfo& depth_node, 
00183     const xn::NodeInfo& ir_node
00184 #endif
00185     )
00186   : image_callback_ (),
00187     depth_callback_ (),
00188     ir_callback_ (),
00189     available_image_modes_ (),
00190     available_depth_modes_ (),
00191     context_ (context),
00192     device_node_info_ (device_node),
00193     depth_generator_ (),
00194     image_generator_ (),
00195     ir_generator_ (),
00196     depth_callback_handle_ (),
00197     image_callback_handle_ (),
00198     ir_callback_handle_ (),
00199     depth_focal_length_SXGA_ (),
00200     baseline_ (),
00201     // This magic value is taken from a calibration routine.
00202     rgb_focal_length_SXGA_ (1050),
00203     shadow_value_ (),
00204     no_sample_value_ (),
00205     image_callback_handle_counter_ (),
00206     depth_callback_handle_counter_ (),
00207     ir_callback_handle_counter_ (),
00208     quit_ (),
00209     image_mutex_ (), depth_mutex_ (), ir_mutex_ (),
00210     image_condition_ (), depth_condition_ (), ir_condition_ (), 
00211     image_thread_ (), depth_thread_ (), ir_thread_ ()
00212 {
00213 // workaround for MAC from Alex Ichim
00214 #ifdef __APPLE__
00215   XnStatus rc;
00216 
00217   std::string config ("/etc/openni/SamplesConfig.xml");
00218   xn::EnumerationErrors errors;
00219   rc = context_.InitFromXmlFile (config.c_str (), &errors);
00220   if (rc == XN_STATUS_NO_NODE_PRESENT)
00221   {
00222     XnChar str_error[1024];
00223     errors.ToString (str_error, 1024);
00224     THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] %s\n", str_error);
00225   }
00226   else if (rc != XN_STATUS_OK)
00227     THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot open %s! (OpenNI: %s)\n", config.c_str (), xnGetStatusString (rc));
00228 
00229   XnStatus status = context_.FindExistingNode (XN_NODE_TYPE_DEPTH, depth_generator_);
00230   //if (status != XN_STATUS_OK)
00231   //  THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot find any depth nodes!\n");
00232   status = context_.FindExistingNode (XN_NODE_TYPE_IR, ir_generator_);
00233   //if (status != XN_STATUS_OK)
00234   //  THROW_OPENNI_EXCEPTION ("[openni_wrapper::OpenNIDevice::OpenNIDevice] Cannot find any IR nodes!\n");
00235 
00236 #else
00237   XnStatus status;
00238 #if (XN_MINOR_VERSION >=3)
00239   // create the production nodes
00240   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(depth_node), depth_generator_);
00241   if (status != XN_STATUS_OK)
00242     THROW_OPENNI_EXCEPTION ("creating depth generator failed. Reason: %s", xnGetStatusString (status));
00243 
00244   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(ir_node), ir_generator_);
00245   if (status != XN_STATUS_OK)
00246     THROW_OPENNI_EXCEPTION ("creating IR generator failed. Reason: %s", xnGetStatusString (status));
00247 #else
00248   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(depth_node));
00249   if (status != XN_STATUS_OK)
00250     THROW_OPENNI_EXCEPTION ("creating depth generator failed. Reason: %s", xnGetStatusString (status));
00251 
00252   status = context_.CreateProductionTree (const_cast<xn::NodeInfo&>(ir_node));
00253   if (status != XN_STATUS_OK)
00254     THROW_OPENNI_EXCEPTION ("creating IR generator failed. Reason: %s", xnGetStatusString (status));
00255   // get production node instances
00256   status = depth_node.GetInstance (depth_generator_);
00257   if (status != XN_STATUS_OK)
00258     THROW_OPENNI_EXCEPTION ("creating depth generator instance failed. Reason: %s", xnGetStatusString (status));
00259 
00260   status = ir_node.GetInstance (ir_generator_);
00261   if (status != XN_STATUS_OK)
00262     THROW_OPENNI_EXCEPTION ("creating IR generator instance failed. Reason: %s", xnGetStatusString (status));
00263 #endif // (XN_MINOR_VERSION >= 3)
00264   ir_generator_.RegisterToNewDataAvailable (static_cast<xn::StateChangedHandler> (NewIRDataAvailable), this, ir_callback_handle_);
00265 #endif // __APPLE__
00266 
00267   depth_generator_.RegisterToNewDataAvailable (static_cast <xn::StateChangedHandler> (NewDepthDataAvailable), this, depth_callback_handle_);
00268   // set up rest
00269   Init ();
00270 
00271   // read sensor configuration from device
00272   InitShiftToDepthConversion();
00273 }
00274 
00276 // For ONI Player devices
00277 openni_wrapper::OpenNIDevice::OpenNIDevice (xn::Context& context)
00278   : image_callback_ (),
00279     depth_callback_ (),
00280     ir_callback_ (),
00281     available_image_modes_ (),
00282     available_depth_modes_ (),
00283     context_ (context),
00284     device_node_info_ (0),
00285     depth_generator_ (),
00286     image_generator_ (),
00287     ir_generator_ (),
00288     depth_callback_handle_ (),
00289     image_callback_handle_ (),
00290     ir_callback_handle_ (),
00291     depth_focal_length_SXGA_ (),
00292     baseline_ (),
00293     // This magic value is taken from a calibration routine.
00294     rgb_focal_length_SXGA_ (1050),
00295     shadow_value_ (),
00296     no_sample_value_ (),
00297     image_callback_handle_counter_ (),
00298     depth_callback_handle_counter_ (),
00299     ir_callback_handle_counter_ (),
00300     quit_ (),
00301     image_mutex_ (), depth_mutex_ (), ir_mutex_ (),
00302     image_condition_ (), depth_condition_ (), ir_condition_ (), 
00303     image_thread_ (), depth_thread_ (), ir_thread_ ()
00304 {
00305 }
00306 
00308 openni_wrapper::OpenNIDevice::~OpenNIDevice () throw ()
00309 {
00310   // stop streams
00311   if (image_generator_.IsValid() && image_generator_.IsGenerating ())
00312     image_generator_.StopGenerating ();
00313 
00314   if (depth_generator_.IsValid () && depth_generator_.IsGenerating ())
00315     depth_generator_.StopGenerating ();
00316 
00317   if (ir_generator_.IsValid () && ir_generator_.IsGenerating ())
00318     ir_generator_.StopGenerating ();
00319 
00320   // lock before changing running flag
00321   image_mutex_.lock ();
00322   depth_mutex_.lock ();
00323   ir_mutex_.lock ();
00324   quit_ = true;
00325 
00326   depth_condition_.notify_all ();
00327   image_condition_.notify_all ();
00328   ir_condition_.notify_all ();
00329   ir_mutex_.unlock ();
00330   depth_mutex_.unlock ();
00331   image_mutex_.unlock ();
00332 
00333   xn::Device deviceNode;
00334   device_node_info_.GetInstance(deviceNode);
00335   if (deviceNode.IsValid())
00336     deviceNode.Release ();
00337   
00338   if (hasImageStream ())
00339   {
00340     image_thread_.join ();
00341     image_generator_.Release ();
00342   }
00343   
00344   if (hasDepthStream ())
00345   {
00346     depth_thread_.join ();
00347     depth_generator_.Release ();
00348   }
00349   
00350   if (hasIRStream ())
00351   {
00352     ir_thread_.join ();
00353     ir_generator_.Release ();
00354   }
00355 }
00356 
00358 void 
00359 openni_wrapper::OpenNIDevice::Init ()
00360 {
00361   quit_ = false;
00362   XnDouble pixel_size;
00363 
00364   // set Depth resolution here only once... since no other mode for kinect is available -> deactivating setDepthResolution method!
00365   if (hasDepthStream ())
00366   {
00367     boost::unique_lock<boost::mutex> depth_lock (depth_mutex_);
00368     XnStatus status = depth_generator_.GetRealProperty ("ZPPS", pixel_size);
00369     if (status != XN_STATUS_OK)
00370       THROW_OPENNI_EXCEPTION ("reading the pixel size of IR camera failed. Reason: %s", xnGetStatusString (status));
00371 
00372     XnUInt64 depth_focal_length_SXGA;
00373     status = depth_generator_.GetIntProperty ("ZPD", depth_focal_length_SXGA);
00374     if (status != XN_STATUS_OK)
00375       THROW_OPENNI_EXCEPTION ("reading the focal length of IR camera failed. Reason: %s", xnGetStatusString (status));
00376 
00377     XnDouble baseline;
00378     status = depth_generator_.GetRealProperty ("LDDIS", baseline);
00379     if (status != XN_STATUS_OK)
00380       THROW_OPENNI_EXCEPTION ("reading the baseline failed. Reason: %s", xnGetStatusString (status));
00381 
00382     status = depth_generator_.GetIntProperty ("ShadowValue", shadow_value_);
00383     if (status != XN_STATUS_OK)
00384       THROW_OPENNI_EXCEPTION ("reading the value for pixels in shadow regions failed. Reason: %s", xnGetStatusString (status));
00385 
00386     status = depth_generator_.GetIntProperty ("NoSampleValue", no_sample_value_);
00387     if (status != XN_STATUS_OK)
00388       THROW_OPENNI_EXCEPTION ("reading the value for pixels with no depth estimation failed. Reason: %s", xnGetStatusString (status));
00389 
00390     // baseline from cm -> meters
00391     baseline_ = static_cast<float> (baseline * 0.01);
00392 
00393     //focal length from mm -> pixels (valid for 1280x1024)
00394     depth_focal_length_SXGA_ = static_cast<float> (static_cast<XnDouble> (depth_focal_length_SXGA) / pixel_size);
00395 
00396     depth_thread_ = boost::thread (&OpenNIDevice::DepthDataThreadFunction, this);
00397   }
00398 
00399   if (hasImageStream ())
00400   {
00401     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00402     image_thread_ = boost::thread (&OpenNIDevice::ImageDataThreadFunction, this);
00403   }
00404 
00405   if (hasIRStream ())
00406   {
00407     boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
00408     ir_thread_ = boost::thread (&OpenNIDevice::IRDataThreadFunction, this);
00409   }
00410 }
00411 
00412 void openni_wrapper::OpenNIDevice::InitShiftToDepthConversion ()
00413 {
00414   // Read device configuration from OpenNI sensor node
00415   ReadDeviceParametersFromSensorNode();
00416 
00417   if (shift_conversion_parameters_.init_)
00418   {
00419     // Calculate shift conversion table
00420 
00421     pcl::int32_t nIndex = 0;
00422     pcl::int32_t nShiftValue = 0;
00423     double dFixedRefX = 0;
00424     double dMetric = 0;
00425     double dDepth = 0;
00426     double dPlanePixelSize = shift_conversion_parameters_.zero_plane_pixel_size_;
00427     double dPlaneDsr = shift_conversion_parameters_.zero_plane_distance_;
00428     double dPlaneDcl = shift_conversion_parameters_.emitter_dcmos_distace_;
00429     pcl::int32_t nConstShift = shift_conversion_parameters_.param_coeff_ *
00430         shift_conversion_parameters_.const_shift_;
00431 
00432     dPlanePixelSize *= shift_conversion_parameters_.pixel_size_factor_;
00433     nConstShift /= shift_conversion_parameters_.pixel_size_factor_;
00434 
00435     shift_to_depth_table_.resize(shift_conversion_parameters_.device_max_shift_+1);
00436 
00437     for (nIndex = 1; nIndex < shift_conversion_parameters_.device_max_shift_; nIndex++)
00438     {
00439       nShiftValue = (pcl::int32_t)nIndex;
00440 
00441       dFixedRefX = (double) (nShiftValue - nConstShift) /
00442                    (double) shift_conversion_parameters_.param_coeff_;
00443       dFixedRefX -= 0.375;
00444       dMetric = dFixedRefX * dPlanePixelSize;
00445       dDepth = shift_conversion_parameters_.shift_scale_ *
00446                ((dMetric * dPlaneDsr / (dPlaneDcl - dMetric)) + dPlaneDsr);
00447 
00448       // check cut-offs
00449       if ((dDepth > shift_conversion_parameters_.min_depth_) &&
00450           (dDepth < shift_conversion_parameters_.max_depth_))
00451       {
00452         shift_to_depth_table_[nIndex] = (pcl::uint16_t)(dDepth);
00453       }
00454     }
00455 
00456   }
00457   else
00458       THROW_OPENNI_EXCEPTION ("Shift-to-depth lookup calculation failed. Reason: Device configuration not initialized.");
00459 }
00460 
00461 void
00462 openni_wrapper::OpenNIDevice::ReadDeviceParametersFromSensorNode ()
00463 {
00464   if (hasDepthStream ())
00465   {
00466 
00467     XnUInt64 nTemp;
00468     XnDouble dTemp;
00469 
00470     XnStatus status = depth_generator_.GetIntProperty ("ZPD", nTemp);
00471     if (status != XN_STATUS_OK)
00472       THROW_OPENNI_EXCEPTION ("reading the zero plane distance failed. Reason: %s", xnGetStatusString (status));
00473 
00474     shift_conversion_parameters_.zero_plane_distance_ =  (XnUInt16)nTemp;
00475 
00476     status = depth_generator_.GetRealProperty ("ZPPS", dTemp);
00477     if (status != XN_STATUS_OK)
00478       THROW_OPENNI_EXCEPTION ("reading the zero plane pixel size failed. Reason: %s", xnGetStatusString (status));
00479 
00480     shift_conversion_parameters_.zero_plane_pixel_size_ =  (XnFloat)dTemp;
00481 
00482     status = depth_generator_.GetRealProperty ("LDDIS", dTemp);
00483     if (status != XN_STATUS_OK)
00484       THROW_OPENNI_EXCEPTION ("reading the dcmos distance failed. Reason: %s", xnGetStatusString (status));
00485 
00486     shift_conversion_parameters_.emitter_dcmos_distace_ =  (XnFloat)dTemp;
00487 
00488     status = depth_generator_.GetIntProperty ("MaxShift", nTemp);
00489     if (status != XN_STATUS_OK)
00490       THROW_OPENNI_EXCEPTION ("reading the max shift parameter failed. Reason: %s", xnGetStatusString (status));
00491 
00492     shift_conversion_parameters_.max_shift_ =  (XnUInt32)nTemp;
00493 
00494     status = depth_generator_.GetIntProperty ("DeviceMaxDepth", nTemp);
00495     if (status != XN_STATUS_OK)
00496       THROW_OPENNI_EXCEPTION ("reading the device max depth parameter failed. Reason: %s", xnGetStatusString (status));
00497 
00498     shift_conversion_parameters_.device_max_shift_ =  (XnUInt32)nTemp;
00499 
00500     status = depth_generator_.GetIntProperty ("ConstShift", nTemp);
00501     if (status != XN_STATUS_OK)
00502       THROW_OPENNI_EXCEPTION ("reading the const shift parameter failed. Reason: %s", xnGetStatusString (status));
00503 
00504     shift_conversion_parameters_.const_shift_ =  (XnUInt32)nTemp;
00505 
00506     status = depth_generator_.GetIntProperty ("PixelSizeFactor", nTemp);
00507     if (status != XN_STATUS_OK)
00508       THROW_OPENNI_EXCEPTION ("reading the pixel size factor failed. Reason: %s", xnGetStatusString (status));
00509 
00510     shift_conversion_parameters_.pixel_size_factor_ =  (XnUInt32)nTemp;
00511 
00512     status = depth_generator_.GetIntProperty ("ParamCoeff", nTemp);
00513     if (status != XN_STATUS_OK)
00514       THROW_OPENNI_EXCEPTION ("reading the param coeff parameter failed. Reason: %s", xnGetStatusString (status));
00515 
00516     shift_conversion_parameters_.param_coeff_ =  (XnUInt32)nTemp;
00517 
00518     status = depth_generator_.GetIntProperty ("ShiftScale", nTemp);
00519     if (status != XN_STATUS_OK)
00520       THROW_OPENNI_EXCEPTION ("reading the shift scale parameter failed. Reason: %s", xnGetStatusString (status));
00521 
00522     shift_conversion_parameters_.shift_scale_ =  (XnUInt32)nTemp;
00523 
00524     status = depth_generator_.GetIntProperty ("MinDepthValue", nTemp);
00525     if (status != XN_STATUS_OK)
00526       THROW_OPENNI_EXCEPTION ("reading the min depth value parameter failed. Reason: %s", xnGetStatusString (status));
00527 
00528     shift_conversion_parameters_.min_depth_ =  (XnUInt32)nTemp;
00529 
00530     status = depth_generator_.GetIntProperty ("MaxDepthValue", nTemp);
00531     if (status != XN_STATUS_OK)
00532       THROW_OPENNI_EXCEPTION ("reading the max depth value parameter failed. Reason: %s", xnGetStatusString (status));
00533 
00534     shift_conversion_parameters_.max_depth_ =  (XnUInt32)nTemp;
00535 
00536     shift_conversion_parameters_.init_ = true;
00537   }
00538 }
00539 
00541 void 
00542 openni_wrapper::OpenNIDevice::startImageStream ()
00543 {
00544   if (hasImageStream ())
00545   {
00546     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00547     if (!image_generator_.IsGenerating ())
00548     {
00549       XnStatus status = image_generator_.StartGenerating ();
00550       if (status != XN_STATUS_OK)
00551         THROW_OPENNI_EXCEPTION ("starting image stream failed. Reason: %s", xnGetStatusString (status));
00552     }
00553   }
00554   else
00555     THROW_OPENNI_EXCEPTION ("Device does not provide an image stream");
00556 }
00557 
00559 void 
00560 openni_wrapper::OpenNIDevice::stopImageStream ()
00561 {
00562   if (hasImageStream ())
00563   {
00564     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00565     if (image_generator_.IsGenerating ())
00566     {
00567       XnStatus status = image_generator_.StopGenerating ();
00568       if (status != XN_STATUS_OK)
00569         THROW_OPENNI_EXCEPTION ("stopping image stream failed. Reason: %s", xnGetStatusString (status));
00570     }
00571   }
00572   else
00573     THROW_OPENNI_EXCEPTION ("Device does not provide an image stream");
00574 }
00575 
00577 void 
00578 openni_wrapper::OpenNIDevice::startDepthStream ()
00579 {
00580   if (hasDepthStream ())
00581   {
00582     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00583     if (!depth_generator_.IsGenerating ())
00584     {
00585       XnStatus status = depth_generator_.StartGenerating ();
00586 
00587       if (status != XN_STATUS_OK)
00588         THROW_OPENNI_EXCEPTION ("starting depth stream failed. Reason: %s", xnGetStatusString (status));
00589     }
00590   }
00591   else
00592     THROW_OPENNI_EXCEPTION ("Device does not provide a depth stream");
00593 }
00594 
00596 void 
00597 openni_wrapper::OpenNIDevice::stopDepthStream ()
00598 {
00599   if (hasDepthStream ())
00600   {
00601     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00602     if (depth_generator_.IsGenerating ())
00603     {
00604       XnStatus status = depth_generator_.StopGenerating ();
00605 
00606       if (status != XN_STATUS_OK)
00607         THROW_OPENNI_EXCEPTION ("stopping depth stream failed. Reason: %s", xnGetStatusString (status));
00608     }
00609   }
00610   else
00611     THROW_OPENNI_EXCEPTION ("Device does not provide a depth stream");
00612 }
00613 
00615 void 
00616 openni_wrapper::OpenNIDevice::startIRStream ()
00617 {
00618   if (hasIRStream ())
00619   {
00620     boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
00621     if (!ir_generator_.IsGenerating ())
00622     {
00623       XnStatus status = ir_generator_.StartGenerating ();
00624 
00625       if (status != XN_STATUS_OK)
00626         THROW_OPENNI_EXCEPTION ("starting IR stream failed. Reason: %s", xnGetStatusString (status));
00627     }
00628   }
00629 #ifndef __APPLE__
00630   else
00631     THROW_OPENNI_EXCEPTION ("Device does not provide an IR stream");
00632 #endif
00633 }
00634 
00636 void 
00637 openni_wrapper::OpenNIDevice::stopIRStream ()
00638 {
00639   if (hasIRStream ())
00640   {
00641     boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
00642     if (ir_generator_.IsGenerating ())
00643     {
00644       XnStatus status = ir_generator_.StopGenerating ();
00645 
00646       if (status != XN_STATUS_OK)
00647         THROW_OPENNI_EXCEPTION ("stopping IR stream failed. Reason: %s", xnGetStatusString (status));
00648     }
00649   }
00650   else
00651     THROW_OPENNI_EXCEPTION ("Device does not provide an IR stream");
00652 }
00653 
00655 bool 
00656 openni_wrapper::OpenNIDevice::isImageStreamRunning () const throw ()
00657 {
00658   boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00659   return (image_generator_.IsValid () && image_generator_.IsGenerating ());
00660 }
00661 
00663 bool 
00664 openni_wrapper::OpenNIDevice::isDepthStreamRunning () const throw ()
00665 {
00666   boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00667   return (depth_generator_.IsValid () && depth_generator_.IsGenerating ());
00668 }
00669 
00671 bool 
00672 openni_wrapper::OpenNIDevice::isIRStreamRunning () const throw ()
00673 {
00674   boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
00675   return (ir_generator_.IsValid () && ir_generator_.IsGenerating ());
00676 }
00677 
00679 bool 
00680 openni_wrapper::OpenNIDevice::hasImageStream () const throw ()
00681 {
00682   boost::lock_guard<boost::mutex> lock (image_mutex_);
00683   return (image_generator_.IsValid () != 0);
00684   //return (available_image_modes_.size() != 0);
00685 }
00686 
00688 bool 
00689 openni_wrapper::OpenNIDevice::hasDepthStream () const throw ()
00690 {
00691   boost::lock_guard<boost::mutex> lock (depth_mutex_);
00692   return (depth_generator_.IsValid () != 0);
00693   //return (available_depth_modes_.size() != 0);
00694 }
00695 
00697 bool 
00698 openni_wrapper::OpenNIDevice::hasIRStream () const throw ()
00699 {
00700   boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
00701   return (ir_generator_.IsValid () != 0);
00702 }
00703 
00705 void 
00706 openni_wrapper::OpenNIDevice::setDepthRegistration (bool on_off)
00707 {
00708   if (hasDepthStream () && hasImageStream())
00709   {
00710     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00711     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00712     if (on_off && !depth_generator_.GetAlternativeViewPointCap ().IsViewPointAs (image_generator_))
00713     {
00714       if (depth_generator_.GetAlternativeViewPointCap ().IsViewPointSupported (image_generator_))
00715       {
00716         XnStatus status = depth_generator_.GetAlternativeViewPointCap ().SetViewPoint (image_generator_);
00717         if (status != XN_STATUS_OK)
00718           THROW_OPENNI_EXCEPTION ("turning registration on failed. Reason: %s", xnGetStatusString (status));
00719       }
00720       else
00721         THROW_OPENNI_EXCEPTION ("turning registration on failed. Reason: unsopported viewpoint");
00722     }
00723     else if (!on_off)
00724     {
00725       XnStatus status = depth_generator_.GetAlternativeViewPointCap ().ResetViewPoint ();
00726 
00727       if (status != XN_STATUS_OK)
00728         THROW_OPENNI_EXCEPTION ("turning registration off failed. Reason: %s", xnGetStatusString (status));
00729     }
00730   }
00731   else
00732     THROW_OPENNI_EXCEPTION ("Device does not provide image + depth stream");
00733 }
00734 
00736 bool 
00737 openni_wrapper::OpenNIDevice::isDepthRegistered () const throw ()
00738 {
00739   if (hasDepthStream () && hasImageStream() )
00740   {
00741     xn::DepthGenerator& depth_generator = const_cast<xn::DepthGenerator&>(depth_generator_);
00742     xn::ImageGenerator& image_generator = const_cast<xn::ImageGenerator&>(image_generator_);
00743 
00744     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00745     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00746     return (depth_generator.GetAlternativeViewPointCap ().IsViewPointAs (image_generator) != 0);
00747   }
00748   return (false);
00749 }
00750 
00752 bool 
00753 openni_wrapper::OpenNIDevice::isDepthRegistrationSupported () const throw ()
00754 {
00755   boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00756   boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00757   xn::ImageGenerator& image_generator = const_cast<xn::ImageGenerator&> (image_generator_);
00758   return (depth_generator_.IsValid() && image_generator_.IsValid() && depth_generator_.GetAlternativeViewPointCap().IsViewPointSupported(image_generator));
00759 }
00760 
00762 bool 
00763 openni_wrapper::OpenNIDevice::isSynchronizationSupported () const throw ()
00764 {
00765   boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00766   boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00767   return (depth_generator_.IsValid() && image_generator_.IsValid() && depth_generator_.IsCapabilitySupported (XN_CAPABILITY_FRAME_SYNC));
00768 }
00769 
00771 void 
00772 openni_wrapper::OpenNIDevice::setSynchronization (bool on_off)
00773 {
00774   if (hasDepthStream () && hasImageStream())
00775   {
00776     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00777     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00778     XnStatus status;
00779 
00780     if (on_off && !depth_generator_.GetFrameSyncCap ().IsFrameSyncedWith (image_generator_))
00781     {
00782       status = depth_generator_.GetFrameSyncCap ().FrameSyncWith (image_generator_);
00783       if (status != XN_STATUS_OK)
00784         THROW_OPENNI_EXCEPTION ("could not turn on frame synchronization. Reason: %s", xnGetStatusString (status));
00785     }
00786     else if (!on_off && depth_generator_.GetFrameSyncCap ().IsFrameSyncedWith (image_generator_))
00787     {
00788       status = depth_generator_.GetFrameSyncCap ().StopFrameSyncWith (image_generator_);
00789       if (status != XN_STATUS_OK)
00790         THROW_OPENNI_EXCEPTION ("could not turn off frame synchronization. Reason: %s", xnGetStatusString (status));
00791     }
00792   }
00793   else
00794     THROW_OPENNI_EXCEPTION ("Device does not provide image + depth stream");
00795 }
00796 
00798 bool 
00799 openni_wrapper::OpenNIDevice::isSynchronized () const throw ()
00800 {
00801   if (hasDepthStream () && hasImageStream())
00802   {
00803     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
00804     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00805     xn::DepthGenerator& depth_generator = const_cast<xn::DepthGenerator&>(depth_generator_);
00806     xn::ImageGenerator& image_generator = const_cast<xn::ImageGenerator&>(image_generator_);
00807     return (depth_generator.GetFrameSyncCap ().CanFrameSyncWith (image_generator) && depth_generator.GetFrameSyncCap ().IsFrameSyncedWith (image_generator));
00808   }
00809   else
00810     return (false);
00811 }
00812 
00814 bool 
00815 openni_wrapper::OpenNIDevice::isDepthCroppingSupported () const throw ()
00816 {
00817   boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00818   return (image_generator_.IsValid() && depth_generator_.IsCapabilitySupported (XN_CAPABILITY_CROPPING) );
00819 }
00820 
00822 bool 
00823 openni_wrapper::OpenNIDevice::isDepthCropped () const
00824 {
00825   if (hasDepthStream ())
00826   {
00827     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00828     XnCropping cropping;
00829     xn::DepthGenerator& depth_generator = const_cast<xn::DepthGenerator&>(depth_generator_);
00830     XnStatus status = depth_generator.GetCroppingCap ().GetCropping (cropping);
00831     if (status != XN_STATUS_OK)
00832       THROW_OPENNI_EXCEPTION ("could not read cropping information for depth stream. Reason: %s", xnGetStatusString (status));
00833 
00834     return (cropping.bEnabled != 0);
00835   }
00836   return (false);
00837 }
00838 
00840 void 
00841 openni_wrapper::OpenNIDevice::setDepthCropping (unsigned x, unsigned y, unsigned width, unsigned height)
00842 {
00843   if (hasDepthStream ())
00844   {
00845     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
00846     XnCropping cropping;
00847     cropping.nXOffset = static_cast<XnUInt16> (x);
00848     cropping.nYOffset = static_cast<XnUInt16> (y);
00849     cropping.nXSize   = static_cast<XnUInt16> (width);
00850     cropping.nYSize   = static_cast<XnUInt16> (height);
00851     
00852     cropping.bEnabled = (width != 0 && height != 0);
00853     XnStatus status = depth_generator_.GetCroppingCap ().SetCropping (cropping);
00854     if (status != XN_STATUS_OK)
00855       THROW_OPENNI_EXCEPTION ("could not set cropping information for depth stream. Reason: %s", xnGetStatusString (status));
00856   }
00857   else
00858     THROW_OPENNI_EXCEPTION ("Device does not provide depth stream");
00859 }
00860 
00862 void 
00863 openni_wrapper::OpenNIDevice::ImageDataThreadFunction ()
00864 {
00865   while (true)
00866   {
00867     // lock before checking running flag
00868     boost::unique_lock<boost::mutex> image_lock (image_mutex_);
00869     if (quit_)
00870       return;
00871     image_condition_.wait (image_lock);
00872     if (quit_)
00873       return;
00874 
00875     image_generator_.WaitAndUpdateData ();
00876     xn::ImageMetaData image_md;
00877     image_generator_.GetMetaData (image_md);
00878     boost::shared_ptr<xn::ImageMetaData> image_data (new xn::ImageMetaData);
00879     image_data->CopyFrom (image_md);
00880     image_lock.unlock ();
00881     
00882     boost::shared_ptr<Image> image = getCurrentImage (image_data);
00883     for (std::map< OpenNIDevice::CallbackHandle, ActualImageCallbackFunction >::iterator callbackIt = image_callback_.begin (); callbackIt != image_callback_.end (); ++callbackIt)
00884     {
00885       callbackIt->second.operator()(image);
00886     }
00887   }
00888 }
00889 
00891 void 
00892 openni_wrapper::OpenNIDevice::DepthDataThreadFunction ()
00893 {
00894   while (true)
00895   {
00896     // lock before checking running flag
00897     boost::unique_lock<boost::mutex> depth_lock (depth_mutex_);
00898     if (quit_)
00899       return;
00900     depth_condition_.wait (depth_lock);
00901     if (quit_)
00902       return;
00903 
00904     depth_generator_.WaitAndUpdateData ();
00905     xn::DepthMetaData depth_md;
00906     depth_generator_.GetMetaData (depth_md);    
00907     boost::shared_ptr<xn::DepthMetaData> depth_data (new xn::DepthMetaData);
00908     depth_data->CopyFrom (depth_md);
00909     depth_lock.unlock ();
00910 
00911     boost::shared_ptr<DepthImage> depth_image ( new DepthImage (depth_data, baseline_, getDepthFocalLength (), shadow_value_, no_sample_value_) );
00912 
00913     for (std::map< OpenNIDevice::CallbackHandle, ActualDepthImageCallbackFunction >::iterator callbackIt = depth_callback_.begin ();
00914          callbackIt != depth_callback_.end (); ++callbackIt)
00915     {
00916       callbackIt->second.operator()(depth_image);
00917     }
00918   }
00919 }
00920 
00922 void 
00923 openni_wrapper::OpenNIDevice::IRDataThreadFunction ()
00924 {
00925   while (true)
00926   {
00927     // lock before checking running flag
00928     boost::unique_lock<boost::mutex> ir_lock (ir_mutex_);
00929     if (quit_)
00930       return;
00931     ir_condition_.wait (ir_lock);
00932     if (quit_)
00933       return;
00934 
00935     ir_generator_.WaitAndUpdateData ();
00936     xn::IRMetaData ir_md;
00937     ir_generator_.GetMetaData (ir_md);
00938     boost::shared_ptr<xn::IRMetaData> ir_data (new xn::IRMetaData);
00939     ir_data->CopyFrom (ir_md);
00940     ir_lock.unlock ();
00941 
00942     boost::shared_ptr<IRImage> ir_image ( new IRImage (ir_data) );
00943 
00944     for (std::map< OpenNIDevice::CallbackHandle, ActualIRImageCallbackFunction >::iterator callbackIt = ir_callback_.begin ();
00945          callbackIt != ir_callback_.end (); ++callbackIt)
00946     {
00947       callbackIt->second.operator()(ir_image);
00948     }
00949   }
00950 }
00951 
00953 void __stdcall 
00954 openni_wrapper::OpenNIDevice::NewDepthDataAvailable (xn::ProductionNode&, void* cookie) throw ()
00955 {
00956   OpenNIDevice* device = reinterpret_cast<OpenNIDevice*>(cookie);
00957   device->depth_condition_.notify_all ();
00958 }
00959 
00961 void __stdcall 
00962 openni_wrapper::OpenNIDevice::NewImageDataAvailable (xn::ProductionNode&, void* cookie) throw ()
00963 {
00964   OpenNIDevice* device = reinterpret_cast<OpenNIDevice*>(cookie);
00965   device->image_condition_.notify_all ();
00966 }
00967 
00969 void __stdcall 
00970 openni_wrapper::OpenNIDevice::NewIRDataAvailable (xn::ProductionNode&, void* cookie) throw ()
00971 {
00972   OpenNIDevice* device = reinterpret_cast<OpenNIDevice*>(cookie);
00973   device->ir_condition_.notify_all ();
00974 }
00975 
00977 openni_wrapper::OpenNIDevice::CallbackHandle 
00978 openni_wrapper::OpenNIDevice::registerImageCallback (const ImageCallbackFunction& callback, void* custom_data) throw ()
00979 {
00980   image_callback_[image_callback_handle_counter_] = boost::bind (callback, _1, custom_data);
00981   return (image_callback_handle_counter_++);
00982 }
00983 
00985 bool 
00986 openni_wrapper::OpenNIDevice::unregisterImageCallback (const OpenNIDevice::CallbackHandle& callbackHandle) throw ()
00987 {
00988   return (image_callback_.erase (callbackHandle) != 0);
00989 }
00990 
00992 openni_wrapper::OpenNIDevice::CallbackHandle 
00993 openni_wrapper::OpenNIDevice::registerDepthCallback (const DepthImageCallbackFunction& callback, void* custom_data) throw ()
00994 {
00995   depth_callback_[depth_callback_handle_counter_] = boost::bind (callback, _1, custom_data);
00996   return (depth_callback_handle_counter_++);
00997 }
00998 
01000 bool 
01001 openni_wrapper::OpenNIDevice::unregisterDepthCallback (const OpenNIDevice::CallbackHandle& callbackHandle) throw ()
01002 {
01003   return (depth_callback_.erase (callbackHandle) != 0);
01004 }
01005 
01007 openni_wrapper::OpenNIDevice::CallbackHandle 
01008 openni_wrapper::OpenNIDevice::registerIRCallback (const IRImageCallbackFunction& callback, void* custom_data) throw ()
01009 {
01010   ir_callback_[ir_callback_handle_counter_] = boost::bind (callback, _1, custom_data);
01011   return (ir_callback_handle_counter_++);
01012 }
01013 
01015 bool 
01016 openni_wrapper::OpenNIDevice::unregisterIRCallback (const OpenNIDevice::CallbackHandle& callbackHandle) throw ()
01017 {
01018   return (ir_callback_.erase (callbackHandle) != 0);
01019 }
01020 
01022 const char* 
01023 openni_wrapper::OpenNIDevice::getSerialNumber () const throw ()
01024 {
01025   return (device_node_info_.GetInstanceName ());
01026 }
01027 
01029 const char* 
01030 openni_wrapper::OpenNIDevice::getConnectionString () const throw ()
01031 {
01032   return (device_node_info_.GetCreationInfo ());
01033 }
01034 
01036 unsigned short 
01037 openni_wrapper::OpenNIDevice::getVendorID () const throw ()
01038 {
01039   unsigned short vendor_id;
01040   unsigned short product_id;
01041 
01042 #ifndef _WIN32
01043   unsigned char bus;
01044   unsigned char address;
01045 
01046   sscanf (device_node_info_.GetCreationInfo(), "%hx/%hx@%hhu/%hhu", &vendor_id, &product_id, &bus, &address);
01047 
01048 #else
01049   OpenNIDriver::getDeviceType (device_node_info_.GetCreationInfo(), vendor_id, product_id);
01050 #endif
01051   return (vendor_id);
01052 }
01053 
01055 unsigned short 
01056 openni_wrapper::OpenNIDevice::getProductID () const throw ()
01057 {
01058   unsigned short vendor_id;
01059   unsigned short product_id;
01060 #ifndef _WIN32
01061   unsigned char bus;
01062   unsigned char address;
01063   sscanf (device_node_info_.GetCreationInfo(), "%hx/%hx@%hhu/%hhu", &vendor_id, &product_id, &bus, &address);
01064 
01065 #else
01066   OpenNIDriver::getDeviceType (device_node_info_.GetCreationInfo(), vendor_id, product_id);
01067 #endif
01068   return (product_id);
01069 }
01070 
01072 unsigned char 
01073 openni_wrapper::OpenNIDevice::getBus () const throw ()
01074 {
01075   unsigned char bus = 0;
01076 #ifndef _WIN32
01077   unsigned short vendor_id;
01078   unsigned short product_id;
01079   unsigned char address;
01080   sscanf (device_node_info_.GetCreationInfo(), "%hx/%hx@%hhu/%hhu", &vendor_id, &product_id, &bus, &address);
01081 #endif
01082   return (bus);
01083 }
01084 
01086 unsigned char 
01087 openni_wrapper::OpenNIDevice::getAddress () const throw ()
01088 {
01089   unsigned char address = 0;
01090 #ifndef _WIN32
01091   unsigned short vendor_id;
01092   unsigned short product_id;
01093   unsigned char bus;
01094   sscanf (device_node_info_.GetCreationInfo(), "%hx/%hx@%hhu/%hhu", &vendor_id, &product_id, &bus, &address);
01095 #endif
01096   return (address);
01097 }
01098 
01100 const char* 
01101 openni_wrapper::OpenNIDevice::getVendorName () const throw ()
01102 {
01103   XnProductionNodeDescription& description = const_cast<XnProductionNodeDescription&>(device_node_info_.GetDescription ());
01104   return (description.strVendor);
01105 }
01106 
01108 const char* 
01109 openni_wrapper::OpenNIDevice::getProductName () const throw ()
01110 {
01111   XnProductionNodeDescription& description = const_cast<XnProductionNodeDescription&>(device_node_info_.GetDescription ());
01112   return (description.strName);
01113 }
01114 
01116 bool 
01117 openni_wrapper::OpenNIDevice::findCompatibleImageMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode) const throw ()
01118 {
01119   if (isImageModeSupported (output_mode))
01120   {
01121     mode = output_mode;
01122     return (true);
01123   }
01124   else
01125   {
01126     bool found = false;
01127     for (std::vector<XnMapOutputMode>::const_iterator modeIt = available_image_modes_.begin (); modeIt != available_image_modes_.end (); ++modeIt)
01128     {
01129       if (modeIt->nFPS == output_mode.nFPS && isImageResizeSupported (modeIt->nXRes, modeIt->nYRes, output_mode.nXRes, output_mode.nYRes))
01130       {
01131         if (found)
01132         { // check wheter the new mode is better -> smaller than the current one.
01133           if (mode.nXRes * mode.nYRes > modeIt->nXRes * modeIt->nYRes )
01134             mode = *modeIt;
01135         }
01136         else
01137         {
01138           mode = *modeIt;
01139           found = true;
01140         }
01141       }
01142     }
01143     return (found);
01144   }
01145 }
01146 
01148 bool 
01149 openni_wrapper::OpenNIDevice::findCompatibleDepthMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode) const throw ()
01150 {
01151   if (isDepthModeSupported (output_mode))
01152   {
01153     mode = output_mode;
01154     return (true);
01155   }
01156   else
01157   {
01158     bool found = false;
01159     for (std::vector<XnMapOutputMode>::const_iterator modeIt = available_depth_modes_.begin (); modeIt != available_depth_modes_.end (); ++modeIt)
01160     {
01161       if (modeIt->nFPS == output_mode.nFPS && isImageResizeSupported (modeIt->nXRes, modeIt->nYRes, output_mode.nXRes, output_mode.nYRes))
01162       {
01163         if (found)
01164         { // check wheter the new mode is better -> smaller than the current one.
01165           if (mode.nXRes * mode.nYRes > modeIt->nXRes * modeIt->nYRes )
01166             mode = *modeIt;
01167         }
01168         else
01169         {
01170           mode = *modeIt;
01171           found = true;
01172         }
01173       }
01174     }
01175     return (found);
01176   }
01177 }
01178 
01180 bool 
01181 openni_wrapper::OpenNIDevice::isImageModeSupported (const XnMapOutputMode& output_mode) const throw ()
01182 {
01183   for (std::vector<XnMapOutputMode>::const_iterator modeIt = available_image_modes_.begin (); modeIt != available_image_modes_.end (); ++modeIt)
01184   {
01185     if (modeIt->nFPS == output_mode.nFPS && modeIt->nXRes == output_mode.nXRes && modeIt->nYRes == output_mode.nYRes)
01186       return (true);
01187   }
01188   return (false);
01189 }
01190 
01192 bool 
01193 openni_wrapper::OpenNIDevice::isDepthModeSupported (const XnMapOutputMode& output_mode) const throw ()
01194 {
01195   for (std::vector<XnMapOutputMode>::const_iterator modeIt = available_depth_modes_.begin (); modeIt != available_depth_modes_.end (); ++modeIt)
01196   {
01197     if (modeIt->nFPS == output_mode.nFPS && modeIt->nXRes == output_mode.nXRes && modeIt->nYRes == output_mode.nYRes)
01198       return (true);
01199   }
01200   return (false);
01201 }
01202 
01204 const XnMapOutputMode& 
01205 openni_wrapper::OpenNIDevice::getDefaultImageMode () const throw ()
01206 {
01207   return (available_image_modes_[0]);
01208 }
01209 
01211 const XnMapOutputMode& 
01212 openni_wrapper::OpenNIDevice::getDefaultDepthMode () const throw ()
01213 {
01214   return (available_depth_modes_[0]);
01215 }
01216 
01218 const XnMapOutputMode& 
01219 openni_wrapper::OpenNIDevice::getDefaultIRMode () const throw ()
01220 {
01222   return (available_depth_modes_[0]);
01223 }
01224 
01226 void 
01227 openni_wrapper::OpenNIDevice::setImageOutputMode (const XnMapOutputMode& output_mode)
01228 {
01229   if (hasImageStream ())
01230   {
01231     boost::lock_guard<boost::mutex> image_lock (image_mutex_);
01232     XnStatus status = image_generator_.SetMapOutputMode (output_mode);
01233     if (status != XN_STATUS_OK)
01234       THROW_OPENNI_EXCEPTION ("Could not set image stream output mode to %dx%d@%d. Reason: %s", output_mode.nXRes, output_mode.nYRes, output_mode.nFPS, xnGetStatusString (status));
01235   }
01236   else
01237     THROW_OPENNI_EXCEPTION ("Device does not provide an image stream");
01238 }
01239 
01241 void 
01242 openni_wrapper::OpenNIDevice::setDepthOutputMode (const XnMapOutputMode& output_mode)
01243 {
01244   if (hasDepthStream ())
01245   {
01246     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
01247     XnStatus status = depth_generator_.SetMapOutputMode (output_mode);
01248     if (status != XN_STATUS_OK)
01249       THROW_OPENNI_EXCEPTION ("Could not set depth stream output mode to %dx%d@%d. Reason: %s", output_mode.nXRes, output_mode.nYRes, output_mode.nFPS, xnGetStatusString (status));
01250   }
01251   else
01252     THROW_OPENNI_EXCEPTION ("Device does not provide a depth stream");
01253 }
01254 
01256 void 
01257 openni_wrapper::OpenNIDevice::setDepthOutputFormat (const DepthMode& depth_mode)
01258 {
01259   if (hasDepthStream ())
01260   {
01261     boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
01262     XnStatus status = depth_generator_.SetIntProperty ("OutputFormat", depth_mode);
01263     if (status != 0)
01264       THROW_OPENNI_EXCEPTION ("Error setting the depth output format. Reason: %s", xnGetStatusString (status));
01265   }
01266   else
01267     THROW_OPENNI_EXCEPTION ("Device does not provide a depth stream");
01268 }
01269 
01271 XnUInt64 
01272 openni_wrapper::OpenNIDevice::getDepthOutputFormat () const
01273 {
01274   if (!hasDepthStream () )
01275     THROW_OPENNI_EXCEPTION ("Device does not provide a depth stream");
01276 
01277   boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
01278   XnUInt64 mode;
01279   XnStatus status = depth_generator_.GetIntProperty ("OutputFormat", mode);
01280   if (status != XN_STATUS_OK)
01281     THROW_OPENNI_EXCEPTION ("Could not get depth output format. Reason: %s", xnGetStatusString (status));
01282   return (mode);
01283 }
01284 
01286 void 
01287 openni_wrapper::OpenNIDevice::setIROutputMode (const XnMapOutputMode& output_mode)
01288 {
01289   if (hasIRStream ())
01290   {
01291     boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
01292     XnStatus status = ir_generator_.SetMapOutputMode (output_mode);
01293     if (status != XN_STATUS_OK)
01294       THROW_OPENNI_EXCEPTION ("Could not set IR stream output mode to %dx%d@%d. Reason: %s", output_mode.nXRes, output_mode.nYRes, output_mode.nFPS, xnGetStatusString (status));
01295   }
01296 #ifndef __APPLE__
01297   else
01298     THROW_OPENNI_EXCEPTION ("Device does not provide an IR stream");
01299 #endif
01300 }
01301 
01303 XnMapOutputMode 
01304 openni_wrapper::OpenNIDevice::getImageOutputMode () const
01305 {
01306   if (!hasImageStream ())
01307     THROW_OPENNI_EXCEPTION ("Device does not provide an image stream");
01308 
01309   XnMapOutputMode output_mode;
01310   boost::lock_guard<boost::mutex> image_lock (image_mutex_);
01311   XnStatus status = image_generator_.GetMapOutputMode (output_mode);
01312   if (status != XN_STATUS_OK)
01313     THROW_OPENNI_EXCEPTION ("Could not get image stream output mode. Reason: %s", xnGetStatusString (status));
01314   return (output_mode);
01315 }
01316 
01318 XnMapOutputMode 
01319 openni_wrapper::OpenNIDevice::getDepthOutputMode () const
01320 {
01321   if (!hasDepthStream () )
01322     THROW_OPENNI_EXCEPTION ("Device does not provide a depth stream");
01323 
01324   XnMapOutputMode output_mode;
01325   boost::lock_guard<boost::mutex> depth_lock (depth_mutex_);
01326   XnStatus status = depth_generator_.GetMapOutputMode (output_mode);
01327   if (status != XN_STATUS_OK)
01328     THROW_OPENNI_EXCEPTION ("Could not get depth stream output mode. Reason: %s", xnGetStatusString (status));
01329   return (output_mode);
01330 }
01331 
01333 XnMapOutputMode 
01334 openni_wrapper::OpenNIDevice::getIROutputMode () const
01335 {
01336   if (!hasIRStream ())
01337     THROW_OPENNI_EXCEPTION ("Device does not provide an IR stream");
01338 
01339   XnMapOutputMode output_mode;
01340   boost::lock_guard<boost::mutex> ir_lock (ir_mutex_);
01341   XnStatus status = ir_generator_.GetMapOutputMode (output_mode);
01342   if (status != XN_STATUS_OK)
01343     THROW_OPENNI_EXCEPTION ("Could not get IR stream output mode. Reason: %s", xnGetStatusString (status));
01344   return (output_mode);
01345 }
01346 
01347 #endif //OPENNI


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