23#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
41constexpr double kStraightForwardLineCost = 10.0;
45 const std::string &config_dir,
const std::string &name,
46 const std::shared_ptr<DependencyInjector> &injector) {
51 return Decider::LoadConfig<RuleBasedStopDeciderConfig>(&config_);
58 StopOnSidePass(frame, reference_line_info);
63 CheckLaneChangeUrgency(frame);
67 AddPathEndStop(frame, reference_line_info);
72void RuleBasedStopDecider::CheckLaneChangeUrgency(
Frame *
const frame) {
73 for (
auto &reference_line_info : *frame->mutable_reference_line_info()) {
77 is_change_lane_planning_succeed_ =
78 reference_line_info.
Cost() < kStraightForwardLineCost;
83 if (frame->reference_line_info().size() <= 1 ||
84 (is_clear_to_change_lane_ && is_change_lane_planning_succeed_)) {
89 const auto &route_end_waypoint =
92 if (!route_end_waypoint.lane) {
95 auto point = route_end_waypoint.
lane->GetSmoothPoint(route_end_waypoint.s);
97 common::SLPoint sl_point;
99 if (reference_line->XYToSL(point, &sl_point) &&
100 reference_line->IsOnLane(sl_point)) {
102 double distance_to_passage_end =
105 if (distance_to_passage_end >
111 const std::string stop_wall_id =
"lane_change_stop";
112 std::vector<std::string> wait_for_obstacles;
115 StopReasonCode::STOP_REASON_LANE_CHANGE_URGENCY, wait_for_obstacles,
116 "RuleBasedStopDecider", frame, &reference_line_info);
121void RuleBasedStopDecider::AddPathEndStop(
122 Frame *
const frame, ReferenceLineInfo *
const reference_line_info) {
123 if (!reference_line_info->path_data().path_label().empty() &&
124 reference_line_info->path_data().frenet_frame_path().back().s() -
125 reference_line_info->path_data().frenet_frame_path().front().s() <
127 const std::string stop_wall_id =
128 PATH_END_VO_ID_PREFIX + reference_line_info->path_data().path_label();
129 std::vector<std::string> wait_for_obstacles;
132 reference_line_info->path_data().frenet_frame_path().back().s() - 0.1,
133 0.0, StopReasonCode::STOP_REASON_REFERENCE_END, wait_for_obstacles,
134 "RuleBasedStopDecider", frame, reference_line_info);
138void RuleBasedStopDecider::StopOnSidePass(
139 Frame *
const frame, ReferenceLineInfo *
const reference_line_info) {
140 static bool check_clear;
141 static common::PathPoint change_lane_stop_path_point;
143 const PathData &path_data = reference_line_info->path_data();
144 double stop_s_on_pathdata = 0.0;
146 if (path_data.path_label().find(
"self") != std::string::npos) {
148 change_lane_stop_path_point.Clear();
153 CheckClearDone(*reference_line_info, change_lane_stop_path_point)) {
158 CheckSidePassStop(path_data, *reference_line_info, &stop_s_on_pathdata)) {
166 if (!CheckADCStop(path_data, *reference_line_info, stop_s_on_pathdata)) {
167 if (!BuildSidePassStopFence(path_data, stop_s_on_pathdata,
168 &change_lane_stop_path_point, frame,
169 reference_line_info)) {
170 AERROR <<
"Set side pass stop fail";
181bool RuleBasedStopDecider::CheckSidePassStop(
182 const PathData &path_data,
const ReferenceLineInfo &reference_line_info,
183 double *stop_s_on_pathdata) {
184 const std::vector<std::tuple<double, PathData::PathPointType, double>>
185 &path_point_decision_guide = path_data.path_point_decision_guide();
188 for (
const auto &point_guide : path_point_decision_guide) {
190 std::get<1>(point_guide) ==
192 *stop_s_on_pathdata = std::get<0>(point_guide);
194 const auto &vehicle_config =
195 common::VehicleConfigHelper::Instance()->GetConfig();
196 const double ego_front_to_center =
197 vehicle_config.vehicle_param().front_edge_to_center();
198 common::PathPoint stop_pathpoint;
199 if (!path_data.GetPathPointWithRefS(*stop_s_on_pathdata,
201 AERROR <<
"Can't get stop point on path data";
204 const double ego_theta = stop_pathpoint.theta();
205 Vec2d shift_vec{ego_front_to_center * std::cos(ego_theta),
206 ego_front_to_center * std::sin(ego_theta)};
207 const Vec2d stop_fence_pose =
208 shift_vec + Vec2d(stop_pathpoint.x(), stop_pathpoint.y());
209 double stop_l_on_pathdata = 0.0;
210 const auto &nearby_path = reference_line_info.reference_line().map_path();
211 nearby_path.GetNearestPoint(stop_fence_pose, stop_s_on_pathdata,
212 &stop_l_on_pathdata);
215 last_path_point_type = std::get<1>(point_guide);
221bool RuleBasedStopDecider::BuildSidePassStopFence(
222 const PathData &path_data,
const double stop_s_on_pathdata,
223 common::PathPoint *stop_point,
Frame *
const frame,
224 ReferenceLineInfo *
const reference_line_info) {
225 CHECK_NOTNULL(frame);
226 CHECK_NOTNULL(reference_line_info);
228 if (!path_data.GetPathPointWithRefS(stop_s_on_pathdata, stop_point)) {
229 AERROR <<
"Can't get stop point on path data";
233 const std::string stop_wall_id =
"Side_Pass_Stop";
234 std::vector<std::string> wait_for_obstacles;
236 const auto &nearby_path = reference_line_info->reference_line().map_path();
237 double stop_point_s = 0.0;
238 double stop_point_l = 0.0;
239 nearby_path.GetNearestPoint({stop_point->x(), stop_point->y()}, &stop_point_s,
243 StopReasonCode::STOP_REASON_SIDEPASS_SAFETY,
244 wait_for_obstacles,
"RuleBasedStopDecider", frame,
245 reference_line_info);
250bool RuleBasedStopDecider::CheckADCStop(
251 const PathData &path_data,
const ReferenceLineInfo &reference_line_info,
252 const double stop_s_on_pathdata) {
253 common::PathPoint stop_point;
254 if (!path_data.GetPathPointWithRefS(stop_s_on_pathdata, &stop_point)) {
255 AERROR <<
"Can't get stop point on path data";
259 const double adc_speed =
injector_->vehicle_state()->linear_velocity();
261 ADEBUG <<
"ADC not stopped: speed[" << adc_speed <<
"]";
266 const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
267 const auto &nearby_path = reference_line_info.reference_line().map_path();
268 double stop_point_s = 0.0;
269 double stop_point_l = 0.0;
270 nearby_path.GetNearestPoint({stop_point.x(), stop_point.y()}, &stop_point_s,
273 const double distance_stop_line_to_adc_front_edge =
274 stop_point_s - adc_front_edge_s;
276 if (distance_stop_line_to_adc_front_edge >
278 ADEBUG <<
"not a valid stop. too far from stop line.";
285bool RuleBasedStopDecider::CheckClearDone(
286 const ReferenceLineInfo &reference_line_info,
287 const common::PathPoint &stop_point) {
288 const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
289 const double adc_back_edge_s = reference_line_info.AdcSlBoundary().start_s();
290 const double adc_start_l = reference_line_info.AdcSlBoundary().start_l();
291 const double adc_end_l = reference_line_info.AdcSlBoundary().end_l();
292 double lane_left_width = 0.0;
293 double lane_right_width = 0.0;
294 reference_line_info.reference_line().GetLaneWidth(
295 (adc_front_edge_s + adc_back_edge_s) / 2.0, &lane_left_width,
297 SLPoint stop_sl_point;
298 reference_line_info.reference_line().XYToSL(stop_point, &stop_sl_point);
301 if (adc_back_edge_s > stop_sl_point.s()) {
302 if (adc_start_l > -lane_right_width || adc_end_l < lane_left_width) {
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
Implements a class of 2-dimensional vectors.
const LaneWaypoint & RouteEndWaypoint() const
Frame holds all data for one planning cycle.
ReferenceLineInfo holds all data for one reference line.
const hdmap::RouteSegments & Lanes() const
const SLBoundary & AdcSlBoundary() const
bool IsChangeLanePath() const
Check if the current reference line is a change lane reference line, i.e., ADC's current position is ...
ReferenceLine * mutable_reference_line()
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
std::shared_ptr< DependencyInjector > injector_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Planning module main class.
This file contains the static member functions from LaneChangeDecider, which are deleted from the cla...
int BuildStopDecision(const std::string &stop_wall_id, const double stop_line_s, const double stop_distance, const StopReasonCode &stop_reason_code, const std::vector< std::string > &wait_for_obstacles, const std::string &decision_tag, Frame *const frame, ReferenceLineInfo *const reference_line_info, double stop_wall_width)
bool IsClearToChangeLane(ReferenceLineInfo *reference_line_info)
A static function to check if the ChangeLanePath type of reference line is safe or if current referen...
bool IsPerceptionBlocked(const ReferenceLineInfo &reference_line_info, const double search_beam_length, const double search_beam_radius_intensity, const double search_range, const double is_block_angle_threshold)
A static function to estimate if an obstacle in certain range in front of ADV blocks too much space p...
optional bool enable_lane_change_urgency_checking
optional double max_adc_stop_speed
optional double search_beam_radius_intensity
optional double urgent_distance_for_lane_change
optional double short_path_length_threshold
optional double approach_distance_for_lane_change
optional double search_beam_length
optional double max_valid_stop_distance
optional double is_block_angle_threshold
optional bool enable_stop_on_side_pass
optional double search_range