Skip to content

Commit d8826bb

Browse files
feat(obstacle_cruise)!: type specified stop deccel limit and enabling abandon to stop (#1336)
* feat(obstacle_cruise_planner): add calculation of obstacle distance to ego (autowarefoundation#6057) Add the arc length from the ego to the obstacle stop point to the stop_reasons topic. Signed-off-by: Ioannis Souflas <isouflas@gmail.com> * refactor(obstacle_cruise): refactor a function checkConsistency() (autowarefoundation#7105) refactor Signed-off-by: Yuki Takagi <yuki.takagi@tier4.jp> * add abandon function Signed-off-by: Yuki Takagi <yuki.takagi@tier4.jp> * fix lib include Signed-off-by: Yuki Takagi <yuki.takagi@tier4.jp> --------- Signed-off-by: Ioannis Souflas <isouflas@gmail.com> Signed-off-by: Yuki Takagi <yuki.takagi@tier4.jp> Co-authored-by: Ioannis Souflas <isouflas@gmail.com>
1 parent 8aa0062 commit d8826bb

File tree

8 files changed

+275
-168
lines changed

8 files changed

+275
-168
lines changed

planning/obstacle_cruise_planner/config/obstacle_cruise_planner.param.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,15 @@
210210
lpf_gain_slow_down_vel: 0.99 # low-pass filter gain for slow down velocity
211211
lpf_gain_lat_dist: 0.999 # low-pass filter gain for lateral distance from obstacle to ego's path
212212
lpf_gain_dist_to_slow_down: 0.7 # low-pass filter gain for distance to slow down start
213+
stop:
214+
type_specified_params:
215+
labels: # For the listed types, the node try to read the following type specified values
216+
- "default"
217+
- "unknown"
218+
# default: For the default type, which denotes the other types listed above, the following param is defined implicitly, and the other type-specified parameters are not defined.
219+
# limit_min_acc: common_param.yaml/limit.min_acc
220+
unknown:
221+
limit_min_acc: -1.2 # overwrite the deceleration limit, in usually, common_param.yaml/limit.min_acc is referred.
222+
sudden_object_acc_threshold: -1.1 # If a stop can be achieved by a deceleration smaller than this value, it is not considered as “sudden stop".
223+
sudden_object_dist_threshold: 1000.0 # If a stop distance is longer than this value, it is not considered as “sudden stop".
224+
abandon_to_stop: false # If true, the planner gives up to stop when it cannot avoid to run over while maintaining the deceleration limit.

planning/obstacle_cruise_planner/include/obstacle_cruise_planner/common_structs.hpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,15 @@ struct StopObstacle : public TargetObstacleInterface
108108
{
109109
StopObstacle(
110110
const std::string & arg_uuid, const rclcpp::Time & arg_stamp,
111-
const geometry_msgs::msg::Pose & arg_pose, const Shape & arg_shape,
112-
const double arg_lon_velocity, const double arg_lat_velocity,
111+
const ObjectClassification & object_classification, const geometry_msgs::msg::Pose & arg_pose,
112+
const Shape & arg_shape, const double arg_lon_velocity, const double arg_lat_velocity,
113113
const geometry_msgs::msg::Point arg_collision_point,
114114
const double arg_dist_to_collide_on_decimated_traj)
115115
: TargetObstacleInterface(arg_uuid, arg_stamp, arg_pose, arg_lon_velocity, arg_lat_velocity),
116116
shape(arg_shape),
117117
collision_point(arg_collision_point),
118-
dist_to_collide_on_decimated_traj(arg_dist_to_collide_on_decimated_traj)
118+
dist_to_collide_on_decimated_traj(arg_dist_to_collide_on_decimated_traj),
119+
classification(object_classification)
119120
{
120121
}
121122
Shape shape;
@@ -124,6 +125,7 @@ struct StopObstacle : public TargetObstacleInterface
124125
// calculateMarginFromObstacleOnCurve() and should be removed as it can be
125126
// replaced by ”dist_to_collide_on_decimated_traj”
126127
double dist_to_collide_on_decimated_traj;
128+
ObjectClassification classification;
127129
};
128130

129131
struct CruiseObstacle : public TargetObstacleInterface

planning/obstacle_cruise_planner/include/obstacle_cruise_planner/node.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ class ObstacleCruisePlannerNode : public rclcpp::Node
263263
bool is_driving_forward_{true};
264264
bool enable_slow_down_planning_{false};
265265

266-
// previous closest obstacle
267-
std::shared_ptr<StopObstacle> prev_closest_stop_obstacle_ptr_{nullptr};
266+
std::vector<StopObstacle> prev_closest_stop_obstacles_{};
268267

269268
std::unique_ptr<tier4_autoware_utils::LoggerLevelConfigure> logger_configure_;
270269
};

planning/obstacle_cruise_planner/include/obstacle_cruise_planner/planner_interface.hpp

+83-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "tier4_autoware_utils/ros/update_param.hpp"
2424
#include "tier4_autoware_utils/system/stop_watch.hpp"
2525

26+
#include <algorithm>
27+
#include <limits>
2628
#include <memory>
2729
#include <optional>
2830
#include <string>
@@ -42,7 +44,8 @@ class PlannerInterface
4244
vehicle_info_(vehicle_info),
4345
ego_nearest_param_(ego_nearest_param),
4446
debug_data_ptr_(debug_data_ptr),
45-
slow_down_param_(SlowDownParam(node))
47+
slow_down_param_(SlowDownParam(node)),
48+
stop_param_(StopParam(node, longitudinal_info))
4649
{
4750
stop_reasons_pub_ = node.create_publisher<StopReasonArray>("~/output/stop_reasons", 1);
4851
velocity_factors_pub_ =
@@ -91,6 +94,7 @@ class PlannerInterface
9194
updateCommonParam(parameters);
9295
updateCruiseParam(parameters);
9396
slow_down_param_.onParam(parameters);
97+
stop_param_.onParam(parameters, longitudinal_info_);
9498
}
9599

96100
Float32MultiArrayStamped getStopPlanningDebugMessage(const rclcpp::Time & current_time) const
@@ -333,6 +337,84 @@ class PlannerInterface
333337
double lpf_gain_dist_to_slow_down;
334338
};
335339
SlowDownParam slow_down_param_;
340+
struct StopParam
341+
{
342+
struct ObstacleSpecificParams
343+
{
344+
double limit_min_acc;
345+
double sudden_object_acc_threshold;
346+
double sudden_object_dist_threshold;
347+
bool abandon_to_stop;
348+
};
349+
const std::unordered_map<uint8_t, std::string> types_maps = {
350+
{ObjectClassification::UNKNOWN, "unknown"}, {ObjectClassification::CAR, "car"},
351+
{ObjectClassification::TRUCK, "truck"}, {ObjectClassification::BUS, "bus"},
352+
{ObjectClassification::TRAILER, "trailer"}, {ObjectClassification::MOTORCYCLE, "motorcycle"},
353+
{ObjectClassification::BICYCLE, "bicycle"}, {ObjectClassification::PEDESTRIAN, "pedestrian"}};
354+
std::unordered_map<std::string, ObstacleSpecificParams> type_specified_param_list;
355+
explicit StopParam(rclcpp::Node & node, const LongitudinalInfo & longitudinal_info)
356+
{
357+
const std::string param_prefix = "stop.type_specified_params.";
358+
std::vector<std::string> obstacle_labels{"default"};
359+
obstacle_labels =
360+
node.declare_parameter<std::vector<std::string>>(param_prefix + "labels", obstacle_labels);
361+
362+
for (const auto & type_str : obstacle_labels) {
363+
if (type_str != "default") {
364+
ObstacleSpecificParams param{
365+
node.declare_parameter<double>(param_prefix + type_str + ".limit_min_acc"),
366+
node.declare_parameter<double>(
367+
param_prefix + type_str + ".sudden_object_acc_threshold"),
368+
node.declare_parameter<double>(
369+
param_prefix + type_str + ".sudden_object_dist_threshold"),
370+
node.declare_parameter<bool>(param_prefix + type_str + ".abandon_to_stop")};
371+
372+
param.sudden_object_acc_threshold =
373+
std::min(param.sudden_object_acc_threshold, longitudinal_info.limit_min_accel);
374+
param.limit_min_acc = std::min(param.limit_min_acc, param.sudden_object_acc_threshold);
375+
376+
type_specified_param_list.emplace(type_str, param);
377+
}
378+
}
379+
}
380+
void onParam(
381+
const std::vector<rclcpp::Parameter> & parameters, const LongitudinalInfo & longitudinal_info)
382+
{
383+
const std::string param_prefix = "stop.type_specified_params.";
384+
for (auto & [type_str, param] : type_specified_param_list) {
385+
if (type_str == "default") {
386+
continue;
387+
}
388+
tier4_autoware_utils::updateParam<double>(
389+
parameters, param_prefix + type_str + ".limit_min_acc", param.limit_min_acc);
390+
tier4_autoware_utils::updateParam<double>(
391+
parameters, param_prefix + type_str + ".sudden_object_acc_threshold",
392+
param.sudden_object_acc_threshold);
393+
tier4_autoware_utils::updateParam<double>(
394+
parameters, param_prefix + type_str + ".sudden_object_dist_threshold",
395+
param.sudden_object_dist_threshold);
396+
tier4_autoware_utils::updateParam<bool>(
397+
parameters, param_prefix + type_str + ".abandon_to_stop", param.abandon_to_stop);
398+
399+
param.sudden_object_acc_threshold =
400+
std::min(param.sudden_object_acc_threshold, longitudinal_info.limit_min_accel);
401+
param.limit_min_acc = std::min(param.limit_min_acc, param.sudden_object_acc_threshold);
402+
}
403+
}
404+
std::string getParamType(const ObjectClassification label)
405+
{
406+
const auto type_str = types_maps.at(label.label);
407+
if (type_specified_param_list.count(type_str) == 0) {
408+
return "default";
409+
}
410+
return type_str;
411+
}
412+
ObstacleSpecificParams getParam(const ObjectClassification label)
413+
{
414+
return type_specified_param_list.at(getParamType(label));
415+
}
416+
};
417+
StopParam stop_param_;
336418
double moving_object_speed_threshold;
337419
double moving_object_hysteresis_range;
338420
std::vector<SlowDownOutput> prev_slow_down_output_;

