00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "descartes_planner/planning_graph.h"
00026
00027 #include <stdio.h>
00028 #include <iomanip>
00029 #include <iostream>
00030 #include <utility>
00031 #include <algorithm>
00032 #include <fstream>
00033
00034 #include <ros/console.h>
00035
00036 #include <boost/graph/dijkstra_shortest_paths.hpp>
00037
00038 using namespace descartes_core;
00039 using namespace descartes_trajectory;
00040 namespace descartes_planner
00041 {
00042
00043
00044 PlanningGraph::PlanningGraph(RobotModelConstPtr model)
00045 : robot_model_(std::move(model))
00046 , cartesian_point_link_(NULL)
00047 {}
00048
00049 PlanningGraph::~PlanningGraph()
00050 {
00051 delete cartesian_point_link_;
00052 }
00053
00054 CartesianMap PlanningGraph::getCartesianMap()
00055 {
00056 TrajectoryPt::ID cart_id = descartes_core::TrajectoryID::make_nil();
00057 for(std::map<TrajectoryPt::ID, CartesianPointInformation>::iterator c_iter = cartesian_point_link_->begin();
00058 c_iter != cartesian_point_link_->end(); c_iter++)
00059 {
00060 ROS_DEBUG_STREAM("Checking for last TrajectoryID: " << c_iter->first);
00061 if(c_iter->second.links_.id_next.is_nil())
00062 {
00063 cart_id = c_iter->first;
00064 break;
00065 }
00066 }
00067
00068 CartesianMap to_return = CartesianMap();
00069 bool done = false;
00070 while(!done)
00071 {
00072 to_return[cart_id] = (*cartesian_point_link_)[cart_id];
00073 cart_id = (*cartesian_point_link_)[cart_id].links_.id_previous;
00074 done = (cart_id.is_nil());
00075 ROS_DEBUG_STREAM("Next CID: " << cart_id);
00076 }
00077
00078 return to_return;
00079 }
00080
00081 descartes_core::RobotModelConstPtr PlanningGraph::getRobotModel()
00082 {
00083 return robot_model_;
00084 }
00085
00086 bool PlanningGraph::insertGraph(const std::vector<TrajectoryPtPtr> *points)
00087 {
00088
00089 if (!points)
00090 {
00091
00092 ROS_ERROR_STREAM("points == null. Cannot initialize graph with null list.");
00093 return false;
00094 }
00095 if (points->size() == 0)
00096 {
00097
00098 ROS_ERROR_STREAM("points.size == 0. Cannot initialize graph with 0 elements.");
00099 return false;
00100 }
00101
00102 delete cartesian_point_link_;
00103 cartesian_point_link_ = new std::map<TrajectoryPt::ID, CartesianPointInformation>();
00104
00105
00106
00107 TrajectoryPt::ID previous_id = descartes_core::TrajectoryID::make_nil();
00108
00109
00110 for (std::vector<TrajectoryPtPtr>::const_iterator point_iter = points->begin();
00111 point_iter != points->end(); point_iter++)
00112 {
00113 (*cartesian_point_link_)[point_iter->get()->getID()].source_trajectory_ = (*point_iter);
00114 CartesianPointRelationship point_link = CartesianPointRelationship();
00115 point_link.id = point_iter->get()->getID();
00116 point_link.id_next = descartes_core::TrajectoryID::make_nil();
00117 point_link.id_previous = descartes_core::TrajectoryID::make_nil();
00118
00119
00120 if (cartesian_point_link_->find(previous_id) != cartesian_point_link_->end())
00121 {
00122 (*cartesian_point_link_)[previous_id].links_.id_next = point_link.id;
00123
00124 ROS_DEBUG_STREAM("PreviousID[" << previous_id << "].links_.id_next = " << point_link.id);
00125 }
00126 else
00127 {
00128 ROS_INFO_STREAM("PreviousID: " << previous_id << " was not found");
00129 }
00130
00131
00132 point_link.id_previous = previous_id;
00133
00134
00135 previous_id = point_link.id;
00136
00137
00138 (*cartesian_point_link_)[point_link.id].links_ = point_link;
00139 }
00140
00141
00142 if (!calculateJointSolutions())
00143 {
00144
00145 ROS_ERROR_STREAM("unable to calculate joint trajectories for input points");
00146 return false;
00147 }
00148
00149 if (!populateGraphVertices())
00150 {
00151 ROS_ERROR_STREAM("unable to populate graph from input points");
00152 return false;
00153 }
00154
00155
00156
00157 std::list<JointEdge> edges;
00158 if (!calculateAllEdgeWeights(edges))
00159 {
00160
00161 ROS_ERROR_STREAM("unable to calculate edge weight of joint transitions for joint trajectories");
00162 return false;
00163 }
00164
00165
00166 if (!populateGraphEdges(edges))
00167 {
00168
00169 ROS_ERROR_STREAM("unable to populate graph from calculated edges");
00170 return false;
00171 }
00172
00173 return true;
00174 }
00175
00176 bool PlanningGraph::addTrajectory(TrajectoryPtPtr point, TrajectoryPt::ID previous_id, TrajectoryPt::ID next_id)
00177 {
00178 if (previous_id.is_nil() && next_id.is_nil())
00179 {
00180
00181 ROS_ERROR_STREAM("unable to add a point that is not connected to one or more existing points");
00182 return false;
00183 }
00184
00185 if (!previous_id.is_nil() && cartesian_point_link_->find(previous_id) == cartesian_point_link_->end())
00186 {
00187
00188 ROS_ERROR_STREAM("unable to find previous point");
00189 return false;
00190 }
00191 if (!next_id.is_nil() && cartesian_point_link_->find(next_id) == cartesian_point_link_->end())
00192 {
00193
00194 ROS_ERROR_STREAM("unable to find next point");
00195 }
00196
00197 CartesianPointRelationship point_link;
00198 point_link.id = point->getID();
00199 point_link.id_next = next_id;
00200 point_link.id_previous = previous_id;
00201
00202
00203 (*cartesian_point_link_)[point_link.id].links_ = point_link;
00204
00205
00206
00207 if(!previous_id.is_nil())
00208 {
00209 (*cartesian_point_link_)[previous_id].links_.id_next = point_link.id;
00210 }
00211
00212
00213 if(!next_id.is_nil())
00214 {
00215 (*cartesian_point_link_)[next_id].links_.id_previous = point_link.id;
00216 }
00217
00218 ROS_DEBUG_STREAM("New ID: " << point_link.id);
00219 ROS_DEBUG_STREAM("New Next ID: " << point_link.id_next);
00220 ROS_DEBUG_STREAM("New Previous ID: " << point_link.id_previous);
00221
00222 std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> joint_vertex_map;
00223 int num_joints = recalculateJointSolutionsVertexMap(joint_vertex_map);
00224
00225 if(!previous_id.is_nil() && !next_id.is_nil())
00226 {
00227
00228 std::list<TrajectoryPt::ID> start_joint_ids = (*cartesian_point_link_)[previous_id].joints_;
00229 std::list<TrajectoryPt::ID> end_joint_ids = (*cartesian_point_link_)[next_id].joints_;
00230 for (std::list<TrajectoryPt::ID>::iterator start_joint_iter = start_joint_ids.begin();
00231 start_joint_iter != start_joint_ids.end(); start_joint_iter++)
00232 {
00233 for (std::list<TrajectoryPt::ID>::iterator end_joint_iter = end_joint_ids.begin();
00234 end_joint_iter != end_joint_ids.end(); end_joint_iter++)
00235 {
00236 ROS_DEBUG_STREAM("Removing edge: " << *start_joint_iter << " -> " << *end_joint_iter);
00237 boost::remove_edge(joint_vertex_map[*start_joint_iter], joint_vertex_map[*end_joint_iter], dg_);
00238 }
00239 }
00240 }
00241
00242
00243 std::vector<std::vector<double> > joint_poses;
00244 point.get()->getJointPoses(*robot_model_, joint_poses);
00245
00246 if (joint_poses.size() == 0)
00247 {
00248 ROS_WARN_STREAM("no joint solution for this point... potential discontinuity in the graph");
00249 }
00250 else
00251 {
00252 for (std::vector<std::vector<double> >::iterator joint_pose_iter = joint_poses.begin();
00253 joint_pose_iter != joint_poses.end(); joint_pose_iter++)
00254 {
00255
00256 JointTrajectoryPt new_pt (*joint_pose_iter, point->getTiming());
00257
00258 (*cartesian_point_link_)[point->getID()].joints_.push_back(new_pt.getID());
00259
00260
00261 JointGraph::vertex_descriptor v = boost::add_vertex(dg_);
00262 dg_[v].id = new_pt.getID();
00263
00264 joint_solutions_map_[new_pt.getID()] = new_pt;
00265 }
00266 }
00267
00268
00269 std::list<TrajectoryPt::ID> traj_solutions = (*cartesian_point_link_)[point->getID()].joints_;
00270
00271 (*cartesian_point_link_)[point->getID()].source_trajectory_ = point;
00272
00273 ROS_INFO_STREAM("SAVE CART POINT ID[" << point->getID() << "]: "
00274 << (*cartesian_point_link_)[point->getID()].source_trajectory_.get()->getID());
00275
00276 std::list<JointEdge> edges;
00277
00278
00279 if(!previous_id.is_nil())
00280 {
00281 std::list<TrajectoryPt::ID> previous_joint_ids = (*cartesian_point_link_)[previous_id].joints_;
00282 calculateEdgeWeights(previous_joint_ids, traj_solutions, edges);
00283 }
00284
00285 if(!next_id.is_nil())
00286 {
00287 std::list<TrajectoryPt::ID> next_joint_ids = (*cartesian_point_link_)[next_id].joints_;
00288 calculateEdgeWeights(traj_solutions, next_joint_ids, edges);
00289 }
00290
00291
00292 populateGraphEdges(edges);
00293
00294
00295
00296
00297
00298
00299
00300
00301 return (cartesian_point_link_->find(point->getID()) != cartesian_point_link_->end());
00302 }
00303
00304 bool PlanningGraph::modifyTrajectory(TrajectoryPtPtr point)
00305 {
00306 TrajectoryPt::ID modify_id = point.get()->getID();
00307 ROS_INFO_STREAM("Attempting to modify point:: " << modify_id);
00308
00309
00310
00311 if (modify_id.is_nil())
00312 {
00313
00314 ROS_ERROR_STREAM("unable to modify a point with nil ID");
00315 return false;
00316 }
00317
00318 if (cartesian_point_link_->find(modify_id) == cartesian_point_link_->end())
00319 {
00320
00321 ROS_ERROR_STREAM("unable to find cartesian point link with ID: " << modify_id);
00322 return false;
00323 }
00324 else
00325 {
00326 ROS_INFO_STREAM("Found ID: " << modify_id << " to modify.");
00327 }
00328
00329 std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> joint_vertex_map;
00330 int num_joints = recalculateJointSolutionsVertexMap(joint_vertex_map);
00331
00332
00333 std::list<TrajectoryPt::ID> start_joint_ids = (*cartesian_point_link_)[modify_id].joints_;
00334
00335 ROS_INFO_STREAM("start_joint_ids.size = " << start_joint_ids.size());
00336
00337 std::vector<JointGraph::edge_descriptor> to_remove_edges;
00338 std::vector<JointGraph::vertex_descriptor> to_remove_vertices;
00339
00340 for (std::list<TrajectoryPt::ID>::iterator start_joint_iter = start_joint_ids.begin();
00341 start_joint_iter != start_joint_ids.end(); start_joint_iter++)
00342 {
00343
00344 JointGraph::vertex_descriptor jv = joint_vertex_map[*start_joint_iter];
00345
00346
00347 ROS_DEBUG_STREAM("jv: " << jv);
00348
00349
00350
00351 std::pair<OutEdgeIterator, OutEdgeIterator> out_ei = out_edges(jv, dg_);
00352
00353 for (OutEdgeIterator out_edge = out_ei.first; out_edge != out_ei.second; ++out_edge)
00354 {
00355 JointGraph::edge_descriptor e = *out_edge;
00356 ROS_DEBUG_STREAM("REMOVE OUTEDGE: " << dg_[e].joint_start << " -> " << dg_[e].joint_end);
00357 to_remove_edges.push_back(e);
00358 }
00359
00360
00361 std::pair<InEdgeIterator, InEdgeIterator> in_ei = in_edges(jv, dg_);
00362 for (InEdgeIterator in_edge = in_ei.first; in_edge != in_ei.second; ++in_edge)
00363 {
00364 JointGraph::edge_descriptor e = *in_edge;
00365 ROS_DEBUG_STREAM("REMOVE INEDGE: " << dg_[e].joint_start << " -> " << dg_[e].joint_end);
00366 to_remove_edges.push_back(e);
00367 }
00368
00369 to_remove_vertices.push_back(jv);
00370 joint_solutions_map_.erase(*start_joint_iter);
00371
00372 }
00373 for(std::vector<JointGraph::edge_descriptor>::iterator e_iter = to_remove_edges.begin(); e_iter != to_remove_edges.end(); e_iter++)
00374 {
00375 ROS_DEBUG_STREAM("REMOVE EDGE: " << dg_[*e_iter].joint_start << " -> " << dg_[*e_iter].joint_end);
00376 boost:remove_edge(*e_iter, dg_);
00377
00378 }
00379 std::sort(to_remove_vertices.begin(), to_remove_vertices.end());
00380 std::reverse(to_remove_vertices.begin(), to_remove_vertices.end());
00381 for(std::vector<JointGraph::vertex_descriptor>::iterator v_iter = to_remove_vertices.begin(); v_iter != to_remove_vertices.end(); v_iter++)
00382 {
00383
00384
00385 ROS_DEBUG_STREAM("REMOVE VERTEX: " << *v_iter);
00386 boost::remove_vertex(*v_iter, dg_);
00387
00388 }
00389 (*cartesian_point_link_)[modify_id].joints_.clear();
00390
00391
00392 std::vector<std::vector<double> > joint_poses;
00393 point.get()->getJointPoses(*robot_model_, joint_poses);
00394
00395 if (joint_poses.size() == 0)
00396 {
00397 ROS_WARN_STREAM("no joint solution for this point... potential discontinuity in the graph");
00398 }
00399 else
00400 {
00401 for (std::vector<std::vector<double> >::iterator joint_pose_iter = joint_poses.begin();
00402 joint_pose_iter != joint_poses.end(); joint_pose_iter++)
00403 {
00404
00405 JointTrajectoryPt new_pt (*joint_pose_iter, point->getTiming());
00406 (*cartesian_point_link_)[modify_id].joints_.push_back(new_pt.getID());
00407
00408
00409 JointGraph::vertex_descriptor v = boost::add_vertex(dg_);
00410 dg_[v].id = new_pt.getID();
00411
00412 joint_solutions_map_[new_pt.getID()] = new_pt;
00413 ROS_INFO_STREAM("Added New Joint: " << v);
00414 }
00415 }
00416
00417 std::list<TrajectoryPt::ID> traj_solutions = (*cartesian_point_link_)[modify_id].joints_;
00418 (*cartesian_point_link_)[modify_id].source_trajectory_ = point;
00419
00420
00421
00422 TrajectoryPt::ID previous_cart_id = (*cartesian_point_link_)[modify_id].links_.id_previous;
00423 TrajectoryPt::ID next_cart_id = (*cartesian_point_link_)[modify_id].links_.id_next;
00424
00425 std::list<JointEdge> edges;
00426
00427
00428 if(!previous_cart_id.is_nil())
00429 {
00430 std::list<TrajectoryPt::ID> previous_joint_ids = (*cartesian_point_link_)[previous_cart_id].joints_;
00431 ROS_DEBUG_STREAM("Calculating previous -> new weights: " << previous_joint_ids.size() << " -> " << traj_solutions.size());
00432 calculateEdgeWeights(previous_joint_ids, traj_solutions, edges);
00433 }
00434
00435 if(!next_cart_id.is_nil())
00436 {
00437 std::list<TrajectoryPt::ID> next_joint_ids = (*cartesian_point_link_)[next_cart_id].joints_;
00438 ROS_DEBUG_STREAM("Calculating new -> next weights: " << traj_solutions.size() << " -> " << next_joint_ids.size());
00439 calculateEdgeWeights(traj_solutions, next_joint_ids, edges);
00440 }
00441
00442 ROS_INFO_STREAM("NEW EDGES: " << edges.size());
00443
00444 return populateGraphEdges(edges);
00445
00446
00447
00448
00449 }
00450
00451 bool PlanningGraph::removeTrajectory(TrajectoryPtPtr point)
00452 {
00453 TrajectoryPt::ID delete_id = point.get()->getID();
00454 ROS_INFO_STREAM("Attempting to delete ID: " << delete_id);
00455
00456 if (delete_id.is_nil())
00457 {
00458
00459 ROS_ERROR_STREAM("unable to delete a point with nil ID");
00460 return false;
00461 }
00462 if (cartesian_point_link_->find(delete_id) == cartesian_point_link_->end())
00463 {
00464
00465 ROS_ERROR_STREAM("unable to find cartesian point link with ID: " << delete_id);
00466 return false;
00467 }
00468
00469 std::list<TrajectoryPt::ID> start_joint_ids = (*cartesian_point_link_)[delete_id].joints_;
00470
00471 ROS_INFO_STREAM("Attempting to delete edges from " << start_joint_ids.size() << " vertices");
00472
00473 std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> joint_vertex_map;
00474 int num_joints = recalculateJointSolutionsVertexMap(joint_vertex_map);
00475
00476 std::vector<JointGraph::edge_descriptor> to_remove_edges;
00477 std::vector<JointGraph::vertex_descriptor> to_remove_vertices;
00478
00479 for (std::list<TrajectoryPt::ID>::iterator start_joint_iter = start_joint_ids.begin();
00480 start_joint_iter != start_joint_ids.end(); start_joint_iter++)
00481 {
00482
00483 JointGraph::vertex_descriptor jv = joint_vertex_map[*start_joint_iter];
00484
00485
00486 std::pair<OutEdgeIterator, OutEdgeIterator> out_ei = out_edges(jv, dg_);
00487
00488 for (OutEdgeIterator out_edge = out_ei.first; out_edge != out_ei.second; ++out_edge)
00489 {
00490 JointGraph::edge_descriptor e = *out_edge;
00491 ROS_DEBUG_STREAM("REMOVE OUTEDGE: " << dg_[e].joint_start << " -> " << dg_[e].joint_end);
00492 to_remove_edges.push_back(e);
00493 }
00494
00495
00496 std::pair<InEdgeIterator, InEdgeIterator> in_ei = in_edges(jv, dg_);
00497 for (InEdgeIterator in_edge = in_ei.first; in_edge != in_ei.second; ++in_edge)
00498 {
00499 JointGraph::edge_descriptor e = *in_edge;
00500 ROS_DEBUG_STREAM("REMOVE INEDGE: " << dg_[e].joint_start << " -> " << dg_[e].joint_end);
00501 to_remove_edges.push_back(e);
00502 }
00503 to_remove_vertices.push_back(jv);
00504
00505
00506 joint_solutions_map_.erase(*start_joint_iter);
00507 }
00508
00509 for(std::vector<JointGraph::edge_descriptor>::iterator e_iter = to_remove_edges.begin(); e_iter != to_remove_edges.end(); e_iter++)
00510 {
00511 boost:remove_edge(*e_iter, dg_);
00512 }
00513
00514 std::sort(to_remove_vertices.begin(), to_remove_vertices.end());
00515 std::reverse(to_remove_vertices.begin(), to_remove_vertices.end());
00516 for(std::vector<JointGraph::vertex_descriptor>::iterator v_iter = to_remove_vertices.begin(); v_iter != to_remove_vertices.end(); v_iter++)
00517 {
00518
00519
00520 ROS_INFO_STREAM("REMOVE VERTEX: " << *v_iter);
00521 boost::remove_vertex(*v_iter, dg_);
00522
00523 }
00524 (*cartesian_point_link_)[delete_id].joints_.clear();
00525
00526
00527 CartesianPointRelationship links = (*cartesian_point_link_)[delete_id].links_;
00528 TrajectoryPt::ID previous_id = links.id_previous;
00529 TrajectoryPt::ID next_id = links.id_next;
00530
00531 if(!previous_id.is_nil())
00532 {
00533
00534 (*cartesian_point_link_)[previous_id].links_.id_next = next_id;
00535 }
00536 if(!next_id.is_nil())
00537 {
00538
00539 (*cartesian_point_link_)[next_id].links_.id_previous = previous_id;
00540 }
00541
00542 std::list<JointEdge> edges;
00543
00544
00545 if(!previous_id.is_nil() && !next_id.is_nil())
00546 {
00547 std::list<TrajectoryPt::ID> previous_joint_ids = (*cartesian_point_link_)[previous_id].joints_;
00548 std::list<TrajectoryPt::ID> next_joint_ids = (*cartesian_point_link_)[next_id].joints_;
00549 calculateEdgeWeights(previous_joint_ids, next_joint_ids, edges);
00550 }
00551
00552
00553 populateGraphEdges(edges);
00554
00555
00556
00557
00558
00559 return true;
00560 }
00561
00562 bool PlanningGraph::findStartVertices(std::list<JointGraph::vertex_descriptor> &start_points)
00563 {
00564
00565 std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> joint_vertex_map;
00566 int num_joints = recalculateJointSolutionsVertexMap(joint_vertex_map);
00567
00568
00569 TrajectoryPt::ID cart_id = descartes_core::TrajectoryID::make_nil();
00570
00571 for(std::map<TrajectoryPt::ID, CartesianPointInformation>::iterator c_iter = cartesian_point_link_->begin();
00572 c_iter != cartesian_point_link_->end(); c_iter++)
00573 {
00574 if(c_iter->second.links_.id_previous.is_nil())
00575 {
00576 cart_id = c_iter->first;
00577 break;
00578 }
00579 }
00580
00581
00582 if (cart_id.is_nil())
00583 {
00584
00585
00586 ROS_ERROR("Could not locate TrajectoryPt with nil previous point. Graph may be cyclic.");
00587 return false;
00588 }
00589
00590
00591 const std::list<descartes_core::TrajectoryPt::ID>& ids = cartesian_point_link_->at(cart_id).joints_;
00592
00593 for (const auto& id : ids)
00594 {
00595 JointGraph::vertex_descriptor v = joint_vertex_map.at(id);
00596 start_points.push_back(v);
00597 }
00598
00599 return !start_points.empty();
00600 }
00601
00602 bool PlanningGraph::findEndVertices(std::list<JointGraph::vertex_descriptor> &end_points)
00603 {
00604
00605 std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> joint_vertex_map;
00606 int num_joints = recalculateJointSolutionsVertexMap(joint_vertex_map);
00607
00608
00609 TrajectoryPt::ID cart_id = descartes_core::TrajectoryID::make_nil();
00610
00611 for(std::map<TrajectoryPt::ID, CartesianPointInformation>::iterator c_iter = cartesian_point_link_->begin();
00612 c_iter != cartesian_point_link_->end(); c_iter++)
00613 {
00614 if(c_iter->second.links_.id_next.is_nil())
00615 {
00616 cart_id = c_iter->first;
00617 break;
00618 }
00619 }
00620
00621
00622 if (cart_id.is_nil())
00623 {
00624
00625
00626 ROS_ERROR("Could not locate TrajectoryPt with nil next point. Graph may be cyclic.");
00627 return false;
00628 }
00629
00630
00631 const std::list<descartes_core::TrajectoryPt::ID>& ids = cartesian_point_link_->at(cart_id).joints_;
00632
00633 for (const auto& id : ids)
00634 {
00635 JointGraph::vertex_descriptor v = joint_vertex_map.at(id);
00636 end_points.push_back(v);
00637 }
00638
00639 return !end_points.empty();
00640 }
00641
00642
00643 bool PlanningGraph::getShortestPath(double &cost, std::list<JointTrajectoryPt> &path)
00644 {
00645 std::list<JointGraph::vertex_descriptor> start_points;
00646 findStartVertices(start_points);
00647 std::list<JointGraph::vertex_descriptor> end_points;
00648 findEndVertices(end_points);
00649
00650 size_t num_vert = boost::num_vertices(dg_);
00651
00652 std::vector<TrajectoryPt::ID> vertex_index_map(num_vert);
00653 std::pair<VertexIterator, VertexIterator> vi = boost::vertices(dg_);
00654 int i = 0;
00655 for (VertexIterator vert_iter = vi.first; vert_iter != vi.second; ++vert_iter)
00656 {
00657 JointGraph::vertex_descriptor jv = *vert_iter;
00658 vertex_index_map[i++] = dg_[jv].id;
00659 }
00660
00661 cost = std::numeric_limits<double>::max();
00662
00663 for (std::list<JointGraph::vertex_descriptor>::iterator start = start_points.begin(); start != start_points.end(); start++)
00664 {
00665
00666 std::vector<JointGraph::vertex_descriptor> predecessors(num_vert);
00667 std::vector<double> weights(num_vert, std::numeric_limits<double>::max());
00668
00669 dijkstra_shortest_paths(
00670 dg_,
00671 *start,
00672 weight_map(get(&JointEdge::transition_cost, dg_)).distance_map(
00673 boost::make_iterator_property_map(weights.begin(), get(boost::vertex_index, dg_))).predecessor_map(
00674 &predecessors[0]));
00675
00676 for (std::list<JointGraph::vertex_descriptor>::iterator end = end_points.begin(); end != end_points.end(); end++)
00677 {
00678
00679 double weight = weights[*end];
00680
00681
00682 if (weight < cost)
00683 {
00684 std::stringstream ss;
00685 ss << "New Shortest Path: ";
00686
00687 cost = weight;
00688 path.clear();
00689
00690 int current = *end;
00691 path.push_front(joint_solutions_map_[vertex_index_map[current]]);
00692
00693 ss << current;
00694
00695
00696 while (current != *start)
00697 {
00698 current = predecessors[current];
00699 ss << " -> " << current;
00700 path.push_front(joint_solutions_map_[vertex_index_map[current]]);
00701 }
00702
00703 ROS_INFO("With %lu - new best score: %f", path.size(), weight);
00704 }
00705 }
00706 }
00707
00708 ROS_INFO("Lowest cost: %f", cost);
00709
00710 if (cost < std::numeric_limits<double>::max())
00711 {
00712 ROS_INFO("FOUND A PATH");
00713 return true;
00714 }
00715 else
00716 {
00717 ROS_ERROR_STREAM("unable to find a valid path");
00718 return false;
00719 }
00720 }
00721
00722 void PlanningGraph::printMaps()
00723 {
00724 ROS_DEBUG_STREAM("Number of points: " << cartesian_point_link_->size());
00725
00726 for(std::map<TrajectoryPt::ID, CartesianPointInformation>::iterator c_iter = cartesian_point_link_->begin();
00727 c_iter != cartesian_point_link_->end(); c_iter++)
00728 {
00729 ROS_DEBUG_STREAM("C_ID: " << c_iter->first << "[P_ID: " << c_iter->second.links_.id_previous << " -> N_ID: "
00730 << c_iter->second.links_.id_next << "](Joints: " << c_iter->second.joints_.size() << ')');
00731 }
00732 }
00733
00734 int PlanningGraph::recalculateJointSolutionsVertexMap(std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> &joint_map)
00735 {
00736 std::pair<VertexIterator, VertexIterator> vi = vertices(dg_);
00737
00738 for (VertexIterator vert_iter = vi.first; vert_iter != vi.second; ++vert_iter)
00739 {
00740 JointGraph::vertex_descriptor jv = *vert_iter;
00741 joint_map[dg_[jv].id] = jv;
00742 }
00743 }
00744
00745
00746 void PlanningGraph::printGraph()
00747 {
00748 ROS_DEBUG_STREAM("\n\nPRINTING GRAPH\n\n");
00749 std::stringstream ss;
00750 ss << "GRAPH VERTICES (" << num_vertices(dg_) << "): ";
00751 ROS_DEBUG_STREAM(ss.str());
00752 std::pair<VertexIterator, VertexIterator> vi = vertices(dg_);
00753 ROS_DEBUG_STREAM("Graph OutEdges:");
00754 for (VertexIterator vert_iter = vi.first; vert_iter != vi.second; ++vert_iter)
00755 {
00756 JointGraph::vertex_descriptor jv = *vert_iter;
00757 ss.str("");
00758 ss << "Vertex: (" << jv << ")";
00759 ss << dg_[jv].id;
00760 std::pair<OutEdgeIterator, OutEdgeIterator> out_ei = out_edges(jv, dg_);
00761 ss << " -> {";
00762 for (OutEdgeIterator out_edge = out_ei.first; out_edge != out_ei.second; ++out_edge)
00763 {
00764 JointGraph::edge_descriptor e = *out_edge;
00765 ss << "[" << dg_[e].joint_end << "] , ";
00766 }
00767 ss << "}";
00768 ROS_DEBUG_STREAM(ss.str());
00769 }
00770
00771 ROS_DEBUG_STREAM("Graph InEdges:");
00772 for (VertexIterator vert_iter = vi.first; vert_iter != vi.second; ++vert_iter)
00773 {
00774 JointGraph::vertex_descriptor jv = *vert_iter;
00775
00776 std::pair<InEdgeIterator, InEdgeIterator> in_ei = in_edges(jv, dg_);
00777 ss.str("");
00778 ss << "{";
00779 for (InEdgeIterator in_edge = in_ei.first; in_edge != in_ei.second; ++in_edge)
00780 {
00781 JointGraph::edge_descriptor e = *in_edge;
00782 ss << source(e, dg_) << "[" << dg_[e].joint_start << "], ";
00783 }
00784 ss << "} -> ";
00785 ss << "Vertex (" << jv << "): " ;
00786 ROS_DEBUG_STREAM(ss.str());
00787 }
00788
00789 ROS_DEBUG_STREAM("GRAPH EDGES (" << num_edges(dg_) << "): ");
00790
00791
00792 std::pair<EdgeIterator, EdgeIterator> ei = edges(dg_);
00793 for (EdgeIterator edge_iter = ei.first; edge_iter != ei.second; ++edge_iter)
00794 {
00795 JointGraph::vertex_descriptor jv = source(*edge_iter, dg_);
00796 JointGraph::edge_descriptor e = *out_edges(jv, dg_).first;
00797
00798 JointGraph::edge_descriptor e2 = *edge_iter;
00799 ROS_DEBUG_STREAM("(" << source(*edge_iter, dg_) << ", " << target(*edge_iter, dg_) << "): cost: " << dg_[e2].transition_cost);
00800 }
00801 ROS_DEBUG_STREAM("\n\nEND PRINTING GRAPH\n\n");
00802 }
00803
00804 bool PlanningGraph::calculateJointSolutions()
00805 {
00806 if (joint_solutions_map_.size() > 0)
00807 {
00808
00809 ROS_WARN_STREAM("existing joint solutions found, clearing map");
00810 joint_solutions_map_.clear();
00811 }
00812
00813
00814 for (std::map<TrajectoryPt::ID, CartesianPointInformation>::iterator trajectory_iter = cartesian_point_link_->begin();
00815 trajectory_iter != cartesian_point_link_->end(); trajectory_iter++)
00816 {
00817
00818
00819 std::list<TrajectoryPt::ID> traj_solutions;
00820 std::vector<std::vector<double> > joint_poses;
00821 trajectory_iter->second.source_trajectory_.get()->getJointPoses(*robot_model_, joint_poses);
00822 TrajectoryPt::ID tempID = trajectory_iter->first;
00823 ROS_INFO_STREAM("CartID: " << tempID << " JointPoses count: " << joint_poses.size());
00824
00825 if (joint_poses.size() == 0)
00826 {
00827 ROS_WARN_STREAM("no joint solution for this point... potential discontinuity in the graph");
00828 }
00829 else
00830 {
00831 for (std::vector<std::vector<double> >::iterator joint_pose_iter = joint_poses.begin();
00832 joint_pose_iter != joint_poses.end(); joint_pose_iter++)
00833 {
00834
00835 JointTrajectoryPt new_pt (*joint_pose_iter, trajectory_iter->second.source_trajectory_.get()->getTiming());
00836 traj_solutions.push_back(new_pt.getID());
00837 joint_solutions_map_[new_pt.getID()] = new_pt;
00838 }
00839 }
00840 trajectory_iter->second.joints_ = traj_solutions;
00841
00842 }
00843
00844 return true;
00845 }
00846
00847 bool PlanningGraph::calculateAllEdgeWeights(std::list<JointEdge> &edges)
00848 {
00849 if (cartesian_point_link_->size() == 0)
00850 {
00851
00852 ROS_ERROR_STREAM("no trajectory point links defined");
00853 return false;
00854 }
00855 else
00856 {
00857 ROS_DEBUG_STREAM("Found %i " << cartesian_point_link_->size() << " trajectory point links");
00858 }
00859
00860 if (joint_solutions_map_.size() == 0)
00861 {
00862
00863 ROS_ERROR_STREAM("no joint solutions available");
00864 return false;
00865 }
00866 else
00867 {
00868 ROS_INFO_STREAM("Found " << joint_solutions_map_.size() << " joint solutions available");
00869 }
00870
00871 for (std::map<TrajectoryPt::ID, CartesianPointInformation>::iterator cart_link_iter = cartesian_point_link_->begin();
00872 cart_link_iter != cartesian_point_link_->end(); cart_link_iter++)
00873 {
00874 TrajectoryPt::ID start_cart_id = cart_link_iter->first;
00875 TrajectoryPt::ID end_cart_id = cart_link_iter->second.links_.id_next;
00876
00877 if(!end_cart_id.is_nil())
00878 {
00879 std::list<TrajectoryPt::ID> start_joint_ids = cart_link_iter->second.joints_;
00880 std::list<TrajectoryPt::ID> end_joint_ids = (*cartesian_point_link_)[end_cart_id].joints_;
00881
00882 if(!calculateEdgeWeights(start_joint_ids, end_joint_ids, edges))
00883 {
00884 ROS_WARN_STREAM("One or more joints lists in the cartesian point link is empty ID:" << start_cart_id <<
00885 "[start ids:" << start_joint_ids.size() << "], ID:" << end_cart_id << "[end ids:" << end_joint_ids.size() << ']');
00886 }
00887 }
00888 else
00889 {
00890
00891 ROS_INFO_STREAM("Not calculating edge weights to nil ID");
00892 }
00893 }
00894
00895 return !edges.empty();
00896 }
00897
00898 bool PlanningGraph::calculateEdgeWeights(const std::list<TrajectoryPt::ID> &start_joints,const std::list<TrajectoryPt::ID> &end_joints, std::list<JointEdge> &edge_results)
00899 {
00900 typedef std::list<TrajectoryPt::ID>::const_iterator TrajIdConstIter;
00901
00902 if(start_joints.empty() || end_joints.empty())
00903 {
00904 ROS_WARN_STREAM("One or more joints lists is empty, Start Joints: " << start_joints.size() << " End Joints: " << end_joints.size());
00905 return false;
00906 }
00907
00908 bool has_valid_transition = false;
00909
00910
00911 for (TrajIdConstIter previous_joint_iter = start_joints.begin();
00912 previous_joint_iter != start_joints.end(); previous_joint_iter++)
00913 {
00914
00915 const JointTrajectoryPt& start_joint = joint_solutions_map_[*previous_joint_iter];
00916
00917
00918 for (TrajIdConstIter next_joint_iter = end_joints.begin();
00919 next_joint_iter != end_joints.end(); next_joint_iter++)
00920 {
00921 const JointTrajectoryPt& end_joint = joint_solutions_map_[*next_joint_iter];
00922
00923 LinearWeightResult edge_result = linearWeight(start_joint, end_joint);
00924
00925
00926 if (!edge_result.first)
00927 {
00928 continue;
00929 }
00930
00931
00932
00933 has_valid_transition = true;
00934
00935 JointEdge edge;
00936 edge.joint_start = *previous_joint_iter;
00937 edge.joint_end = *next_joint_iter;
00938 edge.transition_cost = edge_result.second;
00939 edge_results.push_back(edge);
00940 }
00941 }
00942
00943 return has_valid_transition;
00944 }
00945
00946 bool PlanningGraph::populateGraphVertices()
00947 {
00948 if (joint_solutions_map_.size() == 0)
00949 {
00950
00951 ROS_ERROR_STREAM("no joint solutions defined, thus no graph vertices");
00952 return false;
00953 }
00954
00955 for (std::map<TrajectoryPt::ID, JointTrajectoryPt>::iterator joint_iter = joint_solutions_map_.begin();
00956 joint_iter != joint_solutions_map_.end(); joint_iter++)
00957 {
00958 JointGraph::vertex_descriptor v = boost::add_vertex(dg_);
00959 dg_[v].id = joint_iter->second.getID();
00960 }
00961
00962 return true;
00963 }
00964
00965 bool PlanningGraph::populateGraphEdges(const std::list<JointEdge> &edges)
00966 {
00967 if (edges.size() == 0)
00968 {
00969
00970 ROS_ERROR_STREAM("no graph edges defined");
00971 return false;
00972 }
00973
00974 std::map<TrajectoryPt::ID, JointGraph::vertex_descriptor> joint_vertex_map;
00975 int num_joints = recalculateJointSolutionsVertexMap(joint_vertex_map);
00976
00977 for (std::list<JointEdge>::const_iterator edge_iter = edges.begin(); edge_iter != edges.end(); edge_iter++)
00978 {
00979 JointGraph::edge_descriptor e;
00980 bool b;
00981
00982 boost::tie(e, b) = boost::add_edge(joint_vertex_map[edge_iter->joint_start],
00983 joint_vertex_map[edge_iter->joint_end], dg_);
00984
00985 dg_[e].transition_cost = edge_iter->transition_cost;
00986 dg_[e].joint_start = edge_iter->joint_start;
00987 dg_[e].joint_end = edge_iter->joint_end;
00988 }
00989
00990 return true;
00991 }
00992
00993 PlanningGraph::LinearWeightResult PlanningGraph::linearWeight(const JointTrajectoryPt& start,
00994 const JointTrajectoryPt& end) const
00995 {
00996 LinearWeightResult result;
00997 result.first = false;
00998
00999 const std::vector<double>& start_vector = start.nominal();
01000 const std::vector<double>& end_vector = end.nominal();
01001 if (start_vector.size() == end_vector.size())
01002 {
01003
01004
01005 if (end.getTiming().isSpecified() &&
01006 !robot_model_->isValidMove(start_vector, end_vector, end.getTiming().upper))
01007 {
01008 return result;
01009 }
01010
01011 double vector_diff = 0;
01012 for (unsigned i = 0; i < start_vector.size(); i++)
01013 {
01014 double joint_diff = std::abs(end_vector[i] - start_vector[i]);
01015 vector_diff += joint_diff ;
01016 }
01017
01018 result.first = true;
01019 result.second = vector_diff;
01020 return result;
01021 }
01022 else
01023 {
01024 ROS_WARN_STREAM("unequal joint pose vector lengths: "
01025 << start_vector.size() << " != " << end_vector.size());
01026 }
01027
01028 return result;
01029 }
01030
01031 }