35 #define skl_states (static_cast<nite::SkeletonState*>(m_skeletons_ptr))
36 #define user_tracker (static_cast<nite::UserTracker*>(m_userTracker_ptr))
38 #define FILL_JOINT_DATA(_J1,_J2) \
39 obs->_J1.x = user.getSkeleton().getJoint(_J2).getPosition().x;\
40 obs->_J1.y = user.getSkeleton().getJoint(_J2).getPosition().y;\
41 obs->_J1.z = user.getSkeleton().getJoint(_J2).getPosition().z;\
42 obs->_J1.conf = user.getSkeleton().getJoint(_J2).getPositionConfidence();
46 #pragma comment (lib,"NiTE2.lib")
50 "head",
"neck",
"torso",
51 "left_shoulder",
"left_elbow",
"left_hand",
"left_hip",
"left_knee",
"left_foot",
52 "right_shoulder",
"right_elbow",
"right_hand",
"right_hip",
"right_knee",
"right_foot"
58 CSkeletonTracker::CSkeletonTracker( ) :
59 m_skeletons_ptr (NULL),
60 m_userTracker_ptr (NULL),
65 m_showPreview (false),
70 #if MRPT_HAS_OPENNI2 && MRPT_HAS_NITE2
81 THROW_EXCEPTION(
"MRPT has been compiled with 'BUILD_OPENNI2'=OFF or 'BUILD_NITE2'=OFF, so this class cannot be used.");
91 #if MRPT_HAS_OPENNI2 && MRPT_HAS_NITE2
92 nite::NiTE::shutdown();
114 COpenGLScenePtr & scene =
m_win->get3DSceneAndLock();
115 scene->insert( CGridPlaneXZ::Create(-3,3,0,5,-1.5 ) );
118 m_win->setCameraElevationDeg(-90);
119 m_win->setCameraAzimuthDeg(90);
120 m_win->setCameraZoom(4);
121 m_win->setCameraPointingToPoint(0,0,0);
124 CSetOfObjectsPtr body = CSetOfObjects::Create();
125 body->setName(
"body");
128 CSpherePtr sph = CSphere::Create(0.03f);
129 sph->setColor(0,1,0);
135 CSetOfLinesPtr lines = CSetOfLines::Create();
136 lines->setName(
"lines");
137 lines->setColor(0,0,1);
141 m_win->unlockAccess3DScene();
146 COpenGLScenePtr & scene =
m_win->get3DSceneAndLock();
148 m_win->addTextMessage( 0.35, 0.9,
149 "Please, adopt this position",
154 if( !scene->getByName(
"dummy") )
156 const double SCALE = 0.8;
157 const double BODY_RADIUS = 0.22*SCALE;
158 const double BODY_LENGTH = 0.8*SCALE;
159 const double ARM_RADIUS = 0.05*SCALE;
160 const double ARM_LENGTH = 0.4*SCALE;
161 const double LEG_RADIUS = 0.1*SCALE;
162 const double LEG_LENGTH = 0.8*SCALE;
163 const double HEAD_RADIUS = 0.15*SCALE;
164 const double ALPHA_CH = 0.8;
166 CSetOfObjectsPtr dummy = CSetOfObjects::Create();
167 dummy->setName(
"dummy");
171 CSpherePtr part = CSphere::Create(HEAD_RADIUS);
172 part->setColor(1,1,1,ALPHA_CH);
173 part->setPose(
math::TPose3D(0,0,0.5*BODY_LENGTH+HEAD_RADIUS,0,0,0));
178 CCylinderPtr part = CCylinder::Create(BODY_RADIUS,BODY_RADIUS,BODY_LENGTH);
179 part->setColor(1,1,1,ALPHA_CH);
185 CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
186 part->setColor(1,1,1,ALPHA_CH);
192 CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
193 part->setColor(1,1,1,ALPHA_CH);
194 part->setPose(
math::TPose3D(-BODY_RADIUS-ARM_LENGTH+ARM_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,0,0));
199 CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
200 part->setColor(1,1,1,ALPHA_CH);
206 CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
207 part->setColor(1,1,1,ALPHA_CH);
208 part->setPose(
math::TPose3D(BODY_RADIUS+ARM_LENGTH-ARM_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,0,0));
213 CCylinderPtr part = CCylinder::Create(LEG_RADIUS,LEG_RADIUS,LEG_LENGTH);
214 part->setColor(1,1,1,ALPHA_CH);
215 part->setPose(
math::TPose3D(-BODY_RADIUS+LEG_RADIUS,0,-(0.5*BODY_LENGTH+LEG_LENGTH),0,0,0));
220 CCylinderPtr part = CCylinder::Create(LEG_RADIUS,LEG_RADIUS,LEG_LENGTH);
221 part->setColor(1,1,1,ALPHA_CH);
222 part->setPose(
math::TPose3D(BODY_RADIUS-LEG_RADIUS,0,-(0.5*BODY_LENGTH+LEG_LENGTH),0,0,0));
225 scene->insert(dummy);
229 CSetOfObjectsPtr dummy =
static_cast<CSetOfObjectsPtr
>( scene->getByName(
"dummy") );
230 dummy->setVisibility(
true);
234 CSetOfObjectsPtr body =
static_cast<CSetOfObjectsPtr
>( scene->getByName(
"body") );
239 CSpherePtr
s =
static_cast<CSpherePtr
>( body->getByName(
jointNames[i] ) );
250 s->setPose( sphPos );
251 s->setColor( 1, 0, 0 );
252 s->setRadius( i == 0 ? 0.07 : 0.03 );
255 m_win->unlockAccess3DScene();
256 m_win->forceRepaint();
276 COpenGLScenePtr & scene =
m_win->get3DSceneAndLock();
277 scene->insert( CGridPlaneXZ::Create(-3,3,0,5,-1.5 ) );
280 m_win->setCameraElevationDeg(-90);
281 m_win->setCameraAzimuthDeg(90);
282 m_win->setCameraZoom(4);
283 m_win->setCameraPointingToPoint(0,0,0);
286 CSetOfObjectsPtr body = CSetOfObjects::Create();
287 body->setName(
"body");
290 CSpherePtr sph = CSphere::Create(0.03f);
291 sph->setColor(0,1,0);
297 CSetOfLinesPtr lines = CSetOfLines::Create();
298 lines->setName(
"lines");
299 lines->setColor(0,0,1);
303 m_win->unlockAccess3DScene();
308 COpenGLScenePtr & scene =
m_win->get3DSceneAndLock();
311 m_win->clearTextMessages();
312 CSetOfObjectsPtr dummy =
static_cast<CSetOfObjectsPtr
>( scene->getByName(
"dummy") );
313 if( dummy ) dummy->setVisibility(
false);
317 CSetOfObjectsPtr body =
static_cast<CSetOfObjectsPtr
>( scene->getByName(
"body") );
326 case 0: j = obs->head;
break;
327 case 1: j = obs->neck;
break;
328 case 2: j = obs->torso;
break;
330 case 3: j = obs->left_shoulder;
break;
331 case 4: j = obs->left_elbow;
break;
332 case 5: j = obs->left_hand;
break;
333 case 6: j = obs->left_hip;
break;
334 case 7: j = obs->left_knee;
break;
335 case 8: j = obs->left_foot;
break;
337 case 9: j = obs->right_shoulder;
break;
338 case 10: j = obs->right_elbow;
break;
339 case 11: j = obs->right_hand;
break;
340 case 12: j = obs->right_hip;
break;
341 case 13: j = obs->right_knee;
break;
342 case 14: j = obs->right_foot;
break;
345 CSpherePtr
s =
static_cast<CSpherePtr
>( body->getByName(
jointNames[i] ) );
348 s->setRadius( i == 0 ? 0.07 : 0.03 );
352 CSetOfLinesPtr lines =
static_cast<CSetOfLinesPtr
>(body->getByName(
"lines") );
359 CSpherePtr s0 =
static_cast<CSpherePtr
>( body->getByName(
jointNames[pair.first] ) );
360 CSpherePtr s1 =
static_cast<CSpherePtr
>( body->getByName(
jointNames[pair.second] ) );
364 s0->getPoseX(),s0->getPoseY(),s0->getPoseZ(),
365 s1->getPoseX(),s1->getPoseY(),s1->getPoseZ()
369 m_win->unlockAccess3DScene();
370 m_win->forceRepaint();
380 #if MRPT_HAS_OPENNI2 && MRPT_HAS_NITE2
390 nite::UserTrackerFrameRef userTrackerFrame;
393 if (niteRc != nite::STATUS_OK)
395 printf(
" [Skeleton tracker] Get next frame failed\n");
400 const nite::Array<nite::UserData> & users = userTrackerFrame.getUsers();
404 const nite::UserData & user = users[i];
407 skl_states[user.getId()] = user.getSkeleton().getState();
412 cout <<
" [Skeleton tracker] New user found" << endl;
414 else if( user.getSkeleton().getState() == nite::SKELETON_TRACKED )
416 cout <<
" [Skeleton tracker] User " << user.getId() <<
" tracked" << endl;
417 CObservationSkeletonPtr obs = CObservationSkeleton::Create();
420 const uint64_t nowUI = userTrackerFrame.getTimestamp();
454 obs->sensorLabel =
m_sensorLabel +
"_" + std::to_string(user.getId());
471 cout <<
" [Skeleton tracker] Looking for user..." << endl;
479 cout <<
" [Skeleton tracker] No user found after 2000 attempts ..." << endl;
480 nite::NiTE::shutdown();
483 THROW_EXCEPTION(
"MRPT has been compiled with 'BUILD_OPENNI2'=OFF or 'MRPT_HAS_NITE2'=OFF, so this class cannot be used.");
492 #if MRPT_HAS_OPENNI2 && MRPT_HAS_NITE2
495 nite::NiTE::initialize();
498 if (niteRc != nite::STATUS_OK)
500 printf(
"Couldn't create user tracker\n");
505 printf(
"Sucessfully created user tracker \n");
506 printf(
"Start moving around to get detected...\n(PSI pose may be required for skeleton calibration, depending on the configuration)\n");
528 THROW_EXCEPTION(
"MRPT has been compiled with 'BUILD_OPENNI2'=OFF OR 'MRPT_HAS_NITE2'=OFF, so this class cannot be used.");
540 configSource.
read_float( iniSection,
"pose_x", 0,
false ),
541 configSource.
read_float( iniSection,
"pose_y", 0,
false ),
542 configSource.
read_float( iniSection,
"pose_z", 0,
false ),
551 cout <<
"---------------------------" << endl;
552 cout <<
"Skeleton Tracker parameters: " << endl;
553 cout <<
"---------------------------" << endl;
556 cout <<
"---------------------------" << endl << endl;
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
#define FILL_JOINT_DATA(_J1, _J2)
static CDisplayWindow3DPtr Create()
void appendObservation(const mrpt::utils::CSerializablePtr &obj)
Like appendObservations() but for just one observation.
std::string m_sensorLabel
See CGenericSensor.
A class for grabbing mrpt::obs::CObservationSkeleton from a PrimeSense camera.
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
void processPreviewNone()
unsigned int m_toutCounter
Timeout counter (for internal use only)
mrpt::poses::CPose3D m_sensorPose
Sensor pose.
std::vector< double > m_joint_theta
Joint angles when no skeleton has been detected.
virtual ~CSkeletonTracker()
Destructor.
void processPreview(const mrpt::obs::CObservationSkeletonPtr &obs)
Displays real-time info for the captured skeleton.
void * m_skeletons_ptr
Opaque pointers to specific NITE data.
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
int m_nUsers
Number of detected users.
void initialize()
Connects to the PrimeSense camera and prepares it to get skeleton data.
mrpt::system::TTimeStamp m_timeStartTT
std::vector< std::pair< JOINT, JOINT > > m_linesToPlot
Lines between joints.
uint32_t m_timeStartUI
Timestamp management.
mrpt::gui::CDisplayWindow3DPtr m_win
bool m_showPreview
Preview window management.
A class used to store a 3D point.
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
double x() const
Common members of all points & poses classes.
This class allows loading and storing values and vectors of different types from a configuration text...
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
GLsizei const GLchar ** string
void BASE_IMPEXP sleep(int time_ms) MRPT_NO_THROWS
An OS-independent method for sending the current thread to "sleep" for a given period of time.
mrpt::system::TTimeStamp BASE_IMPEXP secondsToTimestamp(const double nSeconds)
Transform a time interval (in seconds) into TTimeStamp (e.g.
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
#define THROW_EXCEPTION(msg)
Contains classes for various device interfaces.
This namespace contains representation of robot actions and observations.
The namespace for 3D scene representation and rendering.
@ FILL
renders glyphs as filled polygons
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
unsigned __int64 uint64_t
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
A generic joint for the skeleton observation.
double conf
Confidence value [0...1].
A RGB color - floats in the range [0,1].