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 #include <boost/thread/thread.hpp>
00041 #include <boost/thread/mutex.hpp>
00042 #include <boost/thread/condition.hpp>
00043
00044 #include <ros/ros.h>
00045 #include <tf/transform_listener.h>
00046 #include <sensor_msgs/PointCloud.h>
00047 #include <mapping_msgs/PolygonalMap.h>
00048 #include <body_msgs/Hands.h>
00049 #include <sensor_msgs/point_cloud_conversion.h>
00050 #include <pcl_tools/pcl_utils.h>
00051 #include <nnn/nnn.hpp>
00052 #include <pcl_tools/segfast.hpp>
00053
00054
00055 #include "pcl/io/pcd_io.h"
00056 #include "pcl/point_types.h"
00057 #include <pcl/ModelCoefficients.h>
00058
00059 #include <pcl/io/pcd_io.h>
00060 #include <pcl/point_types.h>
00061
00062 #include <pcl/features/normal_3d.h>
00063
00064 #include <pcl/filters/extract_indices.h>
00065 #include <pcl/filters/passthrough.h>
00066
00067 #include <pcl/sample_consensus/method_types.h>
00068 #include <pcl/sample_consensus/model_types.h>
00069 #include <pcl/segmentation/sac_segmentation.h>
00070
00071
00072 #include <body_msgs/Skeletons.h>
00073
00074 #include <turtlesim/Velocity.h>
00075
00076
00077 #define MAX(A, B) ((A) > (B) ? (A) : (B))
00078 #define MIN(A, B) ((A) < (B) ? (A) : (B))
00079 #define ABS(A) (((A) < 0) ? (-(A)) : (A))
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define HEADPOS 0
00091 #define LHANDPOS (HEADPOS+1)
00092 #define RHANDPOS (LHANDPOS+1)
00093 #define NECKPOS (RHANDPOS+1)
00094 #define RIGHT_SHOULDERPOS (NECKPOS+1)
00095 #define LEFT_SHOULDERPOS (RIGHT_SHOULDERPOS+1)
00096 #define RIGHT_ELBOWPOS (LEFT_SHOULDERPOS+1)
00097 #define LEFT_ELBOWPOS (RIGHT_ELBOWPOS+1)
00098 #define TORSOPOS (LEFT_ELBOWPOS+1)
00099 #define LEFT_HIPPOS (TORSOPOS+1)
00100 #define RIGHT_HIPPOS (LEFT_HIPPOS+1)
00101 #define LEFT_KNEEPOS (RIGHT_HIPPOS+1)
00102 #define RIGHT_KNEEPOS (LEFT_KNEEPOS+1)
00103 #define LEFT_FOOTPOS (RIGHT_KNEEPOS+1)
00104 #define RIGHT_FOOTPOS (LEFT_FOOTPOS+1)
00105
00106
00107
00108 #define SKEL_POINTS (RIGHT_FOOTPOS+1)
00109 #define UNDEFINED 99
00110
00111
00112 #define HANDSTOGETHER 100
00113
00114
00115
00116
00117
00119
00122 typedef struct {
00123 uint state1;
00124 uint state2;
00125 uint state3;
00126 uint state4;
00127 uint state5;
00128 uint state6;
00129 uint state7;
00130 uint state8;
00131 uint state9;
00132 uint state10;
00133 uint full;
00134
00135
00136 }stateMachine;
00137
00138 stateMachine rightState, leftState;
00139
00140 int CALIB_FLAG = 0;
00141 int LHAND_FLAG = 0;
00142 int RECOG_FLAG = 1;
00143 int tRecogCounter = 0;
00144 int STATE_BEFORE = -1;
00145 int turtlePubCounter =0;
00146 int DIST_FLAG = 0;
00147 int distCounter=0;
00148
00149 class TimeEvaluator{
00150 timeval tmark;
00151 std::vector<double> times;
00152 std::vector<std::string> eventnames;
00153 std::string name;
00154
00155
00156 public:
00158 TimeEvaluator(std::string _name="Time Evaluator"){
00159 name=_name;
00160
00161
00162 gettimeofday(&tmark, NULL);
00163
00164 }
00165
00166
00167
00168
00169
00171 void mark(std::string _name=""){
00172
00173 if(_name.size())
00174 eventnames.push_back(_name);
00175 else{
00176 int count=eventnames.size();
00177 char tname[10];
00178 sprintf(tname,"E%d",count);
00179 eventnames.push_back(std::string(tname));
00180 }
00181
00182 struct timeval tv;
00183 gettimeofday(&tv, NULL);
00184 times.push_back((double)(tv.tv_sec-tmark.tv_sec) + (tv.tv_usec-tmark.tv_usec)/1000000.0);
00185 }
00186
00188 void print(){
00189 std::cout<<name;
00190 for(uint i=0;i<times.size();++i)
00191 std::cout<<" "<<eventnames[i]<<": "<< std::setprecision (5) << times[i];
00192 std::cout<<std::endl;
00193 }
00194
00195
00196
00197
00198 };
00199
00200
00201
00202
00203
00204
00205 float gdist(pcl::PointXYZ pt, const Eigen::Vector4f &v){
00206 return sqrt((pt.x-v(0))*(pt.x-v(0))+(pt.y-v(1))*(pt.y-v(1))+(pt.z-v(2))*(pt.z-v(2)));
00207 }
00208
00209 void flipvec(const Eigen::Vector4f &palm, const Eigen::Vector4f &fcentroid,Eigen::Vector4f &dir ){
00210 if((fcentroid-palm).dot(dir) <0)
00211 dir=dir*-1.0;
00212
00213 }
00214
00215 template <typename Point1, typename Point2>
00216 void PointConversion(Point1 pt1, Point2 &pt2){
00217 pt2.x=pt1.x;
00218 pt2.y=pt1.y;
00219 pt2.z=pt1.z;
00220 }
00221
00222
00223 geometry_msgs::Point32 eigenToMsgPoint32(const Eigen::Vector4f &v){
00224 geometry_msgs::Point32 p;
00225 p.x=v(0); p.y=v(1); p.z=v(2);
00226 return p;
00227 }
00228 geometry_msgs::Point eigenToMsgPoint(const Eigen::Vector4f &v){
00229 geometry_msgs::Point p;
00230 p.x=v(0); p.y=v(1); p.z=v(2);
00231 return p;
00232 }
00233
00234 pcl::PointXYZ eigenToPclPoint(const Eigen::Vector4f &v){
00235 pcl::PointXYZ p;
00236 p.x=v(0); p.y=v(1); p.z=v(2);
00237 return p;
00238 }
00239
00240
00241 geometry_msgs::Transform pointToTransform(geometry_msgs::Point p){
00242 geometry_msgs::Transform t;
00243 t.translation.x=p.x; t.translation.y=p.y; t.translation.z=p.z;
00244 return t;
00245 }
00246
00247
00248
00249
00250 pcl::PointXYZ pointToPclPoint(geometry_msgs::Point p){
00251 pcl::PointXYZ p1;
00252 p1.x=p.x; p1.y=p.y; p1.z=p.z;
00253 return p1;
00254 }
00255
00256
00257
00258 pcl::PointXYZ addVector(const Eigen::Vector4f &_C, geometry_msgs::Point A, geometry_msgs::Vector3 B, double scale){
00259 Eigen::Vector4f C=_C;
00260 C(0)+=scale*(B.x-A.x);
00261 C(1)+=scale*(B.y-A.y);
00262 C(2)+=scale*(B.z-A.z);
00263 return eigenToPclPoint(C);
00264 }
00265
00266
00267 bool isJointGood(body_msgs::SkeletonJoint &joint){
00268 if(joint.confidence < 0.5)
00269 return false;
00270 else
00271 return true;
00272 }
00273
00274 void getEigens(body_msgs::Hand &h){
00275
00276 pcl::PointCloud<pcl::PointXYZ> cloud;
00277 Eigen::Vector4f centroid, direction,armvector;
00278 pcl::fromROSMsg(h.handcloud,cloud);
00279
00280 EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
00281 EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
00282 Eigen::Matrix3f cov;
00283 pcl::compute3DCentroid (cloud, centroid);
00284 pcl::computeCovarianceMatrixNormalized(cloud,centroid,cov);
00285 pcl::eigen33 (cov, eigen_vectors, eigen_values);
00286 direction(0)=eigen_vectors (0, 2);
00287 direction(1)=eigen_vectors (1, 2);
00288 direction(2)=eigen_vectors (2, 2);
00289 armvector(0)=h.arm.x; armvector(1)=h.arm.y; armvector(2)=h.arm.z;
00290 flipvec(armvector,centroid,direction);
00291
00292 if(eigen_values(1)/eigen_values(2) < .4)
00293 h.state=std::string("Saka zatvorena");
00294 else
00295 h.state=std::string("Saka otvorena");
00296
00297
00298
00299
00300
00301
00302
00303
00304 }
00305
00306
00308
00312 void getHandCloud(body_msgs::Hand &hand, sensor_msgs::PointCloud2 &fullcloud){
00313 pcl::PointCloud<pcl::PointXYZ> handcloud,cloudin;
00314
00315 pcl::fromROSMsg(fullcloud,cloudin);
00316
00317 std::vector<int> inds;
00318 Eigen::Vector4f handcentroid;
00319 pcl::PointXYZ handpos;
00320
00321 PointConversion(hand.palm.translation,handpos);
00322
00323
00324
00325
00326
00327 NNN(cloudin,handpos,inds, .1);
00328
00329
00330
00331
00332
00333
00334 for(int i=0; i<3;i++){
00335 pcl::compute3DCentroid(cloudin,inds,handcentroid);
00336 handpos=addVector(handcentroid,hand.arm,hand.palm.translation,.05);
00337 NNN(cloudin,handpos,inds, .1);
00338 }
00339
00340
00341 getSubCloud(cloudin,inds,handcloud);
00342
00343
00344 pcl::toROSMsg(handcloud,hand.handcloud);
00345 PointConversion(handpos,hand.palm.translation);
00346
00347
00348 hand.state="unprocessed";
00349 getEigens(hand);
00350
00351 hand.thumb=-1;
00352 hand.stamp=fullcloud.header.stamp;
00353 hand.handcloud.header=fullcloud.header;
00354
00355
00356 }
00357
00358
00360
00361 void getHandPos(body_msgs::Hand &hand, pcl::PointXYZ &hand1,char a){
00362
00363 pcl::PointXYZ handpos;
00364
00365 PointConversion(hand.palm.translation,handpos);
00366 hand1.x=handpos.x;
00367 hand1.y=handpos.y;
00368 hand1.z=handpos.z;
00369
00370 if(a=='r'){
00371 printf("[Det_H_w_SK]got RIGHT hand with coordinates%.02f, %02f, %02f ",handpos.x, handpos.y,handpos.z);
00372 }
00373 else{
00374 printf("[Det_H_w_SK]got LEFT hand with coordinates%.02f, %02f, %02f ",handpos.x, handpos.y,handpos.z);
00375 }
00376
00377
00378
00379 }
00380
00381 void getHandPos(body_msgs::Hand &hand, pcl::PointXYZ &hand1){
00382
00383 pcl::PointXYZ handpos;
00384
00385 PointConversion(hand.palm.translation,handpos);
00386 hand1.x=handpos.x;
00387 hand1.y=handpos.y;
00388 hand1.z=handpos.z;
00389
00390
00391
00392
00393
00394
00395
00396 }
00397
00399
00404 void getHands(body_msgs::Skeleton &skel, sensor_msgs::PointCloud2 &cloud, body_msgs::Hands &handsmsg ){
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 if(isJointGood(skel.left_hand)){
00426 body_msgs::Hand lhand;
00427
00428 lhand.arm=skel.left_elbow.position;
00429 lhand.palm=pointToTransform(skel.left_hand.position);
00430 getHandCloud(lhand,cloud);
00431
00432 handsmsg.hands.push_back(lhand);
00433 handsmsg.hands.back().left=true;
00434 }
00435
00436 if(isJointGood(skel.right_hand)){
00437 body_msgs::Hand rhand;
00438
00439 rhand.arm=skel.right_elbow.position;
00440 rhand.palm=pointToTransform(skel.right_hand.position);
00441 getHandCloud(rhand,cloud);
00442
00443 handsmsg.hands.push_back(rhand);
00444 handsmsg.hands.back().left=false;
00445 }
00446
00447 }
00448
00449 void getHands(body_msgs::Skeleton &skel, sensor_msgs::PointCloud2 &cloud, body_msgs::Hands &handsmsg, std::pair<pcl::PointXYZ,pcl::PointXYZ> &var, std::pair<pcl::PointXYZ,pcl::PointXYZ> &shoulders){
00450
00451
00452
00453 if(isJointGood(skel.left_hand)){
00454 body_msgs::Hand lhand;
00455
00456 lhand.arm=skel.left_elbow.position;
00457 lhand.palm=pointToTransform(skel.left_hand.position);
00458 getHandCloud(lhand,cloud);
00459 getHandPos(lhand,var.first);
00460 handsmsg.hands.push_back(lhand);
00461 handsmsg.hands.back().left=true;
00462 }
00463
00464 if(isJointGood(skel.right_hand)){
00465 body_msgs::Hand rhand;
00466
00467 rhand.arm=skel.right_elbow.position;
00468 rhand.palm=pointToTransform(skel.right_hand.position);
00469 getHandCloud(rhand,cloud);
00470 getHandPos(rhand,var.second);
00471 handsmsg.hands.push_back(rhand);
00472 handsmsg.hands.back().left=false;
00473 }
00474
00475
00476
00477
00478
00479 if(isJointGood(skel.left_shoulder)){
00480 body_msgs::Hand thand;
00481
00482 thand.palm=pointToTransform(skel.left_shoulder.position);
00483 getHandPos(thand,shoulders.first);
00484 }
00485
00486 if(isJointGood(skel.right_shoulder)){
00487 body_msgs::Hand thand;
00488 thand.palm=pointToTransform(skel.right_shoulder.position);
00489 getHandPos(thand,shoulders.second);
00490 }
00491
00492 }
00493
00494
00495 bool pointComparisonHands( pcl::PointXYZ a ,pcl::PointXYZ b){
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 if(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z))<0.09){
00508 return true;
00509 }
00510 else {
00511 return false;
00512 }
00513
00514
00515 }
00516
00517 bool pointComparisonHead( pcl::PointXYZ a ,pcl::PointXYZ b){
00518
00519
00520 if(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))<0.09){
00521
00522 return true;
00523 }
00524 else {
00525
00526 return false;
00527 }
00528
00529
00530 }
00531
00532 bool pointComparison( pcl::PointXYZ a ,pcl::PointXYZ b){
00533
00534
00535 if(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))<0.06){
00536
00537 return true;
00538 }
00539 else {
00540
00541 return false;
00542 }
00543
00544
00545 }
00546 void cleanState(stateMachine &state){
00547
00548 state.state1=UNDEFINED;
00549 state.state2=UNDEFINED;
00550 state.state3=UNDEFINED;
00551 state.state4=UNDEFINED;
00552 state.state5=UNDEFINED;
00553 state.state6=UNDEFINED;
00554 state.state7=UNDEFINED;
00555 state.state8=UNDEFINED;
00556 state.state9=UNDEFINED;
00557 state.state10=UNDEFINED;
00558 state.full=0;
00559
00560
00561 }
00562
00563 void eventState(stateMachine &state, uint a){
00564
00565 if(a==HEADPOS){
00566 printf("Clean state machine \n");
00567 cleanState(state);
00568 }
00569
00570 if(a==HANDSTOGETHER){
00571 if(state.state1==UNDEFINED)
00572 printf("HANDSTOGETHER \n ");
00573 state.state1=a;
00574 }
00575 if(a==LEFT_SHOULDERPOS && state.state1==HANDSTOGETHER){
00576
00577 CALIB_FLAG = 1;
00578 RECOG_FLAG = 0;
00579 printf("Usli u calib flag\n");
00580 cleanState(state);
00581
00582 }
00583
00584 if(a==LEFT_ELBOWPOS && state.state1==HANDSTOGETHER){
00585 LHAND_FLAG =!LHAND_FLAG;
00586 printf("LHAND %d",LHAND_FLAG);
00587 cleanState(state);
00588 }
00589 if(a==LEFT_HIPPOS && state.state1==HANDSTOGETHER){
00590 DIST_FLAG = 1;
00591 RECOG_FLAG = 0;
00592 CALIB_FLAG = 0 ;
00593 cleanState(state);
00594 }
00595 }
00596
00597
00598
00600
00608 class HandDetector
00609 {
00610
00611 typedef struct {
00612 bool isCalibrated;
00613 float maxRight,maxLeft;
00614 float maxHands;
00615 } calibrationBundle;
00616
00617 private:
00618 ros::NodeHandle n_;
00619 ros::Publisher cloudpub_[2],handspub_;
00620 ros::Subscriber cloudsub_,skelsub_;
00621 std::string fixedframe;
00622
00623
00624
00625 ros::NodeHandle nh_;
00626 double linear_, angular_, l_scale_, a_scale_;
00627 ros::Publisher vel_pub_;
00628 turtlesim::Velocity vel;
00629 float left_pub,right_pub, height_pub;
00630
00631
00632 body_msgs::Skeletons skelmsg;
00633 sensor_msgs::PointCloud2 pcloudmsg;
00634 int lastskelseq, lastcloudseq;
00635 int calibNum;
00636 vector<calibrationBundle> calibData;
00637 calibrationBundle calib;
00638 pcl::PointXYZ skelpos[SKEL_POINTS] ;
00639 bool isJoint[SKEL_POINTS];
00640
00641
00642
00643
00644
00645 pair <pcl::PointXYZ,pcl::PointXYZ> ruke,ramena;
00646
00647
00648 public:
00649
00650 HandDetector()
00651 {
00652 handspub_ = n_.advertise<body_msgs::Hands> ("hands", 1);
00653 cloudpub_[0] = n_.advertise<sensor_msgs::PointCloud2> ("hand0_fullcloud", 1);
00654 cloudpub_[1] = n_.advertise<sensor_msgs::PointCloud2> ("hand1_fullcloud", 1);
00655 cloudsub_=n_.subscribe("/camera/rgb/points", 1, &HandDetector::cloudcb, this);
00656 skelsub_=n_.subscribe("/skeletons", 1, &HandDetector::skelcb, this);
00657 lastskelseq=0;
00658 lastcloudseq=0;
00659 skelmsg.header.seq=0;
00660 pcloudmsg.header.seq=0;
00661 calibNum=0;
00662
00663
00664
00665
00666 l_scale_= 2.0;
00667 a_scale_= 2.0;
00668 nh_.param("scale_angular", a_scale_, a_scale_);
00669 nh_.param("scale_linear", l_scale_, l_scale_);
00670
00671 vel_pub_ = nh_.advertise<turtlesim::Velocity>("turtle1/command_velocity", 1);
00672 }
00673
00674
00675 float calcDist(float a, float b ){
00676 return sqrt((a-b)*(a-b));
00677 }
00678
00679 float calcPercVal(float a,float b){
00680 float c;
00681 c= a/b;
00682 if (c>1.0) return 1.0;
00683 else return c;
00684 }
00685
00686 void armCalibration( calibrationBundle &c,std::pair<pcl::PointXYZ,pcl::PointXYZ> hands, std::pair<pcl::PointXYZ,pcl::PointXYZ> shoulders){
00687
00688 c.maxLeft = calcDist(hands.first.x, shoulders.first.x);
00689 c.maxRight = calcDist(hands.second.x, shoulders.second.x);
00690 c.maxHands = calcDist(hands.first.y, shoulders.first.y);
00691 printf(".\n");
00692
00693
00694 }
00695
00696
00697 void armCalculationTurtlePub(float &l, float &r, float &h){
00698
00699 float rightCalc,leftCalc, heightCalc;
00700
00701
00702
00703 leftCalc =calcDist(skelpos[LHANDPOS].x, skelpos[LEFT_SHOULDERPOS].x);
00704
00705 heightCalc=calcDist(skelpos[LHANDPOS].y, skelpos[LEFT_SHOULDERPOS].y);
00706
00707 rightCalc =calcDist(skelpos[RHANDPOS].x, skelpos[RIGHT_SHOULDERPOS].x);
00708
00709
00710 l =calcPercVal(leftCalc,calib.maxRight);
00711 r =calcPercVal(rightCalc,calib.maxLeft);
00712 h =calcPercVal(heightCalc,calib.maxHands);
00713
00714 if(skelpos[LHANDPOS].y>0){h=h*(-1);}
00715 if((skelpos[RHANDPOS].y>skelpos[RIGHT_HIPPOS].y) &&(skelpos[LHANDPOS].y>skelpos[LEFT_HIPPOS].y)){h=0;}
00716
00717
00718
00719
00720 }
00721
00722 void getInfoStateMachine(body_msgs::Skeleton &skel, body_msgs::Hands &handsmsg, pcl::PointXYZ* skelpos, bool* isJoint){
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 body_msgs::Hand temphand;
00755
00756 if(isJointGood(skel.head)){
00757 isJoint[HEADPOS]=true;
00758 temphand.palm=pointToTransform(skel.head.position);
00759 getHandPos(temphand,skelpos[HEADPOS]);
00760
00761
00762 } else isJoint[HEADPOS]=false;
00763
00764
00765
00766
00767
00768
00769
00770 isJoint[NECKPOS]=false;
00771
00772 if(isJointGood(skel.left_hand)){
00773 isJoint[LHANDPOS]=true;
00774 temphand.palm=pointToTransform(skel.left_hand.position);
00775 getHandPos(temphand,skelpos[LHANDPOS]);
00776
00777
00778 }else isJoint[LHANDPOS]=false;
00779
00780
00781 if(isJointGood(skel.right_hand)){
00782 isJoint[RHANDPOS]=true;
00783 temphand.palm=pointToTransform(skel.right_hand.position);
00784 getHandPos(temphand,skelpos[RHANDPOS]);
00785
00786
00787 }else isJoint[RHANDPOS]=false;
00788
00789 if(isJointGood(skel.right_shoulder)){
00790 isJoint[RIGHT_SHOULDERPOS]=true;
00791 temphand.palm=pointToTransform(skel.right_shoulder.position);
00792 getHandPos(temphand,skelpos[RIGHT_SHOULDERPOS]);
00793
00794
00795 }else isJoint[RIGHT_SHOULDERPOS]=false;
00796
00797 if(isJointGood(skel.left_shoulder)){
00798 isJoint[LEFT_SHOULDERPOS]=true;
00799 temphand.palm=pointToTransform(skel.left_shoulder.position);
00800 getHandPos(temphand,skelpos[LEFT_SHOULDERPOS]);
00801
00802
00803 }else isJoint[LEFT_SHOULDERPOS]=false;
00804
00805 if(isJointGood(skel.right_elbow)){
00806 isJoint[RIGHT_ELBOWPOS]=true;
00807 temphand.palm=pointToTransform(skel.right_elbow.position);
00808 getHandPos(temphand,skelpos[RIGHT_ELBOWPOS]);
00809
00810
00811 }else isJoint[RIGHT_ELBOWPOS]=false;
00812
00813 if(isJointGood(skel.left_elbow)){
00814 isJoint[LEFT_ELBOWPOS]=true;
00815 temphand.palm=pointToTransform(skel.left_elbow.position);
00816 getHandPos(temphand,skelpos[LEFT_ELBOWPOS]);
00817
00818
00819 }else isJoint[LEFT_ELBOWPOS]=false;
00820
00821 if(isJointGood(skel.torso)){
00822 isJoint[TORSOPOS]=true;
00823 temphand.palm=pointToTransform(skel.torso.position);
00824 getHandPos(temphand,skelpos[TORSOPOS]);
00825
00826
00827 }else isJoint[TORSOPOS]=false;
00828
00829 if(isJointGood(skel.left_hip)){
00830 isJoint[LEFT_HIPPOS]=true;
00831 temphand.palm=pointToTransform(skel.left_hip.position);
00832 getHandPos(temphand,skelpos[LEFT_HIPPOS]);
00833
00834
00835 }else isJoint[LEFT_HIPPOS]=false;
00836
00837 if(isJointGood(skel.right_hip)){
00838 isJoint[RIGHT_HIPPOS]=true;
00839 temphand.palm=pointToTransform(skel.right_hip.position);
00840 getHandPos(temphand,skelpos[RIGHT_HIPPOS]);
00841
00842
00843 }else isJoint[RIGHT_HIPPOS]=false;
00844
00845 if(isJointGood(skel.left_knee)){
00846 isJoint[LEFT_KNEEPOS]=true;
00847 temphand.palm=pointToTransform(skel.left_knee.position);
00848 getHandPos(temphand,skelpos[LEFT_KNEEPOS]);
00849
00850
00851 }else isJoint[LEFT_KNEEPOS]=false;
00852
00853 if(isJointGood(skel.right_knee)){
00854 isJoint[RIGHT_KNEEPOS]=true;
00855 temphand.palm=pointToTransform(skel.right_knee.position);
00856 getHandPos(temphand,skelpos[RIGHT_KNEEPOS]);
00857
00858
00859 }else isJoint[RIGHT_KNEEPOS]=false;
00860
00861 if(isJointGood(skel.left_foot)){
00862 isJoint[LEFT_FOOTPOS]=true;
00863 temphand.palm=pointToTransform(skel.left_foot.position);
00864 getHandPos(temphand,skelpos[LEFT_FOOTPOS]);
00865
00866
00867 }else isJoint[LEFT_FOOTPOS]=false;
00868
00869 if(isJointGood(skel.right_foot)){
00870 isJoint[RIGHT_FOOTPOS]=true;
00871 temphand.palm=pointToTransform(skel.right_foot.position);
00872 getHandPos(temphand,skelpos[RIGHT_FOOTPOS]);
00873
00874
00875 }else isJoint[RIGHT_FOOTPOS]=false;
00876
00877
00878
00879
00880
00881 }
00882
00883
00884
00885
00886
00887 void printRecog(int state, int LR){
00888 if(LR==RHANDPOS)
00889 {
00890 if(state!=STATE_BEFORE){
00891 switch(state){
00892 case HANDSTOGETHER: printf(" RHANDP i LHAND\n");
00893 STATE_BEFORE = HANDSTOGETHER;
00894 break;
00895
00896 case HEADPOS: printf(" RHANDP i HEAD\n");
00897 STATE_BEFORE = HEADPOS;
00898 break;
00899 case RIGHT_SHOULDERPOS: printf(" RHANDP i RIGHT_SHOULDERPOS\n");
00900 STATE_BEFORE = RIGHT_SHOULDERPOS;
00901 break;
00902
00903 case LEFT_SHOULDERPOS: printf(" RHANDP i LEFT_SHOULDERPOS\n");
00904 STATE_BEFORE = LEFT_SHOULDERPOS;
00905 break;
00906
00907 case RIGHT_ELBOWPOS: printf(" RHANDP i RIGHT_ELBOWPOS\n");
00908 STATE_BEFORE = RIGHT_ELBOWPOS;
00909 break;
00910
00911 case LEFT_ELBOWPOS: printf(" RHANDP i LEFT_ELBOWPOS\n");
00912 STATE_BEFORE = LEFT_ELBOWPOS;
00913 break;
00914
00915 case TORSOPOS: printf(" RHANDP i TORSOPOS\n");
00916 STATE_BEFORE = TORSOPOS;
00917 break;
00918
00919
00920 case LEFT_HIPPOS: printf(" RHANDP i LEFT_HIPPOS\n");
00921 STATE_BEFORE = LEFT_HIPPOS;
00922 break;
00923
00924 case RIGHT_HIPPOS: printf(" RHANDP i RIGHT_HIPPOS\n");
00925 STATE_BEFORE = RIGHT_HIPPOS;
00926 break;
00927
00928 case LEFT_KNEEPOS: printf(" RHANDP i LEFT_KNEEPOS\n");
00929 STATE_BEFORE = LEFT_KNEEPOS;
00930 break;
00931
00932 case RIGHT_KNEEPOS: printf(" RHANDP i RIGHT_KNEEPOS\n");
00933 STATE_BEFORE = RIGHT_KNEEPOS;
00934 break;
00935
00936 case LEFT_FOOTPOS: printf(" RHANDP i LEFT_FOOTPOS\n");
00937 STATE_BEFORE= LEFT_FOOTPOS;
00938 break;
00939
00940 case RIGHT_FOOTPOS: printf(" RHANDP i RIGHT_FOOTPOS\n");
00941 STATE_BEFORE = RIGHT_FOOTPOS;
00942 break;
00943 }
00944
00945 }
00946 }
00947 else{
00948 if(state!=STATE_BEFORE){
00949 switch(state){
00950 case HANDSTOGETHER: printf(" LHANDP i LHAND\n");
00951 STATE_BEFORE = HANDSTOGETHER;
00952 break;
00953
00954 case HEADPOS: printf(" LHANDP i HEAD\n");
00955 STATE_BEFORE = HEADPOS;
00956 break;
00957
00958 case RIGHT_SHOULDERPOS: printf(" LHANDP i RIGHT_SHOULDERPOS\n");
00959 STATE_BEFORE = RIGHT_SHOULDERPOS;
00960 break;
00961
00962 case LEFT_SHOULDERPOS: printf(" LHANDP i LEFT_SHOULDERPOS\n");
00963 STATE_BEFORE = LEFT_SHOULDERPOS;
00964 break;
00965
00966 case RIGHT_ELBOWPOS: printf(" LHANDP i RIGHT_ELBOWPOS\n");
00967 STATE_BEFORE = RIGHT_ELBOWPOS;
00968 break;
00969
00970 case LEFT_ELBOWPOS: printf(" LHANDP i LEFT_ELBOWPOS\n");
00971 STATE_BEFORE = LEFT_ELBOWPOS;
00972 break;
00973
00974 case TORSOPOS: printf(" LHANDP i TORSOPOS\n");
00975 STATE_BEFORE = TORSOPOS;
00976 break;
00977
00978 case LEFT_HIPPOS: printf(" LHANDP i LEFT_HIPPOS\n");
00979 STATE_BEFORE = LEFT_HIPPOS;
00980 break;
00981
00982 case RIGHT_HIPPOS: printf(" LHANDP i RIGHT_HIPPOS\n");
00983 STATE_BEFORE = RIGHT_HIPPOS;
00984 break;
00985
00986 case LEFT_KNEEPOS: printf(" LHANDP i LEFT_KNEEPOS\n");
00987 STATE_BEFORE = LEFT_KNEEPOS;
00988 break;
00989
00990 case RIGHT_KNEEPOS: printf(" LHANDP i RIGHT_KNEEPOS\n");
00991 STATE_BEFORE = RIGHT_KNEEPOS;
00992 break;
00993
00994 case LEFT_FOOTPOS: printf(" LHANDP i LEFT_FOOTPOS\n");
00995 STATE_BEFORE = LEFT_FOOTPOS;
00996 break;
00997
00998 case RIGHT_FOOTPOS: printf(" LHANDP i RIGHT_FOOTPOS\n");
00999 STATE_BEFORE = RIGHT_FOOTPOS;
01000 break;
01001 }
01002
01003 }
01004 }
01005
01006 }
01007
01009 void tRecognition(pcl::PointXYZ *p, bool *a){
01010
01011
01012
01013 tRecogCounter = tRecogCounter+1;
01014
01015 if(tRecogCounter>1){
01016
01017 if(a[RHANDPOS] && a[LHANDPOS]){
01018 if(pointComparisonHands( p[RHANDPOS] ,p[LHANDPOS])){
01019 eventState(rightState,HANDSTOGETHER);
01020 if(LHAND_FLAG)eventState(leftState,HANDSTOGETHER);
01021 printRecog(HANDSTOGETHER, RHANDPOS);}
01022 }
01023 if(a[RHANDPOS] && a[HEADPOS]){
01024 if(pointComparisonHead( p[RHANDPOS] ,p[HEADPOS])){
01025 eventState(rightState,HEADPOS);
01026 printRecog(HEADPOS, RHANDPOS);}
01027 }
01028 if(a[LHANDPOS] && a[HEADPOS] && LHAND_FLAG){
01029 if(pointComparisonHead( p[LHANDPOS] ,p[HEADPOS])){
01030 eventState(leftState,HEADPOS);
01031 printRecog(HEADPOS, LHANDPOS);}
01032 }
01033
01034 if(a[RHANDPOS] && a[RIGHT_SHOULDERPOS]){
01035 if(pointComparison( p[RHANDPOS] ,p[RIGHT_SHOULDERPOS])){
01036 eventState(rightState,RIGHT_SHOULDERPOS);
01037 printRecog(RIGHT_SHOULDERPOS, RHANDPOS);}
01038 }
01039 if(a[LHANDPOS] && a[RIGHT_SHOULDERPOS] && LHAND_FLAG){
01040 if(pointComparison( p[LHANDPOS] ,p[RIGHT_SHOULDERPOS])){
01041 eventState(leftState,RIGHT_SHOULDERPOS);
01042 printRecog(RIGHT_SHOULDERPOS, LHANDPOS);}
01043 }
01044
01045 if(a[RHANDPOS] && a[LEFT_SHOULDERPOS]){
01046 if(pointComparison( p[RHANDPOS] ,p[LEFT_SHOULDERPOS])){
01047 eventState(rightState,LEFT_SHOULDERPOS);
01048 printRecog(LEFT_SHOULDERPOS, RHANDPOS);}
01049 }
01050 if(a[LHANDPOS] && a[LEFT_SHOULDERPOS] && LHAND_FLAG){
01051 if(pointComparison( p[LHANDPOS] ,p[LEFT_SHOULDERPOS])){
01052 eventState(leftState,LEFT_SHOULDERPOS);
01053 printRecog(LEFT_SHOULDERPOS, LHANDPOS);}
01054 }
01055
01056
01057 if(a[RHANDPOS] && a[RIGHT_ELBOWPOS]){
01058 if(pointComparison( p[RHANDPOS] ,p[RIGHT_ELBOWPOS])){
01059 eventState(rightState,RIGHT_ELBOWPOS);
01060 printRecog(RIGHT_ELBOWPOS, RHANDPOS);}
01061 }
01062
01063 if(a[LHANDPOS] && a[RIGHT_ELBOWPOS] && LHAND_FLAG){
01064 if(pointComparison( p[LHANDPOS] ,p[RIGHT_ELBOWPOS])){
01065 eventState(leftState,RIGHT_ELBOWPOS);
01066 printRecog(RIGHT_ELBOWPOS, LHANDPOS);}
01067 }
01068
01069
01070 if(a[RHANDPOS] && a[LEFT_ELBOWPOS]){
01071 if(pointComparison( p[RHANDPOS] ,p[LEFT_ELBOWPOS])){
01072 eventState(rightState,LEFT_ELBOWPOS);
01073 printRecog(LEFT_ELBOWPOS, RHANDPOS);}
01074 }
01075
01076 if(a[LHANDPOS] && a[LEFT_ELBOWPOS] && LHAND_FLAG){
01077 if(pointComparison( p[LHANDPOS] ,p[LEFT_ELBOWPOS])){
01078 eventState(leftState,LEFT_ELBOWPOS);
01079 printRecog(LEFT_ELBOWPOS, LHANDPOS);}
01080 }
01081
01082
01083 if(a[RHANDPOS] && a[TORSOPOS]){
01084 if(pointComparison( p[RHANDPOS] ,p[TORSOPOS])){
01085 eventState(rightState,TORSOPOS);
01086 printRecog(TORSOPOS, RHANDPOS);}
01087 }
01088
01089 if(a[LHANDPOS] && a[TORSOPOS] && LHAND_FLAG){
01090 if(pointComparison( p[LHANDPOS] ,p[TORSOPOS])){
01091 eventState(leftState,TORSOPOS);
01092 printRecog(TORSOPOS, RHANDPOS);}
01093 }
01094 if(a[RHANDPOS] && a[LEFT_HIPPOS]){
01095 if(pointComparison( p[RHANDPOS] ,p[LEFT_HIPPOS])){
01096 eventState(rightState,LEFT_HIPPOS);
01097 printRecog(LEFT_HIPPOS, RHANDPOS);}
01098 }
01099
01100 if(a[LHANDPOS] && a[LEFT_HIPPOS] && LHAND_FLAG){
01101 if(pointComparison( p[LHANDPOS] ,p[LEFT_HIPPOS])){
01102 eventState(leftState,LEFT_HIPPOS);
01103 printRecog(LEFT_HIPPOS, LHANDPOS);}
01104 }
01105
01106
01107 if(a[RHANDPOS] && a[RIGHT_HIPPOS]){
01108 if(pointComparison( p[RHANDPOS] ,p[RIGHT_HIPPOS])){
01109 eventState(rightState,RIGHT_HIPPOS);
01110 printRecog(RIGHT_HIPPOS, RHANDPOS);}
01111 }
01112
01113 if(a[LHANDPOS] && a[RIGHT_HIPPOS] && LHAND_FLAG){
01114 if(pointComparison( p[LHANDPOS] ,p[RIGHT_HIPPOS])){
01115 eventState(leftState,RIGHT_HIPPOS);
01116 printRecog(RIGHT_HIPPOS, RHANDPOS);}
01117 }
01118
01119 if(a[RHANDPOS] && a[LEFT_KNEEPOS]){
01120 if(pointComparison( p[RHANDPOS] ,p[LEFT_KNEEPOS])){
01121 eventState(rightState,LEFT_KNEEPOS);
01122 printRecog(LEFT_KNEEPOS, RHANDPOS);}
01123 }
01124 if(a[LHANDPOS] && a[LEFT_KNEEPOS] && LHAND_FLAG){
01125 if(pointComparison( p[LHANDPOS] ,p[LEFT_KNEEPOS])){
01126 eventState(leftState,LEFT_KNEEPOS);
01127 printRecog(LEFT_KNEEPOS, LHANDPOS);}
01128 }
01129 if(a[RHANDPOS] && a[RIGHT_KNEEPOS]){
01130 if(pointComparison( p[RHANDPOS] ,p[RIGHT_KNEEPOS])){
01131 eventState(rightState,RIGHT_KNEEPOS);
01132 printRecog(RIGHT_KNEEPOS, RHANDPOS);}
01133 }
01134
01135 if(a[LHANDPOS] && a[RIGHT_KNEEPOS] && LHAND_FLAG){
01136 if(pointComparison( p[LHANDPOS] ,p[RIGHT_KNEEPOS])){
01137 eventState(leftState,RIGHT_KNEEPOS);
01138 printRecog(RIGHT_KNEEPOS, LHANDPOS);}
01139 }
01140
01141
01142 if(a[RHANDPOS] && a[LEFT_FOOTPOS]){
01143 if(pointComparison( p[RHANDPOS] ,p[LEFT_FOOTPOS])){
01144 eventState(rightState,LEFT_FOOTPOS);
01145 printRecog(RIGHT_FOOTPOS, RHANDPOS);}
01146 }
01147 if(a[LHANDPOS] && a[LEFT_FOOTPOS] && LHAND_FLAG){
01148 if(pointComparison( p[LHANDPOS] ,p[LEFT_FOOTPOS])){
01149 eventState(leftState,LEFT_FOOTPOS);
01150 printRecog(LEFT_FOOTPOS, LHANDPOS);}
01151 }
01152 if(a[RHANDPOS] && a[RIGHT_FOOTPOS]){
01153 if(pointComparison( p[RHANDPOS] ,p[RIGHT_FOOTPOS])){
01154 eventState(rightState,RIGHT_FOOTPOS);
01155 printRecog(RIGHT_FOOTPOS, RHANDPOS);}
01156 }
01157 if(a[LHANDPOS] && a[RIGHT_FOOTPOS] && LHAND_FLAG){
01158 if(pointComparison( p[LHANDPOS] ,p[RIGHT_FOOTPOS])){
01159 eventState(leftState,RIGHT_FOOTPOS);
01160 printRecog(RIGHT_FOOTPOS, LHANDPOS);}
01161 }
01162 if(a[RHANDPOS] && a[LEFT_FOOTPOS]){
01163 if(pointComparison( p[RHANDPOS] ,p[LEFT_FOOTPOS])){
01164 eventState(rightState,LEFT_FOOTPOS);
01165 printRecog(LEFT_FOOTPOS, RHANDPOS);}
01166 }
01167 if(a[LHANDPOS] && a[LEFT_FOOTPOS] && LHAND_FLAG){
01168 if(pointComparison( p[LHANDPOS] ,p[LEFT_FOOTPOS])){
01169 eventState(leftState,LEFT_FOOTPOS);
01170 printRecog(LEFT_FOOTPOS, LHANDPOS);}
01171 }
01172 }
01173 }
01174
01175 void cls(){
01176 cout << string(50, '\n');
01177
01178 }
01179 void distancDataProcessing(pcl::PointXYZ *p){
01180 float dist;
01181 distCounter++;
01182 dist = sqrt((p[RHANDPOS].x-p[LHANDPOS].x)*(p[RHANDPOS].x-p[LHANDPOS].x)+(p[RHANDPOS].y-p[LHANDPOS].y)*(p[RHANDPOS].y-p[LHANDPOS].y)+(p[RHANDPOS].z-p[LHANDPOS].z)*(p[RHANDPOS].z-p[LHANDPOS].z));
01183
01184
01185
01186 printf("\t Distanca||%.02f|| |%d|\n",dist,distCounter);
01187 if(distCounter>20){
01188 DIST_FLAG=0;
01189 RECOG_FLAG=1;
01190 distCounter=0; cls();
01191 }
01192 }
01193
01194
01195 void armCalibrationDataProcessing()
01196 {
01197
01198 calibrationBundle max;
01199 max.maxRight=0;
01200 max.maxLeft =0;
01201 max.maxHands=0;
01202 int tic,tac;
01203 tac=calibData.size();
01204 for(tic=0;tic<tac;tic++){
01205 if(calibData[tic].maxRight>max.maxRight)max.maxRight=calibData[tic].maxRight;
01206 if(calibData[tic].maxLeft>max.maxLeft)max.maxLeft=calibData[tic].maxLeft;
01207 if(calibData[tic].maxHands>max.maxHands)max.maxHands=calibData[tic].maxHands;
01208
01209
01210 }
01211 calib.maxRight=max.maxRight;
01212 calib.maxLeft=max.maxLeft;
01213 calib.maxHands=max.maxHands;
01214
01215
01216 calibNum++;
01217 }
01218
01219 void messageSync(){
01220
01221 if((int)skelmsg.header.seq == (int)lastskelseq || (int)pcloudmsg.header.seq == (int)lastcloudseq)
01222 return;
01223
01224
01225
01226 if(calibNum==10)armCalibrationDataProcessing();
01227
01228
01229 double tdiff = (skelmsg.header.stamp-pcloudmsg.header.stamp).toSec();
01230
01231 if(fabs(tdiff) < .15){
01232 lastskelseq=skelmsg.header.seq;
01233 lastcloudseq=pcloudmsg.header.seq;
01234 processData(skelmsg,pcloudmsg,calib);
01235 calibData.push_back(calib);
01236
01237
01238 }
01239 }
01240
01241
01242
01243
01244
01245
01246
01247 void processData(body_msgs::Skeletons skels, sensor_msgs::PointCloud2 cloud, calibrationBundle &c){
01248
01249
01250 if(skels.skeletons.size()==0)
01251 return;
01252
01253 body_msgs::Hands hands;
01254
01255 getHands(skels.skeletons[0],cloud,hands);
01256 if(RECOG_FLAG)tRecognition(skelpos,isJoint);
01257 if(DIST_FLAG) distancDataProcessing(skelpos);
01258
01259
01263
01264 if((calibNum<10) && (CALIB_FLAG)){
01265 getHands(skels.skeletons[0],cloud,hands,ruke,ramena);
01266 if(calibNum==0){
01267 printf("Kalibracija u toku,slijedite upute \n");
01268 printf("Postavite se paralelno sa senzorskim uredajem\n");
01269 printf("Rasirite ruke\n");
01270 }
01271 if(calibNum==5)printf("Ispruzite ruke u zrak\n");
01272
01273 armCalibration(c,ruke,ramena);
01274
01275 calibNum++;
01276 }
01277 else{
01278
01282
01283
01284 getInfoStateMachine(skels.skeletons[0],hands,skelpos,isJoint );
01285 armCalculationTurtlePub(left_pub,right_pub,height_pub);
01286
01287 linear_=angular_=0;
01288
01289 if(CALIB_FLAG){
01290 if(ABS(left_pub)>ABS(right_pub))
01291 {
01292 angular_=left_pub;
01293 }
01294 else angular_=(-1)*right_pub;
01295
01296 if(ABS(height_pub)<0.10)
01297 {
01298 linear_=0;
01299 }
01300 else linear_=height_pub;
01301
01302 vel.angular = a_scale_*angular_;
01303 vel.linear = l_scale_*linear_;
01304 vel_pub_.publish(vel);
01305 turtlePubCounter++;
01306 if(turtlePubCounter==100){
01307 CALIB_FLAG=0;
01308 RECOG_FLAG = 1;
01309 turtlePubCounter=0;
01310 }
01311 }
01312
01313 }
01314
01315
01316
01317
01321 for(uint i=0;i<hands.hands.size();i++){
01322 if(hands.hands[i].left)
01323 cloudpub_[0].publish(hands.hands[i].handcloud);
01324 else
01325 cloudpub_[1].publish(hands.hands[i].handcloud);
01326 }
01327 if(hands.hands.size())
01328 handspub_.publish(hands);
01329
01330
01331
01332 }
01333
01334
01335
01336
01337
01338 void cloudcb(const sensor_msgs::PointCloud2ConstPtr &scan){
01339 pcloudmsg=*scan;
01340 messageSync();
01341 }
01342
01343 void skelcb(const body_msgs::SkeletonsConstPtr &skels){
01344 skelmsg=*skels;
01345
01346 messageSync();
01347 }
01348
01349 } ;
01350
01351
01352
01353
01354 int main(int argc, char **argv)
01355 {
01356 ros::init(argc, argv, "hand_detector");
01357 ros::NodeHandle n;
01358 HandDetector detector;
01359 ros::spin();
01360 return 0;
01361 }