Apollo 11.0
自动驾驶开放平台
nudge_calculation.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <algorithm>
20#include <memory>
21
22#include "modules/common_msgs/planning_msgs/decision.pb.h"
23
28
29namespace apollo {
30namespace planning {
31
36
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();
42 veh_config_.front_edge_to_center = vehicle_config.vehicle_param().front_edge_to_center();
43}
44
46 Frame* const current_frame,
47 const Frame* last_frame,
48 ReferenceLineInfo* const reference_line_info) {
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();
52 adc_boundary_ = reference_line_info->AdcSlBoundary();
53 auto* tracking_nudge_obs_info = nudge_info->mutable_tracking_nudge_obs_info();
54
55 double ego_v = std::abs(reference_line_info->vehicle_state().linear_velocity());
56 check_forward_dis_ = common::math::Clamp(ego_v, 0.0, 8.0) / 8.0
57 * (config_.max_forward_check_dis() - config_.min_forward_check_dis())
58 + config_.min_forward_check_dis();
59
60 dis2end_ = reference_line_info->SDistanceToDestination();
61
62 if (nullptr != last_frame && nullptr != last_frame->DriveReferenceLineInfo()
63 && ParkDataCenter::Instance()->GetLastFrameNudgeTrackInfo(
64 last_frame->SequenceNum(), last_frame->DriveReferenceLineInfo()->key(), tracking_nudge_obs_info)) {
65 AINFO << "NudgeCalculation: update tracking_nudge_obs_info from last frame";
66 }
67
68 for (auto& iter : nudge_info->tracking_nudge_obs_info()) {
69 AINFO << "last frame tracking info: " << iter.first << ", P(nudge): " << iter.second.nudge_probability;
70 }
71
72 for (const auto* obstacle : reference_line_info->path_decision()->obstacles().Items()) {
73 const std::string& obstacle_id = obstacle->Id();
74 const std::string obstacle_type_name = PerceptionObstacle_Type_Name(obstacle->Perception().type());
75
76 AINFO << "NudgeCalculation: check obstacle id [ " << obstacle_id << " ], type [ " << obstacle_type_name << " ]";
77
78 if (!IsWithinNudgeScopeObstacle(reference_line_info, *obstacle)) {
79 AINFO << "NudgeCalculation: Not IsWithinNudgeScopeObstacle, Skip";
80 continue;
81 }
82
83 // update_static_tracking_obs
84 if (obstacle->IsStatic()) {
85 BuildStaticTrackingObs(reference_line_info, *obstacle, nudge_info);
86 } else {
87 // To Do
88 ADEBUG << "NudgeCalculation: obstacle [ " << obstacle->Id() << "] is dynamic";
89 }
90 }
91
92 // clear tracking obs which is not updated
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()) {
96 ++iter;
97 continue;
98 }
99
100 double current_time = ::apollo::cyber::Clock::NowInSeconds();
101 if (current_time - iter->second.last_track_time > config_.obs_clean_time_out_threshold()) {
102 AINFO << "NudgeCalculation: erase tracking_nudge_obs_info: obs [ " << iter->first << " ]";
103 iter = tracking_nudge_obs_info->erase(iter);
104 continue;
105 }
106 ++iter;
107 }
108
109 // update nudge
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);
114 // track_obs_iter->second.PrintPolygonInfo(obs_id);
115 AINFO << "update nudge [ " << obs_id << " ], "
116 << "nudge_probability: " << track_obs_iter->second.nudge_probability;
117 }
118 }
119
120 // sort sl polygons
121 nudge_info->SortBlockSLPolygons();
122
123 // merge first block obs width nearby obstacle
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();
128
129 // calculate nudge_probability to make nudge decision
130 if (IsProbEnoughToNudge(nudge_info, is_merge_obs_polygon)) {
131 CalcNudgeExtraSpace(reference_line_info, nudge_info);
132 nudge_info->set_enable(true);
133 AINFO << "NudgeCalculation: Enable Nudge";
134 } else {
135 nudge_info->set_enable(false);
136 AINFO << "NudgeCalculation: Not Enable Nudge";
137 }
138 // TODO(fengzhiqi): nudge safety check
139}
140
142 ReferenceLineInfo* const reference_line_info,
143 const Obstacle& obstacle,
144 NudgeInfo* const nudge_info) {
145 std::string obs_id = obstacle.Id();
146 RemainNudgeSpace remain_nudge_space;
147 double lane_left_width = 0.0;
148 double lane_right_width = 0.0;
149 SLBoundary obs_boundary = obstacle.PerceptionSLBoundary();
150 GetRefLineLaneWidth(
151 reference_line_info->reference_line(),
152 adc_boundary_.start_s(),
153 0.5 * (obs_boundary.start_s() + obs_boundary.end_s()),
154 &lane_left_width,
155 &lane_right_width);
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;
159
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;
163 auto* tracking_nudge_obs_info = nudge_info->mutable_tracking_nudge_obs_info();
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
167 << " ]";
168 UpdateTrackingObsInfo(&iter->second, obstacle, is_obs_passable, remain_nudge_space, obs_is_all_on_lane);
169 nudge_info->mutable_update_ids()->insert(obs_id);
170 } else {
171 // Match obs and update obs info
172 if (MatchTrackingObsInfo(obstacle, nudge_info, is_obs_passable, remain_nudge_space, obs_is_all_on_lane)) {
173 return;
174 }
175 if (!is_obs_passable
176 || ((obs_is_all_on_lane || !obs_far_from_lane_boundary)
179 NudgeObstacleInfo new_track_obs_info;
181 UpdateTrackingObsInfo(
182 &new_track_obs_info, obstacle, is_obs_passable, remain_nudge_space, obs_is_all_on_lane);
183 nudge_info->mutable_update_ids()->insert(obs_id);
184 tracking_nudge_obs_info->emplace(obs_id, new_track_obs_info);
185 }
186 }
187}
188
190 const Obstacle& obstacle,
191 NudgeInfo* const nudge_info,
192 bool is_passable,
193 RemainNudgeSpace remain_nudge_space,
194 bool is_all_on_lane) {
195 std::string obs_id = obstacle.Id();
196 for (auto iter = nudge_info->mutable_tracking_nudge_obs_info()->begin();
197 iter != nudge_info->mutable_tracking_nudge_obs_info()->end();
198 iter++) {
199 // skip the tracking obs which is updated
200 auto obs_id_iter = nudge_info->update_ids().find(iter->first);
201 if (obs_id_iter != nudge_info->update_ids().end()) {
202 continue;
203 }
204 // polygon match
205 // case 1. tracking obs polygon contains obstacle // case 2. polygon IoU >
206 // 0.6
207 if (iter->second.expand_polygon.Contains(obstacle.PerceptionPolygon())
208 || iter->second.expand_polygon.ComputeIoU(obstacle.PerceptionPolygon()) > 0.6) {
209 NudgeObstacleInfo new_obs_info = iter->second;
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 << " ]";
213 iter = nudge_info->mutable_tracking_nudge_obs_info()->erase(iter);
214 nudge_info->mutable_tracking_nudge_obs_info()->emplace(obs_id, new_obs_info);
215 nudge_info->mutable_update_ids()->insert(obs_id);
216 return true;
217 }
218 }
219 AINFO << "NudgeCalculation: MatchTrackingObsInfo, can not match any obs for [ " << obs_id << " ]";
220 return false;
221}
222
224 ReferenceLineInfo* const reference_line_info,
225 const Obstacle& obstacle,
226 RemainNudgeSpace* remain_space) {
227 SLBoundary adc_boundary = reference_line_info->AdcSlBoundary();
228 SLBoundary obs_boundary = obstacle.PerceptionSLBoundary();
229 bool is_left = false;
230 double ego_whole_pass_width = 0.5 * veh_config_.width
231 + util::CalculateEquivalentEgoWidth(*reference_line_info, obs_boundary.start_s(), &is_left);
232
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;
239
240 reference_line_info->reference_line().GetLaneWidth(obs_boundary.start_s(), &lane_left_width, &lane_right_width);
241 reference_line_info->reference_line().GetRoadWidth(obs_boundary.start_s(), &road_left_width, &road_right_width);
242 reference_line_info->reference_line().GetLaneBoundaryType(
243 obs_boundary.start_s(), &left_boundary_type, &right_boundary_type);
244 remain_space->left_lane_boundary_type = left_boundary_type;
245 remain_space->right_lane_boundary_type = right_boundary_type;
246
247 remain_space->left_lane_remain
248 = lane_left_width - ego_whole_pass_width - obs_boundary.end_l() - FLAGS_static_obstacle_nudge_l_buffer;
249 remain_space->right_lane_remain
250 = lane_right_width - ego_whole_pass_width + obs_boundary.start_l() - FLAGS_static_obstacle_nudge_l_buffer;
251
253 remain_space->left_road_remain = remain_space->left_lane_remain;
254 } else {
255 remain_space->left_road_remain
256 = road_left_width - ego_whole_pass_width - obs_boundary.end_l() - FLAGS_static_obstacle_nudge_l_buffer;
257 }
258
260 remain_space->right_road_remain = remain_space->right_lane_remain;
261 } else {
262 remain_space->right_road_remain = road_right_width - ego_whole_pass_width + obs_boundary.start_l()
263 - FLAGS_static_obstacle_nudge_l_buffer;
264 }
265
266 bool is_passable = remain_space->left_lane_remain > config_.obs_passable_buffer()
267 || remain_space->right_lane_remain > config_.obs_passable_buffer();
268
269 ADEBUG << "CalcObsRemainSpace: [ " << obstacle.Id() << " ]" << ", left right lane_remain: [ "
270 << remain_space->left_lane_remain << ", " << remain_space->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() << " ]";
274
275 // TODO(fengzhiqi) special buffer for different type obstacles
276
277 return is_passable;
278}
279
281 is_in_nudge_state_ = state;
282}
283
284bool NudgeCalculation::IsWithinNudgeScopeObstacle(
285 ReferenceLineInfo* const reference_line_info,
286 const Obstacle& obstacle) {
287 // Obstacle should be non-virtual.
288 if (obstacle.IsVirtual()) {
289 ADEBUG << "obstacle IsVirtual";
290 return false;
291 }
292 // Obstacle should not have ignore decision.
293 if (obstacle.HasLongitudinalDecision() && obstacle.HasLateralDecision() && obstacle.IsIgnore()) {
294 ADEBUG << "obstacle IsIgnore";
295 return false;
296 }
297 // Obstacle should not be moving obstacle.
298 if (!obstacle.IsStatic() || obstacle.speed() > FLAGS_static_obstacle_speed_threshold) {
299 ADEBUG << "obstacle Is not Static";
300 return false;
301 }
302 // Obstacle should in ROI
303 if (obstacle.PerceptionSLBoundary().start_s() - adc_boundary_.end_s() > dis2end_
304 || obstacle.PerceptionSLBoundary().start_s() - adc_boundary_.end_s() > check_forward_dis_
305 || obstacle.PerceptionSLBoundary().end_s() - adc_boundary_.start_s() < 0) {
306 ADEBUG << "obstacle not in ROI";
307 return false;
308 }
309
310 // check obstacle is in the lane
311 bool obs_on_lane = reference_line_info->reference_line().IsOnLane(obstacle.PerceptionSLBoundary());
312 if (!obs_on_lane) {
313 ADEBUG << "obstacle is out of lane width";
314 return false;
315 }
316 return true;
317}
318
319void NudgeCalculation::UpdateTrackingObsInfo(
320 NudgeObstacleInfo* const track_obs_info,
321 const Obstacle& obstacle,
322 bool is_passable,
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();
329 track_obs_info->last_track_time = ::apollo::cyber::Clock::NowInSeconds();
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) {
334 track_obs_info->nudge_probability += 0.08 / config_.obs_nudge_time_out_threshold();
335 track_obs_info->nudge_probability = common::math::Clamp(track_obs_info->nudge_probability, 0.0, 1.0);
336 }
337}
338
339void NudgeCalculation::GetRefLineLaneWidth(
340 const ReferenceLine& reference_line,
341 const double adc_s,
342 const double search_s,
343 double* const lane_left_width,
344 double* const lane_right_width) {
345 double adc_lane_width = PathBoundsDeciderUtil::GetADCLaneWidth(reference_line, adc_s);
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;
351 }
352}
353
354bool NudgeCalculation::MergeObsPolygon(ReferenceLineInfo* const reference_line_info, NudgeInfo* const nudge_info) {
355 if (nudge_info->block_sl_polygons().size() < 1) {
356 AINFO << "MergeObsPolygon: block_sl_polygons is empty, return";
357 return false;
358 }
359
360 // Find first polygon all on road
361 SLPolygon first_sl_polygon;
362 for (size_t i = 0; i < nudge_info->block_sl_polygons().size(); ++i) {
363 auto iter = nudge_info->tracking_nudge_obs_info().find(nudge_info->block_sl_polygons().at(i).id());
364 if (iter != nudge_info->tracking_nudge_obs_info().end() && iter->second.is_all_on_lane) {
365 first_sl_polygon = nudge_info->block_sl_polygons().at(0);
366 break;
367 }
368 }
369 if (first_sl_polygon.id().empty()) {
370 AINFO << "MergeObsPolygon: not found first_sl_polygon";
371 for (auto sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->begin();
372 sl_polygon_iter != nudge_info->mutable_block_sl_polygons()->end();) {
373 auto track_iter = nudge_info->tracking_nudge_obs_info().find((*sl_polygon_iter).id());
374 if (track_iter == nudge_info->tracking_nudge_obs_info().end()) {
375 break;
376 }
377 if (track_iter->second.is_passable && !track_iter->second.is_all_on_lane) {
378 EraseObsInNudgeinfo(nudge_info, (*sl_polygon_iter).id());
379 sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->erase(sl_polygon_iter);
380 } else {
381 ++sl_polygon_iter;
382 }
383 }
384 return false;
385 }
386 // Merge from first polygon
387 std::string merge_polygon_id = "";
388 std::vector<Vec2d> merge_points;
389 for (auto sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->begin();
390 sl_polygon_iter != nudge_info->mutable_block_sl_polygons()->end();) {
391 if (sl_polygon_iter->MinS() - first_sl_polygon.MaxS() > 0.8) {
392 break;
393 }
394 auto track_iter = nudge_info->tracking_nudge_obs_info().find((*sl_polygon_iter).id());
395 if (track_iter == nudge_info->tracking_nudge_obs_info().end()) {
396 break;
397 }
398 if (!track_iter->second.is_all_on_lane) {
399 ++sl_polygon_iter;
400 continue;
401 }
402 merge_points.insert(
403 merge_points.end(),
404 track_iter->second.origin_polygon.points().begin(),
405 track_iter->second.origin_polygon.points().end());
406 merge_polygon_id += (*sl_polygon_iter).id() + "+";
407 // erase obs which is merged
408 sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->erase(sl_polygon_iter);
409 }
410
411 if (merge_points.empty()) {
412 return false;
413 }
414 Polygon2d merge_polygon;
415 if (!common::math::Polygon2d::ComputeConvexHull(merge_points, &merge_polygon)) {
416 return false;
417 }
418
419 // Merge the obstacle near lane boundary
420 for (auto sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->begin();
421 sl_polygon_iter != nudge_info->mutable_block_sl_polygons()->end();) {
422 auto track_iter = nudge_info->tracking_nudge_obs_info().find((*sl_polygon_iter).id());
423 if (track_iter == nudge_info->tracking_nudge_obs_info().end()) {
424 break;
425 }
426 if (!track_iter->second.is_passable) {
427 ++sl_polygon_iter;
428 continue;
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();
431 EraseObsInNudgeinfo(nudge_info, (*sl_polygon_iter).id());
432 sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->erase(sl_polygon_iter);
433 continue;
434 }
435
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) {
439 merge_points.insert(
440 merge_points.end(),
441 track_iter->second.origin_polygon.points().begin(),
442 track_iter->second.origin_polygon.points().end());
443 merge_polygon_id += (*sl_polygon_iter).id() + "+";
444 } else {
445 // erase obs far from lane boundary
446 AINFO << "MergeObsPolygon: erase obs far from lane boundary: " << (*sl_polygon_iter).id();
447 EraseObsInNudgeinfo(nudge_info, (*sl_polygon_iter).id());
448 }
449 // erase obs which is merged
450 sl_polygon_iter = nudge_info->mutable_block_sl_polygons()->erase(sl_polygon_iter);
451 }
452 Polygon2d merge_polygon_update;
453 if (!common::math::Polygon2d::ComputeConvexHull(merge_points, &merge_polygon_update)) {
454 return false;
455 }
456
457 SLBoundary merge_sl_boundary;
458 if (!reference_line_info->reference_line().GetSLBoundary(merge_polygon_update, &merge_sl_boundary)) {
459 nudge_info->mutable_block_sl_polygons()->insert(
460 nudge_info->mutable_block_sl_polygons()->begin(), first_sl_polygon);
461 AINFO << "MergeObsPolygon: GetSLBoundary failed";
462 return false;
463 }
464
465 SLPolygon merge_sl_polygon(merge_sl_boundary, merge_polygon_id);
466 nudge_info->mutable_block_sl_polygons()->insert(nudge_info->mutable_block_sl_polygons()->begin(), merge_sl_polygon);
467
468 if (merge_polygon_update.points().size() > 0) {
469 PrintCurves print_curve;
470 for (const auto& p : merge_polygon_update.points()) {
471 print_curve.AddPoint(merge_polygon_id + "_BlockObsPolygon", p.x(), p.y());
472 }
473 print_curve.AddPoint(
474 merge_polygon_id + "_BlockObsPolygon", merge_polygon.points()[0].x(), merge_polygon.points()[0].y());
475 print_curve.PrintToLog();
476 }
477 AINFO << "MergeObsPolygon: " << merge_polygon_id;
478
479 // sort sl polygons again
480 nudge_info->SortBlockSLPolygons();
481 if (nudge_info->block_sl_polygons().at(0).id() == merge_polygon_id) {
482 return true;
483 }
484 return false;
485}
486
487void NudgeCalculation::EraseObsInNudgeinfo(NudgeInfo* const nudge_info, std::string id) {
488 nudge_info->mutable_update_ids()->erase(id);
489 nudge_info->mutable_tracking_nudge_obs_info()->erase(id);
490}
491
492bool NudgeCalculation::IsProbEnoughToNudge(NudgeInfo* const nudge_info, bool is_merge_obs) {
493 if (nudge_info->block_sl_polygons().empty()) {
494 return false;
495 }
496 SLPolygon first_block_polygon = nudge_info->block_sl_polygons().at(0);
497 double max_nudge_probability = 0.0;
498 if (is_merge_obs) {
499 std::vector<std::string> block_ids;
500 std::string id;
501 std::istringstream ids_stream(first_block_polygon.id());
502 while (std::getline(ids_stream, id, '+')) {
503 block_ids.push_back(id);
504 }
505 for (const auto& obs_id : block_ids) {
506 auto track_iter = nudge_info->tracking_nudge_obs_info().find(obs_id);
507 if (track_iter == nudge_info->tracking_nudge_obs_info().end()) {
508 continue;
509 }
510 max_nudge_probability = std::max(track_iter->second.nudge_probability, max_nudge_probability);
511 }
512 } else {
513 auto track_iter = nudge_info->tracking_nudge_obs_info().find(first_block_polygon.id());
514 if (track_iter != nudge_info->tracking_nudge_obs_info().end()) {
515 max_nudge_probability = std::max(track_iter->second.nudge_probability, max_nudge_probability);
516 }
517 }
518 AINFO << "max_nudge_probability: " << max_nudge_probability;
519 return max_nudge_probability > 0.8;
520}
521
522void NudgeCalculation::CalcNudgeExtraSpace(ReferenceLineInfo* const reference_line_info, NudgeInfo* const nudge_info) {
523 nudge_info->mutable_extra_nudge_key_points()->clear();
524 if (nudge_info->block_sl_polygons().size() < 1) {
525 AINFO << "No block_sl_polygons, return";
526 return;
527 }
528 double start_s = 1000.0;
529 double end_s = -1000.0;
530 double ego_whole_pass_width = veh_config_.width;
531 // need update
532 double extend_length = veh_config_.length * config_.nudge_key_point_extend_length_coefficient();
533
534 int box_index = 0;
535 bool is_left = false;
536 for (auto& sl_polygon : nudge_info->block_sl_polygons()) {
537 if (box_index > 0 && (sl_polygon.MinS() - end_s) > 3.0 * veh_config_.length) {
538 break;
539 }
540 if (box_index < 3) {
541 ego_whole_pass_width = 0.5 * veh_config_.width
542 + util::CalculateEquivalentEgoWidth(*reference_line_info, sl_polygon.MinS(), &is_left);
543 ++box_index;
544 }
545 start_s = std::min(sl_polygon.MinS() - extend_length, start_s);
546 end_s = std::max(sl_polygon.MaxS() + extend_length, end_s);
547 }
548 start_s = std::max(adc_boundary_.start_s(), start_s);
549 end_s = std::max(adc_boundary_.start_s(), end_s);
550
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) {
556 SLPolygon current_polygon = nudge_info->block_sl_polygons().at(index);
557 if ((index > 0 && s < current_polygon.MaxS()) || end_s < current_polygon.MinS()) {
558 continue;
559 }
560 // if ((index < nudge_info->block_sl_polygons().size() - 1 && s > current_polygon.MaxS())
561 // || end_s < current_polygon.MinS()) {
562 // continue;
563 // }
564 left_max_nudge_l = std::max(
565 current_polygon.MaxL() + 0.5 * ego_whole_pass_width + FLAGS_static_obstacle_nudge_l_buffer,
566 left_max_nudge_l);
567 right_min_nudge_l = std::min(
568 current_polygon.MinL() - 0.5 * ego_whole_pass_width - FLAGS_static_obstacle_nudge_l_buffer,
569 right_min_nudge_l);
570 if (s < current_polygon.MinS()) {
571 break;
572 }
573 }
574 SLPoint left_pt, right_pt;
575
576 left_pt.set_s(s);
577 left_pt.set_l(left_max_nudge_l);
578 right_pt.set_s(s);
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);
582 }
583 nudge_info->mutable_extra_nudge_key_points()->emplace_back(left_nudge_pts);
584 nudge_info->mutable_extra_nudge_key_points()->emplace_back(right_nudge_pts);
585
586 PrintCurves left_print_curve;
587 for (auto& pt : nudge_info->extra_nudge_key_points().at(0)) {
588 left_print_curve.AddPoint("LeftKeyPoints_NudgePoints", pt.s(), pt.l());
589 }
590 left_print_curve.PrintToLog();
591
592 PrintCurves right_print_curve;
593 for (auto& pt : nudge_info->extra_nudge_key_points().at(1)) {
594 right_print_curve.AddPoint("RightKeyPoints_NudgePoints", pt.s(), pt.l());
595 }
596 right_print_curve.PrintToLog();
597}
598
599} // namespace planning
600} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
@Brief This is a helper class that can load vehicle configurations.
The class of polygon in 2-D.
Definition polygon2d.h:42
static bool ComputeConvexHull(const std::vector< Vec2d > &points, Polygon2d *const polygon, bool check_area=true)
Compute the convex hull of a group of points.
Definition polygon2d.cc:261
double DistanceTo(const Vec2d &point) const
Compute the distance from a point to the polygon.
Definition polygon2d.cc:45
const std::vector< Vec2d > & points() const
Get the vertices of the polygon.
Definition polygon2d.h:65
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
Frame holds all data for one planning cycle.
Definition frame.h:62
uint32_t SequenceNum() const
Definition frame.cc:423
const ReferenceLineInfo * DriveReferenceLineInfo() const
Definition frame.cc:573
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)
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()
Definition nudge_info.cc:68
const std::vector< SLPolygon > & block_sl_polygons() const
Definition nudge_info.cc:51
const std::unordered_map< std::string, NudgeObstacleInfo > & tracking_nudge_obs_info() const
Definition nudge_info.cc:43
const std::set< std::string > & update_ids() const
Definition nudge_info.cc:58
std::unordered_map< std::string, NudgeObstacleInfo > * mutable_tracking_nudge_obs_info()
Definition nudge_info.cc:47
std::set< std::string > * mutable_update_ids()
Definition nudge_info.cc:61
std::vector< SLPolygon > * mutable_block_sl_polygons()
Definition nudge_info.cc:54
const std::vector< std::vector< SLPoint > > & extra_nudge_key_points() const
Definition nudge_info.cc:65
This is the class that associates an Obstacle with its path properties.
Definition obstacle.h:62
const perception::PerceptionObstacle & Perception() const
Definition obstacle.h:102
bool HasLongitudinalDecision() const
Definition obstacle.cc:636
const std::string & Id() const
Definition obstacle.h:75
bool HasLateralDecision() const
Definition obstacle.cc:631
const SLBoundary & PerceptionSLBoundary() const
Definition obstacle.cc:694
double speed() const
Definition obstacle.h:78
const common::math::Polygon2d & PerceptionPolygon() const
Definition obstacle.h:93
bool IsIgnore() const
Check if this object can be safely ignored.
Definition obstacle.cc:585
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.
const common::VehicleState & vehicle_state() const
const ReferenceLine & reference_line() 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
std::string id() const
Definition sl_polygon.h:86
Planning module main class.
#define ADEBUG
Definition log.h:41
#define AINFO
Definition log.h:42
Some util functions.
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
Definition math_utils.h:155
double CalculateEquivalentEgoWidth(const ReferenceLineInfo &reference_line_info, double s, bool *is_left)
Definition util.cc:160
class register implement
Definition arena_queue.h:37
hdmap::LaneBoundaryType::Type left_lane_boundary_type
Definition nudge_info.h:51
hdmap::LaneBoundaryType::Type right_lane_boundary_type
Definition nudge_info.h:52