Skip to content

Commit 2f3e335

Browse files
feat: add blockage diagnostics (autowarefoundation#461)
* feat!: add blockage diagnostic Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * fix: typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * docs: add documentation Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * ci(pre-commit): autofix * fix: typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * ci(pre-commit): autofix * fix: typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: add adjustable param Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * ci(pre-commit): autofix * feat!: add blockage diagnostic Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * fix: typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * docs: add documentation Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * ci(pre-commit): autofix * fix: typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * ci(pre-commit): autofix * fix: typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: add adjustable param Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * ci(pre-commit): autofix * chore: rearrange header file Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: fix typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: rearrange header Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * fix: revert accident change Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: fix typo Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * docs: add limits Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> * chore: check overflow Signed-off-by: badai-nguyen <dai.nguyen@tier4.jp> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 7168952 commit 2f3e335

15 files changed

+457
-47
lines changed

common/autoware_point_types/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ endif()
1414
find_package(ament_cmake_auto REQUIRED)
1515
ament_auto_find_build_dependencies()
1616

17+
include_directories(
18+
include
19+
SYSTEM
20+
${PCL_INCLUDE_DIRS}
21+
)
22+
1723
if(BUILD_TESTING)
1824
find_package(ament_lint_auto REQUIRED)
1925
ament_lint_auto_find_test_dependencies()

common/autoware_point_types/include/autoware_point_types/types.hpp

+19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include <point_cloud_msg_wrapper/point_cloud_msg_wrapper.hpp>
1919

20+
#include <pcl/point_types.h>
21+
2022
#include <cmath>
2123
#include <tuple>
2224

@@ -41,6 +43,17 @@ struct PointXYZI
4143
}
4244
};
4345

46+
enum ReturnType : uint8_t {
47+
INVALID = 0,
48+
SINGLE_STRONGEST,
49+
SINGLE_LAST,
50+
DUAL_STRONGEST_FIRST,
51+
DUAL_STRONGEST_LAST,
52+
DUAL_WEAK_FIRST,
53+
DUAL_WEAK_LAST,
54+
DUAL_ONLY,
55+
};
56+
4457
struct PointXYZIRADRT
4558
{
4659
float x{0.0F};
@@ -77,4 +90,10 @@ using PointXYZIRADRTGenerator = std::tuple<
7790

7891
} // namespace autoware_point_types
7992

