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
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
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
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
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
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
00121 double HandleSearch::safeAcos(double x)
00122 {
00123 if (x < -1.0)
00124 x = -1.0;
00125 else if (x > 1.0)
00126 x = 1.0;
00127 return acos(x);
00128 }