openni_tracker.cpp
Go to the documentation of this file.
00001 // openni_tracker.cpp
00002 
00003 #include <ros/ros.h>
00004 #include <ros/package.h>
00005 #include <tf/transform_broadcaster.h>
00006 #include <kdl/frames.hpp>
00007 #include "cob_people_detection/SceneDrawer.h"
00008 
00009 #include <openni/XnOpenNI.h>
00010 #include <openni/XnCodecIDs.h>
00011 #include <openni/XnCppWrapper.h>
00012 
00013 using std::string;
00014 
00015 xn::Context g_Context;
00016 xn::DepthGenerator g_DepthGenerator;
00017 xn::UserGenerator g_UserGenerator;
00018 
00019 XnBool g_bNeedPose = FALSE;
00020 XnChar g_strPose[20] = "";
00021 
00022 void XN_CALLBACK_TYPE User_NewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
00023 {
00024         printf("New User %d\n", nId);
00025 
00026         if (g_bNeedPose)
00027         g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
00028         else
00029         g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00030 }
00031 
00032 void XN_CALLBACK_TYPE User_LostUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
00033 {
00034         printf("Lost user %d\n", nId);
00035 }
00036 
00037 void XN_CALLBACK_TYPE UserCalibration_CalibrationStart(xn::SkeletonCapability& capability, XnUserID nId, void* pCookie)
00038 {
00039         printf("Calibration started for user %d\n", nId);
00040 }
00041 
00042 void XN_CALLBACK_TYPE UserCalibration_CalibrationEnd(xn::SkeletonCapability& capability, XnUserID nId, XnBool bSuccess, void* pCookie)
00043 {
00044         if (bSuccess)
00045         {
00046                 printf("Calibration complete, start tracking user %d\n", nId);
00047                 g_UserGenerator.GetSkeletonCap().StartTracking(nId);
00048         }
00049         else
00050         {
00051                 printf("Calibration failed for user %d\n", nId);
00052                 if (g_bNeedPose)
00053                 g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
00054                 else
00055                 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00056         }
00057 }
00058 
00059 void XN_CALLBACK_TYPE UserPose_PoseDetected(xn::PoseDetectionCapability& capability, XnChar const* strPose, XnUserID nId, void* pCookie)
00060 {
00061         printf("Pose %s detected for user %d\n", strPose, nId);
00062         g_UserGenerator.GetPoseDetectionCap().StopPoseDetection(nId);
00063         g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00064 }
00065 
00066 void publishTransform(XnUserID const& user, XnSkeletonJoint const& joint, string const& frame_id, string const& child_frame_id)
00067 {
00068         static tf::TransformBroadcaster br;
00069 
00070         XnSkeletonJointPosition joint_position;
00071         g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, joint, joint_position);
00072         double x = joint_position.position.X / 1000.0;
00073         double y = joint_position.position.Y / 1000.0;
00074         double z = joint_position.position.Z / 1000.0;
00075 
00076         XnSkeletonJointOrientation joint_orientation;
00077         g_UserGenerator.GetSkeletonCap().GetSkeletonJointOrientation(user, joint, joint_orientation);
00078 
00079         XnFloat* m = joint_orientation.orientation.elements;
00080         KDL::Rotation rotation(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
00081         double qx, qy, qz, qw;
00082         rotation.GetQuaternion(qx, qy, qz, qw);
00083 
00084         tf::Transform transform;
00085         transform.setOrigin(tf::Vector3(x, y, z));
00086         transform.setRotation(tf::Quaternion(qx, qy, qz, qw));
00087         br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), frame_id, child_frame_id));
00088 }
00089 
00090 void publishTransforms(const std::string& frame_id, image_transport::Publisher& pub)
00091 {
00092         XnUserID users[15];
00093         XnUInt16 users_count = 15;
00094         g_UserGenerator.GetUsers(users, users_count);
00095 
00096         for (int i = 0; i < users_count; ++i)
00097         {
00098                 XnUserID user = users[i];
00099                 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00100                         continue;
00101 
00102                 publishTransform(user, XN_SKEL_HEAD, frame_id, "head");
00103                 publishTransform(user, XN_SKEL_NECK, frame_id, "neck");
00104                 publishTransform(user, XN_SKEL_TORSO, frame_id, "torso");
00105 
00106                 publishTransform(user, XN_SKEL_LEFT_SHOULDER, frame_id, "left_shoulder");
00107                 publishTransform(user, XN_SKEL_LEFT_ELBOW, frame_id, "left_elbow");
00108                 publishTransform(user, XN_SKEL_LEFT_HAND, frame_id, "left_hand");
00109 
00110                 publishTransform(user, XN_SKEL_RIGHT_SHOULDER, frame_id, "right_shoulder");
00111                 publishTransform(user, XN_SKEL_RIGHT_ELBOW, frame_id, "right_elbow");
00112                 publishTransform(user, XN_SKEL_RIGHT_HAND, frame_id, "right_hand");
00113 
00114                 publishTransform(user, XN_SKEL_LEFT_HIP, frame_id, "left_hip");
00115                 publishTransform(user, XN_SKEL_LEFT_KNEE, frame_id, "left_knee");
00116                 publishTransform(user, XN_SKEL_LEFT_FOOT, frame_id, "left_foot");
00117 
00118                 publishTransform(user, XN_SKEL_RIGHT_HIP, frame_id, "right_hip");
00119                 publishTransform(user, XN_SKEL_RIGHT_KNEE, frame_id, "right_knee");
00120                 publishTransform(user, XN_SKEL_RIGHT_FOOT, frame_id, "right_foot");
00121         }
00122 
00123         // publish segmented image
00124         xn::SceneMetaData sceneMD;
00125         xn::DepthMetaData depthMD;
00126         g_DepthGenerator.GetMetaData(depthMD);
00127         g_UserGenerator.GetUserPixels(0, sceneMD);
00128         PublishPeopleImage(depthMD, sceneMD, pub);
00129 }
00130 
00131 #define CHECK_RC(nRetVal, what)                                                                         \
00132         if (nRetVal != XN_STATUS_OK)                                                                    \
00133         {                                                                                                                               \
00134                 printf("%s failed: %s\n", what, xnGetStatusString(nRetVal));\
00135                 return nRetVal;                                                                                         \
00136         }
00137 
00138 int main(int argc, char **argv)
00139 {
00140         ros::init(argc, argv, "openni_tracker");
00141         ros::NodeHandle nh;
00142 
00143         string configFilename = ros::package::getPath("openni_tracker") + "/openni_tracker.xml";
00144         XnStatus nRetVal = g_Context.InitFromXmlFile(configFilename.c_str());
00145         CHECK_RC(nRetVal, "InitFromXml");
00146 
00147         nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator);
00148         CHECK_RC(nRetVal, "Find depth generator");
00149 
00150         nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_USER, g_UserGenerator);
00151         if (nRetVal != XN_STATUS_OK)
00152         {
00153                 nRetVal = g_UserGenerator.Create(g_Context);
00154                 CHECK_RC(nRetVal, "Find user generator");
00155         }
00156 
00157         if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON))
00158         {
00159                 printf("Supplied user generator doesn't support skeleton\n");
00160                 return 1;
00161         }
00162 
00163         XnCallbackHandle hUserCallbacks;
00164         g_UserGenerator.RegisterUserCallbacks(User_NewUser, User_LostUser, NULL, hUserCallbacks);
00165 
00166         XnCallbackHandle hCalibrationCallbacks;
00167         g_UserGenerator.GetSkeletonCap().RegisterCalibrationCallbacks(UserCalibration_CalibrationStart, UserCalibration_CalibrationEnd, NULL, hCalibrationCallbacks);
00168 
00169         if (g_UserGenerator.GetSkeletonCap().NeedPoseForCalibration())
00170         {
00171                 g_bNeedPose = TRUE;
00172                 if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION))
00173                 {
00174                         printf("Pose required, but not supported\n");
00175                         return 1;
00176                 }
00177 
00178                 XnCallbackHandle hPoseCallbacks;
00179                 g_UserGenerator.GetPoseDetectionCap().RegisterToPoseCallbacks(UserPose_PoseDetected, NULL, NULL, hPoseCallbacks);
00180 
00181                 g_UserGenerator.GetSkeletonCap().GetCalibrationPose(g_strPose);
00182         }
00183 
00184         g_UserGenerator.GetSkeletonCap().SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
00185 
00186         nRetVal = g_Context.StartGeneratingAll();
00187         CHECK_RC(nRetVal, "StartGenerating");
00188 
00189         ros::Rate r(30);
00190 
00191         ros::NodeHandle pnh("~");
00192         string frame_id("openni_depth_frame");
00193         pnh.getParam("camera_frame_id", frame_id);
00194 
00195         image_transport::ImageTransport it(nh);
00196         image_transport::Publisher pub = it.advertise("people_segmentation_image", 1);
00197 
00198         while (ros::ok())
00199         {
00200                 g_Context.WaitAndUpdateAll();
00201                 publishTransforms(frame_id, pub);
00202                 r.sleep();
00203         }
00204 
00205         g_Context.Shutdown();
00206         return 0;
00207 }


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Fri Aug 28 2015 10:24:13