00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include <math.h>
00078
00079
00080 #include <ros/ros.h>
00081 #include <ros/package.h>
00082 #include <tf/transform_broadcaster.h>
00083 #include <kdl/frames.hpp>
00084
00085
00086
00087 #include <std_msgs/String.h>
00088 #include <geometry_msgs/Twist.h>
00089 #include <nao_ctrl/MotionCommandBtn.h>
00090 #include <nao_ctrl/HeadAngles.h>
00091
00092
00093
00094 #include <XnOpenNI.h>
00095 #include <XnCodecIDs.h>
00096 #include <XnCppWrapper.h>
00097
00098 using std::string;
00099
00100
00101 xn::Context g_Context;
00102 xn::DepthGenerator g_DepthGenerator;
00103 xn::UserGenerator g_UserGenerator;
00104
00105 XnBool g_bNeedPose = FALSE;
00106 XnChar g_strPose[20] = "";
00107
00108
00109 std_msgs::String naosay;
00110 XnPoint3D init_usr_loc;
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 float anterior_safe_line = 0.0;
00140 float posterior_safe_line = 0.0;
00141 float right_safe_line = 0.0;
00142 float left_safe_line = 0.0;
00143 float safe_angle = 0.0;
00144
00145 float anterior_control_line = 0.0;
00146 float posterior_control_line = 0.0;
00147 float right_control_line = 0.0;
00148 float left_control_line = 0.0;
00149 float control_angle = 0.0;
00150
00151 XnPoint3D init_usr_RS;
00152 XnPoint3D init_usr_LS;
00153
00154
00155 #define CHECK_RC(nRetVal, what) \
00156 if (nRetVal != XN_STATUS_OK) \
00157 { \
00158 printf("%s failed: %s\n", what, xnGetStatusString(nRetVal)); \
00159 return nRetVal; \
00160 }
00161
00162 #define my_pi 3.141592653589793 // Define the PI number for vector calculations
00163 #define walking_speed 0.3 // Walking speed of the robot [0.0 - 1.0]
00164 #define rotating_speed 0.3 // Angular speed of the robot
00165
00166 #define control_dist 300.0 // Distance to step in order to control the robot
00167 #define safety_dist 200.0 // Distance where user can reset the speed of the robot
00168
00169 #define control_rot 1.57 // Angle to turn, in order to rotate the torso of the robot
00170 #define safety_rot 0.3 // Angle up to which the user can reset the rotational speed of the robot
00171
00172 #define rot_constant 0.04 // Tune this!
00173
00174 class TeleopNaoNi
00175 {
00176 public:
00177 TeleopNaoNi();
00178 void pubMsg();
00179 ros::NodeHandle nh;
00180 ros::NodeHandle privateNh;
00181
00182 bool m_enabled;
00183 bool m_teleopEnabled;
00184 bool m_attentionEnabled;
00185 bool m_commandEnabled;
00186 int m_xAxis;
00187 int m_yAxis;
00188 int m_turnAxis;
00189 int m_headYawAxis;
00190 int m_headPitchAxis;
00191 int m_crouchBtn;
00192 int m_initPoseBtn;
00193 int m_enableBtn;
00194 int m_modifyHeadBtn;
00195 int m_startScanBtn;
00196 int m_stopScanBtn;
00197 double m_maxVx;
00198 double m_maxVy;
00199 double m_maxVw;
00200 double m_maxHeadYaw;
00201 double m_maxHeadPitch;
00202
00203 ros::Publisher m_movePub;
00204 ros::Publisher m_moveBtnPub;
00205 ros::Publisher m_headPub;
00206 ros::Publisher m_speechPub;
00207 ros::Publisher m_lShoulderPub;
00208 ros::Publisher m_rShoulderPub;
00209 ros::Publisher m_lElbowPub;
00210 ros::Publisher m_rElbowPub;
00211 geometry_msgs::Twist m_motion;
00212 nao_ctrl::HeadAngles m_headAngles;
00213 nao_ctrl::HeadAngles m_lShoulderAngles;
00214 nao_ctrl::HeadAngles m_rShoulderAngles;
00215 nao_ctrl::HeadAngles m_lElbowAngles;
00216 nao_ctrl::HeadAngles m_rElbowAngles;
00217 };
00218
00219
00220 TeleopNaoNi::TeleopNaoNi()
00221 : privateNh("~"), m_enabled(false), m_teleopEnabled(false), m_attentionEnabled(false), m_commandEnabled(false),
00222 m_xAxis(3), m_yAxis(2), m_turnAxis(0), m_headYawAxis(4), m_headPitchAxis(5),
00223 m_crouchBtn(9), m_initPoseBtn(0), m_enableBtn(8), m_modifyHeadBtn(5),
00224 m_startScanBtn(2), m_stopScanBtn(3),
00225 m_maxVx(1.0), m_maxVy(1.0), m_maxVw(0.5),
00226 m_maxHeadYaw(2.0943), m_maxHeadPitch(0.7853)
00227 {
00228 privateNh.param("axis_x", m_xAxis, m_xAxis);
00229 privateNh.param("axis_y", m_yAxis, m_yAxis);
00230 privateNh.param("axis_turn", m_turnAxis, m_turnAxis);
00231 privateNh.param("axis_head_yaw", m_headYawAxis, m_headYawAxis);
00232 privateNh.param("axis_head_pitch", m_headPitchAxis, m_headPitchAxis);
00233 privateNh.param("btn_crouch", m_crouchBtn, m_crouchBtn);
00234 privateNh.param("btn_enable_control", m_enableBtn, m_enableBtn);
00235 privateNh.param("btn_head_mod", m_modifyHeadBtn, m_modifyHeadBtn);
00236 privateNh.param("btn_start_scan", m_startScanBtn, m_startScanBtn);
00237 privateNh.param("btn_stop_scan", m_stopScanBtn, m_stopScanBtn);
00238 privateNh.param("max_vx", m_maxVx, m_maxVx);
00239 privateNh.param("max_vy", m_maxVy, m_maxVy);
00240 privateNh.param("max_vw", m_maxVw, m_maxVw);
00241
00242 privateNh.param("max_head_yaw", m_maxHeadYaw, m_maxHeadYaw);
00243 privateNh.param("max_head_pitch", m_maxHeadPitch, m_maxHeadPitch);
00244
00245
00246 m_motion.linear.x = m_motion.linear.y = m_motion.angular.z = 0;
00247 m_headAngles.yaw = 0.0;
00248 m_headAngles.pitch = 0.0;
00249 m_headAngles.absolute = 1.0;
00250
00251 m_lShoulderAngles.yaw=0.0;
00252 m_lShoulderAngles.pitch=0.0;
00253 m_lShoulderAngles.absolute=1.0;
00254
00255 m_rShoulderAngles.yaw=0.0;
00256 m_rShoulderAngles.pitch=0.0;
00257 m_rShoulderAngles.absolute=1.0;
00258
00259 m_lElbowAngles.yaw=0.0;
00260 m_lElbowAngles.pitch=0.0;
00261 m_lElbowAngles.absolute=1.0;
00262
00263 m_rElbowAngles.yaw=0.0;
00264 m_rElbowAngles.pitch=0.0;
00265 m_rElbowAngles.absolute=1.0;
00266
00267
00268 m_movePub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 10);
00269 m_moveBtnPub = nh.advertise<nao_ctrl::MotionCommandBtn>("motion_command_btn", 1);
00270 m_headPub = nh.advertise<nao_ctrl::HeadAngles>("head_angles", 1);
00271 m_speechPub = nh.advertise<std_msgs::String>("speech", 1);
00272 m_lShoulderPub = nh.advertise<nao_ctrl::HeadAngles>("lshoulder_angles",1);
00273 m_rShoulderPub = nh.advertise<nao_ctrl::HeadAngles>("rshoulder_angles",1);
00274 m_lElbowPub = nh.advertise<nao_ctrl::HeadAngles>("lelbow_angles",1);
00275 m_rElbowPub = nh.advertise<nao_ctrl::HeadAngles>("relbow_angles",1);
00276 }
00277
00278
00279
00280
00281 void TeleopNaoNi::pubMsg(){
00282
00283 if (m_enabled){
00284
00285 m_movePub.publish(m_motion);
00286 m_headPub.publish(m_headAngles);
00287 m_lShoulderPub.publish(m_lShoulderAngles);
00288 m_rShoulderPub.publish(m_rShoulderAngles);
00289 m_lElbowPub.publish(m_lElbowAngles);
00290 m_rElbowPub.publish(m_rElbowAngles);
00291 }
00292 }
00293
00294 void stopWalking(TeleopNaoNi &robot){
00295 robot.m_motion.linear.x = robot.m_motion.linear.y = robot.m_motion.angular.z = 0;
00296 }
00297
00298
00299 void XN_CALLBACK_TYPE User_NewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie) {
00300 printf("New User %d\n", nId);
00301
00302 if (g_bNeedPose)
00303 g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
00304 else
00305 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00306 }
00307
00308 void XN_CALLBACK_TYPE User_LostUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie) {
00309
00310 printf("Lost user %d\n", nId);
00311 }
00312
00313 void XN_CALLBACK_TYPE UserCalibration_CalibrationStart(xn::SkeletonCapability& capability, XnUserID nId, void* pCookie) {
00314
00315 printf("Calibration started for user %d\n", nId);
00316 }
00317
00318 void XN_CALLBACK_TYPE UserCalibration_CalibrationEnd(xn::SkeletonCapability& capability, XnUserID nId, XnBool bSuccess, void* pCookie) {
00319 if (bSuccess) {
00320 printf("Calibration complete, start tracking user %d\n", nId);
00321
00322 g_UserGenerator.GetSkeletonCap().StartTracking(nId);
00323 }
00324 else {
00325 printf("Calibration failed for user %d\n", nId);
00326
00327 if (g_bNeedPose)
00328 g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
00329 else
00330 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00331 }
00332 }
00333
00334 void XN_CALLBACK_TYPE UserPose_PoseDetected(xn::PoseDetectionCapability& capability, XnChar const* strPose, XnUserID nId, void* pCookie) {
00335 printf("Pose %s detected for user %d\n", strPose, nId);
00336
00337 g_UserGenerator.GetPoseDetectionCap().StopPoseDetection(nId);
00338 g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
00339 }
00340
00341
00342 XnPoint3D getBodyLoc(XnUserID const& user, XnSkeletonJoint const& eJoint1){
00343 XnPoint3D pt;
00344
00345
00346 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00347 {
00348 printf("not tracked!\n");
00349 pt.X=0.0; pt.Y=0.0; pt.Z=0.0;
00350 return pt;
00351 }
00352
00353
00354 XnSkeletonJointPosition joint1;
00355 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00356
00357
00358 if (joint1.fConfidence < 0.7)
00359 {
00360 pt.X=0.0; pt.Y=0.0; pt.Z=0.0;
00361 return pt;
00362 }
00363
00364 pt = joint1.position;
00365 return pt;
00366 }
00367
00368
00369 float getAngleBetweenLimbs(XnUserID const& user, XnSkeletonJoint const& eJoint1, XnSkeletonJoint const& eJoint2, XnSkeletonJoint const& eJoint3, XnSkeletonJoint const& eJoint4){
00370
00371
00372
00373
00374
00375
00376
00377 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00378 {
00379 printf("not tracked!\n");
00380 return -998.0;
00381 }
00382
00383
00384 XnSkeletonJointPosition joint1, joint2, joint3, joint4;
00385 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00386 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint2, joint2);
00387 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint3, joint3);
00388 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint4, joint4);
00389
00390
00391
00392 if (joint1.fConfidence < 0.6 && joint2.fConfidence < 0.6 && joint3.fConfidence < 0.6 && joint4.fConfidence < 0.6)
00393 {
00394 return -999.0;
00395 }
00396
00397 XnPoint3D pt[4];
00398 pt[0] = joint1.position;
00399 pt[1] = joint2.position;
00400 pt[2] = joint3.position;
00401 pt[3] = joint4.position;
00402
00403 XnVector3D v[2];
00404
00405
00406
00407 v[0].X=pt[2].X-pt[3].X;
00408 v[0].Y=pt[2].Y-pt[3].Y;
00409 v[0].Z=pt[2].Z-pt[3].Z;
00410
00411
00412
00413 v[1].X=pt[0].X-pt[1].X;
00414 v[1].Y=pt[0].Y-pt[1].Y;
00415 v[1].Z=pt[0].Z-pt[1].Z;
00416
00417
00418 float v0_magnitude = sqrt(v[0].X*v[0].X + v[0].Y*v[0].Y + v[0].Z*v[0].Z);
00419 float v1_magnitude = sqrt(v[1].X*v[1].X + v[1].Y*v[1].Y + v[1].Z*v[1].Z);
00420
00421
00422
00423
00424 if(v0_magnitude != 0.0 && v1_magnitude != 0.0){
00425 v[0].X = v[0].X * (1.0/v0_magnitude);
00426 v[0].Y = v[0].Y * (1.0/v0_magnitude);
00427 v[0].Z = v[0].Z * (1.0/v0_magnitude);
00428
00429 v[1].X = v[1].X * (1.0/v1_magnitude);
00430 v[1].Y = v[1].Y * (1.0/v1_magnitude);
00431 v[1].Z = v[1].Z * (1.0/v1_magnitude);
00432
00433
00434
00435 float theta = acos(v[0].X*v[1].X + v[0].Y*v[1].Y + v[0].Z*v[1].Z);
00436 float angle_in_degrees = theta * 180 / my_pi;
00437
00438 return angle_in_degrees;
00439 }
00440 else return -997.0;
00441 }
00442
00443
00444 float getLimbAngle(XnUserID const& user, XnSkeletonJoint const& eJoint1, XnSkeletonJoint const& eJoint2, XnSkeletonJoint const& eJoint3){
00445 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00446 {
00447 printf("not tracked!\n");
00448 return -998.0;
00449 }
00450
00451
00452 XnSkeletonJointPosition joint1, joint2, joint3;
00453 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00454 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint2, joint2);
00455 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint3, joint3);
00456
00457
00458 if (joint1.fConfidence < 0.6 && joint2.fConfidence < 0.6 && joint3.fConfidence < 0.6 )
00459 {
00460 return -999.0;
00461 }
00462
00463 XnPoint3D pt[3];
00464 pt[0] = joint1.position;
00465 pt[1] = joint2.position;
00466 pt[2] = joint3.position;
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 XnVector3D v[2];
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 v[0].X=pt[1].X-pt[2].X;
00487 v[0].Y=pt[1].Y-pt[2].Y;
00488 v[0].Z=pt[1].Z-pt[2].Z;
00489
00490
00491
00492 v[1].X=pt[0].X-pt[1].X;
00493 v[1].Y=pt[0].Y-pt[1].Y;
00494 v[1].Z=pt[0].Z-pt[1].Z;
00495
00496
00497 float v0_magnitude = sqrt(v[0].X*v[0].X + v[0].Y*v[0].Y + v[0].Z*v[0].Z);
00498 float v1_magnitude = sqrt(v[1].X*v[1].X + v[1].Y*v[1].Y + v[1].Z*v[1].Z);
00499
00500
00501
00502 if(v0_magnitude != 0.0 && v1_magnitude != 0.0){
00503 v[0].X = v[0].X * (1.0/v0_magnitude);
00504 v[0].Y = v[0].Y * (1.0/v0_magnitude);
00505 v[0].Z = v[0].Z * (1.0/v0_magnitude);
00506
00507 v[1].X = v[1].X * (1.0/v1_magnitude);
00508 v[1].Y = v[1].Y * (1.0/v1_magnitude);
00509 v[1].Z = v[1].Z * (1.0/v1_magnitude);
00510
00511
00512
00513 float theta = acos(v[0].X*v[1].X + v[0].Y*v[1].Y + v[0].Z*v[1].Z);
00514 float angle_in_degrees = theta * 180 / my_pi;
00515
00516 return angle_in_degrees;
00517 }
00518 else return -997.0;
00519 }
00520
00521
00522
00523 float getTorsoRotation(XnUserID const& user, XnSkeletonJoint const& eJoint1, XnSkeletonJoint const& eJoint2){
00524
00525 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00526 {
00527 printf("not tracked!\n");
00528 return -998.0;
00529 }
00530
00531
00532 XnSkeletonJointPosition joint1, joint2;
00533 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint1, joint1);
00534 g_UserGenerator.GetSkeletonCap().GetSkeletonJointPosition(user, eJoint2, joint2);
00535
00536
00537 if (joint1.fConfidence < 0.6 && joint2.fConfidence < 0.6)
00538 {
00539 return -999.0;
00540 }
00541
00542 XnPoint3D pt[4];
00543 pt[0] = init_usr_LS;
00544 pt[1] = init_usr_RS;
00545 pt[2] = joint1.position;
00546 pt[3] = joint2.position;
00547
00548 XnVector3D v[2];
00549
00550
00551 v[0].X=pt[2].X-pt[3].X;
00552 v[0].Y=pt[2].Y-pt[3].Y;
00553 v[0].Z=pt[2].Z-pt[3].Z;
00554
00555 v[1].X=pt[0].X-pt[1].X;
00556 v[1].Y=pt[0].Y-pt[1].Y;
00557 v[1].Z=pt[0].Z-pt[1].Z;
00558
00559
00560 float v0_magnitude = sqrt(v[0].X*v[0].X + v[0].Y*v[0].Y + v[0].Z*v[0].Z);
00561 float v1_magnitude = sqrt(v[1].X*v[1].X + v[1].Y*v[1].Y + v[1].Z*v[1].Z);
00562
00563
00564
00565
00566 if(v0_magnitude != 0.0 && v1_magnitude != 0.0){
00567 v[0].X = v[0].X * (1.0/v0_magnitude);
00568 v[0].Y = v[0].Y * (1.0/v0_magnitude);
00569 v[0].Z = v[0].Z * (1.0/v0_magnitude);
00570
00571 v[1].X = v[1].X * (1.0/v1_magnitude);
00572 v[1].Y = v[1].Y * (1.0/v1_magnitude);
00573 v[1].Z = v[1].Z * (1.0/v1_magnitude);
00574
00575
00576
00577 float theta = acos(v[0].X*v[1].X + v[0].Y*v[1].Y + v[0].Z*v[1].Z);
00578 float angle_in_degrees = theta * 180 / my_pi;
00579
00580 return angle_in_degrees;
00581 }
00582 else return -997.0;
00583 }
00584
00585 void checkPose(TeleopNaoNi &obj) {
00586 XnUserID users[2];
00587 XnUInt16 users_count = 2;
00588 g_UserGenerator.GetUsers(users, users_count);
00589
00590 for (int i = 0; i < users_count; ++i) {
00591 XnUserID user = users[i];
00592 if (!g_UserGenerator.GetSkeletonCap().IsTracking(user))
00593 continue;
00594
00595
00596
00597
00598
00599
00600 float right_limb_angle = getLimbAngle(user, XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_KNEE, XN_SKEL_RIGHT_FOOT);
00601
00602
00603
00604
00605 float left_limb_angle = getLimbAngle(user, XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_KNEE, XN_SKEL_LEFT_FOOT);
00606
00607
00608
00609 float left_elbow_angle = getLimbAngle(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND);
00610
00611
00612 XnPoint3D current_bl = getBodyLoc(user, XN_SKEL_TORSO);
00613
00614
00615 if(obj.m_enabled && obj.m_teleopEnabled){
00616 if( (left_control_line <=current_bl.X) && (current_bl.X<=left_safe_line )){
00617
00618 obj.m_motion.linear.y = walking_speed;
00619 }
00620 else if( (right_control_line>=current_bl.X) && (current_bl.X>=right_safe_line) ){
00621
00622 obj.m_motion.linear.y = -walking_speed;
00623 }
00624 else if( (left_safe_line<=current_bl.X) && (current_bl.X<=right_safe_line)){
00625
00626 obj.m_motion.linear.y = 0.0;
00627 }
00628
00629 if( (anterior_control_line<=current_bl.Z) && (current_bl.Z<=anterior_safe_line)){
00630
00631 obj.m_motion.linear.x = walking_speed;
00632 }
00633 else if( (posterior_safe_line<=current_bl.Z) && (current_bl.Z<=posterior_control_line)){
00634
00635 obj.m_motion.linear.x = -walking_speed;
00636 }
00637 else if( (anterior_safe_line<=current_bl.Z) && (current_bl.Z<=posterior_safe_line)){
00638
00639 obj.m_motion.linear.x = 0.0;
00640 }
00641
00642
00643
00644 XnPoint3D current_ls = getBodyLoc(user, XN_SKEL_LEFT_SHOULDER);
00645 XnPoint3D current_rs = getBodyLoc(user, XN_SKEL_RIGHT_SHOULDER);
00646
00647
00648 float current_angle = getTorsoRotation(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_RIGHT_SHOULDER)*my_pi/180.0;
00649
00650
00651 if( (control_rot>=current_angle) && (current_angle>=safety_rot)){
00652 if((current_rs.Z+100.0) < current_ls.Z){
00653 obj.m_motion.angular.z = rotating_speed;
00654
00655 }
00656 else if(current_rs.Z > (current_ls.Z+100.0)){
00657 obj.m_motion.angular.z = -1.0*rotating_speed;
00658
00659 }
00660 }
00661 else if(safety_rot>=current_angle && current_angle>=0.0 ){
00662 obj.m_motion.angular.z = 0.0;
00663 }
00664
00665
00666 float lsap = getLimbAngle(user, XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW)*my_pi/180.0;
00667 lsap = lsap - 1.6;
00668 if(lsap>=-2.0 && lsap<=2.0){
00669 obj.m_lShoulderAngles.pitch = lsap;
00670 }
00671
00672
00673
00674 float lear = getLimbAngle(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND)*my_pi/180.0;
00675 lear = -1*lear;
00676 if(lear>=-1.55 && lear<=-0.01){
00677 obj.m_lElbowAngles.pitch = lear;
00678 }
00679
00680
00681 float leay = getAngleBetweenLimbs(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND)*my_pi/180.0;
00682
00683
00684
00685 leay = 1.57 - leay;
00686 if(2.0>=leay && leay>=-2.0){
00687 obj.m_lElbowAngles.yaw = leay;
00688 }
00689
00690
00691 float rsap = getLimbAngle(user, XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW)*my_pi/180.0;
00692 rsap = rsap - 1.6;
00693 if(rsap>=-2.0 && rsap<=2.0){
00694 obj.m_rShoulderAngles.pitch = rsap;
00695 }
00696
00697
00698
00699 float rear = getLimbAngle(user, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND)*my_pi/180.0;
00700 if(1.55>=rear && rear>=0.01){
00701 obj.m_rElbowAngles.pitch = rear;
00702 }
00703
00704
00705 float reay = getAngleBetweenLimbs(user, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND)*my_pi/180.0;
00706 reay = reay - 1.57;
00707 if(2.0>=reay && reay>=-2.0){
00708 obj.m_rElbowAngles.yaw = reay;
00709 }
00710
00711
00712 float rsar = getAngleBetweenLimbs(user, XN_SKEL_RIGHT_HIP, XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW)*my_pi/180.0;
00713
00714
00715
00716 rsar = 1.63 - rsar;
00717 if(-0.01>=rsar && rsar>=-1.63){
00718 obj.m_rShoulderAngles.yaw = rsar;
00719 }
00720
00721
00722 float lsar = getAngleBetweenLimbs(user, XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_HIP, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW)*my_pi/180.0;
00723
00724
00725 lsar = lsar - 1.57;
00726 if(1.63>=lsar && lsar>=0.01){
00727 obj.m_lShoulderAngles.yaw = lsar;
00728 }
00729 }
00730
00731
00732 if(obj.m_enabled && obj.m_attentionEnabled){
00733
00734
00735 float leay = getAngleBetweenLimbs(user, XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND);
00736
00737
00738 if(left_elbow_angle>=87.0 && left_elbow_angle<=93.0 && leay >= 135.0){
00739
00740
00741 if(obj.m_commandEnabled){
00742 obj.m_commandEnabled = false;
00743 stopWalking(obj);
00744 printf("Command Mode OFF, Back to attention mode\n");
00745 naosay.data="mission accomplished";
00746 }
00747
00748 else{
00749 obj.m_commandEnabled = true;
00750 printf("Command Mode ON, Walking towards target\n");
00751 naosay.data="as you wish";
00752 }
00753 ros::Duration(2.0).sleep();
00754 }
00755 }
00756
00757
00758 if(obj.m_enabled && obj.m_commandEnabled){
00759
00760
00761
00762 float counter = floor(obj.m_headAngles.yaw / rot_constant);
00763 if (counter>0.0){
00764 obj.m_motion.angular.z = rotating_speed;
00765 obj.m_headAngles.yaw -= rot_constant;
00766 }
00767 else if (counter<0.0){
00768 obj.m_motion.angular.z = -rotating_speed;
00769 obj.m_headAngles.yaw += rot_constant;
00770 }
00771 else if (counter == 0.0){
00772 obj.m_motion.angular.z = 0.0;
00773 obj.m_motion.linear.x = walking_speed;
00774 }
00775 }
00776
00777
00778
00779 if(obj.m_enabled && obj.m_attentionEnabled && !obj.m_commandEnabled){
00780
00781
00782 float hay = getAngleBetweenLimbs(user, XN_SKEL_RIGHT_HIP, XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND)*my_pi/180.0;
00783 hay = hay - 1.57;
00784 if(2.0>=hay && hay>=-2.0){
00785 obj.m_headAngles.yaw = hay;
00786 }
00787
00788
00789 float hap = getAngleBetweenLimbs(user, XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND)*my_pi/180.0;
00790 hap = 0.5 - hap;
00791 if(0.5>=hay && hay>=-0.66){
00792 obj.m_headAngles.pitch = hap;
00793 }
00794 obj.m_headAngles.absolute = 1.0;
00795 }
00796
00797
00798
00799
00800 if ((right_limb_angle>=87.0) && (right_limb_angle<=93) ){
00801 if(obj.m_teleopEnabled){
00802 obj.m_teleopEnabled = false;
00803 obj.m_attentionEnabled = true;
00804 naosay.data = "Attention mode";
00805 printf("Teleop OFF, Attention ON\n");
00806 }
00807 else{
00808 obj.m_teleopEnabled = true;
00809 obj.m_attentionEnabled = false;
00810 naosay.data = "Tele operation mode";
00811 printf("Teleop ON, Attention OFF\n");
00812 }
00813 ros::Duration(2.0).sleep();
00814
00815 }
00816
00817
00818
00819
00820 if((left_limb_angle>=87.0) && (left_limb_angle<=93)){
00821 if(obj.m_enabled){
00822 obj.m_enabled = false;
00823 naosay.data = "Motors off";
00824 printf("Motors OFF\n");
00825
00826 nao_ctrl::MotionCommandBtn motionCmd;
00827 motionCmd.button = nao_ctrl::MotionCommandBtn::crouchNoStiff;
00828 obj.m_moveBtnPub.publish(motionCmd);
00829 }
00830 else{
00831 obj.m_enabled = true;
00832
00833 naosay.data = "Motors on";
00834 printf("Motors ON\n");
00835
00836 ros::Duration(0.2).sleep();
00837
00838 nao_ctrl::MotionCommandBtn motionCmd;
00839 motionCmd.button = nao_ctrl::MotionCommandBtn::stiffnessOn;
00840 obj.m_moveBtnPub.publish(motionCmd);
00841
00842 ros::Duration(0.2).sleep();
00843
00844 motionCmd.button = nao_ctrl::MotionCommandBtn::initPose;
00845 obj.m_moveBtnPub.publish(motionCmd);
00846
00847 init_usr_loc = getBodyLoc(user, XN_SKEL_TORSO);
00848
00849
00850 anterior_safe_line = init_usr_loc.Z - safety_dist;
00851 posterior_safe_line = init_usr_loc.Z + safety_dist;
00852
00853 right_safe_line = init_usr_loc.X + safety_dist;
00854 left_safe_line = init_usr_loc.X - safety_dist;
00855
00856
00857 anterior_control_line = anterior_safe_line - control_dist;
00858 posterior_control_line = posterior_safe_line + control_dist;
00859
00860 right_control_line = right_safe_line + control_dist;
00861 left_control_line = left_safe_line - control_dist;
00862
00863
00864 init_usr_RS = getBodyLoc(user,XN_SKEL_RIGHT_SHOULDER);
00865 init_usr_LS = getBodyLoc(user,XN_SKEL_LEFT_SHOULDER);
00866
00867 }
00868 ros::Duration(2.0).sleep();
00869 }
00870
00871 if (naosay.data != ""){
00872 obj.m_speechPub.publish(naosay);
00873 naosay.data="";
00874 }
00875
00876 }
00877
00878 }
00879
00880 int main(int argc, char** argv)
00881 {
00882
00883 ros::init(argc, argv, "teleop_nao_ni");
00884
00885 TeleopNaoNi teleopNao;
00886 naosay.data="";
00887 string configFilename = ros::package::getPath("nao_openni") + "/openni_tracker.xml";
00888
00889
00890 double publishRate = 5.0;
00891 teleopNao.privateNh.param("motion_publish_rate", publishRate, publishRate);
00892 ros::Rate pubRate(publishRate);
00893
00894 unsigned char state=0;
00895
00896
00897
00898 XnStatus nRetVal = g_Context.InitFromXmlFile(configFilename.c_str());
00899 CHECK_RC(nRetVal, "InitFromXml");
00900
00901 nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator);
00902 CHECK_RC(nRetVal, "Find depth generator");
00903
00904 nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_USER, g_UserGenerator);
00905 if (nRetVal != XN_STATUS_OK) {
00906 nRetVal = g_UserGenerator.Create(g_Context);
00907 CHECK_RC(nRetVal, "Find user generator");
00908 }
00909
00910 if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) {
00911 printf("Supplied user generator doesn't support skeleton\n");
00912 return 1;
00913 }
00914
00915 XnCallbackHandle hUserCallbacks;
00916 g_UserGenerator.RegisterUserCallbacks(User_NewUser, User_LostUser, NULL, hUserCallbacks);
00917
00918 XnCallbackHandle hCalibrationCallbacks;
00919 g_UserGenerator.GetSkeletonCap().RegisterCalibrationCallbacks(UserCalibration_CalibrationStart, UserCalibration_CalibrationEnd, NULL, hCalibrationCallbacks);
00920
00921 if (g_UserGenerator.GetSkeletonCap().NeedPoseForCalibration()) {
00922 g_bNeedPose = TRUE;
00923 if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) {
00924 printf("Pose required, but not supported\n");
00925 return 1;
00926 }
00927
00928 XnCallbackHandle hPoseCallbacks;
00929 g_UserGenerator.GetPoseDetectionCap().RegisterToPoseCallbacks(UserPose_PoseDetected, NULL, NULL, hPoseCallbacks);
00930
00931 g_UserGenerator.GetSkeletonCap().GetCalibrationPose(g_strPose);
00932 }
00933
00934 g_UserGenerator.GetSkeletonCap().SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
00935
00936 nRetVal = g_Context.StartGeneratingAll();
00937 CHECK_RC(nRetVal, "StartGenerating");
00938
00939
00940
00941 while(teleopNao.nh.ok()){
00942
00943
00944
00945
00946
00947
00948
00949
00950 if (state == 0){
00951
00952 teleopNao.m_enabled = true;
00953 naosay.data = "Control enabled";
00954 nao_ctrl::MotionCommandBtn motionCmd;
00955 motionCmd.button = nao_ctrl::MotionCommandBtn::stiffnessOn;
00956 teleopNao.m_moveBtnPub.publish(motionCmd);
00957 state++;
00958 }
00959 else if (state == 1){
00960
00961 naosay.data = "Stiffness removed";
00962 nao_ctrl::MotionCommandBtn motionCmd;
00963 motionCmd.button = nao_ctrl::MotionCommandBtn::stiffnessOff;
00964 teleopNao.m_moveBtnPub.publish(motionCmd);
00965 state++;
00966
00967 }
00968 else if (state == 2){
00969
00970 teleopNao.m_enabled = false;
00971 naosay.data = "Control disabled";
00972 state++;
00973 }
00974
00975 if (naosay.data != ""){
00976 teleopNao.m_speechPub.publish(naosay);
00977 naosay.data="";
00978 }
00979
00980 g_Context.WaitAndUpdateAll();
00981
00982 checkPose(teleopNao);
00983
00984 teleopNao.pubMsg();
00985
00986 pubRate.sleep();
00987 }
00988
00989 g_Context.Shutdown();
00990 return 0;
00991
00992 }