lmc_visualizer_node.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "visualization_msgs/Marker.h"
00003 #include "visualization_msgs/MarkerArray.h"
00004 
00005 #include "leap_motion/Human.h"
00006 #include "leap_motion/Hand.h"
00007 #include "leap_motion/Finger.h"
00008 #include "leap_motion/Bone.h"
00009 
00010 #include "Leap.h"
00011 #include <iostream>
00012 
00013 static ros::Publisher* marker_pub;
00014 const std::string fingerNames[] = {"Thumb", "Index", "Middle", "Ring", "Pinky"};
00015 
00027 visualization_msgs::Marker createJointMarker(const leap_motion::Human::ConstPtr& human, 
00028     std::string hand_ns, std::string finger_ns, unsigned int id, geometry_msgs::Pose location ){
00029 
00030     visualization_msgs::Marker joint_marker;
00031 
00032     joint_marker.header.frame_id = human->header.frame_id;
00033     joint_marker.header.stamp = human->header.stamp;
00034     joint_marker.ns = hand_ns+"_"+finger_ns;
00035     joint_marker.id = id;
00036     joint_marker.type =  visualization_msgs::Marker::SPHERE;
00037     joint_marker.action = visualization_msgs::Marker::ADD;
00038 
00039     // Location data in meters from origin
00040     joint_marker.pose.position.x = location.position.x;
00041     joint_marker.pose.position.y = location.position.y; 
00042     joint_marker.pose.position.z = location.position.z;
00043 
00044     joint_marker.scale.x = 0.015;
00045     joint_marker.scale.y = 0.015;
00046     joint_marker.scale.z = 0.015;
00047     
00048     joint_marker.color.r = 1.0f;
00049     joint_marker.color.g = 0.0f;
00050     joint_marker.color.b = 0.0f;
00051     joint_marker.color.a = 1.0f;
00052     joint_marker.lifetime = ros::Duration(0.1);
00053 
00054     return joint_marker;
00055 }
00056 
00068 visualization_msgs::Marker createFingerLines(const leap_motion::Human::ConstPtr &human, 
00069     std::string hand_ns, std::string finger_ns, unsigned int id, leap_motion::Bone current_bone){
00070     
00071     visualization_msgs::Marker line_list;
00072     line_list.header.frame_id = human -> header.frame_id;
00073     line_list.header.stamp = human -> header.stamp;
00074     line_list.ns = hand_ns + "_" + finger_ns;
00075     line_list.type = visualization_msgs::Marker::LINE_LIST;
00076     line_list.action = visualization_msgs::Marker::ADD;
00077     line_list.id = id;
00078 
00079     line_list.scale.x = 0.0075;
00080 
00081     // Line list is white
00082     line_list.color.r = 1.0f;
00083     line_list.color.g = 1.0f;
00084     line_list.color.b = 1.0f;
00085     line_list.color.a = 1.0f;
00086     line_list.lifetime = ros::Duration(0.1);
00087 
00088     geometry_msgs::Point p;
00089     p.x = current_bone.bone_start.position.x;
00090     p.y = current_bone.bone_start.position.y;
00091     p.z = current_bone.bone_start.position.z;
00092     line_list.points.push_back(p);
00093 
00094     p.x = current_bone.bone_end.position.x;
00095     p.y = current_bone.bone_end.position.y;
00096     p.z = current_bone.bone_end.position.z;
00097     line_list.points.push_back(p);
00098 
00099     return line_list;
00100 }
00101 
00113 visualization_msgs::Marker createHandOutline(const leap_motion::Human::ConstPtr &human, 
00114     std::string hand_ns, unsigned int id, leap_motion::Hand current_hand){
00115 
00116     visualization_msgs::Marker line_list;
00117     line_list.header.frame_id = human -> header.frame_id;
00118     line_list.header.stamp = human -> header.stamp;
00119     line_list.ns = hand_ns;
00120     line_list.id = id;
00121     
00122     line_list.type = visualization_msgs::Marker::LINE_LIST;
00123     line_list.action = visualization_msgs::Marker::ADD;
00124 
00125     line_list.scale.x = 0.0075;
00126 
00127     // Line list is white
00128     line_list.color.r = 1.0f;
00129     line_list.color.g = 1.0f;
00130     line_list.color.b = 1.0f;
00131     line_list.color.a = 1.0f;
00132     line_list.lifetime = ros::Duration(0.1);
00133 
00134     for(unsigned int j = 0; j < current_hand.finger_list.size(); j++){
00135         
00136         geometry_msgs::Point p;
00137 
00138         leap_motion::Finger finger = current_hand.finger_list[j];
00139         leap_motion::Bone bone = finger.bone_list[0];
00140 
00141         // Connects thumb start and index finger
00142         if(finger.type == Leap::Finger::Type::TYPE_THUMB)
00143         {
00144             p.x = bone.bone_start.position.x;
00145             p.y = bone.bone_start.position.y;
00146             p.z = bone.bone_start.position.z;
00147             line_list.points.push_back(p);
00148 
00149             // Assumption that the hand has all 5 fingers and 
00150             // that the fingers are given in order from thumb[idx 0] to pinky[idx 4].
00151             finger = current_hand.finger_list[1];
00152             bone = finger.bone_list[1];
00153             p.x = bone.bone_start.position.x;
00154             p.y = bone.bone_start.position.y;
00155             p.z = bone.bone_start.position.z;
00156             line_list.points.push_back(p);
00157         }
00158         // Connect wrist and pinky
00159         else if(finger.type == Leap::Finger::Type::TYPE_PINKY)
00160         {
00161             p.x = bone.bone_start.position.x;
00162             p.y = bone.bone_start.position.y;
00163             p.z = bone.bone_start.position.z;
00164             line_list.points.push_back(p);
00165 
00166             p.x = bone.bone_end.position.x;
00167             p.y = bone.bone_end.position.y;
00168             p.z = bone.bone_end.position.z;
00169             line_list.points.push_back(p);
00170 
00171             // Creates the line from index to pinky at the wrist
00172             p.x = bone.bone_start.position.x;
00173             p.y = bone.bone_start.position.y;
00174             p.z = bone.bone_start.position.z;
00175             line_list.points.push_back(p);
00176 
00177             finger = current_hand.finger_list[0];
00178             bone = finger.bone_list[0];
00179             p.x = bone.bone_start.position.x;
00180             p.y = bone.bone_start.position.y;
00181             p.z = bone.bone_start.position.z;
00182             line_list.points.push_back(p);
00183         }
00184         else
00185         {   
00186             // Connects current finger and the follwing finger at the start of proximal bone (id 1)
00187             leap_motion::Bone bone = finger.bone_list[1];
00188             p.x = bone.bone_start.position.x;
00189             p.y = bone.bone_start.position.y;
00190             p.z = bone.bone_start.position.z;
00191             line_list.points.push_back(p);
00192 
00193             leap_motion::Finger temp_finger = current_hand.finger_list[j+1];
00194             bone = temp_finger.bone_list[1];
00195             p.x = bone.bone_start.position.x;
00196             p.y = bone.bone_start.position.y;
00197             p.z = bone.bone_start.position.z;
00198             line_list.points.push_back(p);
00199         }
00200     }
00201 
00202     return line_list;
00203 }
00204 
00216 visualization_msgs::Marker createPalmPosition(const leap_motion::Human::ConstPtr &human, 
00217     std::string hand_ns, unsigned int id, geometry_msgs::Point centre_point){
00218     
00219     visualization_msgs::Marker palm_centre;
00220     palm_centre.header.frame_id = human -> header.frame_id;
00221     palm_centre.header.stamp = human -> header.stamp;
00222 
00223     palm_centre.ns = hand_ns;
00224     palm_centre.id = id;
00225     palm_centre.type = visualization_msgs::Marker::SPHERE;
00226     palm_centre.action = visualization_msgs::Marker::ADD;
00227 
00228     // Location data in meters from origin
00229     palm_centre.pose.position.x = centre_point.x;
00230     palm_centre.pose.position.y = centre_point.y; 
00231     palm_centre.pose.position.z = centre_point.z;
00232 
00233     palm_centre.scale.x = 0.025;
00234     palm_centre.scale.y = 0.025;
00235     palm_centre.scale.z = 0.025;
00236    
00237     palm_centre.color.r = 0.0f;
00238     palm_centre.color.g = 0.0f;
00239     palm_centre.color.b = 1.0f;
00240     palm_centre.color.a = 1.0f;
00241     palm_centre.lifetime = ros::Duration(0.1);
00242 
00243     return palm_centre;
00244 }
00245 
00259 void createVisualization(visualization_msgs::MarkerArray* marker_array, const leap_motion::Human::ConstPtr& human,
00260     leap_motion::Hand hand, std::string hand_ns, uint8_t hand_id){
00261 
00262     marker_array->markers.push_back(createPalmPosition(human, hand_ns, 55, hand.palm_center));
00263     marker_array->markers.push_back(createHandOutline(human, hand_ns, hand_id, hand) );
00264 
00265     leap_motion::Finger finger;
00266     for(unsigned int j = 0; j < hand.finger_list.size(); j++)
00267     {
00268         finger = hand.finger_list[j];
00269         std::string ns_finger = fingerNames[finger.type];
00270         unsigned int id_offset = finger.bone_list.size();
00271         
00272         leap_motion::Bone bone;
00273         for(unsigned int k = 1; k < finger.bone_list.size(); k++)
00274         {
00275             bone = finger.bone_list[k];
00276             marker_array->markers.push_back(createFingerLines(human, hand_ns, ns_finger, k, bone));
00277             marker_array->markers.push_back(createJointMarker(human, hand_ns, ns_finger, k + id_offset, bone.bone_start));
00278             
00279             // The circle at the very bottom of the pinky
00280             if(finger.type == Leap::Finger::Type::TYPE_PINKY)
00281             {
00282                 leap_motion::Bone temp_bone = finger.bone_list[0];
00283                 marker_array->markers.push_back(createJointMarker(human, hand_ns, ns_finger,
00284                     k + id_offset+1, temp_bone.bone_start));    
00285             }
00286             // Fingertip circles
00287             if(k == Leap::Bone::Type::TYPE_DISTAL)
00288             {
00289                 marker_array->markers.push_back(createJointMarker(human, hand_ns, ns_finger,
00290                     k + id_offset + 2, bone.bone_end));
00291             }
00292         }
00293     }
00294 }
00295 
00301 void frameCallback(const leap_motion::Human::ConstPtr& human){
00302 
00303     visualization_msgs::MarkerArray marker_array;
00304     leap_motion::Hand hand;
00305 
00306     if( human -> right_hand.is_present )
00307     {
00308         hand = human -> right_hand;
00309         createVisualization(&marker_array, human, hand, "Right", 0);
00310     }
00311     
00312     if( human -> left_hand.is_present )
00313     {
00314         hand = human -> left_hand;
00315         createVisualization(&marker_array, human, hand, "Left", 1);
00316     }
00317     
00318     marker_pub->publish(marker_array);
00319 }
00320 
00321 int main(int argc, char** argv) {
00322     ros::init(argc, argv, "leap_motion");
00323     ros::NodeHandle nh("leap_motion");
00324     bool enable_filter;
00325 
00326     nh.getParam("/enable_filter", enable_filter);
00327     ros::Subscriber human_sub;
00328 
00329     human_sub = nh.subscribe<leap_motion::Human>("leap_device", 1, frameCallback);
00330     if(enable_filter)
00331     {
00332         human_sub = nh.subscribe<leap_motion::Human>("leap_filtered", 1, frameCallback);
00333     }
00334 
00335     ROS_INFO("enable_filter: %s", enable_filter ? "true" : "false");
00336     
00337     ros::Publisher m_pub = nh.advertise<visualization_msgs::MarkerArray>("visualization_marker_array", 1);
00338     marker_pub = &m_pub;
00339 
00340     ros::spin();
00341     return 0;
00342 }
00343 


leap_motion
Author(s): Florian Lier , Mirza Shah , Isaac IY Saito
autogenerated on Sat Jun 8 2019 18:47:25