$search
00001 #include <string> 00002 #include <ros/ros.h> 00003 #include <sensor_msgs/PointCloud.h> 00004 #include <sensor_msgs/PointCloud2.h> 00005 #include <sensor_msgs/point_cloud_conversion.h> 00006 00007 #include <tf/transform_listener.h> 00008 #include <vector> 00009 #include "boost/filesystem/operations.hpp" 00010 #include "boost/filesystem/path.hpp" 00011 #include "geometry_msgs/Pose.h" 00012 00013 #include <household_objects_database_msgs/DatabaseModelPose.h> 00014 #include <household_objects_database_msgs/DatabaseModelPoseList.h> 00015 #include <household_objects_database_msgs/GetModelMesh.h> 00016 00017 #include "tabletop_vfh_cluster_detector/TabletopObjectRecognition.h" 00018 #include <vfh_recognizer_db/vfh_recognition.h> 00019 00020 #include "tabletop_vfh_cluster_detector/marker_generator.h" 00021 00022 namespace tabletop_vfh_cluster_detector 00023 { 00024 class TabletopVFHClassifier 00025 { 00026 private: 00028 ros::NodeHandle nh_; 00030 ros::NodeHandle priv_nh_; 00032 ros::ServiceServer object_recognition_srv_; 00034 ros::ServiceClient get_model_mesh_srv_; 00035 00037 ros::Publisher marker_pub_; 00039 tf::TransformListener listener_; 00040 00042 int num_markers_published_; 00044 int current_marker_id_; 00045 00046 //VFH recognizer 00047 vfh_recognizer_db::VFHRecognizerDB<flann::HistIntersectionUnionDistance > vfh_recognizer; 00048 00049 void publishFitMarkers(const std::vector<household_objects_database_msgs::DatabaseModelPoseList> &potential_models, 00050 std::string frame_id); 00051 00052 void clearOldMarkers(std::string frame_id); 00053 00054 //------------------ Callbacks ------------------- 00055 00057 bool 00058 serviceCallback (TabletopObjectRecognition::Request &request, TabletopObjectRecognition::Response &response); 00059 00060 public: 00062 TabletopVFHClassifier (ros::NodeHandle nh); 00063 00065 ~TabletopVFHClassifier () 00066 { 00067 } 00068 }; 00069 00070 TabletopVFHClassifier::TabletopVFHClassifier (ros::NodeHandle nh) : 00071 nh_ (nh), priv_nh_ ("~") 00072 { 00073 num_markers_published_ = 1; 00074 current_marker_id_ = 1; 00075 00076 std::string get_model_mesh_srv_name; 00077 priv_nh_.param<std::string>("get_model_mesh_srv", get_model_mesh_srv_name, "get_model_mesh_srv"); 00078 while ( !ros::service::waitForService(get_model_mesh_srv_name, ros::Duration(2.0)) && nh_.ok() ) 00079 { 00080 ROS_INFO("Waiting for %s service to come up", get_model_mesh_srv_name.c_str()); 00081 } 00082 if (!nh_.ok()) exit(0); 00083 get_model_mesh_srv_ = nh_.serviceClient<household_objects_database_msgs::GetModelMesh> 00084 (get_model_mesh_srv_name, true); 00085 00086 marker_pub_ = nh_.advertise<visualization_msgs::Marker>(nh_.resolveName("markers_out"), 10); 00087 00088 //advertise service and define service callback 00089 object_recognition_srv_ = nh_.advertiseService (nh_.resolveName ("object_recognition_srv"), 00090 &TabletopVFHClassifier::serviceCallback, this); 00091 00092 //initialize vfh_recognizer 00093 bf::path dpath = "/tmp/training_data"; 00094 vfh_recognizer.cache_enabled_ = true; 00095 vfh_recognizer.initialize (false, dpath, 0, 41); 00096 vfh_recognizer.setApplyVoxelGrid(false); 00097 vfh_recognizer.setApplyICP(true); 00098 vfh_recognizer.setICPIterations(10); 00099 } 00100 00101 void TabletopVFHClassifier::publishFitMarkers( 00102 const std::vector<household_objects_database_msgs::DatabaseModelPoseList> &potential_models, 00103 std::string frame_id) 00104 { 00105 for (size_t i=0; i<potential_models.size(); i++) 00106 { 00107 const std::vector<household_objects_database_msgs::DatabaseModelPose> models = potential_models[i].model_list; 00108 for (size_t j=0; j<models.size(); j++) 00109 { 00110 household_objects_database_msgs::GetModelMesh get_mesh; 00111 get_mesh.request.model_id = models[j].model_id; 00112 if ( !get_model_mesh_srv_.call(get_mesh) || 00113 get_mesh.response.return_code.code != get_mesh.response.return_code.SUCCESS ) 00114 { 00115 ROS_ERROR("tabletop_object_detector: failed to call database get mesh service for marker display"); 00116 } 00117 else 00118 { 00119 double rank = ((double)j) / std::max( (int)(models.size())-1, 1 ); 00120 visualization_msgs::Marker fitMarker = MarkerGenerator::getFitMarker(get_mesh.response.mesh, rank); 00121 fitMarker.header.stamp = ros::Time::now(); 00122 fitMarker.header.frame_id = frame_id; 00123 fitMarker.pose = models[j].pose.pose; 00124 fitMarker.ns = "tabletop_node_model_" + boost::lexical_cast<std::string>(j); 00125 fitMarker.id = current_marker_id_++; 00126 marker_pub_.publish(fitMarker); 00127 } 00128 } 00129 } 00130 } 00131 00132 void TabletopVFHClassifier::clearOldMarkers(std::string frame_id) 00133 { 00134 for (int id=current_marker_id_; id < num_markers_published_; id++) 00135 { 00136 visualization_msgs::Marker delete_marker; 00137 delete_marker.header.stamp = ros::Time::now(); 00138 delete_marker.header.frame_id = frame_id; 00139 delete_marker.id = id; 00140 delete_marker.action = visualization_msgs::Marker::DELETE; 00141 //a hack, but we don't know what namespace the marker was in 00142 for (size_t j=0; j<10; j++) 00143 { 00144 delete_marker.ns = "tabletop_node_model_" + boost::lexical_cast<std::string>(j); 00145 marker_pub_.publish(delete_marker); 00146 } 00147 } 00148 num_markers_published_ = current_marker_id_; 00149 current_marker_id_ = 0; 00150 } 00151 00152 00153 bool 00154 TabletopVFHClassifier::serviceCallback (TabletopObjectRecognition::Request &request, 00155 TabletopObjectRecognition::Response &response) 00156 { 00157 //std::vector < boost::shared_ptr<household_objects_database::DatabaseView> > views; 00158 ROS_INFO("Incoming service call"); 00159 //iterate over the clusters and call detection 00160 for (size_t i = 0; i < request.clusters.size (); ++i) 00161 { 00162 ROS_INFO("Processing model %d", i); 00163 int numModels = request.num_models; 00164 std::vector<int> scaled_model_ids; 00165 std::vector<float> confidences; 00166 std::vector < geometry_msgs::Pose > poses; 00167 00168 std::cout << "NUM_MODELS:" << numModels << std::endl; 00169 numModels = 10; 00170 //transform cluster to sensor_msg/PointCloud2 00171 sensor_msgs::PointCloud2* pc2 = new sensor_msgs::PointCloud2; 00172 ROS_INFO(" Original point cloud has %d points in frame %s", request.clusters[i].points.size(), 00173 request.clusters[i].header.frame_id.c_str()); 00174 sensor_msgs::convertPointCloudToPointCloud2(request.clusters[i], *pc2); 00175 ROS_INFO(" Converted point cloud has data size %d", (int)pc2->data.size()); 00176 sensor_msgs::PointCloud2Ptr msg(pc2); 00177 vfh_recognizer.detect (msg, numModels, scaled_model_ids, poses, confidences, true); 00178 ROS_INFO(" Recognition complete. Found %d models", (int)scaled_model_ids.size()); 00179 00180 household_objects_database_msgs::DatabaseModelPoseList model_potential_fit_list; 00181 00182 for (size_t j=0; j < request.num_models; j++) { 00183 //create the model fit result 00184 //std::cout << poses[i] << std::endl; 00185 household_objects_database_msgs::DatabaseModelPose pose_msg; 00186 pose_msg.model_id = scaled_model_ids[j]; 00187 std::cout << "id:" << scaled_model_ids[j] << std::endl; 00188 pose_msg.pose.header = request.clusters[i].header; 00189 pose_msg.pose.pose = poses[j]; 00190 pose_msg.confidence = confidences[j]; 00191 //and push it in the list for this cluster 00192 model_potential_fit_list.model_list.push_back(pose_msg); 00193 } 00194 00195 //add the models together with pose to the response 00196 response.models.push_back(model_potential_fit_list); 00197 00198 response.cluster_model_indices.push_back(i); 00199 ROS_INFO(" Model %d complete", (int)i); 00200 } 00201 ROS_INFO("Recognition done. Publishing markers."); 00202 publishFitMarkers(response.models, request.table.pose.header.frame_id); 00203 clearOldMarkers(request.table.pose.header.frame_id); 00204 return true; 00205 } 00206 } //namespace tabletop_vfh_cluster_detector 00207 00208 int 00209 main (int argc, char **argv) 00210 { 00211 ros::init (argc, argv, "tabletop_vfh_classifier"); 00212 ros::NodeHandle nh; 00213 00214 tabletop_vfh_cluster_detector::TabletopVFHClassifier node (nh); 00215 ros::spin (); 00216 return 0; 00217 }