Skip to content

Commit 3d77938

Browse files
feat(autoware_motion_velocity_obstacle_<stop/slow_down>_module): brings Point Cloud handling to this module (autowarefoundation#10112)
pointcloud handling for slowdown and stop module Signed-off-by: Arjun Jagdish Ram <arjun.ram@tier4.jp>
1 parent 4dd4d88 commit 3d77938

File tree

12 files changed

+557
-20
lines changed

12 files changed

+557
-20
lines changed

planning/motion_velocity_planner/autoware_motion_velocity_obstacle_slow_down_module/config/obstacle_slow_down.param.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
pedestrian: true
4343
pointcloud: false
4444

45+
pointcloud:
46+
pointcloud_voxel_grid_x: 0.05
47+
pointcloud_voxel_grid_y: 0.05
48+
pointcloud_voxel_grid_z: 100000.0
49+
pointcloud_cluster_tolerance: 1.0
50+
pointcloud_min_cluster_size: 1
51+
pointcloud_max_cluster_size: 100000
52+
4553
min_lat_margin: 0.0 # lateral margin between obstacle and trajectory band with ego's width to avoid the conflict with the obstacle_stop
4654
max_lat_margin: 1.1 # lateral margin between obstacle and trajectory band with ego's width
4755
lat_hysteresis_margin: 0.2

planning/motion_velocity_planner/autoware_motion_velocity_obstacle_slow_down_module/src/obstacle_slow_down_module.cpp

+177-1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,94 @@ void ObstacleSlowDownModule::update_parameters(
231231
{
232232
}
233233

234+
std::vector<autoware::motion_velocity_planner::SlowDownPointData>
235+
ObstacleSlowDownModule::convert_point_cloud_to_slow_down_points(
236+
const PlannerData::Pointcloud & pointcloud, const std::vector<TrajectoryPoint> & traj_points,
237+
const VehicleInfo & vehicle_info, const size_t ego_idx)
238+
{
239+
if (pointcloud.pointcloud.empty()) {
240+
return {};
241+
}
242+
243+
autoware::universe_utils::ScopedTimeTrack st(__func__, *time_keeper_);
244+
245+
const auto & p = obstacle_filtering_param_;
246+
247+
std::vector<autoware::motion_velocity_planner::SlowDownPointData> slow_down_points;
248+
249+
// 1. transform pointcloud
250+
pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud_ptr =
251+
std::make_shared<pcl::PointCloud<pcl::PointXYZ>>(pointcloud.pointcloud);
252+
// 2. downsample & cluster pointcloud
253+
PointCloud::Ptr filtered_points_ptr(new PointCloud);
254+
pcl::VoxelGrid<pcl::PointXYZ> filter;
255+
filter.setInputCloud(pointcloud_ptr);
256+
filter.setLeafSize(
257+
p.pointcloud_obstacle_filtering_param.pointcloud_voxel_grid_x,
258+
p.pointcloud_obstacle_filtering_param.pointcloud_voxel_grid_y,
259+
p.pointcloud_obstacle_filtering_param.pointcloud_voxel_grid_z);
260+
filter.filter(*filtered_points_ptr);
261+
262+
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
263+
tree->setInputCloud(filtered_points_ptr);
264+
std::vector<pcl::PointIndices> clusters;
265+
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
266+
ec.setClusterTolerance(p.pointcloud_obstacle_filtering_param.pointcloud_cluster_tolerance);
267+
ec.setMinClusterSize(p.pointcloud_obstacle_filtering_param.pointcloud_min_cluster_size);
268+
ec.setMaxClusterSize(p.pointcloud_obstacle_filtering_param.pointcloud_max_cluster_size);
269+
ec.setSearchMethod(tree);
270+
ec.setInputCloud(filtered_points_ptr);
271+
ec.extract(clusters);
272+
273+
// 3. convert clusters to obstacles
274+
for (const auto & cluster_indices : clusters) {
275+
double ego_to_slow_down_front_collision_distance = std::numeric_limits<double>::max();
276+
double ego_to_slow_down_back_collision_distance = std::numeric_limits<double>::min();
277+
double lat_dist_from_obstacle_to_traj = std::numeric_limits<double>::max();
278+
std::optional<geometry_msgs::msg::Point> slow_down_front_collision_point = std::nullopt;
279+
std::optional<geometry_msgs::msg::Point> slow_down_back_collision_point = std::nullopt;
280+
281+
for (const auto & index : cluster_indices.indices) {
282+
const auto obstacle_point = autoware::motion_velocity_planner::utils::to_geometry_point(
283+
filtered_points_ptr->points[index]);
284+
const auto current_lat_dist_from_obstacle_to_traj =
285+
autoware::motion_utils::calcLateralOffset(traj_points, obstacle_point);
286+
const auto min_lat_dist_to_traj_poly =
287+
std::abs(current_lat_dist_from_obstacle_to_traj) - vehicle_info.vehicle_width_m;
288+
289+
if (min_lat_dist_to_traj_poly >= p.max_lat_margin) {
290+
continue;
291+
}
292+
293+
const auto current_ego_to_obstacle_distance =
294+
autoware::motion_velocity_planner::utils::calc_distance_to_front_object(
295+
traj_points, ego_idx, obstacle_point);
296+
if (!current_ego_to_obstacle_distance) {
297+
continue;
298+
}
299+
300+
lat_dist_from_obstacle_to_traj =
301+
std::min(lat_dist_from_obstacle_to_traj, current_lat_dist_from_obstacle_to_traj);
302+
303+
if (*current_ego_to_obstacle_distance < ego_to_slow_down_front_collision_distance) {
304+
slow_down_front_collision_point = obstacle_point;
305+
ego_to_slow_down_front_collision_distance = *current_ego_to_obstacle_distance;
306+
} else if (*current_ego_to_obstacle_distance > ego_to_slow_down_back_collision_distance) {
307+
slow_down_back_collision_point = obstacle_point;
308+
ego_to_slow_down_back_collision_distance = *current_ego_to_obstacle_distance;
309+
}
310+
}
311+
312+
if (slow_down_front_collision_point) {
313+
slow_down_points.emplace_back(
314+
slow_down_front_collision_point, slow_down_back_collision_point,
315+
lat_dist_from_obstacle_to_traj);
316+
}
317+
}
318+
319+
return slow_down_points;
320+
}
321+
234322
VelocityPlanningResult ObstacleSlowDownModule::plan(
235323
const std::vector<autoware_planning_msgs::msg::TrajectoryPoint> & raw_trajectory_points,
236324
[[maybe_unused]] const std::vector<autoware_planning_msgs::msg::TrajectoryPoint> &
@@ -249,12 +337,22 @@ VelocityPlanningResult ObstacleSlowDownModule::plan(
249337
planner_data->ego_nearest_dist_threshold, planner_data->ego_nearest_yaw_threshold,
250338
planner_data->trajectory_polygon_collision_check.decimate_trajectory_step_length, 0.0);
251339

252-
const auto slow_down_obstacles = filter_slow_down_obstacle_for_predicted_object(
340+
auto slow_down_obstacles_for_predicted_object = filter_slow_down_obstacle_for_predicted_object(
253341
planner_data->current_odometry, planner_data->ego_nearest_dist_threshold,
254342
planner_data->ego_nearest_yaw_threshold, raw_trajectory_points, decimated_traj_points,
255343
planner_data->objects, rclcpp::Time(planner_data->predicted_objects_header.stamp),
256344
planner_data->vehicle_info_, planner_data->trajectory_polygon_collision_check);
257345

346+
auto slow_down_obstacles_for_point_cloud = filter_slow_down_obstacle_for_point_cloud(
347+
planner_data->current_odometry, raw_trajectory_points, decimated_traj_points,
348+
planner_data->no_ground_pointcloud, planner_data->vehicle_info_,
349+
planner_data->trajectory_polygon_collision_check,
350+
planner_data->find_index(raw_trajectory_points, planner_data->current_odometry.pose.pose));
351+
352+
const auto slow_down_obstacles = autoware::motion_velocity_planner::utils::concat_vectors(
353+
std::move(slow_down_obstacles_for_predicted_object),
354+
std::move(slow_down_obstacles_for_point_cloud));
355+
258356
VelocityPlanningResult result;
259357
result.slowdown_intervals = plan_slow_down(
260358
planner_data, raw_trajectory_points, slow_down_obstacles, result.velocity_limit,
@@ -348,6 +446,53 @@ ObstacleSlowDownModule::filter_slow_down_obstacle_for_predicted_object(
348446
return slow_down_obstacles;
349447
}
350448

449+
std::vector<SlowDownObstacle> ObstacleSlowDownModule::filter_slow_down_obstacle_for_point_cloud(
450+
const Odometry & odometry, const std::vector<TrajectoryPoint> & traj_points,
451+
const std::vector<TrajectoryPoint> & decimated_traj_points,
452+
const PlannerData::Pointcloud & point_cloud, const VehicleInfo & vehicle_info,
453+
const TrajectoryPolygonCollisionCheck & trajectory_polygon_collision_check, size_t ego_idx)
454+
{
455+
autoware::universe_utils::ScopedTimeTrack st(__func__, *time_keeper_);
456+
457+
// calculate collision points with trajectory with lateral stop margin
458+
// NOTE: For additional margin, hysteresis is not divided by two.
459+
const auto & p = obstacle_filtering_param_;
460+
const auto & tp = trajectory_polygon_collision_check;
461+
const auto decimated_traj_polys_with_lat_margin = polygon_utils::create_one_step_polygons(
462+
decimated_traj_points, vehicle_info, odometry.pose.pose,
463+
p.max_lat_margin + p.lat_hysteresis_margin, tp.enable_to_consider_current_pose,
464+
tp.time_to_convergence, tp.decimate_trajectory_step_length);
465+
debug_data_ptr_->decimated_traj_polys = decimated_traj_polys_with_lat_margin;
466+
467+
// Get Objects
468+
const std::vector<autoware::motion_velocity_planner::SlowDownPointData> slow_down_points_data =
469+
convert_point_cloud_to_slow_down_points(point_cloud, traj_points, vehicle_info, ego_idx);
470+
471+
// slow down
472+
std::vector<SlowDownObstacle> slow_down_obstacles;
473+
for (const auto & slow_down_point_data : slow_down_points_data) {
474+
if (!slow_down_point_data.front) {
475+
continue;
476+
}
477+
const auto & front_collision_point = *slow_down_point_data.front;
478+
const auto & back_collision_point = slow_down_point_data.back.value_or(front_collision_point);
479+
480+
const auto slow_down_obstacle = create_slow_down_obstacle_for_point_cloud(
481+
rclcpp::Time(point_cloud.pointcloud.header.stamp), front_collision_point,
482+
back_collision_point, slow_down_point_data.lat_dist_to_traj);
483+
484+
if (slow_down_obstacle) {
485+
slow_down_obstacles.push_back(*slow_down_obstacle);
486+
continue;
487+
}
488+
}
489+
490+
RCLCPP_DEBUG(
491+
logger_, "The number of output obstacles of filter_slow_down_obstacles is %ld",
492+
slow_down_obstacles.size());
493+
return slow_down_obstacles;
494+
}
495+
351496
std::optional<SlowDownObstacle>
352497
ObstacleSlowDownModule::create_slow_down_obstacle_for_predicted_object(
353498
const std::vector<TrajectoryPoint> & traj_points,
@@ -485,6 +630,37 @@ ObstacleSlowDownModule::create_slow_down_obstacle_for_predicted_object(
485630
back_collision_point};
486631
}
487632

633+
std::optional<SlowDownObstacle> ObstacleSlowDownModule::create_slow_down_obstacle_for_point_cloud(
634+
const rclcpp::Time & stamp, const geometry_msgs::msg::Point & front_collision_point,
635+
const geometry_msgs::msg::Point & back_collision_point, const double lat_dist_to_traj)
636+
{
637+
if (!obstacle_filtering_param_.use_pointcloud) {
638+
return std::nullopt;
639+
}
640+
const unique_identifier_msgs::msg::UUID obj_uuid;
641+
const auto & obj_uuid_str = autoware::universe_utils::toHexString(obj_uuid);
642+
643+
ObjectClassification unknown_object_classification;
644+
unknown_object_classification.label = ObjectClassification::UNKNOWN;
645+
unknown_object_classification.probability = 1.0;
646+
647+
const geometry_msgs::msg::Pose unconfigured_pose;
648+
649+
const double unconfigured_lon_velocity = 0.;
650+
const double unconfigured_lat_velocity = 0.;
651+
652+
return SlowDownObstacle{
653+
obj_uuid_str,
654+
stamp,
655+
unknown_object_classification,
656+
unconfigured_pose,
657+
unconfigured_lon_velocity,
658+
unconfigured_lat_velocity,
659+
lat_dist_to_traj,
660+
front_collision_point,
661+
back_collision_point};
662+
}
663+
488664
std::vector<SlowdownInterval> ObstacleSlowDownModule::plan_slow_down(
489665
const std::shared_ptr<const PlannerData> planner_data,
490666
const std::vector<TrajectoryPoint> & traj_points, const std::vector<SlowDownObstacle> & obstacles,

planning/motion_velocity_planner/autoware_motion_velocity_obstacle_slow_down_module/src/obstacle_slow_down_module.hpp

+21
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@
2828
#include <autoware/motion_velocity_planner_common_universe/velocity_planning_result.hpp>
2929
#include <autoware/objects_of_interest_marker_interface/objects_of_interest_marker_interface.hpp>
3030
#include <rclcpp/rclcpp.hpp>
31+
#include <tf2_eigen/tf2_eigen.hpp>
32+
33+
#include <pcl/common/transforms.h>
34+
#include <pcl/filters/voxel_grid.h>
35+
#include <pcl/kdtree/kdtree_flann.h>
36+
#include <pcl/segmentation/euclidean_cluster_comparator.h>
37+
#include <pcl/segmentation/extract_clusters.h>
38+
#include <pcl_conversions/pcl_conversions.h>
39+
#include <tf2_ros/buffer.h>
3140

3241
#include <algorithm>
3342
#include <iostream>
@@ -82,18 +91,30 @@ class ObstacleSlowDownModule : public PluginModuleInterface
8291
mutable std::shared_ptr<universe_utils::TimeKeeper> time_keeper_;
8392
mutable std::optional<std::vector<Polygon2d>> decimated_traj_polys_{std::nullopt};
8493

94+
std::vector<autoware::motion_velocity_planner::SlowDownPointData>
95+
convert_point_cloud_to_slow_down_points(
96+
const PlannerData::Pointcloud & pointcloud, const std::vector<TrajectoryPoint> & traj_points,
97+
const VehicleInfo & vehicle_info, const size_t ego_idx);
8598
std::vector<SlowDownObstacle> filter_slow_down_obstacle_for_predicted_object(
8699
const Odometry & odometry, const double ego_nearest_dist_threshold,
87100
const double ego_nearest_yaw_threshold, const std::vector<TrajectoryPoint> & traj_points,
88101
const std::vector<TrajectoryPoint> & decimated_traj_points,
89102
const std::vector<std::shared_ptr<PlannerData::Object>> & objects,
90103
const rclcpp::Time & predicted_objects_stamp, const VehicleInfo & vehicle_info,
91104
const TrajectoryPolygonCollisionCheck & trajectory_polygon_collision_check);
105+
std::vector<SlowDownObstacle> filter_slow_down_obstacle_for_point_cloud(
106+
const Odometry & odometry, const std::vector<TrajectoryPoint> & traj_points,
107+
const std::vector<TrajectoryPoint> & decimated_traj_points,
108+
const PlannerData::Pointcloud & point_cloud, const VehicleInfo & vehicle_info,
109+
const TrajectoryPolygonCollisionCheck & trajectory_polygon_collision_check, size_t ego_idx);
92110
std::optional<SlowDownObstacle> create_slow_down_obstacle_for_predicted_object(
93111
const std::vector<TrajectoryPoint> & traj_points,
94112
const std::vector<Polygon2d> & decimated_traj_polys_with_lat_margin,
95113
const std::shared_ptr<PlannerData::Object> object, const rclcpp::Time & predicted_objects_stamp,
96114
const double dist_from_obj_poly_to_traj_poly);
115+
std::optional<SlowDownObstacle> create_slow_down_obstacle_for_point_cloud(
116+
const rclcpp::Time & stamp, const geometry_msgs::msg::Point & front_collision_point,
117+
const geometry_msgs::msg::Point & back_collision_point, const double lat_dist_to_traj);
97118
std::vector<SlowdownInterval> plan_slow_down(
98119
const std::shared_ptr<const PlannerData> planner_data,
99120
const std::vector<TrajectoryPoint> & traj_points,

planning/motion_velocity_planner/autoware_motion_velocity_obstacle_slow_down_module/src/parameters.hpp

+32
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef PARAMETERS_HPP_
1616
#define PARAMETERS_HPP_
1717

18+
#include "autoware/motion_utils/trajectory/conversion.hpp"
1819
#include "type_alias.hpp"
1920
#include "types.hpp"
2021

@@ -55,10 +56,24 @@ struct CommonParam
5556

5657
struct ObstacleFilteringParam
5758
{
59+
struct PointcloudObstacleFilteringParam
60+
{
61+
double pointcloud_voxel_grid_x{};
62+
double pointcloud_voxel_grid_y{};
63+
double pointcloud_voxel_grid_z{};
64+
double pointcloud_cluster_tolerance{};
65+
double pointcloud_min_cluster_size{};
66+
double pointcloud_max_cluster_size{};
67+
};
68+
69+
PointcloudObstacleFilteringParam pointcloud_obstacle_filtering_param;
5870
std::vector<uint8_t> object_types{};
5971

72+
bool use_pointcloud{false};
73+
6074
double min_lat_margin{};
6175
double max_lat_margin{};
76+
6277
double lat_hysteresis_margin{};
6378

6479
int successive_num_to_entry_slow_down_condition{};
@@ -67,18 +82,35 @@ struct ObstacleFilteringParam
6782
ObstacleFilteringParam() = default;
6883
explicit ObstacleFilteringParam(rclcpp::Node & node)
6984
{
85+
use_pointcloud = getOrDeclareParameter<bool>(
86+
node, "obstacle_slow_down.obstacle_filtering.object_type.pointcloud");
7087
object_types =
7188
utils::get_target_object_type(node, "obstacle_slow_down.obstacle_filtering.object_type.");
7289
min_lat_margin =
7390
getOrDeclareParameter<double>(node, "obstacle_slow_down.obstacle_filtering.min_lat_margin");
7491
max_lat_margin =
7592
getOrDeclareParameter<double>(node, "obstacle_slow_down.obstacle_filtering.max_lat_margin");
93+
7694
lat_hysteresis_margin = getOrDeclareParameter<double>(
7795
node, "obstacle_slow_down.obstacle_filtering.lat_hysteresis_margin");
7896
successive_num_to_entry_slow_down_condition = getOrDeclareParameter<int>(
7997
node, "obstacle_slow_down.obstacle_filtering.successive_num_to_entry_slow_down_condition");
8098
successive_num_to_exit_slow_down_condition = getOrDeclareParameter<int>(
8199
node, "obstacle_slow_down.obstacle_filtering.successive_num_to_exit_slow_down_condition");
100+
101+
pointcloud_obstacle_filtering_param.pointcloud_voxel_grid_x = getOrDeclareParameter<double>(
102+
node, "obstacle_slow_down.obstacle_filtering.pointcloud.pointcloud_voxel_grid_x");
103+
pointcloud_obstacle_filtering_param.pointcloud_voxel_grid_y = getOrDeclareParameter<double>(
104+
node, "obstacle_slow_down.obstacle_filtering.pointcloud.pointcloud_voxel_grid_y");
105+
pointcloud_obstacle_filtering_param.pointcloud_voxel_grid_z = getOrDeclareParameter<double>(
106+
node, "obstacle_slow_down.obstacle_filtering.pointcloud.pointcloud_voxel_grid_z");
107+
pointcloud_obstacle_filtering_param.pointcloud_cluster_tolerance =
108+
getOrDeclareParameter<double>(
109+
node, "obstacle_slow_down.obstacle_filtering.pointcloud.pointcloud_cluster_tolerance");
110+
pointcloud_obstacle_filtering_param.pointcloud_min_cluster_size = getOrDeclareParameter<int>(
111+
node, "obstacle_slow_down.obstacle_filtering.pointcloud.pointcloud_min_cluster_size");
112+
pointcloud_obstacle_filtering_param.pointcloud_max_cluster_size = getOrDeclareParameter<int>(
113+
node, "obstacle_slow_down.obstacle_filtering.pointcloud.pointcloud_max_cluster_size");
82114
}
83115
};
84116

planning/motion_velocity_planner/autoware_motion_velocity_obstacle_slow_down_module/src/types.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,28 @@
1818
#include "type_alias.hpp"
1919

2020
#include <algorithm>
21+
#include <optional>
2122
#include <string>
2223
#include <unordered_map>
2324
#include <vector>
2425

2526
namespace autoware::motion_velocity_planner
2627
{
28+
29+
struct SlowDownPointData
30+
{
31+
std::optional<geometry_msgs::msg::Point> front{std::nullopt};
32+
std::optional<geometry_msgs::msg::Point> back{std::nullopt};
33+
34+
double lat_dist_to_traj{0};
35+
36+
SlowDownPointData(
37+
const std::optional<geometry_msgs::msg::Point> & front_point,
38+
const std::optional<geometry_msgs::msg::Point> & back_point, double lat_dist_to_traj)
39+
: front(front_point), back(back_point), lat_dist_to_traj(lat_dist_to_traj)
40+
{
41+
}
42+
};
2743
struct SlowDownObstacle
2844
{
2945
SlowDownObstacle(

planning/motion_velocity_planner/autoware_motion_velocity_obstacle_stop_module/config/obstacle_stop.param.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@
5454
bicycle: false
5555
pedestrian: false
5656

57+
pointcloud:
58+
pointcloud_voxel_grid_x: 0.05
59+
pointcloud_voxel_grid_y: 0.05
60+
pointcloud_voxel_grid_z: 100000.0
61+
pointcloud_cluster_tolerance: 1.0
62+
pointcloud_min_cluster_size: 1
63+
pointcloud_max_cluster_size: 100000
64+
5765
# hysteresis for velocity
5866
obstacle_velocity_threshold_to_stop : 3.0 # stop planning is executed to the obstacle whose velocity is less than this value [m/s]
5967
obstacle_velocity_threshold_from_stop : 3.5 # stop planning is executed to the obstacle whose velocity is less than this value [m/s]

0 commit comments

Comments
 (0)