93+
POINT_CLOUD_REGISTER_POINT_STRUCT(
94+
autoware_point_types::PointXYZIRADRT,
95+
(float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(std::uint16_t, ring, ring)(
96+
float, azimuth, azimuth)(float, distance, distance)(std::uint8_t, return_type, return_type)(
97+
double, time_stamp, time_stamp))
98+
8099
#endif // AUTOWARE_POINT_TYPES__TYPES_HPP_

common/autoware_point_types/package.xml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<depend>ament_cmake_cppcheck</depend>
1919
<depend>ament_cmake_lint_cmake</depend>
2020
<depend>ament_cmake_xmllint</depend>
21+
<depend>pcl_ros</depend>
2122
<depend>point_cloud_msg_wrapper</depend>
2223

2324
<test_depend>ament_cmake_gtest</test_depend>

sensing/pointcloud_preprocessor/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ ament_auto_add_library(pointcloud_preprocessor_filter SHARED
5757
src/pointcloud_accumulator/pointcloud_accumulator_nodelet.cpp
5858
src/vector_map_filter/lanelet2_map_filter_nodelet.cpp
5959
src/distortion_corrector/distortion_corrector.cpp
60+
src/blockage_diag/blockage_diag_nodelet.cpp
6061
)
6162

6263
target_link_libraries(pointcloud_preprocessor_filter
@@ -149,6 +150,10 @@ rclcpp_components_register_node(pointcloud_preprocessor_filter
149150
PLUGIN "pointcloud_preprocessor::DistortionCorrectorComponent"
150151
EXECUTABLE distortion_corrector_node)
151152

153+
# ========== Blockage Diagnostics ===========
154+
rclcpp_components_register_node(pointcloud_preprocessor_filter
155+
PLUGIN "pointcloud_preprocessor::BlockageDiagComponent"
156+
EXECUTABLE blockage_diag_node)
152157

153158
if(BUILD_TESTING)
154159
find_package(ament_lint_auto REQUIRED)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# blockage_diag
2+
3+
## Purpose
4+
5+
To ensure the performance of LiDAR and safety for autonomous driving, the abnormal condition diagnostics feature is needed.
6+
LiDAR blockage is abnormal condition of LiDAR when some unwanted objects stitch to and block the light pulses and return signal.
7+
This node's purpose is to detect the existing of blockage on LiDAR and its related size and location.
8+
9+
## Inner-workings / Algorithms
10+
11+
This node bases on the no-return region and its location to decide if it is a blockage.
12+
13+
![blockage situation](./image/blockage_diag.png)
14+
15+
The logic is showed as below
16+
17+
![blockage_diag_flowchart](./image/blockage_diag_flowchart.drawio.svg)
18+
19+
## Inputs / Outputs
20+
21+
This implementation inherits `pointcloud_preprocessor::Filter` class, please refer [README](../README.md).
22+
23+
### Input
24+
25+
| Name | Type | Description |
26+
| --------------------------- | ------------------------------- | --------------------------------------------------------------- |
27+
| `~/input/pointcloud_raw_ex` | `sensor_msgs::msg::PointCloud2` | The raw point cloud data is used to detect the no-return region |
28+
29+
### Output
30+
31+
| Name | Type | Description |
32+
| ---------------------------------------------------- | --------------------------------------- | -------------------------------------------------- |
33+
| `~/output/blockage_diag/debug/blockage_mask_image` | `sensor_msgs::msg::Image` | The mask image of detected blockage |
34+
| `~/output/blockage_diag/debug/ground_blockage_ratio` | `tier4_debug_msgs::msg::Float32Stamped` | The area ratio of blockage region in ground region |
35+
| `~/output/blockage_diag/debug/sky_blockage_ratio` | `tier4_debug_msgs::msg::Float32Stamped` | The area ratio of blockage region in sky region |
36+
| `~/output/blockage_diag/debug/lidar_depth_map` | `sensor_msgs::msg::Image` | The depth map image of input point cloud |
37+
38+
## Parameters
39+
40+
| Name | Type | Description |
41+
| -------------------------- | ------ | -------------------------------------------------- |
42+
| `blockage_ratio_threshold` | float | The threshold of blockage area ratio |
43+
| `blockage_count_threshold` | float | The threshold of number continuous blockage frames |
44+
| `horizontal_ring_id` | int | The id of horizontal ring of the LiDAR |
45+
| `angle_range` | vector | The effective range of LiDAR |
46+
| `vertical_bins` | int | The LiDAR channel number |
47+
| `model` | string | The LiDAR model |
48+
49+
## Assumptions / Known limits
50+
51+
1. Only Hesai Pandar40P and Hesai PandarQT were tested. For a new LiDAR, it is neccessary to check order of channel id in vertical distribution manually and modifiy the code.
52+
2. The current method is still limited for dust type of blockage when dust particles are sparsely distributed.
53+
54+
## (Optional) Error detection and handling
55+
56+
## (Optional) Performance characterization
57+
58+
## References/External links
59+
60+
## (Optional) Future extensions / Unimplemented parts

sensing/pointcloud_preprocessor/docs/dual-return-outlier-filter.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This node can remove rain and fog by considering the light reflected from the ob
1010

1111
![outlier_filter-return_type](./image/outlier_filter-return_type.drawio.svg)
1212

13-
Therefore, in order to use this node, the sensor driver must publish custom data including `return_type`. please refer to [PointXYZIRADT](https://github.com/tier4/AutowareArchitectureProposal.iv/blob/5d8dff0db51634f0c42d2a3e87ca423fbee84348/sensing/preprocessor/pointcloud/pointcloud_preprocessor/include/pointcloud_preprocessor/outlier_filter/dual_return_outlier_filter_nodelet.hpp#L86-L96) data structure.
13+
Therefore, in order to use this node, the sensor driver must publish custom data including `return_type`. please refer to [PointXYZIRADRT](../../../common/autoware_point_types/include/autoware_point_types/types.hpp#L57-L76) data structure.
1414

1515
Another feature of this node is that it publishes visibility as a diagnostic topic. With this function, for example, in heavy rain, the sensing module can notify that the processing performance has reached its limit, which can lead to ensuring the safety of the vehicle.
1616

@@ -73,7 +73,7 @@ This implementation inherits `pointcloud_preprocessor::Filter` class, please ref
7373
## Assumptions / Known limits
7474

7575
Not recommended for use as it is under development.
76-
Input data must be `PointXYZIRADT` type data including `return_type`.
76+
Input data must be `PointXYZIRADRT` type data including `return_type`.
7777

7878
## (Optional) Error detection and handling
7979

Loading

sensing/pointcloud_preprocessor/docs/image/blockage_diag_flowchart.drawio.svg

+4
Loading

sensing/pointcloud_preprocessor/docs/image/outlier_filter-dual_return_detail.drawio.svg

+1-1
Loading

sensing/pointcloud_preprocessor/docs/image/outlier_filter-dual_return_overall.drawio.svg

+1-1
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright 2022 TIER IV, Inc.
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+
#ifndef POINTCLOUD_PREPROCESSOR__BLOCKAGE_DIAG__BLOCKAGE_DIAG_NODELET_HPP_
16+
#define POINTCLOUD_PREPROCESSOR__BLOCKAGE_DIAG__BLOCKAGE_DIAG_NODELET_HPP_
17+
18+
#include "pointcloud_preprocessor/filter.hpp"
19+
20+
#include <diagnostic_updater/diagnostic_updater.hpp>
21+
#include <image_transport/image_transport.hpp>
22+
#include <opencv2/highgui/highgui.hpp>
23+
#include <rclcpp/rclcpp.hpp>
24+
25+
#include <diagnostic_msgs/msg/diagnostic_array.hpp>
26+
#include <sensor_msgs/msg/point_cloud2.hpp>
27+
#include <std_msgs/msg/header.hpp>
28+
#include <tier4_debug_msgs/msg/float32_stamped.hpp>
29+
30+
#include <cv_bridge/cv_bridge.h>
31+
32+
#include <string>
33+
#include <vector>
34+
35+
namespace pointcloud_preprocessor
36+
{
37+
using diagnostic_updater::DiagnosticStatusWrapper;
38+
using diagnostic_updater::Updater;
39+
40+
class BlockageDiagComponent : public pointcloud_preprocessor::Filter
41+
{
42+
protected:
43+
virtual void filter(
44+
const PointCloud2ConstPtr & input, [[maybe_unused]] const IndicesPtr & indices,
45+
PointCloud2 & output);
46+
/** \brief Parameter service callback result : needed to be hold */
47+
OnSetParametersCallbackHandle::SharedPtr set_param_res_;
48+
49+
/** \brief Parameter service callback */
50+
rcl_interfaces::msg::SetParametersResult paramCallback(const std::vector<rclcpp::Parameter> & p);
51+
image_transport::Publisher lidar_depth_map_pub_;
52+
image_transport::Publisher blockage_mask_pub_;
53+
rclcpp::Publisher<tier4_debug_msgs::msg::Float32Stamped>::SharedPtr ground_blockage_ratio_pub_;
54+
rclcpp::Publisher<tier4_debug_msgs::msg::Float32Stamped>::SharedPtr sky_blockage_ratio_pub_;
55+
56+
private:
57+
void onBlockageChecker(DiagnosticStatusWrapper & stat);
58+
Updater updater_{this};
59+
uint vertical_bins_;
60+
std::vector<double> angle_range_deg_;
61+
uint horizontal_ring_id_ = 12;
62+
float blockage_ratio_threshold_;
63+
float ground_blockage_ratio_ = -1.0f;
64+
float sky_blockage_ratio_ = -1.0f;
65+
std::vector<float> ground_blockage_range_deg_ = {0.0f, 0.0f};
66+
std::vector<float> sky_blockage_range_deg_ = {0.0f, 0.0f};
67+
uint erode_kernel_ = 10;
68+
uint ground_blockage_count_ = 0;
69+
uint sky_blockage_count_ = 0;
70+
uint blockage_count_threshold_;
71+
std::string lidar_model_;
72+
73+
public:
74+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
75+
explicit BlockageDiagComponent(const rclcpp::NodeOptions & options);
76+
};
77+
78+
} // namespace pointcloud_preprocessor
79+
80+
#endif // POINTCLOUD_PREPROCESSOR__BLOCKAGE_DIAG__BLOCKAGE_DIAG_NODELET_HPP_

sensing/pointcloud_preprocessor/include/pointcloud_preprocessor/outlier_filter/dual_return_outlier_filter_nodelet.hpp

-33
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,6 @@ namespace pointcloud_preprocessor
3939
using diagnostic_updater::DiagnosticStatusWrapper;
4040
using diagnostic_updater::Updater;
4141

42-
enum ReturnType : uint8_t {
43-
INVALID = 0,
44-
SINGLE_STRONGEST,
45-
SINGLE_LAST,
46-
DUAL_STRONGEST_FIRST,
47-
DUAL_STRONGEST_LAST,
48-
DUAL_WEAK_FIRST,
49-
DUAL_WEAK_LAST,
50-
DUAL_ONLY,
51-
};
52-
5342
std::unordered_map<std::string, uint8_t> roi_mode_map_ = {
5443
{"No_ROI", 0},
5544
{"Fixed_xyz_ROI", 1},
@@ -101,26 +90,4 @@ class DualReturnOutlierFilterComponent : public pointcloud_preprocessor::Filter
10190

10291
} // namespace pointcloud_preprocessor
10392

104-
namespace return_type_cloud
105-
{
106-
struct PointXYZIRADT
107-
{
108-
PCL_ADD_POINT4D;
109-
float intensity;
110-
std::uint16_t ring;
111-
float azimuth;
112-
float distance;
113-
std::uint8_t return_type;
114-
double time_stamp;
115-
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
116-
} EIGEN_ALIGN16;
117-
118-
} // namespace return_type_cloud
119-
120-
POINT_CLOUD_REGISTER_POINT_STRUCT(
121-
return_type_cloud::PointXYZIRADT,
122-
(float, x, x)(float, y, y)(float, z, z)(float, intensity, intensity)(std::uint16_t, ring, ring)(
123-
float, azimuth, azimuth)(float, distance, distance)(std::uint8_t, return_type, return_type)(
124-
double, time_stamp, time_stamp))
125-
12693
#endif // POINTCLOUD_PREPROCESSOR__OUTLIER_FILTER__DUAL_RETURN_OUTLIER_FILTER_NODELET_HPP_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<launch>
2+
<arg name="input_topic_name" default="pointcloud_raw_ex" />
3+
<arg name="output_topic_name" default="blockage_diag/pointcloud" />
4+
5+
<node pkg="pointcloud_preprocessor" exec="blockage_diag_node" name="blockage_diag">
6+
<remap from="input" to="$(var input_topic_name)" />
7+
<remap from="output" to="$(var output_topic_name)" />
8+
</node>
9+
</launch>

0 commit comments

Comments
 (0)