planning/obstacle_cruise_planner/include/obstacle_cruise_planner/utils.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ PoseWithStamp getCurrentObjectPose(
3636
const PredictedObject & predicted_object, const rclcpp::Time & obj_base_time,
3737
const rclcpp::Time & current_time, const bool use_prediction);
3838

39-
std::optional<StopObstacle> getClosestStopObstacle(
40-
const std::vector<StopObstacle> & stop_obstacles);
39+
std::vector<StopObstacle> getClosestStopObstacles(const std::vector<StopObstacle> & stop_obstacles);
4140

4241
template <class T>
4342
size_t getIndexWithLongitudinalOffset(

planning/obstacle_cruise_planner/src/node.cpp

+28-64
Original file line numberDiff line numberDiff line change
@@ -1073,9 +1073,9 @@ std::optional<StopObstacle> ObstacleCruisePlannerNode::createStopObstacle(
10731073
}
10741074

10751075
const auto [tangent_vel, normal_vel] = projectObstacleVelocityToTrajectory(traj_points, obstacle);
1076-
return StopObstacle{
1077-
obstacle.uuid, obstacle.stamp, obstacle.pose, obstacle.shape,
1078-
tangent_vel, normal_vel, collision_point->first, collision_point->second};
1076+
return StopObstacle{obstacle.uuid, obstacle.stamp, obstacle.classification,
1077+
obstacle.pose, obstacle.shape, tangent_vel,
1078+
normal_vel, collision_point->first, collision_point->second};
10791079
}
10801080

