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;
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
double x() const
Common members of all points & poses classes.
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
void * m_skeletons_ptr
Opaque pointers to specific NITE data.
virtual ~CSkeletonTracker()
Destructor.
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
mrpt::system::TTimeStamp m_timeStartTT
void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
std::string m_sensorLabel
See CGenericSensor.
#define THROW_EXCEPTION(msg)
unsigned int m_toutCounter
Timeout counter (for internal use only)
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
std::vector< std::pair< JOINT, JOINT > > m_linesToPlot
Lines between joints.
int m_nUsers
Number of detected users.
This class allows loading and storing values and vectors of different types from a configuration text...
mrpt::poses::CPose3D m_sensorPose
Sensor pose.
static CDisplayWindow3DPtr Create()
A class for grabbing mrpt::obs::CObservationSkeleton from a PrimeSense camera.
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...
void processPreview(const mrpt::obs::CObservationSkeletonPtr &obs)
Displays real-time info for the captured skeleton.
This namespace contains representation of robot actions and observations.
void initialize()
Connects to the PrimeSense camera and prepares it to get skeleton data.
double conf
Confidence value [0...1].
void processPreviewNone()
GLsizei const GLchar ** string
A class used to store a 3D point.
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
unsigned __int64 uint64_t
mrpt::gui::CDisplayWindow3DPtr m_win
bool m_showPreview
Preview window management.
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...
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
The namespace for 3D scene representation and rendering.
A RGB color - floats in the range [0,1].
void appendObservation(const mrpt::utils::CSerializablePtr &obj)
Like appendObservations() but for just one observation.
mrpt::system::TTimeStamp BASE_IMPEXP secondsToTimestamp(const double nSeconds)
Transform a time interval (in seconds) into TTimeStamp (e.g.
A generic joint for the skeleton observation.
uint32_t m_timeStartUI
Timestamp management.
renders glyphs as filled polygons
#define FILL_JOINT_DATA(_J1, _J2)
std::vector< double > m_joint_theta
Joint angles when no skeleton has been detected.