Skip to content

Commit 03fdcc7

Browse files
feat(autoware_crop_box_filter): reimplementation in core repo (#279)
Signed-off-by: liuXinGangChina <lxg19892021@gmail.com> Co-authored-by: Yutaka Kondo <yutaka.kondo@youtalk.jp>
1 parent a5563e2 commit 03fdcc7

File tree

8 files changed

+1003
-0
lines changed

8 files changed

+1003
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
cmake_minimum_required(VERSION 3.14)
2+
project(autoware_crop_box_filter)
3+
4+
find_package(autoware_cmake REQUIRED)
5+
find_package(Eigen3 REQUIRED)
6+
find_package(PCL REQUIRED)
7+
8+
autoware_package()
9+
10+
include_directories(
11+
include
12+
SYSTEM
13+
${PCL_INCLUDE_DIRS}
14+
${EIGEN3_INCLUDE_DIRS}
15+
)
16+
17+
ament_auto_add_library(crop_box_filter_node SHARED
18+
src/crop_box_filter_node.cpp
19+
)
20+
21+
rclcpp_components_register_node(crop_box_filter_node
22+
PLUGIN "autoware::crop_box_filter::CropBoxFilter"
23+
EXECUTABLE crop_box_filter)
24+
25+
if(BUILD_TESTING)
26+
find_package(ament_cmake_gtest REQUIRED)
27+
ament_auto_add_gtest(test_crop_box_filter_node
28+
test/test_crop_box_filter_node.cpp
29+
)
30+
endif()
31+
32+
ament_auto_package(INSTALL_TO_SHARE
33+
launch
34+
config
35+
test
36+
)
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# autoware_crop_box_filter
2+
3+
## Overview
4+
5+
The `autoware_crop_box_filter` is a package that crops the input pointcloud to a specified bounding box. This is useful for reducing the computational load and improving the performance of the system.
6+
7+
## Design
8+
9+
The `autoware_crop_box_filter` is implemented as a autoware core node that subscribes to the input pointcloud, and publishes the filtered pointcloud. The bounding box is specified using the `min_point` and `max_point` parameters.
10+
11+
## Inputs / Outputs
12+
13+
### Input
14+
15+
| Name | Type | Description |
16+
| ---------------- | ------------------------------- | ---------------- |
17+
| `~/input/points` | `sensor_msgs::msg::PointCloud2` | reference points |
18+
19+
### Output
20+
21+
| Name | Type | Description |
22+
| -------------------- | ------------------------------------ | -------------------- |
23+
| `~/output/points` | `sensor_msgs::msg::PointCloud2` | filtered points |
24+
| `~/crop_box_polygon` | `geometry_msgs::msg::PolygonStamped` | bounding box polygon |
25+
26+
## Parameters
27+
28+
### Launch file Parameters
29+
30+
| Name | Type | Default Value | Description |
31+
| ---------------------------- | ------ | ------------- | -------------------------------------------- |
32+
| `input_frame` | string | " " | the frame id in which filtering is performed |
33+
| `output_frame` | string | " " | output frame id of the filtered points |
34+
| `input_pointcloud_frame` | string | " " | frame id of input pointcloud |
35+
| `max_queue_size` | int | 5 | max buffer size of input/output topics |
36+
| `crop_box_filter_param_file` | string | " " | path to the parameter file for the node |
37+
38+
### Node Parameters
39+
40+
| Name | Type | Default Value | Description |
41+
| ---------- | ------ | ------------- | ---------------------------------------------------------------------------------------- |
42+
| `min_x` | double | -5.0 | minimum x value of the crop box |
43+
| `min_y` | double | -5.0 | minimum y value of the crop box |
44+
| `min_z` | double | -5.0 | minimum z value of the crop box |
45+
| `max_x` | double | 5.0 | maximum x value of the crop box |
46+
| `max_y` | double | 5.0 | maximum y value of the crop box |
47+
| `max_z` | double | 5.0 | maximum z value of the crop box |
48+
| `negative` | bool | true | if true, points inside the box are removed, otherwise points outside the box are removed |
49+
50+
## Usage
51+
52+
### 1.publish static tf from input pointcloud to target frame that is used for filtering
53+
54+
```cpp
55+
ros2 run tf2_ros static_transform_publisher 2.0 3.2 1.3 0 0 0 1 velodyne_top_base_link base_link
56+
```
57+
58+
### 2.launch node
59+
60+
```cpp
61+
ros2 launch autoware_crop_box_filter crop_box_filter_node.launch.xml
62+
```
63+
64+
### 3. launch rviz2 and AWSIM
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**:
2+
ros__parameters:
3+
min_x: -5.0
4+
min_y: -5.0
5+
min_z: -5.0
6+
max_x: 5.0
7+
max_y: 5.0
8+
max_z: 5.0
9+
negative: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright(c) 2025 AutoCore Technology (Nanjing) Co., Ltd. All rights reserved.
2+
//
3+
// Copyright 2025 TIER IV, Inc.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
#ifndef AUTOWARE__CROP_BOX_FILTER__CROP_BOX_FILTER_NODE_HPP_
18+
#define AUTOWARE__CROP_BOX_FILTER__CROP_BOX_FILTER_NODE_HPP_
19+
20+
#include <autoware/point_types/types.hpp>
21+
#include <autoware_utils/ros/debug_publisher.hpp>
22+
#include <autoware_utils/ros/managed_transform_buffer.hpp>
23+
#include <autoware_utils/ros/published_time_publisher.hpp>
24+
#include <autoware_utils/system/stop_watch.hpp>
25+
26+
#include <geometry_msgs/msg/polygon_stamped.hpp>
27+
#include <sensor_msgs/msg/point_cloud2.hpp>
28+
#include <sensor_msgs/point_cloud2_iterator.hpp>
29+
30+
#include <memory>
31+
#include <string>
32+
#include <utility>
33+
#include <vector>
34+
35+
using PointCloud2 = sensor_msgs::msg::PointCloud2;
36+
using PointCloud2ConstPtr = sensor_msgs::msg::PointCloud2::ConstSharedPtr;
37+
38+
using PointCloud = pcl::PointCloud<pcl::PointXYZ>;
39+
using PointCloudPtr = PointCloud::Ptr;
40+
using PointCloudConstPtr = PointCloud::ConstPtr;
41+
42+
namespace autoware::crop_box_filter
43+
{
44+
45+
class CropBoxFilter : public rclcpp::Node
46+
{
47+
private:
48+
// member variable declaration & definitions *************************************
49+
50+
/** \brief The managed transform buffer. */
51+
std::unique_ptr<autoware_utils::ManagedTransformBuffer> managed_tf_buffer_{nullptr};
52+
53+
/** \brief The input TF frame the data should be transformed into,
54+
* if input.header.frame_id is different. */
55+
std::string tf_input_frame_;
56+
57+
/** \brief The original data input TF frame. */
58+
std::string tf_input_orig_frame_;
59+
60+
/** \brief The output TF frame the data should be transformed into,
61+
* if input.header.frame_id is different. */
62+
std::string tf_output_frame_;
63+
64+
/** \brief The maximum queue size (default: 3). */
65+
size_t max_queue_size_ = 3;
66+
67+
/** \brief Internal mutex. */
68+
std::mutex mutex_;
69+
70+
bool need_preprocess_transform_ = false;
71+
bool need_postprocess_transform_ = false;
72+
73+
Eigen::Matrix4f eigen_transform_preprocess_ = Eigen::Matrix4f::Identity(4, 4);
74+
Eigen::Matrix4f eigen_transform_postprocess_ = Eigen::Matrix4f::Identity(4, 4);
75+
76+
struct CropBoxParam
77+
{
78+
float min_x;
79+
float max_x;
80+
float min_y;
81+
float max_y;
82+
float min_z;
83+
float max_z;
84+
bool negative{false};
85+
} param_;
86+
87+
/** \brief Parameter service callback result : needed to be hold */
88+
OnSetParametersCallbackHandle::SharedPtr set_param_res_;
89+
90+
// publisher and subscriber declaration *********************
91+
92+
/** \brief The input PointCloud2 subscriber. */
93+
rclcpp::Subscription<PointCloud2>::SharedPtr sub_input_;
94+
95+
rclcpp::Publisher<PointCloud2>::SharedPtr pub_output_;
96+
rclcpp::Publisher<geometry_msgs::msg::PolygonStamped>::SharedPtr crop_box_polygon_pub_;
97+
98+
/** \brief processing time publisher. **/
99+
std::unique_ptr<autoware_utils::StopWatch<std::chrono::milliseconds>> stop_watch_ptr_;
100+
std::unique_ptr<autoware_utils::DebugPublisher> debug_publisher_;
101+
std::unique_ptr<autoware_utils::PublishedTimePublisher> published_time_publisher_;
102+
103+
// function declaration *************************************
104+
105+
void publish_crop_box_polygon();
106+
107+
void pointcloud_callback(const PointCloud2ConstPtr cloud);
108+
109+
/** \brief Parameter service callback */
110+
rcl_interfaces::msg::SetParametersResult param_callback(const std::vector<rclcpp::Parameter> & p);
111+
112+
/** \brief Return whether the input PointCloud2 data has the same layout than PointXYZI. That is
113+
* to say whether you can memcpy from the PointCloud2 data buffer to a PointXYZI */
114+
bool is_data_layout_compatible_with_point_xyzi(const PointCloud2 & input);
115+
116+
/** \brief Return whether the input PointCloud2 data has the same layout than PointXYZIRC. That is
117+
* to say whether you can memcpy from the PointCloud2 data buffer to a PointXYZIRC */
118+
bool is_data_layout_compatible_with_point_xyzirc(const PointCloud2 & input);
119+
120+
/** \brief Return whether the input PointCloud2 data has the same layout than PointXYZIRADRT. That
121+
* is to say whether you can memcpy from the PointCloud2 data buffer to a PointXYZIRADRT */
122+
bool is_data_layout_compatible_with_point_xyziradrt(const PointCloud2 & input);
123+
124+
/** \brief Return whether the input PointCloud2 data has the same layout than PointXYZIRCAEDT.
125+
* That is to say whether you can memcpy from the PointCloud2 data buffer to a PointXYZIRCAEDT */
126+
bool is_data_layout_compatible_with_point_xyzircaedt(const PointCloud2 & input);
127+
128+
bool is_valid(const PointCloud2ConstPtr & cloud);
129+
130+
/** \brief For parameter service callback */
131+
template <typename T>
132+
bool get_param(const std::vector<rclcpp::Parameter> & p, const std::string & name, T & value)
133+
{
134+
auto it = std::find_if(p.cbegin(), p.cend(), [&name](const rclcpp::Parameter & parameter) {
135+
return parameter.get_name() == name;
136+
});
137+
if (it != p.cend()) {
138+
value = it->template get_value<T>();
139+
return true;
140+
}
141+
return false;
142+
}
143+
144+
public:
145+
PCL_MAKE_ALIGNED_OPERATOR_NEW
146+
explicit CropBoxFilter(const rclcpp::NodeOptions & options);
147+
void filter_pointcloud(const PointCloud2ConstPtr & cloud, PointCloud2 & output);
148+
};
149+
} // namespace autoware::crop_box_filter
150+
151+
#endif // AUTOWARE__CROP_BOX_FILTER__CROP_BOX_FILTER_NODE_HPP_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<launch>
3+
<arg name="input_topic_name" default="/sensing/lidar/top/pointcloud_raw_ex"/>
4+
<arg name="output_topic_name" default="/sensing/lidar/top/self_cropped/pointcloud_ex"/>
5+
<arg name="input_frame" default="base_link"/>
6+
<arg name="output_frame" default="base_link"/>
7+
<arg name="input_pointcloud_frame" default="velodyne_top_base_link"/>
8+
<arg name="crop_box_filter_param_file" default="$(find-pkg-share autoware_crop_box_filter)/config/crop_box_filter_node.param.yaml"/>
9+
<node pkg="autoware_crop_box_filter" exec="crop_box_filter" name="crop_box_filter">
10+
<param from="$(var crop_box_filter_param_file)"/>
11+
<remap from="input" to="$(var input_topic_name)"/>
12+
<remap from="output" to="$(var output_topic_name)"/>
13+
<param name="input_pointcloud_frame" value="$(var input_pointcloud_frame)"/>
14+
<param name="input_frame" value="$(var input_frame)"/>
15+
<param name="output_frame" value="$(var output_frame)"/>
16+
</node>
17+
</launch>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>autoware_crop_box_filter</name>
5+
<version>0.0.0</version>
6+
<description>The ROS 2 autoware_crop_box_filter package</description>
7+
<maintainer email="abrahammonrroy@yahoo.com">amc-nu</maintainer>
8+
<maintainer email="yukihiro.saito@tier4.jp">Yukihiro Saito</maintainer>
9+
<maintainer email="kyoichi.sugahara@tier4.jp">Kyoichi Sugahara</maintainer>
10+
<maintainer email="dai.nguyen@tier4.jp">Dai Nguyen</maintainer>
11+
<maintainer email="kenzo.lobos@tier4.jp">Kenzo Lobos-Tsunekawa</maintainer>
12+
<maintainer email="yihsiang.fang@tier4.jp">Yihsiang Fang</maintainer>
13+
<maintainer email="yoshi.ri@tier4.jp">Yoshi Ri</maintainer>
14+
<maintainer email="david.wong@tier4.jp">David Wong</maintainer>
15+
<maintainer email="melike@leodrive.ai">Melike Tanrikulu</maintainer>
16+
<maintainer email="max.schmeller@tier4.jp">Max Schmeller</maintainer>
17+
<maintainer email="lxg19892021@gmail.com">Xingang Liu</maintainer>
18+
<license>Apache License 2.0</license>
19+
20+
<buildtool_depend>ament_cmake_auto</buildtool_depend>
21+
<buildtool_depend>autoware_cmake</buildtool_depend>
22+
23+
<depend>autoware_point_types</depend>
24+
<depend>autoware_utils</depend>
25+
<depend>geometry_msgs</depend>
26+
<depend>rclcpp</depend>
27+
<depend>rclcpp_components</depend>
28+
<depend>sensor_msgs</depend>
29+
30+
<test_depend>ament_lint_auto</test_depend>
31+
<test_depend>autoware_lint_common</test_depend>
32+
33+
<export>
34+
<build_type>ament_cmake</build_type>
35+
</export>
36+
</package>

0 commit comments

Comments
 (0)