LCOV - code coverage report
Current view: top level - src/perception/filters/ray_ground_classifier/src - ray_ground_classifier.cpp (source / functions) Hit Total Coverage
Test: lcov.total.filtered Lines: 51 60 85.0 %
Date: 2023-03-03 05:44:19 Functions: 8 12 66.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 34 44 77.3 %

           Branch data     Line data    Source code
       1                 :            : // Copyright 2017-2020 the Autoware Foundation, Arm Limited
       2                 :            : //
       3                 :            : // Licensed under the Apache License, Version 2.0 (the "License");
       4                 :            : // you may not use this file except in compliance with the License.
       5                 :            : // You may obtain a copy of the License at
       6                 :            : //
       7                 :            : //     http://www.apache.org/licenses/LICENSE-2.0
       8                 :            : //
       9                 :            : // Unless required by applicable law or agreed to in writing, software
      10                 :            : // distributed under the License is distributed on an "AS IS" BASIS,
      11                 :            : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :            : // See the License for the specific language governing permissions and
      13                 :            : // limitations under the License.
      14                 :            : //
      15                 :            : // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
      16                 :            : 
      17                 :            : //lint -e537 NOLINT  // cpplint vs pclint
      18                 :            : #include <utility>
      19                 :            : //lint -e537 NOLINT  // cpplint vs pclint
      20                 :            : #include <algorithm>
      21                 :            : #include <cstdint>
      22                 :            : #include <stdexcept>
      23                 :            : 
      24                 :            : #include "common/types.hpp"
      25                 :            : #include "ray_ground_classifier/ray_ground_classifier.hpp"
      26                 :            : #include "ray_ground_classifier/ray_ground_point_classifier.hpp"
      27                 :            : 
      28                 :            : using autoware::common::types::bool8_t;
      29                 :            : using autoware::common::types::float32_t;
      30                 :            : 
      31                 :            : namespace autoware
      32                 :            : {
      33                 :            : namespace perception
      34                 :            : {
      35                 :            : namespace filters
      36                 :            : {
      37                 :            : namespace ray_ground_classifier
      38                 :            : {
      39                 :            : 
      40                 :            : ////////////////////////////////////////////////////////////////////////////////
      41                 :         29 : RayGroundClassifier::RayGroundClassifier(const Config & cfg)
      42                 :            : : m_sort_array(autoware::common::types::POINT_BLOCK_CAPACITY),
      43                 :            :   m_ray_sorter(autoware::common::types::POINT_BLOCK_CAPACITY),
      44   [ +  -  +  - ]:         29 :   m_point_classifier(cfg)
      45                 :            : {
      46                 :            :   m_sort_array.clear();
      47                 :         29 : }
      48                 :            : ////////////////////////////////////////////////////////////////////////////////
      49                 :          0 : RayGroundClassifier::RayGroundClassifier(const RayGroundClassifier & original)
      50                 :          0 : : m_sort_array(original.m_sort_array),
      51                 :            :   m_ray_sorter(original.m_ray_sorter.capacity()),
      52   [ #  #  #  #  :          0 :   m_point_classifier(original.m_point_classifier)
                   #  # ]
      53                 :            : {
      54                 :            :   m_sort_array.clear();
      55                 :          0 : }
      56                 :            : ////////////////////////////////////////////////////////////////////////////////
      57                 :     359434 : void RayGroundClassifier::insert(const PointXYZIF * pt)
      58                 :            : {
      59                 :     359434 :   insert(PointXYZIFR{pt});
      60                 :     359433 : }
      61                 :            : ////////////////////////////////////////////////////////////////////////////////
      62                 :     359434 : void RayGroundClassifier::insert(const PointXYZIFR & pt)
      63                 :            : {
      64         [ +  + ]:     359434 :   if (m_sort_array.size() >= m_sort_array.capacity()) {
      65         [ +  - ]:          1 :     throw std::runtime_error("RayGroundClassifier: cannot insert into full array");
      66                 :            :   }
      67                 :     359433 :   m_sort_array.push_back(pt);
      68                 :     359433 : }
      69                 :            : ////////////////////////////////////////////////////////////////////////////////
      70                 :        774 : bool8_t RayGroundClassifier::can_fit_result(
      71                 :            :   const Ray & ray,
      72                 :            :   const PointPtrBlock & ground_block,
      73                 :            :   const PointPtrBlock & nonground_block) const
      74                 :            : {
      75         [ +  + ]:        774 :   return (ray.size() + std::max(ground_block.size(), nonground_block.size())) <=
      76                 :        774 :          autoware::common::types::POINT_BLOCK_CAPACITY;
      77                 :            : }
      78                 :            : ////////////////////////////////////////////////////////////////////////////////
      79                 :         25 : bool8_t RayGroundClassifier::can_fit_result(
      80                 :            :   const PointPtrBlock & ground_block,
      81                 :            :   const PointPtrBlock & nonground_block) const
      82                 :            : {
      83                 :         25 :   return can_fit_result(m_sort_array, ground_block, nonground_block);
      84                 :            : }
      85                 :            : ////////////////////////////////////////////////////////////////////////////////
      86                 :         25 : void RayGroundClassifier::partition(
      87                 :            :   PointPtrBlock & ground_block,
      88                 :            :   PointPtrBlock & nonground_block,
      89                 :            :   const bool8_t presorted)
      90                 :            : {
      91         [ +  + ]:         25 :   if (!presorted) {
      92                 :            :     sort_ray();
      93                 :            :   }
      94                 :            :   segment_ray(ground_block, nonground_block);
      95                 :         23 : }
      96                 :            : ////////////////////////////////////////////////////////////////////////////////
      97         [ +  + ]:        703 : void RayGroundClassifier::structured_partition(
      98                 :            :   const PointPtrBlock & raw_block,
      99                 :            :   PointPtrBlock & ground_block,
     100                 :            :   PointPtrBlock & nonground_block)
     101                 :            : {
     102                 :            :   // reset blocks
     103                 :            :   ground_block.clear();
     104                 :            :   nonground_block.clear();
     105                 :            :   // insert points and segment rays
     106                 :        703 :   uint16_t last_id = raw_block[0U]->id;
     107         [ +  + ]:     359167 :   for (const PointXYZIF * pt : raw_block) {
     108                 :     358465 :     const uint16_t id = pt->id;
     109                 :            :     // terminal scan, add to both
     110         [ +  + ]:     358465 :     if (static_cast<uint16_t>(autoware::common::types::PointXYZIF::END_OF_SCAN_ID) == id) {
     111                 :          1 :       insert(ground_block, pt);
     112                 :          1 :       insert(nonground_block, pt);
     113                 :            :       break;
     114                 :            :     }
     115         [ +  + ]:     358464 :     if (id != last_id) {
     116                 :            :       // we have started a new ray; last ray is complete
     117                 :            :       sort_ray();
     118                 :            :       segment_ray(ground_block, nonground_block);
     119                 :            :       // reset stuff
     120                 :            :       last_id = id;
     121                 :            :     }
     122                 :     358464 :     insert(pt);
     123                 :            :   }
     124                 :            :   // segment last ray
     125                 :            :   sort_ray();
     126                 :            :   segment_ray(ground_block, nonground_block);
     127                 :        703 : }
     128                 :            : 
     129                 :            : ////////////////////////////////////////////////////////////////////////////////
     130                 :          0 : void RayGroundClassifier::sort_ray()
     131                 :            : {
     132                 :            :   // sort by radial distance
     133                 :        728 :   m_ray_sorter.sort(m_sort_array.begin(), m_sort_array.end());
     134                 :         24 : }
     135                 :            : ////////////////////////////////////////////////////////////////////////////////
     136                 :          0 : void RayGroundClassifier::insert(PointPtrBlock & block, const PointXYZIF * pt)
     137                 :            : {
     138                 :     359454 :   block.push_back(pt);
     139                 :          0 : }
     140                 :            : ////////////////////////////////////////////////////////////////////////////////
     141                 :          0 : void RayGroundClassifier::segment_ray(PointPtrBlock & ground_block, PointPtrBlock & nonground_block)
     142                 :            : {
     143                 :        729 :   partition(m_sort_array, ground_block, nonground_block);
     144                 :            :   // reset internal array
     145                 :            :   m_sort_array.clear();  // capacity unchanged
     146                 :          0 : }
     147                 :            : ////////////////////////////////////////////////////////////////////////////////
     148                 :        749 : void RayGroundClassifier::partition(
     149                 :            :   const Ray & ray,
     150                 :            :   PointPtrBlock & ground_block,
     151                 :            :   PointPtrBlock & nonground_block)
     152                 :            : {
     153                 :            :   // Make sure result can fit
     154         [ +  + ]:        749 :   if (!can_fit_result(ray, ground_block, nonground_block)) {
     155         [ +  - ]:          2 :     throw std::runtime_error("RayGroundClassifier: Blocks cannot fit partition result");
     156                 :            :   }
     157                 :            :   // reset classifier
     158                 :        747 :   m_point_classifier.reset();
     159                 :            :   // filter and push to appropriate queues
     160                 :            :   const PointXYZIF * last_point_ptr = nullptr;
     161                 :            :   RayGroundPointClassifier::PointLabel last_label =
     162                 :            :     RayGroundPointClassifier::PointLabel::NONGROUND;
     163         [ +  + ]:     360200 :   for (std::size_t idx = 0U; idx < ray.size(); ++idx) {
     164                 :            :     const std::size_t jdx = idx;  // fixes PCLint FP: idx modified in loop
     165                 :            :     const PointXYZIFR & pt = ray[jdx];
     166                 :     359453 :     const RayGroundPointClassifier::PointLabel label = m_point_classifier.is_ground(pt);
     167                 :            :     // modify label of last point
     168                 :     359453 :     if (((label == RayGroundPointClassifier::PointLabel::NONGROUND) &&
     169   [ +  +  +  + ]:     359453 :       (last_label == RayGroundPointClassifier::PointLabel::PROVISIONAL_GROUND)) ||
     170                 :            :       (label == RayGroundPointClassifier::PointLabel::RETRO_NONGROUND))
     171                 :            :     {
     172                 :            :       last_label = RayGroundPointClassifier::PointLabel::NONGROUND;
     173                 :            :     }
     174                 :            :     // push last point accordingly
     175         [ +  + ]:     359453 :     if (last_point_ptr != nullptr) {
     176         [ +  + ]:     358708 :       if (RayGroundPointClassifier::label_is_ground(last_label)) {
     177                 :     146973 :         insert(ground_block, last_point_ptr);
     178                 :            :       } else {
     179                 :     211735 :         insert(nonground_block, last_point_ptr);
     180                 :            :       }
     181                 :            :     }
     182                 :            :     // update state
     183                 :     359453 :     last_point_ptr = pt.get_point_pointer();
     184                 :            :     last_label = label;
     185                 :            :   }
     186                 :            :   // push trailing point
     187         [ +  + ]:        747 :   if (last_point_ptr != nullptr) {
     188         [ +  + ]:        745 :     if (RayGroundPointClassifier::label_is_ground(last_label)) {
     189                 :        731 :       insert(ground_block, last_point_ptr);
     190                 :            :     } else {
     191                 :         14 :       insert(nonground_block, last_point_ptr);
     192                 :            :     }
     193                 :            :   }
     194                 :        747 : }
     195                 :            : 
     196                 :            : }  // namespace ray_ground_classifier
     197                 :            : }  // namespace filters
     198                 :            : }  // namespace perception
     199                 :            : }  // namespace autoware

Generated by: LCOV version 1.14