ad_map_access
RouteExpander.hpp
Go to the documentation of this file.
1 // ----------------- BEGIN LICENSE BLOCK ---------------------------------
2 //
3 // Copyright (C) 2019-2021 Intel Corporation
4 //
5 // SPDX-License-Identifier: MIT
6 //
7 // ----------------- END LICENSE BLOCK -----------------------------------
12 #pragma once
13 
14 #include <utility>
15 
17 #include "ad/map/route/Route.hpp"
18 #include "ad/physics/Operation.hpp"
19 
21 namespace ad {
23 namespace map {
25 namespace route {
29 namespace planning {
30 
31 static const physics::Distance cMinimumNeighborDistance{0.1};
32 
33 static const physics::Duration cMinimumNeighborDuration{0.05};
34 
35 static const physics::Speed cMinimumSpeed{10.};
36 
43 template <class RoutingCostData> class RouteExpander : public Route
44 {
45 public:
47  struct RoutingCost
48  {
49  physics::Distance routeDistance{0.};
50  physics::Duration routeDuration{0.};
51  RoutingCostData costData{};
52  };
54  typedef std::pair<RoutingParaPoint, RoutingCost> RoutingPoint;
55 
66  const RoutingParaPoint &dest,
67  physics::Distance const &maxDistance,
68  physics::Duration const &maxDuration,
69  Type const &routingType)
70  : Route(start, dest, maxDistance, maxDuration, routingType)
71  {
72  }
73 
74  RouteExpander(RouteExpander const &) = delete;
75  RouteExpander(RouteExpander const &&) = delete;
76  RouteExpander &operator=(RouteExpander const &) = delete;
77  RouteExpander &operator=(RouteExpander &&) = delete;
78 
82  virtual ~RouteExpander() = default;
83 
87  void expandNeighbors(RoutingPoint const &origin);
88 
93  void setRelevantLanes(::ad::map::lane::LaneIdSet const &relevantLanes)
94  {
95  mRelevantLanes = relevantLanes;
96  }
97 
102  {
103  mRelevantLanes.clear();
104  }
105 
106 protected:
110  enum class ExpandReason
111  {
115  Destination,
116  };
117 
129  virtual void addNeighbor(lane::Lane::ConstPtr originLane,
130  RoutingPoint const &origin,
131  lane::Lane::ConstPtr neighborLane,
132  RoutingPoint const &neighbor,
133  ExpandReason const &expandReason)
134  = 0;
135 
137  bool isStart(RoutingPoint const &origin)
138  {
139  return origin.first.point.parametricOffset == physics::ParametricValue(0.);
140  }
141 
143  bool isEnd(RoutingPoint const &origin)
144  {
145  return origin.first.point.parametricOffset == physics::ParametricValue(1.);
146  }
147 
150  {
152  && (origin.first.direction == RoutingDirection::POSITIVE);
153  }
154 
157  {
159  && (origin.first.direction == RoutingDirection::NEGATIVE);
160  }
161 
163  bool isLaneRelevantForExpansion(lane::LaneId const laneId) const
164  {
166  }
167 
173  void expandLateralNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin);
174 
177  RoutingPoint const &origin,
178  lane::Lane::ConstPtr neighborLane,
179  RoutingParaPoint neighborRoutingParaPoint);
181  RoutingPoint createLongitudinalNeighbor(RoutingPoint const &origin, RoutingParaPoint neighborRoutingParaPoint);
182 
184  ::ad::map::lane::LaneIdSet mRelevantLanes;
185 };
186 
187 template <class RoutingCostData>
189  typename RouteExpander<RoutingCostData>::RoutingPoint const &origin)
190 {
191  if (origin.first.direction == RoutingDirection::DONT_CARE)
192  {
193  throw std::runtime_error("RouteExpander::ExpandNeighbors invalid routing direction!");
194  }
195 
196  lane::Lane::ConstPtr lane = lane::getLanePtr(origin.first.point.laneId);
197  if (lane)
198  {
199  if ( // lane has to be routable to expand
200  isRouteable(*lane)
201  && ( // max distance and max duration are not yet reached
202  ((origin.second.routeDistance < mMaxDistance) && (origin.second.routeDuration < mMaxDuration))
203  // or we are within an intersection
205  {
206  expandSameLaneNeighbors(lane, origin);
207  expandLongitudinalNeighbors(lane, origin);
208  expandLateralNeighbors(lane, origin);
209  }
210  }
211  else
212  {
213  throw std::runtime_error("RouteExpander::ExpandNeighbors No lane!");
214  }
215 }
216 
217 template <class RoutingCostData>
220  RoutingPoint const &origin,
221  lane::Lane::ConstPtr neighborLane,
222  RoutingParaPoint neighborRoutingParaPoint)
223 {
224  RoutingPoint neighbor;
225  neighbor.first = neighborRoutingParaPoint;
226 
227  physics::Distance neighborDistance{0.};
228  physics::Duration neighborDuration{0.};
229  point::ECEFPoint pt_origin
230  = getParametricPoint(*originLane, origin.first.point.parametricOffset, physics::ParametricValue(0.5));
231  point::ECEFPoint pt_neighbor
232  = getParametricPoint(*neighborLane, neighbor.first.point.parametricOffset, physics::ParametricValue(0.5));
233  neighborDistance = point::distance(pt_neighbor, pt_origin);
234  physics::ParametricRange drivingRange;
235  if (origin.first.point.parametricOffset < neighbor.first.point.parametricOffset)
236  {
237  drivingRange.minimum = origin.first.point.parametricOffset;
238  drivingRange.maximum = neighbor.first.point.parametricOffset;
239  }
240  else
241  {
242  drivingRange.minimum = neighbor.first.point.parametricOffset;
243  drivingRange.maximum = origin.first.point.parametricOffset;
244  }
245 
246  if (originLane == neighborLane)
247  {
248  neighborDuration = getDuration(*originLane, drivingRange);
249  }
250  else
251  {
252  auto const maxSpeed = std::max(getMaxSpeed(*originLane, drivingRange), cMinimumSpeed);
253  neighborDuration = neighborDistance / maxSpeed;
254  }
255  neighborDistance = std::max(neighborDistance, cMinimumNeighborDistance);
256  neighborDuration = std::max(neighborDuration, cMinimumNeighborDuration);
257  neighbor.second.routeDistance = origin.second.routeDistance + neighborDistance;
258  neighbor.second.routeDuration = origin.second.routeDuration + neighborDuration;
259  return neighbor;
260 }
261 
262 template <class RoutingCostData>
265  RoutingParaPoint neighborRoutingParaPoint)
266 {
267  RoutingPoint neighbor;
268  neighbor.first = neighborRoutingParaPoint;
269  neighbor.second.routeDistance = origin.second.routeDistance + cMinimumNeighborDistance;
270  neighbor.second.routeDuration = origin.second.routeDuration + cMinimumNeighborDuration;
271  return neighbor;
272 }
273 
274 template <class RoutingCostData>
277 {
278  if ((lane->id == getDest().laneId)
279  && ((isPositiveMovement(lane, origin) && (origin.first.point.parametricOffset <= getDest().parametricOffset))
280  || (isNegativeMovement(lane, origin) && (origin.first.point.parametricOffset >= getDest().parametricOffset))))
281  {
282  // approaching the destination from valid side
283  auto const neighbor = createNeighbor(lane, origin, lane, getRoutingDest());
284  addNeighbor(lane, origin, lane, neighbor, ExpandReason::Destination);
285  }
286  if (isPositiveMovement(lane, origin) && !isEnd(origin))
287  {
288  auto const neighbor = createNeighbor(
289  lane, origin, lane, createRoutingParaPoint(lane->id, physics::ParametricValue(1.), origin.first.direction));
290  addNeighbor(lane, origin, lane, neighbor, ExpandReason::SameLaneNeighbor);
291  }
292  if (isNegativeMovement(lane, origin) && !isStart(origin))
293  {
294  auto const neighbor = createNeighbor(
295  lane, origin, lane, createRoutingParaPoint(lane->id, physics::ParametricValue(0.), origin.first.direction));
296  addNeighbor(lane, origin, lane, neighbor, ExpandReason::SameLaneNeighbor);
297  }
298 }
299 
300 template <class RoutingCostData>
303 {
304  lane::ContactLaneList contactLanes;
305  if (isEnd(origin) && isPositiveMovement(lane, origin))
306  {
308  }
309  else if (isStart(origin) && isNegativeMovement(lane, origin))
310  {
312  }
313  for (auto contactLane : contactLanes)
314  {
315  if (!isLaneRelevantForExpansion(contactLane.toLane))
316  {
317  continue;
318  }
319  lane::Lane::ConstPtr otherLane = lane::getLanePtr(contactLane.toLane);
320  if (otherLane)
321  {
322  if (isRouteable(*otherLane))
323  {
324  lane::ContactLocation otherToLane = getContactLocation(*otherLane, lane->id);
325  if (otherToLane == lane::ContactLocation::SUCCESSOR)
326  {
327  auto routingDirection = RoutingDirection::NEGATIVE;
328  auto const neighbor = createLongitudinalNeighbor(
329  origin, createRoutingParaPoint(otherLane->id, physics::ParametricValue(1.), routingDirection));
330 
331  addNeighbor(lane, origin, otherLane, neighbor, ExpandReason::LongitudinalNeighbor);
332  }
333  else if (otherToLane == lane::ContactLocation::PREDECESSOR)
334  {
335  auto routingDirection = RoutingDirection::POSITIVE;
336  auto const neighbor = createLongitudinalNeighbor(
337  origin, createRoutingParaPoint(otherLane->id, physics::ParametricValue(0.), routingDirection));
338 
339  addNeighbor(lane, origin, otherLane, neighbor, ExpandReason::LongitudinalNeighbor);
340  }
341  else
342  {
343  throw std::runtime_error("Other lane neither SUCCESSOR not PREDECESSOR!");
344  }
345  }
346  }
347  else
348  {
349  throw std::runtime_error("No other lane!");
350  }
351  }
352 }
353 
354 template <class RoutingCostData>
357 {
358  for (auto const &contactLane :
360  {
361  if (!isLaneRelevantForExpansion(contactLane.toLane))
362  {
363  continue;
364  }
365  lane::Lane::ConstPtr otherLane = lane::getLanePtr(contactLane.toLane);
366  if (otherLane)
367  {
368  if (isRouteable(*otherLane))
369  {
370  if (laneDirectionIsIgnored() || (lane->direction == otherLane->direction))
371  {
372  auto const neighbor = createNeighbor(
373  lane,
374  origin,
375  otherLane,
376  createRoutingParaPoint(otherLane->id, origin.first.point.parametricOffset, origin.first.direction));
377  addNeighbor(lane, origin, otherLane, neighbor, ExpandReason::LateralNeighbor);
378  }
379  }
380  }
381  else
382  {
383  throw std::runtime_error("No other lane!");
384  }
385  }
386 }
387 
388 } // namespace planning
389 } // namespace route
390 } // namespace map
391 } // namespace ad
ad::map::route::planning::RouteExpander::isLaneRelevantForExpansion
bool isLaneRelevantForExpansion(lane::LaneId const laneId) const
check if lane is relevant for route expander
Definition: RouteExpander.hpp:163
ad::map::lane::ContactLocation::PREDECESSOR
@ PREDECESSOR
ad
namespace ad
Definition: GeometryStoreItem.hpp:28
ad::map::lane::ContactLocation::RIGHT
@ RIGHT
ad::map::route::planning::RouteExpander::~RouteExpander
virtual ~RouteExpander()=default
destructor.
ad::map::lane::getDuration
physics::Duration getDuration(Lane const &lane, physics::ParametricRange const &range)
ad::map::lane::isLaneRelevantForExpansion
bool isLaneRelevantForExpansion(lane::LaneId const &laneId, lane::LaneIdSet const &relevantLanes)
Checks if the laneId is relevant for expansion given the set of relevant lanes.
ad::map::route::planning::RouteExpander
Implements routing support functionality on the lane network.
Definition: RouteExpander.hpp:43
ad::map::lane::ContactLaneList
std::vector<::ad::map::lane::ContactLane > ContactLaneList
DataType ContactLaneList.
Definition: ContactLaneList.hpp:42
ad::map::lane::isLaneDirectionNegative
bool isLaneDirectionNegative(Lane const &lane)
Definition: LaneOperation.hpp:192
ad::map::route::planning::createRoutingParaPoint
RoutingParaPoint createRoutingParaPoint(lane::LaneId const &laneId, physics::ParametricValue const &parametricOffset, RoutingDirection const &routingDirection=RoutingDirection::DONT_CARE)
create a RoutingParaPoint
Definition: Routing.hpp:89
ad::map::route::planning::RouteExpander::expandNeighbors
void expandNeighbors(RoutingPoint const &origin)
Triggers the expansion of the given routing point origin to its valid neighborhood.
Definition: RouteExpander.hpp:188
ad::map::route::planning::RouteExpander::expandLateralNeighbors
void expandLateralNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
perform the expansion of the neighbor points in lateral (contacts: left/right) lane direction
Definition: RouteExpander.hpp:355
ad::map::route::planning::RouteExpander::RoutingPoint
std::pair< RoutingParaPoint, RoutingCost > RoutingPoint
definition of the routing point
Definition: RouteExpander.hpp:54
ad::map::route::planning::RouteExpander::clearRelevantLanes
void clearRelevantLanes()
clear the list of relevant lanes.
Definition: RouteExpander.hpp:101
ad::map::route::planning::RouteExpander::RoutingCost
definition of the routing cost data
Definition: RouteExpander.hpp:47
ad::map::lane::ContactLocation
ContactLocation
DataType ContactLocation.
Definition: ContactLocation.hpp:43
ad::map::route::planning::RouteExpander::ExpandReason::SameLaneNeighbor
@ SameLaneNeighbor
expand the route by a neighbor point within the same lane
ad::map::lane::getParametricPoint
point::ECEFPoint getParametricPoint(Lane const &lane, physics::ParametricValue const &longitudinalOffset, physics::ParametricValue const &lateralOffset)
Calculates parametric point on the lane. Point is calculated by first calculating t_long parametric p...
ad::map::route::planning::RouteExpander::setRelevantLanes
void setRelevantLanes(::ad::map::lane::LaneIdSet const &relevantLanes)
set the lanes that are relevant for routing All the rest of the lanes in the map are ignored.
Definition: RouteExpander.hpp:93
ad::map::route::planning::RoutingDirection::DONT_CARE
@ DONT_CARE
Vehicle direction is not relevant.
ad::map::route::planning::RouteExpander::RouteExpander
RouteExpander(const RoutingParaPoint &start, const RoutingParaPoint &dest, physics::Distance const &maxDistance, physics::Duration const &maxDuration, Type const &routingType)
Constructor.
Definition: RouteExpander.hpp:65
ad::map::route::planning::RouteExpander::expandSameLaneNeighbors
void expandSameLaneNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
perform the expansion of the neighbor points on the same lane
Definition: RouteExpander.hpp:275
ad::map::route::planning::RoutingDirection::NEGATIVE
@ NEGATIVE
Vehicle direction is opposite of Lane orientation.
ad::map::route::planning::Route::Type
Type
Routing type.
Definition: Route.hpp:59
ad::map::route::planning::RouteExpander::ExpandReason::Destination
@ Destination
expand the destination
ad::map::point::distance
physics::Distance distance(BoundingSphere const &left, BoundingSphere const &right)
Computes distance between BoundingSpheres.
Definition: BoundingSphereOperation.hpp:29
ad::map::route::planning::Route::laneDirectionIsIgnored
bool laneDirectionIsIgnored() const
ad::map::lane::ContactLocation::SUCCESSOR
@ SUCCESSOR
ad::map::lane::LaneId
DataType LaneId.
Definition: LaneId.hpp:66
ad::map::route::planning::RouteExpander::ExpandReason::LongitudinalNeighbor
@ LongitudinalNeighbor
expand the route by a longitudinal neighbor lane point
ad::map::route::planning::RouteExpander::ExpandReason::LateralNeighbor
@ LateralNeighbor
expand the route by a lateral neighbor lane point
ad::map::route::planning::RouteExpander::addNeighbor
virtual void addNeighbor(lane::Lane::ConstPtr originLane, RoutingPoint const &origin, lane::Lane::ConstPtr neighborLane, RoutingPoint const &neighbor, ExpandReason const &expandReason)=0
a neighbor is added
ad::map::lane::isLaneDirectionPositive
bool isLaneDirectionPositive(Lane const &lane)
Definition: LaneOperation.hpp:184
ad::map::route::planning::RouteExpander::createNeighbor
RoutingPoint createNeighbor(lane::Lane::ConstPtr originLane, RoutingPoint const &origin, lane::Lane::ConstPtr neighborLane, RoutingParaPoint neighborRoutingParaPoint)
create neighbor point and calculate the actual distance/duration to reach it
Definition: RouteExpander.hpp:219
ad::map::route::planning::RouteExpander::expandLongitudinalNeighbors
void expandLongitudinalNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
perform the expansion of the neighbor points in longitudinal (contacts: successor/predecessor) lane d...
Definition: RouteExpander.hpp:301
ad::map::lane::getLanePtr
Lane::ConstPtr getLanePtr(LaneId const &id)
Method to be called to retrieve Lane from the Store.
ad::map::route::planning::Route
Implements routing on the lane network.
Definition: Route.hpp:34
LaneOperation.hpp
ad::map::route::planning::RoutingDirection::POSITIVE
@ POSITIVE
Vehicle direction is same as Lane orientation.
ad::map::route::planning::RouteExpander::isPositiveMovement
bool isPositiveMovement(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
Definition: RouteExpander.hpp:149
ad::map::lane::isLanePartOfAnIntersection
bool isLanePartOfAnIntersection(Lane const &lane)
Definition: LaneOperation.hpp:209
ad::map::lane::isRouteable
bool isRouteable(Lane const &lane)
Definition: LaneOperation.hpp:200
ad::map::lane::getMaxSpeed
physics::Speed getMaxSpeed(Lane const &lane, physics::ParametricRange const &range)
ad::map::point::ECEFPoint
DataType ECEFPoint.
Definition: ECEFPoint.hpp:45
ad::map::route::planning::RouteExpander::isEnd
bool isEnd(RoutingPoint const &origin)
Definition: RouteExpander.hpp:143
ad::map::route::planning::RouteExpander::createLongitudinalNeighbor
RoutingPoint createLongitudinalNeighbor(RoutingPoint const &origin, RoutingParaPoint neighborRoutingParaPoint)
create longitudinal neighbor point with minimal actual distance/duration to reach
Definition: RouteExpander.hpp:264
ad::map::route::planning::RoutingParaPoint
routing para point
Definition: Routing.hpp:44
ad::map::route::planning::RouteExpander::mRelevantLanes
::ad::map::lane::LaneIdSet mRelevantLanes
relevant lanes for the routing
Definition: RouteExpander.hpp:184
Route.hpp
ad::map::lane::getContactLanes
ContactLaneList getContactLanes(Lane const &lane, ContactLocation const &location)
Find contact lanes at specific relative location.
ad::map::lane::ContactLocation::LEFT
@ LEFT
ad::map::route::planning::RouteExpander::isNegativeMovement
bool isNegativeMovement(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
Definition: RouteExpander.hpp:156
ad::map::route::planning::RouteExpander::isStart
bool isStart(RoutingPoint const &origin)
Definition: RouteExpander.hpp:137
ad::map::lane::Lane::ConstPtr
std::shared_ptr< Lane const > ConstPtr
Smart pointer on constant Lane.
Definition: Lane.hpp:66
ad::map::lane::getContactLocation
ContactLocation getContactLocation(Lane const &lane, LaneId const &to_lane_id)
Check nature of contact between this lane and another lane.
ad::map::route::planning::RouteExpander< RouteAstarScore >::ExpandReason
ExpandReason
Definition of the reasons for route expansion.
Definition: RouteExpander.hpp:110