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
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
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
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
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
00150
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
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
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
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
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
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
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