Skip to content

Commit 65e903c

Browse files
feat(obstacle_stop): upd obstacle hunting (#1068)
* Adapted from PR #1458 Signed-off-by: Shigekazu Fukuta <shigekazu.fukuta@tier4.jp> * Adapted from PR #1627 Signed-off-by: Shigekazu Fukuta <shigekazu.fukuta@tier4.jp> * fix parameter name Signed-off-by: Shigekazu Fukuta <shigekazu.fukuta@tier4.jp> * Adapted from PR autowarefoundation#2647 Signed-off-by: Shigekazu Fukuta <shigekazu.fukuta@tier4.jp> * ci(pre-commit): autofix * fix build error * ci(pre-commit): autofix * remove comment line * remove logic * Delete parameters other than those added this time * ci(pre-commit): autofix * add stop vehicle check * ci(pre-commit): autofix * fix stop velocity threshold * fix engage obstacle clear and stop threshold * ci(pre-commit): autofix --------- Signed-off-by: Shigekazu Fukuta <shigekazu.fukuta@tier4.jp> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 861c01e commit 65e903c

File tree

4 files changed

+118
-34
lines changed

4 files changed

+118
-34
lines changed

planning/obstacle_stop_planner/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ When the deceleration section is inserted, the start point of the section is ins
3939

4040
## Modules
4141

42+
### Common Parameter
43+
44+
| Parameter | Type | Description |
45+
| ---------------------- | ------ | ----------------------------------------------------------------------------------------- |
46+
| `chattering_threshold` | double | even if the obstacle disappears, the stop judgment continues for chattering_threshold [s] |
47+
4248
### Obstacle Stop Planner
4349

4450
#### Role

planning/obstacle_stop_planner/config/obstacle_stop_planner.param.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/**:
22
ros__parameters:
3+
chattering_threshold: 0.5 # even if the obstacle disappears, the stop judgment continues for chattering_threshold [s]
4+
35
stop_planner:
46
stop_margin: 5.0 # stop margin distance from obstacle on the path [m]
57
min_behavior_stop_margin: 2.0 # stop margin distance when any other stop point is inserted in stop margin [m]

planning/obstacle_stop_planner/include/obstacle_stop_planner/node.hpp

+42-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include <map>
5858
#include <memory>
5959
#include <mutex>
60+
#include <utility>
6061
#include <vector>
6162

6263
namespace motion_planning
@@ -76,6 +77,8 @@ using tier4_planning_msgs::msg::VelocityLimit;
7677
using tier4_planning_msgs::msg::VelocityLimitClearCommand;
7778
using vehicle_info_util::VehicleInfo;
7879

80+
using PointCloud = pcl::PointCloud<pcl::PointXYZ>;
81+
7982
struct StopPoint
8083
{
8184
TrajectoryPoint point{};
@@ -91,6 +94,17 @@ struct SlowDownSection
9194
double velocity;
9295
};
9396

97+
struct ObstacleWithDetectionTime
98+
{
99+
explicit ObstacleWithDetectionTime(const rclcpp::Time & t, pcl::PointXYZ & p)
100+
: detection_time(t), point(p)
101+
{
102+
}
103+
104+
rclcpp::Time detection_time;
105+
pcl::PointXYZ point;
106+
};
107+
94108
class ObstacleStopPlannerNode : public rclcpp::Node
95109
{
96110
public:
@@ -101,7 +115,7 @@ class ObstacleStopPlannerNode : public rclcpp::Node
101115
bool enable_slow_down; // set True, slow down for obstacle beside the path
102116
double max_velocity; // max velocity [m/s]
103117
double lowpass_gain; // smoothing calculated current acceleration [-]
104-
double hunting_threshold; // keep slow down or stop state if obstacle vanished [s]
118+
double chattering_threshold; // keep slow down or stop state if obstacle vanished [s]
105119
double max_yaw_deviation_rad; // maximum ego yaw deviation from trajectory [rad] (measures
106120
// against overlapping lanes)
107121
};
@@ -184,12 +198,12 @@ class ObstacleStopPlannerNode : public rclcpp::Node
184198
std::unique_ptr<motion_planning::AdaptiveCruiseController> acc_controller_;
185199
std::shared_ptr<ObstacleStopPlannerDebugNode> debug_ptr_;
186200
std::shared_ptr<LowpassFilter1d> lpf_acc_{nullptr};
187-
boost::optional<SlowDownSection> latest_slow_down_section_{};
201+
boost::optional<SlowDownSection> latest_slow_down_section_{boost::none};
202+
std::vector<ObstacleWithDetectionTime> obstacle_history_{};
188203
tf2_ros::Buffer tf_buffer_{get_clock()};
189204
tf2_ros::TransformListener tf_listener_{tf_buffer_};
190205
sensor_msgs::msg::PointCloud2::SharedPtr obstacle_ros_pointcloud_ptr_{nullptr};
191206
PredictedObjects::ConstSharedPtr object_ptr_{nullptr};
192-
rclcpp::Time last_detection_time_;
193207

194208
nav_msgs::msg::Odometry::ConstSharedPtr current_velocity_ptr_{nullptr};
195209
nav_msgs::msg::Odometry::ConstSharedPtr prev_velocity_ptr_{nullptr};
@@ -305,6 +319,31 @@ class ObstacleStopPlannerNode : public rclcpp::Node
305319

306320
void publishDebugData(
307321
const PlannerData & planner_data, const double current_acc, const double current_vel);
322+
323+
void updateObstacleHistory(const rclcpp::Time & now, const double chattering_threshold)
324+
{
325+
for (auto itr = obstacle_history_.begin(); itr != obstacle_history_.end();) {
326+
const auto expired = (now - itr->detection_time).seconds() > chattering_threshold;
327+
328+
if (expired) {
329+
itr = obstacle_history_.erase(itr);
330+
continue;
331+
}
332+
333+
itr++;
334+
}
335+
}
336+
337+
PointCloud::Ptr getOldPointCloudPtr() const
338+
{
339+
PointCloud::Ptr ret(new PointCloud);
340+
341+
for (const auto & p : obstacle_history_) {
342+
ret->push_back(p.point);
343+
}
344+
345+
return ret;
346+
}
308347
};
309348
} // namespace motion_planning
310349

planning/obstacle_stop_planner/src/node.cpp

+68-31
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ using tier4_autoware_utils::createPoint;
4242
using tier4_autoware_utils::findNearestIndex;
4343
using tier4_autoware_utils::getRPY;
4444

45+
using PointCloud = pcl::PointCloud<pcl::PointXYZ>;
46+
4547
namespace
4648
{
4749
rclcpp::SubscriptionOptions createSubscriptionOptions(rclcpp::Node * node_ptr)
@@ -443,7 +445,7 @@ ObstacleStopPlannerNode::ObstacleStopPlannerNode(const rclcpp::NodeOptions & nod
443445
auto & p = node_param_;
444446
p.enable_slow_down = declare_parameter("enable_slow_down", false);
445447
p.max_velocity = declare_parameter("max_velocity", 20.0);
446-
p.hunting_threshold = declare_parameter("hunting_threshold", 0.5);
448+
p.chattering_threshold = declare_parameter("chattering_threshold", 0.5);
447449
p.lowpass_gain = declare_parameter("lowpass_gain", 0.9);
448450
lpf_acc_ = std::make_shared<LowpassFilter1d>(0.0, p.lowpass_gain);
449451
const double max_yaw_deviation_deg = declare_parameter("max_yaw_deviation_deg", 90.0);
@@ -503,7 +505,6 @@ ObstacleStopPlannerNode::ObstacleStopPlannerNode(const rclcpp::NodeOptions & nod
503505
acc_controller_ = std::make_unique<motion_planning::AdaptiveCruiseController>(
504506
this, i.vehicle_width_m, i.vehicle_length_m, i.max_longitudinal_offset_m);
505507
debug_ptr_ = std::make_shared<ObstacleStopPlannerDebugNode>(this, i.max_longitudinal_offset_m);
506-
last_detection_time_ = this->now();
507508

508509
// Publishers
509510
path_pub_ = this->create_publisher<Trajectory>("~/output/trajectory", 1);
@@ -632,9 +633,7 @@ void ObstacleStopPlannerNode::pathCallback(const Trajectory::ConstSharedPtr inpu
632633
current_vel, stop_param);
633634

634635
const auto no_slow_down_section = !planner_data.slow_down_require && !latest_slow_down_section_;
635-
const auto no_hunting = (rclcpp::Time(input_msg->header.stamp) - last_detection_time_).seconds() >
636-
node_param_.hunting_threshold;
637-
if (node_param_.enable_slow_down && no_slow_down_section && set_velocity_limit_ && no_hunting) {
636+
if (node_param_.enable_slow_down && no_slow_down_section && set_velocity_limit_) {
638637
resetExternalVelocityLimit(current_acc, current_vel);
639638
}
640639

@@ -662,6 +661,11 @@ void ObstacleStopPlannerNode::searchObstacle(
662661
return;
663662
}
664663

664+
const auto now = this->now();
665+
const bool is_stopping = (std::fabs(current_velocity_ptr->twist.twist.linear.x) < 0.001);
666+
const double history_erase_sec = (is_stopping) ? node_param_.chattering_threshold : 0.0;
667+
updateObstacleHistory(now, history_erase_sec);
668+
665669
for (size_t i = 0; i < decimate_trajectory.size() - 1; ++i) {
666670
// create one step circle center for vehicle
667671
const auto & p_front = decimate_trajectory.at(i).pose;
@@ -721,37 +725,79 @@ void ObstacleStopPlannerNode::searchObstacle(
721725
new pcl::PointCloud<pcl::PointXYZ>);
722726
collision_pointcloud_ptr->header = obstacle_candidate_pointcloud_ptr->header;
723727

724-
planner_data.found_collision_points = withinPolygon(
728+
const auto found_collision_points = withinPolygon(
725729
one_step_move_vehicle_polygon, stop_param.stop_search_radius, prev_center_point,
726730
next_center_point, slow_down_pointcloud_ptr, collision_pointcloud_ptr);
727731

728-
if (planner_data.found_collision_points) {
729-
planner_data.decimate_trajectory_collision_index = i;
732+
if (found_collision_points) {
733+
pcl::PointXYZ nearest_collision_point;
734+
rclcpp::Time nearest_collision_point_time;
730735
getNearestPoint(
731-
*collision_pointcloud_ptr, p_front, &planner_data.nearest_collision_point,
732-
&planner_data.nearest_collision_point_time);
736+
*collision_pointcloud_ptr, p_front, &nearest_collision_point,
737+
&nearest_collision_point_time);
733738

734-
debug_ptr_->pushObstaclePoint(planner_data.nearest_collision_point, PointType::Stop);
735-
debug_ptr_->pushPolygon(
736-
one_step_move_vehicle_polygon, p_front.position.z, PolygonType::Collision);
737-
738-
planner_data.stop_require = planner_data.found_collision_points;
739-
acc_controller_->insertAdaptiveCruiseVelocity(
740-
decimate_trajectory, planner_data.decimate_trajectory_collision_index,
741-
planner_data.current_pose, planner_data.nearest_collision_point,
742-
planner_data.nearest_collision_point_time, object_ptr, current_velocity_ptr,
743-
&planner_data.stop_require, &output, trajectory_header);
739+
obstacle_history_.emplace_back(now, nearest_collision_point);
744740

745741
break;
746742
}
747743
}
748744
}
745+
for (size_t i = 0; i < decimate_trajectory.size() - 1; ++i) {
746+
// create one step circle center for vehicle
747+
const auto & p_front = decimate_trajectory.at(i).pose;
748+
const auto & p_back = decimate_trajectory.at(i + 1).pose;
749+
const auto prev_center_pose = getVehicleCenterFromBase(p_front, vehicle_info);
750+
const Point2d prev_center_point(prev_center_pose.position.x, prev_center_pose.position.y);
751+
const auto next_center_pose = getVehicleCenterFromBase(p_back, vehicle_info);
752+
const Point2d next_center_point(next_center_pose.position.x, next_center_pose.position.y);
753+
std::vector<cv::Point2d> one_step_move_vehicle_polygon;
754+
// create one step polygon for vehicle
755+
createOneStepPolygon(
756+
p_front, p_back, one_step_move_vehicle_polygon, vehicle_info, stop_param.expand_stop_range);
757+
debug_ptr_->pushPolygon(
758+
one_step_move_vehicle_polygon, decimate_trajectory.at(i).pose.position.z,
759+
PolygonType::Vehicle);
760+
761+
PointCloud::Ptr collision_pointcloud_ptr(new PointCloud);
762+
collision_pointcloud_ptr->header = obstacle_candidate_pointcloud_ptr->header;
763+
764+
// check new collision points
765+
planner_data.found_collision_points = withinPolygon(
766+
one_step_move_vehicle_polygon, stop_param.stop_search_radius, prev_center_point,
767+
next_center_point, getOldPointCloudPtr(), collision_pointcloud_ptr);
768+
769+
if (planner_data.found_collision_points) {
770+
planner_data.decimate_trajectory_collision_index = i;
771+
getNearestPoint(
772+
*collision_pointcloud_ptr, p_front, &planner_data.nearest_collision_point,
773+
&planner_data.nearest_collision_point_time);
774+
775+
debug_ptr_->pushObstaclePoint(planner_data.nearest_collision_point, PointType::Stop);
776+
debug_ptr_->pushPolygon(
777+
one_step_move_vehicle_polygon, p_front.position.z, PolygonType::Collision);
778+
779+
planner_data.stop_require = planner_data.found_collision_points;
780+
781+
acc_controller_->insertAdaptiveCruiseVelocity(
782+
decimate_trajectory, planner_data.decimate_trajectory_collision_index,
783+
planner_data.current_pose, planner_data.nearest_collision_point,
784+
planner_data.nearest_collision_point_time, object_ptr, current_velocity_ptr,
785+
&planner_data.stop_require, &output, trajectory_header);
786+
787+
if (!planner_data.stop_require) {
788+
obstacle_history_.clear();
789+
}
790+
791+
break;
792+
}
793+
}
749794
}
750795

751796
void ObstacleStopPlannerNode::insertVelocity(
752797
TrajectoryPoints & output, PlannerData & planner_data,
753-
const std_msgs::msg::Header & trajectory_header, const VehicleInfo & vehicle_info,
754-
const double current_acc, const double current_vel, const StopParam & stop_param)
798+
[[maybe_unused]] const std_msgs::msg::Header & trajectory_header,
799+
const VehicleInfo & vehicle_info, const double current_acc, const double current_vel,
800+
const StopParam & stop_param)
755801
{
756802
if (output.size() < 3) {
757803
return;
@@ -799,17 +845,8 @@ void ObstacleStopPlannerNode::insertVelocity(
799845
index_with_dist_remain.get().second, dist_baselink_to_obstacle, vehicle_info, current_acc,
800846
current_vel);
801847

802-
if (
803-
!latest_slow_down_section_ &&
804-
dist_baselink_to_obstacle + index_with_dist_remain.get().second <
805-
vehicle_info.max_longitudinal_offset_m) {
806-
latest_slow_down_section_ = slow_down_section;
807-
}
808-
809848
insertSlowDownSection(slow_down_section, output);
810849
}
811-
812-
last_detection_time_ = trajectory_header.stamp;
813850
}
814851

815852
if (node_param_.enable_slow_down && latest_slow_down_section_) {

0 commit comments

Comments
 (0)