10811081
std::optional<SlowDownObstacle> ObstacleCruisePlannerNode::createSlowDownObstacle(
@@ -1245,72 +1245,36 @@ void ObstacleCruisePlannerNode::checkConsistency(
12451245
const rclcpp::Time & current_time, const PredictedObjects & predicted_objects,
12461246
std::vector<StopObstacle> & stop_obstacles)
12471247
{
1248-
const auto current_closest_stop_obstacle =
1249-
obstacle_cruise_utils::getClosestStopObstacle(stop_obstacles);
1250-
1251-
// If previous closest obstacle ptr is not set
1252-
if (!prev_closest_stop_obstacle_ptr_) {
1253-
if (current_closest_stop_obstacle) {
1254-
prev_closest_stop_obstacle_ptr_ =
1255-
std::make_shared<StopObstacle>(*current_closest_stop_obstacle);
1248+
for (const auto & prev_closest_stop_obstacle : prev_closest_stop_obstacles_) {
1249+
const auto predicted_object_itr = std::find_if(
1250+
predicted_objects.objects.begin(), predicted_objects.objects.end(),
1251+
[&prev_closest_stop_obstacle](const PredictedObject & po) {
1252+
return tier4_autoware_utils::toHexString(po.object_id) == prev_closest_stop_obstacle.uuid;
1253+
});
1254+
// If previous closest obstacle disappear from the perception result, do nothing anymore.
1255+
if (predicted_object_itr == predicted_objects.objects.end()) {
1256+
continue;
12561257
}
1257-
return;
1258-
}
1259-
1260-
// Put previous closest target obstacle if necessary
1261-
const auto predicted_object_itr = std::find_if(
1262-
predicted_objects.objects.begin(), predicted_objects.objects.end(),
1263-
[&](PredictedObject predicted_object) {
1264-
return tier4_autoware_utils::toHexString(predicted_object.object_id) ==
1265-
prev_closest_stop_obstacle_ptr_->uuid;
1266-
});
1267-
1268-
// If previous closest obstacle is not in the current perception lists
1269-
// just return the current target obstacles
1270-
if (predicted_object_itr == predicted_objects.objects.end()) {
1271-
return;
1272-
}
12731258

1274-
// Previous closest obstacle is in the perception lists
1275-
const auto obstacle_itr = std::find_if(
1276-
stop_obstacles.begin(), stop_obstacles.end(),
1277-
[&](const auto & obstacle) { return obstacle.uuid == prev_closest_stop_obstacle_ptr_->uuid; });
1278-
1279-
// Previous closest obstacle is both in the perception lists and target obstacles
1280-
if (obstacle_itr != stop_obstacles.end()) {
1281-
if (current_closest_stop_obstacle) {
1282-
if ((current_closest_stop_obstacle->uuid == prev_closest_stop_obstacle_ptr_->uuid)) {
1283-
// prev_closest_obstacle is current_closest_stop_obstacle just return the target
1284-
// obstacles(in target obstacles)
1285-
prev_closest_stop_obstacle_ptr_ =
1286-
std::make_shared<StopObstacle>(*current_closest_stop_obstacle);
1287-
} else {
1288-
// New obstacle becomes new stop obstacle
1289-
prev_closest_stop_obstacle_ptr_ =
1290-
std::make_shared<StopObstacle>(*current_closest_stop_obstacle);
1259+
const auto is_disappeared_from_stop_obstacle = std::none_of(
1260+
stop_obstacles.begin(), stop_obstacles.end(),
1261+
[&prev_closest_stop_obstacle](const StopObstacle & so) {
1262+
return so.uuid == prev_closest_stop_obstacle.uuid;
1263+
});
1264+
if (is_disappeared_from_stop_obstacle) {
1265+
// re-evaluate as a stop candidate, and overwrite the current decision if "maintain stop"
1266+
// condition is satisfied
1267+
const double elapsed_time = (current_time - prev_closest_stop_obstacle.stamp).seconds();
1268+
if (
1269+
predicted_object_itr->kinematics.initial_twist_with_covariance.twist.linear.x <
1270+
behavior_determination_param_.obstacle_velocity_threshold_from_stop_to_cruise &&
1271+
elapsed_time < behavior_determination_param_.stop_obstacle_hold_time_threshold) {
1272+
stop_obstacles.push_back(prev_closest_stop_obstacle);
12911273
}
1292-
} else {
1293-
// Previous closest stop obstacle becomes cruise obstacle
1294-
prev_closest_stop_obstacle_ptr_ = nullptr;
1295-
}
1296-
} else {
1297-
// prev obstacle is not in the target obstacles, but in the perception list
1298-
const double elapsed_time = (current_time - prev_closest_stop_obstacle_ptr_->stamp).seconds();
1299-
if (
1300-
predicted_object_itr->kinematics.initial_twist_with_covariance.twist.linear.x <
1301-
behavior_determination_param_.obstacle_velocity_threshold_from_stop_to_cruise &&
1302-
elapsed_time < behavior_determination_param_.stop_obstacle_hold_time_threshold) {
1303-
stop_obstacles.push_back(*prev_closest_stop_obstacle_ptr_);
1304-
return;
1305-
}
1306-
1307-
if (current_closest_stop_obstacle) {
1308-
prev_closest_stop_obstacle_ptr_ =
1309-
std::make_shared<StopObstacle>(*current_closest_stop_obstacle);
1310-
} else {
1311-
prev_closest_stop_obstacle_ptr_ = nullptr;
13121274
}
13131275
}
1276+
1277+
prev_closest_stop_obstacles_ = obstacle_cruise_utils::getClosestStopObstacles(stop_obstacles);
13141278
}
13151279

13161280
bool ObstacleCruisePlannerNode::isObstacleCrossing(

0 commit comments

Comments
 (0)