22#include "modules/common_msgs/planning_msgs/decision.pb.h"
38 config_.CopyFrom(nudge_config);
39 const auto& vehicle_config = common::VehicleConfigHelper::Instance()->GetConfig();
40 veh_config_.
width = vehicle_config.vehicle_param().width();
41 veh_config_.
length = vehicle_config.vehicle_param().length();
46 Frame*
const current_frame,
47 const Frame* last_frame,
49 auto* nudge_info = ParkDataCenter::Instance()->mutable_current_nudge_info(reference_line_info->
key());
50 nudge_info->mutable_update_ids()->clear();
51 nudge_info->mutable_block_sl_polygons()->clear();
53 auto* tracking_nudge_obs_info = nudge_info->mutable_tracking_nudge_obs_info();
63 && ParkDataCenter::Instance()->GetLastFrameNudgeTrackInfo(
65 AINFO <<
"NudgeCalculation: update tracking_nudge_obs_info from last frame";
68 for (
auto& iter : nudge_info->tracking_nudge_obs_info()) {
69 AINFO <<
"last frame tracking info: " << iter.first <<
", P(nudge): " << iter.second.nudge_probability;
73 const std::string& obstacle_id = obstacle->Id();
74 const std::string obstacle_type_name = PerceptionObstacle_Type_Name(obstacle->Perception().type());
76 AINFO <<
"NudgeCalculation: check obstacle id [ " << obstacle_id <<
" ], type [ " << obstacle_type_name <<
" ]";
78 if (!IsWithinNudgeScopeObstacle(reference_line_info, *obstacle)) {
79 AINFO <<
"NudgeCalculation: Not IsWithinNudgeScopeObstacle, Skip";
84 if (obstacle->IsStatic()) {
88 ADEBUG <<
"NudgeCalculation: obstacle [ " << obstacle->Id() <<
"] is dynamic";
93 for (
auto iter = tracking_nudge_obs_info->begin(); iter != tracking_nudge_obs_info->end();) {
94 auto obs_id_iter = nudge_info->update_ids().find(iter->first);
95 if (obs_id_iter != nudge_info->update_ids().end()) {
102 AINFO <<
"NudgeCalculation: erase tracking_nudge_obs_info: obs [ " << iter->first <<
" ]";
103 iter = tracking_nudge_obs_info->erase(iter);
110 for (
const auto& obs_id : nudge_info->update_ids()) {
111 auto track_obs_iter = tracking_nudge_obs_info->find(obs_id);
112 if (track_obs_iter != tracking_nudge_obs_info->end()) {
113 nudge_info->mutable_block_sl_polygons()->emplace_back(track_obs_iter->second.sl_boundary, obs_id);
115 AINFO <<
"update nudge [ " << obs_id <<
" ], "
116 <<
"nudge_probability: " << track_obs_iter->second.nudge_probability;
121 nudge_info->SortBlockSLPolygons();
124 bool is_merge_obs_polygon =
MergeObsPolygon(reference_line_info, nudge_info);
125 nudge_info->set_is_merge_block_obs(is_merge_obs_polygon);
126 AINFO <<
"NudgeCalculation: is_merge_obs_polygon: " << is_merge_obs_polygon;
127 AINFO <<
"block_sl_polygons size : " << nudge_info->block_sl_polygons().size();
132 nudge_info->set_enable(
true);
133 AINFO <<
"NudgeCalculation: Enable Nudge";
135 nudge_info->set_enable(
false);
136 AINFO <<
"NudgeCalculation: Not Enable Nudge";
145 std::string obs_id = obstacle.
Id();
147 double lane_left_width = 0.0;
148 double lane_right_width = 0.0;
156 bool obs_is_all_on_lane = obs_boundary.
start_l() > -lane_right_width && obs_boundary.
end_l() < lane_left_width;
157 bool obs_far_from_lane_boundary = obs_boundary.
start_l() - lane_left_width > veh_config_.
width
158 || obs_boundary.
end_l() + lane_right_width < -veh_config_.
width;
160 bool is_obs_passable =
CalcObsRemainSpace(reference_line_info, obstacle, &remain_nudge_space);
161 AINFO <<
"NudgeCalculation: BuildStaticTrackingObs: [ " << obs_id <<
" ], is passable: " << is_obs_passable
162 <<
", obs_is_all_on_lane: " << obs_is_all_on_lane;
164 auto iter = tracking_nudge_obs_info->find(obs_id);
165 if (iter != tracking_nudge_obs_info->end()) {
166 AINFO <<
"NudgeCalculation: MatchTrackingObsInfo: [ " << obs_id <<
" ] with last tracking obs [ " << iter->first
168 UpdateTrackingObsInfo(&iter->second, obstacle, is_obs_passable, remain_nudge_space, obs_is_all_on_lane);
172 if (
MatchTrackingObsInfo(obstacle, nudge_info, is_obs_passable, remain_nudge_space, obs_is_all_on_lane)) {
176 || ((obs_is_all_on_lane || !obs_far_from_lane_boundary)
181 UpdateTrackingObsInfo(
182 &new_track_obs_info, obstacle, is_obs_passable, remain_nudge_space, obs_is_all_on_lane);
184 tracking_nudge_obs_info->emplace(obs_id, new_track_obs_info);
194 bool is_all_on_lane) {
195 std::string obs_id = obstacle.
Id();
200 auto obs_id_iter = nudge_info->
update_ids().find(iter->first);
201 if (obs_id_iter != nudge_info->
update_ids().end()) {
210 UpdateTrackingObsInfo(&new_obs_info, obstacle, is_passable, remain_nudge_space, is_all_on_lane);
211 AINFO <<
"NudgeCalculation: MatchTrackingObsInfo [ " << obs_id <<
" ] with last tracking obs [ "
212 << iter->first <<
" ]";
219 AINFO <<
"NudgeCalculation: MatchTrackingObsInfo, can not match any obs for [ " << obs_id <<
" ]";
229 bool is_left =
false;
230 double ego_whole_pass_width = 0.5 * veh_config_.
width
233 double lane_left_width = 0.0;
234 double lane_right_width = 0.0;
235 double road_left_width = 0.0;
236 double road_right_width = 0.0;
243 obs_boundary.
start_s(), &left_boundary_type, &right_boundary_type);
248 = lane_left_width - ego_whole_pass_width - obs_boundary.
end_l() - FLAGS_static_obstacle_nudge_l_buffer;
250 = lane_right_width - ego_whole_pass_width + obs_boundary.
start_l() - FLAGS_static_obstacle_nudge_l_buffer;
256 = road_left_width - ego_whole_pass_width - obs_boundary.
end_l() - FLAGS_static_obstacle_nudge_l_buffer;
263 - FLAGS_static_obstacle_nudge_l_buffer;
269 ADEBUG <<
"CalcObsRemainSpace: [ " << obstacle.
Id() <<
" ]" <<
", left right lane_remain: [ "
271 <<
", lane left right width: " << lane_left_width <<
", " << lane_right_width <<
" ]"
272 <<
", ego_whole_pass_width: " << ego_whole_pass_width <<
", obs_boundary l: [ " << obs_boundary.
start_l()
273 <<
", " << obs_boundary.
end_l() <<
" ]";
281 is_in_nudge_state_ = state;
284bool NudgeCalculation::IsWithinNudgeScopeObstacle(
289 ADEBUG <<
"obstacle IsVirtual";
294 ADEBUG <<
"obstacle IsIgnore";
298 if (!obstacle.
IsStatic() || obstacle.
speed() > FLAGS_static_obstacle_speed_threshold) {
299 ADEBUG <<
"obstacle Is not Static";
306 ADEBUG <<
"obstacle not in ROI";
313 ADEBUG <<
"obstacle is out of lane width";
319void NudgeCalculation::UpdateTrackingObsInfo(
320 NudgeObstacleInfo*
const track_obs_info,
321 const Obstacle& obstacle,
323 RemainNudgeSpace remain_nudge_space,
324 bool is_all_on_lane) {
325 AINFO <<
"NudgeCalculation: UpdateTrackingObsInfo: [ " << obstacle.Id() <<
" ], is_passable: " << is_passable;
326 track_obs_info->origin_polygon = obstacle.PerceptionPolygon();
327 track_obs_info->expand_polygon = track_obs_info->origin_polygon.ExpandByDistance(config_.
expand_polygon_buffer());
328 track_obs_info->sl_boundary = obstacle.PerceptionSLBoundary();
330 track_obs_info->is_passable = is_passable;
331 track_obs_info->remain_nudge_space = remain_nudge_space;
332 track_obs_info->is_all_on_lane = is_all_on_lane;
333 if (!track_obs_info->is_passable || track_obs_info->is_all_on_lane) {
335 track_obs_info->nudge_probability =
common::math::Clamp(track_obs_info->nudge_probability, 0.0, 1.0);
339void NudgeCalculation::GetRefLineLaneWidth(
340 const ReferenceLine& reference_line,
342 const double search_s,
343 double*
const lane_left_width,
344 double*
const lane_right_width) {
346 double refline_offset_to_lane_center = 0.0;
347 reference_line.GetOffsetToMap(search_s, &refline_offset_to_lane_center);
348 if (!reference_line.GetLaneWidth(search_s, lane_left_width, lane_right_width)) {
349 *lane_left_width = 0.5 * adc_lane_width - refline_offset_to_lane_center;
350 *lane_right_width = 0.5 * adc_lane_width + refline_offset_to_lane_center;
356 AINFO <<
"MergeObsPolygon: block_sl_polygons is empty, return";
369 if (first_sl_polygon.
id().empty()) {
370 AINFO <<
"MergeObsPolygon: not found first_sl_polygon";
377 if (track_iter->second.is_passable && !track_iter->second.is_all_on_lane) {
387 std::string merge_polygon_id =
"";
388 std::vector<Vec2d> merge_points;
391 if (sl_polygon_iter->MinS() - first_sl_polygon.
MaxS() > 0.8) {
398 if (!track_iter->second.is_all_on_lane) {
404 track_iter->second.origin_polygon.points().begin(),
405 track_iter->second.origin_polygon.points().end());
406 merge_polygon_id += (*sl_polygon_iter).id() +
"+";
411 if (merge_points.empty()) {
426 if (!track_iter->second.is_passable) {
429 }
else if (sl_polygon_iter->MinS() - first_sl_polygon.
MaxS() > 0.8) {
430 AINFO <<
"MergeObsPolygon: erase obs far and passable: " << (*sl_polygon_iter).id();
436 if (!track_iter->second.is_all_on_lane
437 && merge_polygon.
DistanceTo(track_iter->second.origin_polygon)
438 < veh_config_.
width + FLAGS_static_obstacle_nudge_l_buffer * 2.0) {
441 track_iter->second.origin_polygon.points().begin(),
442 track_iter->second.origin_polygon.points().end());
443 merge_polygon_id += (*sl_polygon_iter).id() +
"+";
446 AINFO <<
"MergeObsPolygon: erase obs far from lane boundary: " << (*sl_polygon_iter).id();
461 AINFO <<
"MergeObsPolygon: GetSLBoundary failed";
465 SLPolygon merge_sl_polygon(merge_sl_boundary, merge_polygon_id);
468 if (merge_polygon_update.
points().size() > 0) {
470 for (
const auto& p : merge_polygon_update.
points()) {
471 print_curve.
AddPoint(merge_polygon_id +
"_BlockObsPolygon", p.x(), p.y());
474 merge_polygon_id +
"_BlockObsPolygon", merge_polygon.
points()[0].x(), merge_polygon.
points()[0].y());
477 AINFO <<
"MergeObsPolygon: " << merge_polygon_id;
497 double max_nudge_probability = 0.0;
499 std::vector<std::string> block_ids;
501 std::istringstream ids_stream(first_block_polygon.
id());
502 while (std::getline(ids_stream,
id,
'+')) {
503 block_ids.push_back(
id);
505 for (
const auto& obs_id : block_ids) {
510 max_nudge_probability = std::max(track_iter->second.nudge_probability, max_nudge_probability);
515 max_nudge_probability = std::max(track_iter->second.nudge_probability, max_nudge_probability);
518 AINFO <<
"max_nudge_probability: " << max_nudge_probability;
519 return max_nudge_probability > 0.8;
525 AINFO <<
"No block_sl_polygons, return";
528 double start_s = 1000.0;
529 double end_s = -1000.0;
530 double ego_whole_pass_width = veh_config_.
width;
535 bool is_left =
false;
537 if (box_index > 0 && (sl_polygon.MinS() - end_s) > 3.0 * veh_config_.
length) {
541 ego_whole_pass_width = 0.5 * veh_config_.
width
545 start_s = std::min(sl_polygon.MinS() - extend_length, start_s);
546 end_s = std::max(sl_polygon.MaxS() + extend_length, end_s);
548 start_s = std::max(adc_boundary_.
start_s(), start_s);
549 end_s = std::max(adc_boundary_.
start_s(), end_s);
551 std::vector<SLPoint> left_nudge_pts, right_nudge_pts;
552 for (
double s = start_s; s <= end_s; s += 0.1) {
553 double left_max_nudge_l = -1000.0;
554 double right_min_nudge_l = 1000.0;
555 for (
size_t index = 0; index < nudge_info->
block_sl_polygons().size(); ++index) {
557 if ((index > 0 && s < current_polygon.
MaxS()) || end_s < current_polygon.
MinS()) {
564 left_max_nudge_l = std::max(
565 current_polygon.
MaxL() + 0.5 * ego_whole_pass_width + FLAGS_static_obstacle_nudge_l_buffer,
567 right_min_nudge_l = std::min(
568 current_polygon.
MinL() - 0.5 * ego_whole_pass_width - FLAGS_static_obstacle_nudge_l_buffer,
570 if (s < current_polygon.
MinS()) {
577 left_pt.set_l(left_max_nudge_l);
579 right_pt.set_l(right_min_nudge_l);
580 left_nudge_pts.emplace_back(left_pt);
581 right_nudge_pts.emplace_back(right_pt);
588 left_print_curve.
AddPoint(
"LeftKeyPoints_NudgePoints", pt.s(), pt.l());
594 right_print_curve.
AddPoint(
"RightKeyPoints_NudgePoints", pt.s(), pt.l());
A general class to denote the return status of an API call.
@Brief This is a helper class that can load vehicle configurations.
The class of polygon in 2-D.
static bool ComputeConvexHull(const std::vector< Vec2d > &points, Polygon2d *const polygon, bool check_area=true)
Compute the convex hull of a group of points.
double DistanceTo(const Vec2d &point) const
Compute the distance from a point to the polygon.
const std::vector< Vec2d > & points() const
Get the vertices of the polygon.
Implements a class of 2-dimensional vectors.
static double NowInSeconds()
gets the current time in second.
Frame holds all data for one planning cycle.
uint32_t SequenceNum() const
const ReferenceLineInfo * DriveReferenceLineInfo() const
const std::vector< const T * > & Items() const
List all the items in the container.
bool MatchTrackingObsInfo(const Obstacle &obstacle, NudgeInfo *const nudge_info, bool is_passable, RemainNudgeSpace remain_nudge_space, bool is_all_on_lane)
void set_in_nudge_state(bool state)
bool MergeObsPolygon(ReferenceLineInfo *const reference_line_info, NudgeInfo *const nudge_info)
bool IsProbEnoughToNudge(NudgeInfo *const nudge_info, bool is_merge_obs=false)
void CalcNudgeExtraSpace(ReferenceLineInfo *const reference_line_info, NudgeInfo *const nudge_info)
NudgeCalculation(const ObstacleNudgeDeciderConfig &cross_line_nudge_config)
void BuildNudgeDecisionWithObs(Frame *const current_frame, const Frame *last_frame, ReferenceLineInfo *const reference_line_info)
void EraseObsInNudgeinfo(NudgeInfo *const nudge_info, std::string id)
bool CalcObsRemainSpace(ReferenceLineInfo *const reference_line_info, const Obstacle &obstacle, RemainNudgeSpace *remain_space)
void BuildStaticTrackingObs(ReferenceLineInfo *const reference_line_info, const Obstacle &obstacle, NudgeInfo *const nudge_info)
std::vector< std::vector< SLPoint > > * mutable_extra_nudge_key_points()
const std::vector< SLPolygon > & block_sl_polygons() const
const std::unordered_map< std::string, NudgeObstacleInfo > & tracking_nudge_obs_info() const
const std::set< std::string > & update_ids() const
std::unordered_map< std::string, NudgeObstacleInfo > * mutable_tracking_nudge_obs_info()
void SortBlockSLPolygons()
std::set< std::string > * mutable_update_ids()
std::vector< SLPolygon > * mutable_block_sl_polygons()
const std::vector< std::vector< SLPoint > > & extra_nudge_key_points() const
This is the class that associates an Obstacle with its path properties.
const perception::PerceptionObstacle & Perception() const
bool HasLongitudinalDecision() const
const std::string & Id() const
bool HasLateralDecision() const
const SLBoundary & PerceptionSLBoundary() const
const common::math::Polygon2d & PerceptionPolygon() const
bool IsIgnore() const
Check if this object can be safely ignored.
static double GetADCLaneWidth(const ReferenceLine &reference_line, const double adc_frenet_s)
Get lane width in init_sl_state.
const IndexedList< std::string, Obstacle > & obstacles() const
void AddPoint(std::string key, double x, double y)
add point to curve key
ReferenceLineInfo holds all data for one reference line.
PathDecision * path_decision()
const common::VehicleState & vehicle_state() const
const ReferenceLine & reference_line() const
double SDistanceToDestination() const
const SLBoundary & AdcSlBoundary() const
bool IsOnLane(const common::SLPoint &sl_point) const
: check if a box/point is on lane along reference line
void GetLaneBoundaryType(const double s, hdmap::LaneBoundaryType::Type *const left_boundary_type, hdmap::LaneBoundaryType::Type *const right_boundary_type) const
bool GetSLBoundary(const common::math::Box2d &box, SLBoundary *const sl_boundary, double warm_start_s=-1.0) const
Get the SL Boundary of the box.
bool GetRoadWidth(const double s, double *const road_left_width, double *const road_right_width) const
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
Planning module main class.
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
double CalculateEquivalentEgoWidth(const ReferenceLineInfo &reference_line_info, double s, bool *is_left)
optional double linear_velocity
optional double nudge_key_point_extend_length_coefficient
optional double obs_clean_time_out_threshold
optional double max_forward_check_dis
optional double min_forward_check_dis
optional double obs_passable_buffer
optional double obs_nudge_time_out_threshold
optional double expand_polygon_buffer
hdmap::LaneBoundaryType::Type left_lane_boundary_type
hdmap::LaneBoundaryType::Type right_lane_boundary_type
double front_edge_to_center