libfreenect.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OpenKinect Project. http://www.openkinect.org
3  *
4  * Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
5  * for details.
6  *
7  * This code is licensed to you under the terms of the Apache License, version
8  * 2.0, or, at your option, the terms of the GNU General Public License,
9  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
10  * or the following URLs:
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * http://www.gnu.org/licenses/gpl-2.0.txt
13  *
14  * If you redistribute this file in source form, modified or unmodified, you
15  * may:
16  * 1) Leave this header intact and distribute it under the same terms,
17  * accompanying it with the APACHE20 and GPL20 files, or
18  * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19  * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
20  * In all cases you must keep the copyright notice intact and include a copy
21  * of the CONTRIB file.
22  *
23  * Binary distributions must follow the binary distribution requirements of
24  * either License.
25  */
26 #pragma once
27 
28 #include "libfreenect.h"
29 #include <stdexcept>
30 #include <sstream>
31 #include <map>
32 #include <pthread.h>
33 #include <libusb.h>
34 
35 namespace Freenect {
36  class Noncopyable {
37  public:
40  private:
41  Noncopyable( const Noncopyable& );
42  const Noncopyable& operator=( const Noncopyable& );
43  };
44 
46  friend class FreenectDevice;
48  m_code(_state->tilt_status), m_state(_state)
49  {}
50  public:
51  void getAccelerometers(double* x, double* y, double* z) {
52  freenect_get_mks_accel(m_state, x, y, z);
53  }
54  double getTiltDegs() {
55  return freenect_get_tilt_degs(m_state);
56  }
57  public:
59  private:
61  };
62 
64  public:
65  FreenectDevice(freenect_context *_ctx, int _index)
66  : m_video_resolution(FREENECT_RESOLUTION_MEDIUM), m_depth_resolution(FREENECT_RESOLUTION_MEDIUM)
67  {
68  if(freenect_open_device(_ctx, &m_dev, _index) < 0) throw std::runtime_error("Cannot open Kinect");
69  freenect_set_user(m_dev, this);
72  freenect_set_depth_callback(m_dev, freenect_depth_callback);
73  freenect_set_video_callback(m_dev, freenect_video_callback);
74  }
75  virtual ~FreenectDevice() {
76  if(freenect_close_device(m_dev) < 0){} //FN_WARNING("Device did not shutdown in a clean fashion");
77  }
78  void startVideo() {
79  if(freenect_start_video(m_dev) < 0) throw std::runtime_error("Cannot start RGB callback");
80  }
81  void stopVideo() {
82  if(freenect_stop_video(m_dev) < 0) throw std::runtime_error("Cannot stop RGB callback");
83  }
84  void startDepth() {
85  if(freenect_start_depth(m_dev) < 0) throw std::runtime_error("Cannot start depth callback");
86  }
87  void stopDepth() {
88  if(freenect_stop_depth(m_dev) < 0) throw std::runtime_error("Cannot stop depth callback");
89  }
90  void setTiltDegrees(double _angle) {
91  if(freenect_set_tilt_degs(m_dev, _angle) < 0) throw std::runtime_error("Cannot set angle in degrees");
92  }
93  void setLed(freenect_led_options _option) {
94  if(freenect_set_led(m_dev, _option) < 0) throw std::runtime_error("Cannot set led");
95  }
96  void updateState() {
97  if (freenect_update_tilt_state(m_dev) < 0) throw std::runtime_error("Cannot update device state");
98  }
101  }
103  if (requested_format != m_video_format || requested_resolution != m_video_resolution) {
104  bool wasRunning = (freenect_stop_video(m_dev) >= 0);
106  if (!mode.is_valid) throw std::runtime_error("Cannot set video format: invalid mode");
107  if (freenect_set_video_mode(m_dev, mode) < 0) throw std::runtime_error("Cannot set video format");
108  if (wasRunning)
109  freenect_start_video(m_dev);
110  m_video_format = requested_format;
111  m_video_resolution = requested_resolution;
112  }
113  }
115  return m_video_format;
116  }
118  return m_video_resolution;
119  }
121  if (requested_format != m_depth_format || requested_resolution != m_depth_resolution) {
122  bool wasRunning = (freenect_stop_depth(m_dev) >= 0);
124  if (!mode.is_valid) throw std::runtime_error("Cannot set depth format: invalid mode");
125  if (freenect_set_depth_mode(m_dev, mode) < 0) throw std::runtime_error("Cannot set depth format");
126  if (wasRunning)
127  freenect_start_depth(m_dev);
128  m_depth_format = requested_format;
129  m_depth_resolution = requested_resolution;
130  }
131  }
133  return m_depth_format;
134  }
136  return m_depth_resolution;
137  }
138  int setFlag(freenect_flag flag, bool value)
139  {
140  return freenect_set_flag(m_dev, flag, value ? FREENECT_ON : FREENECT_OFF);
141  }
143  return m_dev;
144  }
145  // Do not call directly even in child
146  virtual void VideoCallback(void *video, uint32_t timestamp) { }
147  // Do not call directly even in child
148  virtual void DepthCallback(void *depth, uint32_t timestamp) { }
149  protected:
151  switch(m_video_format) {
152  case FREENECT_VIDEO_RGB:
159  return freenect_find_video_mode(m_video_resolution, m_video_format).bytes;
160  default:
161  return 0;
162  }
163  }
166  }
167  private:
173  static void freenect_depth_callback(freenect_device *dev, void *depth, uint32_t timestamp) {
174  FreenectDevice* device = static_cast<FreenectDevice*>(freenect_get_user(dev));
175  device->DepthCallback(depth, timestamp);
176  }
177  static void freenect_video_callback(freenect_device *dev, void *video, uint32_t timestamp) {
178  FreenectDevice* device = static_cast<FreenectDevice*>(freenect_get_user(dev));
179  device->VideoCallback(video, timestamp);
180  }
181  };
182 
184  private:
185  typedef std::map<int, FreenectDevice*> DeviceMap;
186  public:
187  Freenect() : m_stop(false) {
188  if(freenect_init(&m_ctx, NULL) < 0) throw std::runtime_error("Cannot initialize freenect library");
189  // We claim both the motor and camera devices, since this class exposes both.
190  // It does not support audio, so we do not claim it.
191  freenect_select_subdevices(m_ctx, static_cast<freenect_device_flags>(FREENECT_DEVICE_MOTOR | FREENECT_DEVICE_CAMERA));
192  if(pthread_create(&m_thread, NULL, pthread_callback, (void*)this) != 0) throw std::runtime_error("Cannot initialize freenect thread");
193  }
195  m_stop = true;
196  for(DeviceMap::iterator it = m_devices.begin() ; it != m_devices.end() ; ++it) {
197  delete it->second;
198  }
199  pthread_join(m_thread, NULL);
200  if(freenect_shutdown(m_ctx) < 0){} //FN_WARNING("Freenect did not shutdown in a clean fashion");
201  }
202  template <typename ConcreteDevice>
203  ConcreteDevice& createDevice(int _index) {
204  DeviceMap::iterator it = m_devices.find(_index);
205  if (it != m_devices.end()) delete it->second;
206  ConcreteDevice * device = new ConcreteDevice(m_ctx, _index);
207  m_devices[_index] = device;
208  return *device;
209  }
210  void deleteDevice(int _index) {
211  DeviceMap::iterator it = m_devices.find(_index);
212  if (it == m_devices.end()) return;
213  delete it->second;
214  m_devices.erase(it);
215  }
216  int deviceCount() {
217  return freenect_num_devices(m_ctx);
218  }
219  // Do not call directly, thread runs here
220  void operator()() {
221  while (!m_stop) {
222  static timeval timeout = { 1, 0 };
223  int res = freenect_process_events_timeout(m_ctx, &timeout);
224  if (res < 0)
225  {
226  // libusb signals an error has occurred
227  if (res == LIBUSB_ERROR_INTERRUPTED)
228  {
229  // This happens sometimes, it means that a system call in libusb was interrupted somehow (perhaps due to a signal)
230  // The simple solution seems to be just ignore it.
231  continue;
232  }
233  std::stringstream ss;
234  ss << "Cannot process freenect events (libusb error code: " << res << ")";
235  throw std::runtime_error(ss.str());
236  }
237  }
238  }
239  static void *pthread_callback(void *user_data) {
240  Freenect* freenect = static_cast<Freenect*>(user_data);
241  (*freenect)();
242  return NULL;
243  }
244  protected:
246  private:
247  volatile bool m_stop;
248  pthread_t m_thread;
249  DeviceMap m_devices;
250  };
251 
252 }
253 
void freenect_set_video_callback(freenect_device *dev, freenect_video_cb cb)
Definition: fakenect.c:241
freenect_flag
Enumeration of flags to toggle features with freenect_set_flag()
Definition: libfreenect.h:110
void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs)
Definition: fakenect.c:338
const freenect_device * getDevice()
void freenect_get_mks_accel(freenect_raw_tilt_state *state, double *x, double *y, double *z)
Definition: fakenect.c:227
void setTiltDegrees(double _angle)
Definition: libfreenect.hpp:90
int freenect_stop_video(freenect_device *dev)
Definition: fakenect.c:383
freenect_resolution getVideoResolution()
freenect_video_format
Definition: libfreenect.h:86
int setFlag(freenect_flag flag, bool value)
ConcreteDevice & createDevice(int _index)
int freenect_num_devices(freenect_context *ctx)
Definition: fakenect.c:308
void setLed(freenect_led_options _option)
Definition: libfreenect.hpp:93
void deleteDevice(int _index)
static void freenect_depth_callback(freenect_device *dev, void *depth, uint32_t timestamp)
int freenect_start_depth(freenect_device *dev)
Definition: fakenect.c:365
int freenect_set_led(freenect_device *dev, freenect_led_options option)
Definition: fakenect.c:414
freenect_video_format m_video_format
freenect_tilt_status_code m_code
Definition: libfreenect.hpp:58
FreenectTiltState(freenect_raw_tilt_state *_state)
Definition: libfreenect.hpp:47
int freenect_shutdown(freenect_context *ctx)
Definition: fakenect.c:402
Freenect::Freenect freenect
virtual void DepthCallback(void *depth, uint32_t timestamp)
freenect_depth_format getDepthFormat()
FREENECTAPI int freenect_set_flag(freenect_device *dev, freenect_flag flag, freenect_flag_value value)
Definition: flags.c:48
freenect_depth_format
Definition: libfreenect.h:99
int freenect_set_video_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:246
int freenect_set_tilt_degs(freenect_device *dev, double angle)
Definition: fakenect.c:410
int freenect_process_events_timeout(freenect_context *ctx, struct timeval *timeout)
Definition: fakenect.c:206
freenect_raw_tilt_state * m_state
Definition: libfreenect.hpp:60
void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb)
Definition: fakenect.c:236
freenect_depth_format m_depth_format
int freenect_start_video(freenect_device *dev)
Definition: fakenect.c:371
freenect_resolution m_depth_resolution
const Noncopyable & operator=(const Noncopyable &)
double freenect_get_tilt_degs(freenect_raw_tilt_state *state)
Definition: fakenect.c:211
freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt)
Definition: fakenect.c:260
freenect_frame_mode freenect_get_current_depth_mode(freenect_device *dev)
Definition: fakenect.c:303
freenect_context * m_ctx
freenect_resolution m_video_resolution
void setVideoFormat(freenect_video_format requested_format, freenect_resolution requested_resolution=FREENECT_RESOLUTION_MEDIUM)
freenect_device * m_dev
void * freenect_get_user(freenect_device *dev)
Definition: fakenect.c:360
freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt)
Definition: fakenect.c:284
MyFreenectDevice * device
freenect_led_options
Definition: libfreenect.h:148
freenect_resolution getDepthResolution()
static void * pthread_callback(void *user_data)
static void freenect_video_callback(freenect_device *dev, void *video, uint32_t timestamp)
freenect_raw_tilt_state * freenect_get_tilt_state(freenect_device *dev)
Definition: fakenect.c:217
int freenect_update_tilt_state(freenect_device *dev)
Definition: fakenect.c:418
int freenect_close_device(freenect_device *dev)
Definition: fakenect.c:406
int freenect_set_depth_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:253
int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
Definition: fakenect.c:314
freenect_resolution
Definition: libfreenect.h:77
volatile bool m_stop
Data from the tilt motor and accelerometer.
Definition: libfreenect.h:167
FreenectTiltState getState() const
Definition: libfreenect.hpp:99
virtual void VideoCallback(void *video, uint32_t timestamp)
freenect_video_format requested_format
Definition: glview.c:71
void getAccelerometers(double *x, double *y, double *z)
Definition: libfreenect.hpp:51
unsigned int uint32_t
std::map< int, FreenectDevice * > DeviceMap
int freenect_stop_depth(freenect_device *dev)
Definition: fakenect.c:377
freenect_resolution requested_resolution
Definition: hiview.c:71
freenect_video_format getVideoFormat()
freenect_tilt_status_code
Enumeration of tilt motor status.
Definition: libfreenect.h:160
FreenectDevice(freenect_context *_ctx, int _index)
Definition: libfreenect.hpp:65
void freenect_set_user(freenect_device *dev, void *user)
Definition: fakenect.c:355
void setDepthFormat(freenect_depth_format requested_format, freenect_resolution requested_resolution=FREENECT_RESOLUTION_MEDIUM)
int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx)
Definition: fakenect.c:327


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Mon Jun 10 2019 13:46:42