Fawkes API  Fawkes Development Version
usertracker_thread.cpp
1 
2 /***************************************************************************
3  * usertracker_thread.cpp - OpenNI user tracker thread
4  *
5  * Created: Sun Feb 27 17:53:38 2011
6  * Copyright 2006-2011 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "usertracker_thread.h"
24 
25 #include "utils/setup.h"
26 
27 #include <core/threading/mutex_locker.h>
28 #include <fvutils/ipc/shm_image.h>
29 #include <interfaces/HumanSkeletonInterface.h>
30 #include <interfaces/HumanSkeletonProjectionInterface.h>
31 
32 #include <memory>
33 
34 using namespace fawkes;
35 using namespace firevision;
36 
37 /** @class OpenNiUserTrackerThread "usertracker_thread.h"
38  * OpenNI User Tracker Thread.
39  * This thread requests a user tracker node from OpenNI and publishes the
40  * retrieved information via the blackboard.
41  *
42  * @author Tim Niemueller
43  */
44 
45 /** Constructor. */
47 : Thread("OpenNiUserTrackerThread", Thread::OPMODE_WAITFORWAKEUP),
48  BlockedTimingAspect(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS)
49 {
50 }
51 
52 /** Destructor. */
54 {
55 }
56 
57 static void XN_CALLBACK_TYPE
58 cb_new_user(xn::UserGenerator &generator, XnUserID id, void *cookie)
59 {
60  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
61  t->new_user(id);
62 }
63 
64 static void XN_CALLBACK_TYPE
65 cb_lost_user(xn::UserGenerator &generator, XnUserID id, void *cookie)
66 {
67  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
68  t->lost_user(id);
69 }
70 
71 static void XN_CALLBACK_TYPE
72 cb_pose_start(xn::PoseDetectionCapability &capability,
73  const XnChar * pose_name,
74  XnUserID id,
75  void * cookie)
76 {
77  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
78  t->pose_start(id, pose_name);
79 }
80 
81 static void XN_CALLBACK_TYPE
82 cb_pose_end(xn::PoseDetectionCapability &capability,
83  const XnChar * pose_name,
84  XnUserID id,
85  void * cookie)
86 {
87  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
88  t->pose_end(id, pose_name);
89 }
90 
91 static void XN_CALLBACK_TYPE
92 cb_calibration_start(xn::SkeletonCapability &capability, XnUserID id, void *cookie)
93 {
94  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
95  t->calibration_start(id);
96 }
97 
98 #if XN_VERSION_GE(1, 3, 2, 0)
99 static void XN_CALLBACK_TYPE
100 cb_calibration_complete(xn::SkeletonCapability &capability,
101  XnUserID id,
102  XnCalibrationStatus status,
103  void * cookie)
104 {
105  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
106  t->calibration_end(id, status == XN_CALIBRATION_STATUS_OK);
107 }
108 #else
109 static void XN_CALLBACK_TYPE
110 cb_calibration_end(xn::SkeletonCapability &capability, XnUserID id, XnBool success, void *cookie)
111 {
112  OpenNiUserTrackerThread *t = static_cast<OpenNiUserTrackerThread *>(cookie);
113  t->calibration_end(id, success);
114 }
115 #endif
116 
117 void
119 {
121 
122  user_gen_ = new xn::UserGenerator();
123  std::auto_ptr<xn::UserGenerator> usergen_autoptr(user_gen_);
124 
125  depth_gen_ = new xn::DepthGenerator();
126  std::auto_ptr<xn::DepthGenerator> depthgen_autoptr(depth_gen_);
127 
128  XnStatus st;
129 
130  fawkes::openni::find_or_create_node(openni, XN_NODE_TYPE_DEPTH, depth_gen_);
131  fawkes::openni::setup_map_generator(*depth_gen_, config);
132  fawkes::openni::find_or_create_node(openni, XN_NODE_TYPE_USER, user_gen_);
133 
134  if (!user_gen_->IsCapabilitySupported(XN_CAPABILITY_SKELETON)) {
135  throw Exception("User generator does not support skeleton capability");
136  }
137 
138  scene_md_ = new xn::SceneMetaData();
139  std::auto_ptr<xn::SceneMetaData> scenemd_autoptr(scene_md_);
140  if ((st = user_gen_->GetUserPixels(0, *scene_md_)) != XN_STATUS_OK) {
141  throw Exception("Failed to get scene meta data (%s)", xnGetStatusString(st));
142  }
143 
144  st = user_gen_->RegisterUserCallbacks(cb_new_user, cb_lost_user, this, user_cb_handle_);
145  if (st != XN_STATUS_OK) {
146  throw Exception("Failed to register user callbacks (%s)", xnGetStatusString(st));
147  }
148 
149  skelcap_ = new xn::SkeletonCapability(user_gen_->GetSkeletonCap());
150 
151 #if XN_VERSION_GE(1, 3, 2, 0)
152  st = skelcap_->RegisterToCalibrationStart(cb_calibration_start, this, calib_start_cb_handle_);
153  if (st != XN_STATUS_OK) {
154  throw Exception("Failed to register calibration start event (%s)", xnGetStatusString(st));
155  }
156  st = skelcap_->RegisterToCalibrationComplete(cb_calibration_complete,
157  this,
158  calib_complete_cb_handle_);
159 #else
160  st = skelcap_->RegisterCalibrationCallbacks(cb_calibration_start,
161  cb_calibration_end,
162  this,
163  calib_cb_handle_);
164 #endif
165 
166  if (st != XN_STATUS_OK) {
167  throw Exception("Failed to register calibration callback (%s)", xnGetStatusString(st));
168  }
169 
170  skel_need_calib_pose_ = skelcap_->NeedPoseForCalibration();
171 
172  if (skel_need_calib_pose_) {
173  if (!user_gen_->IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) {
174  throw Exception("Calibration requires pose, but not supported by node");
175  }
176  skelcap_->GetCalibrationPose(calib_pose_name_);
177 
178  xn::PoseDetectionCapability posecap = user_gen_->GetPoseDetectionCap();
179 
180 #if XN_VERSION_GE(1, 3, 2, 0)
181  st = posecap.RegisterToPoseDetected(cb_pose_start, this, pose_start_cb_handle_);
182  if (st != XN_STATUS_OK) {
183  throw Exception("Failed to register pose detect event (%s)", xnGetStatusString(st));
184  }
185  st = posecap.RegisterToOutOfPose(cb_pose_end, this, pose_end_cb_handle_);
186 #else
187  st = posecap.RegisterToPoseCallbacks(cb_pose_start, cb_pose_end, this, pose_cb_handle_);
188 #endif
189  if (st != XN_STATUS_OK) {
190  throw Exception("Failed to register pose callbacks (%s)", xnGetStatusString(st));
191  }
192  }
193 
194  skelcap_->SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
195 
196  depth_gen_->StartGenerating();
197  user_gen_->StartGenerating();
198 
199  label_buf_ =
200  new SharedMemoryImageBuffer("openni-labels", RAW16, scene_md_->XRes(), scene_md_->YRes());
201  label_bufsize_ = colorspace_buffer_size(RAW16, scene_md_->XRes(), scene_md_->YRes());
202 
203  usergen_autoptr.release();
204  depthgen_autoptr.release();
205  scenemd_autoptr.release();
206 }
207 
208 void
210 {
211  // we do not stop generating, we don't know if there is no other plugin
212  // using the node.
213  delete user_gen_;
214  delete scene_md_;
215  delete skelcap_;
216  delete label_buf_;
217 
218  UserMap::iterator i;
219  for (i = users_.begin(); i != users_.end(); ++i) {
220  blackboard->close(i->second.skel_if);
221  blackboard->close(i->second.proj_if);
222  }
223 }
224 
225 void
227 {
228  // we do not lock here, we are only operating on our user generator copy
229  // and the update happens in a different main loop hook
230 
231  if (!user_gen_->IsDataNew())
232  return;
233 
234  UserMap::iterator i;
235  for (i = users_.begin(); i != users_.end(); ++i) {
236  if (!i->second.valid)
237  continue;
238 
239  bool needs_write = false;
240 
241  HumanSkeletonInterface::State new_state = i->second.skel_if->state();
242  if (skelcap_->IsTracking(i->first)) {
243  new_state = HumanSkeletonInterface::STATE_TRACKING;
244  } else if (skelcap_->IsCalibrating(i->first)) {
245  new_state = HumanSkeletonInterface::STATE_CALIBRATING;
246  } else {
247  new_state = HumanSkeletonInterface::STATE_DETECTING_POSE;
248  }
249 
250  if (new_state != i->second.skel_if->state()) {
251  i->second.skel_if->set_state(new_state);
252  needs_write = true;
253  }
254 
255  if (new_state == HumanSkeletonInterface::STATE_TRACKING) {
256  // update skeleton information
257  try {
258  update_user(i->first, i->second);
259  update_com(i->first, i->second);
260  needs_write = true;
261  } catch (Exception &e) {
262  logger->log_warn(name(),
263  "Failed to update skeleton data for %u, "
264  "exception follows",
265  i->first);
266  logger->log_warn(name(), e);
267  }
268  } else if (new_state == HumanSkeletonInterface::STATE_DETECTING_POSE) {
269  update_com(i->first, i->second);
270  needs_write = true;
271  } else if (new_state == HumanSkeletonInterface::STATE_CALIBRATING) {
272  update_com(i->first, i->second);
273  needs_write = true;
274  }
275 
276  if (needs_write) {
277  i->second.skel_if->write();
278  i->second.proj_if->write();
279  }
280  }
281 
282  if (label_buf_->num_attached() > 1) {
283  memcpy(label_buf_->buffer(), scene_md_->Data(), label_bufsize_);
284  }
285 }
286 
287 // Very noisy when added to st != XN_STATUS_OK case
288 //logger->log_warn(name(), "Failed to get joint transformation for "
289 // "%s joint (%s)",
290 // joint_name, xnGetStatusString(st));
291 
292 // change from mm to m
293 // translating to Fawkes coordinates, empirically verified
294 // permute ori columns to match our coordinate system, empirically verified
295 #define SET_JTF(id, joint, joint_name, bbfield) \
296  st = skelcap_->GetSkeletonJoint(id, joint, jtf); \
297  if (st != XN_STATUS_OK) { \
298  ori[0] = ori[1] = ori[2] = ori[3] = ori[4] = ori[5] = 0.; \
299  ori[6] = ori[7] = ori[8] = ori_confidence = pos_confidence = 0.; \
300  proj[0] = proj[1] = 0; \
301  } else { \
302  pos[0] = jtf.position.position.Z * 0.001; \
303  pos[1] = -jtf.position.position.X * 0.001; \
304  pos[2] = jtf.position.position.Y * 0.001; \
305  pos_confidence = jtf.position.fConfidence; \
306  \
307  ori[0] = jtf.orientation.orientation.elements[2]; \
308  ori[1] = -jtf.orientation.orientation.elements[0]; \
309  ori[2] = jtf.orientation.orientation.elements[1]; \
310  ori[3] = jtf.orientation.orientation.elements[5]; \
311  ori[4] = -jtf.orientation.orientation.elements[3]; \
312  ori[5] = jtf.orientation.orientation.elements[4]; \
313  ori[6] = jtf.orientation.orientation.elements[8]; \
314  ori[7] = -jtf.orientation.orientation.elements[6]; \
315  ori[8] = jtf.orientation.orientation.elements[7]; \
316  ori_confidence = jtf.orientation.fConfidence; \
317  \
318  XnPoint3D pt; \
319  pt = jtf.position.position; \
320  depth_gen_->ConvertRealWorldToProjective(1, &pt, &pt); \
321  proj[0] = pt.X; \
322  proj[1] = pt.Y; \
323  } \
324  user.skel_if->set_pos_##bbfield(pos); \
325  user.skel_if->set_pos_##bbfield##_confidence(pos_confidence); \
326  user.skel_if->set_ori_##bbfield(ori); \
327  user.skel_if->set_ori_##bbfield##_confidence(ori_confidence); \
328  \
329  user.proj_if->set_proj_##bbfield(proj);
330 
331 void
332 OpenNiUserTrackerThread::update_user(XnUserID id, UserInfo &user)
333 {
334  XnSkeletonJointTransformation jtf;
335  XnStatus st;
336 
337  float pos[3], ori[9], proj[2], pos_confidence, ori_confidence;
338 
339  SET_JTF(id, XN_SKEL_HEAD, "head", head);
340  SET_JTF(id, XN_SKEL_NECK, "neck", neck);
341  SET_JTF(id, XN_SKEL_TORSO, "torso", torso);
342  SET_JTF(id, XN_SKEL_WAIST, "waist", waist);
343  SET_JTF(id, XN_SKEL_LEFT_COLLAR, "left collar", left_collar);
344  SET_JTF(id, XN_SKEL_LEFT_SHOULDER, "left shoulder", left_shoulder);
345  SET_JTF(id, XN_SKEL_LEFT_ELBOW, "left elbow", left_elbow);
346  SET_JTF(id, XN_SKEL_LEFT_WRIST, "left wrist", left_wrist);
347  SET_JTF(id, XN_SKEL_LEFT_HAND, "left hand", left_hand);
348  SET_JTF(id, XN_SKEL_LEFT_FINGERTIP, "left finger tip", left_fingertip);
349  SET_JTF(id, XN_SKEL_RIGHT_COLLAR, "right collar", right_collar);
350  SET_JTF(id, XN_SKEL_RIGHT_SHOULDER, "right shoulder", right_shoulder);
351  SET_JTF(id, XN_SKEL_RIGHT_ELBOW, "right elbow", right_elbow);
352  SET_JTF(id, XN_SKEL_RIGHT_WRIST, "right wrist", right_wrist);
353  SET_JTF(id, XN_SKEL_RIGHT_HAND, "right hand", right_hand);
354  SET_JTF(id, XN_SKEL_RIGHT_FINGERTIP, "right finger tip", right_fingertip);
355  SET_JTF(id, XN_SKEL_LEFT_HIP, "left hip", left_hip);
356  SET_JTF(id, XN_SKEL_LEFT_KNEE, "left knee", left_knee);
357  SET_JTF(id, XN_SKEL_LEFT_ANKLE, "left ankle", left_ankle);
358  SET_JTF(id, XN_SKEL_LEFT_FOOT, "left foot", left_foot);
359  SET_JTF(id, XN_SKEL_RIGHT_HIP, "right hip", right_hip);
360  SET_JTF(id, XN_SKEL_RIGHT_KNEE, "right knee", right_knee);
361  SET_JTF(id, XN_SKEL_RIGHT_ANKLE, "right ankle", right_ankle);
362  SET_JTF(id, XN_SKEL_RIGHT_FOOT, "right foot", right_foot);
363 }
364 
365 void
366 OpenNiUserTrackerThread::update_com(XnUserID id, UserInfo &user)
367 {
368  XnPoint3D compt, compt_proj;
369  XnStatus st;
370  float com[3], com_proj[2];
371  com[0] = com[1] = com[2] = com_proj[0] = com_proj[1] = 0.;
372  if ((st = user_gen_->GetCoM(id, compt)) == XN_STATUS_OK) {
373  // translating to Fawkes coordinates, empirically verified
374  com[0] = compt.Z * 0.001;
375  com[1] = -compt.X * 0.001;
376  com[2] = compt.Y * 0.001;
377 
378  depth_gen_->ConvertRealWorldToProjective(1, &compt, &compt_proj);
379  com_proj[0] = compt_proj.X;
380  com_proj[1] = compt_proj.Y;
381  } else {
382  logger->log_warn(name(), "GetCoM failed: %s", xnGetStatusString(st));
383  }
384 
385  user.skel_if->set_com(com);
386  user.proj_if->set_proj_com(com_proj);
387 
388  int current_vishist = user.skel_if->visibility_history();
389  if ((com[0] == 0.) && (com[1] == 0.) && (com[2] == 0.)) {
390  if (current_vishist < 0) {
391  user.skel_if->set_visibility_history(--current_vishist);
392  } else {
393  user.skel_if->set_visibility_history(-1);
394  }
395  } else {
396  if (current_vishist > 0) {
397  user.skel_if->set_visibility_history(++current_vishist);
398  } else {
399  user.skel_if->set_visibility_history(1);
400  }
401  }
402 }
403 
404 /** Notify of new user.
405  * This is called by the OpenNI callback when a new user has been detected.
406  * @param id new user's ID
407  */
408 void
410 {
411  if (users_.find(id) != users_.end()) {
412  logger->log_error(name(), "New user ID %u, interface already exists", id);
413  } else {
414  char *ifid;
415  if (asprintf(&ifid, "OpenNI Human %u", id) == -1) {
416  logger->log_warn(name(),
417  "New user ID %u, but cannot generate "
418  "interface ID",
419  id);
420  return;
421  }
422  try {
423  logger->log_debug(name(), "Opening interface 'HumanSkeletonInterface::%s'", ifid);
424  users_[id].skel_if = blackboard->open_for_writing<HumanSkeletonInterface>(ifid);
425  users_[id].skel_if->set_user_id(id);
426  users_[id].skel_if->write();
427  } catch (Exception &e) {
428  logger->log_warn(name(), "Failed to open interface, exception follows");
429  logger->log_warn(name(), e);
430  }
431 
432  try {
433  logger->log_debug(name(), "Opening interface 'HumanSkeletonProjectionInterface::%s'", ifid);
434  users_[id].proj_if = blackboard->open_for_writing<HumanSkeletonProjectionInterface>(ifid);
435  XnFieldOfView fov;
436  XnStatus st;
437  if ((st = depth_gen_->GetFieldOfView(fov)) != XN_STATUS_OK) {
438  logger->log_error(name(),
439  "Failed to get field of view, ignoring. (%s)",
440  xnGetStatusString(st));
441  } else {
442  users_[id].proj_if->set_horizontal_fov(fov.fHFOV);
443  users_[id].proj_if->set_vertical_fov(fov.fVFOV);
444  }
445 
446  xn::DepthMetaData dmd;
447  depth_gen_->GetMetaData(dmd);
448  users_[id].proj_if->set_res_x(dmd.XRes());
449  users_[id].proj_if->set_res_y(dmd.YRes());
450  users_[id].proj_if->set_max_depth(depth_gen_->GetDeviceMaxDepth());
451  users_[id].proj_if->write();
452  } catch (Exception &e) {
453  blackboard->close(users_[id].proj_if);
454  users_.erase(id);
455  logger->log_warn(name(), "Failed to open interface, exception follows");
456  logger->log_warn(name(), e);
457  }
458 
459  free(ifid);
460  }
461 
462  users_[id].valid = true;
463 
464  if (skel_need_calib_pose_) {
465  user_gen_->GetPoseDetectionCap().StartPoseDetection(calib_pose_name_, id);
466  } else {
467  user_gen_->GetSkeletonCap().RequestCalibration(id, TRUE);
468  }
469 }
470 
471 /** Notify of lost user.
472  * This is called by the OpenNI callback when a user has been lost,
473  * i.e. it has not been visible for some time.
474  * @param id lost user's ID
475  */
476 void
478 {
479  if (users_.find(id) == users_.end()) {
480  logger->log_error(name(), "Lost user ID %u, but interface does not exist", id);
481  return;
482  }
483 
484  logger->log_error(name(),
485  "Lost user ID %u, setting interface '%s' to invalid",
486  id,
487  users_[id].skel_if->uid());
488  // write invalid, a reader might still be open
489  users_[id].skel_if->set_state(HumanSkeletonInterface::STATE_INVALID);
490  users_[id].skel_if->write();
491  users_[id].valid = false;
492  //blackboard->close(users_[id].skel_if);
493  //blackboard->close(users_[id].proj_if);
494  //users_.erase(id);
495 }
496 
497 /** Notify of detected pose.
498  * This is called if a pose has been detected.
499  * @param id ID of user who is in the pose
500  * @param pose_name name of the detected pose
501  */
502 void
503 OpenNiUserTrackerThread::pose_start(XnUserID id, const char *pose_name)
504 {
505  if (users_.find(id) == users_.end()) {
506  logger->log_error(name(),
507  "Pose start for user ID %u, "
508  "but interface does not exist",
509  id);
510  return;
511  }
512 
513  logger->log_info(name(), "Pose %s detected for user %u", pose_name, id);
514 
515  users_[id].skel_if->set_pose(pose_name);
516  user_gen_->GetPoseDetectionCap().StopPoseDetection(id);
517  user_gen_->GetSkeletonCap().RequestCalibration(id, TRUE);
518 }
519 
520 /** Notify of pose detection end.
521  * This is called if a pose is no longer detected. The NITE middleware seems
522  * not to call this.
523  * @param id ID of user who is in the pose
524  * @param pose_name name of the no longer detected pose
525  */
526 void
527 OpenNiUserTrackerThread::pose_end(XnUserID id, const char *pose_name)
528 {
529  if (users_.find(id) == users_.end()) {
530  logger->log_error(name(),
531  "Pose end for user ID %u, "
532  "but interface does not exist",
533  id);
534  return;
535  }
536 
537  users_[id].skel_if->set_pose("");
538 }
539 
540 /** Notify of calibration start.
541  * This is called when tracking for a user has been started.
542  * @param id ID of user who is being calibrated.
543  */
544 void
546 {
547  if (users_.find(id) == users_.end()) {
548  logger->log_error(name(),
549  "Pose end for user ID %u, "
550  "but interface does not exist",
551  id);
552  return;
553  }
554 
555  logger->log_info(name(), "Calibration started for user %u", id);
556 }
557 
558 /** Notify of calibration end.
559  * This is called when tracking for a user has finished.
560  * @param id ID of user who was being calibrated
561  * @param success true if the calibration was successful, false otherwise
562  */
563 void
565 {
566  if (users_.find(id) == users_.end()) {
567  logger->log_error(name(),
568  "Pose end for user ID %u, "
569  "but interface does not exist",
570  id);
571  return;
572  }
573 
574  users_[id].skel_if->set_pose("");
575 
576  if (success) {
577  logger->log_info(name(),
578  "Calibration successful for user %u, "
579  "starting tracking",
580  id);
581  user_gen_->GetSkeletonCap().StartTracking(id);
582  } else {
583  logger->log_info(name(), "Calibration failed for user %u, restarting", id);
584  if (skel_need_calib_pose_) {
585  user_gen_->GetPoseDetectionCap().StartPoseDetection(calib_pose_name_, id);
586  } else {
587  user_gen_->GetSkeletonCap().RequestCalibration(id, TRUE);
588  }
589  }
590 }
OpenNiUserTrackerThread::calibration_start
void calibration_start(XnUserID id)
Notify of calibration start.
Definition: usertracker_thread.cpp:545
OpenNiUserTrackerThread::calibration_end
void calibration_end(XnUserID id, bool success)
Notify of calibration end.
Definition: usertracker_thread.cpp:564
OpenNiUserTrackerThread::pose_end
void pose_end(XnUserID id, const char *pose_name)
Notify of pose detection end.
Definition: usertracker_thread.cpp:527
OpenNiUserTrackerThread::init
virtual void init()
Initialize the thread.
Definition: usertracker_thread.cpp:118
fawkes::HumanSkeletonInterface
HumanSkeletonInterface Fawkes BlackBoard Interface.
Definition: HumanSkeletonInterface.h:34
fawkes::Logger::log_info
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
fawkes::SharedMemory::num_attached
unsigned int num_attached() const
Get number of attached processes.
Definition: shm.cpp:763
fawkes::MutexLocker
Mutex locking helper.
Definition: mutex_locker.h:34
fawkes::LockPtr::objmutex_ptr
Mutex * objmutex_ptr() const
Get object mutex.
Definition: lockptr.h:284
OpenNiUserTrackerThread::finalize
virtual void finalize()
Finalize the thread.
Definition: usertracker_thread.cpp:209
fawkes::BlockedTimingAspect
Thread aspect to use blocked timing.
Definition: blocked_timing.h:51
firevision::SharedMemoryImageBuffer
Shared memory image buffer.
Definition: shm_image.h:184
fawkes::Thread::name
const char * name() const
Get name of thread.
Definition: thread.h:100
fawkes::HumanSkeletonProjectionInterface
HumanSkeletonProjectionInterface Fawkes BlackBoard Interface.
Definition: HumanSkeletonProjectionInterface.h:34
fawkes::LoggingAspect::logger
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:41
fawkes::BlackBoard::close
virtual void close(Interface *interface)=0
Close interface.
fawkes::Logger::log_error
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
fawkes
Fawkes library namespace.
OpenNiUserTrackerThread::lost_user
void lost_user(XnUserID id)
Notify of lost user.
Definition: usertracker_thread.cpp:477
fawkes::Logger::log_warn
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
fawkes::ConfigurableAspect::config
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:41
firevision::SharedMemoryImageBuffer::buffer
unsigned char * buffer() const
Get image buffer.
Definition: shm_image.cpp:228
fawkes::Thread
Thread class encapsulation of pthreads.
Definition: thread.h:46
fawkes::BlackBoardAspect::blackboard
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
Definition: blackboard.h:44
OpenNiUserTrackerThread
OpenNI User Tracker Thread.
Definition: usertracker_thread.h:55
OpenNiUserTrackerThread::loop
virtual void loop()
Code to execute in the thread.
Definition: usertracker_thread.cpp:226
OpenNiUserTrackerThread::OpenNiUserTrackerThread
OpenNiUserTrackerThread()
Constructor.
Definition: usertracker_thread.cpp:46
OpenNiUserTrackerThread::~OpenNiUserTrackerThread
virtual ~OpenNiUserTrackerThread()
Destructor.
Definition: usertracker_thread.cpp:53
fawkes::Logger::log_debug
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
OpenNiUserTrackerThread::new_user
void new_user(XnUserID id)
Notify of new user.
Definition: usertracker_thread.cpp:409
fawkes::BlackBoard::open_for_writing
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
fawkes::HumanSkeletonInterface::State
State
Current tracking state for the skeleton.
Definition: HumanSkeletonInterface.h:44
fawkes::OpenNiAspect::openni
LockPtr< xn::Context > openni
Central OpenNI context.
Definition: openni.h:47
OpenNiUserTrackerThread::pose_start
void pose_start(XnUserID id, const char *pose_name)
Notify of detected pose.
Definition: usertracker_thread.cpp:503
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36