Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
openni_device.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2009-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #include <pcl/pcl_config.h>
39 #ifdef HAVE_OPENNI
40 
41 #ifndef __OPENNI_IDEVICE_H__
42 #define __OPENNI_IDEVICE_H__
43 #include <map>
44 #include <vector>
45 #include <utility>
46 #include "openni_exception.h"
47 #include <XnCppWrapper.h>
48 #include <boost/function.hpp>
49 #include <boost/thread.hpp>
50 #include <boost/thread/condition.hpp>
51 
52 #include <pcl/pcl_macros.h>
53 
55 
56 #ifndef _WIN32
57 #define __stdcall
58 #endif
59 
60 namespace openni_wrapper
61 {
62  class Image;
63  class DepthImage;
64  class IRImage;
65 
70  class PCL_EXPORTS OpenNIDevice
71  {
72  public:
73  typedef boost::function<void(boost::shared_ptr<Image>, void* cookie) > ImageCallbackFunction;
74  typedef boost::function<void(boost::shared_ptr<DepthImage>, void* cookie) > DepthImageCallbackFunction;
75  typedef boost::function<void(boost::shared_ptr<IRImage>, void* cookie) > IRImageCallbackFunction;
76  typedef unsigned CallbackHandle;
77 
78  public:
79 
81  virtual ~OpenNIDevice () throw ();
82 
90  bool
91  findCompatibleImageMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode ) const throw ();
92 
100  bool
101  findCompatibleDepthMode (const XnMapOutputMode& output_mode, XnMapOutputMode& mode ) const throw ();
102 
107  bool
108  isImageModeSupported (const XnMapOutputMode& output_mode) const throw ();
109 
114  bool
115  isDepthModeSupported (const XnMapOutputMode& output_mode) const throw ();
116 
121  const XnMapOutputMode&
122  getDefaultImageMode () const throw ();
123 
127  const XnMapOutputMode&
128  getDefaultDepthMode () const throw ();
129 
133  const XnMapOutputMode&
134  getDefaultIRMode () const throw ();
135 
139  void
140  setImageOutputMode (const XnMapOutputMode& output_mode);
141 
145  void
146  setDepthOutputMode (const XnMapOutputMode& output_mode);
147 
151  void
152  setIROutputMode (const XnMapOutputMode& output_mode);
153 
155  XnMapOutputMode
156  getImageOutputMode () const;
157 
159  XnMapOutputMode
160  getDepthOutputMode () const;
161 
163  XnMapOutputMode
164  getIROutputMode () const;
165 
169  void
170  setDepthRegistration (bool on_off);
171 
173  bool
174  isDepthRegistered () const throw ();
175 
177  bool
178  isDepthRegistrationSupported () const throw ();
179 
183  void
184  setSynchronization (bool on_off);
185 
187  bool
188  isSynchronized () const throw ();
189 
191  bool
192  isSynchronizationSupported () const throw ();
193 
195  bool
196  isDepthCropped () const;
197 
204  void
205  setDepthCropping (unsigned x, unsigned y, unsigned width, unsigned height);
206 
208  bool
209  isDepthCroppingSupported () const throw ();
210 
214  inline float
215  getImageFocalLength (int output_x_resolution = 0) const throw ();
216 
220  inline float
221  getDepthFocalLength (int output_x_resolution = 0) const throw ();
222 
224  inline float
225  getBaseline () const throw ();
226 
228  virtual void
229  startImageStream ();
230 
232  virtual void
233  stopImageStream ();
234 
236  virtual void
237  startDepthStream ();
238 
240  virtual void
241  stopDepthStream ();
242 
244  virtual void
245  startIRStream ();
246 
248  virtual void
249  stopIRStream ();
250 
252  bool
253  hasImageStream () const throw ();
254 
256  bool
257  hasDepthStream () const throw ();
258 
260  bool
261  hasIRStream () const throw ();
262 
264  virtual bool
265  isImageStreamRunning () const throw ();
266 
268  virtual bool
269  isDepthStreamRunning () const throw ();
270 
272  virtual bool
273  isIRStreamRunning () const throw ();
274 
281  CallbackHandle
282  registerImageCallback (const ImageCallbackFunction& callback, void* cookie = NULL) throw ();
283 
291  template<typename T> CallbackHandle
292  registerImageCallback (void (T::*callback)(boost::shared_ptr<Image>, void* cookie), T& instance, void* cookie = NULL) throw ();
293 
298  bool
299  unregisterImageCallback (const CallbackHandle& callbackHandle) throw ();
300 
301 
308  CallbackHandle
309  registerDepthCallback (const DepthImageCallbackFunction& callback, void* cookie = NULL) throw ();
310 
318  template<typename T> CallbackHandle
319  registerDepthCallback (void (T::*callback)(boost::shared_ptr<DepthImage>, void* cookie), T& instance, void* cookie = NULL) throw ();
320 
325  bool
326  unregisterDepthCallback (const CallbackHandle& callbackHandle) throw ();
327 
334  CallbackHandle
335  registerIRCallback (const IRImageCallbackFunction& callback, void* cookie = NULL) throw ();
336 
344  template<typename T> CallbackHandle
345  registerIRCallback (void (T::*callback)(boost::shared_ptr<IRImage>, void* cookie), T& instance, void* cookie = NULL) throw ();
346 
351  bool
352  unregisterIRCallback (const CallbackHandle& callbackHandle) throw ();
353 
357  const char*
358  getSerialNumber () const throw ();
359 
361  const char*
362  getConnectionString () const throw ();
363 
365  const char*
366  getVendorName () const throw ();
367 
369  const char*
370  getProductName () const throw ();
371 
373  unsigned short
374  getVendorID () const throw ();
375 
377  unsigned short
378  getProductID () const throw ();
379 
381  unsigned char
382  getBus () const throw ();
383 
385  unsigned char
386  getAddress () const throw ();
387 
391  inline void
392  setRGBFocalLength (float focal_length)
393  {
394  rgb_focal_length_SXGA_ = focal_length;
395  }
396 
400  inline void
401  setDepthFocalLength (float focal_length)
402  {
403  depth_focal_length_SXGA_ = focal_length;
404  }
405  private:
406  // make OpenNIDevice non copyable
407  OpenNIDevice (OpenNIDevice const &);
408  OpenNIDevice& operator=(OpenNIDevice const &);
409  protected:
410  typedef boost::function<void(boost::shared_ptr<Image>) > ActualImageCallbackFunction;
411  typedef boost::function<void(boost::shared_ptr<DepthImage>) > ActualDepthImageCallbackFunction;
412  typedef boost::function<void(boost::shared_ptr<IRImage>) > ActualIRImageCallbackFunction;
413 
414  OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, const xn::NodeInfo& image_node, const xn::NodeInfo& depth_node, const xn::NodeInfo& ir_node);
415  OpenNIDevice (xn::Context& context, const xn::NodeInfo& device_node, const xn::NodeInfo& depth_node, const xn::NodeInfo& ir_node);
416  OpenNIDevice (xn::Context& context);
417  static void __stdcall NewDepthDataAvailable (xn::ProductionNode& node, void* cookie) throw ();
418  static void __stdcall NewImageDataAvailable (xn::ProductionNode& node, void* cookie) throw ();
419  static void __stdcall NewIRDataAvailable (xn::ProductionNode& node, void* cookie) throw ();
420 
421  // This is a workaround, since in the NewDepthDataAvailable function WaitAndUpdateData leads to a dead-lock behaviour
422  // and retrieving image data without WaitAndUpdateData leads to incomplete images!!!
423  void
424  ImageDataThreadFunction ();
425 
426  void
427  DepthDataThreadFunction ();
428 
429  void
430  IRDataThreadFunction ();
431 
432  virtual bool
433  isImageResizeSupported (unsigned input_width, unsigned input_height, unsigned output_width, unsigned output_height) const throw () = 0;
434 
435  void
436  setRegistration (bool on_off);
437 
438  virtual boost::shared_ptr<Image>
439  getCurrentImage (boost::shared_ptr<xn::ImageMetaData> image_data) const throw () = 0;
440 
441  void
442  Init ();
443  // holds the callback functions together with custom data
444  // since same callback function can be registered multiple times with e.g. different custom data
445  // we use a map structure with a handle as the key
446  std::map<CallbackHandle, ActualImageCallbackFunction> image_callback_;
447  std::map<CallbackHandle, ActualDepthImageCallbackFunction> depth_callback_;
448  std::map<CallbackHandle, ActualIRImageCallbackFunction> ir_callback_;
449 
450  std::vector<XnMapOutputMode> available_image_modes_;
451  std::vector<XnMapOutputMode> available_depth_modes_;
452 
454  xn::Context& context_;
456  xn::NodeInfo device_node_info_;
457 
459  xn::DepthGenerator depth_generator_;
461  xn::ImageGenerator image_generator_;
463  xn::IRGenerator ir_generator_;
464 
465  XnCallbackHandle depth_callback_handle_;
466  XnCallbackHandle image_callback_handle_;
467  XnCallbackHandle ir_callback_handle_;
468 
470  float depth_focal_length_SXGA_;
472  float baseline_;
474  float rgb_focal_length_SXGA_;
475 
477  XnUInt64 shadow_value_;
479  XnUInt64 no_sample_value_;
480 
481  OpenNIDevice::CallbackHandle image_callback_handle_counter_;
482  OpenNIDevice::CallbackHandle depth_callback_handle_counter_;
483  OpenNIDevice::CallbackHandle ir_callback_handle_counter_;
484 
485  bool quit_;
486  mutable boost::mutex image_mutex_;
487  mutable boost::mutex depth_mutex_;
488  mutable boost::mutex ir_mutex_;
489  boost::condition_variable image_condition_;
490  boost::condition_variable depth_condition_;
491  boost::condition_variable ir_condition_;
492  boost::thread image_thread_;
493  boost::thread depth_thread_;
494  boost::thread ir_thread_;
495  } ;
496 
498  float
499  OpenNIDevice::getImageFocalLength (int output_x_resolution) const throw ()
500  {
501  if (output_x_resolution == 0)
502  output_x_resolution = getImageOutputMode ().nXRes;
503 
504  float scale = static_cast<float> (output_x_resolution) / static_cast<float> (XN_SXGA_X_RES);
505  return (rgb_focal_length_SXGA_ * scale);
506  }
507 
509  float
510  OpenNIDevice::getDepthFocalLength (int output_x_resolution) const throw ()
511  {
512  if (output_x_resolution == 0)
513  output_x_resolution = getDepthOutputMode ().nXRes;
514 
515  float scale = static_cast<float> (output_x_resolution) / static_cast<float> (XN_SXGA_X_RES);
516  if (isDepthRegistered ())
517  return (rgb_focal_length_SXGA_ * scale);
518  else
519  return (depth_focal_length_SXGA_ * scale);
520  }
521 
523  float
524  OpenNIDevice::getBaseline () const throw ()
525  {
526  return (baseline_);
527  }
528 
530  template<typename T> OpenNIDevice::CallbackHandle
531  OpenNIDevice::registerImageCallback (void (T::*callback)(boost::shared_ptr<Image>, void* cookie), T& instance, void* custom_data) throw ()
532  {
533  image_callback_[image_callback_handle_counter_] = boost::bind (callback, boost::ref (instance), _1, custom_data);
534  return (image_callback_handle_counter_++);
535  }
536 
538  template<typename T> OpenNIDevice::CallbackHandle
539  OpenNIDevice::registerDepthCallback (void (T::*callback)(boost::shared_ptr<DepthImage>, void* cookie), T& instance, void* custom_data) throw ()
540  {
541  depth_callback_[depth_callback_handle_counter_] = boost::bind ( callback, boost::ref (instance), _1, custom_data);
542  return (depth_callback_handle_counter_++);
543  }
544 
546  template<typename T> OpenNIDevice::CallbackHandle
547  OpenNIDevice::registerIRCallback (void (T::*callback)(boost::shared_ptr<IRImage>, void* cookie), T& instance, void* custom_data) throw ()
548  {
549  ir_callback_[ir_callback_handle_counter_] = boost::bind ( callback, boost::ref (instance), _1, custom_data);
550  return (ir_callback_handle_counter_++);
551  }
552 
553 }
554 #endif // __OPENNI_IDEVICE_H__
555 #endif // HAVE_OPENNI