LCOV - code coverage report
Current view: top level - src/core - RssSituationExtraction.cpp (source / functions) Hit Total Coverage
Test: ad_rss Lines: 278 295 94.2 %
Date: 2025-07-15 04:35:03 Functions: 11 12 91.7 %
Branches: 230 314 73.2 %

           Branch data     Line data    Source code
       1                 :            : // ----------------- BEGIN LICENSE BLOCK ---------------------------------
       2                 :            : //
       3                 :            : // Copyright (C) 2018-2021 Intel Corporation
       4                 :            : //
       5                 :            : // SPDX-License-Identifier: LGPL-2.1-only
       6                 :            : //
       7                 :            : // ----------------- END LICENSE BLOCK -----------------------------------
       8                 :            : 
       9                 :            : #include "ad/rss/core/RssSituationExtraction.hpp"
      10                 :            : #include <algorithm>
      11                 :            : #include "ad/rss/core/Logging.hpp"
      12                 :            : #include "ad/rss/structured/RssConstellationIdProvider.hpp"
      13                 :            : #include "ad/rss/structured/RssLaneCoordinateSystemConversion.hpp"
      14                 :            : #include "ad/rss/world/WorldModelValidInputRange.hpp"
      15                 :            : 
      16                 :            : namespace ad {
      17                 :            : namespace rss {
      18                 :            : namespace core {
      19                 :            : 
      20                 :            : using physics::Distance;
      21                 :            : using physics::MetricRange;
      22                 :            : 
      23                 :          0 : void RssSituationExtraction::dropObjectHistory(world::ObjectId const &object_id)
      24                 :            : {
      25                 :          0 :   mConstellationIdProvider.dropConstellationIds(object_id);
      26                 :          0 : }
      27                 :            : 
      28                 :       3981 : void RssSituationExtraction::calcluateRelativeLongitudinalPosition(MetricRange const &egoMetricRange,
      29                 :            :                                                                    MetricRange const &otherMetricRange,
      30                 :            :                                                                    LongitudinalRelativePosition &longitudinal_position,
      31                 :            :                                                                    Distance &longitudinal_distance)
      32                 :            : {
      33         [ +  + ]:       3981 :   if (egoMetricRange.minimum > otherMetricRange.maximum)
      34                 :            :   {
      35                 :        723 :     longitudinal_position = LongitudinalRelativePosition::InFront;
      36                 :        723 :     longitudinal_distance = egoMetricRange.minimum - otherMetricRange.maximum;
      37                 :            :   }
      38         [ +  + ]:       3257 :   else if (otherMetricRange.minimum > egoMetricRange.maximum)
      39                 :            :   {
      40                 :       2112 :     longitudinal_position = LongitudinalRelativePosition::AtBack;
      41                 :       2112 :     longitudinal_distance = otherMetricRange.minimum - egoMetricRange.maximum;
      42                 :            :   }
      43                 :            :   else
      44                 :            :   {
      45                 :       1146 :     longitudinal_distance = Distance(0.);
      46   [ +  +  +  +  :       1146 :     if ((egoMetricRange.minimum > otherMetricRange.minimum) && (egoMetricRange.maximum > otherMetricRange.maximum))
                   +  + ]
      47                 :            :     {
      48                 :        105 :       longitudinal_position = LongitudinalRelativePosition::OverlapFront;
      49                 :            :     }
      50   [ +  +  +  +  :       1041 :     else if ((egoMetricRange.minimum < otherMetricRange.minimum) && (egoMetricRange.maximum < otherMetricRange.maximum))
                   +  + ]
      51                 :            :     {
      52                 :         19 :       longitudinal_position = LongitudinalRelativePosition::OverlapBack;
      53                 :            :     }
      54                 :            :     else
      55                 :            :     {
      56                 :       1022 :       longitudinal_position = LongitudinalRelativePosition::Overlap;
      57                 :            :     }
      58                 :            :   }
      59                 :       3981 : }
      60                 :            : 
      61                 :        802 : void RssSituationExtraction::calcluateRelativeLongitudinalPositionIntersection(
      62                 :            :   MetricRange const &egoMetricRange,
      63                 :            :   MetricRange const &otherMetricRange,
      64                 :            :   LongitudinalRelativePosition &longitudinal_position,
      65                 :            :   Distance &longitudinal_distance)
      66                 :            : {
      67         [ +  + ]:        802 :   if (egoMetricRange.maximum < otherMetricRange.minimum)
      68                 :            :   {
      69                 :        109 :     longitudinal_position = LongitudinalRelativePosition::InFront;
      70                 :        109 :     longitudinal_distance = otherMetricRange.minimum - egoMetricRange.maximum;
      71                 :            :   }
      72         [ +  + ]:        693 :   else if (otherMetricRange.maximum < egoMetricRange.minimum)
      73                 :            :   {
      74                 :        545 :     longitudinal_position = LongitudinalRelativePosition::AtBack;
      75                 :        545 :     longitudinal_distance = egoMetricRange.minimum - otherMetricRange.maximum;
      76                 :            :   }
      77                 :            :   else
      78                 :            :   {
      79                 :        148 :     longitudinal_distance = Distance(0.);
      80   [ +  +  +  +  :        148 :     if ((egoMetricRange.minimum < otherMetricRange.minimum) && (egoMetricRange.maximum < otherMetricRange.maximum))
                   +  + ]
      81                 :            :     {
      82                 :         52 :       longitudinal_position = LongitudinalRelativePosition::OverlapFront;
      83                 :            :     }
      84   [ +  +  +  -  :         96 :     else if ((egoMetricRange.minimum > otherMetricRange.minimum) && (egoMetricRange.maximum > otherMetricRange.maximum))
                   +  + ]
      85                 :            :     {
      86                 :         48 :       longitudinal_position = LongitudinalRelativePosition::OverlapBack;
      87                 :            :     }
      88                 :            :     else
      89                 :            :     {
      90                 :         48 :       longitudinal_position = LongitudinalRelativePosition::Overlap;
      91                 :            :     }
      92                 :            :   }
      93                 :        802 : }
      94                 :            : 
      95                 :       3834 : void RssSituationExtraction::calcluateRelativeLateralPosition(MetricRange const &egoMetricRange,
      96                 :            :                                                               MetricRange const &otherMetricRange,
      97                 :            :                                                               LateralRelativePosition &lateral_position,
      98                 :            :                                                               Distance &lateral_distance)
      99                 :            : {
     100         [ +  + ]:       3834 :   if (egoMetricRange.minimum > otherMetricRange.maximum)
     101                 :            :   {
     102                 :       1145 :     lateral_position = LateralRelativePosition::AtRight;
     103                 :       1145 :     lateral_distance = egoMetricRange.minimum - otherMetricRange.maximum;
     104                 :            :   }
     105         [ +  + ]:       2689 :   else if (otherMetricRange.minimum > egoMetricRange.maximum)
     106                 :            :   {
     107                 :        923 :     lateral_position = LateralRelativePosition::AtLeft;
     108                 :        923 :     lateral_distance = otherMetricRange.minimum - egoMetricRange.maximum;
     109                 :            :   }
     110                 :            :   else
     111                 :            :   {
     112                 :       1766 :     lateral_distance = Distance(0.);
     113   [ +  +  +  +  :       1766 :     if ((egoMetricRange.minimum > otherMetricRange.minimum) && (egoMetricRange.maximum > otherMetricRange.maximum))
                   +  + ]
     114                 :            :     {
     115                 :        117 :       lateral_position = LateralRelativePosition::OverlapRight;
     116                 :            :     }
     117   [ +  +  +  +  :       1649 :     else if ((egoMetricRange.minimum < otherMetricRange.minimum) && (egoMetricRange.maximum < otherMetricRange.maximum))
                   +  + ]
     118                 :            :     {
     119                 :        133 :       lateral_position = LateralRelativePosition::OverlapLeft;
     120                 :            :     }
     121                 :            :     else
     122                 :            :     {
     123                 :       1516 :       lateral_position = LateralRelativePosition::Overlap;
     124                 :            :     }
     125                 :            :   }
     126                 :       3834 : }
     127                 :            : 
     128                 :       3961 : bool RssSituationExtraction::convertObjectsNonIntersection(world::Constellation const &currentConstellation,
     129                 :            :                                                            core::RelativeConstellation &constellation)
     130                 :            : {
     131         [ +  + ]:       3961 :   if (!currentConstellation.intersecting_road.empty())
     132                 :            :   {
     133   [ +  -  +  - ]:          2 :     core::getLogger()->error(
     134                 :            :       "RssSituationExtraction::convertObjectsNonIntersection[{}->{}]>> Intersecting road not empty {}",
     135                 :          1 :       currentConstellation.ego_vehicle.object_id,
     136         [ +  - ]:          1 :       currentConstellation.object.object_id,
     137                 :            :       currentConstellation);
     138                 :          1 :     return false;
     139                 :            :   }
     140                 :            : 
     141                 :       3959 :   bool result = true;
     142                 :            : 
     143         [ +  - ]:       3959 :   structured::ObjectDimensions egoVehicleDimension;
     144         [ +  - ]:       3961 :   structured::ObjectDimensions objectToBeCheckedDimension;
     145         [ +  - ]:       3960 :   result = structured::calculateObjectDimensions(currentConstellation, egoVehicleDimension, objectToBeCheckedDimension);
     146                 :            : 
     147                 :            :   LongitudinalRelativePosition longitudinal_position;
     148                 :       3961 :   Distance longitudinal_distance;
     149         [ +  - ]:       3960 :   calcluateRelativeLongitudinalPosition(egoVehicleDimension.longitudinalDimensions,
     150                 :            :                                         objectToBeCheckedDimension.longitudinalDimensions,
     151                 :            :                                         longitudinal_position,
     152                 :            :                                         longitudinal_distance);
     153                 :            : 
     154                 :       3959 :   constellation.relative_position.longitudinal_position = longitudinal_position;
     155                 :       3959 :   constellation.relative_position.longitudinal_distance = longitudinal_distance;
     156                 :            : 
     157                 :       3959 :   constellation.ego_state.structured_object_state.is_in_correct_lane = !egoVehicleDimension.onNegativeLane;
     158                 :            : 
     159         [ +  + ]:       3959 :   if (currentConstellation.constellation_type == ::ad::rss::world::ConstellationType::OppositeDirection)
     160                 :            :   {
     161                 :       1101 :     constellation.other_state.structured_object_state.is_in_correct_lane = !objectToBeCheckedDimension.onPositiveLane;
     162                 :            :   }
     163                 :            :   else
     164                 :            :   {
     165                 :       2858 :     constellation.other_state.structured_object_state.is_in_correct_lane = !objectToBeCheckedDimension.onNegativeLane;
     166                 :            :   }
     167                 :            : 
     168                 :            :   /**
     169                 :            :    * Set lateral restrictions
     170                 :            :    */
     171         [ +  + ]:       3959 :   if (result)
     172                 :            :   {
     173                 :            :     LateralRelativePosition lateral_position;
     174                 :       3812 :     Distance lateral_distance;
     175         [ +  - ]:       3812 :     calcluateRelativeLateralPosition(egoVehicleDimension.lateralDimensions,
     176                 :            :                                      objectToBeCheckedDimension.lateralDimensions,
     177                 :            :                                      lateral_position,
     178                 :            :                                      lateral_distance);
     179                 :            : 
     180                 :       3814 :     constellation.relative_position.lateral_position = lateral_position;
     181                 :       3814 :     constellation.relative_position.lateral_distance = lateral_distance;
     182                 :            :   }
     183                 :       3961 :   return result;
     184                 :            : }
     185                 :            : 
     186                 :       1604 : void RssSituationExtraction::convertToIntersectionCentric(MetricRange const &objectDimension,
     187                 :            :                                                           MetricRange const &intersectionPosition,
     188                 :            :                                                           MetricRange &dimensionsIntersection)
     189                 :            : {
     190                 :       1604 :   dimensionsIntersection.maximum = intersectionPosition.minimum - objectDimension.minimum;
     191                 :       1604 :   dimensionsIntersection.minimum = intersectionPosition.minimum - objectDimension.maximum;
     192                 :       1604 : }
     193                 :            : 
     194                 :        845 : bool RssSituationExtraction::convertObjectsIntersection(world::Constellation const &currentConstellation,
     195                 :            :                                                         core::RelativeConstellation &constellation)
     196                 :            : {
     197         [ +  - ]:        845 :   structured::ObjectDimensions egoVehicleDimension;
     198         [ +  - ]:        845 :   structured::ObjectDimensions objectDimension;
     199                 :            : 
     200                 :       1690 :   bool result = structured::calculateObjectDimensions(
     201         [ +  - ]:        845 :     currentConstellation.ego_vehicle, currentConstellation.ego_vehicle_road, egoVehicleDimension);
     202                 :            : 
     203                 :        845 :   result = result
     204   [ +  +  +  + ]:       1669 :     && structured::calculateObjectDimensions(
     205         [ +  - ]:        824 :              currentConstellation.object, currentConstellation.intersecting_road, objectDimension);
     206                 :            : 
     207         [ +  + ]:        845 :   if (result)
     208                 :            :   {
     209                 :        802 :     constellation.ego_state.structured_object_state.is_in_correct_lane = !egoVehicleDimension.onNegativeLane;
     210                 :        802 :     constellation.other_state.structured_object_state.is_in_correct_lane = !objectDimension.onNegativeLane;
     211                 :            : 
     212                 :            :     // For intersection the lanes don't have the same origin so the positions cannot be directly compared
     213                 :            :     // Intersection entry should be the common point so convert the positions to this reference point
     214         [ +  - ]:        802 :     MetricRange egoDimensionsIntersection;
     215         [ +  - ]:        802 :     convertToIntersectionCentric(
     216                 :            :       egoVehicleDimension.longitudinalDimensions, egoVehicleDimension.intersectionPosition, egoDimensionsIntersection);
     217                 :            : 
     218         [ +  - ]:        802 :     MetricRange objectDimensionsIntersection;
     219                 :            : 
     220         [ +  - ]:        802 :     convertToIntersectionCentric(
     221                 :            :       objectDimension.longitudinalDimensions, objectDimension.intersectionPosition, objectDimensionsIntersection);
     222                 :            : 
     223                 :            :     constellation.ego_state.structured_object_state.distance_to_enter_intersection
     224         [ +  - ]:        802 :       = std::max(Distance(0.), egoDimensionsIntersection.minimum);
     225                 :            :     constellation.ego_state.structured_object_state.distance_to_leave_intersection
     226         [ +  - ]:        802 :       = std::max(Distance(0.),
     227         [ +  - ]:        802 :                  egoVehicleDimension.intersectionPosition.maximum - egoVehicleDimension.longitudinalDimensions.minimum);
     228                 :            : 
     229                 :            :     constellation.other_state.structured_object_state.distance_to_enter_intersection
     230         [ +  - ]:        802 :       = std::max(Distance(0.), objectDimensionsIntersection.minimum);
     231         [ +  - ]:        802 :     constellation.other_state.structured_object_state.distance_to_leave_intersection = std::max(
     232         [ +  - ]:        802 :       Distance(0.), objectDimension.intersectionPosition.maximum - objectDimension.longitudinalDimensions.minimum);
     233                 :            : 
     234                 :            :     LongitudinalRelativePosition longitudinal_position;
     235                 :        802 :     Distance longitudinal_distance;
     236         [ +  - ]:        802 :     calcluateRelativeLongitudinalPositionIntersection(
     237                 :            :       egoDimensionsIntersection, objectDimensionsIntersection, longitudinal_position, longitudinal_distance);
     238                 :            : 
     239                 :        802 :     constellation.relative_position.longitudinal_position = longitudinal_position;
     240                 :        802 :     constellation.relative_position.longitudinal_distance = longitudinal_distance;
     241                 :            : 
     242                 :        802 :     constellation.relative_position.lateral_position = LateralRelativePosition::Overlap;
     243                 :        802 :     constellation.relative_position.lateral_distance = Distance(0.);
     244                 :            :   }
     245                 :            : 
     246         [ +  + ]:        845 :   if (currentConstellation.constellation_type == world::ConstellationType::IntersectionEgoHasPriority)
     247                 :            :   {
     248                 :        409 :     constellation.ego_state.structured_object_state.has_priority = true;
     249                 :        409 :     constellation.other_state.structured_object_state.has_priority = false;
     250                 :            :   }
     251         [ +  + ]:        436 :   else if (currentConstellation.constellation_type == world::ConstellationType::IntersectionObjectHasPriority)
     252                 :            :   {
     253                 :        218 :     constellation.ego_state.structured_object_state.has_priority = false;
     254                 :        218 :     constellation.other_state.structured_object_state.has_priority = true;
     255                 :            :   }
     256         [ +  - ]:        218 :   else if (currentConstellation.constellation_type == world::ConstellationType::IntersectionSamePriority)
     257                 :            :   {
     258                 :        218 :     constellation.ego_state.structured_object_state.has_priority = false;
     259                 :        218 :     constellation.other_state.structured_object_state.has_priority = false;
     260                 :            :   }
     261                 :            :   else
     262                 :            :   {
     263                 :            :     // This function should never be called if we are not in intersection constellation
     264   [ #  #  #  # ]:          0 :     core::getLogger()->error(
     265                 :            :       "RssSituationExtraction::convertObjectsIntersection[{}->{}]>> Unexpected constellation_type {}",
     266                 :          0 :       currentConstellation.ego_vehicle.object_id,
     267         [ #  # ]:          0 :       currentConstellation.object.object_id,
     268                 :            :       currentConstellation);
     269                 :            :     result = false; // LCOV_EXCL_LINE: unreachable code, keep to be on the safe side
     270                 :            :   }
     271                 :            : 
     272                 :        845 :   return result;
     273                 :            : }
     274                 :            : 
     275                 :       5001 : bool RssSituationExtraction::extractConstellationInputRangeChecked(world::TimeIndex const &time_index,
     276                 :            :                                                                    world::Constellation const &worldConstellation,
     277                 :            :                                                                    core::RelativeConstellation &relativeConstellation)
     278                 :            : {
     279                 :            :   // ensure the object types are semantically correct
     280                 :            :   // @toDo: add this restriction to the data type model
     281                 :            :   //       and extend generated withinValidInputRange by these
     282         [ +  + ]:       5001 :   if (((worldConstellation.object.object_type != world::ObjectType::OtherVehicle)
     283         [ +  + ]:         14 :        && (worldConstellation.object.object_type != world::ObjectType::ArtificialObject)
     284         [ +  + ]:         12 :        && (worldConstellation.object.object_type != world::ObjectType::ArtificialPedestrian)
     285         [ +  + ]:          9 :        && (worldConstellation.object.object_type != world::ObjectType::ArtificialVehicle)
     286         [ +  + ]:          6 :        && (worldConstellation.object.object_type != world::ObjectType::Pedestrian)
     287         [ +  + ]:          5 :        && (worldConstellation.object.object_type != world::ObjectType::Bicycle)
     288         [ +  + ]:          4 :        && (worldConstellation.object.object_type != world::ObjectType::OtherObject))
     289         [ +  + ]:       4998 :       || (worldConstellation.ego_vehicle.object_type != world::ObjectType::EgoVehicle))
     290                 :            :   {
     291         [ +  - ]:         24 :     core::getLogger()->error(
     292                 :            :       "RssSituationExtraction::extractConstellationInputRangeChecked[{}->{}]>> Invalid object type. Ego: "
     293                 :            :       "{} Object: {}",
     294                 :         12 :       worldConstellation.ego_vehicle.object_id,
     295                 :         12 :       worldConstellation.object.object_id,
     296                 :         12 :       worldConstellation.ego_vehicle,
     297         [ +  - ]:         12 :       worldConstellation.object);
     298                 :         12 :     return false;
     299                 :            :   }
     300         [ +  + ]:       4989 :   if (worldConstellation.object.object_id == worldConstellation.ego_vehicle.object_id)
     301                 :            :   {
     302         [ +  - ]:          2 :     core::getLogger()->error(
     303                 :            :       "RssSituationExtraction::extractConstellationInputRangeChecked[{}->{}]>> Object and ego vehicle must not have "
     304                 :            :       "the same id. Ego: {} Object: {}",
     305                 :          1 :       worldConstellation.ego_vehicle.object_id,
     306                 :          1 :       worldConstellation.object.object_id,
     307                 :          1 :       worldConstellation.ego_vehicle,
     308         [ +  - ]:          1 :       worldConstellation.object);
     309                 :          1 :     return false;
     310                 :            :   }
     311                 :       4988 :   bool result = false;
     312                 :            : 
     313                 :            :   try
     314                 :            :   {
     315                 :            :     relativeConstellation.constellation_id
     316         [ +  + ]:       4988 :       = mConstellationIdProvider.getConstellationId(time_index, worldConstellation);
     317                 :       4968 :     relativeConstellation.ego_id = worldConstellation.ego_vehicle.object_id;
     318                 :       4968 :     relativeConstellation.object_id = worldConstellation.object.object_id;
     319                 :       4968 :     relativeConstellation.constellation_type = worldConstellation.constellation_type;
     320                 :            : 
     321                 :       4968 :     relativeConstellation.ego_state.object_type = worldConstellation.ego_vehicle.object_type;
     322                 :       4968 :     relativeConstellation.other_state.object_type = worldConstellation.object.object_type;
     323                 :            : 
     324                 :       4968 :     relativeConstellation.ego_state.unstructured_object_state = worldConstellation.ego_vehicle.state;
     325                 :       4968 :     relativeConstellation.other_state.unstructured_object_state = worldConstellation.object.state;
     326                 :            : 
     327                 :       4968 :     relativeConstellation.ego_state.structured_object_state.has_priority = false;
     328                 :       4968 :     relativeConstellation.other_state.structured_object_state.has_priority = false;
     329                 :            : 
     330                 :       4968 :     relativeConstellation.ego_state.structured_object_state.is_in_correct_lane = true;
     331                 :       4968 :     relativeConstellation.other_state.structured_object_state.is_in_correct_lane = true;
     332                 :            : 
     333                 :       4968 :     relativeConstellation.ego_state.structured_object_state.distance_to_enter_intersection = Distance(0.);
     334                 :       4968 :     relativeConstellation.ego_state.structured_object_state.distance_to_leave_intersection = Distance(1000.);
     335                 :            : 
     336                 :       4966 :     relativeConstellation.other_state.structured_object_state.distance_to_enter_intersection = Distance(0.);
     337                 :       4966 :     relativeConstellation.other_state.structured_object_state.distance_to_leave_intersection = Distance(1000.);
     338                 :            : 
     339                 :       4968 :     structured::convertVehicleStateDynamics(
     340         [ +  - ]:       4968 :       worldConstellation.ego_vehicle, worldConstellation.ego_vehicle_rss_dynamics, relativeConstellation.ego_state);
     341                 :       4964 :     structured::convertVehicleStateDynamics(
     342         [ +  - ]:       4964 :       worldConstellation.object, worldConstellation.object_rss_dynamics, relativeConstellation.other_state);
     343                 :            : 
     344   [ +  +  +  - ]:       4967 :     switch (worldConstellation.constellation_type)
     345                 :            :     {
     346                 :       3962 :       case ad::rss::world::ConstellationType::SameDirection:
     347                 :            :       case ad::rss::world::ConstellationType::OppositeDirection:
     348                 :            :       {
     349         [ +  - ]:       3962 :         result = convertObjectsNonIntersection(worldConstellation, relativeConstellation);
     350                 :            : 
     351                 :       3962 :         break;
     352                 :            :       }
     353                 :        845 :       case ad::rss::world::ConstellationType::IntersectionEgoHasPriority:
     354                 :            :       case ad::rss::world::ConstellationType::IntersectionObjectHasPriority:
     355                 :            :       case ad::rss::world::ConstellationType::IntersectionSamePriority:
     356                 :            :       {
     357         [ +  - ]:        845 :         result = convertObjectsIntersection(worldConstellation, relativeConstellation);
     358                 :        845 :         break;
     359                 :            :       }
     360                 :        160 :       case ad::rss::world::ConstellationType::NotRelevant:
     361                 :            :       case ad::rss::world::ConstellationType::Unstructured:
     362                 :            :       {
     363                 :        160 :         result = true;
     364                 :        160 :         break;
     365                 :            :       }
     366                 :          0 :       default:
     367                 :            :       {
     368   [ +  -  +  - ]:          1 :         core::getLogger()->error(
     369                 :            :           "RssSituationExtraction::extractConstellationInputRangeChecked[{}->{}]>> Invalid constellation type {}",
     370                 :          1 :           worldConstellation.ego_vehicle.object_id,
     371         [ +  - ]:          1 :           worldConstellation.object.object_id,
     372                 :            :           worldConstellation);
     373                 :          1 :         result = false;
     374                 :          1 :         break;
     375                 :            :       }
     376                 :            :     }
     377                 :            :   }
     378         [ +  - ]:         21 :   catch (std::exception &e)
     379                 :            :   {
     380   [ +  -  +  - ]:         42 :     core::getLogger()->critical(
     381                 :            :       "RssSituationExtraction::extractConstellationInputRangeChecked[{}->{}]>> Exception caught '{}' {} {}",
     382                 :         21 :       worldConstellation.ego_vehicle.object_id,
     383                 :         21 :       worldConstellation.object.object_id,
     384         [ +  - ]:         42 :       e.what(),
     385                 :            :       time_index,
     386                 :            :       worldConstellation);
     387                 :         21 :     result = false;
     388                 :         21 :   }
     389                 :          0 :   catch (...)
     390                 :            :   {
     391   [ -  -  -  - ]:          0 :     core::getLogger()->critical(
     392                 :            :       "RssSituationExtraction::extractConstellationInputRangeChecked[{}->{}]>> Exception caught {} {}",
     393                 :          0 :       worldConstellation.ego_vehicle.object_id,
     394         [ -  - ]:          0 :       worldConstellation.object.object_id,
     395                 :            :       time_index,
     396                 :            :       worldConstellation);
     397                 :          0 :     result = false;
     398                 :          0 :   }
     399                 :            : 
     400                 :       4988 :   return result;
     401                 :            : }
     402                 :            : 
     403                 :         70 : bool RssSituationExtraction::mergeVehicleStates(MergeMode const &mergeMode,
     404                 :            :                                                 core::RelativeObjectState const &other_state,
     405                 :            :                                                 core::RelativeObjectState &mergedVehicleState)
     406                 :            : {
     407                 :            :   // on vehicle states there are only differences in intersection distances allowed due to different road definitions
     408                 :         70 :   if ((other_state.dynamics.alpha_lat.accel_max != mergedVehicleState.dynamics.alpha_lat.accel_max)
     409         [ +  + ]:         68 :       || (other_state.dynamics.alpha_lat.brake_min != mergedVehicleState.dynamics.alpha_lat.brake_min)
     410         [ +  + ]:         67 :       || (other_state.dynamics.alpha_lon.accel_max != mergedVehicleState.dynamics.alpha_lon.accel_max)
     411         [ +  + ]:         67 :       || (other_state.dynamics.alpha_lon.brake_min_correct != mergedVehicleState.dynamics.alpha_lon.brake_min_correct)
     412         [ +  + ]:         65 :       || (other_state.dynamics.alpha_lon.brake_min != mergedVehicleState.dynamics.alpha_lon.brake_min)
     413         [ +  + ]:         65 :       || (other_state.dynamics.alpha_lon.brake_max != mergedVehicleState.dynamics.alpha_lon.brake_max)
     414         [ +  - ]:         64 :       || (other_state.dynamics.lateral_fluctuation_margin != mergedVehicleState.dynamics.lateral_fluctuation_margin)
     415         [ +  + ]:         63 :       || (other_state.dynamics.response_time != mergedVehicleState.dynamics.response_time)
     416   [ +  -  +  +  :        136 :       || (other_state.structured_object_state.has_priority != mergedVehicleState.structured_object_state.has_priority))
                   +  + ]
     417                 :            :   {
     418                 :          8 :     return false;
     419                 :            :   }
     420                 :            :   // consider the worst cases
     421         [ +  + ]:         60 :   if (mergeMode == MergeMode::EgoVehicle)
     422                 :            :   {
     423                 :            :     // worst case for ego vehicle is not driving in correct lane
     424                 :            :     mergedVehicleState.structured_object_state.is_in_correct_lane
     425                 :         34 :       = mergedVehicleState.structured_object_state.is_in_correct_lane
     426   [ +  -  +  + ]:         34 :       && other_state.structured_object_state.is_in_correct_lane;
     427                 :            :   }
     428                 :            :   else
     429                 :            :   {
     430                 :            :     // worst case for other vehicle is driving in correct lane
     431                 :            :     mergedVehicleState.structured_object_state.is_in_correct_lane
     432                 :         26 :       = mergedVehicleState.structured_object_state.is_in_correct_lane
     433   [ -  +  -  - ]:         26 :       || other_state.structured_object_state.is_in_correct_lane;
     434                 :            :   }
     435                 :            : 
     436                 :            :   mergedVehicleState.structured_object_state.distance_to_enter_intersection
     437                 :        121 :     = std::min(mergedVehicleState.structured_object_state.distance_to_enter_intersection,
     438                 :         60 :                other_state.structured_object_state.distance_to_enter_intersection);
     439                 :            :   mergedVehicleState.structured_object_state.distance_to_leave_intersection
     440                 :        121 :     = std::max(mergedVehicleState.structured_object_state.distance_to_leave_intersection,
     441                 :         61 :                other_state.structured_object_state.distance_to_leave_intersection);
     442                 :            :   mergedVehicleState.structured_object_state.velocity.speed_lon_min
     443                 :        122 :     = std::min(mergedVehicleState.structured_object_state.velocity.speed_lon_min,
     444                 :         60 :                other_state.structured_object_state.velocity.speed_lon_min);
     445                 :            :   mergedVehicleState.structured_object_state.velocity.speed_lon_max
     446                 :        123 :     = std::max(mergedVehicleState.structured_object_state.velocity.speed_lon_max,
     447                 :         62 :                other_state.structured_object_state.velocity.speed_lon_max);
     448                 :            :   mergedVehicleState.structured_object_state.velocity.speed_lat_min
     449                 :        120 :     = std::min(mergedVehicleState.structured_object_state.velocity.speed_lat_min,
     450                 :         61 :                other_state.structured_object_state.velocity.speed_lat_min);
     451                 :            :   mergedVehicleState.structured_object_state.velocity.speed_lat_max
     452                 :        121 :     = std::max(mergedVehicleState.structured_object_state.velocity.speed_lat_max,
     453                 :         59 :                other_state.structured_object_state.velocity.speed_lat_max);
     454                 :            : 
     455                 :         62 :   return true;
     456                 :            : }
     457                 :            : 
     458                 :         35 : bool RssSituationExtraction::mergeConstellations(core::RelativeConstellation const &otherConstellation,
     459                 :            :                                                  core::RelativeConstellation &mergedConstellation)
     460                 :            : {
     461                 :         34 :   if ( // basic data has to match
     462                 :         35 :     (otherConstellation.constellation_id != mergedConstellation.constellation_id)
     463         [ +  - ]:         35 :     || (otherConstellation.ego_id != mergedConstellation.ego_id)
     464         [ +  - ]:         35 :     || (otherConstellation.object_id != mergedConstellation.object_id)
     465         [ +  - ]:         35 :     || (otherConstellation.constellation_type != mergedConstellation.constellation_type)
     466   [ +  -  +  - ]:         35 :     || !mergeVehicleStates(MergeMode::EgoVehicle, otherConstellation.ego_state, mergedConstellation.ego_state)
     467   [ +  -  +  -  :         70 :     || !mergeVehicleStates(MergeMode::OtherVehicle, otherConstellation.other_state, mergedConstellation.other_state))
             +  +  +  + ]
     468                 :            :   {
     469                 :          8 :     return false;
     470                 :            :   }
     471                 :            : 
     472                 :            :   // worst case
     473                 :            :   mergedConstellation.relative_position.longitudinal_distance
     474                 :         52 :     = std::min(mergedConstellation.relative_position.longitudinal_distance,
     475                 :         26 :                otherConstellation.relative_position.longitudinal_distance);
     476                 :         26 :   if (otherConstellation.relative_position.longitudinal_position
     477         [ +  + ]:         26 :       != mergedConstellation.relative_position.longitudinal_position)
     478                 :            :   {
     479         [ +  + ]:          8 :     if ((mergedConstellation.relative_position.longitudinal_position == LongitudinalRelativePosition::Overlap)
     480         [ +  + ]:          7 :         || (otherConstellation.relative_position.longitudinal_position == LongitudinalRelativePosition::Overlap)
     481         [ +  + ]:          6 :         || ((mergedConstellation.relative_position.longitudinal_position < LongitudinalRelativePosition::Overlap)
     482         [ +  + ]:          3 :             && (otherConstellation.relative_position.longitudinal_position > LongitudinalRelativePosition::Overlap))
     483         [ +  + ]:          5 :         || ((mergedConstellation.relative_position.longitudinal_position > LongitudinalRelativePosition::Overlap)
     484         [ +  + ]:          3 :             && (otherConstellation.relative_position.longitudinal_position < LongitudinalRelativePosition::Overlap)))
     485                 :            :     {
     486                 :            :       // overlap is also worst case for contradicting input, ensure the longitudinal distance becomes 0.
     487                 :          4 :       mergedConstellation.relative_position.longitudinal_position = LongitudinalRelativePosition::Overlap;
     488                 :          4 :       mergedConstellation.relative_position.longitudinal_distance = Distance(0.);
     489                 :            :     }
     490         [ +  + ]:          4 :     else if ((mergedConstellation.relative_position.longitudinal_position == LongitudinalRelativePosition::OverlapFront)
     491         [ +  + ]:          3 :              || (otherConstellation.relative_position.longitudinal_position
     492                 :            :                  == LongitudinalRelativePosition::OverlapFront))
     493                 :            :     {
     494                 :            :       // one of the both is overlap font (the other then only can be InFront in here)
     495                 :          2 :       mergedConstellation.relative_position.longitudinal_position = LongitudinalRelativePosition::OverlapFront;
     496                 :            :     }
     497         [ +  + ]:          2 :     else if ((mergedConstellation.relative_position.longitudinal_position == LongitudinalRelativePosition::OverlapBack)
     498         [ +  - ]:          1 :              || (otherConstellation.relative_position.longitudinal_position
     499                 :            :                  == LongitudinalRelativePosition::OverlapBack))
     500                 :            :     {
     501                 :            :       // one of the both is overlap back (the other then only can be AtBack in here)
     502                 :          2 :       mergedConstellation.relative_position.longitudinal_position = LongitudinalRelativePosition::OverlapBack;
     503                 :            :     }
     504                 :            :     else
     505                 :            :     {
     506                 :            :       // LCOV_EXCL_START: unreachable code, keep to be on the safe side
     507                 :            :       // this is impossible to reach, set to overlap having longitudinal distance to 0. to be on the safe side
     508                 :            :       mergedConstellation.relative_position.longitudinal_position = LongitudinalRelativePosition::Overlap;
     509                 :            :       mergedConstellation.relative_position.longitudinal_distance = Distance(0.);
     510                 :            :       // LCOV_EXCL_STOP: unreachable code, keep to be on the safe side
     511                 :            :     }
     512                 :            :   }
     513                 :            : 
     514                 :         53 :   mergedConstellation.relative_position.lateral_distance = std::min(
     515                 :         26 :     mergedConstellation.relative_position.lateral_distance, otherConstellation.relative_position.lateral_distance);
     516         [ +  + ]:         27 :   if (otherConstellation.relative_position.lateral_position != mergedConstellation.relative_position.lateral_position)
     517                 :            :   {
     518         [ +  + ]:          8 :     if ((mergedConstellation.relative_position.lateral_position == LateralRelativePosition::Overlap)
     519         [ +  + ]:          7 :         || (otherConstellation.relative_position.lateral_position == LateralRelativePosition::Overlap)
     520         [ +  + ]:          6 :         || ((mergedConstellation.relative_position.lateral_position < LateralRelativePosition::Overlap)
     521         [ +  + ]:          3 :             && (otherConstellation.relative_position.lateral_position > LateralRelativePosition::Overlap))
     522         [ +  + ]:          5 :         || ((mergedConstellation.relative_position.lateral_position > LateralRelativePosition::Overlap)
     523         [ +  + ]:          3 :             && (otherConstellation.relative_position.lateral_position < LateralRelativePosition::Overlap)))
     524                 :            :     {
     525                 :            :       // overlap is also worst case for contradicting input, ensure the lateral distance becomes 0.
     526                 :          4 :       mergedConstellation.relative_position.lateral_position = LateralRelativePosition::Overlap;
     527                 :          4 :       mergedConstellation.relative_position.lateral_distance = Distance(0.);
     528                 :            :     }
     529         [ +  + ]:          4 :     else if ((mergedConstellation.relative_position.lateral_position == LateralRelativePosition::OverlapLeft)
     530         [ +  + ]:          3 :              || (otherConstellation.relative_position.lateral_position == LateralRelativePosition::OverlapLeft))
     531                 :            :     {
     532                 :            :       // one of the both is overlap left (the other then only can be AtLeft in here)
     533                 :          2 :       mergedConstellation.relative_position.lateral_position = LateralRelativePosition::OverlapLeft;
     534                 :            :     }
     535         [ +  + ]:          2 :     else if ((mergedConstellation.relative_position.lateral_position == LateralRelativePosition::OverlapRight)
     536         [ +  - ]:          1 :              || (otherConstellation.relative_position.lateral_position == LateralRelativePosition::OverlapRight))
     537                 :            :     {
     538                 :            :       // one of the both is overlap right (the other then only can be AtRight in here)
     539                 :          2 :       mergedConstellation.relative_position.lateral_position = LateralRelativePosition::OverlapRight;
     540                 :            :     }
     541                 :            :     else
     542                 :            :     {
     543                 :            :       // LCOV_EXCL_START: unreachable code, keep to be on the safe side
     544                 :            :       // this is impossible to reach, set to overlap having lateral distance to 0. to be on the safe side
     545                 :            :       mergedConstellation.relative_position.lateral_position = LateralRelativePosition::Overlap;
     546                 :            :       mergedConstellation.relative_position.lateral_distance = Distance(0.);
     547                 :            :       // LCOV_EXCL_STOP: unreachable code, keep to be on the safe side
     548                 :            :     }
     549                 :            :   }
     550                 :            : 
     551         [ +  - ]:         27 :   mergedConstellation.world_model_indices.insert(mergedConstellation.world_model_indices.end(),
     552                 :            :                                                  otherConstellation.world_model_indices.begin(),
     553                 :            :                                                  otherConstellation.world_model_indices.end());
     554                 :            : 
     555                 :         25 :   return true;
     556                 :            : }
     557                 :            : 
     558                 :       4329 : bool RssSituationExtraction::extractSituation(world::WorldModel const &worldModel,
     559                 :            :                                               core::RssSituationSnapshot &situationSnapshot)
     560                 :            : {
     561         [ +  + ]:       4329 :   if (!withinValidInputRange(worldModel))
     562                 :            :   {
     563         [ +  - ]:         38 :     core::getLogger()->error("RssSituationExtraction::extractSituation>> Invalid input {}", worldModel);
     564                 :         19 :     return false;
     565                 :            :   }
     566                 :            : 
     567                 :       4310 :   bool result = true;
     568                 :            :   try
     569                 :            :   {
     570                 :       4310 :     situationSnapshot.time_index = worldModel.time_index;
     571                 :       4310 :     situationSnapshot.default_ego_vehicle_rss_dynamics = worldModel.default_ego_vehicle_rss_dynamics;
     572                 :       4310 :     situationSnapshot.constellations.clear();
     573         [ +  + ]:       9275 :     for (uint64_t world_model_index = 0u; world_model_index < worldModel.constellations.size(); world_model_index++)
     574                 :            :     {
     575         [ +  + ]:       5108 :       auto const worldConstellation = worldModel.constellations[world_model_index];
     576         [ +  - ]:       5009 :       core::RelativeConstellation relativeConstellation;
     577         [ +  + ]:       5010 :       relativeConstellation.world_model_indices.push_back(world_model_index);
     578                 :            :       bool const extractResult
     579         [ +  - ]:       4993 :         = extractConstellationInputRangeChecked(worldModel.time_index, worldConstellation, relativeConstellation);
     580         [ +  + ]:       4995 :       if (extractResult)
     581                 :            :       {
     582                 :            :         // constellation id creation might detect that different world constellations are representing identical
     583                 :            :         // relative constellations
     584                 :            :         // ensure the situationSnapshot is unique while containing the merged constellation
     585                 :            :         auto findResult
     586         [ +  - ]:       4774 :           = std::find_if(situationSnapshot.constellations.begin(),
     587                 :            :                          situationSnapshot.constellations.end(),
     588                 :       5580 :                          [&relativeConstellation](core::RelativeConstellation const &checkConstellation) {
     589                 :       5580 :                            return checkConstellation.constellation_id == relativeConstellation.constellation_id;
     590                 :            :                          });
     591         [ +  + ]:       4770 :         if (findResult == situationSnapshot.constellations.end())
     592                 :            :         {
     593         [ +  + ]:       4735 :           situationSnapshot.constellations.push_back(relativeConstellation);
     594                 :            :         }
     595   [ +  -  +  + ]:         35 :         else if (!mergeConstellations(relativeConstellation, *findResult))
     596                 :            :         {
     597                 :          8 :           result = false;
     598                 :            :         }
     599                 :            :       }
     600                 :            :       else
     601                 :            :       {
     602   [ +  -  +  - ]:        442 :         core::getLogger()->error("RssSituationExtraction::extractSituation>> Extraction failed {}", worldConstellation);
     603                 :        221 :         result = false;
     604                 :            :       }
     605                 :       5052 :     }
     606                 :            :   }
     607         [ +  - ]:        143 :   catch (std::exception &e)
     608                 :            :   {
     609   [ +  -  +  - ]:        286 :     core::getLogger()->critical(
     610         [ +  - ]:        286 :       "RssSituationExtraction::extractSituation>> Exception caught '{}' {}", e.what(), worldModel);
     611                 :        143 :     result = false;
     612                 :        143 :   }
     613                 :          0 :   catch (...)
     614                 :            :   {
     615   [ -  -  -  - ]:          0 :     core::getLogger()->critical("RssSituationExtraction::extractSituation>> Exception caught {}", worldModel);
     616                 :          0 :     result = false;
     617                 :          0 :   }
     618                 :       4310 :   return result;
     619                 :            : }
     620                 :            : 
     621                 :            : } // namespace core
     622                 :            : } // namespace rss
     623                 :            : } // namespace ad

Generated by: LCOV version 1.14