|
1 | 1 | // Copyright(c) 2025 AutoCore Technology (Nanjing) Co., Ltd. All rights reserved.
|
2 |
| - |
| 2 | +// |
3 | 3 | // Copyright 2024 TIER IV, Inc.
|
4 | 4 | //
|
5 | 5 | // Licensed under the Apache License, Version 2.0 (the "License");
|
|
52 | 52 | */
|
53 | 53 |
|
54 | 54 | #include "autoware/crop_box_filter/crop_box_filter_node.hpp"
|
55 |
| - |
56 |
| -#include <sensor_msgs/point_cloud2_iterator.hpp> |
57 |
| - |
58 | 55 | #include <memory>
|
59 | 56 | #include <vector>
|
| 57 | +#include <string> |
| 58 | +#include <utility> |
60 | 59 |
|
61 | 60 | namespace autoware::crop_box_filter
|
62 | 61 | {
|
@@ -191,32 +190,7 @@ CropBoxFilter::CropBoxFilter(const rclcpp::NodeOptions & node_options)
|
191 | 190 |
|
192 | 191 | void CropBoxFilter::pointcloud_callback(const PointCloud2ConstPtr cloud)
|
193 | 192 | {
|
194 |
| - // chechk if the pointcloud is valid |
195 |
| - if ( |
196 |
| - !is_data_layout_compatible_with_point_xyzircaedt(*cloud) && |
197 |
| - !is_data_layout_compatible_with_point_xyzirc(*cloud)) |
198 |
| - { |
199 |
| - RCLCPP_ERROR( |
200 |
| - get_logger(), |
201 |
| - "The pointcloud layout is not compatible with PointXYZIRCAEDT or PointXYZIRC. Aborting"); |
202 |
| - |
203 |
| - if (is_data_layout_compatible_with_point_xyziradrt(*cloud)) { |
204 |
| - RCLCPP_ERROR( |
205 |
| - get_logger(), |
206 |
| - "The pointcloud layout is compatible with PointXYZIRADRT. You may be using legacy " |
207 |
| - "code/data"); |
208 |
| - } |
209 |
| - |
210 |
| - if (is_data_layout_compatible_with_point_xyzi(*cloud)) { |
211 |
| - RCLCPP_ERROR( |
212 |
| - get_logger(), |
213 |
| - "The pointcloud layout is compatible with PointXYZI. You may be using legacy " |
214 |
| - "code/data"); |
215 |
| - } |
216 |
| - |
217 |
| - return; |
218 |
| - } |
219 |
| - |
| 193 | + // check whether the pointcloud is valid |
220 | 194 | if (!is_valid(cloud)) {
|
221 | 195 | RCLCPP_ERROR(this->get_logger(), "[input_pointcloud_callback] Invalid input pointcloud!");
|
222 | 196 | return;
|
@@ -249,27 +223,30 @@ void CropBoxFilter::pointcloud_callback(const PointCloud2ConstPtr cloud)
|
249 | 223 | for (size_t global_offset = 0; global_offset + cloud->point_step <= cloud->data.size();
|
250 | 224 | global_offset += cloud->point_step)
|
251 | 225 | {
|
| 226 | + // extract point data from point cloud data buffer |
252 | 227 | Eigen::Vector4f point;
|
253 |
| - Eigen::Vector4f point_preprocessed; |
| 228 | + |
254 | 229 | std::memcpy(&point[0], &cloud->data[global_offset + x_offset], sizeof(float));
|
255 | 230 | std::memcpy(&point[1], &cloud->data[global_offset + y_offset], sizeof(float));
|
256 | 231 | std::memcpy(&point[2], &cloud->data[global_offset + z_offset], sizeof(float));
|
257 | 232 | point[3] = 1;
|
258 |
| - point_preprocessed[3] = 1; |
259 | 233 |
|
260 | 234 | if (!std::isfinite(point[0]) || !std::isfinite(point[1]) || !std::isfinite(point[2])) {
|
261 | 235 | skipped_count++;
|
262 | 236 | continue;
|
263 | 237 | }
|
264 | 238 |
|
| 239 | + // preprocess point for filtering |
| 240 | + Eigen::Vector4f point_preprocessed = point; |
| 241 | + |
265 | 242 | // apply pre-transform if needed
|
266 | 243 | if (need_preprocess_transform_) {
|
267 | 244 | point_preprocessed = eigen_transform_preprocess_ * point;
|
268 | 245 | }
|
269 | 246 |
|
270 |
| - bool point_is_inside = point[2] > param_.min_z && point[2] < param_.max_z && |
271 |
| - point[1] > param_.min_y && point[1] < param_.max_y && |
272 |
| - point[0] > param_.min_x && point[0] < param_.max_x; |
| 247 | + bool point_is_inside = point_preprocessed[2] > param_.min_z && point_preprocessed[2] < param_.max_z && |
| 248 | + point_preprocessed[1] > param_.min_y && point_preprocessed[1] < param_.max_y && |
| 249 | + point_preprocessed[0] > param_.min_x && point_preprocessed[0] < param_.max_x; |
273 | 250 | if ((!param_.negative && point_is_inside) || (param_.negative && !point_is_inside)) {
|
274 | 251 |
|
275 | 252 | // apply post-transform if needed
|
@@ -627,6 +604,33 @@ bool CropBoxFilter::is_data_layout_compatible_with_point_xyzircaedt(const PointC
|
627 | 604 |
|
628 | 605 | bool CropBoxFilter::is_valid( const PointCloud2ConstPtr & cloud)
|
629 | 606 | {
|
| 607 | + // firstly check the fields of the point cloud |
| 608 | + if ( |
| 609 | + !is_data_layout_compatible_with_point_xyzircaedt(*cloud) && |
| 610 | + !is_data_layout_compatible_with_point_xyzirc(*cloud)) |
| 611 | + { |
| 612 | + RCLCPP_ERROR( |
| 613 | + get_logger(), |
| 614 | + "The pointcloud layout is not compatible with PointXYZIRCAEDT or PointXYZIRC. Aborting"); |
| 615 | + |
| 616 | + if (is_data_layout_compatible_with_point_xyziradrt(*cloud)) { |
| 617 | + RCLCPP_ERROR( |
| 618 | + get_logger(), |
| 619 | + "The pointcloud layout is compatible with PointXYZIRADRT. You may be using legacy " |
| 620 | + "code/data"); |
| 621 | + } |
| 622 | + |
| 623 | + if (is_data_layout_compatible_with_point_xyzi(*cloud)) { |
| 624 | + RCLCPP_ERROR( |
| 625 | + get_logger(), |
| 626 | + "The pointcloud layout is compatible with PointXYZI. You may be using legacy " |
| 627 | + "code/data"); |
| 628 | + } |
| 629 | + |
| 630 | + return false; |
| 631 | + } |
| 632 | + |
| 633 | + // secondly, verify the total size of the point cloud |
630 | 634 | if (cloud->width * cloud->height * cloud->point_step != cloud->data.size()) {
|
631 | 635 | RCLCPP_WARN(
|
632 | 636 | this->get_logger(),
|
|
0 commit comments