handle_search.cpp
Go to the documentation of this file.
00001 #include <agile_grasp/handle_search.h>
00002 
00003 
00004 std::vector<Handle> HandleSearch::findHandles(const std::vector<GraspHypothesis>& hand_list, int min_inliers,
00005   double min_length)
00006 {
00007   double t0 = omp_get_wtime();
00008   std::vector<Handle> handle_list;
00009   std::vector<GraspHypothesis> reduced_hand_list(hand_list);
00010 
00011         for (int i = 0; i < hand_list.size(); i++)
00012         {
00013     if (reduced_hand_list[i].getGraspWidth() == -1)
00014       continue;
00015     
00016     Eigen::Vector3d iaxis = reduced_hand_list[i].getAxis();
00017                 Eigen::Vector3d ipt = reduced_hand_list[i].getGraspBottom();
00018                 Eigen::Vector3d inormal = reduced_hand_list[i].getApproach();
00019     std::vector<Eigen::Vector2d> inliers;
00020     
00021     for (int j = 0; j < hand_list.size(); j++)
00022     {
00023       if (reduced_hand_list[j].getGraspWidth() == -1)
00024         continue;
00025       
00026       Eigen::Vector3d jaxis = reduced_hand_list[j].getAxis();
00027                         Eigen::Vector3d jpt = reduced_hand_list[j].getGraspBottom();
00028                         Eigen::Vector3d jnormal = reduced_hand_list[j].getApproach();
00029       
00030       // how good is this match?
00031                         double dist_from_line = ((Eigen::Matrix3d::Identity(3, 3) - iaxis * iaxis.transpose()) * (jpt - ipt)).norm();
00032                         double dist_along_line = iaxis.transpose() * (jpt - ipt);
00033                         Eigen::Vector2d angle_axis;
00034                         angle_axis << safeAcos(iaxis.transpose() * jaxis), M_PI - safeAcos(iaxis.transpose() * jaxis);
00035                         double dist_angle_axis = angle_axis.minCoeff();
00036                         double dist_from_normal = safeAcos(inormal.transpose() * jnormal);
00037                         if (dist_from_line < 0.01 && dist_angle_axis < 0.34 && dist_from_normal < 0.34)
00038                         {
00039         Eigen::Vector2d inlier;
00040                                 inlier << j, dist_along_line;
00041                                 inliers.push_back(inlier);
00042                         }
00043     }
00044     
00045     if (inliers.size() < min_inliers)
00046                         continue;
00047 
00048                 // shorten handle to a continuous piece
00049                 double handle_gap_threshold = 0.02;
00050                 std::vector<Eigen::Vector2d> inliers_list(inliers.begin(), inliers.end());
00051                 while (!shortenHandle(inliers_list, handle_gap_threshold))
00052                 {       };
00053     
00054     if (inliers_list.size() < min_inliers)
00055       continue;
00056     
00057                 // find grasps farthest away from i-th grasp 
00058     double min_dist = 10000000;
00059                 double max_dist = -10000000;
00060     std::vector<int> in(inliers_list.size());
00061                 for (int k = 0; k < inliers_list.size(); k++)
00062                 {
00063       in[k] = inliers_list[k](0);
00064       
00065                         if (inliers_list[k](1) < min_dist)
00066                                 min_dist = inliers_list[k](1);
00067                         if (inliers_list[k](1) > max_dist)
00068                                 max_dist = inliers_list[k](1);
00069                 }
00070     
00071     // handle found
00072     if (max_dist - min_dist > min_length)
00073     {
00074       handle_list.push_back(Handle(hand_list, in));
00075       std::cout << "handle found with " << in.size() << " inliers\n";
00076       
00077       // eliminate hands in this handle from future search
00078                         for (int k = 0; k < in.size(); k++)
00079                         {
00080                                 reduced_hand_list[in[k]].setGraspWidth(-1);
00081                         }
00082     }
00083   }
00084   
00085   std::cout << "Handle Search\n";
00086   std::cout << " runtime: " << omp_get_wtime() - t0 << " sec\n";
00087         std::cout << " " << handle_list.size() << " handles found\n"; 
00088   return handle_list; 
00089 }
00090 
00091 
00092 bool HandleSearch::shortenHandle(std::vector<Eigen::Vector2d> &inliers, double gap_threshold)
00093 {
00094         std::sort(inliers.begin(), inliers.end(), HandleSearch::LastElementComparator());
00095         bool is_done = true;
00096 
00097         for (int i = 0; i < inliers.size() - 1; i++)
00098         {
00099                 double diff = inliers[i + 1](1) - inliers[i](1);
00100                 if (diff > gap_threshold)
00101                 {
00102                         std::vector<Eigen::Vector2d> out;
00103                         if (inliers[i](2) < 0)
00104                         {
00105                                 out.assign(inliers.begin() + i + 1, inliers.end());
00106                                 is_done = false;
00107                         }
00108                         else
00109                         {
00110                                 out.assign(inliers.begin(), inliers.begin() + i);
00111                         }
00112                         inliers = out;
00113                         break;
00114                 }
00115         }
00116 
00117         return is_done;
00118 }
00119 
00120 void HandleSearch::plotHandles(const std::vector<Handle>& handle_list, const PointCloud::Ptr& cloud,
00121                 std::string str)
00122 {
00123   std::cout << "Drawing " << handle_list.size() << " handles.\n";
00124   
00125         double colors[9][3] = { { 0, 0.4470, 0.7410 }, { 0.8500, 0.3250, 0.0980 }, { 0.9290, 0.6940, 0.1250 }, {
00126                         0.4940, 0.1840, 0.5560 }, { 0.4660, 0.6740, 0.1880 }, { 0.3010, 0.7450, 0.9330 }, { 0.6350, 0.0780,
00127                         0.1840 }, { 0, 0.4470, 0.7410 }, { 0.8500, 0.3250, 0.0980 } };
00128 
00129         //          0.9290    0.6940    0.1250
00130         //          0.4940    0.1840    0.5560
00131         //          0.4660    0.6740    0.1880
00132         //          0.3010    0.7450    0.9330
00133         //          0.6350    0.0780    0.1840
00134         //               0    0.4470    0.7410
00135         //          0.8500    0.3250    0.0980
00136         //          0.9290    0.6940    0.1250
00137         //          0.4940    0.1840    0.5560
00138         //          0.4660    0.6740    0.1880
00139         //          0.3010    0.7450    0.9330
00140         //          0.6350    0.0780    0.1840
00141 
00142         std::vector<pcl::PointCloud<pcl::PointNormal>::Ptr> clouds;
00143         pcl::PointCloud<pcl::PointNormal>::Ptr handle_cloud(new pcl::PointCloud<pcl::PointNormal>());
00144 
00145         for (int i = 0; i < handle_list.size(); i++)
00146         {
00147                 pcl::PointNormal p;
00148                 p.x = handle_list[i].getHandsCenter()(0);
00149                 p.y = handle_list[i].getHandsCenter()(1);
00150                 p.z = handle_list[i].getHandsCenter()(2);
00151                 p.normal[0] = -handle_list[i].getApproach()(0);
00152                 p.normal[1] = -handle_list[i].getApproach()(1);
00153                 p.normal[2] = -handle_list[i].getApproach()(2);
00154                 handle_cloud->points.push_back(p);
00155 
00156                 const std::vector<int>& inliers = handle_list[i].getInliers();
00157                 const std::vector<GraspHypothesis>& hand_list = handle_list[i].getHandList();
00158                 pcl::PointCloud<pcl::PointNormal>::Ptr axis_cloud(new pcl::PointCloud<pcl::PointNormal>);
00159 
00160                 for (int j = 0; j < inliers.size(); j++)
00161                 {
00162                         pcl::PointNormal p;
00163                         p.x = hand_list[inliers[j]].getGraspSurface()(0);
00164                         p.y = hand_list[inliers[j]].getGraspSurface()(1);
00165                         p.z = hand_list[inliers[j]].getGraspSurface()(2);
00166                         p.normal[0] = -hand_list[inliers[j]].getApproach()(0);
00167                         p.normal[1] = -hand_list[inliers[j]].getApproach()(1);
00168                         p.normal[2] = -hand_list[inliers[j]].getApproach()(2);
00169                         axis_cloud->points.push_back(p);
00170                 }
00171                 clouds.push_back(axis_cloud);
00172         }
00173 
00174         std::string title = "Handles: " + str;
00175         boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer(title));
00176         viewer->setBackgroundColor(1, 1, 1);
00177   //viewer->setPosition(0, 0);
00178   //viewer->setSize(640, 480);  
00179         viewer->addPointCloud<pcl::PointXYZ>(cloud, "registered point cloud");
00180         viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1,
00181                         "registered point cloud");
00182         viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0.0, 1.0, 0.0,
00183                         "registered point cloud");
00184 
00185         for (int i = 0; i < clouds.size(); i++)
00186         {
00187                 std::string name = "handle_" + boost::lexical_cast<std::string>(i);
00188                 int ci = i % 6;
00189 //              std::cout << "ci: " << ci << "\n";
00190                 viewer->addPointCloud<pcl::PointNormal>(clouds[i], name);
00191                 viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, colors[ci][0],
00192                                 colors[ci][1], colors[ci][2], name);
00193                 std::string name2 = "approach_" + boost::lexical_cast<std::string>(i);
00194                 viewer->addPointCloudNormals<pcl::PointNormal>(clouds[i], 1, 0.04, name2);
00195                 viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 2, name2);
00196                 viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, colors[ci][0],
00197                                 colors[ci][1], colors[ci][2], name2);
00198         }
00199 
00200         viewer->addPointCloud<pcl::PointNormal>(handle_cloud, "handles");
00201         viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "handles");
00202         viewer->addPointCloudNormals<pcl::PointNormal>(handle_cloud, 1, 0.08, "approach");
00203         viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 4, "approach");
00204         viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "approach");
00205 
00206         // viewer->addCoordinateSystem(1.0, "", 0);
00207         viewer->initCameraParameters();
00208   viewer->setPosition(0, 0);
00209         viewer->setSize(640, 480);
00210 
00211         while (!viewer->wasStopped())
00212         {
00213                 viewer->spinOnce(100);
00214                 boost::this_thread::sleep(boost::posix_time::microseconds(100000));
00215         }
00216   
00217   viewer->close();
00218 
00219         //      std::vector<pcl::visualization::Camera> cam;
00220         //
00221         //      // print the position of the camera
00222         //      viewer->getCameras(cam);
00223         //      std::cout << "Cam: " << std::endl << " - pos: (" << cam[0].pos[0] << ", " << cam[0].pos[1] << ", "
00224         //                      << cam[0].pos[2] << ")" << std::endl << " - view: (" << cam[0].view[0] << ", " << cam[0].view[1] << ", "
00225         //                      << cam[0].view[2] << ")" << std::endl << " - focal: (" << cam[0].focal[0] << ", " << cam[0].focal[1]
00226         //                      << ", " << cam[0].focal[2] << ")" << std::endl;
00227 }
00228 
00229 double HandleSearch::safeAcos(double x)
00230 {
00231         if (x < -1.0)
00232                 x = -1.0;
00233         else if (x > 1.0)
00234                 x = 1.0;
00235         return acos(x);
00236 }


agile_grasp
Author(s):
autogenerated on Thu Aug 27 2015 12:01:28