00001
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
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 }