06_routing/main.cpp
Go to the documentation of this file.
1 #include <lanelet2_core/primitives/Lanelet.h>
2 #include <lanelet2_io/Io.h>
9 
10 // we want assert statements to work in release mode
11 #undef NDEBUG
12 
13 namespace {
14 std::string exampleMapPath = std::string(PKG_DIR) + "/../lanelet2_maps/res/mapping_example.osm";
15 } // namespace
16 
18 void part2UsingRoutes();
20 
21 int main() {
22  // this tutorial finally shows you how to use routing graphs.
26  return 0;
27 }
28 
30  using namespace lanelet;
31  // a routing graph is created from a map, traffic rules and routing cost. Each routing graph can be created with
32  // multiple different routing cost calculations. By default distance and time (using the speed limit of each
33  // lanelet) are used.
34  // The choice of the traffic object influences from which perspective the routing graph will be generated. We will
35  // make a routing graph for vehicles:
36  LaneletMapPtr map = load(exampleMapPath, projection::UtmProjector(Origin({49, 8.4})));
37  traffic_rules::TrafficRulesPtr trafficRules =
39  routing::RoutingGraphUPtr routingGraph = routing::RoutingGraph::build(*map, *trafficRules);
40 
41  // the routing graph can be used to query thre different kinds of information: Neighbourhood relations for a
42  // specific lanelet/area, possible routes from a lanelet/area and shortest routes between two lanelets.
43 
44  // we will do the following queries from the perspective of lanelet 4984315 (if you search it in josm: it is the
45  // leftmost lanelet on the bottom right intersection arm leading into the roundabout.
46  // When working with the routing graph, it is a good idea to use Const objects because the routing graph will not
47  // notice (unwanted) changes to the map.
48  ConstLanelet lanelet = map->laneletLayer.get(4984315);
49 
50  // lets inspect the neighbourhood
51  assert(!routingGraph->adjacentLeft(lanelet));
52  assert(!routingGraph->adjacentRight(lanelet)); // adjacent lanelets are neighbours but not reachable by lane change
53  assert(!!routingGraph->right(lanelet)); // right lanelets are lane-changable neighbours
54  assert(routingGraph->besides(lanelet).size() == 3); // besides gives us the "slice" of the road where the lanelet is
55  assert(routingGraph->following(lanelet).size() == 1);
56  assert(routingGraph->conflicting(lanelet).empty()); // we can also search for conflicting lanelets/areas, but this
57  // will only return conflicts with other lanelets of the same
58  // participant type. E.g. this will never return a crosswalk
59  // when this graph is for vehicles.
60 
61  // we can also find out what paths are possible from here. We chose routing cost id 0, this will give us routes that
62  // are at least 100m long.
63  routing::LaneletPaths paths = routingGraph->possiblePaths(lanelet, 100, 0, false);
64  assert(paths.size() == 1); // there is just one possible path if lane changes are excluded
65  paths = routingGraph->possiblePaths(lanelet, 100, 0, true);
66  assert(paths.size() == 4); // with lane changes, we have more options
67 
68  // you can also obtain the reachable set, this is basically the same as possible paths, but the lanelets are in an
69  // unsorted order and contain no duplicates. Also, possiblePaths discards paths that are below the cost threshold
70  // while reachable set keeps them all.
71  ConstLanelets reachableSet = routingGraph->reachableSet(lanelet, 100, 0);
72  assert(reachableSet.size() > 10);
73 
74  // finally the routing stuff. Here we only concentrate on shortest path and will cover the more mighty Route type in
75  // the next part.
76  ConstLanelet toLanelet = map->laneletLayer.get(2925017);
77  Optional<routing::LaneletPath> shortestPath = routingGraph->shortestPath(lanelet, toLanelet, 1);
78  assert(!!shortestPath);
79 
80  // the shortest path can contain (sudden) lane changes. It is more a guideline for the vehicle which lanelets should
81  // be preferred than a full route recommendation. You can query the path for the sequence of lanelets that you can
82  // follow until you must make a lane change:
83  LaneletSequence lane = shortestPath->getRemainingLane(shortestPath->begin());
84  assert(!lane.empty());
85 
86  // routing graph also have a self-check mechanism that validates if all parts of the graph are in a sane state.
87  routingGraph->checkValidity();
88 }
89 
91  using namespace lanelet;
92  LaneletMapPtr map = load(exampleMapPath, projection::UtmProjector(Origin({49, 8.4})));
93  traffic_rules::TrafficRulesPtr trafficRules =
95  routing::RoutingGraphUPtr routingGraph = routing::RoutingGraph::build(*map, *trafficRules);
96  ConstLanelet lanelet = map->laneletLayer.get(4984315);
97  ConstLanelet toLanelet = map->laneletLayer.get(2925017);
98 
99  // the Route object is built upon the shortest path between start and destination. But instead of only containing
100  // the lanelets along the shortest path, it contains all lanelets that can be used to the destination without
101  // leaving the chosen road. When you want to know all your options of getting to the destination (including lane
102  // changes), this is the object to go for.
103  Optional<routing::Route> route = routingGraph->getRoute(lanelet, toLanelet, 0);
104  assert(!!route);
105 
106  // if we want the actual underlying shortest path, we can now ask the route object
107  routing::LaneletPath shortestPath = route->shortestPath();
108  assert(!shortestPath.empty());
109 
110  // now we can get individual lanes from the route. They are as long as possible before either the destination is
111  // reached or we have to make a lane change:
112  LaneletSequence fullLane = route->fullLane(lanelet);
113  assert(!fullLane.empty());
114 
115  // but we can also check for earlier possibilites of a lane change or query other relations, similar to the routing
116  // graph.
117  auto right = route->rightRelation(lanelet);
118  assert(!!right);
119 
120  // finally, we can also create a lanelet submap from the route that only contains the relevant primitives for the
121  // chosen route:
122  LaneletSubmapConstPtr routeMap = route->laneletSubmap();
123  assert(!routeMap->laneletLayer.empty());
124 }
125 
127  // since routing graphs only contain primitives that are usable for one specific participant, we can not use them to
128  // query possible conflicts between different participants. This problem is solved by the routing graph container:
129  // It finds conflicts between individual participants by comparing the topology of the different graphs.
130  using namespace lanelet;
131  LaneletMapPtr map = load(exampleMapPath, projection::UtmProjector(Origin({49, 8.4})));
132  traffic_rules::TrafficRulesPtr trafficRules =
134  traffic_rules::TrafficRulesPtr pedestrianRules =
136  routing::RoutingGraphConstPtr vehicleGraph = routing::RoutingGraph::build(*map, *trafficRules);
137  routing::RoutingGraphConstPtr pedestrGraph = routing::RoutingGraph::build(*map, *pedestrianRules);
138  routing::RoutingGraphContainer graphs({vehicleGraph, pedestrGraph});
139  ConstLanelet lanelet = map->laneletLayer.get(4984315);
140  ConstLanelet intersectLanelet = map->laneletLayer.get(185265);
141  assert(graphs.conflictingInGraph(lanelet, 1).empty());
142  assert(graphs.conflictingInGraph(intersectLanelet, 1).size() == 1);
143 }
static RoutingGraphUPtr build(const LaneletMap &laneletMap, const traffic_rules::TrafficRules &trafficRules, const RoutingCostPtrs &routingCosts=defaultRoutingCosts(), const Configuration &config=Configuration())
static constexpr char Germany[]
static constexpr const char Vehicle[]
std::shared_ptr< LaneletMap > LaneletMapPtr
bool empty() const noexcept
void part2UsingRoutes()
void part1CreatingAndUsingRoutingGraphs()
BasicPolygon3d right
static TrafficRulesUPtr create(const std::string &location, const std::string &participant, TrafficRules::Configuration configuration=TrafficRules::Configuration())
static constexpr const char Pedestrian[]
void part3UsingRoutingGraphContainers()
std::vector< LaneletPath > LaneletPaths
boost::optional< T > Optional
std::unique_ptr< RoutingGraph > RoutingGraphUPtr
map
std::unique_ptr< LaneletMap > load(const std::string &filename, const Origin &origin=Origin::defaultOrigin(), ErrorMessages *errors=nullptr, const io::Configuration &params=io::Configuration())
std::shared_ptr< const RoutingGraph > RoutingGraphConstPtr
std::shared_ptr< const LaneletSubmap > LaneletSubmapConstPtr
std::shared_ptr< TrafficRules > TrafficRulesPtr
int main()
std::vector< ConstLanelet > ConstLanelets


lanelet2_examples
Author(s): Fabian Poggenhans
autogenerated on Tue Jun 6 2023 02:24:00