00001
00002 #include <coverage_3d_planning/NeighborhoodGraph.h>
00003 #include <coverage_3d_tools/conversions.h>
00004 #include <coverage_3d_arm_navigation/openrave_ik.h>
00005 #include <eigen3/Eigen/src/Core/EigenBase.h>
00006 #include <eigen3/Eigen/src/Geometry/Quaternion.h>
00007 #include <pcl/kdtree/kdtree_flann.h>
00008
00009 #include <tf/tf.h>
00010 #include <voro/voro++.hh>
00011
00012 NeighborhoodGraph::NeighborhoodGraph(ros::NodeHandle& nh) :
00013 nh_(nh), dist_above_surface_(0.06), max_neigborhood_(8), max_neigborhood_radius_(0.08), octomap_(0), coll_checker_(
00014 0), n_ik_samples_(1), coll_check_(true) {
00015 if (coll_check_) {
00016 coll_checker_ = new CollisionCheck(nh_);
00017 }
00018 }
00019 NeighborhoodGraph::NeighborhoodGraph(ros::NodeHandle& nh, bool coll_check) :
00020 nh_(nh), dist_above_surface_(0.06), max_neigborhood_(8), max_neigborhood_radius_(0.08), octomap_(0), coll_checker_(
00021 0), n_ik_samples_(1), coll_check_(coll_check) {
00022 if (coll_check_) {
00023 coll_checker_ = new CollisionCheck(nh_);
00024 }
00025 }
00026
00027 NeighborhoodGraph::NeighborhoodGraph(ros::NodeHandle& nh, std::vector<SurfacePatch> patches,
00028 octomap::OctomapROS<octomap::OcTree>* octomap) :
00029 nh_(nh), dist_above_surface_(0.06), max_neigborhood_(8), max_neigborhood_radius_(0.08), octomap_(0), coll_checker_(
00030 0), n_ik_samples_(1), coll_check_(true) {
00031 surface_ = patches;
00032 octomap_ = octomap;
00033 if (coll_check_) {
00034 coll_checker_ = new CollisionCheck(nh_);
00035 }
00036 }
00037
00038 NeighborhoodGraph::NeighborhoodGraph(ros::NodeHandle& nh, std::vector<SurfacePatch> patches,
00039 octomap::OctomapROS<octomap::OcTree>* octomap, double dist_above_surface, int max_neigborhood,
00040 double max_neigborhood_radius, int n_ik_samples, bool coll_check) :
00041 nh_(nh), dist_above_surface_(dist_above_surface), max_neigborhood_(max_neigborhood), max_neigborhood_radius_(
00042 max_neigborhood_radius), octomap_(0), coll_checker_(0), n_ik_samples_(n_ik_samples), coll_check_(
00043 coll_check) {
00044 surface_ = patches;
00045 octomap_ = octomap;
00046 if (coll_check_) {
00047 coll_checker_ = new CollisionCheck(nh_);
00048 }
00049 }
00050
00051 NeighborhoodGraph::~NeighborhoodGraph() {
00052 if (coll_check_) {
00053 delete coll_checker_;
00054 }
00055
00056 }
00057 void NeighborhoodGraph::setPatches(std::vector<SurfacePatch> patches) {
00058 surface_ = patches;
00059 }
00060 void NeighborhoodGraph::setSurfaceDist(double dist) {
00061 dist_above_surface_ = dist;
00062 }
00063
00064 void NeighborhoodGraph::setOctomap(octomap::OctomapROS<octomap::OcTree>* octomap) {
00065 octomap_ = octomap;
00066 }
00067
00068 void NeighborhoodGraph::getReachableVector(std::vector<bool>& reachable) {
00069 reachable = reachable_surface_;
00070 }
00071 void NeighborhoodGraph::sampleSurfacePoints(const std::vector<SurfacePatch>& surface,
00072 std::vector<pcl::PointXYZ>& samples) const {
00073
00074 samples.clear();
00075 float dist = dist_above_surface_;
00076
00077 for (unsigned int i = 0; i < surface.size(); ++i) {
00078
00079 SurfacePatch patch = surface[i];
00080 Eigen::Vector3f tmp = patch.getVector3fMap() + (dist * patch.getNormalVector3fMap().normalized());
00081 tmp = tmp + ((patch.scale_z / 2.0) * patch.getNormalVector3fMap().normalized());
00082 samples.push_back(VectorEigen2PointXYZ(tmp));
00083 }
00084 }
00085 void NeighborhoodGraph::sampleSurfacePoints(const std::vector<SurfacePatch>& surface,
00086 pcl::PointCloud<pcl::PointXYZ>& samples) const {
00087
00088 samples.clear();
00089 float dist = dist_above_surface_;
00090
00091 for (unsigned int i = 0; i < surface.size(); ++i) {
00092
00093 SurfacePatch patch = surface[i];
00094 Eigen::Vector3f tmp = patch.getVector3fMap() + (dist * patch.getNormalVector3fMap().normalized());
00095 tmp = tmp + ((patch.scale_z / 2.0) * patch.getNormalVector3fMap().normalized());
00096 samples.push_back(VectorEigen2PointXYZ(tmp));
00097 }
00098 }
00099 void NeighborhoodGraph::buildAdjacencyMatrixUsingOctomap() {
00100
00101
00102 ROS_INFO_STREAM("NeighborhoodGraph Computing Adjacency Matrix from " << surface_.size() << "patches");
00103
00104 pcl::PointCloud<pcl::PointXYZ> samples;
00105 sampleSurfacePoints(surface_, samples);
00106 octomap::Pointcloud octocloud;
00107 octomap::pointcloudPCLToOctomap(samples, octocloud);
00108
00109 pcl::KdTreeFLANN<pcl::PointXYZ> tree;
00110 tree.setInputCloud(samples.makeShared());
00111
00112 adjacency_ = Eigen::MatrixXi::Zero(octocloud.size(), octocloud.size());
00113 ROS_DEBUG_STREAM("NeighborhoodGraph::buildAdjacencyMatrixUsingOctomap " << octocloud.size() << " " << samples.size());
00114 ROS_DEBUG_STREAM("NeighborhoodGraph::buildAdjacencyMatrixUsingOctomap max neighborhood " << max_neigborhood_ << " " << max_neigborhood_radius_);
00115 omp_set_num_threads(6);
00116 for (unsigned int i = 0; i < octocloud.size(); ++i) {
00117 std::vector<int> inlier;
00118 std::vector<float> dist;
00119 tree.radiusSearch(samples[i], max_neigborhood_radius_, inlier, dist);
00120
00121
00122 unsigned int n_inliers = max_neigborhood_;
00123 if (inlier.size() < n_inliers) {
00124 n_inliers = inlier.size();
00125 }
00126 #pragma omp parallel for
00127 for (unsigned int j = 0; j < n_inliers; ++j) {
00128 octomap::point3d origin = octocloud.getPoint(i);
00129 octomap::point3d end = octocloud.getPoint(inlier[j]);
00130 octomap::point3d dir = end - origin;
00131 if (i != (unsigned int) inlier[j]) {
00132 float dist = dir.norm();
00133
00134
00135 if (!octomap_->octree.castRay(origin, dir, end, false, dist)) {
00136 if (octomap_->octree.search(end)) {
00137 adjacency_(i, inlier[j]) = 1;
00138 adjacency_(inlier[j], i) = 1;
00139 }
00140 }
00141
00142 }
00143 }
00144 }
00145 std::cout << "size Surface Adjacency Matrix " << surface_.size() << " " << adjacency_.rows() << " "
00146 << adjacency_.cols() << std::endl;
00147 }
00148
00149 void NeighborhoodGraph::buildAdjacencyMatrixUsingVoronoi() {
00150
00151
00152 std::cout << "Computing Adjacency Matrix using Voronoi Graph" << surface_.size() << std::endl;
00153
00154 pcl::PointCloud<pcl::PointXYZ> samples;
00155 sampleSurfacePoints(surface_, samples);
00156 octomap::Pointcloud octocloud;
00157 octomap::pointcloudPCLToOctomap(samples, octocloud);
00158
00159 Eigen::MatrixXf e_samples = samples.getMatrixXfMap();
00160 adjacency_ = Eigen::MatrixXi::Zero(surface_.size(), surface_.size());
00161
00162
00163
00164 double x_min = e_samples.row(0).array().minCoeff() - 0.001;
00165 double x_max = e_samples.row(0).array().maxCoeff() + 0.001;
00166 double y_min = e_samples.row(1).array().minCoeff() - 0.001;
00167 double y_max = e_samples.row(1).array().maxCoeff() + 0.001;
00168 double z_min = e_samples.row(2).array().minCoeff() - 0.001;
00169 double z_max = e_samples.row(2).array().maxCoeff() + 0.001;
00170
00171
00172 int n_x = 1, n_y = 1, n_z = 1;
00173
00174
00175 voro::container con(x_min, x_max, y_min, y_max, z_min, z_max, n_x, n_y, n_z, false, false, false, 10000);
00176
00177
00178 for (unsigned int i = 0; i < e_samples.cols(); i++) {
00179 con.put(i, e_samples(0, i), e_samples(1, i), e_samples(2, i));
00180 }
00181
00182
00183 voro::c_loop_all vl(con);
00184 voro::voronoicell_neighbor c;
00185 if (vl.start())
00186 do
00187 if (con.compute_cell(c, vl)) {
00188 int idx1 = con.id[vl.ijk][vl.q];
00189 int idx2 = 0;
00190 std::vector<int> local_neighbors;
00191 c.neighbors(local_neighbors);
00192 for (unsigned int j = 0; j < local_neighbors.size(); ++j) {
00193
00194
00195 if (local_neighbors[j] >= 0) {
00196 idx2 = local_neighbors[j];
00197 octomap::point3d origin = octocloud.getPoint(idx1);
00198 octomap::point3d end = octocloud.getPoint(idx2);
00199 octomap::point3d dir = end - origin;
00200 float dist = dir.norm();
00201
00202 if (!octomap_->octree.castRay(origin, dir, end, false, dist)) {
00203
00204 if (octomap_->octree.search(end)) {
00205 if (dist < 0.5) {
00206 adjacency_(idx1, idx2) = 1;
00207 adjacency_(idx2, idx1) = 1;
00208 }
00209 }
00210 }
00211 }
00212 }
00213 } while (vl.inc());
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 }
00227 bool NeighborhoodGraph::isPoseValid(const tf::Pose pose, const bool check_collision,
00228 std::vector<std::vector<double> >& ik_solutions) {
00229
00230
00231 ik_solutions.clear();
00232 std::vector<std::vector<double> > solutions;
00233 getIKSolutions(pose, solutions);
00234
00235 if (solutions.size() > 0) {
00236
00237
00238 for (unsigned int j = 0; j < solutions.size(); ++j) {
00239 if (check_collision) {
00240 if (coll_checker_->checkJointStateRight(solutions[j])) {
00241 ik_solutions.push_back(solutions[j]);
00242 }
00243 } else {
00244 ik_solutions.push_back(solutions[j]);
00245 }
00246 }
00247 }
00248 if (ik_solutions.size() > 0) {
00249 return true;
00250 } else {
00251 return false;
00252 }
00253 }
00254
00255 void NeighborhoodGraph::getValidIKSolutions(const std::vector<tf::Pose>& poses, const bool check_collision,
00256 std::vector<bool>& valid, std::vector<std::vector<std::vector<double> > >& ik_solutions) {
00257
00258 valid.resize(poses.size(), false);
00259 ik_solutions.resize(poses.size());
00260
00261 for (unsigned int i = 0; i < poses.size(); ++i) {
00262 std::vector<std::vector<double> > tmp_solutions;
00263 if (isPoseValid(poses[i], check_collision, tmp_solutions)) {
00264 valid[i] = true;
00265 ik_solutions[i] = tmp_solutions;
00266 }
00267 }
00268 }
00269
00270 void NeighborhoodGraph::depthFirstConnectedComponentSearch(const int node, Eigen::MatrixXi& adjacency,
00271 std::set<int>& graph) {
00272
00273 graph.insert(node);
00274 for (int i = 0; i < adjacency.cols(); ++i) {
00275 if (adjacency(node, i) == 1) {
00276 adjacency(node, i) = 0;
00277 depthFirstConnectedComponentSearch(i, adjacency, graph);
00278 }
00279 }
00280 }
00281 void NeighborhoodGraph::computeConnectedComponents() {
00282 subgraphs_.clear();
00283
00284 std::set<int> usable_indexes;
00285 for (unsigned int i = 0; i < adjacency_.rows(); i++) {
00286 usable_indexes.insert(i);
00287 }
00288 Eigen::MatrixXi tmp = adjacency_;
00289
00290 std::set<int> tmp_set;
00291 while (usable_indexes.size() > 0) {
00292
00293
00294 std::set<int>::iterator it = usable_indexes.begin();
00295 std::advance(it, rand() % usable_indexes.size());
00296 int index = *it;
00297
00298 depthFirstConnectedComponentSearch(index, tmp, tmp_set);
00299
00300
00301 BOOST_FOREACH(int i, tmp_set)
00302 {
00303
00304 it = usable_indexes.find(i);
00305 if (!(it == usable_indexes.end()))
00306 usable_indexes.erase(it);
00307 }
00308 if (tmp_set.size() > 1) {
00309 subgraphs_.push_back(tmp_set);
00310 }
00311 }
00312 }
00313
00314 void NeighborhoodGraph::getSubgraphAdjacency(const std::set<int>& subgraph, std::map<int, int>& index_map,
00315 Eigen::MatrixXi& subgraph_adj, const std::vector<SurfacePatch>& patches,
00316 std::vector<SurfacePatch>& subgraph_patches) {
00317
00318 index_map.clear();
00319 subgraph_patches.clear();
00320 subgraph_adj = Eigen::MatrixXi::Zero(subgraph.size(), subgraph.size());
00321 int k = 0, l = 0;
00322 BOOST_FOREACH(int i, subgraph)
00323 {
00324 l = 0;
00325 index_map.insert(std::pair<int, int>(k, i));
00326 BOOST_FOREACH(int j, subgraph)
00327 {
00328 subgraph_adj(k, l) = adjacency_(i, j);
00329
00330 l++;
00331 }
00332 subgraph_patches.push_back(patches[i]);
00333 k++;
00334 }
00335 }
00336
00337 void NeighborhoodGraph::getIKSolutions(const tf::Pose p, std::vector<std::vector<double> >& ik_solutions) const {
00338 ik_solutions.clear();
00339 int n_free_joints = 1;
00340 int n_joints = 7;
00341
00342 double vfree[n_free_joints];
00343 double eerot[9], eetrans[3];
00344
00345 tf::Matrix3x3 rot = p.getBasis();
00346 tf::Vector3 trans = p.getOrigin();
00347
00348 eerot[0] = rot[0][0];
00349 eerot[1] = rot[0][1];
00350 eerot[2] = rot[0][2];
00351 eerot[3] = rot[1][0];
00352 eerot[4] = rot[1][1];
00353 eerot[5] = rot[1][2];
00354 eerot[6] = rot[2][0];
00355 eerot[7] = rot[2][1];
00356 eerot[8] = rot[2][2];
00357
00358 eetrans[0] = trans[0];
00359 eetrans[1] = trans[1];
00360 eetrans[2] = trans[2];
00361
00362
00363
00364
00365
00366 std::vector<float> vfree_samples;
00367 if (n_ik_samples_ == 1) {
00368 vfree_samples.push_back(-1.51);
00369 } else if (n_ik_samples_ == 2) {
00370 vfree_samples.push_back(-1.75);
00371 vfree_samples.push_back(-1.27);
00372 } else if (n_ik_samples_ == 3) {
00373 vfree_samples.push_back(-1.51);
00374 vfree_samples.push_back(-1.75);
00375 vfree_samples.push_back(-1.27);
00376 } else if (n_ik_samples_ == 5) {
00377 vfree_samples.push_back(-1.51);
00378 vfree_samples.push_back(-1.75);
00379 vfree_samples.push_back(-1.27);
00380 vfree_samples.push_back(-1.03);
00381 vfree_samples.push_back(-1.99);
00382 } else if (n_ik_samples_ == 9) {
00383 vfree_samples.push_back(-1.51);
00384 vfree_samples.push_back(-1.75);
00385 vfree_samples.push_back(-1.27);
00386 vfree_samples.push_back(-1.03);
00387 vfree_samples.push_back(-1.99);
00388 vfree_samples.push_back(-2.23);
00389 vfree_samples.push_back(-0.79);
00390 vfree_samples.push_back(-2.46);
00391 vfree_samples.push_back(-0.55);
00392 } else if (n_ik_samples_ == 10) {
00393 float min = -3.7;
00394 float max = 0.6;
00395 float max_samples = 20;
00396 float dist = (max - min) / max_samples;
00397 for (float i = -3.7; i < 0.6001; i = i + dist) {
00398 vfree_samples.push_back(i);
00399 }
00400 } else if (n_ik_samples_ == 11) {
00401 float min = -3.7;
00402 float max = 0.6;
00403 float max_samples = 50;
00404 float dist = (max - min) / max_samples;
00405 for (float i = -3.7; i < 0.6001; i = i + dist) {
00406 vfree_samples.push_back(i);
00407 }
00408 } else if (n_ik_samples_ == 12) {
00409 float min = -3.7;
00410 float max = 0.6;
00411 float max_samples = 100;
00412 float dist = (max - min) / max_samples;
00413 for (float i = -3.7; i < 0.6001; i = i + dist) {
00414 vfree_samples.push_back(i);
00415 }
00416 } else {
00417 ROS_ERROR("not supported sample number");
00418 }
00419
00420 for (unsigned int i = 0; i < vfree_samples.size(); ++i) {
00421
00422 vfree[0] = vfree_samples[i];
00423 std::vector<IKSolution> vsolutions;
00424 ik(eetrans, eerot, vfree, vsolutions);
00425
00426
00427 std::vector<double> sol(n_joints);
00428 for (std::size_t i = 0; i < vsolutions.size(); ++i) {
00429 std::vector<double> vsolfree(vsolutions[i].GetFree().size());
00430 vsolutions[i].GetSolution(&sol[0], vsolfree.size() > 0 ? &vsolfree[0] : NULL);
00431 ik_solutions.push_back(sol);
00432 }
00433 }
00434
00435 }
00436
00437
00438 void NeighborhoodGraph::computeEndEffectorPose(const SurfacePatch p1, const double dist_above_surface,
00439 std::vector<tf::Pose>& poses, bool single_pose) const {
00440
00441 poses.clear();
00442
00443 Eigen::Vector3f origin = p1.getVector3fMap() + (dist_above_surface * p1.getNormalVector3fMap().normalized())
00444 + ((p1.scale_z / 2.0) * p1.getNormalVector3fMap().normalized());
00445
00446
00447 Eigen::Vector3f z_axis = p1.getVector3fMap() - origin;
00448 z_axis.normalize();
00449
00450
00451
00452
00453 Eigen::Vector3f cross_product = Eigen::Vector3f(0, 0, 1).cross(z_axis);
00454 Eigen::Matrix3f rot_matrix;
00455 cross_product.normalize();
00456 float angle = 0;
00457 if (cross_product.norm() > 0.000000001) {
00458 angle = acos(z_axis.dot(Eigen::Vector3f(0, 0, 1)));
00459 rot_matrix = Eigen::AngleAxis<float>(angle, cross_product).toRotationMatrix();
00460 } else {
00461 double tmp = z_axis.dot(Eigen::Vector3f(0, 0, 1));
00462 if (tmp > 0) {
00463 rot_matrix = Eigen::Matrix3f::Identity();
00464 } else {
00465 angle = M_PI;
00466 rot_matrix = Eigen::AngleAxis<float>(angle, cross_product).toRotationMatrix();
00467 }
00468 }
00469
00470
00471 tf::Pose pose;
00472 pose.setOrigin(tf::Point(origin[0], origin[1], origin[2]));
00473 Eigen::Quaternion<float> quat(rot_matrix);
00474 tf::Quaternion tf_quat(quat.x(), quat.y(), quat.z(), quat.w());
00475 pose.setRotation(tf_quat);
00476 poses.push_back(pose);
00477
00478 if (!single_pose) {
00479
00480 angle = M_PI / 8.0;
00481 rot_matrix = Eigen::AngleAxis<float>(angle, Eigen::Vector3f(0, 0, 1)).toRotationMatrix();
00482 quat = Eigen::Quaternion<float>(rot_matrix);
00483 tf_quat = tf::Quaternion(quat.x(), quat.y(), quat.z(), quat.w());
00484 pose.setRotation(tf_quat);
00485 poses.push_back(pose);
00486
00487 angle = M_PI / 4.0;
00488 rot_matrix = Eigen::AngleAxis<float>(angle, Eigen::Vector3f(0, 0, 1)).toRotationMatrix();
00489 quat = Eigen::Quaternion<float>(rot_matrix);
00490 tf_quat = tf::Quaternion(quat.x(), quat.y(), quat.z(), quat.w());
00491 pose.setRotation(tf_quat);
00492 poses.push_back(pose);
00493 }
00494 }
00495
00496 void NeighborhoodGraph::computeEndEffectorPose(const SurfacePatch p1, const SurfacePatch p2,
00497 const double dist_above_surface, tf::Pose& pose) const {
00498
00499
00500 Eigen::Vector3f origin = p1.getVector3fMap() + (dist_above_surface * p1.getNormalVector3fMap().normalized())
00501 + ((p1.scale_z / 2.0) * p1.getNormalVector3fMap().normalized());
00502
00503
00504 Eigen::Vector3f z_axis = p1.getVector3fMap() - origin;
00505 z_axis.normalize();
00506
00507
00508
00509
00510 Eigen::Vector3f cross_product = Eigen::Vector3f(0, 0, 1).cross(z_axis);
00511 Eigen::Matrix3f rot_matrix;
00512 cross_product.normalize();
00513 float angle = 0;
00514 if (cross_product.norm() > 0.000000001) {
00515 angle = acos(z_axis.dot(Eigen::Vector3f(0, 0, 1)));
00516 rot_matrix = Eigen::AngleAxis<float>(angle, cross_product).toRotationMatrix();
00517 } else {
00518 double tmp = z_axis.dot(Eigen::Vector3f(0, 0, 1));
00519 if (tmp > 0) {
00520 rot_matrix = Eigen::Matrix3f::Identity();
00521 } else {
00522 angle = M_PI;
00523 rot_matrix = Eigen::AngleAxis<float>(angle, cross_product).toRotationMatrix();
00524 }
00525 }
00526
00527
00528 Eigen::Vector3f origin_next = p2.getVector3fMap() + (dist_above_surface * p2.getNormalVector3fMap().normalized())
00529 + ((p2.scale_z / 2.0) * p2.getNormalVector3fMap().normalized());
00530
00531 origin_next = rot_matrix.transpose() * (origin_next - origin);
00532 origin_next[2] = 0;
00533 origin_next.normalize();
00534 Eigen::Vector3f align_axis = (origin_next);
00535 Eigen::Vector3f x_axis = Eigen::Vector3f(0, 1, 0);
00536 cross_product = x_axis.cross(align_axis);
00537 cross_product.normalize();
00538
00539 Eigen::Matrix3f rot_matrix2;
00540 angle = 0;
00541 if (cross_product.norm() > 0.000000001) {
00542 angle = acos(align_axis.dot(x_axis));
00543
00544 rot_matrix2 = Eigen::AngleAxis<float>(angle, cross_product).toRotationMatrix();
00545 } else {
00546 double tmp = align_axis.dot(x_axis);
00547 if (tmp > 0) {
00548 rot_matrix2 = Eigen::Matrix3f::Identity();
00549 } else {
00550 angle = M_PI;
00551 rot_matrix2 = Eigen::AngleAxis<float>(angle, cross_product).toRotationMatrix();
00552 }
00553 }
00554
00555
00556 pose.setOrigin(tf::Point(origin[0], origin[1], origin[2]));
00557 Eigen::Quaternion<float> quat(rot_matrix * rot_matrix2);
00558 tf::Quaternion tf_quat(quat.x(), quat.y(), quat.z(), quat.w());
00559 pose.setRotation(tf_quat);
00560
00561
00562 if (fabs(tf_quat.length2() - 1) > tf::QUATERNION_TOLERANCE) {
00563 ROS_WARN_STREAM(
00564 "TF to MSG: Quaternion Not Properly Normalized" << tf_quat.x() << " "<< tf_quat.y() <<" " << tf_quat.z() << " "<<tf_quat.w());
00565 ROS_WARN_STREAM("MATRIX " << rot_matrix << std::endl << rot_matrix2);
00566 }
00567 }
00568
00569 void NeighborhoodGraph::getGraph(std::vector<SurfacePatch>& patches, std::vector<pcl::PointXYZ>&surface_points,
00570 Eigen::MatrixXi& adjacency, std::vector<std::vector<tf::Pose> >&coll_free_poses,
00571 std::vector<std::vector<std::vector<std::vector<double> > > >& coll_free_ik) {
00572
00573 patches.clear();
00574 surface_points.clear();
00575 coll_free_poses.clear();
00576 coll_free_ik.clear();
00577
00578 reachable_surface_.resize(surface_.size(), false);
00579
00580 std::vector<pcl::PointXYZ> samples;
00581 sampleSurfacePoints(surface_, samples);
00582
00583
00584 buildAdjacencyMatrixUsingOctomap();
00585
00586 std::map<int, int> old_to_new_indexes;
00587 std::vector<std::pair<int, int> > new_adj_pairs_old_index;
00588
00589
00590 for (unsigned int i = 0; i < adjacency_.rows(); ++i) {
00591
00592
00593
00594 int n_edges = adjacency_.row(i).array().sum();
00595
00596 if (n_edges == 0) {
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 } else {
00625
00626 std::vector<tf::Pose> valid_poses;
00627 std::vector<std::vector<std::vector<double> > > valid_ik_solutions;
00628
00629 for (int j = 0; j < adjacency_.cols(); ++j) {
00630 if (adjacency_(i, j) == 1) {
00631 if (adjacency_(i, j) != 1) {
00632 std::cout << "error 2" << std::endl;
00633 }
00634 tf::Pose tmp_pose;
00635 computeEndEffectorPose(surface_[i], surface_[j], dist_above_surface_, tmp_pose);
00636 std::vector<tf::Pose> patch_poses;
00637 patch_poses.push_back(tmp_pose);
00638 geometry_msgs::Pose geom_pose;
00639 tf::poseTFToMsg(tmp_pose, geom_pose);
00640
00641 std::vector<bool> valid;
00642 std::vector<std::vector<std::vector<double> > > ik_solutions;
00643 getValidIKSolutions(patch_poses, true, valid, ik_solutions);
00644
00645 tf::Pose tmp_pose2;
00646 computeEndEffectorPose(surface_[j], surface_[i], dist_above_surface_, tmp_pose2);
00647 std::vector<tf::Pose> patch_poses2;
00648 patch_poses2.push_back(tmp_pose2);
00649
00650
00651 std::vector<bool> valid2;
00652 std::vector<std::vector<std::vector<double> > > ik_solutions2;
00653 getValidIKSolutions(patch_poses2, true, valid2, ik_solutions2);
00654
00655 if (valid[0] && valid2[0]) {
00656 valid_poses.push_back(tmp_pose);
00657 valid_ik_solutions.push_back(ik_solutions[0]);
00658 new_adj_pairs_old_index.push_back(std::pair<int, int>(i, j));
00659 }
00660 }
00661 }
00662 if (valid_poses.size() > 0) {
00663 reachable_surface_[i] = true;
00664 patches.push_back(surface_[i]);
00665 surface_points.push_back(samples[i]);
00666 coll_free_poses.push_back(valid_poses);
00667 coll_free_ik.push_back(valid_ik_solutions);
00668 old_to_new_indexes.insert(std::pair<int, int>(i, patches.size() - 1));
00669
00670 }
00671
00672 }
00673
00674 }
00675
00676
00677 adjacency = Eigen::MatrixXi::Zero(patches.size(), patches.size());
00678 int errors = 0;
00679 for (unsigned int i = 0; i < new_adj_pairs_old_index.size(); ++i) {
00680 std::pair<int, int> tmp = new_adj_pairs_old_index[i];
00681
00682 std::map<int, int>::iterator it_ind1 = old_to_new_indexes.find(tmp.first);
00683 std::map<int, int>::iterator it_ind2 = old_to_new_indexes.find(tmp.second);
00684
00685
00686
00687 if (!(it_ind1 == old_to_new_indexes.end() || it_ind2 == old_to_new_indexes.end())) {
00688 adjacency((*it_ind1).second, (*it_ind2).second) = 1;
00689 } else {
00690 errors++;
00691 std::cout << "error" << " " << errors << " " << tmp.first << " " << tmp.second << " " << (*it_ind1).second
00692 << " " << (*it_ind2).second << std::endl;
00693 }
00694 }
00695
00696 }
00697
00698 void NeighborhoodGraph::constructGraphMarker(const std::vector<pcl::PointXYZ>& surface_samples,
00699 const Eigen::MatrixXi& adjacency, const std::string frame_id, visualization_msgs::Marker& marker) const {
00700
00701 marker.points.clear();
00702
00703
00704 marker.header.frame_id = frame_id;
00705 marker.header.stamp = ros::Time::now();
00706
00707
00708
00709 marker.ns = "coverage";
00710
00711
00712 marker.type = visualization_msgs::Marker::LINE_LIST;
00713
00714
00715 marker.action = visualization_msgs::Marker::MODIFY;
00716
00717
00718 marker.scale.x = 0.005;
00719 marker.scale.y = 0.005;
00720 marker.scale.z = 0.005;
00721
00722
00723 marker.color.a = 1.0;
00724 marker.color.g = 1.0;
00725
00726 geometry_msgs::Point start;
00727 geometry_msgs::Point end;
00728 marker.points.clear();
00729
00730 for (unsigned int i = 0; i < surface_samples.size(); ++i) {
00731
00732 for (unsigned int j = 0; j < surface_samples.size(); ++j) {
00733 if (!(i == j) && (adjacency(i, j) == 1)) {
00734 start.x = surface_samples[i].x;
00735 start.y = surface_samples[i].y;
00736 start.z = surface_samples[i].z;
00737 end.x = surface_samples[j].x;
00738 end.y = surface_samples[j].y;
00739 end.z = surface_samples[j].z;
00740
00741 marker.points.push_back(start);
00742 marker.points.push_back(end);
00743 }
00744 }
00745 }
00746
00747 }
00748 void NeighborhoodGraph::constructGraphMarker(const std::vector<SurfacePatch>& surface, const Eigen::MatrixXi& adjacency,
00749 const std::string frame_id, visualization_msgs::Marker& marker) const {
00750
00751 std::vector<pcl::PointXYZ> samples;
00752 sampleSurfacePoints(surface, samples);
00753 constructGraphMarker(samples, adjacency, frame_id, marker);
00754 }