Go to the documentation of this file.00001 #include "ros/ros.h"
00002 #include "narf_recognition/LocateObjects.h"
00003 #include <iostream>
00004 #include <exception>
00005 using namespace std;
00006
00007 #include <narf_recognition/object_recognition_helper.h>
00008 #include <boost/thread/thread.hpp>
00009 #include "pcl/console/parse.h"
00010
00011 #include "pcl/visualization/range_image_visualizer.h"
00012 #include "pcl/visualization/pcl_visualizer.h"
00013
00014 #include "Eigen/Geometry"
00015 #include "pcl/point_cloud.h"
00016 #include "pcl/point_types.h"
00017
00018 #include "pcl/io/pcd_io.h"
00019 #include "pcl/range_image/range_image.h"
00020 #include "pcl/features/narf.h"
00021
00022 #include "pcl/common/point_correspondence.h"
00023 #include "pcl/common/poses_from_matches.h"
00024 #include "pcl/features/range_image_border_extractor.h"
00025 #include "pcl/keypoints/narf_keypoint.h"
00026 #include "pcl/range_image/range_image_planar.h"
00027 #include "sensor_msgs/Image.h"
00028 #include "pcl/common/file_io.h"
00029
00030
00031
00032 #include "pcl/common/common_headers.h"
00033
00034 #include "ros/ros.h"
00035
00036 #include <pcl/visualization/cloud_viewer.h>
00037 #include <ros/ros.h>
00038 #include <pcl_ros/point_cloud.h>
00039 #include <pcl/point_types.h>
00040 #include <boost/foreach.hpp>
00041 #include <pcl/ModelCoefficients.h>
00042 #include <pcl/io/pcd_io.h>
00043 #include <pcl/point_types.h>
00044 #include <pcl/sample_consensus/method_types.h>
00045 #include <pcl/sample_consensus/model_types.h>
00046 #include <pcl/segmentation/sac_segmentation.h>
00047 #include "pcl/visualization/pcl_visualizer.h"
00048 #include <pcl/filters/extract_indices.h>
00049 #include <pcl/filters/passthrough.h>
00050 #include <pcl/features/normal_3d.h>
00051 #include <pcl/filters/voxel_grid.h>
00052 #include <pcl/kdtree/kdtree.h>
00053 #include <pcl/segmentation/extract_clusters.h>
00054 #include <pcl/console/parse.h>
00055 #include <cstdlib>
00056 #include <iostream>
00057 #include <boost/thread/thread.hpp>
00058 #include "pcl/range_image/range_image.h"
00059 #include "pcl/features/range_image_border_extractor.h"
00060 #include <pcl_ros/impl/transforms.hpp>
00061 #include "narf_recognition/Locate_Server.h"
00062
00063 using namespace pcl;
00064 using namespace pcl::visualization;
00065
00066 Locate_Server::Locate_Server(ros::NodeHandle& n) :
00067 nh(n) {
00068 noise_level_factor = 0.1;
00069 support_size_factor = 0.5f;
00070
00071 show_model_views = 1;
00072 show_view_simulation_results = 0;
00073 show_validation_points = 0;
00074 show_found_objects = 1;
00075 show_feature_match_positions = 0;
00076 show_interest_points = 0;
00077 print_timings = true;
00078
00079 cloud_received = false;
00080 got_new_data = false;
00081
00082
00083
00084
00085 viewer = new pcl::visualization::PCLVisualizer("3D Viewer");
00086 ObjectRecognitionHelper::Parameters& orh_params =
00087 object_recognition_helper.getParameters();
00088 FalsePositivesFilter& false_positives_filter =
00089 object_recognition_helper.getFalsePositivesFilter();
00090 FalsePositivesFilter::Parameters& fpf_params =
00091 false_positives_filter.getParameters();
00092
00093 orh_params.view_sampling_first_layer = 0;
00094 orh_params.view_sampling_last_layer = 0;
00095
00096 set_unseen_to_max_range = true;
00097 fpf_params.do_icp = false;
00098 max_no_of_threads = 2;
00099 angular_resolution = deg2rad(0.3);
00100 use_rotation_invariance = true;
00101
00102 vector<RangeImage> view_simulation_results;
00103 if (show_view_simulation_results)
00104 false_positives_filter.setViewSimulationImagesPtr(
00105 &view_simulation_results);
00106
00107 sub = nh.subscribe<sensor_msgs::PointCloud2>("/camera/rgb/points", 1,
00108 &Locate_Server::cloud_cb_, this);
00109
00110 XmlRpc::XmlRpcValue file_list;
00111
00112 std::vector<std::string> filenames;
00113 std::string key;
00114 key.assign("locate_objects_server/filenames");
00115 n.getParam(key, file_list);
00116
00117 for (unsigned int i = 0; i < file_list.size(); i++) {
00118 filenames.push_back(file_list[i]);
00119 std::cout << filenames[i] << std::endl;
00120 }
00121 std::cout << "got filenames. \n";
00122 if (got_new_data) {
00123 getModels(filenames);
00124 }
00125
00126 got_new_data = false;
00127
00128 ros::Rate r(10);
00129 while (!cloud_received) {
00130 ros::spinOnce();
00131 r.sleep();
00132 }
00133
00134 service = n.advertiseService("locate_objects", &Locate_Server::locate, this);
00135
00136 ROS_INFO("Ready to locate objects.");
00137
00138
00139
00140 }
00141
00142 Locate_Server::~Locate_Server() {
00143 delete viewer;
00144 }
00145 void Locate_Server::getModels(std::vector<string> model_filenames) {
00146 if (model_filenames.size() == 0) {
00147 cout << "No*.pcd file for model given.\n\n";
00148 exit(0);
00149 }
00150
00151 object_models =
00152 object_recognition_helper.getIntermediateElements().object_models;
00153 if (!object_recognition_helper.addObjectModelsFromPcdFiles(
00154 model_filenames)) {
00155
00156 exit(1);
00157 }
00158
00159 float average_model_radius = object_models.getAverageModelRadius();
00160 float support_size = support_size_factor * average_model_radius;
00161 float noise_level = noise_level_factor * average_model_radius;
00162 cout << "\n-----\n" << "The average object model radius is "
00163 << average_model_radius << "m.\n" << " => using support size "
00164 << support_size << "m.\n" << " => using noise level "
00165 << noise_level << "m.\n" << "-----\n\n";
00166 orh_params.support_size = support_size;
00167 orh_params.noise_level = noise_level;
00168
00169 }
00170
00171 void Locate_Server::cloud_cb_(const sensor_msgs::PointCloud2 msg) {
00172
00173 PointCloud<PointXYZ> point_cloud;
00174 PointCloud<PointWithViewpoint> far_ranges;
00175 fromROSMsg(msg, point_cloud);
00176
00177
00178 RangeImage::extractFarRanges(msg, far_ranges);
00179 if (!object_recognition_helper.createRangeImageFromPointCloud(point_cloud,
00180 &far_ranges)) {
00181 std::cout << "Failed to create Range Image From Point Cloud. \n";
00182 }
00183 got_new_data = true;
00184 cloud_received = true;
00185 }
00186
00187 void Locate_Server::visualize(
00188 PCLVisualizer& viewer,
00189 std::vector<PosesFromMatches::PoseEstimatesVector>& pose_estimates_per_model,
00190 std::vector<string>& point_clouds_in_viewer) {
00191 boost::shared_ptr<RangeImage>& scene_range_image_ptr =
00192 object_recognition_helper.getIntermediateElements().scene_range_image_ptr;
00193
00194 vector<boost::shared_ptr<ObjectModel::PointCloudType> > objects_in_scene;
00195 for (unsigned int model_idx = 0; model_idx < object_models.size();
00196 ++model_idx) {
00197
00198 PosesFromMatches::PoseEstimatesVector& pose_estimates =
00199 pose_estimates_per_model[model_idx];
00200 ObjectModel& object_model = *object_models[model_idx];
00201
00202 for (unsigned int pose_estimate_idx = 0;
00203 pose_estimate_idx < pose_estimates.size() && show_found_objects;
00204 ++pose_estimate_idx) {
00205 const PosesFromMatches::PoseEstimate& pose_estimate =
00206 pose_estimates[pose_estimate_idx];
00207 objects_in_scene.push_back(
00208 boost::shared_ptr<ObjectModel::PointCloudType>(
00209 new ObjectModel::PointCloudType));
00210 object_model.getTransformedPointCloud(pose_estimate.transformation,
00211 *objects_in_scene.back());
00212 }
00213 }
00214
00215
00216 if (objects_in_scene.size() > 0) {
00217 for (unsigned int i = 0; i < point_clouds_in_viewer.size(); ++i)
00218 viewer.removePointCloud(point_clouds_in_viewer[i]);
00219
00220 point_clouds_in_viewer.clear();
00221
00222
00223 PointCloudColorHandlerCustom<pcl::PointWithRange> color_handler_cloud(
00224 scene_range_image_ptr, 0, 0, 0);
00225 point_clouds_in_viewer.push_back("scene_range_image");
00226 viewer.addPointCloud<PointWithRange>(scene_range_image_ptr,
00227 color_handler_cloud, point_clouds_in_viewer.back());
00228 point_clouds_in_viewer.push_back("feature_match_positions");
00229 viewer.setPointCloudRenderingProperties(PCL_VISUALIZER_POINT_SIZE, 7,
00230 point_clouds_in_viewer.back());
00231 for (unsigned int i = 0; i < objects_in_scene.size(); ++i) {
00232 stringstream ss;
00233 ss << "Found object " << i;
00234 point_clouds_in_viewer.push_back(ss.str());
00235 PointCloudColorHandlerRandom<ObjectModel::PointCloudType::PointType> color_handler(
00236 objects_in_scene[i]);
00237 viewer.addPointCloud<ObjectModel::PointCloudType::PointType>(
00238 objects_in_scene[i], color_handler,
00239 point_clouds_in_viewer.back());
00240 }
00241 }
00242
00243 }
00244
00245 bool Locate_Server::locate(narf_recognition::LocateObjects::Request &req,
00246 narf_recognition::LocateObjects::Response &res) {
00247
00248 std::cout << "started locating. \n";
00249
00250 object_recognition_helper.extractModelFeatures();
00251 object_recognition_helper.getIntermediateElements().database_feature_sources;
00252 std::cout << "Got Model Features.\n";
00253
00254 viewer->setBackgroundColor(1, 1, 1);
00255
00256
00257
00258 vector<string> point_clouds_in_viewer;
00259 RangeImageVisualizer scene_range_image_widget("scene range image");
00260 vector<RangeImageVisualizer*> view_simulation_result_widgets;
00261 vector<RangeImageVisualizer*> interest_points_widgets;
00262 vector<RangeImageVisualizer*> range_image_widgets;
00263
00264 if (!got_new_data) {
00265 if (!cloud_received) {
00266 std::cout << "No cloud received yet. \n";
00267 }
00268 return false;
00269
00270 }
00271 got_new_data = false;
00272 cout << "Got new data.\n";
00273
00274 object_recognition_helper.extractSceneFeatures();
00275 object_recognition_helper.extractPoseEstimates();
00276 std::vector<PosesFromMatches::PoseEstimatesVector>& pose_estimates_per_model =
00277 object_recognition_helper.filterFalsePositives();
00278 object_recognition_helper.printTimings();
00279
00280 std::vector<PosesFromMatches::PoseEstimatesVector> poses =
00281 object_recognition_helper.getIntermediateElements().pose_estimates_per_model;
00282 size_t numPoseEstimates = poses.size();
00283
00284 for (unsigned int i = 0; i < numPoseEstimates; i++) {
00285 for (unsigned int j = 0; j < poses[i].size(); j++) {
00286 Eigen::Affine3f eigen_pose = poses[i][j].transformation;
00287
00288 Eigen::Quaternionf rot(eigen_pose.rotation());
00289 Eigen::Vector3f origin(eigen_pose.translation());
00290
00291 geometry_msgs::Pose pose;
00292 pose.position.x = origin[0];
00293 pose.position.y = origin[1];
00294 pose.position.z = origin[2];
00295
00296 pose.orientation.w = rot.w();
00297 pose.orientation.x = rot.x();
00298 pose.orientation.y = rot.y();
00299 pose.orientation.z = rot.z();
00300 res.pos.push_back(pose);
00301 }
00302 }
00304
00305 visualize(*viewer, pose_estimates_per_model, point_clouds_in_viewer);
00306 viewer->spinOnce(100);
00307
00308
00309 ROS_INFO("sending back response.");
00310 return true;
00311
00312
00313 }
00314
00315 int main(int argc, char **argv) {
00316 ros::init(argc, argv, "locate_objects_server");
00317 ros::NodeHandle n;
00318
00319 Locate_Server locator(n);
00320 while (ros::ok() && !locator.viewer->wasStopped()) {
00321 locator.viewer->spinOnce(100);
00322 ros::spinOnce();
00323 }
00324 return 0;
00325 }