Skip to content

Commit ec708c5

Browse files
committed
feat(avoidance): limit acceleration during avoidance maneuver
Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com>
1 parent 6602cc0 commit ec708c5

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/helper.hpp

+56
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,37 @@ class AvoidanceHelper
367390
return true;
368391
}
369392

393+
void updateAccelEndPoint(const PathWithLaneId & path)
394+
{
395+
const auto & a_now = data_->self_acceleration->accel.accel.linear.x;
396+
if (a_now < 0.0) {
397+
max_v_point_ = std::nullopt;
398+
return;
399+
}
400+
401+
if (max_v_point_.has_value()) {
402+
return;
403+
}
404+
405+
const auto & p = parameters_;
406+
const auto & v_max = data_->parameters.max_vel;
407+
const auto v0 = getEgoSpeed() + p->buf_slow_down_speed;
408+
const auto t_accel = (v_max - v0) / p->max_acceleration;
409+
const auto x_accel = v0 * t_accel + 0.5 * p->max_acceleration * t_accel * t_accel;
410+
411+
const auto point = calcLongitudinalOffsetPose(path.points, getEgoPosition(), x_accel);
412+
if (point.has_value()) {
413+
max_v_point_ = std::make_pair(point.value(), v_max);
414+
}
415+
416+
const auto x_end = calcSignedArcLength(path.points, getEgoPosition(), path.points.size() - 1);
417+
const auto t_end =
418+
(std::sqrt(v0 * v0 + 2.0 * p->max_acceleration * x_end) - v0) / p->max_acceleration;
419+
const auto v_end = v0 + p->max_acceleration * t_end;
420+
421+
max_v_point_ = std::make_pair(getPose(path.points.back()), v_end);
422+
}
423+
370424
void reset()
371425
{
372426
prev_reference_path_ = PathWithLaneId();
@@ -417,6 +471,8 @@ class AvoidanceHelper
417471
ShiftedPath prev_linear_shift_path_;
418472

419473
lanelet::ConstLanelets prev_driving_lanes_;
474+
475+
std::optional<std::pair<Pose, double>> max_v_point_;
420476
};
421477
} // namespace behavior_path_planner::helper::avoidance
422478

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp

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

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

planning/behavior_path_avoidance_module/src/manager.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,16 @@ void AvoidanceModuleManager::updateModuleParams(const std::vector<rclcpp::Parame
146146
}
147147
}
148148

149+
{
150+
const std::string ns = "avoidance.constraints.longitudinal.";
151+
152+
updateParam<double>(parameters, ns + "nominal_deceleration", p->nominal_deceleration);
153+
updateParam<double>(parameters, ns + "nominal_jerk", p->nominal_jerk);
154+
updateParam<double>(parameters, ns + "max_deceleration", p->max_deceleration);
155+
updateParam<double>(parameters, ns + "max_jerk", p->max_jerk);
156+
updateParam<double>(parameters, ns + "max_acceleration", p->max_acceleration);
157+
}
158+
149159
{
150160
const std::string ns = "avoidance.shift_line_pipeline.";
151161
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: {
@@ -1706,6 +1707,52 @@ void AvoidanceModule::insertPrepareVelocity(ShiftedPath & shifted_path) const
17061707
shifted_path.path.points, start_idx, distance_to_object);
17071708
}
17081709

1710+
void AvoidanceModule::insertAvoidanceVelocity(ShiftedPath & shifted_path) const
1711+
{
1712+
const auto & data = avoid_data_;
1713+
1714+
// do nothing if no shift line is approved.
1715+
if (path_shifter_.getShiftLines().empty()) {
1716+
return;
1717+
}
1718+
1719+
// do nothing if there is no avoidance target.
1720+
if (data.target_objects.empty()) {
1721+
return;
1722+
}
1723+
1724+
const auto [distance_to_accel_end_point, v_max] =
1725+
helper_->getDistanceToAccelEndPoint(shifted_path.path);
1726+
if (distance_to_accel_end_point < 1e-3) {
1727+
return;
1728+
}
1729+
1730+
const auto start_idx = planner_data_->findEgoIndex(shifted_path.path.points);
1731+
for (size_t i = start_idx; i < shifted_path.path.points.size(); ++i) {
1732+
const auto distance_from_ego = calcSignedArcLength(shifted_path.path.points, start_idx, i);
1733+
1734+
// slow down speed is inserted only in front of the object.
1735+
const auto accel_distance = distance_to_accel_end_point - distance_from_ego;
1736+
if (accel_distance < 0.0) {
1737+
break;
1738+
}
1739+
1740+
const double v_target_square =
1741+
v_max * v_max - 2.0 * parameters_->max_acceleration * accel_distance;
1742+
if (v_target_square < 1e-3) {
1743+
break;
1744+
}
1745+
1746+
// target speed with nominal jerk limits.
1747+
const double v_target = std::max(getEgoSpeed(), std::sqrt(v_target_square));
1748+
const double v_original = shifted_path.path.points.at(i).point.longitudinal_velocity_mps;
1749+
shifted_path.path.points.at(i).point.longitudinal_velocity_mps = std::min(v_original, v_target);
1750+
}
1751+
1752+
slow_pose_ = motion_utils::calcLongitudinalOffsetPose(
1753+
shifted_path.path.points, start_idx, distance_to_accel_end_point);
1754+
}
1755+
17091756
std::shared_ptr<AvoidanceDebugMsgArray> AvoidanceModule::get_debug_msg_array() const
17101757
{
17111758
debug_data_.avoidance_debug_msg_array.header.stamp = clock_->now();

0 commit comments

Comments
 (0)