LCOV - code coverage report
Current view: top level - src/unstructured - RssUnstructuredConstellationChecker.cpp (source / functions) Hit Total Coverage
Test: ad_rss Lines: 185 213 86.9 %
Date: 2025-07-22 06:53:46 Functions: 7 9 77.8 %
Branches: 147 271 54.2 %

           Branch data     Line data    Source code
       1                 :            : // ----------------- BEGIN LICENSE BLOCK ---------------------------------
       2                 :            : //
       3                 :            : // Copyright (C) 2020-2022 Intel Corporation
       4                 :            : //
       5                 :            : // SPDX-License-Identifier: LGPL-2.1-only
       6                 :            : //
       7                 :            : // ----------------- END LICENSE BLOCK -----------------------------------
       8                 :            : 
       9                 :            : #include "ad/rss/unstructured/RssUnstructuredConstellationChecker.hpp"
      10                 :            : #include <cmath>
      11                 :            : #include <limits>
      12                 :            : #include "ad/rss/core/Logging.hpp"
      13                 :            : #include "ad/rss/core/Physics.hpp"
      14                 :            : #include "ad/rss/unstructured/TrajectoryPedestrian.hpp"
      15                 :            : #include "ad/rss/unstructured/TrajectoryVehicle.hpp"
      16                 :            : 
      17                 :            : namespace ad {
      18                 :            : namespace rss {
      19                 :            : namespace unstructured {
      20                 :            : 
      21                 :            : const ad::physics::Speed c_drive_away_stopped_max_speed(0.1);
      22                 :            : 
      23                 :        787 : RssUnstructuredConstellationChecker::RssUnstructuredConstellationChecker()
      24                 :            : {
      25                 :            :   CalculateTrajectorySetsCallbackFunctionType trajectoryVehicleCallback
      26                 :         20 :     = [](::ad::rss::core::RelativeConstellation const &constellation,
      27                 :            :          ::ad::rss::world::ObjectId const &objectId,
      28                 :            :          core::RelativeObjectState const &vehicleState,
      29                 :            :          ::ad::geometry::Polygon &brakePolygon,
      30                 :            :          ::ad::geometry::Polygon &continueForwardPolygon) -> bool {
      31                 :            :     (void)constellation;
      32                 :            :     (void)objectId;
      33                 :         20 :     unstructured::TrajectoryVehicle trajectoryVehicle;
      34         [ +  - ]:         20 :     bool result = trajectoryVehicle.calculateTrajectorySets(vehicleState, brakePolygon, continueForwardPolygon);
      35                 :         20 :     return result;
      36                 :        787 :   };
      37                 :            :   CalculateTrajectorySetsCallbackFunctionType trajectoryPedestrianCallback
      38                 :          0 :     = [](::ad::rss::core::RelativeConstellation const &constellation,
      39                 :            :          ::ad::rss::world::ObjectId const &objectId,
      40                 :            :          core::RelativeObjectState const &vehicleState,
      41                 :            :          ::ad::geometry::Polygon &brakePolygon,
      42                 :            :          ::ad::geometry::Polygon &continueForwardPolygon) -> bool {
      43                 :            :     (void)constellation;
      44                 :            :     (void)objectId;
      45                 :          0 :     unstructured::TrajectoryPedestrian trajectoryPedestrian;
      46         [ #  # ]:          0 :     bool result = trajectoryPedestrian.calculateTrajectorySets(vehicleState, brakePolygon, continueForwardPolygon);
      47                 :          0 :     return result;
      48                 :        787 :   };
      49   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::EgoVehicle] = trajectoryVehicleCallback;
      50   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::Bicycle] = trajectoryVehicleCallback;
      51   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::OtherObject] = trajectoryVehicleCallback;
      52   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::OtherVehicle] = trajectoryVehicleCallback;
      53   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::ArtificialVehicle] = trajectoryVehicleCallback;
      54                 :            : 
      55   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::Pedestrian] = trajectoryPedestrianCallback;
      56   [ +  -  +  - ]:        787 :   mCalculateTrajectorySetsCallbackMap[world::ObjectType::ArtificialPedestrian] = trajectoryPedestrianCallback;
      57                 :        787 : }
      58                 :            : 
      59                 :          3 : RssUnstructuredConstellationChecker::RssUnstructuredConstellationChecker(
      60                 :          3 :   RssUnstructuredConstellationChecker const &other)
      61                 :          3 :   : mOtherMustBrakeStatesBeforeDangerThresholdTime(other.mOtherMustBrakeStatesBeforeDangerThresholdTime)
      62         [ +  - ]:          3 :   , mNewOtherMustBrakeStatesBeforeDangerThresholdTime(other.mNewOtherMustBrakeStatesBeforeDangerThresholdTime)
      63                 :          3 :   , mCurrentTimeIndex(other.mCurrentTimeIndex)
      64         [ +  - ]:          3 :   , mDriveAwayStateMap(other.mDriveAwayStateMap)
      65                 :            : {
      66         [ +  - ]:          3 :   core::shared_lock_guard const shared_lock(other.mCallbackRwLock);
      67         [ +  - ]:          3 :   mCalculateTrajectorySetsCallbackMap = other.mCalculateTrajectorySetsCallbackMap;
      68                 :          3 : }
      69                 :            : 
      70                 :            : RssUnstructuredConstellationChecker &
      71                 :          0 : RssUnstructuredConstellationChecker::operator=(RssUnstructuredConstellationChecker const &other)
      72                 :            : {
      73         [ #  # ]:          0 :   core::shared_lock_guard const shared_lock(other.mCallbackRwLock);
      74                 :            : 
      75         [ #  # ]:          0 :   mOtherMustBrakeStatesBeforeDangerThresholdTime = other.mOtherMustBrakeStatesBeforeDangerThresholdTime;
      76         [ #  # ]:          0 :   mNewOtherMustBrakeStatesBeforeDangerThresholdTime = other.mNewOtherMustBrakeStatesBeforeDangerThresholdTime;
      77                 :          0 :   mCurrentTimeIndex = other.mCurrentTimeIndex;
      78         [ #  # ]:          0 :   mDriveAwayStateMap = other.mDriveAwayStateMap;
      79         [ #  # ]:          0 :   mCalculateTrajectorySetsCallbackMap = other.mCalculateTrajectorySetsCallbackMap;
      80                 :          0 :   return *this;
      81                 :          0 : }
      82                 :            : 
      83                 :         24 : bool RssUnstructuredConstellationChecker::calculateUnstructuredConstellationStateInfo(
      84                 :            :   ::ad::rss::core::RelativeConstellation const &constellation,
      85                 :            :   ::ad::rss::world::ObjectId const &objectId,
      86                 :            :   core::RelativeObjectState const &vehicleState,
      87                 :            :   state::UnstructuredConstellationStateInformation &stateInfo) const
      88                 :            : {
      89                 :         24 :   bool result = true;
      90         [ +  - ]:         24 :   ::ad::geometry::Polygon brake;
      91         [ +  - ]:         24 :   ::ad::geometry::Polygon continueForward;
      92                 :            : 
      93         [ +  - ]:         24 :   core::shared_lock_guard const shared_lock(mCallbackRwLock);
      94         [ +  - ]:         24 :   auto callbackIter = mCalculateTrajectorySetsCallbackMap.find(vehicleState.object_type);
      95         [ +  - ]:         24 :   if (callbackIter != mCalculateTrajectorySetsCallbackMap.end())
      96                 :            :   {
      97         [ +  - ]:         24 :     result = callbackIter->second(constellation, objectId, vehicleState, brake, continueForward);
      98                 :            :   }
      99                 :            :   else
     100                 :            :   {
     101                 :          0 :     result = false;
     102   [ #  #  #  # ]:          0 :     core::getLogger()->error("RssUnstructuredConstellationChecker::calculateUnstructuredConstellationStateInfo>> "
     103                 :            :                              "object type {} not yet supported for unstructured calculation.",
     104         [ #  # ]:          0 :                              std::to_string(vehicleState.object_type));
     105                 :            :   }
     106                 :            : 
     107         [ +  - ]:         24 :   if (result)
     108                 :            :   {
     109         [ +  - ]:         24 :     ::ad::geometry::toTrajectorySet(brake, stateInfo.brake_trajectory_set);
     110         [ +  - ]:         24 :     ::ad::geometry::toTrajectorySet(continueForward, stateInfo.continue_forward_trajectory_set);
     111                 :            :     stateInfo.considered_drive_away_steering_angle
     112         [ +  - ]:         24 :       = normalizeAngleSigned(constellation.ego_state.unstructured_object_state.yaw
     113         [ +  - ]:         48 :                              + constellation.ego_state.unstructured_object_state.steering_angle);
     114                 :            :   }
     115                 :         24 :   return result;
     116                 :         24 : }
     117                 :            : 
     118                 :         12 : bool RssUnstructuredConstellationChecker::calculateRssStateUnstructured(
     119                 :            :   world::TimeIndex const &time_index,
     120                 :            :   core::RelativeConstellation const &constellation,
     121                 :            :   state::UnstructuredConstellationStateInformation &egoStateInfo,
     122                 :            :   state::RssState &rssState)
     123                 :            : {
     124                 :         12 :   bool result = true;
     125                 :            : 
     126         [ +  - ]:         12 :   if (time_index != mCurrentTimeIndex)
     127                 :            :   {
     128                 :         12 :     mOtherMustBrakeStatesBeforeDangerThresholdTime.swap(mNewOtherMustBrakeStatesBeforeDangerThresholdTime);
     129                 :         12 :     mNewOtherMustBrakeStatesBeforeDangerThresholdTime.clear();
     130                 :         12 :     mCurrentTimeIndex = time_index;
     131                 :            : 
     132                 :            :     // ego state only has to be calculated once per time step
     133                 :         12 :     result = calculateUnstructuredConstellationStateInfo(
     134                 :         12 :       constellation, constellation.ego_id, constellation.ego_state, egoStateInfo);
     135                 :            :   }
     136                 :            : 
     137         [ +  - ]:         12 :   if (result)
     138                 :            :   {
     139                 :            :     result
     140                 :         12 :       = calculateUnstructuredConstellationStateInfo(constellation,
     141                 :         12 :                                                     constellation.object_id,
     142                 :         12 :                                                     constellation.other_state,
     143                 :         12 :                                                     rssState.unstructured_constellation_state.rss_state_information);
     144                 :            :   }
     145                 :            : 
     146         [ +  - ]:         12 :   if (result)
     147                 :            :   {
     148                 :         12 :     result = calculateState(constellation,
     149                 :            :                             egoStateInfo,
     150                 :         12 :                             rssState.unstructured_constellation_state.rss_state_information,
     151                 :         12 :                             rssState.unstructured_constellation_state);
     152                 :            :   }
     153                 :            : 
     154         [ +  - ]:         12 :   if (result)
     155                 :            :   {
     156         [ +  + ]:         12 :     if (rssState.unstructured_constellation_state.response == state::UnstructuredConstellationResponse::DriveAway)
     157                 :            :     {
     158   [ +  -  +  - ]:          6 :       core::getLogger()->debug(
     159                 :            :         "Unstructured Constellation[{}->{}:{}] store drive-away state with allowed heading range {}.",
     160                 :          3 :         constellation.ego_id,
     161                 :          3 :         constellation.object_id,
     162                 :          3 :         constellation.constellation_id,
     163         [ +  - ]:          3 :         rssState.unstructured_constellation_state.heading_range);
     164         [ +  - ]:          3 :       DriveAwayState driveAwayState;
     165                 :          3 :       driveAwayState.allowedHeadingRange = rssState.unstructured_constellation_state.heading_range;
     166                 :          3 :       driveAwayState.otherPosition = constellation.other_state.unstructured_object_state.center_point;
     167         [ +  - ]:          3 :       mDriveAwayStateMap[constellation.constellation_id] = driveAwayState;
     168                 :            :     }
     169                 :            :     else
     170                 :            :     {
     171         [ +  - ]:          9 :       auto foundDriveAwayStateIt = mDriveAwayStateMap.find(constellation.constellation_id);
     172                 :            : 
     173         [ +  + ]:          9 :       if (foundDriveAwayStateIt != mDriveAwayStateMap.end())
     174                 :            :       {
     175                 :          3 :         bool keepDriveAwayState = true;
     176                 :            : 
     177         [ -  + ]:          3 :         if (rssState.unstructured_constellation_state.is_safe)
     178                 :            :         {
     179   [ #  #  #  # ]:          0 :           core::getLogger()->trace("Unstructured Constellation[{}->{}:{}] Remove previous drive-away state as "
     180                 :            :                                    "constellation became safe again.",
     181                 :          0 :                                    constellation.ego_id,
     182                 :          0 :                                    constellation.object_id,
     183         [ #  # ]:          0 :                                    constellation.constellation_id);
     184                 :          0 :           keepDriveAwayState = false;
     185                 :            :         }
     186                 :          3 :         else if (constellation.other_state.unstructured_object_state.center_point
     187   [ +  -  +  + ]:          3 :                  != foundDriveAwayStateIt->second.otherPosition)
     188                 :            :         {
     189   [ +  -  +  - ]:          2 :           core::getLogger()->trace(
     190                 :            :             "Unstructured Constellation[{}->{}:{}] Remove previous drive-away state as other object has moved.",
     191                 :          1 :             constellation.ego_id,
     192                 :          1 :             constellation.object_id,
     193         [ +  - ]:          1 :             constellation.constellation_id);
     194                 :          1 :           keepDriveAwayState = false;
     195                 :            :         }
     196         [ +  + ]:          2 :         else if (!::ad::geometry::isInsideHeadingRange(
     197                 :          2 :                    rssState.unstructured_constellation_state.rss_state_information.considered_drive_away_steering_angle,
     198         [ +  - ]:          2 :                    foundDriveAwayStateIt->second.allowedHeadingRange))
     199                 :            :         {
     200   [ +  -  +  - ]:          2 :           core::getLogger()->trace(
     201                 :            :             "Unstructured Constellation[{}->{}:{}] Remove previous drive-away state as steering "
     202                 :            :             "angle {} is not within range {}.",
     203                 :          1 :             constellation.ego_id,
     204                 :          1 :             constellation.object_id,
     205                 :          1 :             constellation.constellation_id,
     206                 :          1 :             rssState.unstructured_constellation_state.rss_state_information.considered_drive_away_steering_angle,
     207         [ +  - ]:          1 :             foundDriveAwayStateIt->second.allowedHeadingRange);
     208                 :          1 :           keepDriveAwayState = false;
     209                 :            :         }
     210                 :            : 
     211         [ +  + ]:          3 :         if (keepDriveAwayState)
     212                 :            :         {
     213   [ +  -  +  - ]:          2 :           core::getLogger()->debug(
     214                 :            :             "Unstructured Constellation[{}->{}:{}] ego vehicle driving away with previously allowed heading {}.",
     215                 :          1 :             constellation.ego_id,
     216                 :          1 :             constellation.object_id,
     217                 :          1 :             constellation.constellation_id,
     218         [ +  - ]:          1 :             foundDriveAwayStateIt->second.allowedHeadingRange);
     219                 :          1 :           rssState.unstructured_constellation_state.response = state::UnstructuredConstellationResponse::DriveAway;
     220                 :          1 :           rssState.unstructured_constellation_state.is_safe = false;
     221                 :          1 :           rssState.unstructured_constellation_state.heading_range = foundDriveAwayStateIt->second.allowedHeadingRange;
     222                 :            :         }
     223                 :            :         else
     224                 :            :         {
     225         [ +  - ]:          2 :           mDriveAwayStateMap.erase(foundDriveAwayStateIt);
     226                 :            :         }
     227                 :            :       }
     228                 :            :     }
     229                 :            :   }
     230                 :         12 :   return result;
     231                 :            : }
     232                 :            : 
     233                 :         17 : bool RssUnstructuredConstellationChecker::calculateState(
     234                 :            :   core::RelativeConstellation const &constellation,
     235                 :            :   state::UnstructuredConstellationStateInformation const &egoStateInfo,
     236                 :            :   state::UnstructuredConstellationStateInformation const &otherStateInfo,
     237                 :            :   state::UnstructuredConstellationRssState &rssState)
     238                 :            : {
     239                 :         17 :   bool result = true;
     240                 :         17 :   auto const &egoBrake = egoStateInfo.brake_trajectory_set;
     241                 :         17 :   auto const &egoContinueForward = egoStateInfo.continue_forward_trajectory_set;
     242                 :         17 :   auto const &otherBrake = otherStateInfo.brake_trajectory_set;
     243                 :         17 :   auto const &otherContinueForward = otherStateInfo.continue_forward_trajectory_set;
     244                 :            : 
     245   [ +  +  +  -  :         17 :   if (egoBrake.empty() || egoContinueForward.empty() || otherBrake.empty() || otherContinueForward.empty())
          +  -  -  +  +  
                      + ]
     246                 :            :   {
     247   [ +  -  +  - ]:          2 :     core::getLogger()->warn("Unstructured Constellation[{}->{}:{}] refers to empty trajectory sets",
     248                 :          1 :                             constellation.ego_id,
     249                 :          1 :                             constellation.object_id,
     250         [ +  - ]:          1 :                             constellation.constellation_id);
     251                 :          1 :     return false;
     252                 :            :   }
     253                 :            : 
     254                 :            :   // check if distance is safe
     255         [ +  - ]:         16 :   bool egoBrakeOtherContinueForwardOverlap = ::ad::geometry::collides(egoBrake, otherContinueForward);
     256         [ +  - ]:         16 :   bool otherBrakeEgoContinueForwardOverlap = ::ad::geometry::collides(otherBrake, egoContinueForward);
     257         [ +  - ]:         16 :   bool egoBrakeOtherBrakeOverlap = ::ad::geometry::collides(egoBrake, otherBrake);
     258                 :            : 
     259   [ +  +  +  + ]:         16 :   bool isSafeEgoMustBrake = !egoBrakeOtherContinueForwardOverlap && otherBrakeEgoContinueForwardOverlap;
     260   [ +  +  +  + ]:         16 :   bool isSafeOtherMustBrake = !otherBrakeEgoContinueForwardOverlap && egoBrakeOtherContinueForwardOverlap;
     261                 :         16 :   bool isSafeBrakeBoth = !egoBrakeOtherBrakeOverlap;
     262                 :            : 
     263   [ +  +  +  +  :         16 :   auto is_safe = isSafeEgoMustBrake || isSafeOtherMustBrake || isSafeBrakeBoth;
                   +  + ]
     264                 :            : 
     265   [ +  -  +  - ]:         32 :   core::getLogger()->trace("Unstructured Constellation[{}->{}:{}] safe check: isSafeEgoMustBrake: {}, "
     266                 :            :                            "isSafeOtherMustBrake: {}, isSafeBrakeBoth: {}",
     267                 :         16 :                            constellation.ego_id,
     268                 :         16 :                            constellation.object_id,
     269         [ +  - ]:         16 :                            constellation.constellation_id,
     270                 :            :                            isSafeEgoMustBrake,
     271                 :            :                            isSafeOtherMustBrake,
     272                 :            :                            isSafeBrakeBoth);
     273                 :         16 :   DrivingMode mode{DrivingMode::Invalid};
     274                 :            : 
     275         [ +  + ]:         16 :   if (is_safe)
     276                 :            :   {
     277   [ +  -  +  - ]:         10 :     core::getLogger()->debug("Unstructured Constellation[{}->{}:{}] safe. Store value otherMustBrake: {}",
     278                 :          5 :                              constellation.ego_id,
     279                 :          5 :                              constellation.object_id,
     280                 :          5 :                              constellation.constellation_id,
     281   [ +  +  +  - ]:         10 :                              isSafeOtherMustBrake ? "true" : "false");
     282         [ +  - ]:          5 :     mNewOtherMustBrakeStatesBeforeDangerThresholdTime[constellation.constellation_id] = isSafeOtherMustBrake;
     283                 :          5 :     mode = DrivingMode::ContinueForward;
     284                 :            :   }
     285                 :            :   else
     286                 :            :   {
     287                 :            :     // not safe
     288                 :         11 :     bool lastOtherMustBrake = false;
     289         [ +  - ]:         11 :     auto foundStateIt = mOtherMustBrakeStatesBeforeDangerThresholdTime.find(constellation.constellation_id);
     290         [ +  + ]:         11 :     if (foundStateIt != mOtherMustBrakeStatesBeforeDangerThresholdTime.end())
     291                 :            :     {
     292                 :          7 :       lastOtherMustBrake = foundStateIt->second;
     293         [ +  - ]:          7 :       mNewOtherMustBrakeStatesBeforeDangerThresholdTime[constellation.constellation_id] = lastOtherMustBrake;
     294                 :            :     }
     295                 :            : 
     296                 :            :     // Rule 1: If both cars were already at a full stop, then one can drive away from other vehicle
     297         [ +  - ]:         11 :     if (((constellation.ego_state.unstructured_object_state.speed_range.maximum <= c_drive_away_stopped_max_speed)
     298   [ +  +  +  + ]:         15 :          && (constellation.other_state.unstructured_object_state.speed_range.maximum
     299   [ +  -  +  + ]:          4 :              <= c_drive_away_stopped_max_speed)))
     300                 :            :     {
     301   [ +  -  +  - ]:          6 :       core::getLogger()->debug(
     302                 :            :         "Unstructured Constellation[{}->{}:{}] Rule 1: both stopped, unsafe distance -> drive away.",
     303                 :          3 :         constellation.ego_id,
     304                 :          3 :         constellation.object_id,
     305         [ +  - ]:          3 :         constellation.constellation_id);
     306                 :          3 :       mode = DrivingMode::DriveAway;
     307                 :            :     }
     308                 :            : 
     309                 :            :     // Rule 2: If:
     310                 :            :     // - ego-brake and other-continue-forward not overlap
     311                 :            :     // and
     312                 :            :     // - other-brake and ego-continue-forward overlap
     313   [ +  +  +  + ]:         11 :     if ((mode == DrivingMode::Invalid) && lastOtherMustBrake)
     314                 :            :     {
     315   [ +  -  +  + ]:          2 :       if (constellation.ego_state.unstructured_object_state.speed_range.maximum > c_drive_away_stopped_max_speed)
     316                 :            :       {
     317   [ +  -  +  - ]:          2 :         core::getLogger()->debug("Unstructured Constellation[{}->{}:{}] Rule 2: opponent is moving -> continue forward",
     318                 :          1 :                                  constellation.ego_id,
     319                 :          1 :                                  constellation.object_id,
     320         [ +  - ]:          1 :                                  constellation.constellation_id);
     321                 :          1 :         mode = DrivingMode::ContinueForward;
     322                 :            :       }
     323                 :            :       else
     324                 :            :       {
     325   [ +  -  +  - ]:          2 :         core::getLogger()->debug("Unstructured Constellation[{}->{}:{}] Rule 2: opponent is stopped -> drive away",
     326                 :          1 :                                  constellation.ego_id,
     327                 :          1 :                                  constellation.object_id,
     328         [ +  - ]:          1 :                                  constellation.constellation_id);
     329                 :          1 :         mode = DrivingMode::DriveAway;
     330                 :            :       }
     331                 :            :     }
     332                 :            : 
     333                 :            :     // Rule 3: Brake
     334         [ +  + ]:         11 :     if (mode == DrivingMode::Invalid)
     335                 :            :     {
     336   [ +  -  +  - ]:         12 :       core::getLogger()->debug("Unstructured Constellation[{}->{}:{}] Rule 3: brake (brake collides with other brake)",
     337                 :          6 :                                constellation.ego_id,
     338                 :          6 :                                constellation.object_id,
     339         [ +  - ]:          6 :                                constellation.constellation_id);
     340                 :          6 :       mode = DrivingMode::Brake;
     341                 :            :     }
     342                 :            :   }
     343                 :            : 
     344   [ +  +  +  -  :         16 :   switch (mode)
                      - ]
     345                 :            :   {
     346                 :          6 :     case DrivingMode::ContinueForward:
     347                 :          6 :       rssState.response = state::UnstructuredConstellationResponse::ContinueForward;
     348                 :          6 :       rssState.is_safe = true;
     349                 :          6 :       break;
     350                 :          6 :     case DrivingMode::Brake:
     351                 :          6 :       rssState.response = state::UnstructuredConstellationResponse::Brake;
     352                 :          6 :       rssState.is_safe = false;
     353                 :          6 :       break;
     354                 :          4 :     case DrivingMode::DriveAway:
     355                 :            :     {
     356   [ +  -  +  - ]:          4 :       calculateDriveAwayAngle(::ad::geometry::toPoint(constellation.ego_state.unstructured_object_state.center_point),
     357                 :          0 :                               ::ad::geometry::toPoint(constellation.other_state.unstructured_object_state.center_point),
     358                 :          4 :                               constellation.ego_state.dynamics.unstructured_settings.drive_away_max_angle,
     359         [ +  - ]:          4 :                               rssState.heading_range);
     360                 :          4 :       rssState.response = state::UnstructuredConstellationResponse::DriveAway;
     361                 :          4 :       rssState.is_safe = false;
     362                 :          4 :       break;
     363                 :            :     }
     364                 :          0 :     case DrivingMode::Invalid:
     365                 :          0 :       result = false;
     366                 :          0 :       break;
     367                 :          0 :     default:
     368                 :          0 :       result = false;
     369         [ #  # ]:          0 :       throw std::runtime_error("RssUnstructuredConstellationChecker::calculateState>> invalid driving mode");
     370                 :            :       break;
     371                 :            :   }
     372                 :            : 
     373                 :         16 :   return result;
     374                 :            : }
     375                 :            : 
     376                 :         12 : bool RssUnstructuredConstellationChecker::calculateDriveAwayAngle(::ad::geometry::Point const &egoVehicleLocation,
     377                 :            :                                                                   ::ad::geometry::Point const &otherVehicleLocation,
     378                 :            :                                                                   physics::Angle const &maxAllowedAngleWhenBothStopped,
     379                 :            :                                                                   ::ad::geometry::HeadingRange &range) const
     380                 :            : {
     381         [ +  - ]:         12 :   auto const substractedLocationVector = egoVehicleLocation - otherVehicleLocation;
     382                 :            : 
     383                 :            :   // get vector angle
     384                 :            :   auto const substractedLocationVectorAngle = physics::Angle(
     385   [ +  -  +  - ]:         12 :     std::atan2(static_cast<double>(substractedLocationVector.y()), static_cast<double>(substractedLocationVector.x())));
     386                 :            : 
     387   [ +  -  +  - ]:         12 :   range.begin = physics::normalizeAngleSigned(substractedLocationVectorAngle - maxAllowedAngleWhenBothStopped);
     388   [ +  -  +  - ]:         12 :   range.end = physics::normalizeAngleSigned(substractedLocationVectorAngle + maxAllowedAngleWhenBothStopped);
     389                 :         12 :   return true;
     390                 :            : }
     391                 :            : 
     392                 :            : } // namespace unstructured
     393                 :            : } // namespace rss
     394                 :            : } // namespace ad

Generated by: LCOV version 1.14