detect_hands_wskel.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2010, Garratt Gallagher
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name Garratt Gallagher nor the names of other
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 /*boost::posix_time::ptime t1 = boost::posix_time::second_clock::local_time();
00035     boost::this_thread::sleep(boost::posix_time::millisec(500));
00036     boost::posix_time::ptime t2 = boost::posix_time::second_clock::local_time();
00037     boost::posix_time::time_duration diff = t2 - t1;
00038     std::cout << diff.total_milliseconds() << std::endl;*/
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                         KRATKO ADRESIRANJE
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 //STATEMACHINE
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;   //kalibracija
00141 int LHAND_FLAG = 0;  //prepoznavanje lijeve ruke za state machine
00142 int RECOG_FLAG = 1; //prepoznavanje za state machinu u pocetku radi
00143 int tRecogCounter = 0;
00144 int STATE_BEFORE = -1; //stanje prethodnog ispisa
00145 int turtlePubCounter =0;
00146 int DIST_FLAG = 0; //racunanja distance
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;  //name is used to identify the evaluator as a whole
00154 
00155 
00156 public:
00158    TimeEvaluator(std::string _name="Time Evaluator"){
00159       name=_name;
00160       //be default the clock starts running when TimeEvaluator is initialized
00161 
00162       gettimeofday(&tmark, NULL);
00163 
00164    }
00165 
00166 
00167 
00168 
00169 
00171    void mark(std::string _name=""){
00172       //Give the event a name:
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       //record the time since last event
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 //adds a set amount (scale) of a vector from pos A to pos B to point C
00257 //this function is mostly here to do all the nasty conversions...
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     // printf("[Det_H_w_SK]Eigenvaluess: %.02f, %.02f \n",eigen_values(0)/eigen_values(1),eigen_values(1)/eigen_values(2));
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      //eigen eigen_values(1)/eigen_values(2) < .4 means closed fist, unless you are pointing at the kinect
00297 
00298 //     //make polygon
00299 //     geometry_msgs::Polygon p;
00300 //     p.points.push_back(eigenToMsgPoint32(centroid));
00301 //     p.points.push_back(eigenToMsgPoint32(centroid+direction));
00302 //     pmap.polygons.push_back(p);
00303 //     pmap.header=h.handcloud.header;
00304 }
00305 
00306 
00308 
00312 void getHandCloud(body_msgs::Hand &hand, sensor_msgs::PointCloud2 &fullcloud){
00313    pcl::PointCloud<pcl::PointXYZ> handcloud,cloudin;
00314    //convert to pcl cloud
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);  //updating estimate of location of the hand
00322   
00323 
00324 
00325    //printf("[Det_H_w_SK]got hand!%.02f, %02f, %02f ",handpos.x, handpos.y,handpos.z);
00326    //find points near the skeletal hand position
00327    NNN(cloudin,handpos,inds, .1);
00328 
00329    //Iterate the following:
00330    //    find centroid of current cluster
00331    //    push the cluster slightly away from the arm
00332    //    search again around the centroid to redefine our cluster
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    //save this cluster as a separate cloud.
00341    getSubCloud(cloudin,inds,handcloud);
00342 
00343    //convert the cloud back to a message
00344    pcl::toROSMsg(handcloud,hand.handcloud);
00345    PointConversion(handpos,hand.palm.translation);
00346 
00347    //add other hand message stuff:
00348    hand.state="unprocessed";
00349    getEigens(hand);
00350   // std::cout<<hand.state<<std::endl; //PRINTANJE CLOSEDA I OPEN...
00351    hand.thumb=-1; //because we have not processed the hand...
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);  //updating estimate of location of the hand
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);  //updating estimate of location of the hand
00386    hand1.x=handpos.x;
00387    hand1.y=handpos.y;
00388    hand1.z=handpos.z; 
00389         
00390         
00391                 // printf("[Det_H_w_SK]got RIGHT hand with coordinates%.02f, %02f, %02f ",handpos.x, handpos.y,handpos.z);
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    pcl::PointXYZ headpos;//
00409    pcl::PointXYZ neckpos;//
00410    pcl::PointXYZ right_handpos;//
00411    pcl::PointXYZ left_handpos;//
00412    pcl::PointXYZ right_shoulderpos;//
00413    pcl::PointXYZ left_shoulderpos;//
00414    pcl::PointXYZ right_elbowpos;//
00415    pcl::PointXYZ left_elbowpos;//
00416    pcl::PointXYZ torsopos;//
00417    pcl::PointXYZ left_hippos;//
00418    pcl::PointXYZ right_hippos;//
00419    pcl::PointXYZ left_kneepos;
00420    pcl::PointXYZ right_kneepos;
00421    pcl::PointXYZ left_footpos;
00422    pcl::PointXYZ right_footpos; 
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       //getHandPos(lhand,lhandpos,'l');//       
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      // getHandPos(rhand,rhandpos,'r');//
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    //...Shoulders TODO check
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);//left  
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);//right      
00490    }
00491  
00492 }
00493 
00494 
00495 bool pointComparisonHands( pcl::PointXYZ a ,pcl::PointXYZ b){
00496         //if((ABS(sqrt((a.x-b.x)*(a.x-b.x))) < 0.01) && (ABS(sqrt((a.y-b.y)*(a.y-b.y))) < 0.1))printf("udaljenost spojene");
00497         //printf("X [%.02f], Y[%.02f]",ABS(a.x-b.x),ABS(a.y-b.y));
00498         //float c ;
00499         //c=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));
00500         //float x,y;
00501         //x=sqrt((a.x-b.x)*(a.x-b.x));
00502         //y=sqrt((a.y-b.y)*(a.y-b.y));
00503         //printf("UDALJENOST %f %f  \n",x,y);
00504         //printf("A[%f %f %f] \n ",a.x,a.y,a.z);
00505         //printf("B[ %f %f %f]\n",b.x,b.y,b.z);
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                 //TODO postavi zastavicu da pokrene kornjacu
00577                 CALIB_FLAG = 1; //kalibracija
00578                 RECOG_FLAG = 0; //tRecognition iskljucen 
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   // turtle stuff
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         //printf(" LRUKA[%.02f %.02f %.02f] \n DRUKA[%.02f %.02f %.02f] \n",            hands.first.x ,hands.first.y ,hands.first.z ,hands.second.x ,hands.first.y ,hands.first.z);
00693         
00694         }
00695 
00696  
00697    void armCalculationTurtlePub(float &l, float &r, float &h){//kalkulacija polozaja ruku za publishera
00698         
00699         float rightCalc,leftCalc, heightCalc;
00700         
00701    
00702         
00703         leftCalc  =calcDist(skelpos[LHANDPOS].x, skelpos[LEFT_SHOULDERPOS].x);
00704         //if(ABS(leftCalc)<0.13)//hardkodiran pojas u kojem ocitavamo height
00705         heightCalc=calcDist(skelpos[LHANDPOS].y, skelpos[LEFT_SHOULDERPOS].y);
00706         //else heightCalc=0;
00707         rightCalc =calcDist(skelpos[RHANDPOS].x, skelpos[RIGHT_SHOULDERPOS].x);
00708         //printf(" skelpos HANDPOS %.02f SHOULDERPOS %.02f \n",skelpos[LHANDPOS].y,skelpos[LEFT_SHOULDERPOS].y);
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);} //ako je l.ruka ispod razine ramena idemo u minus
00715         if((skelpos[RHANDPOS].y>skelpos[RIGHT_HIPPOS].y) &&(skelpos[LHANDPOS].y>skelpos[LEFT_HIPPOS].y)){h=0;}
00716         //printf("[armCalc]LEFT RIGHT HEIGHT POSTO %.02f %.02f %.02f \n",l,r,h);
00717         
00718         
00719 
00720         }
00721 
00722         void getInfoStateMachine(body_msgs::Skeleton &skel, body_msgs::Hands &handsmsg, pcl::PointXYZ* skelpos, bool* isJoint){
00723            
00724            
00725            //pcl::PointXYZ skelpos [SKEL_POINTS];
00726            //bool isJoint[SKEL_POINTS];
00727            
00728         
00729 
00730            //XYZ component      X [LEFT RIGHT] Y [UP DOWN] Z [IN OUT]
00731         /*----------------------------------------------------------------------------
00732                                 SHORT ADRESING
00733         ----------------------------------------------------------------------------
00734 
00735         #define HEADPOS                 0
00736         #define LHANDPOS                (HEADPOS+1)
00737         #define RHANDPOS                (LHANDPOS+1)
00738         #define NECKPOS                 (RHANDPOS+1)
00739         #define RIGHT_SHOULDERPOS       (NECKPOS+1)
00740         #define LEFT_SHOULDERPOS        (RIGHT_SHOULDERPOS+1)
00741         #define RIGHT_ELBOWPOS          (LEFT_SHOULDERPOS+1)
00742         #define LEFT_ELBOWPOS           (RIGHT_ELBOWPOS+1)
00743         #define TORSOPOS                (LEFT_ELBOWPOS+1)
00744         #define LEFT_HIPPOS             (TORSOPOS+1)
00745         #define RIGHT_HIPPOS            (LEFT_HIPPOS+1)
00746         #define LEFT_KNEEPOS            (RIGHT_HIPPOS+1)
00747         #define RIGHT_KNEEPOS           (LEFT_KNEEPOS+1)
00748         #define LEFT_FOOTPOS            (RIGHT_KNEEPOS+1)
00749         #define RIGHT_FOOTPOS           (LEFT_FOOTPOS+1)
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                 //printf("HEAD POS %.02f,%.02f,%.02f\n\n", skelpos[HEADPOS].x,skelpos[HEADPOS].y,skelpos[HEADPOS].z);
00762                  }  else isJoint[HEADPOS]=false;
00763 
00764                 /*if(isJointGood(skel.neck)){
00765                 isJoint[NECKPOS]=true;
00766                 temphand.palm=pointToTransform(skel.neck.position);
00767                 getHandPos(temphand,skelpos[NECKPOS]);
00768                 //printf("NECK POS %.02f %.02f %.02f\n", skelpos[NECKPOS].x,skelpos[NECKPOS].y,skelpos[NECKPOS].z);
00769 
00770                  }else*/ 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                 //printf("LHAND POS %.02f %.02f %.02f\n", skelpos[LHANDPOS].x,skelpos[LHANDPOS].y,skelpos[LHANDPOS].z);
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                 //printf("RHAND POS %.02f %.02f %.02f\n", skelpos[RHANDPOS].x,skelpos[RHANDPOS].y,skelpos[RHANDPOS].z);
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                 //printf("RSHOULDER POS %.02f %.02f %.02f\n", skelpos[RIGHT_SHOULDERPOS].x,skelpos[RIGHT_SHOULDERPOS].y,skelpos[RIGHT_SHOULDERPOS].z);
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                 //printf("LSHOULDER POS %.02f %.02f %.02f\n", skelpos[LEFT_SHOULDERPOS].x,skelpos[LEFT_SHOULDERPOS].y,skelpos[LEFT_SHOULDERPOS].z);
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                 //printf("RELBOW POS %.02f %.02f %.02f\n", skelpos[RIGHT_ELBOWPOS].x,skelpos[RIGHT_ELBOWPOS].y,skelpos[RIGHT_ELBOWPOS].z);
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                 //printf("LELBOW POS %.02f %.02f %.02f\n", skelpos[LEFT_ELBOWPOS].x,skelpos[LEFT_ELBOWPOS].y,skelpos[LEFT_ELBOWPOS].z);
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                 //printf("TORSO POS%.02f %.02f %.02f\n", skelpos[TORSOPOS].x,skelpos[TORSOPOS].y,skelpos[TORSOPOS].z);
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                 //printf("LHIPPO POS %.02f %.02f %.02f\n", skelpos[LEFT_HIPPOS].x,skelpos[LEFT_HIPPOS].y,skelpos[LEFT_HIPPOS].z);
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                 //printf("RHIPPO POS %.02f %.02f %.02f\n", skelpos[RIGHT_HIPPOS].x,skelpos[RIGHT_HIPPOS].y,skelpos[RIGHT_HIPPOS].z);
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                 //printf("LKEE POS %.02f %.02f %.02f\n", skelpos[LEFT_KNEEPOS].x,skelpos[LEFT_KNEEPOS].y,skelpos[LEFT_KNEEPOS].z);
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                 //printf("RKNEE POS %.02f %.02f %.02f\n", skelpos[RIGHT_KNEEPOS].x,skelpos[RIGHT_KNEEPOS].y,skelpos[RIGHT_KNEEPOS].z);
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                 //printf("LFOOT POS %.02f %.02f %.02f\n", skelpos[LEFT_FOOTPOS].x,skelpos[LEFT_FOOTPOS].y,skelpos[LEFT_FOOTPOS].z);
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                 //printf("RFOOT POS %.02f %.02f %.02f\n", skelpos[RIGHT_FOOTPOS].x,skelpos[RIGHT_FOOTPOS].y,skelpos[RIGHT_FOOTPOS].z);
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)//desna ruka
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{//LEFT
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          //LEFT_HIPPOS   RIGHT_HIPPOS    LEFT_KNEEPOS  RIGHT_KNEEPOS     LEFT_FOOTPOS    RIGHT_FOOTPOS          
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);//znaci neki event...
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         //TODO znaci uzeti podatke iz calibData, max hand visina , max hand sirina prema ramenima, dodati calibNum+1 td ne ulazi u uvjet.
01198         calibrationBundle max;
01199         max.maxRight=0;
01200         max.maxLeft =0;
01201         max.maxHands=0;//visina
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         //printf("Vrijednosti L %.02f R %.02f UP %.02f\n",calib.maxRight, calib.maxLeft, calib.maxHands);
01215         
01216         calibNum++;
01217         }
01218   
01219   void messageSync(){
01220      //don't even consider it if the sequence numbers have not changed
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      //At 30 hz, assume that the timing will be less than 15ms apart
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      //getHands(skels.skeletons[0],cloud,hands);
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         } //END OF CALIBRATION PROCEDURE
01277         else{
01278 
01282 
01283                 
01284                 getInfoStateMachine(skels.skeletons[0],hands,skelpos,isJoint );
01285                 armCalculationTurtlePub(left_pub,right_pub,height_pub);//LEFT RIGHT HEIGHT
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      //printf("[Det_H_w_SK]skel callback tdiff = %.04f \n",(skelmsg.header.stamp-pcloudmsg.header.stamp).toSec());
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 }


labust_kinect
Author(s): LABUST
autogenerated on Fri Feb 7 2014 11:37:27