Skip to content

Commit 548e515

Browse files
committed
feat(avoidance): limit acceleration during avoidance maneuver (autowarefoundation#6698)
Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com>
1 parent b994184 commit 548e515

File tree

7 files changed

+148
-1
lines changed

7 files changed

+148
-1
lines changed

planning/behavior_path_avoidance_module/config/avoidance.param.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@
287287
nominal_jerk: 0.5 # [m/sss]
288288
max_deceleration: -1.5 # [m/ss]
289289
max_jerk: 1.0 # [m/sss]
290-
max_acceleration: 1.0 # [m/ss]
290+
max_acceleration: 0.5 # [m/ss]
291+
min_velocity_to_limit_max_acceleration: 2.78 # [m/ss]
291292

292293
shift_line_pipeline:
293294
trim:

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ struct AvoidanceParameters
143143
// To prevent large acceleration while avoidance.
144144
double max_acceleration{0.0};
145145

146+
// To prevent large acceleration while avoidance.
147+
double min_velocity_to_limit_max_acceleration{0.0};
148+
146149
// upper distance for envelope polygon expansion.
147150
double upper_distance_for_polygon_expansion{0.0};
148151

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp

+75
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <algorithm>
2525
#include <limits>
2626
#include <memory>
27+
#include <utility>
2728
#include <vector>
2829

2930
namespace behavior_path_planner::helper::avoidance
@@ -32,7 +33,10 @@ namespace behavior_path_planner::helper::avoidance
3233
using behavior_path_planner::PathShifter;
3334
using behavior_path_planner::PlannerData;
3435
using motion_utils::calcDecelDistWithJerkAndAccConstraints;
36+
using motion_utils::calcLongitudinalOffsetPose;
37+
using motion_utils::calcSignedArcLength;
3538
using motion_utils::findNearestIndex;
39+
using tier4_autoware_utils::getPose;
3640

3741
class AvoidanceHelper
3842
{
@@ -61,6 +65,11 @@ class AvoidanceHelper
6165

6266
geometry_msgs::msg::Pose getEgoPose() const { return data_->self_odometry->pose.pose; }
6367

68+
geometry_msgs::msg::Point getEgoPosition() const
69+
{
70+
return data_->self_odometry->pose.pose.position;
71+
}
72+
6473
static size_t getConstraintsMapIndex(const double velocity, const std::vector<double> & values)
6574
{
6675
const auto itr = std::find_if(
@@ -262,6 +271,20 @@ class AvoidanceHelper
262271
return *itr;
263272
}
264273

274+
std::pair<double, double> getDistanceToAccelEndPoint(const PathWithLaneId & path)
275+
{
276+
updateAccelEndPoint(path);
277+
278+
if (!max_v_point_.has_value()) {
279+
return std::make_pair(0.0, std::numeric_limits<double>::max());
280+
}
281+
282+
const auto start_idx = data_->findEgoIndex(path.points);
283+
const auto distance =
284+
calcSignedArcLength(path.points, start_idx, max_v_point_.value().first.position);
285+
return std::make_pair(distance, max_v_point_.value().second);
286+
}
287+
265288
double getFeasibleDecelDistance(
266289
const double target_velocity, const bool use_hard_constraints = true) const
267290
{
@@ -367,6 +390,56 @@ class AvoidanceHelper
367390
return true;
368391
}
369392

393+
void updateAccelEndPoint(const PathWithLaneId & path)
394+
{
395+
const auto & p = parameters_;
396+
const auto & a_now = data_->self_acceleration->accel.accel.linear.x;
397+
if (a_now < 0.0) {
398+
max_v_point_ = std::nullopt;
399+
return;
400+
}
401+
402+
if (getEgoSpeed() < p->min_velocity_to_limit_max_acceleration) {
403+
max_v_point_ = std::nullopt;
404+
return;
405+
}
406+
407+
if (max_v_point_.has_value()) {
408+
return;
409+
}
410+
411+
const auto v0 = getEgoSpeed() + p->buf_slow_down_speed;
412+
413+
const auto t_neg_jerk = std::max(0.0, a_now - p->max_acceleration) / p->max_jerk;
414+
const auto v_neg_jerk = v0 + a_now * t_neg_jerk + std::pow(t_neg_jerk, 2.0) / 2.0;
415+
const auto x_neg_jerk = v0 * t_neg_jerk + a_now * std::pow(t_neg_jerk, 2.0) / 2.0 +
416+
p->max_jerk * std::pow(t_neg_jerk, 3.0) / 6.0;
417+
418+
const auto & v_max = data_->parameters.max_vel;
419+
if (v_max < v_neg_jerk) {
420+
max_v_point_ = std::nullopt;
421+
return;
422+
}
423+
424+
const auto t_max_accel = (v_max - v_neg_jerk) / p->max_acceleration;
425+
const auto x_max_accel =
426+
v_neg_jerk * t_max_accel + p->max_acceleration * std::pow(t_max_accel, 2.0) / 2.0;
427+
428+
const auto point =
429+
calcLongitudinalOffsetPose(path.points, getEgoPosition(), x_neg_jerk + x_max_accel);
430+
if (point.has_value()) {
431+
max_v_point_ = std::make_pair(point.value(), v_max);
432+
return;
433+
}
434+
435+
const auto x_end = calcSignedArcLength(path.points, getEgoPosition(), path.points.size() - 1);
436+
const auto t_end =
437+
(std::sqrt(v0 * v0 + 2.0 * p->max_acceleration * x_end) - v0) / p->max_acceleration;
438+
const auto v_end = v0 + p->max_acceleration * t_end;
439+
440+
max_v_point_ = std::make_pair(getPose(path.points.back()), v_end);
441+
}
442+
370443
void reset()
371444
{
372445
prev_reference_path_ = PathWithLaneId();
@@ -417,6 +490,8 @@ class AvoidanceHelper
417490
ShiftedPath prev_linear_shift_path_;
418491

419492
lanelet::ConstLanelets prev_driving_lanes_;
493+
494+
std::optional<std::pair<Pose, double>> max_v_point_;
420495
};
421496
} // namespace behavior_path_planner::helper::avoidance
422497

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/parameter_helper.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ AvoidanceParameters getParameter(rclcpp::Node * node)
334334
p.max_deceleration = getOrDeclareParameter<double>(*node, ns + "max_deceleration");
335335
p.max_jerk = getOrDeclareParameter<double>(*node, ns + "max_jerk");
336336
p.max_acceleration = getOrDeclareParameter<double>(*node, ns + "max_acceleration");
337+
p.min_velocity_to_limit_max_acceleration =
338+
getOrDeclareParameter<double>(*node, ns + "min_velocity_to_limit_max_acceleration");
337339
}
338340

339341
// constraints (lateral)

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ class AvoidanceModule : public SceneModuleInterface
233233
*/
234234
void insertPrepareVelocity(ShiftedPath & shifted_path) const;
235235

236+
/**
237+
* @brief insert max velocity in output path to limit acceleration.
238+
* @param target path.
239+
*/
240+
void insertAvoidanceVelocity(ShiftedPath & shifted_path) const;
241+
236242
/**
237243
* @brief calculate stop distance based on object's overhang.
238244
* @param stop distance.

planning/behavior_path_avoidance_module/src/manager.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,19 @@ void AvoidanceModuleManager::updateModuleParams(const std::vector<rclcpp::Parame
244244
}
245245
}
246246

247+
{
248+
const std::string ns = "avoidance.constraints.longitudinal.";
249+
250+
updateParam<double>(parameters, ns + "nominal_deceleration", p->nominal_deceleration);
251+
updateParam<double>(parameters, ns + "nominal_jerk", p->nominal_jerk);
252+
updateParam<double>(parameters, ns + "max_deceleration", p->max_deceleration);
253+
updateParam<double>(parameters, ns + "max_jerk", p->max_jerk);
254+
updateParam<double>(parameters, ns + "max_acceleration", p->max_acceleration);
255+
updateParam<double>(
256+
parameters, ns + "min_velocity_to_limit_max_acceleration",
257+
p->min_velocity_to_limit_max_acceleration);
258+
}
259+
247260
{
248261
const std::string ns = "avoidance.shift_line_pipeline.";
249262
updateParam<double>(

planning/behavior_path_avoidance_module/src/scene.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ void AvoidanceModule::updateEgoBehavior(const AvoidancePlanningData & data, Shif
686686
}
687687

688688
insertPrepareVelocity(path);
689+
insertAvoidanceVelocity(path);
689690

690691
switch (data.state) {
691692
case AvoidanceState::NOT_AVOID: {
@@ -1725,6 +1726,52 @@ void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
17251726
shifted_path.path.points, start_idx, distance_to_object);
17261727
}
17271728

1729+
void AvoidanceModule::insertAvoidanceVelocity(ShiftedPath & shifted_path) const
1730+
{
1731+
const auto & data = avoid_data_;
1732+
1733+
// do nothing if no shift line is approved.
1734+
if (path_shifter_.getShiftLines().empty()) {
1735+
return;
1736+
}
1737+
1738+
// do nothing if there is no avoidance target.
1739+
if (data.target_objects.empty()) {
1740+
return;
1741+
}
1742+
1743+
const auto [distance_to_accel_end_point, v_max] =
1744+
helper_->getDistanceToAccelEndPoint(shifted_path.path);
1745+
if (distance_to_accel_end_point < 1e-3) {
1746+
return;
1747+
}
1748+
1749+
const auto start_idx = planner_data_->findEgoIndex(shifted_path.path.points);
1750+
for (size_t i = start_idx; i < shifted_path.path.points.size(); ++i) {
1751+
const auto distance_from_ego = calcSignedArcLength(shifted_path.path.points, start_idx, i);
1752+
1753+
// slow down speed is inserted only in front of the object.
1754+
const auto accel_distance = distance_to_accel_end_point - distance_from_ego;
1755+
if (accel_distance < 0.0) {
1756+
break;
1757+
}
1758+
1759+
const double v_target_square =
1760+
v_max * v_max - 2.0 * parameters_->max_acceleration * accel_distance;
1761+
if (v_target_square < 1e-3) {
1762+
break;
1763+
}
1764+
1765+
// target speed with nominal jerk limits.
1766+
const double v_target = std::max(getEgoSpeed(), std::sqrt(v_target_square));
1767+
const double v_original = shifted_path.path.points.at(i).point.longitudinal_velocity_mps;
1768+
shifted_path.path.points.at(i).point.longitudinal_velocity_mps = std::min(v_original, v_target);
1769+
}
1770+
1771+
slow_pose_ = motion_utils::calcLongitudinalOffsetPose(
1772+
shifted_path.path.points, start_idx, distance_to_accel_end_point);
1773+
}
1774+
17281775
std::shared_ptr<AvoidanceDebugMsgArray> AvoidanceModule::get_debug_msg_array() const
17291776
{
17301777
debug_data_.avoidance_debug_msg_array.header.stamp = clock_->now();

0 commit comments

Comments
 (0)