00001
00008
00009 #include <math.h>
00010 #include <vector>
00011
00012
00013 #include <ros/ros.h>
00014 #include <ros/package.h>
00015 #include <pr2_controllers_msgs/JointTrajectoryAction.h>
00016 #include <actionlib/client/simple_action_client.h>
00017 #include <tf/transform_broadcaster.h>
00018 #include <kdl/frames.hpp>
00019
00020 #include <std_msgs/String.h>
00021 #include <geometry_msgs/Twist.h>
00022
00023
00024 #include <Eigen/Core>
00025
00026
00027 #include <XnOpenNI.h>
00028 #include <XnCodecIDs.h>
00029 #include <XnCppWrapper.h>
00030
00031 #define my_pi 3.141592653589793
00032
00033 using std::string;
00034
00035 typedef actionlib::SimpleActionClient<pr2_controllers_msgs::JointTrajectoryAction> TrajClient;
00036 typedef std::vector<std::pair<Eigen::VectorXd, Eigen::VectorXd> > Trajectory;
00037 TrajClient *arm_client_r;
00038 TrajClient *arm_client_l;
00039
00040
00041 xn::Context g_Context;
00042 xn::DepthGenerator g_DepthGenerator;
00043 xn::UserGenerator g_UserGenerator;
00044
00045 XnPoint3D init_usr_loc;
00046 XnPoint3D init_usr_RS;
00047 XnPoint3D init_usr_LS;
00048
00049 XnBool g_bNeedPose = FALSE;
00050 XnChar g_strPose[20] = "";
00051
00052
00053 #define CHECK_RC(nRetVal, what) \
00054 if (nRetVal != XN_STATUS_OK) \
00055 { \
00056 printf("%s failed: %s\n", what, xnGetStatusString(nRetVal)); \
00057 return nRetVal; \
00058 }
00059
00060
00061 struct pr2_joint
00062 {
00063 float yaw;
00064 float pitch;
00065 float absolute;
00066 };
00067
00068 class TeleopPR2Ni
00069 {
00070
00071 public:
00072 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00073
00074 TeleopPR2Ni();
00075 void
00076 updateTrajectory(double rate);
00077 void
00078 pubMsg(double rate);
00079 void
00080 initangles(pr2_joint &joint);
00081 void
00082 updateTrajectoryFromJoints(Trajectory &trajectory, pr2_joint &shoulderAngles,
00083 pr2_joint &elbowAngles, Eigen::VectorXd &curr_pos, Eigen::VectorXd &last_pos, double rate);
00084 void
00085 fillGoal(pr2_controllers_msgs::JointTrajectoryGoal &goal, Trajectory &trajectory, double rate);
00086
00087 ros::NodeHandle nh_;
00088 ros::NodeHandle privateNh_;
00089
00090 bool enabled_;
00091 bool teleopEnabled_;
00092 bool useLeftArm_;
00093 ros::Publisher rShoulderPub_;
00094 ros::Publisher rElbowPub_;
00095 ros::Publisher lShoulderPub_;
00096 ros::Publisher lElbowPub_;
00097
00098 pr2_joint rShoulderAngles_;
00099 pr2_joint rElbowAngles_;
00100 pr2_joint lShoulderAngles_;
00101 pr2_joint lElbowAngles_;
00102
00103 Eigen::VectorXd curr_pos_r_;
00104 Eigen::VectorXd last_pos_r_;
00105 Eigen::VectorXd curr_pos_l_;
00106 Eigen::VectorXd last_pos_l_;
00107
00108 Trajectory trajectory_r_;
00109 Trajectory trajectory_l_;
00110 };
00111
00112
00113 TeleopPR2Ni::TeleopPR2Ni() :
00114 privateNh_("~"), teleopEnabled_(false)
00115 {
00116 enabled_ = true;
00117
00118
00119 initangles(rShoulderAngles_);
00120 initangles(rElbowAngles_);
00121 initangles(lShoulderAngles_);
00122 initangles(lElbowAngles_);
00123
00124 curr_pos_r_.setZero(4);
00125 last_pos_r_.setZero(4);
00126 curr_pos_l_.setZero(4);
00127 last_pos_l_.setZero(4);
00128 }
00129
00130 void
00131 TeleopPR2Ni::initangles(pr2_joint &joint)
00132 {
00133
00134 joint.yaw = 0.0;
00135 joint.pitch = 0.0;
00136 joint.absolute = 1.0;
00137 }
00138
00139 void
00140 TeleopPR2Ni::updateTrajectoryFromJoints(Trajectory &trajectory, pr2_joint &shoulderAngles,
00141 pr2_joint &elbowAngles, Eigen::VectorXd &curr_pos, Eigen::VectorXd &last_pos, double rate)
00142 {
00143 Eigen::VectorXd next_pos(4);
00144 Eigen::VectorXd next_vel(4);
00145
00146 next_pos(0) = shoulderAngles.yaw;
00147 next_pos(1) = shoulderAngles.pitch;
00148 next_pos(2) = elbowAngles.yaw;
00149 next_pos(3) = -elbowAngles.pitch;
00150
00151 next_vel = (next_pos - last_pos) / (2. * (1. / rate));
00152
00153 if ((next_pos - curr_pos).norm() > 1. * my_pi / 180.)
00154 {
00155 trajectory.push_back(std::make_pair<Eigen::VectorXd, Eigen::VectorXd>(next_pos, next_vel));
00156 last_pos = curr_pos;
00157 curr_pos = next_pos;
00158 }
00159 else
00160 {
00161 last_pos = curr_pos;
00162 next_vel.setZero(4);
00163 trajectory.push_back(std::make_pair<Eigen::VectorXd, Eigen::VectorXd>(curr_pos, next_vel));
00164 }
00165 }
00166
00167 void
00168 TeleopPR2Ni::updateTrajectory(double rate)
00169 {
00170 updateTrajectoryFromJoints(trajectory_r_, rShoulderAngles_, rElbowAngles_, curr_pos_r_,
00171 last_pos_r_, rate);
00172 updateTrajectoryFromJoints(trajectory_l_, lShoulderAngles_, lElbowAngles_, curr_pos_l_,
00173 last_pos_l_, rate);
00174 }
00175
00176 void
00177 TeleopPR2Ni::fillGoal(pr2_controllers_msgs::JointTrajectoryGoal &goal, Trajectory &trajectory,
00178 double rate)
00179 {
00180
00181 goal.trajectory.points.resize(trajectory.size());
00182 for (size_t ind = 0; ind < trajectory.size(); ++ind)
00183 {
00184 Eigen::VectorXd &pos = trajectory[ind].first;
00185 Eigen::VectorXd &vel = trajectory[ind].second;
00186
00187 goal.trajectory.points[ind].positions.resize(7);
00188 goal.trajectory.points[ind].positions[0] = pos(0);
00189 goal.trajectory.points[ind].positions[1] = pos(1);
00190 goal.trajectory.points[ind].positions[2] = pos(2);
00191 goal.trajectory.points[ind].positions[3] = pos(3);
00192 goal.trajectory.points[ind].positions[4] = 0.0;
00193 goal.trajectory.points[ind].positions[5] = 0.0;
00194 goal.trajectory.points[ind].positions[6] = 0.0;
00195
00196
00197 vel /= 50.;
00198 goal.trajectory.points[ind].velocities.resize(7);
00199 goal.trajectory.points[ind].velocities[0] = vel(0);
00200 goal.trajectory.points[ind].velocities[1] = vel(1);
00201 goal.trajectory.points[ind].velocities[2] = vel(2);
00202 goal.trajectory.points[ind].velocities[3] = vel(3);
00203 goal.trajectory.points[ind].velocities[4] = 0.0;
00204 goal.trajectory.points[ind].velocities[5] = 0.0;
00205 goal.trajectory.points[ind].velocities[6] = 0.0;
00206
00207 goal.trajectory.points[ind].time_from_start = ros::Duration((ind + 1) * (1 / rate));
00208 }
00209
00210
00211 }
00212
00213 void
00214 TeleopPR2Ni::pubMsg(double rate)
00215 {
00216 if (teleopEnabled_ && arm_client_r && trajectory_r_.size() >= 3)
00217 {
00218 pr2_controllers_msgs::JointTrajectoryGoal goal;
00219 goal.trajectory.header.stamp = ros::Time::now();
00220
00221 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint");
00222 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint");
00223 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint");
00224 goal.trajectory.joint_names.push_back("r_elbow_flex_joint");
00225 goal.trajectory.joint_names.push_back("r_forearm_roll_joint");
00226 goal.trajectory.joint_names.push_back("r_wrist_flex_joint");
00227 goal.trajectory.joint_names.push_back("r_wrist_roll_joint");
00228
00229 fillGoal(goal, trajectory_r_, rate);
00230
00231 arm_client_r->sendGoal(goal);
00232 trajectory_r_.clear();
00233 }
00234 if (teleopEnabled_ && useLeftArm_ && arm_client_l && trajectory_l_.size() >= 3)
00235 {
00236 pr2_controllers_msgs::JointTrajectoryGoal goal;
00237 goal.trajectory.header.stamp = ros::Time::now() + ros::Duration(1 / rate);
00238
00239 goal.trajectory.joint_names.push_back("l_shoulder_pan_joint");
00240 goal.trajectory.joint_names.push_back("l_shoulder_lift_joint");
00241 goal.trajectory.joint_names.push_back("l_upper_arm_roll_joint");
00242 goal.trajectory.joint_names.push_back("l_elbow_flex_joint");
00243 goal.trajectory.joint_names.push_back("l_forearm_roll_joint");
00244 goal.trajectory.joint_names.push_back("l_wrist_flex_joint");
00245 goal.trajectory.joint_names.push_back("l_wrist_roll_joint");
00246
00247 fillGoal(goal, trajectory_l_, rate);
00248
00249 arm_client_l->sendGoal(goal);
00250 trajectory_l_.clear();
00251 }
00252 }
00253
00254 void XN_CALLBACK_TYPE User_NewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
00255 {
00256 printf("New User %d\n", nId);
00257 if (g_bNeedPose)
00258 g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
00259 else
00260 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00261 }
00262
00263 void XN_CALLBACK_TYPE User_LostUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
00264 {
00265 printf("Lost user %d\n", nId);
00266 }
00267
00268 void XN_CALLBACK_TYPE UserCalibration_CalibrationStart(xn::SkeletonCapability& capability, XnUserID nId, void* pCookie)
00269 {
00270 printf("Calibration started for user %d\n", nId);
00271 }
00272
00273 void XN_CALLBACK_TYPE UserCalibration_CalibrationEnd(xn::SkeletonCapability& capability, XnUserID nId, XnBool bSuccess, void* pCookie)
00274 {
00275 if (bSuccess)
00276 {
00277 printf("Calibration complete, start tracking user %d\n", nId);
00278 g_UserGenerator.GetSkeletonCap().StartTracking(nId);
00279 }
00280 else
00281 {
00282 printf("Calibration failed for user %d\n", nId);
00283 if (g_bNeedPose)
00284 g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
00285 else
00286 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00287 }
00288 }
00289
00290 void XN_CALLBACK_TYPE UserPose_PoseDetected(xn::PoseDetectionCapability& capability, XnChar const* strPose, XnUserID nId, void* pCookie)
00291 {
00292 printf("Pose %s detected for user %d\n", strPose, nId);
00293 g_UserGenerator.GetPoseDetectionCap().StopPoseDetection(nId);
00294 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00295 }
00296
00297 XnPoint3D
00298 getBodyLoc(XnUserID const& user, XnSkeletonJoint const& eJoint1)
00299 {
00300 XnPoint3D pt;
00301
00302
00303 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00304 {
00305 printf("not tracked!\n");
00306 pt.X = 0.0;
00307 pt.Y = 0.0;
00308 pt.Z = 0.0;
00309 return pt;
00310 }
00311
00312
00313 XnSkeletonJointPosition joint1;
00314 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00315
00316
00317 if (joint1.fConfidence < 0.7)
00318 {
00319 pt.X = 0.0;
00320 pt.Y = 0.0;
00321 pt.Z = 0.0;
00322 return pt;
00323 }
00324
00325 pt = joint1.position;
00326 return pt;
00327 }
00328
00329
00330
00331 float
00332 getAngleBetweenLimbs(XnUserID const& user, XnSkeletonJoint const& eJoint1,
00333 XnSkeletonJoint const& eJoint2, XnSkeletonJoint const& eJoint3, XnSkeletonJoint const& eJoint4)
00334 {
00335
00336
00337
00338
00339
00340
00341
00342 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00343 {
00344 printf("not tracked!\n");
00345 return -998.0;
00346 }
00347
00348
00349 XnSkeletonJointPosition joint1, joint2, joint3, joint4;
00350 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00351 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint2, joint2);
00352 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint3, joint3);
00353 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint4, joint4);
00354
00355
00356 if (joint1.fConfidence < 0.6 && joint2.fConfidence < 0.6 && joint3.fConfidence < 0.6
00357 && joint4.fConfidence < 0.6)
00358 {
00359 return -999.0;
00360 }
00361
00362 XnPoint3D pt[4];
00363 pt[0] = joint1.position;
00364 pt[1] = joint2.position;
00365 pt[2] = joint3.position;
00366 pt[3] = joint4.position;
00367
00368 XnVector3D v[2];
00369
00370
00371
00372 v[0].X = pt[2].X - pt[3].X;
00373 v[0].Y = pt[2].Y - pt[3].Y;
00374 v[0].Z = pt[2].Z - pt[3].Z;
00375
00376
00377
00378 v[1].X = pt[0].X - pt[1].X;
00379 v[1].Y = pt[0].Y - pt[1].Y;
00380 v[1].Z = pt[0].Z - pt[1].Z;
00381
00382
00383 float v0_magnitude = sqrt(v[0].X * v[0].X + v[0].Y * v[0].Y + v[0].Z * v[0].Z);
00384 float v1_magnitude = sqrt(v[1].X * v[1].X + v[1].Y * v[1].Y + v[1].Z * v[1].Z);
00385
00386
00387
00388
00389 if (v0_magnitude != 0.0 && v1_magnitude != 0.0)
00390 {
00391 v[0].X = v[0].X * (1.0 / v0_magnitude);
00392 v[0].Y = v[0].Y * (1.0 / v0_magnitude);
00393 v[0].Z = v[0].Z * (1.0 / v0_magnitude);
00394
00395 v[1].X = v[1].X * (1.0 / v1_magnitude);
00396 v[1].Y = v[1].Y * (1.0 / v1_magnitude);
00397 v[1].Z = v[1].Z * (1.0 / v1_magnitude);
00398
00399
00400 float theta = acos(v[0].X * v[1].X + v[0].Y * v[1].Y + v[0].Z * v[1].Z);
00401 float angle_in_degrees = theta * 180 / my_pi;
00402
00403 return angle_in_degrees;
00404 }
00405 else
00406 return -997.0;
00407 }
00408
00409
00410
00411 float
00412 getLimbAngle(XnUserID const& user, XnSkeletonJoint const& eJoint1, XnSkeletonJoint const& eJoint2,
00413 XnSkeletonJoint const& eJoint3)
00414 {
00415 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00416 {
00417 printf("not tracked!\n");
00418 return -998.0;
00419 }
00420
00421
00422 XnSkeletonJointPosition joint1, joint2, joint3;
00423 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00424 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint2, joint2);
00425 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint3, joint3);
00426
00427
00428 if (joint1.fConfidence < 0.6 && joint2.fConfidence < 0.6 && joint3.fConfidence < 0.6)
00429 {
00430 return -999.0;
00431 }
00432
00433 XnPoint3D pt[3];
00434 pt[0] = joint1.position;
00435 pt[1] = joint2.position;
00436 pt[2] = joint3.position;
00437
00438 XnVector3D v[2];
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 v[0].X = pt[1].X - pt[2].X;
00449 v[0].Y = pt[1].Y - pt[2].Y;
00450 v[0].Z = pt[1].Z - pt[2].Z;
00451
00452
00453
00454 v[1].X = pt[0].X - pt[1].X;
00455 v[1].Y = pt[0].Y - pt[1].Y;
00456 v[1].Z = pt[0].Z - pt[1].Z;
00457
00458
00459 float v0_magnitude = sqrt(v[0].X * v[0].X + v[0].Y * v[0].Y + v[0].Z * v[0].Z);
00460 float v1_magnitude = sqrt(v[1].X * v[1].X + v[1].Y * v[1].Y + v[1].Z * v[1].Z);
00461
00462
00463 if (v0_magnitude != 0.0 && v1_magnitude != 0.0)
00464 {
00465 v[0].X = v[0].X * (1.0 / v0_magnitude);
00466 v[0].Y = v[0].Y * (1.0 / v0_magnitude);
00467 v[0].Z = v[0].Z * (1.0 / v0_magnitude);
00468
00469 v[1].X = v[1].X * (1.0 / v1_magnitude);
00470 v[1].Y = v[1].Y * (1.0 / v1_magnitude);
00471 v[1].Z = v[1].Z * (1.0 / v1_magnitude);
00472
00473
00474 float theta = acos(v[0].X * v[1].X + v[0].Y * v[1].Y + v[0].Z * v[1].Z);
00475 float angle_in_degrees = theta * 180 / my_pi;
00476
00477 return angle_in_degrees;
00478 }
00479 else
00480 return -997.0;
00481 }
00482
00483
00484
00485 float
00486 getTorsoRotation(XnUserID const& user, XnSkeletonJoint const& eJoint1,
00487 XnSkeletonJoint const& eJoint2)
00488 {
00489
00490 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00491 {
00492 printf("not tracked!\n");
00493 return -998.0;
00494 }
00495
00496
00497 XnSkeletonJointPosition joint1, joint2;
00498 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00499 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint2, joint2);
00500
00501
00502 if (joint1.fConfidence < 0.6 && joint2.fConfidence < 0.6)
00503 {
00504 return -999.0;
00505 }
00506
00507 XnPoint3D pt[4];
00508 pt[0] = init_usr_LS;
00509 pt[1] = init_usr_RS;
00510 pt[2] = joint1.position;
00511 pt[3] = joint2.position;
00512
00513 XnVector3D v[2];
00514
00515
00516 v[0].X = pt[2].X - pt[3].X;
00517 v[0].Y = pt[2].Y - pt[3].Y;
00518 v[0].Z = pt[2].Z - pt[3].Z;
00519
00520 v[1].X = pt[0].X - pt[1].X;
00521 v[1].Y = pt[0].Y - pt[1].Y;
00522 v[1].Z = pt[0].Z - pt[1].Z;
00523
00524
00525 float v0_magnitude = sqrt(v[0].X * v[0].X + v[0].Y * v[0].Y + v[0].Z * v[0].Z);
00526 float v1_magnitude = sqrt(v[1].X * v[1].X + v[1].Y * v[1].Y + v[1].Z * v[1].Z);
00527
00528
00529
00530
00531 if (v0_magnitude != 0.0 && v1_magnitude != 0.0)
00532 {
00533 v[0].X = v[0].X * (1.0 / v0_magnitude);
00534 v[0].Y = v[0].Y * (1.0 / v0_magnitude);
00535 v[0].Z = v[0].Z * (1.0 / v0_magnitude);
00536
00537 v[1].X = v[1].X * (1.0 / v1_magnitude);
00538 v[1].Y = v[1].Y * (1.0 / v1_magnitude);
00539 v[1].Z = v[1].Z * (1.0 / v1_magnitude);
00540
00541
00542 float theta = acos(v[0].X * v[1].X + v[0].Y * v[1].Y + v[0].Z * v[1].Z);
00543 float angle_in_degrees = theta * 180 / my_pi;
00544
00545 return angle_in_degrees;
00546 }
00547 else
00548 return -997.0;
00549 }
00550
00551 void
00552 checkPose(TeleopPR2Ni &obj)
00553 {
00554 XnUserID users[2];
00555 XnUInt16 users_count = 2;
00556 g_UserGenerator.GetUsers(users, users_count);
00557 obj.teleopEnabled_ = false;
00558
00559 for (int i = 0; i < users_count; ++i)
00560 {
00561 XnUserID user = users[i];
00562 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00563 continue;
00564
00565 obj.teleopEnabled_ = true;
00566
00567
00568
00569
00570
00571 XnPoint3D current_bl = getBodyLoc(user, XN_SKEL_TORSO);
00572
00573
00574 XnPoint3D current_rs = getBodyLoc(user, XN_SKEL_RIGHT_SHOULDER);
00575
00576 XnPoint3D current_ls = getBodyLoc(user, XN_SKEL_LEFT_SHOULDER);
00577
00578
00579
00580
00581
00582
00583 float rsap = getLimbAngle(user, XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_SHOULDER,
00584 XN_SKEL_RIGHT_ELBOW) * my_pi / 180.0;
00585 rsap = rsap - 1.6;
00586 if (rsap >= -0.5 && rsap <= 1.4)
00587 {
00588 obj.rShoulderAngles_.pitch = rsap;
00589 }
00590
00591
00592
00593 float rear = getLimbAngle(user, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW,
00594 XN_SKEL_RIGHT_HAND) * my_pi / 180.0;
00595 if (2.4 >= rear && rear >= 0.0)
00596 {
00597 obj.rElbowAngles_.pitch = rear;
00598 }
00599
00600
00601
00602 float reay = getAngleBetweenLimbs(user, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_HIP,
00603 XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND) * my_pi / 180.0;
00604 reay = reay - 2.8;
00605 if (0.8 >= reay && reay >= -3.9)
00606 {
00607 obj.rElbowAngles_.yaw = reay;
00608 }
00609
00610
00611
00612 float rsar = getAngleBetweenLimbs(user, XN_SKEL_RIGHT_HIP, XN_SKEL_LEFT_HIP,
00613 XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW) * my_pi / 180.0;
00614
00615
00616
00617 rsar = 1.63 - rsar;
00618 if ( 0.7 >= rsar && rsar >= -2.3)
00619 {
00620 obj.rShoulderAngles_.yaw = rsar;
00621 }
00622
00623
00624
00625
00626
00627
00628 float lsap = getLimbAngle(user, XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW)
00629 * my_pi / 180.0;
00630 lsap = lsap - 1.6;
00631 if (lsap >= -0.5 && lsap <= 1.4)
00632 {
00633 obj.lShoulderAngles_.pitch = lsap;
00634 }
00635
00636
00637
00638 float lear = getLimbAngle(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND)
00639 * my_pi / 180.0;
00640 if (2.4 >= lear && lear >= 0.0)
00641 {
00642 obj.lElbowAngles_.pitch = lear;
00643 }
00644
00645
00646
00647 float leay = getAngleBetweenLimbs(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_HIP,
00648 XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND) * my_pi / 180.0;
00649 leay = 2.8 - leay;
00650 if (3.9 >= leay && leay >= -0.8)
00651 {
00652 obj.lElbowAngles_.yaw = leay;
00653 }
00654
00655
00656
00657 float lsar = getAngleBetweenLimbs(user, XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_HIP,
00658 XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW) * my_pi / 180.0;
00659
00660
00661
00662 lsar = lsar - 1.63;
00663 if (2.3 >= lsar && lsar >= -0.7)
00664 {
00665
00666 obj.lShoulderAngles_.yaw = lsar;
00667 }
00668
00669 }
00670 }
00671
00672 int
00673 main(int argc, char** argv)
00674 {
00675
00676 ros::init(argc, argv, "teleop_pr2_ni");
00677
00678 bool useLeftArm = true;
00679 arm_client_r = new TrajClient("r_arm_controller/joint_trajectory_action", true);
00680 arm_client_l = new TrajClient("l_arm_controller/joint_trajectory_action", true);
00681
00682 ros::NodeHandle n("/kinect_teleop");
00683
00684
00685 if (!n.getParam("use_left_arm", useLeftArm))
00686 {
00687 ROS_INFO("Not using left arm!");
00688 useLeftArm = false;
00689 }
00690
00691
00692 while (!arm_client_r->waitForServer(ros::Duration(5.0)))
00693 {
00694 ROS_INFO("Waiting for the right arm action server to come up");
00695 }
00696 while (useLeftArm && !arm_client_l->waitForServer(ros::Duration(5.0)))
00697 {
00698 ROS_INFO("Waiting for the left arm action server to come up");
00699 }
00700
00701 TeleopPR2Ni teleopPR2;
00702 teleopPR2.useLeftArm_ = useLeftArm;
00703 string configFilename = ros::package::getPath("kinect_teleop") + "/openni_tracker.xml";
00704
00705 int count = 0;
00706 double publishRate = 50;
00707 teleopPR2.privateNh_.param("motion_publish_rate", publishRate, publishRate);
00708 ros::Rate pubRate(publishRate);
00709
00710
00711
00712 XnStatus nRetVal = g_Context.InitFromXmlFile(configFilename.c_str());
00713 CHECK_RC(nRetVal, "InitFromXml");
00714
00715 nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator);
00716 CHECK_RC(nRetVal, "Find depth generator");
00717
00718 nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_USER, g_UserGenerator);
00719 if (nRetVal != XN_STATUS_OK)
00720 {
00721 nRetVal = g_UserGenerator.Create(g_Context);
00722 CHECK_RC(nRetVal, "Find user generator");
00723 }
00724
00725 if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON))
00726 {
00727 printf("Supplied user generator doesn't support skeleton\n");
00728 return 1;
00729 }
00730
00731 XnCallbackHandle hUserCallbacks;
00732 g_UserGenerator.RegisterUserCallbacks(User_NewUser, User_LostUser, NULL, hUserCallbacks);
00733
00734 XnCallbackHandle hCalibrationCallbacks;
00735 g_UserGenerator.GetSkeletonCap().RegisterCalibrationCallbacks(UserCalibration_CalibrationStart,
00736 UserCalibration_CalibrationEnd, NULL, hCalibrationCallbacks);
00737
00738 if (g_UserGenerator.GetSkeletonCap().NeedPoseForCalibration())
00739 {
00740 g_bNeedPose = TRUE;
00741 if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION))
00742 {
00743 printf("Pose required, but not supported\n");
00744 return 1;
00745 }
00746
00747 XnCallbackHandle hPoseCallbacks;
00748 g_UserGenerator.GetPoseDetectionCap().RegisterToPoseCallbacks(UserPose_PoseDetected, NULL,
00749 NULL, hPoseCallbacks);
00750
00751 g_UserGenerator.GetSkeletonCap().GetCalibrationPose(g_strPose);
00752 }
00753
00754 g_UserGenerator.GetSkeletonCap().SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
00755
00756 nRetVal = g_Context.StartGeneratingAll();
00757 CHECK_RC(nRetVal, "StartGenerating");
00758
00759
00760
00761 while (teleopPR2.nh_.ok())
00762 {
00763
00764 g_Context.WaitAndUpdateAll();
00765
00766 checkPose(teleopPR2);
00767
00768 teleopPR2.updateTrajectory(publishRate);
00769
00770 if (count % 3 == 0)
00771 {
00772 teleopPR2.pubMsg(publishRate / 50);
00773 count = 0;
00774 }
00775
00776 ++count;
00777 pubRate.sleep();
00778 }
00779
00780 g_Context.Shutdown();
00781 return 0;
00782
00783 }