4 #include <lanelet2_core/geometry/Area.h>
5 #include <lanelet2_core/geometry/Lanelet.h>
7 #include <unordered_map>
17 inline IdPair orderedIdPair(
const Id id1,
const Id id2) {
return (id1 < id2) ?
IdPair(id1, id2) :
IdPair(id2, id1); }
37 template <
typename Func1,
typename Func2>
48 template <
typename Func1,
typename Func2>
50 iter->second.visited =
true;
53 std::reverse(predecessors.first.begin(), predecessors.first.end());
54 std::reverse(predecessors.second.begin(), predecessors.second.end());
55 std::pair<ConstLanelets, ConstLanelets> result;
61 template <
typename Func1>
63 std::pair<ConstLanelets, ConstLanelets> successors;
65 auto nextSourceLlts =
adjacent(iter->first);
66 auto nextTargetLlts =
adjacent(iter->second.target);
67 if (nextSourceLlts.size() != 1 || nextTargetLlts.size() != 1) {
73 if (iter ==
laneChanges_.end() || iter->second.visited || iter->second.target != nextTargetLlt) {
76 iter->second.visited =
true;
77 successors.first.push_back(nextSourceLlt);
78 successors.second.push_back(nextTargetLlt);
89 :
graph_{std::make_unique<RoutingGraphGraph>(routingCosts.size())},
90 trafficRules_{trafficRules},
91 routingCosts_{routingCosts},
101 addEdges(passableLanelets, passableMap->laneletLayer);
102 addEdges(passableAreas, passableMap->laneletLayer, passableMap->areaLayer);
103 return std::make_unique<RoutingGraph>(std::move(
graph_), std::move(passableMap));
109 llts.reserve(lanelets.
size());
110 std::copy_if(lanelets.
begin(), lanelets.
end(), std::back_inserter(llts),
111 [&trafficRules](
const ConstLanelet& llt) { return trafficRules.canPass(llt); });
118 ars.reserve(areas.
size());
119 std::copy_if(areas.
begin(), areas.
end(), std::back_inserter(ars),
120 [&trafficRules](
const ConstArea& area) { return trafficRules.canPass(area); });
125 std::deque<ConstLanelet> invLanelets;
126 for (
auto&
ll : llts) {
128 invLanelets.push_back(
ll.invert());
132 llts.insert(llts.end(), invLanelets.begin(), invLanelets.end());
136 for (
auto&
ll : llts) {
143 for (
auto& ar : areas) {
152 for (
auto const&
ll : lanelets) {
166 for (
const auto& area : areas) {
173 auto endPointsLanelets =
174 pointsToLanelets_.equal_range(orderedIdPair(
ll.leftBound().back().id(),
ll.rightBound().back().id()));
177 std::for_each(endPointsLanelets.first, endPointsLanelets.second, [&
ll,
this, &following](
auto it) {
178 if (geometry::follows(ll, it.second) && this->trafficRules_.canPass(ll, it.second)) {
179 following.push_back(it.second);
182 if (following.empty()) {
187 std::for_each(endPointsLanelets.first, endPointsLanelets.second, [&following,
this, &merging](
auto it) {
188 if (geometry::follows(it.second, following.front()) && this->trafficRules_.canPass(it.second, following.front())) {
189 merging.push_back(it.second);
193 for (
auto& followingIt : following) {
194 assignCosts(
ll, followingIt, relation);
200 auto directlySideway = [&relation, &
ll](
const ConstLanelet& sideLl) {
203 auto sideOf = pointsToLanelets_.equal_range(orderedIdPair(bound.
front().id(), bound.
back().id()));
204 for (
auto it = sideOf.first; it != sideOf.second; ++it) {
205 if (
ll != it->second && !hasEdge(
ll, it->second) && directlySideway(it->second)) {
206 if (trafficRules_.canChangeLane(
ll, it->second)) {
208 laneChangeLanelets.
add(
ll, it->second);
210 assignCosts(
ll, it->second, relation);
220 for (
auto& result : results) {
221 if (bothWaysLaneletIds_.find(
ll.id()) != bothWaysLaneletIds_.end() && result ==
ll) {
222 other = result.invert();
223 assignCosts(
ll,
other, RelationType::Conflicting);
224 assignCosts(
other,
ll, RelationType::Conflicting);
228 if (hasEdge(
ll, result)) {
232 if (!vertex || result ==
ll) {
235 auto maxHeight = participantHeight();
237 assignCosts(
ll,
other, RelationType::Conflicting);
238 assignCosts(
other,
ll, RelationType::Conflicting);
244 auto getSuccessors = [
this](
auto beginEdgeIt,
auto endEdgeIt,
auto getVertex) {
246 for (; beginEdgeIt != endEdgeIt; ++beginEdgeIt) {
247 auto& edgeInfo =
graph_->get()[*beginEdgeIt];
248 if (edgeInfo.relation == RelationType::Successor && edgeInfo.costId == 0) {
249 nexts.push_back(
graph_->get()[getVertex(*beginEdgeIt,
graph_->get())].lanelet());
255 auto edges = boost::out_edges(*
graph_->getVertex(llt),
graph_->get());
256 return getSuccessors(edges.first, edges.second, [](
auto edge,
const auto& g) { return boost::target(edge, g); });
258 auto prev = [
this, &getSuccessors](
const ConstLanelet& llt) {
259 auto edges = boost::in_edges(*
graph_->getVertex(llt),
graph_->get());
260 return getSuccessors(edges.first, edges.second, [](
auto edge,
const auto& g) { return boost::source(edge, g); });
264 assignLaneChangeCosts(std::move(laneChangeLanelets->first), std::move(laneChangeLanelets->second), relation);
270 for (
auto& candidate : candidates) {
271 bool canPass =
false;
272 if (trafficRules_.canPass(area, candidate)) {
274 assignCosts(area, candidate, RelationType::Area);
276 if (trafficRules_.canPass(area, candidate.invert())) {
278 assignCosts(area, candidate.invert(), RelationType::Area);
280 if (trafficRules_.canPass(candidate, area)) {
282 assignCosts(candidate, area, RelationType::Area);
284 if (trafficRules_.canPass(candidate.invert(), area)) {
286 assignCosts(candidate.invert(), area, RelationType::Area);
291 auto maxHeight = participantHeight();
294 assignCosts(candidate, area, RelationType::Conflicting);
301 for (
auto& candidate : candidates) {
302 if (candidate == area) {
305 if (trafficRules_.canPass(area, candidate)) {
306 assignCosts(area, candidate, RelationType::Area);
309 auto maxHeight = participantHeight();
312 assignCosts(candidate, area, RelationType::Conflicting);
318 auto height = config_.find(RoutingGraph::ParticipantHeight);
319 if (height != config_.end()) {
320 return height->second.asDouble();
326 using PointLaneletPair = std::pair<IdPair, ConstLanelet>;
327 pointsToLanelets_.insert(
328 PointLaneletPair(orderedIdPair(
ll.leftBound().front().id(),
ll.rightBound().front().id()),
ll));
329 pointsToLanelets_.insert(
330 PointLaneletPair(orderedIdPair(
ll.leftBound().back().id(),
ll.rightBound().back().id()),
ll));
331 pointsToLanelets_.insert(
332 PointLaneletPair(orderedIdPair(
ll.leftBound().front().id(),
ll.leftBound().back().id()),
ll));
333 pointsToLanelets_.insert(
334 PointLaneletPair(orderedIdPair(
ll.rightBound().front().id(),
ll.rightBound().back().id()),
ll));
338 return !!
graph_->getEdgeInfo(from, to);
342 assert(relation == RelationType::Left || relation == RelationType::Right);
343 assert(froms.size() == tos.size());
344 for (; !froms.empty(); froms.erase(froms.begin()), tos.erase(tos.begin())) {
346 auto cost = routingCosts_[costId]->getCostLaneChange(trafficRules_, froms, tos);
347 if (!std::isfinite(cost)) {
349 auto adjacent = relation == RelationType::Left ? RelationType::AdjacentLeft : RelationType::AdjacentRight;
353 graph_->addEdge(froms.front(), tos.front(),
EdgeInfo{cost, costId, relation});
363 edgeInfo.relation = relation;
364 auto& routingCost = *routingCosts_[rci];
365 if (relation == RelationType::Successor || relation == RelationType::Area) {
366 edgeInfo.routingCost = routingCost.getCostSucceeding(trafficRules_, from, to);
367 }
else if (relation == RelationType::Left || relation == RelationType::Right) {
368 edgeInfo.routingCost = routingCost.getCostLaneChange(trafficRules_, {*from.
lanelet()}, {*to.
lanelet()});
369 }
else if (relation == RelationType::AdjacentLeft || relation == RelationType::AdjacentRight ||
370 relation == RelationType::Conflicting) {
371 edgeInfo.routingCost = 1;
373 assert(
false &&
"Trying to add edge with wrong relation type to graph.");
376 graph_->addEdge(from, to, edgeInfo);