LCOV - code coverage report
Current view: top level - include/ad/map/route - RouteExpander.hpp (source / functions) Hit Total Coverage
Test: ad_map_access Lines: 113 118 95.8 %
Date: 2022-10-04 09:48:07 Functions: 28 28 100.0 %
Branches: 158 252 62.7 %

           Branch data     Line data    Source code
       1                 :            : // ----------------- BEGIN LICENSE BLOCK ---------------------------------
       2                 :            : //
       3                 :            : // Copyright (C) 2019-2021 Intel Corporation
       4                 :            : //
       5                 :            : // SPDX-License-Identifier: MIT
       6                 :            : //
       7                 :            : // ----------------- END LICENSE BLOCK -----------------------------------
       8                 :            : /**
       9                 :            :  * @file
      10                 :            :  */
      11                 :            : 
      12                 :            : #pragma once
      13                 :            : 
      14                 :            : #include <utility>
      15                 :            : 
      16                 :            : #include "ad/map/lane/LaneOperation.hpp"
      17                 :            : #include "ad/map/route/Route.hpp"
      18                 :            : #include "ad/physics/Operation.hpp"
      19                 :            : 
      20                 :            : /** @brief namespace ad */
      21                 :            : namespace ad {
      22                 :            : /** @brief namespace map */
      23                 :            : namespace map {
      24                 :            : /** @brief namespace route */
      25                 :            : namespace route {
      26                 :            : /**
      27                 :            :  * @brief provides route planning capabilities on the road network of the map
      28                 :            :  */
      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                 :            : 
      37                 :            : /**
      38                 :            :  * @brief Implements routing support functionality on the lane network.
      39                 :            :  *
      40                 :            :  * This class is used to expand a route by its reachable neighbors.
      41                 :            :  * The routing cost data is defined by a template type to be defined by the actual routing class.
      42                 :            :  */
      43                 :            : template <class RoutingCostData> class RouteExpander : public Route
      44                 :            : {
      45                 :            : public:
      46                 :            :   //! definition of the routing cost data
      47                 :            :   struct RoutingCost
      48                 :            :   {
      49                 :            :     physics::Distance routeDistance{0.};
      50                 :            :     physics::Duration routeDuration{0.};
      51                 :            :     RoutingCostData costData{};
      52                 :            :   };
      53                 :            :   //! definition of the routing point
      54                 :            :   typedef std::pair<RoutingParaPoint, RoutingCost> RoutingPoint;
      55                 :            : 
      56                 :            :   /**
      57                 :            :    * @brief Constructor
      58                 :            :    *
      59                 :            :    * @param[in] start Start point.
      60                 :            :    * @param[in] dest  Destination point.
      61                 :            :    * @param[in] maxDistance maximum route search distance.
      62                 :            :    * @param[in] maxDuration maximum route search duration.
      63                 :            :    * @param[in] typ   Type of the route to be calculated.
      64                 :            :    */
      65                 :       2763 :   RouteExpander(const RoutingParaPoint &start,
      66                 :            :                 const RoutingParaPoint &dest,
      67                 :            :                 physics::Distance const &maxDistance,
      68                 :            :                 physics::Duration const &maxDuration,
      69                 :            :                 Type const &routingType)
      70                 :       2763 :     : Route(start, dest, maxDistance, maxDuration, routingType)
      71                 :            :   {
      72                 :       2763 :   }
      73                 :            : 
      74                 :            :   RouteExpander(RouteExpander const &) = delete;
      75                 :            :   RouteExpander(RouteExpander const &&) = delete;
      76                 :            :   RouteExpander &operator=(RouteExpander const &) = delete;
      77                 :            :   RouteExpander &operator=(RouteExpander &&) = delete;
      78                 :            : 
      79                 :            :   /**
      80                 :            :    * @brief destructor.
      81                 :            :    */
      82                 :       2763 :   virtual ~RouteExpander() = default;
      83                 :            : 
      84                 :            :   /**
      85                 :            :    * @brief Triggers the expansion of the given routing point \a origin to its valid neighborhood
      86                 :            :    */
      87                 :            :   void expandNeighbors(RoutingPoint const &origin);
      88                 :            : 
      89                 :            :   /**
      90                 :            :    * @brief set the lanes that are relevant for routing
      91                 :            :    * All the rest of the lanes in the map are ignored.
      92                 :            :    */
      93                 :         51 :   void setRelevantLanes(::ad::map::lane::LaneIdSet const &relevantLanes)
      94                 :            :   {
      95                 :         51 :     mRelevantLanes = relevantLanes;
      96                 :         51 :   }
      97                 :            : 
      98                 :            :   /**
      99                 :            :    * @brief clear the list of relevant lanes.
     100                 :            :    */
     101                 :            :   void clearRelevantLanes()
     102                 :            :   {
     103                 :            :     mRelevantLanes.clear();
     104                 :            :   }
     105                 :            : 
     106                 :            : protected:
     107                 :            :   /**
     108                 :            :    * @brief Definition of the reasons for route expansion
     109                 :            :    */
     110                 :            :   enum class ExpandReason
     111                 :            :   {
     112                 :            :     SameLaneNeighbor,     //!< expand the route by a neighbor point within the same lane
     113                 :            :     LongitudinalNeighbor, //!< expand the route by a longitudinal neighbor lane point
     114                 :            :     LateralNeighbor,      //!< expand the route by a lateral neighbor lane point
     115                 :            :     Destination,          //!< expand the destination
     116                 :            :   };
     117                 :            : 
     118                 :            :   /**
     119                 :            :    * @brief a neighbor is added
     120                 :            :    *
     121                 :            :    * Override this function in the derived class to get notified on expanded neighbors.
     122                 :            :    *
     123                 :            :    * @param[in] originLane the lane object of the \a origin point
     124                 :            :    * @param[in] origin the origin RoutingPoint provided to the ExpandNeighbors() function
     125                 :            :    * @param[in] neighborLane the lane object of the \a neighbor point
     126                 :            :    * @param[in] neighbor the neighbor RoutingPoint which is added (RoutingCostData not filled!)
     127                 :            :    * @param[in] expandReason the reason why the origin was expanded to this neighbor
     128                 :            :    */
     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                 :            : 
     136                 :            :   //! @returns \c true if the given origin point is the parametric start
     137                 :      35121 :   bool isStart(RoutingPoint const &origin)
     138                 :            :   {
     139         [ +  - ]:      35121 :     return origin.first.point.parametricOffset == physics::ParametricValue(0.);
     140                 :            :   }
     141                 :            : 
     142                 :            :   //! @returns \c true if the given origin point is the parametric end
     143                 :      44374 :   bool isEnd(RoutingPoint const &origin)
     144                 :            :   {
     145         [ +  - ]:      44374 :     return origin.first.point.parametricOffset == physics::ParametricValue(1.);
     146                 :            :   }
     147                 :            : 
     148                 :            :   //! @returns \c true if the given origin point on the given lane defines a positive movement
     149                 :      42797 :   bool isPositiveMovement(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
     150                 :            :   {
     151         [ +  + ]:      85257 :     return (laneDirectionIsIgnored() || isLaneDirectionPositive(*lane))
     152   [ +  +  +  + ]:      85257 :       && (origin.first.direction == RoutingDirection::POSITIVE);
     153                 :            :   }
     154                 :            : 
     155                 :            :   //! @returns \c true if the given origin point on the given lane defines a negative movement
     156                 :      42605 :   bool isNegativeMovement(lane::Lane::ConstPtr lane, RoutingPoint const &origin)
     157                 :            :   {
     158         [ +  + ]:      84884 :     return (laneDirectionIsIgnored() || isLaneDirectionNegative(*lane))
     159   [ +  +  +  + ]:      84884 :       && (origin.first.direction == RoutingDirection::NEGATIVE);
     160                 :            :   }
     161                 :            : 
     162                 :            :   //! check if lane is relevant for route expander
     163                 :      55738 :   bool isLaneRelevantForExpansion(lane::LaneId const laneId) const
     164                 :            :   {
     165                 :      55738 :     return lane::isLaneRelevantForExpansion(laneId, mRelevantLanes);
     166                 :            :   }
     167                 :            : 
     168                 :            :   //! perform the expansion of the neighbor points on the same lane
     169                 :            :   void expandSameLaneNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin);
     170                 :            :   //! perform the expansion of the neighbor points in longitudinal (contacts: successor/predecessor) lane direction
     171                 :            :   void expandLongitudinalNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin);
     172                 :            :   //! perform the expansion of the neighbor points in lateral (contacts: left/right) lane direction
     173                 :            :   void expandLateralNeighbors(lane::Lane::ConstPtr lane, RoutingPoint const &origin);
     174                 :            : 
     175                 :            :   //! create neighbor point and calculate the actual distance/duration to reach it
     176                 :            :   RoutingPoint createNeighbor(lane::Lane::ConstPtr originLane,
     177                 :            :                               RoutingPoint const &origin,
     178                 :            :                               lane::Lane::ConstPtr neighborLane,
     179                 :            :                               RoutingParaPoint neighborRoutingParaPoint);
     180                 :            :   //! create longitudinal neighbor point with minimal actual distance/duration to reach
     181                 :            :   RoutingPoint createLongitudinalNeighbor(RoutingPoint const &origin, RoutingParaPoint neighborRoutingParaPoint);
     182                 :            : 
     183                 :            :   //! relevant lanes for the routing
     184                 :            :   ::ad::map::lane::LaneIdSet mRelevantLanes;
     185                 :            : };
     186                 :            : 
     187                 :            : template <class RoutingCostData>
     188                 :      29505 : void RouteExpander<RoutingCostData>::expandNeighbors(
     189                 :            :   typename RouteExpander<RoutingCostData>::RoutingPoint const &origin)
     190                 :            : {
     191         [ -  + ]:      29505 :   if (origin.first.direction == RoutingDirection::DONT_CARE)
     192                 :            :   {
     193         [ #  # ]:          0 :     throw std::runtime_error("RouteExpander::ExpandNeighbors invalid routing direction!");
     194                 :            :   }
     195                 :            : 
     196         [ +  - ]:      59010 :   lane::Lane::ConstPtr lane = lane::getLanePtr(origin.first.point.laneId);
     197         [ +  - ]:      29505 :   if (lane)
     198                 :            :   {
     199                 :      29505 :     if ( // lane has to be routable to expand
     200                 :      29505 :       isRouteable(*lane)
     201   [ +  -  +  + ]:      59010 :       && ( // max distance and max duration are not yet reached
     202   [ +  -  +  +  :      29505 :         ((origin.second.routeDistance < mMaxDistance) && (origin.second.routeDuration < mMaxDuration))
             +  -  +  + ]
     203                 :            :         // or we are within an intersection
     204         [ +  + ]:        354 :         || lane::isLanePartOfAnIntersection(*lane)))
     205                 :            :     {
     206         [ +  - ]:      29301 :       expandSameLaneNeighbors(lane, origin);
     207         [ +  - ]:      29301 :       expandLongitudinalNeighbors(lane, origin);
     208         [ +  - ]:      29301 :       expandLateralNeighbors(lane, origin);
     209                 :            :     }
     210                 :            :   }
     211                 :            :   else
     212                 :            :   {
     213         [ #  # ]:          0 :     throw std::runtime_error("RouteExpander::ExpandNeighbors No lane!");
     214                 :            :   }
     215                 :      29505 : }
     216                 :            : 
     217                 :            : template <class RoutingCostData>
     218                 :            : typename RouteExpander<RoutingCostData>::RoutingPoint
     219                 :      29789 : RouteExpander<RoutingCostData>::createNeighbor(lane::Lane::ConstPtr originLane,
     220                 :            :                                                RoutingPoint const &origin,
     221                 :            :                                                lane::Lane::ConstPtr neighborLane,
     222                 :            :                                                RoutingParaPoint neighborRoutingParaPoint)
     223                 :            : {
     224         [ +  - ]:      29789 :   RoutingPoint neighbor;
     225                 :      29789 :   neighbor.first = neighborRoutingParaPoint;
     226                 :            : 
     227                 :      29789 :   physics::Distance neighborDistance{0.};
     228                 :      29789 :   physics::Duration neighborDuration{0.};
     229                 :            :   point::ECEFPoint pt_origin
     230         [ +  - ]:      29789 :     = getParametricPoint(*originLane, origin.first.point.parametricOffset, physics::ParametricValue(0.5));
     231                 :            :   point::ECEFPoint pt_neighbor
     232         [ +  - ]:      29789 :     = getParametricPoint(*neighborLane, neighbor.first.point.parametricOffset, physics::ParametricValue(0.5));
     233         [ +  - ]:      29789 :   neighborDistance = point::distance(pt_neighbor, pt_origin);
     234         [ +  - ]:      29789 :   physics::ParametricRange drivingRange;
     235   [ +  -  +  + ]:      29789 :   if (origin.first.point.parametricOffset < neighbor.first.point.parametricOffset)
     236                 :            :   {
     237                 :      11455 :     drivingRange.minimum = origin.first.point.parametricOffset;
     238                 :      11455 :     drivingRange.maximum = neighbor.first.point.parametricOffset;
     239                 :            :   }
     240                 :            :   else
     241                 :            :   {
     242                 :      18334 :     drivingRange.minimum = neighbor.first.point.parametricOffset;
     243                 :      18334 :     drivingRange.maximum = origin.first.point.parametricOffset;
     244                 :            :   }
     245                 :            : 
     246         [ +  + ]:      29789 :   if (originLane == neighborLane)
     247                 :            :   {
     248         [ +  - ]:      19873 :     neighborDuration = getDuration(*originLane, drivingRange);
     249                 :            :   }
     250                 :            :   else
     251                 :            :   {
     252   [ +  -  +  - ]:       9916 :     auto const maxSpeed = std::max(getMaxSpeed(*originLane, drivingRange), cMinimumSpeed);
     253         [ +  - ]:       9916 :     neighborDuration = neighborDistance / maxSpeed;
     254                 :            :   }
     255         [ +  - ]:      29789 :   neighborDistance = std::max(neighborDistance, cMinimumNeighborDistance);
     256         [ +  - ]:      29789 :   neighborDuration = std::max(neighborDuration, cMinimumNeighborDuration);
     257         [ +  - ]:      29789 :   neighbor.second.routeDistance = origin.second.routeDistance + neighborDistance;
     258         [ +  - ]:      29789 :   neighbor.second.routeDuration = origin.second.routeDuration + neighborDuration;
     259                 :      59578 :   return neighbor;
     260                 :            : }
     261                 :            : 
     262                 :            : template <class RoutingCostData>
     263                 :            : typename RouteExpander<RoutingCostData>::RoutingPoint
     264                 :      24368 : RouteExpander<RoutingCostData>::createLongitudinalNeighbor(RoutingPoint const &origin,
     265                 :            :                                                            RoutingParaPoint neighborRoutingParaPoint)
     266                 :            : {
     267                 :      24368 :   RoutingPoint neighbor;
     268                 :      24368 :   neighbor.first = neighborRoutingParaPoint;
     269                 :      24368 :   neighbor.second.routeDistance = origin.second.routeDistance + cMinimumNeighborDistance;
     270                 :      24368 :   neighbor.second.routeDuration = origin.second.routeDuration + cMinimumNeighborDuration;
     271                 :      24368 :   return neighbor;
     272                 :            : }
     273                 :            : 
     274                 :            : template <class RoutingCostData>
     275                 :      29301 : void RouteExpander<RoutingCostData>::expandSameLaneNeighbors(
     276                 :            :   lane::Lane::ConstPtr lane, typename RouteExpander<RoutingCostData>::RoutingPoint const &origin)
     277                 :            : {
     278         [ +  - ]:      29301 :   if ((lane->id == getDest().laneId)
     279   [ +  +  +  -  :      89119 :       && ((isPositiveMovement(lane, origin) && (origin.first.point.parametricOffset <= getDest().parametricOffset))
          +  +  +  -  +  
             +  +  +  -  
                      - ]
     280   [ +  -  +  +  :      30517 :           || (isNegativeMovement(lane, origin) && (origin.first.point.parametricOffset >= getDest().parametricOffset))))
          +  -  +  +  +  
             +  +  +  -  
                      - ]
     281                 :            :   {
     282                 :            :     // approaching the destination from valid side
     283         [ +  - ]:       2756 :     auto const neighbor = createNeighbor(lane, origin, lane, getRoutingDest());
     284         [ +  - ]:       2756 :     addNeighbor(lane, origin, lane, neighbor, ExpandReason::Destination);
     285                 :            :   }
     286   [ +  -  +  +  :      29301 :   if (isPositiveMovement(lane, origin) && !isEnd(origin))
          +  -  +  +  +  
             -  +  +  -  
                      - ]
     287                 :            :   {
     288         [ +  - ]:       9893 :     auto const neighbor = createNeighbor(
     289         [ +  - ]:       9893 :       lane, origin, lane, createRoutingParaPoint(lane->id, physics::ParametricValue(1.), origin.first.direction));
     290         [ +  - ]:       9893 :     addNeighbor(lane, origin, lane, neighbor, ExpandReason::SameLaneNeighbor);
     291                 :            :   }
     292   [ +  -  +  +  :      29301 :   if (isNegativeMovement(lane, origin) && !isStart(origin))
          +  -  +  +  +  
             -  +  +  -  
                      - ]
     293                 :            :   {
     294         [ +  - ]:       7224 :     auto const neighbor = createNeighbor(
     295         [ +  - ]:       7224 :       lane, origin, lane, createRoutingParaPoint(lane->id, physics::ParametricValue(0.), origin.first.direction));
     296         [ +  - ]:       7224 :     addNeighbor(lane, origin, lane, neighbor, ExpandReason::SameLaneNeighbor);
     297                 :            :   }
     298                 :      29301 : }
     299                 :            : 
     300                 :            : template <class RoutingCostData>
     301                 :      29301 : void RouteExpander<RoutingCostData>::expandLongitudinalNeighbors(
     302                 :            :   lane::Lane::ConstPtr lane, typename RouteExpander<RoutingCostData>::RoutingPoint const &origin)
     303                 :            : {
     304                 :      58602 :   lane::ContactLaneList contactLanes;
     305   [ +  -  +  +  :      29301 :   if (isEnd(origin) && isPositiveMovement(lane, origin))
          +  -  +  +  +  
             +  +  +  -  
                      - ]
     306                 :            :   {
     307         [ +  - ]:       5180 :     contactLanes = lane::getContactLanes(*lane, lane::ContactLocation::SUCCESSOR);
     308                 :            :   }
     309   [ +  -  +  +  :      24121 :   else if (isStart(origin) && isNegativeMovement(lane, origin))
          +  -  +  +  +  
             +  +  +  -  
                      - ]
     310                 :            :   {
     311         [ +  - ]:       3776 :     contactLanes = lane::getContactLanes(*lane, lane::ContactLocation::PREDECESSOR);
     312                 :            :   }
     313   [ +  +  +  - ]:      53674 :   for (auto contactLane : contactLanes)
     314                 :            :   {
     315   [ +  -  +  + ]:      24373 :     if (!isLaneRelevantForExpansion(contactLane.toLane))
     316                 :            :     {
     317                 :          5 :       continue;
     318                 :            :     }
     319         [ +  - ]:      48736 :     lane::Lane::ConstPtr otherLane = lane::getLanePtr(contactLane.toLane);
     320         [ +  - ]:      24368 :     if (otherLane)
     321                 :            :     {
     322         [ +  - ]:      24368 :       if (isRouteable(*otherLane))
     323                 :            :       {
     324         [ +  - ]:      24368 :         lane::ContactLocation otherToLane = getContactLocation(*otherLane, lane->id);
     325         [ +  + ]:      24368 :         if (otherToLane == lane::ContactLocation::SUCCESSOR)
     326                 :            :         {
     327                 :       9981 :           auto routingDirection = RoutingDirection::NEGATIVE;
     328         [ +  - ]:      19962 :           auto const neighbor = createLongitudinalNeighbor(
     329         [ +  - ]:       9981 :             origin, createRoutingParaPoint(otherLane->id, physics::ParametricValue(1.), routingDirection));
     330                 :            : 
     331         [ +  - ]:       9981 :           addNeighbor(lane, origin, otherLane, neighbor, ExpandReason::LongitudinalNeighbor);
     332                 :            :         }
     333         [ +  - ]:      14387 :         else if (otherToLane == lane::ContactLocation::PREDECESSOR)
     334                 :            :         {
     335                 :      14387 :           auto routingDirection = RoutingDirection::POSITIVE;
     336         [ +  - ]:      28774 :           auto const neighbor = createLongitudinalNeighbor(
     337         [ +  - ]:      14387 :             origin, createRoutingParaPoint(otherLane->id, physics::ParametricValue(0.), routingDirection));
     338                 :            : 
     339         [ +  - ]:      14387 :           addNeighbor(lane, origin, otherLane, neighbor, ExpandReason::LongitudinalNeighbor);
     340                 :            :         }
     341                 :            :         else
     342                 :            :         {
     343         [ #  # ]:          0 :           throw std::runtime_error("Other lane neither SUCCESSOR not PREDECESSOR!");
     344                 :            :         }
     345                 :            :       }
     346                 :            :     }
     347                 :            :     else
     348                 :            :     {
     349         [ #  # ]:          0 :       throw std::runtime_error("No other lane!");
     350                 :            :     }
     351                 :            :   }
     352                 :      29301 : }
     353                 :            : 
     354                 :            : template <class RoutingCostData>
     355                 :      29301 : void RouteExpander<RoutingCostData>::expandLateralNeighbors(
     356                 :            :   lane::Lane::ConstPtr lane, typename RouteExpander<RoutingCostData>::RoutingPoint const &origin)
     357                 :            : {
     358   [ +  -  +  -  :      89967 :   for (auto const &contactLane :
                   +  + ]
     359                 :      29301 :        lane::getContactLanes(*lane, {lane::ContactLocation::LEFT, lane::ContactLocation::RIGHT}))
     360                 :            :   {
     361   [ +  -  +  + ]:      31365 :     if (!isLaneRelevantForExpansion(contactLane.toLane))
     362                 :            :     {
     363                 :          8 :       continue;
     364                 :            :     }
     365         [ +  - ]:      62714 :     lane::Lane::ConstPtr otherLane = lane::getLanePtr(contactLane.toLane);
     366         [ +  - ]:      31357 :     if (otherLane)
     367                 :            :     {
     368         [ +  + ]:      31357 :       if (isRouteable(*otherLane))
     369                 :            :       {
     370   [ +  -  +  +  :      30104 :         if (laneDirectionIsIgnored() || (lane->direction == otherLane->direction))
             +  +  +  + ]
     371                 :            :         {
     372         [ +  - ]:       9916 :           auto const neighbor = createNeighbor(
     373                 :            :             lane,
     374                 :            :             origin,
     375                 :            :             otherLane,
     376         [ +  - ]:       9916 :             createRoutingParaPoint(otherLane->id, origin.first.point.parametricOffset, origin.first.direction));
     377         [ +  - ]:       9916 :           addNeighbor(lane, origin, otherLane, neighbor, ExpandReason::LateralNeighbor);
     378                 :            :         }
     379                 :            :       }
     380                 :            :     }
     381                 :            :     else
     382                 :            :     {
     383         [ #  # ]:          0 :       throw std::runtime_error("No other lane!");
     384                 :            :     }
     385                 :            :   }
     386                 :      29301 : }
     387                 :            : 
     388                 :            : } // namespace planning
     389                 :            : } // namespace route
     390                 :            : } // namespace map
     391                 :            : } // namespace ad

Generated by: LCOV version 1.14