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
00026
00027
00028
00029
00030
00039 #include <topological_roadmap/shortest_paths.h>
00040 #include <boost/property_map/property_map.hpp>
00041 #include <boost/graph/dijkstra_shortest_paths.hpp>
00042 #include <boost/make_shared.hpp>
00043 #include <boost/foreach.hpp>
00044 #include <ros/ros.h>
00045 #include <list>
00046
00047 namespace topological_roadmap
00048 {
00049
00050 namespace msg=topological_nav_msgs;
00051
00052 using std::vector;
00053 using std::map;
00054 using std::list;
00055 using std::pair;
00056 using boost::optional;
00057
00058 typedef map<GraphVertex, double> DistanceMap;
00059 typedef map<GraphVertex, GraphVertex> PredMap;
00060 typedef pair<DistanceMap, PredMap> DijkstraResult;
00061
00062 DijkstraResult dijkstra (const Roadmap& r, const unsigned src)
00063 {
00064 using boost::associative_property_map;
00065
00066
00067
00068 typedef map<GraphEdge, double> WeightMap;
00069 typedef map<GraphVertex, unsigned> IndexMap;
00070
00071
00072
00073 typedef associative_property_map<DistanceMap> DistancePMap;
00074 typedef associative_property_map<PredMap> PredPMap;
00075 typedef associative_property_map<WeightMap> WeightPMap;
00076 typedef associative_property_map<IndexMap> IndexPMap;
00077
00078
00079 IndexMap imap;
00080 IndexPMap index_pmap(imap);
00081 {
00082 unsigned ind=0;
00083 BOOST_FOREACH (const GraphVertex v, vertices(r))
00084 imap[v] = ind++;
00085 }
00086
00087
00088 WeightMap wmap;
00089 WeightPMap weight_pmap(wmap);
00090 BOOST_FOREACH (const GraphEdge e, edges(r))
00091 wmap[e] = r[e].cost;
00092
00093
00094 DistanceMap dmap;
00095 DistancePMap distance_pmap(dmap);
00096 PredMap pmap;
00097 PredPMap predecessor_pmap(pmap);
00098
00099
00100 boost::dijkstra_shortest_paths(r, r.node(src), weight_map(weight_pmap).\
00101 vertex_index_map(index_pmap).\
00102 distance_map(distance_pmap).\
00103 predecessor_map(predecessor_pmap));
00104
00105
00106 return DijkstraResult(dmap, pmap);
00107 }
00108
00109
00110 struct SingleSourceShortestPaths
00111 {
00112 unsigned src;
00113 GraphVertex v;
00114 DijkstraResult res;
00115 const Roadmap& r;
00116 SingleSourceShortestPaths (unsigned src, GraphVertex v, DijkstraResult res,
00117 const Roadmap& r) :
00118 src(src), v(v), res(res), r(r)
00119 {}
00120 };
00121
00122 ResultPtr shortestPaths (const Roadmap& r, const unsigned src)
00123 {
00124 return boost::make_shared<SingleSourceShortestPaths>(src, r.node(src),
00125 dijkstra(r, src), r);
00126 }
00127
00128 optional<Path> extractPath (DijkstraResult& res,
00129 const unsigned src,
00130 const unsigned dest,
00131 const Roadmap& r)
00132 {
00133 BOOST_FOREACH (const PredMap::value_type& e, res.second)
00134 {
00135 const unsigned n=r[e.first].id;
00136 ROS_DEBUG_NAMED ("shortest_paths",
00137 "Predecessor of %u is %u and cost of %u is %.2f",
00138 n, r[e.second].id, n, res.first[e.first]);
00139 }
00140 optional<Path> p;
00141 const GraphVertex w = r.node(dest);
00142 if (dest == src || res.second[w]!=w)
00143 {
00144 list<unsigned> nodes;
00145 for (GraphVertex x=w; x!=res.second[x]; x=res.second[x]) {
00146 const unsigned n=r[x].id;
00147 nodes.push_front(n);
00148 }
00149 nodes.push_front(src);
00150 p = Path();
00151 copy(nodes.begin(), nodes.end(), back_inserter(p->first));
00152 }
00153 return p;
00154 }
00155
00156 optional<Path> extractPath (ResultPtr res, const unsigned dest)
00157 {
00158 return extractPath (res->res, res->src, dest, res->r);
00159 }
00160
00161 }