LCOV - code coverage report
Current view: top level - src/route - RouteAStar.cpp (source / functions) Hit Total Coverage
Test: ad_map_access Lines: 79 91 86.8 %
Date: 2022-10-04 09:48:07 Functions: 8 10 80.0 %
Branches: 48 88 54.5 %

           Branch data     Line data    Source code
       1                 :            : // ----------------- BEGIN LICENSE BLOCK ---------------------------------
       2                 :            : //
       3                 :            : // Copyright (C) 2018-2021 Intel Corporation
       4                 :            : //
       5                 :            : // SPDX-License-Identifier: MIT
       6                 :            : //
       7                 :            : // ----------------- END LICENSE BLOCK -----------------------------------
       8                 :            : 
       9                 :            : #include "ad/map/route/RouteAStar.hpp"
      10                 :            : 
      11                 :            : #include <algorithm>
      12                 :            : #include "ad/map/access/Logging.hpp"
      13                 :            : 
      14                 :            : #define DEBUG_OUTPUT 0
      15                 :            : 
      16                 :            : #if DEBUG_OUTPUT
      17                 :            : #include <iostream>
      18                 :            : 
      19                 :            : namespace std {
      20                 :            : 
      21                 :            : inline ostream &operator<<(ostream &out, ::ad::map::route::planning::RouteAstar::RoutingPoint const &value)
      22                 :            : {
      23                 :            :   out << value.first.point << "|" << (int)value.first.direction << " ("
      24                 :            :       << static_cast<double>(value.second.routeDistance) << ","
      25                 :            :       << static_cast<double>(value.second.costData.estimatedDistanceToTarget) << ")";
      26                 :            :   return out;
      27                 :            : }
      28                 :            : 
      29                 :            : } // namespace std
      30                 :            : #endif
      31                 :            : 
      32                 :            : namespace ad {
      33                 :            : namespace map {
      34                 :            : namespace route {
      35                 :            : namespace planning {
      36                 :            : 
      37                 :         12 : RouteAstar::RouteAstar(const RoutingParaPoint &start,
      38                 :            :                        const RoutingParaPoint &dest,
      39                 :            :                        physics::Distance const &maxDistance,
      40                 :            :                        physics::Duration const &maxDuration,
      41                 :         12 :                        Type typ)
      42                 :         12 :   : RouteExpander(start, dest, maxDistance, maxDuration, typ)
      43                 :            : {
      44         [ +  - ]:         12 :   initLanePointer();
      45                 :         12 : }
      46                 :            : 
      47                 :          0 : RouteAstar::RouteAstar(const RoutingParaPoint &start,
      48                 :            :                        const RoutingParaPoint &dest,
      49                 :            :                        physics::Distance const &maxDistance,
      50                 :          0 :                        Type typ)
      51         [ #  # ]:          0 :   : RouteExpander(start, dest, maxDistance, physics::Duration::getMax(), typ)
      52                 :            : {
      53         [ #  # ]:          0 :   initLanePointer();
      54                 :          0 : }
      55                 :            : 
      56                 :          0 : RouteAstar::RouteAstar(const RoutingParaPoint &start,
      57                 :            :                        const RoutingParaPoint &dest,
      58                 :            :                        physics::Duration const &maxDuration,
      59                 :          0 :                        Type typ)
      60         [ #  # ]:          0 :   : RouteExpander(start, dest, physics::Distance::getMax(), maxDuration, typ)
      61                 :            : {
      62         [ #  # ]:          0 :   initLanePointer();
      63                 :          0 : }
      64                 :            : 
      65                 :       2711 : RouteAstar::RouteAstar(const RoutingParaPoint &start, const RoutingParaPoint &dest, Type typ)
      66         [ +  - ]:       2711 :   : RouteExpander(start, dest, physics::Distance::getMax(), physics::Duration::getMax(), typ)
      67                 :            : {
      68         [ +  - ]:       2711 :   initLanePointer();
      69                 :       2711 : }
      70                 :            : 
      71                 :       2723 : void RouteAstar::initLanePointer()
      72                 :            : {
      73                 :       2723 :   mDestLane = lane::getLanePtr(mDest.point.laneId);
      74         [ -  + ]:       2723 :   if (!mDestLane)
      75                 :            :   {
      76         [ #  # ]:          0 :     throw std::runtime_error("Dest lane not found!");
      77                 :            :   }
      78                 :       2723 :   mStartLane = lane::getLanePtr(mStart.point.laneId);
      79         [ -  + ]:       2723 :   if (!mStartLane)
      80                 :            :   {
      81         [ #  # ]:          0 :     throw std::runtime_error("Start lane not found!");
      82                 :            :   }
      83                 :       2723 : }
      84                 :            : 
      85                 :            : // https://en.wikipedia.org/wiki/A*_search_algorithm
      86                 :       2723 : bool RouteAstar::calculate()
      87                 :            : {
      88                 :       2723 :   mProcessedPoints.clear();
      89                 :       2723 :   mProcessingMap.clear();
      90                 :       2723 :   mCameFrom.clear();
      91                 :       2723 :   mRawRoutes.clear();
      92                 :            : 
      93                 :            :   // A* working structures.
      94                 :            :   // Initial values.
      95                 :       2723 :   RoutingCost cost;
      96         [ +  - ]:       2723 :   cost.costData.estimatedDistanceToTarget = costEstimate(mStartLane, mStart.point);
      97         [ +  + ]:       2723 :   if (mStart.direction == RoutingDirection::DONT_CARE)
      98                 :            :   {
      99                 :            :     // Don't care routing direction means the vehicle can drive forward or backward.
     100                 :            :     // Within the routing we have to replace this by concrete directions,
     101                 :            :     // otherwise the vehicle would be able to switch between forward/backward while driving on the route
     102                 :            :     // which especially is not meant by the don't care flag.
     103                 :       2711 :     auto startPositive = mStart;
     104                 :       2711 :     startPositive.direction = RoutingDirection::POSITIVE;
     105         [ +  - ]:       2711 :     mProcessingMap.insert({startPositive, cost});
     106                 :       2711 :     auto startNegative = mStart;
     107                 :       2711 :     startNegative.direction = RoutingDirection::NEGATIVE;
     108         [ +  - ]:       2711 :     mProcessingMap.insert({startNegative, cost});
     109                 :            :   }
     110                 :            :   else
     111                 :            :   {
     112         [ +  - ]:         12 :     mProcessingMap.insert({mStart, cost});
     113                 :            :   }
     114                 :            :   // Run
     115                 :       2723 :   bool pathFound = false;
     116                 :            : #if DEBUG_OUTPUT
     117                 :            :   std::cout << "######### (typ:" << (int)mType << " #########"
     118                 :            :             << " start: " << mStart.point << " dest: " << mDest.point << std::endl;
     119                 :            : #endif
     120         [ +  + ]:      33265 :   while (!mProcessingMap.empty())
     121                 :            :   {
     122                 :            :     // sort the routing points by the smallest total cost
     123                 :            :     struct FScoreCompare
     124                 :            :     {
     125                 :      75082 :       bool operator()(RoutingPoint const &left, RoutingPoint const &right) const
     126                 :            :       {
     127                 :      75082 :         return left.second.costData.estimatedDistanceToTarget < right.second.costData.estimatedDistanceToTarget;
     128                 :            :       }
     129                 :            :     };
     130         [ +  - ]:      30542 :     auto minimumCostIterator = std::min_element(mProcessingMap.begin(), mProcessingMap.end(), FScoreCompare());
     131         [ +  - ]:          2 :     if (((mDest.direction == RoutingDirection::DONT_CARE) || (mDest.direction == minimumCostIterator->first.direction))
     132   [ +  +  +  -  :      30544 :         && (minimumCostIterator->first.point == mDest.point))
             +  +  +  + ]
     133                 :            :     {
     134         [ +  - ]:       2709 :       reconstructPath(*minimumCostIterator);
     135                 :       2709 :       pathFound = true;
     136                 :            : #if DEBUG_OUTPUT
     137                 :            :       std::cout << "Target reached " << *minimumCostIterator << std::endl;
     138                 :            :       for (auto const &point : getRawRoute().paraPointList)
     139                 :            :       {
     140                 :            :         std::cout << " " << point << std::endl;
     141                 :            :       }
     142                 :            :       std::cout << "#########" << std::endl;
     143                 :            : #endif
     144                 :       2709 :       mProcessingMap.clear();
     145                 :            :     }
     146                 :            :     else
     147                 :            :     {
     148                 :      27833 :       RoutingPoint const minimumValue = *minimumCostIterator;
     149         [ +  - ]:      27833 :       mProcessingMap.erase(minimumCostIterator);
     150         [ +  - ]:      27833 :       mProcessedPoints.insert(minimumValue.first);
     151                 :            : #if DEBUG_OUTPUT
     152                 :            :       std::cout << "Expanding: " << minimumValue << std::endl;
     153                 :            : #endif
     154         [ +  - ]:      27833 :       expandNeighbors(minimumValue);
     155                 :            : #if DEBUG_OUTPUT
     156                 :            :       std::cout << "Results in " << std::endl;
     157                 :            :       for (auto &element : mProcessingMap)
     158                 :            :       {
     159                 :            :         std::cout << " " << element << std::endl;
     160                 :            :       }
     161                 :            :       std::cout << "----------" << std::endl;
     162                 :            : #endif
     163                 :            :     }
     164                 :            :   }
     165                 :            : 
     166                 :       2723 :   mProcessedPoints.clear();
     167                 :       2723 :   mProcessingMap.clear();
     168                 :       2723 :   mCameFrom.clear();
     169                 :            : 
     170                 :       2723 :   return pathFound;
     171                 :            : }
     172                 :            : 
     173                 :      38423 : physics::Distance RouteAstar::costEstimate(lane::Lane::ConstPtr neighborLane, point::ParaPoint const &neighbor)
     174                 :            : {
     175         [ +  - ]:      38423 :   point::ECEFPoint pt_a = getParametricPoint(*neighborLane, neighbor.parametricOffset, physics::ParametricValue(0.5));
     176         [ +  - ]:      38423 :   point::ECEFPoint pt_b = getParametricPoint(*mDestLane, getDest().parametricOffset, physics::ParametricValue(0.5));
     177         [ +  - ]:      38423 :   physics::Distance d = distance(pt_a, pt_b);
     178                 :      38423 :   return d;
     179                 :            : }
     180                 :            : 
     181                 :      51273 : void RouteAstar::addNeighbor(lane::Lane::ConstPtr originLane,
     182                 :            :                              RoutingPoint const &origin,
     183                 :            :                              lane::Lane::ConstPtr neighborLane,
     184                 :            :                              RoutingPoint const &neighbor,
     185                 :            :                              ExpandReason const &expandReason)
     186                 :            : {
     187                 :            :   (void)originLane;
     188                 :            :   (void)expandReason;
     189                 :            : 
     190   [ +  -  +  + ]:      51273 :   if (mProcessedPoints.find(neighbor.first) == mProcessedPoints.end())
     191                 :            :   {
     192         [ +  - ]:      47663 :     auto insertResult = mProcessingMap.insert(neighbor);
     193                 :      47663 :     if ( // insertion succeeded
     194   [ +  +  +  + ]:      60714 :       insertResult.second ||
     195                 :            :       // actual distance of new neighbor is smaller than the found duplicate
     196   [ +  -  +  + ]:      13051 :       (neighbor.second.routeDistance < insertResult.first->second.routeDistance))
     197                 :            :     {
     198         [ +  - ]:      35700 :       auto const estimatedDestCost = costEstimate(neighborLane, neighbor.first.point);
     199                 :      35700 :       insertResult.first->second.routeDistance = neighbor.second.routeDistance;
     200         [ +  - ]:      35700 :       insertResult.first->second.costData.estimatedDistanceToTarget = neighbor.second.routeDistance + estimatedDestCost;
     201         [ +  - ]:      35700 :       mCameFrom[neighbor.first] = origin.first;
     202                 :            : #if DEBUG_OUTPUT
     203                 :            :       std::cout << "Inserted: " << *insertResult.first << std::endl;
     204                 :            : #endif
     205                 :            :     }
     206                 :            :   }
     207                 :      51273 : }
     208                 :            : 
     209                 :       2709 : void RouteAstar::reconstructPath(RoutingPoint const &dest)
     210                 :            : {
     211                 :       5418 :   RawRoute rawRoute;
     212                 :       2709 :   rawRoute.routeDistance = dest.second.routeDistance;
     213                 :       2709 :   rawRoute.routeDuration = dest.second.routeDuration;
     214                 :       2709 :   for (auto current = dest.first;;)
     215                 :            :   {
     216         [ +  - ]:      18737 :     rawRoute.paraPointList.insert(rawRoute.paraPointList.begin(), current.point);
     217         [ +  - ]:      18737 :     auto it = mCameFrom.find(current);
     218         [ +  + ]:      18737 :     if (it == mCameFrom.end())
     219                 :            :     {
     220                 :       2709 :       break;
     221                 :            :     }
     222                 :            :     else
     223                 :            :     {
     224                 :      16028 :       current = it->second;
     225                 :            :     }
     226                 :      16028 :   }
     227                 :       2709 :   mDest = dest.first;
     228                 :       2709 :   mValid = true;
     229         [ +  - ]:       2709 :   mRawRoutes.push_back(rawRoute);
     230                 :       2709 : }
     231                 :            : 
     232                 :            : } // namespace planning
     233                 :            : } // namespace route
     234                 :            : } // namespace map
     235                 :            : } // namespace ad

Generated by: LCOV version 1.14