47 const std::string &config_dir,
const std::string &name,
48 const std::shared_ptr<DependencyInjector> &injector) {
53 CHECK_NOTNULL(hdmap_);
57 bool res = Decider::LoadConfig<OpenSpaceRoiDeciderConfig>(&config_);
58 AINFO << config_.DebugString();
63 if (frame ==
nullptr) {
64 const std::string msg =
65 "Invalid frame, fail to process the OpenSpaceRoiDecider.";
67 return Status(ErrorCode::PLANNING_ERROR, msg);
73 std::array<Vec2d, 4> spot_vertices;
77 std::vector<std::vector<common::math::Vec2d>> roi_boundary;
79 const auto &roi_type = config_.
roi_type();
82 ParkingInfo parking_info;
83 if (!GetParkingSpot(frame, &parking_info)) {
84 const std::string msg =
"Fail to get parking boundary from map";
86 return Status(ErrorCode::PLANNING_ERROR, msg);
90 parking_info.parking_type);
92 SetOrigin(parking_info, frame);
94 SetParkingSpotEndPose(parking_info, frame);
96 if (!GetParkingBoundary(parking_info, *nearby_path_, frame,
98 const std::string msg =
"Fail to get parking boundary from map";
100 return Status(ErrorCode::PLANNING_ERROR, msg);
103 if (!GetPullOverSpot(frame, &spot_vertices, &nearby_path)) {
104 const std::string msg =
"Fail to get parking boundary from map";
106 return Status(ErrorCode::PLANNING_ERROR, msg);
109 SetOrigin(frame, spot_vertices);
111 SetPullOverSpotEndPose(frame);
113 if (!GetPullOverBoundary(frame, spot_vertices, nearby_path,
115 const std::string msg =
"Fail to get parking boundary from map";
117 return Status(ErrorCode::PLANNING_ERROR, msg);
120 ADEBUG <<
"in Park_and_Go";
124 ADEBUG <<
"nearby_path: " << nearby_path.DebugString();
125 ADEBUG <<
"found nearby_path";
129 .has_adc_init_position()) {
130 const std::string msg =
"ADC initial position is unavailable";
132 return Status(ErrorCode::PLANNING_ERROR, msg);
134 SetOriginFromADC(frame, nearby_path);
140 if (!is_parking_out) {
142 adc_point, 2.0, vehicle_state_.
heading(), M_PI / 3.0,
143 &lane, &s, &l) == -1;
145 if (is_parking_out) {
146 AINFO <<
"GetParkingOutBoundary!!";
147 if (!GetParkingOutBoundary(nearby_path, frame, &roi_boundary)) {
148 const std::string msg =
"Fail to get park and go boundary from map";
150 return Status(ErrorCode::PLANNING_ERROR, msg);
153 AINFO <<
"GetParkAndGoBoundary!!!";
154 if (!GetParkAndGoBoundary(frame, nearby_path, &roi_boundary)) {
155 const std::string msg =
"Fail to get park and go boundary from map";
157 return Status(ErrorCode::PLANNING_ERROR, msg);
161 SetParkAndGoEndPose(frame);
164 const std::string msg =
165 "chosen open space roi secenario type not implemented";
167 return Status(ErrorCode::PLANNING_ERROR, msg);
169 if (!FormulateBoundaryConstraints(roi_boundary, frame)) {
170 const std::string msg =
"Fail to formulate boundary constraints";
172 return Status(ErrorCode::PLANNING_ERROR, msg);
179void OpenSpaceRoiDecider::SetOriginFromADC(
Frame *
const frame,
180 const hdmap::Path &nearby_path) {
182 const auto &park_and_go_status =
183 injector_->planning_context()->planning_status().park_and_go();
185 const double adc_init_x = park_and_go_status.adc_init_position().x();
186 const double adc_init_y = park_and_go_status.adc_init_position().y();
187 const double adc_init_heading = park_and_go_status.adc_init_heading();
188 common::math::Vec2d adc_init_position = {adc_init_x, adc_init_y};
189 const double adc_length = vehicle_params_.
length();
190 const double adc_width = vehicle_params_.
width();
192 Box2d adc_box(adc_init_position, adc_init_heading, adc_length + 2.0,
195 std::vector<common::math::Vec2d> adc_corners;
196 adc_box.GetAllCorners(&adc_corners);
197 for (
size_t i = 0; i < adc_corners.size(); ++i) {
198 AINFO <<
"ADC [" << i <<
"]x: " << std::setprecision(9)
199 << adc_corners[i].x();
200 AINFO <<
"ADC [" << i <<
"]y: " << std::setprecision(9)
201 << adc_corners[i].y();
203 auto left_top = adc_corners[1];
205 ADEBUG <<
"left_top x: " << std::setprecision(9) << left_top.x();
206 ADEBUG <<
"left_top y: " << std::setprecision(9) << left_top.y();
212 if (!nearby_path.GetHeadingAlongPath(left_top, &heading)) {
213 AERROR <<
"fail to get heading on reference line";
217 frame->mutable_open_space_info()->set_origin_heading(
219 ADEBUG <<
"heading: " << heading;
220 frame->mutable_open_space_info()->mutable_origin_point()->set_x(left_top.x());
221 frame->mutable_open_space_info()->mutable_origin_point()->set_y(left_top.y());
224void OpenSpaceRoiDecider::SetOrigin(
225 Frame *
const frame,
const std::array<common::math::Vec2d, 4> &vertices) {
226 auto left_top = vertices[0];
227 auto right_top = vertices[3];
230 Vec2d heading_vec = right_top - left_top;
231 frame->mutable_open_space_info()->set_origin_heading(heading_vec.Angle());
232 frame->mutable_open_space_info()->mutable_origin_point()->set_x(left_top.x());
233 frame->mutable_open_space_info()->mutable_origin_point()->set_y(left_top.y());
236void OpenSpaceRoiDecider::SetOrigin(
const ParkingInfo &parking_info,
237 Frame *
const frame) {
238 auto left_top = parking_info.corner_points[0];
239 auto right_top = parking_info.corner_points[1];
242 Vec2d heading_vec = right_top - left_top;
243 frame->mutable_open_space_info()->set_origin_heading(heading_vec.Angle());
244 frame->mutable_open_space_info()->mutable_origin_point()->set_x(left_top.x());
245 frame->mutable_open_space_info()->mutable_origin_point()->set_y(left_top.y());
248void OpenSpaceRoiDecider::SetParkingSpotEndPose(
const ParkingInfo &parking_info,
249 Frame *
const frame) {
250 auto left_top = parking_info.corner_points[0];
251 auto left_down = parking_info.corner_points[3];
252 auto right_down = parking_info.corner_points[2];
253 auto right_top = parking_info.corner_points[1];
255 const auto &origin_point = frame->open_space_info().origin_point();
256 const auto &origin_heading = frame->open_space_info().origin_heading();
259 left_top -= origin_point;
260 left_top.SelfRotate(-origin_heading);
261 left_down -= origin_point;
262 left_down.SelfRotate(-origin_heading);
263 right_top -= origin_point;
264 right_top.SelfRotate(-origin_heading);
265 right_down -= origin_point;
266 right_down.SelfRotate(-origin_heading);
268 double parking_heading = 0;
273 if (parking_inwards) {
274 parking_heading = (left_down - left_top).Angle();
275 Vec2d middle_top = (left_top + right_top) / 2.0;
278 parking_depth_buffer);
280 parking_heading = (left_top - left_down).Angle();
281 Vec2d middle_down = (left_down + right_down) / 2.0;
284 parking_depth_buffer);
287 parking_heading = (right_top - left_top).Angle();
288 Vec2d middle_left = (left_top + left_down) / 2.0;
289 end_pt = middle_left +
294 frame->mutable_open_space_info()->mutable_open_space_end_pose();
295 end_pose->push_back(end_pt.x());
296 end_pose->push_back(end_pt.y());
297 end_pose->push_back(parking_heading);
298 end_pose->push_back(0.0);
301void OpenSpaceRoiDecider::SetPullOverSpotEndPose(
Frame *
const frame) {
302 const auto &pull_over_status =
303 injector_->planning_context()->planning_status().pull_over();
304 const double pull_over_x = pull_over_status.position().x();
305 const double pull_over_y = pull_over_status.position().y();
306 double pull_over_theta = pull_over_status.theta();
309 const auto &origin_point = frame->open_space_info().origin_point();
310 const auto &origin_heading = frame->open_space_info().origin_heading();
311 Vec2d center(pull_over_x, pull_over_y);
312 center -= origin_point;
313 center.SelfRotate(-origin_heading);
318 frame->mutable_open_space_info()->mutable_open_space_end_pose();
319 end_pose->push_back(center.x());
320 end_pose->push_back(center.y());
321 end_pose->push_back(pull_over_theta);
323 end_pose->push_back(0.0);
326void OpenSpaceRoiDecider::SetParkAndGoEndPose(
Frame *
const frame) {
328 const double kSpeedRatio = 0.1;
331 auto park_and_go_status =
injector_->planning_context()
332 ->mutable_planning_status()
333 ->mutable_park_and_go();
335 const double adc_init_x = park_and_go_status->adc_init_position().x();
336 const double adc_init_y = park_and_go_status->adc_init_position().y();
338 ADEBUG <<
"ADC position (x): " << std::setprecision(9) << adc_init_x;
339 ADEBUG <<
"ADC position (y): " << std::setprecision(9) << adc_init_y;
341 const common::math::Vec2d adc_position = {adc_init_x, adc_init_y};
342 common::SLPoint adc_position_sl;
345 const auto &reference_line_list = frame->reference_line_info();
346 ADEBUG << reference_line_list.size();
347 const auto reference_line_info = std::min_element(
348 reference_line_list.begin(), reference_line_list.end(),
349 [&](
const ReferenceLineInfo &ref_a,
const ReferenceLineInfo &ref_b) {
350 common::SLPoint adc_position_sl_a;
351 common::SLPoint adc_position_sl_b;
352 ref_a.reference_line().XYToSL(adc_position, &adc_position_sl_a);
353 ref_b.reference_line().XYToSL(adc_position, &adc_position_sl_b);
354 return std::fabs(adc_position_sl_a.l()) <
355 std::fabs(adc_position_sl_b.l());
358 const auto &reference_line = reference_line_info->reference_line();
359 reference_line.XYToSL(adc_position, &adc_position_sl);
362 const double target_s = adc_position_sl.s() + kSTargetBuffer;
363 const auto reference_point = reference_line.GetReferencePoint(target_s);
364 const double target_x = reference_point.x();
365 const double target_y = reference_point.y();
366 double target_theta = reference_point.heading();
368 park_and_go_status->mutable_adc_adjust_end_pose()->set_x(target_x);
369 park_and_go_status->mutable_adc_adjust_end_pose()->set_y(target_y);
371 ADEBUG <<
"center.x(): " << std::setprecision(9) << target_x;
372 ADEBUG <<
"center.y(): " << std::setprecision(9) << target_y;
373 ADEBUG <<
"target_theta: " << std::setprecision(9) << target_theta;
376 const auto &origin_point = frame->open_space_info().origin_point();
377 const auto &origin_heading = frame->open_space_info().origin_heading();
378 Vec2d center(target_x, target_y);
379 center -= origin_point;
380 center.SelfRotate(-origin_heading);
384 frame->mutable_open_space_info()->mutable_open_space_end_pose();
386 end_pose->push_back(center.x());
387 end_pose->push_back(center.y());
388 end_pose->push_back(target_theta);
390 ADEBUG <<
"ADC position (x): " << std::setprecision(9) << (*end_pose)[0];
391 ADEBUG <<
"ADC position (y): " << std::setprecision(9) << (*end_pose)[1];
392 ADEBUG <<
"reference_line ID: " << reference_line_info->Lanes().Id();
395 double target_speed = reference_line.GetSpeedLimitFromS(target_s);
396 end_pose->push_back(kSpeedRatio * target_speed);
399void OpenSpaceRoiDecider::GetRoadBoundary(
400 const hdmap::Path &nearby_path,
const double center_line_s,
401 const common::math::Vec2d &origin_point,
const double origin_heading,
402 std::vector<Vec2d> *left_lane_boundary,
403 std::vector<Vec2d> *right_lane_boundary,
404 std::vector<Vec2d> *center_lane_boundary_left,
405 std::vector<Vec2d> *center_lane_boundary_right,
406 std::vector<double> *center_lane_s_left,
407 std::vector<double> *center_lane_s_right,
408 std::vector<double> *left_lane_road_width,
409 std::vector<double> *right_lane_road_width) {
413 hdmap::MapPathPoint start_point = nearby_path.GetSmoothPoint(start_s);
414 double last_check_point_heading = start_point.heading();
416 double check_point_s = start_s;
422 while (check_point_s <= end_s) {
423 hdmap::MapPathPoint check_point = nearby_path.GetSmoothPoint(check_point_s);
424 double check_point_heading = check_point.heading();
425 bool is_center_lane_heading_change =
427 last_check_point_heading)) >
429 last_check_point_heading = check_point_heading;
431 ADEBUG <<
"is is_center_lane_heading_change: "
432 << is_center_lane_heading_change;
436 bool is_anchor_point = check_point_s == start_s || check_point_s == end_s ||
437 is_center_lane_heading_change;
439 AddBoundaryKeyPoint(nearby_path, check_point_s, start_s, end_s,
440 is_anchor_point,
true, center_lane_boundary_left,
441 left_lane_boundary, center_lane_s_left,
442 left_lane_road_width);
444 AddBoundaryKeyPoint(nearby_path, check_point_s, start_s, end_s,
445 is_anchor_point,
false, center_lane_boundary_right,
446 right_lane_boundary, center_lane_s_right,
447 right_lane_road_width);
448 if (check_point_s == end_s) {
453 check_point_s = check_point_s >= end_s ? end_s : check_point_s;
456 size_t left_point_size = left_lane_boundary->size();
457 size_t right_point_size = right_lane_boundary->size();
458 for (
size_t i = 0; i < left_point_size; i++) {
459 left_lane_boundary->at(i) -= origin_point;
460 left_lane_boundary->at(i).SelfRotate(-origin_heading);
462 for (
size_t i = 0; i < right_point_size; i++) {
463 right_lane_boundary->at(i) -= origin_point;
464 right_lane_boundary->at(i).SelfRotate(-origin_heading);
468void OpenSpaceRoiDecider::GetRoadBoundaryFromMap(
469 const hdmap::Path &nearby_path,
const double center_line_s,
470 const Vec2d &origin_point,
const double origin_heading,
471 std::vector<Vec2d> *left_lane_boundary,
472 std::vector<Vec2d> *right_lane_boundary,
473 std::vector<Vec2d> *center_lane_boundary_left,
474 std::vector<Vec2d> *center_lane_boundary_right,
475 std::vector<double> *center_lane_s_left,
476 std::vector<double> *center_lane_s_right,
477 std::vector<double> *left_lane_road_width,
478 std::vector<double> *right_lane_road_width) {
482 hdmap::MapPathPoint start_point = nearby_path.GetSmoothPoint(start_s);
484 double check_point_s = start_s;
486 while (check_point_s <= end_s) {
487 hdmap::MapPathPoint check_point = nearby_path.GetSmoothPoint(check_point_s);
490 double left_road_width = nearby_path.GetRoadLeftWidth(check_point_s);
491 double right_road_width = nearby_path.GetRoadRightWidth(check_point_s);
493 double current_road_width = std::max(left_road_width, right_road_width);
496 common::PointENU check_point_xy;
497 std::vector<hdmap::RoadRoiPtr> road_boundaries;
498 std::vector<hdmap::JunctionInfoConstPtr> junctions;
499 check_point_xy.set_x(check_point.x());
500 check_point_xy.set_y(check_point.y());
502 &road_boundaries, &junctions);
504 if (check_point_s < center_line_s) {
506 i < (*road_boundaries.at(0)).left_boundary.line_points.size(); i++) {
507 right_lane_boundary->emplace_back(
508 Vec2d((*road_boundaries.at(0)).left_boundary.line_points[i].x(),
509 (*road_boundaries.at(0)).left_boundary.line_points[i].y()));
512 i < (*road_boundaries.at(0)).right_boundary.line_points.size();
514 left_lane_boundary->emplace_back(
515 Vec2d((*road_boundaries.at(0)).right_boundary.line_points[i].x(),
516 (*road_boundaries.at(0)).right_boundary.line_points[i].y()));
520 i < (*road_boundaries.at(0)).left_boundary.line_points.size(); i++) {
521 left_lane_boundary->emplace_back(
522 Vec2d((*road_boundaries.at(0)).left_boundary.line_points[i].x(),
523 (*road_boundaries.at(0)).left_boundary.line_points[i].y()));
526 i < (*road_boundaries.at(0)).right_boundary.line_points.size();
528 right_lane_boundary->emplace_back(
529 Vec2d((*road_boundaries.at(0)).right_boundary.line_points[i].x(),
530 (*road_boundaries.at(0)).right_boundary.line_points[i].y()));
534 center_lane_boundary_right->emplace_back(check_point);
535 center_lane_boundary_left->emplace_back(check_point);
536 center_lane_s_left->emplace_back(check_point_s);
537 center_lane_s_right->emplace_back(check_point_s);
538 left_lane_road_width->emplace_back(left_road_width);
539 right_lane_road_width->emplace_back(right_road_width);
544 size_t left_point_size = left_lane_boundary->size();
545 size_t right_point_size = right_lane_boundary->size();
546 ADEBUG <<
"right_road_boundary size: " << right_lane_boundary->size();
547 ADEBUG <<
"left_road_boundary size: " << left_lane_boundary->size();
548 for (
size_t i = 0; i < left_point_size; i++) {
549 left_lane_boundary->at(i) -= origin_point;
550 left_lane_boundary->at(i).SelfRotate(-origin_heading);
551 ADEBUG <<
"left_road_boundary: [" << std::setprecision(9)
552 << left_lane_boundary->at(i).x() <<
", "
553 << left_lane_boundary->at(i).y() <<
"]";
555 for (
size_t i = 0; i < right_point_size; i++) {
556 right_lane_boundary->at(i) -= origin_point;
557 right_lane_boundary->at(i).SelfRotate(-origin_heading);
558 ADEBUG <<
"right_road_boundary: [" << std::setprecision(9)
559 << right_lane_boundary->at(i).x() <<
", "
560 << right_lane_boundary->at(i).y() <<
"]";
562 if (!left_lane_boundary->empty()) {
563 sort(left_lane_boundary->begin(), left_lane_boundary->end(),
564 [](
const Vec2d &first_pt,
const Vec2d &second_pt) {
565 return first_pt.x() < second_pt.x() ||
566 (first_pt.x() == second_pt.x() &&
567 first_pt.y() < second_pt.y());
570 std::unique(left_lane_boundary->begin(), left_lane_boundary->end());
571 left_lane_boundary->erase(unique_end, left_lane_boundary->end());
573 if (!right_lane_boundary->empty()) {
574 sort(right_lane_boundary->begin(), right_lane_boundary->end(),
575 [](
const Vec2d &first_pt,
const Vec2d &second_pt) {
576 return first_pt.x() < second_pt.x() ||
577 (first_pt.x() == second_pt.x() &&
578 first_pt.y() < second_pt.y());
581 std::unique(right_lane_boundary->begin(), right_lane_boundary->end());
582 right_lane_boundary->erase(unique_end, right_lane_boundary->end());
586void OpenSpaceRoiDecider::AddBoundaryKeyPoint(
587 const hdmap::Path &nearby_path,
const double check_point_s,
588 const double start_s,
const double end_s,
const bool is_anchor_point,
589 const bool is_left_curb, std::vector<Vec2d> *center_lane_boundary,
590 std::vector<Vec2d> *curb_lane_boundary, std::vector<double> *center_lane_s,
591 std::vector<double> *road_width) {
615 const double previous_distance_s =
617 const double next_distance_s =
620 hdmap::MapPathPoint current_check_point =
621 nearby_path.GetSmoothPoint(check_point_s);
623 double current_check_point_heading = current_check_point.heading();
624 double current_road_width =
625 is_left_curb ? nearby_path.GetRoadLeftWidth(check_point_s)
626 : nearby_path.GetRoadRightWidth(check_point_s);
629 if (is_anchor_point) {
630 double point_vec_cos =
631 is_left_curb ? std::cos(current_check_point_heading + M_PI / 2.0)
632 :
std::
cos(current_check_point_heading - M_PI / 2.0);
633 double point_vec_sin =
634 is_left_curb ? std::sin(current_check_point_heading + M_PI / 2.0)
635 :
std::
sin(current_check_point_heading - M_PI / 2.0);
636 Vec2d curb_lane_point = Vec2d(current_road_width * point_vec_cos,
637 current_road_width * point_vec_sin);
638 curb_lane_point = curb_lane_point + current_check_point;
639 center_lane_boundary->push_back(current_check_point);
640 curb_lane_boundary->push_back(curb_lane_point);
641 center_lane_s->push_back(check_point_s);
642 road_width->push_back(current_road_width);
645 double previous_road_width =
647 ? nearby_path.GetRoadLeftWidth(check_point_s - previous_distance_s)
648 : nearby_path.GetRoadRightWidth(check_point_s - previous_distance_s);
649 double next_road_width =
651 ? nearby_path.GetRoadLeftWidth(check_point_s + next_distance_s)
652 : nearby_path.GetRoadRightWidth(check_point_s + next_distance_s);
653 double previous_curb_segment_angle =
654 (current_road_width - previous_road_width) / previous_distance_s;
655 double next_segment_angle =
656 (next_road_width - current_road_width) / next_distance_s;
657 double current_curb_point_delta_theta =
658 next_segment_angle - previous_curb_segment_angle;
662 if (std::abs(current_curb_point_delta_theta) >
664 double point_vec_cos =
665 is_left_curb ? std::cos(current_check_point_heading + M_PI / 2.0)
666 :
std::
cos(current_check_point_heading - M_PI / 2.0);
667 double point_vec_sin =
668 is_left_curb ? std::sin(current_check_point_heading + M_PI / 2.0)
669 :
std::
sin(current_check_point_heading - M_PI / 2.0);
670 Vec2d curb_lane_point = Vec2d(current_road_width * point_vec_cos,
671 current_road_width * point_vec_sin);
672 curb_lane_point = curb_lane_point + current_check_point;
673 center_lane_boundary->push_back(current_check_point);
674 curb_lane_boundary->push_back(curb_lane_point);
675 center_lane_s->push_back(check_point_s);
676 road_width->push_back(current_road_width);
680bool OpenSpaceRoiDecider::GetParkingBoundary(
681 const ParkingInfo &parking_info,
const hdmap::Path &nearby_path,
683 std::vector<std::vector<common::math::Vec2d>> *
const roi_parking_boundary) {
684 auto left_top = parking_info.corner_points[0];
685 ADEBUG << std::fixed <<
"left_top: " << left_top.x() <<
", " << left_top.y();
686 auto left_down = parking_info.corner_points[3];
687 ADEBUG << std::fixed <<
"left_down: " << left_down.x() <<
", "
689 auto right_down = parking_info.corner_points[2];
690 ADEBUG << std::fixed <<
"right_down: " << right_down.x() <<
", "
692 auto right_top = parking_info.corner_points[1];
693 ADEBUG << std::fixed <<
"right_top: " << right_top.x() <<
", "
696 const auto &origin_point = frame->open_space_info().origin_point();
697 ADEBUG << std::fixed <<
"origin_point: " << origin_point.x() <<
", "
699 const auto &origin_heading = frame->open_space_info().origin_heading();
701 double left_top_s = 0.0;
702 double left_top_l = 0.0;
703 double right_top_s = 0.0;
704 double right_top_l = 0.0;
705 if (!(nearby_path.GetProjection(left_top, &left_top_s, &left_top_l) &&
706 nearby_path.GetProjection(right_top, &right_top_s, &right_top_l))) {
707 AERROR <<
"fail to get parking spot points' projections on reference line";
711 left_top -= origin_point;
712 left_top.SelfRotate(-origin_heading);
713 left_down -= origin_point;
714 left_down.SelfRotate(-origin_heading);
715 right_top -= origin_point;
716 right_top.SelfRotate(-origin_heading);
717 right_down -= origin_point;
718 right_down.SelfRotate(-origin_heading);
720 const double center_line_s = (left_top_s + right_top_s) / 2.0;
721 std::vector<Vec2d> left_lane_boundary;
722 std::vector<Vec2d> right_lane_boundary;
725 std::vector<Vec2d> center_lane_boundary_left;
728 std::vector<Vec2d> center_lane_boundary_right;
730 std::vector<double> center_lane_s_left;
732 std::vector<double> center_lane_s_right;
736 std::vector<double> left_lane_road_width;
740 std::vector<double> right_lane_road_width;
742 GetRoadBoundary(nearby_path, center_line_s, origin_point, origin_heading,
743 &left_lane_boundary, &right_lane_boundary,
744 ¢er_lane_boundary_left, ¢er_lane_boundary_right,
745 ¢er_lane_s_left, ¢er_lane_s_right,
746 &left_lane_road_width, &right_lane_road_width);
751 const double average_l = (left_top_l + right_top_l) / 2.0;
752 std::vector<Vec2d> boundary_points;
759 ADEBUG <<
"average_l is less than 0 in OpenSpaceROI";
760 size_t point_size = right_lane_boundary.size();
761 for (
size_t i = 0; i < point_size; i++) {
762 right_lane_boundary[i].SelfRotate(origin_heading);
763 right_lane_boundary[i] += origin_point;
764 right_lane_boundary[i] -= center_lane_boundary_right[i];
765 right_lane_boundary[i] /= right_lane_road_width[i];
766 right_lane_boundary[i] *= (-average_l);
767 right_lane_boundary[i] += center_lane_boundary_right[i];
768 right_lane_boundary[i] -= origin_point;
769 right_lane_boundary[i].SelfRotate(-origin_heading);
772 auto point_left_to_left_top_connor_s = std::lower_bound(
773 center_lane_s_right.begin(), center_lane_s_right.end(), left_top_s);
774 size_t point_left_to_left_top_connor_index = std::distance(
775 center_lane_s_right.begin(), point_left_to_left_top_connor_s);
776 point_left_to_left_top_connor_index =
777 point_left_to_left_top_connor_index == 0
778 ? point_left_to_left_top_connor_index
779 : point_left_to_left_top_connor_index - 1;
780 auto point_left_to_left_top_connor_itr =
781 right_lane_boundary.begin() + point_left_to_left_top_connor_index;
782 auto point_right_to_right_top_connor_s = std::upper_bound(
783 center_lane_s_right.begin(), center_lane_s_right.end(), right_top_s);
784 size_t point_right_to_right_top_connor_index = std::distance(
785 center_lane_s_right.begin(), point_right_to_right_top_connor_s);
786 auto point_right_to_right_top_connor_itr =
787 right_lane_boundary.begin() + point_right_to_right_top_connor_index;
789 std::copy(right_lane_boundary.begin(), point_left_to_left_top_connor_itr,
790 std::back_inserter(boundary_points));
792 std::vector<Vec2d> parking_spot_boundary{left_top, left_down, right_down,
795 std::copy(parking_spot_boundary.begin(), parking_spot_boundary.end(),
796 std::back_inserter(boundary_points));
798 std::copy(point_right_to_right_top_connor_itr, right_lane_boundary.end(),
799 std::back_inserter(boundary_points));
801 std::reverse_copy(left_lane_boundary.begin(), left_lane_boundary.end(),
802 std::back_inserter(boundary_points));
805 boundary_points.push_back(right_lane_boundary.front());
808 for (
size_t i = 0; i < point_left_to_left_top_connor_index; i++) {
809 std::vector<Vec2d> segment{right_lane_boundary[i],
810 right_lane_boundary[i + 1]};
811 roi_parking_boundary->push_back(segment);
814 std::vector<Vec2d> left_stitching_segment{
815 right_lane_boundary[point_left_to_left_top_connor_index], left_top};
816 roi_parking_boundary->push_back(left_stitching_segment);
818 std::vector<Vec2d> left_parking_spot_segment{left_top, left_down};
819 std::vector<Vec2d> down_parking_spot_segment{left_down, right_down};
820 std::vector<Vec2d> right_parking_spot_segment{right_down, right_top};
821 roi_parking_boundary->push_back(left_parking_spot_segment);
822 roi_parking_boundary->push_back(down_parking_spot_segment);
823 roi_parking_boundary->push_back(right_parking_spot_segment);
825 std::vector<Vec2d> right_stitching_segment{
826 right_top, right_lane_boundary[point_right_to_right_top_connor_index]};
827 roi_parking_boundary->push_back(right_stitching_segment);
829 size_t right_lane_boundary_last_index = right_lane_boundary.size() - 1;
830 for (
size_t i = point_right_to_right_top_connor_index;
831 i < right_lane_boundary_last_index; i++) {
832 std::vector<Vec2d> segment{right_lane_boundary[i],
833 right_lane_boundary[i + 1]};
834 roi_parking_boundary->push_back(segment);
837 size_t left_lane_boundary_last_index = left_lane_boundary.size() - 1;
838 for (
size_t i = left_lane_boundary_last_index; i > 0; i--) {
839 std::vector<Vec2d> segment{left_lane_boundary[i],
840 left_lane_boundary[i - 1]};
841 roi_parking_boundary->push_back(segment);
847 ADEBUG <<
"average_l is greater than 0 in OpenSpaceROI";
848 size_t point_size = left_lane_boundary.size();
849 for (
size_t i = 0; i < point_size; i++) {
850 left_lane_boundary[i].SelfRotate(origin_heading);
851 left_lane_boundary[i] += origin_point;
852 left_lane_boundary[i] -= center_lane_boundary_left[i];
853 left_lane_boundary[i] /= left_lane_road_width[i];
854 left_lane_boundary[i] *= average_l;
855 left_lane_boundary[i] += center_lane_boundary_left[i];
856 left_lane_boundary[i] -= origin_point;
857 left_lane_boundary[i].SelfRotate(-origin_heading);
858 ADEBUG <<
"left_lane_boundary[" << i <<
"]: " << left_lane_boundary[i].x()
859 <<
", " << left_lane_boundary[i].y();
862 auto point_right_to_right_top_connor_s = std::lower_bound(
863 center_lane_s_left.begin(), center_lane_s_left.end(), right_top_s);
864 size_t point_right_to_right_top_connor_index = std::distance(
865 center_lane_s_left.begin(), point_right_to_right_top_connor_s);
867 auto point_right_to_right_top_connor_itr =
868 left_lane_boundary.begin() + point_right_to_right_top_connor_index;
870 auto point_left_to_left_top_connor_s = std::upper_bound(
871 center_lane_s_left.begin(), center_lane_s_left.end(), left_top_s);
872 size_t point_left_to_left_top_connor_index = std::distance(
873 center_lane_s_left.begin(), point_left_to_left_top_connor_s);
874 point_left_to_left_top_connor_index =
875 point_left_to_left_top_connor_index == 0
876 ? point_left_to_left_top_connor_index
877 : point_left_to_left_top_connor_index - 1;
878 auto point_left_to_left_top_connor_itr =
879 left_lane_boundary.begin() + point_left_to_left_top_connor_index;
881 std::copy(right_lane_boundary.begin(), right_lane_boundary.end(),
882 std::back_inserter(boundary_points));
884 std::reverse_copy(point_left_to_left_top_connor_itr,
885 left_lane_boundary.end(),
886 std::back_inserter(boundary_points));
888 std::vector<Vec2d> parking_spot_boundary{left_top, left_down, right_down,
890 std::copy(parking_spot_boundary.begin(), parking_spot_boundary.end(),
891 std::back_inserter(boundary_points));
893 std::reverse_copy(left_lane_boundary.begin(),
894 point_right_to_right_top_connor_itr,
895 std::back_inserter(boundary_points));
898 boundary_points.push_back(right_lane_boundary.front());
901 size_t right_lane_boundary_last_index = right_lane_boundary.size() - 1;
902 for (
size_t i = 0; i < right_lane_boundary_last_index; i++) {
903 std::vector<Vec2d> segment{right_lane_boundary[i],
904 right_lane_boundary[i + 1]};
905 roi_parking_boundary->push_back(segment);
908 size_t left_lane_boundary_last_index = left_lane_boundary.size() - 1;
909 for (
size_t i = left_lane_boundary_last_index;
910 i > point_right_to_right_top_connor_index; i--) {
911 std::vector<Vec2d> segment{left_lane_boundary[i],
912 left_lane_boundary[i - 1]};
913 roi_parking_boundary->push_back(segment);
916 std::vector<Vec2d> left_stitching_segment{
917 left_lane_boundary[point_right_to_right_top_connor_index], right_top};
918 roi_parking_boundary->push_back(left_stitching_segment);
920 std::vector<Vec2d> right_parking_spot_segment{right_top, right_down};
921 std::vector<Vec2d> down_parking_spot_segment{right_down, left_down};
922 std::vector<Vec2d> left_parking_spot_segment{left_down, left_top};
923 roi_parking_boundary->push_back(right_parking_spot_segment);
924 roi_parking_boundary->push_back(down_parking_spot_segment);
925 roi_parking_boundary->push_back(left_parking_spot_segment);
927 std::vector<Vec2d> right_stitching_segment{
928 left_top, left_lane_boundary[point_left_to_left_top_connor_index]};
929 roi_parking_boundary->push_back(right_stitching_segment);
931 for (
size_t i = point_left_to_left_top_connor_index; i > 0; --i) {
932 std::vector<Vec2d> segment{left_lane_boundary[i],
933 left_lane_boundary[i - 1]};
934 roi_parking_boundary->push_back(segment);
939 if (!FuseLineSegments(roi_parking_boundary)) {
940 AERROR <<
"FuseLineSegments failed in parking ROI";
944 auto xminmax = std::minmax_element(
945 boundary_points.begin(), boundary_points.end(),
946 [](
const Vec2d &a,
const Vec2d &b) { return a.x() < b.x(); });
947 auto yminmax = std::minmax_element(
948 boundary_points.begin(), boundary_points.end(),
949 [](
const Vec2d &a,
const Vec2d &b) { return a.y() < b.y(); });
950 std::vector<double> ROI_xy_boundary{xminmax.first->x(), xminmax.second->x(),
951 yminmax.first->y(), yminmax.second->y()};
953 frame->mutable_open_space_info()->mutable_ROI_xy_boundary();
954 xy_boundary->assign(ROI_xy_boundary.begin(), ROI_xy_boundary.end());
956 Vec2d vehicle_xy = Vec2d(vehicle_state_.
x(), vehicle_state_.
y());
957 vehicle_xy -= origin_point;
958 vehicle_xy.SelfRotate(-origin_heading);
959 if (vehicle_xy.x() < ROI_xy_boundary[0] ||
960 vehicle_xy.x() > ROI_xy_boundary[1] ||
961 vehicle_xy.y() < ROI_xy_boundary[2] ||
962 vehicle_xy.y() > ROI_xy_boundary[3]) {
963 AERROR <<
"vehicle outside of xy boundary of parking ROI";
969bool OpenSpaceRoiDecider::GetPullOverBoundary(
970 Frame *
const frame,
const std::array<common::math::Vec2d, 4> &vertices,
971 const hdmap::Path &nearby_path,
972 std::vector<std::vector<common::math::Vec2d>> *
const roi_parking_boundary) {
973 auto left_top = vertices[0];
974 auto left_down = vertices[1];
975 auto right_down = vertices[2];
976 auto right_top = vertices[3];
978 const auto &origin_point = frame->open_space_info().origin_point();
979 const auto &origin_heading = frame->open_space_info().origin_heading();
981 double left_top_s = 0.0;
982 double left_top_l = 0.0;
983 double right_top_s = 0.0;
984 double right_top_l = 0.0;
985 if (!(nearby_path.GetProjection(left_top, &left_top_s, &left_top_l) &&
986 nearby_path.GetProjection(right_top, &right_top_s, &right_top_l))) {
987 AERROR <<
"fail to get parking spot points' projections on reference line";
991 left_top -= origin_point;
992 left_top.SelfRotate(-origin_heading);
993 left_down -= origin_point;
994 left_down.SelfRotate(-origin_heading);
995 right_top -= origin_point;
996 right_top.SelfRotate(-origin_heading);
997 right_down -= origin_point;
998 right_down.SelfRotate(-origin_heading);
1000 const double center_line_s = (left_top_s + right_top_s) / 2.0;
1001 std::vector<Vec2d> left_lane_boundary;
1002 std::vector<Vec2d> right_lane_boundary;
1003 std::vector<Vec2d> center_lane_boundary_left;
1004 std::vector<Vec2d> center_lane_boundary_right;
1005 std::vector<double> center_lane_s_left;
1006 std::vector<double> center_lane_s_right;
1007 std::vector<double> left_lane_road_width;
1008 std::vector<double> right_lane_road_width;
1010 GetRoadBoundary(nearby_path, center_line_s, origin_point, origin_heading,
1011 &left_lane_boundary, &right_lane_boundary,
1012 ¢er_lane_boundary_left, ¢er_lane_boundary_right,
1013 ¢er_lane_s_left, ¢er_lane_s_right,
1014 &left_lane_road_width, &right_lane_road_width);
1017 std::reverse(left_lane_boundary.begin(), left_lane_boundary.end());
1019 std::vector<Vec2d> boundary_points;
1020 std::copy(right_lane_boundary.begin(), right_lane_boundary.end(),
1021 std::back_inserter(boundary_points));
1022 std::copy(left_lane_boundary.begin(), left_lane_boundary.end(),
1023 std::back_inserter(boundary_points));
1025 size_t right_lane_boundary_last_index = right_lane_boundary.size() - 1;
1026 for (
size_t i = 0; i < right_lane_boundary_last_index; i++) {
1027 std::vector<Vec2d> segment{right_lane_boundary[i],
1028 right_lane_boundary[i + 1]};
1029 roi_parking_boundary->push_back(segment);
1032 size_t left_lane_boundary_last_index = left_lane_boundary.size() - 1;
1033 for (
size_t i = left_lane_boundary_last_index; i > 0; i--) {
1034 std::vector<Vec2d> segment{left_lane_boundary[i],
1035 left_lane_boundary[i - 1]};
1036 roi_parking_boundary->push_back(segment);
1040 if (!FuseLineSegments(roi_parking_boundary)) {
1044 auto xminmax = std::minmax_element(
1045 boundary_points.begin(), boundary_points.end(),
1046 [](
const Vec2d &a,
const Vec2d &b) { return a.x() < b.x(); });
1047 auto yminmax = std::minmax_element(
1048 boundary_points.begin(), boundary_points.end(),
1049 [](
const Vec2d &a,
const Vec2d &b) { return a.y() < b.y(); });
1050 std::vector<double> ROI_xy_boundary{xminmax.first->x(), xminmax.second->x(),
1051 yminmax.first->y(), yminmax.second->y()};
1053 frame->mutable_open_space_info()->mutable_ROI_xy_boundary();
1054 xy_boundary->assign(ROI_xy_boundary.begin(), ROI_xy_boundary.end());
1056 Vec2d vehicle_xy = Vec2d(vehicle_state_.
x(), vehicle_state_.
y());
1057 vehicle_xy -= origin_point;
1058 vehicle_xy.SelfRotate(-origin_heading);
1059 if (vehicle_xy.x() < ROI_xy_boundary[0] ||
1060 vehicle_xy.x() > ROI_xy_boundary[1] ||
1061 vehicle_xy.y() < ROI_xy_boundary[2] ||
1062 vehicle_xy.y() > ROI_xy_boundary[3]) {
1063 AERROR <<
"vehicle outside of xy boundary of parking ROI";
1069bool OpenSpaceRoiDecider::GetParkAndGoBoundary(
1070 Frame *
const frame,
const hdmap::Path &nearby_path,
1071 std::vector<std::vector<common::math::Vec2d>> *
const roi_parking_boundary) {
1072 const auto &park_and_go_status =
1073 injector_->planning_context()->planning_status().park_and_go();
1074 const double adc_init_x = park_and_go_status.adc_init_position().x();
1075 const double adc_init_y = park_and_go_status.adc_init_position().y();
1076 const double adc_init_heading = park_and_go_status.adc_init_heading();
1077 common::math::Vec2d adc_init_position = {adc_init_x, adc_init_y};
1078 const double adc_length = vehicle_params_.
length();
1079 const double adc_width = vehicle_params_.
width();
1081 Box2d adc_box(adc_init_position, adc_init_heading, adc_length, adc_width);
1083 std::vector<common::math::Vec2d> adc_corners;
1084 adc_box.GetAllCorners(&adc_corners);
1085 auto left_top = adc_corners[1];
1086 auto right_top = adc_corners[0];
1088 const auto &origin_point = frame->open_space_info().origin_point();
1089 const auto &origin_heading = frame->open_space_info().origin_heading();
1091 double left_top_s = 0.0;
1092 double left_top_l = 0.0;
1093 double right_top_s = 0.0;
1094 double right_top_l = 0.0;
1095 if (!(nearby_path.GetProjection(left_top, &left_top_s, &left_top_l) &&
1096 nearby_path.GetProjection(right_top, &right_top_s, &right_top_l))) {
1097 AERROR <<
"fail to get parking spot points' projections on reference line";
1100 left_top -= origin_point;
1101 left_top.SelfRotate(-origin_heading);
1102 right_top -= origin_point;
1103 right_top.SelfRotate(-origin_heading);
1105 const double center_line_s = (left_top_s + right_top_s) / 2.0;
1106 std::vector<Vec2d> left_lane_boundary;
1107 std::vector<Vec2d> right_lane_boundary;
1108 std::vector<Vec2d> center_lane_boundary_left;
1109 std::vector<Vec2d> center_lane_boundary_right;
1110 std::vector<double> center_lane_s_left;
1111 std::vector<double> center_lane_s_right;
1112 std::vector<double> left_lane_road_width;
1113 std::vector<double> right_lane_road_width;
1116 GetRoadBoundaryFromMap(
1117 nearby_path, center_line_s, origin_point, origin_heading,
1118 &left_lane_boundary, &right_lane_boundary, ¢er_lane_boundary_left,
1119 ¢er_lane_boundary_right, ¢er_lane_s_left, ¢er_lane_s_right,
1120 &left_lane_road_width, &right_lane_road_width);
1122 GetRoadBoundary(nearby_path, center_line_s, origin_point, origin_heading,
1123 &left_lane_boundary, &right_lane_boundary,
1124 ¢er_lane_boundary_left, ¢er_lane_boundary_right,
1125 ¢er_lane_s_left, ¢er_lane_s_right,
1126 &left_lane_road_width, &right_lane_road_width);
1130 std::reverse(left_lane_boundary.begin(), left_lane_boundary.end());
1132 std::vector<Vec2d> boundary_points;
1133 std::copy(right_lane_boundary.begin(), right_lane_boundary.end(),
1134 std::back_inserter(boundary_points));
1135 std::copy(left_lane_boundary.begin(), left_lane_boundary.end(),
1136 std::back_inserter(boundary_points));
1138 size_t right_lane_boundary_last_index = right_lane_boundary.size() - 1;
1139 for (
size_t i = 0; i < right_lane_boundary_last_index; i++) {
1140 std::vector<Vec2d> segment{right_lane_boundary[i],
1141 right_lane_boundary[i + 1]};
1142 ADEBUG <<
"right segment";
1143 ADEBUG <<
"right_road_boundary: [" << std::setprecision(9)
1144 << right_lane_boundary[i].x() <<
", " << right_lane_boundary[i].y()
1146 ADEBUG <<
"right_road_boundary: [" << std::setprecision(9)
1147 << right_lane_boundary[i + 1].x() <<
", "
1148 << right_lane_boundary[i + 1].y() <<
"]";
1149 roi_parking_boundary->push_back(segment);
1152 size_t left_lane_boundary_last_index = left_lane_boundary.size() - 1;
1153 for (
size_t i = left_lane_boundary_last_index; i > 0; i--) {
1154 std::vector<Vec2d> segment{left_lane_boundary[i],
1155 left_lane_boundary[i - 1]};
1156 roi_parking_boundary->push_back(segment);
1159 PrintCurves print_curves;
1160 for (
auto it : *roi_parking_boundary) {
1161 for (
auto pt : it) {
1162 pt.SelfRotate(origin_heading);
1164 print_curves.AddPoint(
"roi_parking_boundary", pt);
1167 print_curves.PrintToLog();
1169 ADEBUG <<
"roi_parking_boundary size: [" << roi_parking_boundary->size()
1173 if (!FuseLineSegments(roi_parking_boundary)) {
1177 ADEBUG <<
"roi_parking_boundary size: [" << roi_parking_boundary->size()
1180 auto xminmax = std::minmax_element(
1181 boundary_points.begin(), boundary_points.end(),
1182 [](
const Vec2d &a,
const Vec2d &b) { return a.x() < b.x(); });
1183 auto yminmax = std::minmax_element(
1184 boundary_points.begin(), boundary_points.end(),
1185 [](
const Vec2d &a,
const Vec2d &b) { return a.y() < b.y(); });
1186 std::vector<double> ROI_xy_boundary{xminmax.first->x(), xminmax.second->x(),
1187 yminmax.first->y(), yminmax.second->y()};
1189 frame->mutable_open_space_info()->mutable_ROI_xy_boundary();
1190 xy_boundary->assign(ROI_xy_boundary.begin(), ROI_xy_boundary.end());
1192 Vec2d vehicle_xy = Vec2d(vehicle_state_.
x(), vehicle_state_.
y());
1193 vehicle_xy -= origin_point;
1194 vehicle_xy.SelfRotate(-origin_heading);
1195 if (vehicle_xy.x() < ROI_xy_boundary[0] ||
1196 vehicle_xy.x() > ROI_xy_boundary[1] ||
1197 vehicle_xy.y() < ROI_xy_boundary[2] ||
1198 vehicle_xy.y() > ROI_xy_boundary[3]) {
1199 AERROR <<
"vehicle outside of xy boundary of parking ROI";
1205bool OpenSpaceRoiDecider::GetParkingSpot(
Frame *
const frame,
1206 ParkingInfo *parking_info) {
1207 if (frame ==
nullptr) {
1208 AERROR <<
"Invalid frame, fail to GetParkingSpotFromMap from frame. ";
1211 const auto &parking_spot_id_string =
1212 frame->open_space_info().target_parking_spot_id();
1215 if (!nearby_path_) {
1216 GetNearbyPath(frame->local_view().planning_command->lane_follow_command(),
1217 parking_spot, &nearby_path_);
1220 auto points = parking_spot->polygon().points();
1222 Vec2d center_point(0, 0);
1223 for (
size_t i = 0; i < points.size(); i++) {
1224 center_point += points[i];
1226 center_point /= 4.0;
1227 double lane_heading = 0;
1228 parking_info->center_point = center_point;
1229 nearby_path_->GetHeadingAlongPath(center_point, &lane_heading);
1231 nearby_path_->GetProjection(center_point, &s, &l);
1233 parking_info->is_on_left =
true;
1234 std::swap(points[1], points[3]);
1236 parking_info->is_on_left =
false;
1239 lane_heading, parking_spot->parking_space().heading());
1240 if (std::fabs(diff_angle) < M_PI / 3.0) {
1245 parking_info->corner_points = points;
1246 double parallel_dist =
1247 parking_info->corner_points[0].DistanceTo(parking_info->corner_points[1]);
1248 double verticle_dist =
1249 parking_info->corner_points[0].DistanceTo(parking_info->corner_points[3]);
1250 if (parallel_dist > verticle_dist) {
1258bool OpenSpaceRoiDecider::GetPullOverSpot(
1259 Frame *
const frame, std::array<common::math::Vec2d, 4> *vertices,
1260 hdmap::Path *nearby_path) {
1261 const auto &pull_over_status =
1262 injector_->planning_context()->planning_status().pull_over();
1263 if (!pull_over_status.has_position() ||
1264 !pull_over_status.position().has_x() ||
1265 !pull_over_status.position().has_y() || !pull_over_status.has_theta()) {
1266 AERROR <<
"Pull over position not set in planning context";
1270 if (frame->reference_line_info().size() > 1) {
1271 AERROR <<
"Should not be in pull over when changing lane in open space "
1277 frame->reference_line_info().front().reference_line().GetMapPath();
1280 double pull_over_x = pull_over_status.position().x();
1281 double pull_over_y = pull_over_status.position().y();
1282 const double pull_over_theta = pull_over_status.theta();
1283 const double pull_over_length_front = pull_over_status.length_front();
1284 const double pull_over_length_back = pull_over_status.length_back();
1285 const double pull_over_width_left = pull_over_status.width_left();
1286 const double pull_over_width_right = pull_over_status.width_right();
1288 Vec2d center_shift_vec((pull_over_length_front - pull_over_length_back) * 0.5,
1289 (pull_over_width_left - pull_over_width_right) * 0.5);
1290 center_shift_vec.SelfRotate(pull_over_theta);
1291 pull_over_x += center_shift_vec.x();
1292 pull_over_y += center_shift_vec.y();
1294 const double half_length =
1295 (pull_over_length_front + pull_over_length_back) / 2.0;
1296 const double half_width =
1297 (pull_over_width_left + pull_over_width_right) / 2.0;
1299 const double cos_heading = std::cos(pull_over_theta);
1300 const double sin_heading = std::sin(pull_over_theta);
1302 const double dx1 = cos_heading * half_length;
1303 const double dy1 = sin_heading * half_length;
1304 const double dx2 = sin_heading * half_width;
1305 const double dy2 = -cos_heading * half_width;
1307 Vec2d left_top(pull_over_x - dx1 + dx2, pull_over_y - dy1 + dy2);
1308 Vec2d left_down(pull_over_x - dx1 - dx2, pull_over_y - dy1 - dy2);
1309 Vec2d right_down(pull_over_x + dx1 - dx2, pull_over_y + dy1 - dy2);
1310 Vec2d right_top(pull_over_x + dx1 + dx2, pull_over_y + dy1 + dy2);
1312 std::array<Vec2d, 4> pull_over_vertices{left_top, left_down, right_down,
1314 *vertices = std::move(pull_over_vertices);
1319void OpenSpaceRoiDecider::SearchTargetParkingSpotOnPath(
1320 const hdmap::Path &nearby_path,
1321 ParkingSpaceInfoConstPtr *target_parking_spot) {
1322 const auto &parking_space_overlaps = nearby_path.parking_space_overlaps();
1323 for (
const auto &parking_overlap : parking_space_overlaps) {
1324 if (parking_overlap.object_id == target_parking_spot_id_) {
1326 id.set_id(parking_overlap.object_id);
1332bool OpenSpaceRoiDecider::FuseLineSegments(
1333 std::vector<std::vector<common::math::Vec2d>> *line_segments_vec) {
1334 static constexpr double kEpsilon = 1.0e-8;
1335 auto cur_segment = line_segments_vec->begin();
1336 while (cur_segment != line_segments_vec->end() - 1) {
1337 auto next_segment = cur_segment + 1;
1338 auto cur_last_point = cur_segment->back();
1339 auto next_first_point = next_segment->front();
1341 if (cur_last_point.DistanceTo(next_first_point) > kEpsilon) {
1345 if (cur_segment->size() < 2 || next_segment->size() < 2) {
1346 AERROR <<
"Single point line_segments vec not expected";
1349 size_t cur_segments_size = cur_segment->size();
1350 auto cur_second_to_last_point = cur_segment->at(cur_segments_size - 2);
1351 auto next_second_point = next_segment->at(1);
1352 if (
CrossProd(cur_second_to_last_point, cur_last_point, next_second_point) <
1354 cur_segment->push_back(next_second_point);
1355 next_segment->erase(next_segment->begin(), next_segment->begin() + 2);
1356 if (next_segment->empty()) {
1357 line_segments_vec->erase(next_segment);
1366bool OpenSpaceRoiDecider::FormulateBoundaryConstraints(
1367 const std::vector<std::vector<common::math::Vec2d>> &roi_parking_boundary,
1368 Frame *
const frame) {
1370 if (!LoadObstacleInVertices(roi_parking_boundary, frame)) {
1371 AERROR <<
"fail at LoadObstacleInVertices()";
1375 if (!LoadObstacleInHyperPlanes(frame)) {
1376 AERROR <<
"fail at LoadObstacleInHyperPlanes()";
1382bool OpenSpaceRoiDecider::LoadObstacleInVertices(
1383 const std::vector<std::vector<common::math::Vec2d>> &roi_parking_boundary,
1384 Frame *
const frame) {
1385 auto *mutable_open_space_info = frame->mutable_open_space_info();
1386 const auto &open_space_info = frame->open_space_info();
1387 auto *obstacles_vertices_vec =
1388 mutable_open_space_info->mutable_obstacles_vertices_vec();
1389 auto *obstacles_edges_num_vec =
1390 mutable_open_space_info->mutable_obstacles_edges_num();
1394 size_t parking_boundaries_num = roi_parking_boundary.size();
1395 size_t perception_obstacles_num = 0;
1397 for (
size_t i = 0; i < parking_boundaries_num; ++i) {
1398 obstacles_vertices_vec->push_back(roi_parking_boundary[i]);
1401 Eigen::MatrixXi parking_boundaries_obstacles_edges_num(parking_boundaries_num,
1403 for (
size_t i = 0; i < parking_boundaries_num; i++) {
1404 if (roi_parking_boundary[i].size() <= 1U) {
1405 AERROR <<
"Roi parking boundary is invalid: "
1406 << roi_parking_boundary[i].size();
1409 parking_boundaries_obstacles_edges_num(i, 0) =
1410 static_cast<int>(roi_parking_boundary[i].size()) - 1;
1414 if (perception_obstacles_num == 0) {
1415 ADEBUG <<
"no obstacle given by perception";
1420 const auto &origin_point = open_space_info.origin_point();
1421 const auto &origin_heading = open_space_info.origin_heading();
1422 for (
const auto &obstacle : obstacles_by_frame_->Items()) {
1423 if (FilterOutObstacle(*frame, *obstacle)) {
1426 ++perception_obstacles_num;
1428 std::vector<Vec2d> vertices_ccw;
1430 common::math::Polygon2d original_polygon =
1431 obstacle->PerceptionPolygon();
1433 original_polygon.CalculateVertices(-1.0 * origin_point);
1434 vertices_ccw = original_polygon.GetAllVertices();
1436 Box2d original_box = obstacle->PerceptionBoundingBox();
1437 original_box.Shift(-1.0 * origin_point);
1440 vertices_ccw = original_box.GetAllCorners();
1450 std::vector<Vec2d> vertices_cw;
1451 while (!vertices_ccw.empty()) {
1452 auto current_corner_pt = vertices_ccw.back();
1453 current_corner_pt.SelfRotate(-1.0 * origin_heading);
1454 vertices_cw.push_back(current_corner_pt);
1455 vertices_ccw.pop_back();
1460 vertices_cw.push_back(vertices_cw.front());
1461 obstacles_vertices_vec->push_back(vertices_cw);
1465 Eigen::MatrixXi perception_obstacles_edges_num =
1466 4 * Eigen::MatrixXi::Ones(perception_obstacles_num, 1);
1468 obstacles_edges_num_vec->resize(
1469 parking_boundaries_obstacles_edges_num.rows() +
1470 perception_obstacles_edges_num.rows(),
1472 *(obstacles_edges_num_vec) << parking_boundaries_obstacles_edges_num,
1473 perception_obstacles_edges_num;
1476 obstacles_edges_num_vec->resize(
1477 parking_boundaries_obstacles_edges_num.rows(), 1);
1478 *(obstacles_edges_num_vec) << parking_boundaries_obstacles_edges_num;
1481 mutable_open_space_info->set_obstacles_num(parking_boundaries_num +
1482 perception_obstacles_num);
1486bool OpenSpaceRoiDecider::FilterOutObstacle(
const Frame &frame,
1487 const Obstacle &obstacle) {
1488 if (obstacle.IsVirtual() || !obstacle.IsStatic()) {
1492 const auto &open_space_info = frame.open_space_info();
1493 const auto &origin_point = open_space_info.origin_point();
1494 const auto &origin_heading = open_space_info.origin_heading();
1495 const auto &obstacle_box = obstacle.PerceptionBoundingBox();
1496 auto obstacle_center_xy = obstacle_box.center();
1499 const auto &roi_xy_boundary = open_space_info.ROI_xy_boundary();
1500 obstacle_center_xy -= origin_point;
1501 obstacle_center_xy.SelfRotate(-origin_heading);
1502 if (obstacle_center_xy.x() < roi_xy_boundary[0] ||
1503 obstacle_center_xy.x() > roi_xy_boundary[1] ||
1504 obstacle_center_xy.y() < roi_xy_boundary[2] ||
1505 obstacle_center_xy.y() > roi_xy_boundary[3]) {
1510 const auto &end_pose = open_space_info.open_space_end_pose();
1511 Vec2d end_pose_x_y(end_pose[0], end_pose[1]);
1512 end_pose_x_y.SelfRotate(origin_heading);
1513 end_pose_x_y += origin_point;
1516 Vec2d vehicle_x_y(vehicle_state_.
x(), vehicle_state_.
y());
1519 const double vehicle_center_to_obstacle =
1520 obstacle_box.DistanceTo(vehicle_x_y);
1521 const double end_pose_center_to_obstacle =
1522 obstacle_box.DistanceTo(end_pose_x_y);
1523 const double filtering_distance =
1525 if (vehicle_center_to_obstacle > filtering_distance &&
1526 end_pose_center_to_obstacle > filtering_distance) {
1532bool OpenSpaceRoiDecider::LoadObstacleInHyperPlanes(
Frame *
const frame) {
1533 *(frame->mutable_open_space_info()->mutable_obstacles_A()) =
1534 Eigen::MatrixXd::Zero(
1535 frame->open_space_info().obstacles_edges_num().sum(), 2);
1536 *(frame->mutable_open_space_info()->mutable_obstacles_b()) =
1537 Eigen::MatrixXd::Zero(
1538 frame->open_space_info().obstacles_edges_num().sum(), 1);
1540 if (!GetHyperPlanes(
1541 frame->open_space_info().obstacles_num(),
1542 frame->open_space_info().obstacles_edges_num(),
1543 frame->open_space_info().obstacles_vertices_vec(),
1544 frame->mutable_open_space_info()->mutable_obstacles_A(),
1545 frame->mutable_open_space_info()->mutable_obstacles_b())) {
1546 AERROR <<
"Fail to present obstacle in hyperplane";
1552bool OpenSpaceRoiDecider::GetHyperPlanes(
1553 const size_t &obstacles_num,
const Eigen::MatrixXi &obstacles_edges_num,
1554 const std::vector<std::vector<Vec2d>> &obstacles_vertices_vec,
1555 Eigen::MatrixXd *A_all, Eigen::MatrixXd *b_all) {
1556 if (obstacles_num != obstacles_vertices_vec.size()) {
1557 AERROR <<
"obstacles_num != obstacles_vertices_vec.size()";
1561 A_all->resize(obstacles_edges_num.sum(), 2);
1562 b_all->resize(obstacles_edges_num.sum(), 1);
1565 double kEpsilon = 1.0e-5;
1567 for (
size_t i = 0; i < obstacles_num; ++i) {
1568 size_t current_vertice_num = obstacles_edges_num(i, 0);
1569 Eigen::MatrixXd A_i(current_vertice_num, 2);
1570 Eigen::MatrixXd b_i(current_vertice_num, 1);
1573 for (
size_t j = 0; j < current_vertice_num; ++j) {
1574 Vec2d v1 = obstacles_vertices_vec[i][j];
1575 Vec2d v2 = obstacles_vertices_vec[i][j + 1];
1577 Eigen::MatrixXd A_tmp(2, 1), b_tmp(1, 1), ab(2, 1);
1579 if (std::abs(v1.x() - v2.x()) < kEpsilon) {
1580 if (v2.y() < v1.y()) {
1587 }
else if (std::abs(v1.y() - v2.y()) < kEpsilon) {
1588 if (v1.x() < v2.x()) {
1596 Eigen::MatrixXd tmp1(2, 2);
1597 tmp1 << v1.x(), 1, v2.x(), 1;
1598 Eigen::MatrixXd tmp2(2, 1);
1599 tmp2 << v1.y(), v2.y();
1600 ab = tmp1.inverse() * tmp2;
1601 double a = ab(0, 0);
1602 double b = ab(1, 0);
1604 if (v1.x() < v2.x()) {
1614 A_i.block(j, 0, 1, 2) = A_tmp.transpose();
1615 b_i.block(j, 0, 1, 1) = b_tmp;
1618 A_all->block(counter, 0, A_i.rows(), 2) = A_i;
1619 b_all->block(counter, 0, b_i.rows(), 1) = b_i;
1620 counter +=
static_cast<int>(current_vertice_num);
1625bool OpenSpaceRoiDecider::IsInParkingLot(
1626 const double adc_init_x,
const double adc_init_y,
1627 const double adc_init_heading, std::array<Vec2d, 4> *parking_lot_vertices) {
1628 std::vector<ParkingSpaceInfoConstPtr> parking_lots;
1630 const double kDistance = 1.0;
1631 auto adc_parking_spot =
1633 ADEBUG <<
"IsInParkingLot";
1637 if (hdmap_->GetParkingSpaces(adc_parking_spot, kDistance, &parking_lots) ==
1639 GetParkSpotFromMap(parking_lots.front(), parking_lot_vertices);
1640 AINFO <<
"Get park lot from map!!";
1646void OpenSpaceRoiDecider::GetParkSpotFromMap(
1647 ParkingSpaceInfoConstPtr parking_lot, std::array<Vec2d, 4> *vertices) {
1650 Vec2d left_top = parking_lot->polygon().points().at(3);
1651 Vec2d left_down = parking_lot->polygon().points().at(0);
1652 Vec2d right_down = parking_lot->polygon().points().at(1);
1653 Vec2d right_top = parking_lot->polygon().points().at(2);
1655 std::array<Vec2d, 4> parking_vertices{left_top, left_down, right_down,
1658 *vertices = std::move(parking_vertices);
1659 Vec2d tmp = (*vertices)[0];
1661 ADEBUG <<
"parking_lot_vertices: (" << tmp.x() <<
", " << tmp.y() <<
")";
1664void OpenSpaceRoiDecider::GetAllLaneSegments(
1665 const routing::RoutingResponse &routing_response,
1666 std::vector<routing::LaneSegment> *routing_segments) {
1667 routing_segments->clear();
1668 for (
const auto &road : routing_response.road()) {
1669 for (
const auto &passage : road.passage()) {
1670 for (
const auto &segment : passage.segment()) {
1671 routing_segments->emplace_back(segment);
1677bool OpenSpaceRoiDecider::GetNearbyPath(
1679 const ParkingSpaceInfoConstPtr &parking_spot,
1680 std::shared_ptr<hdmap::Path> *nearby_path) {
1682 if (
nullptr == parking_spot) {
1683 AERROR <<
"The parking spot id is invalid!" << parking_spot->id().id();
1686 auto parking_space = parking_spot->parking_space();
1687 auto overlap_ids = parking_space.overlap_id();
1688 if (overlap_ids.empty()) {
1689 AERROR <<
"There is no lane overlaps with the parking spot: "
1690 << parking_spot->id().id();
1693 std::vector<routing::LaneSegment> lane_segments;
1694 GetAllLaneSegments(routing_response, &lane_segments);
1695 bool has_found_nearest_lane =
false;
1696 size_t nearest_lane_index = 0;
1697 for (
auto id : overlap_ids) {
1698 auto overlaps = hdmap_->GetOverlapById(
id)->overlap();
1699 for (
auto object : overlaps.object()) {
1700 if (!
object.has_lane_overlap_info()) {
1703 nearest_lane = hdmap_->GetLaneById(
object.
id());
1704 if (nearest_lane ==
nullptr) {
1708 for (
auto &segment : lane_segments) {
1709 if (segment.id() == nearest_lane->id().id()) {
1710 has_found_nearest_lane =
true;
1713 ++nearest_lane_index;
1715 if (has_found_nearest_lane) {
1720 if (!has_found_nearest_lane) {
1721 AERROR <<
"Cannot find the lane nearest to the parking spot when "
1730 double vehicle_lane_s = 0.0;
1731 double vehicle_lane_l = 0.0;
1732 int status = hdmap_->GetNearestLaneWithHeading(
1733 point, 10.0, vehicle_state_.
heading(), M_PI / 2.0,
1734 &nearest_lane_to_vehicle, &vehicle_lane_s, &vehicle_lane_l);
1736 size_t nearest_lane_to_vehicle_index = 0;
1737 bool has_found_nearest_lane_to_vehicle =
false;
1738 for (
auto &segment : lane_segments) {
1739 if (segment.id() == nearest_lane_to_vehicle->id().id()) {
1740 has_found_nearest_lane_to_vehicle =
true;
1743 ++nearest_lane_to_vehicle_index;
1746 if (has_found_nearest_lane_to_vehicle &&
1747 nearest_lane_to_vehicle_index < nearest_lane_index) {
1748 nearest_lane = nearest_lane_to_vehicle;
1754 LaneSegment nearest_lanesegment =
1755 LaneSegment(nearest_lane, nearest_lane->accumulate_s().front(),
1756 nearest_lane->accumulate_s().back());
1757 std::vector<LaneSegment> segments_vector;
1758 int next_lanes_num = nearest_lane->lane().successor_id_size();
1759 if (next_lanes_num != 0) {
1760 auto next_lane_id = nearest_lane->lane().successor_id(0);
1761 segments_vector.push_back(nearest_lanesegment);
1762 auto next_lane = hdmap_->GetLaneById(next_lane_id);
1763 LaneSegment next_lanesegment =
1764 LaneSegment(next_lane, next_lane->accumulate_s().front(),
1765 next_lane->accumulate_s().back());
1766 segments_vector.push_back(next_lanesegment);
1767 size_t succeed_lanes_num = next_lane->lane().successor_id_size();
1768 if (succeed_lanes_num != 0) {
1769 auto succeed_lane_id = next_lane->lane().successor_id(0);
1770 auto succeed_lane = hdmap_->GetLaneById(succeed_lane_id);
1771 LaneSegment succeed_lanesegment =
1772 LaneSegment(succeed_lane, succeed_lane->accumulate_s().front(),
1773 succeed_lane->accumulate_s().back());
1774 segments_vector.push_back(succeed_lanesegment);
1776 *nearby_path = std::make_shared<Path>(segments_vector);
1778 segments_vector.push_back(nearest_lanesegment);
1779 *nearby_path = std::make_shared<Path>(segments_vector);
1783bool OpenSpaceRoiDecider::AdjustPointsOrderToClockwise(
1784 std::vector<Vec2d> *polygon) {
1787 ADEBUG <<
"point is anticlockwise,reverse";
1788 std::reverse(polygon->begin(), polygon->end());
1795bool OpenSpaceRoiDecider::GetParkingOutBoundary(
1796 const hdmap::Path &nearby_path,
Frame *
const frame,
1797 std::vector<std::vector<common::math::Vec2d>> *
const roi_parking_boundary) {
1798 const auto &park_and_go_status =
1799 injector_->planning_context()->planning_status().park_and_go();
1800 const double adc_init_x = park_and_go_status.adc_init_position().x();
1801 const double adc_init_y = park_and_go_status.adc_init_position().y();
1802 const double adc_init_heading = park_and_go_status.adc_init_heading();
1803 common::math::Vec2d adc_init_position = {adc_init_x, adc_init_y};
1804 const double adc_length = vehicle_params_.
length();
1805 const double adc_width = vehicle_params_.
width();
1806 AINFO << std::fixed <<
"adc_init_x is " << adc_init_x <<
"adc_init_y is "
1807 << adc_init_y <<
"adc_init_heading is " << adc_init_heading;
1809 double shift_distance =
1811 adc_init_position = adc_init_position +
1814 Box2d adc_box(adc_init_position, adc_init_heading, adc_length, adc_width);
1816 std::vector<common::math::Vec2d> adc_corners;
1817 adc_box.GetAllCorners(&adc_corners);
1819 std::vector<ParkingSpaceInfoConstPtr> parking_lots;
1820 auto adc_parking_spot =
1822 const double kDistance = 1.0;
1823 if (hdmap_->GetParkingSpaces(adc_parking_spot, kDistance, &parking_lots) !=
1825 AINFO <<
"Failed to get the parking spot!!!";
1828 AINFO <<
"Get " << parking_lots.size() <<
" parking spots";
1830 std::vector<Vec2d> parking_boundary;
1831 for (
const auto &parking_overlap : parking_lots) {
1832 const auto parking_polygon = parking_overlap->polygon();
1833 AINFO <<
"parking_polygon: " << parking_polygon.DebugString();
1834 bool is_in_parking_spot =
true;
1835 for (
const auto &corner : adc_corners) {
1836 if (!parking_polygon.IsPointIn(corner)) {
1837 is_in_parking_spot =
false;
1838 AINFO <<
"Vehicle is out of parking spot!";
1842 if (is_in_parking_spot) {
1843 auto points = parking_polygon.points();
1845 for (
size_t i = 0; i < points.size(); i++) {
1846 int t =
static_cast<int>(i + 1) %
static_cast<int>(points.size());
1847 parking_boundary.emplace_back(points.at(t).x(), points.at(t).y());
1851 if (parking_boundary.size() < 4) {
1852 AINFO <<
" Current parking spot is invalid!";
1855 auto left_top = parking_boundary[3];
1856 auto right_top = parking_boundary[0];
1857 auto right_down = parking_boundary[1];
1858 auto left_down = parking_boundary[2];
1860 double left_top_s = 0.0;
1861 double left_top_l = 0.0;
1862 double right_top_s = 0.0;
1863 double right_top_l = 0.0;
1864 double left_down_s = 0.0;
1865 double left_down_l = 0.0;
1866 double right_down_s = 0.0;
1867 double right_down_l = 0.0;
1868 if (!(nearby_path.GetProjection(left_top, &left_top_s, &left_top_l) &&
1869 nearby_path.GetProjection(right_top, &right_top_s, &right_top_l))) {
1870 AERROR <<
"fail to get parking spot points' projections on reference line";
1874 if (!(nearby_path.GetProjection(left_down, &left_down_s, &left_down_l) &&
1875 nearby_path.GetProjection(right_down, &right_down_s, &right_down_l))) {
1876 AERROR <<
"fail to get parking spot points' projections on reference line";
1879 if (fabs(left_top_l + right_top_l) > fabs(left_down_l + right_down_l)) {
1880 frame->mutable_open_space_info()->mutable_origin_point()->set_x(
1882 frame->mutable_open_space_info()->mutable_origin_point()->set_y(
1885 if (!nearby_path.GetHeadingAlongPath(right_down, &heading)) {
1886 AERROR <<
"fail to get heading on reference line";
1889 frame->mutable_open_space_info()->set_origin_heading(
1891 std::swap(right_down, left_top);
1892 std::swap(right_top, left_down);
1893 std::swap(right_down_s, left_top_s);
1894 std::swap(right_down_l, left_top_l);
1895 std::swap(right_top_s, left_down_s);
1896 std::swap(right_top_l, left_down_l);
1899 const double center_line_s = (left_top_s + right_top_s) / 2.0;
1900 std::vector<Vec2d> left_lane_boundary;
1901 std::vector<Vec2d> right_lane_boundary;
1904 std::vector<Vec2d> center_lane_boundary_left;
1907 std::vector<Vec2d> center_lane_boundary_right;
1909 std::vector<double> center_lane_s_left;
1911 std::vector<double> center_lane_s_right;
1915 std::vector<double> left_lane_road_width;
1919 std::vector<double> right_lane_road_width;
1921 GetRoadBoundary(nearby_path, center_line_s, Vec2d(0.0, 0.0), 0.0,
1922 &left_lane_boundary, &right_lane_boundary,
1923 ¢er_lane_boundary_left, ¢er_lane_boundary_right,
1924 ¢er_lane_s_left, ¢er_lane_s_right,
1925 &left_lane_road_width, &right_lane_road_width);
1930 const double average_l = (left_top_l + right_top_l) / 2.0;
1931 const double average_s = (left_top_s + right_top_s) / 2.0;
1933 std::vector<Vec2d> boundary_points;
1937 if (average_l < 0) {
1940 ADEBUG <<
"average_l is less than 0 in OpenSpaceROI";
1941 size_t point_size = right_lane_boundary.size();
1942 for (
size_t i = 0; i < point_size; i++) {
1943 right_lane_boundary[i] -= center_lane_boundary_right[i];
1944 right_lane_boundary[i] /= right_lane_road_width[i];
1945 if (center_lane_s_right[i] < (average_s)) {
1946 right_lane_boundary[i] *= (std::fabs(left_top_l));
1948 right_lane_boundary[i] *= (std::fabs(right_top_l));
1950 right_lane_boundary[i] += center_lane_boundary_right[i];
1953 auto point_left_to_left_top_connor_s = std::lower_bound(
1954 center_lane_s_right.begin(), center_lane_s_right.end(), left_top_s);
1955 size_t point_left_to_left_top_connor_index = std::distance(
1956 center_lane_s_right.begin(), point_left_to_left_top_connor_s);
1957 point_left_to_left_top_connor_index =
1958 point_left_to_left_top_connor_index == 0
1959 ? point_left_to_left_top_connor_index
1960 : point_left_to_left_top_connor_index - 1;
1961 auto point_left_to_left_top_connor_itr =
1962 right_lane_boundary.begin() + point_left_to_left_top_connor_index;
1963 auto point_right_to_right_top_connor_s = std::upper_bound(
1964 center_lane_s_right.begin(), center_lane_s_right.end(), right_top_s);
1965 size_t point_right_to_right_top_connor_index = std::distance(
1966 center_lane_s_right.begin(), point_right_to_right_top_connor_s);
1967 auto point_right_to_right_top_connor_itr =
1968 right_lane_boundary.begin() + point_right_to_right_top_connor_index;
1970 std::copy(right_lane_boundary.begin(), point_left_to_left_top_connor_itr,
1971 std::back_inserter(boundary_points));
1973 std::vector<Vec2d> parking_spot_boundary{left_top, left_down, right_down,
1976 std::copy(parking_spot_boundary.begin(), parking_spot_boundary.end(),
1977 std::back_inserter(boundary_points));
1979 std::copy(point_right_to_right_top_connor_itr, right_lane_boundary.end(),
1980 std::back_inserter(boundary_points));
1982 std::reverse_copy(left_lane_boundary.begin(), left_lane_boundary.end(),
1983 std::back_inserter(boundary_points));
1986 boundary_points.push_back(right_lane_boundary.front());
1989 for (
size_t i = 0; i < point_left_to_left_top_connor_index; i++) {
1990 std::vector<Vec2d> segment{right_lane_boundary[i],
1991 right_lane_boundary[i + 1]};
1992 roi_parking_boundary->push_back(segment);
1995 std::vector<Vec2d> left_stitching_segment{
1996 right_lane_boundary[point_left_to_left_top_connor_index], left_top};
1997 roi_parking_boundary->push_back(left_stitching_segment);
1999 std::vector<Vec2d> left_parking_spot_segment{left_top, left_down};
2000 std::vector<Vec2d> down_parking_spot_segment{left_down, right_down};
2001 std::vector<Vec2d> right_parking_spot_segment{right_down, right_top};
2002 roi_parking_boundary->push_back(left_parking_spot_segment);
2003 roi_parking_boundary->push_back(down_parking_spot_segment);
2004 roi_parking_boundary->push_back(right_parking_spot_segment);
2006 std::vector<Vec2d> right_stitching_segment{
2007 right_top, right_lane_boundary[point_right_to_right_top_connor_index]};
2008 roi_parking_boundary->push_back(right_stitching_segment);
2010 size_t right_lane_boundary_last_index = right_lane_boundary.size() - 1;
2011 for (
size_t i = point_right_to_right_top_connor_index;
2012 i < right_lane_boundary_last_index; i++) {
2013 std::vector<Vec2d> segment{right_lane_boundary[i],
2014 right_lane_boundary[i + 1]};
2015 roi_parking_boundary->push_back(segment);
2018 size_t left_lane_boundary_last_index = left_lane_boundary.size() - 1;
2019 for (
size_t i = left_lane_boundary_last_index; i > 0; i--) {
2020 std::vector<Vec2d> segment{left_lane_boundary[i],
2021 left_lane_boundary[i - 1]};
2022 roi_parking_boundary->push_back(segment);
2028 ADEBUG <<
"average_l is greater than 0 in OpenSpaceROI";
2029 size_t point_size = left_lane_boundary.size();
2030 for (
size_t i = 0; i < point_size; i++) {
2031 left_lane_boundary[i] -= center_lane_boundary_left[i];
2032 left_lane_boundary[i] /= left_lane_road_width[i];
2033 if (center_lane_s_right[i] < (average_s)) {
2034 left_lane_boundary[i] *= (std::fabs(right_top_l));
2036 left_lane_boundary[i] *= (std::fabs(left_top_l));
2038 left_lane_boundary[i] += center_lane_boundary_left[i];
2039 ADEBUG <<
"left_lane_boundary[" << i <<
"]: " << left_lane_boundary[i].x()
2040 <<
", " << left_lane_boundary[i].y();
2043 auto point_right_to_right_top_connor_s = std::lower_bound(
2044 center_lane_s_left.begin(), center_lane_s_left.end(), right_top_s);
2045 size_t point_right_to_right_top_connor_index = std::distance(
2046 center_lane_s_left.begin(), point_right_to_right_top_connor_s);
2047 if (point_right_to_right_top_connor_index > 0) {
2048 --point_right_to_right_top_connor_index;
2050 auto point_right_to_right_top_connor_itr =
2051 left_lane_boundary.begin() + point_right_to_right_top_connor_index;
2053 auto point_left_to_left_top_connor_s = std::upper_bound(
2054 center_lane_s_left.begin(), center_lane_s_left.end(), left_top_s);
2055 size_t point_left_to_left_top_connor_index = std::distance(
2056 center_lane_s_left.begin(), point_left_to_left_top_connor_s);
2057 auto point_left_to_left_top_connor_itr =
2058 left_lane_boundary.begin() + point_left_to_left_top_connor_index;
2060 std::copy(right_lane_boundary.begin(), right_lane_boundary.end(),
2061 std::back_inserter(boundary_points));
2063 std::reverse_copy(point_left_to_left_top_connor_itr,
2064 left_lane_boundary.end(),
2065 std::back_inserter(boundary_points));
2067 std::vector<Vec2d> parking_spot_boundary{left_top, left_down, right_down,
2069 std::copy(parking_spot_boundary.begin(), parking_spot_boundary.end(),
2070 std::back_inserter(boundary_points));
2072 std::reverse_copy(left_lane_boundary.begin(),
2073 point_right_to_right_top_connor_itr,
2074 std::back_inserter(boundary_points));
2077 boundary_points.push_back(right_lane_boundary.front());
2080 size_t right_lane_boundary_last_index = right_lane_boundary.size() - 1;
2081 for (
size_t i = 0; i < right_lane_boundary_last_index; i++) {
2082 std::vector<Vec2d> segment{right_lane_boundary[i],
2083 right_lane_boundary[i + 1]};
2084 roi_parking_boundary->push_back(segment);
2087 size_t left_lane_boundary_last_index = left_lane_boundary.size() - 1;
2088 for (
size_t i = left_lane_boundary_last_index;
2089 i > point_left_to_left_top_connor_index; i--) {
2090 std::vector<Vec2d> segment{left_lane_boundary[i],
2091 left_lane_boundary[i - 1]};
2092 roi_parking_boundary->push_back(segment);
2095 std::vector<Vec2d> left_stitching_segment{
2096 left_lane_boundary[point_left_to_left_top_connor_index], left_top};
2097 roi_parking_boundary->push_back(left_stitching_segment);
2099 std::vector<Vec2d> left_parking_spot_segment{left_top, left_down};
2100 std::vector<Vec2d> down_parking_spot_segment{left_down, right_down};
2101 std::vector<Vec2d> right_parking_spot_segment{right_down, right_top};
2102 roi_parking_boundary->push_back(left_parking_spot_segment);
2103 roi_parking_boundary->push_back(down_parking_spot_segment);
2104 roi_parking_boundary->push_back(right_parking_spot_segment);
2106 std::vector<Vec2d> right_stitching_segment{
2107 right_top, left_lane_boundary[point_right_to_right_top_connor_index]};
2108 roi_parking_boundary->push_back(right_stitching_segment);
2110 for (
size_t i = point_right_to_right_top_connor_index; i > 0; --i) {
2111 std::vector<Vec2d> segment{left_lane_boundary[i],
2112 left_lane_boundary[i - 1]};
2113 roi_parking_boundary->push_back(segment);
2116 PrintCurves print_curves;
2117 const auto &origin_point = frame->mutable_open_space_info()->origin_point();
2118 double origin_heading = frame->mutable_open_space_info()->origin_heading();
2120 for (
auto it : *roi_parking_boundary) {
2121 for (
auto pt : it) {
2122 print_curves.AddPoint(
"roi_parking_boundary", pt);
2126 roi_parking_boundary);
2127 for (
auto it : *roi_parking_boundary) {
2128 for (
auto pt : it) {
2129 print_curves.AddPoint(
"transformed_roi_parking_boundary", pt);
2133 if (!FuseLineSegments(roi_parking_boundary)) {
2134 AERROR <<
"FuseLineSegments failed in parking ROI";
2137 print_curves.PrintToLog();
2139 frame->mutable_open_space_info()->mutable_ROI_xy_boundary();
2142 Vec2d vehicle_xy = Vec2d(vehicle_state_.
x(), vehicle_state_.
y());
2143 vehicle_xy -= origin_point;
2144 vehicle_xy.SelfRotate(-origin_heading);
2145 if (vehicle_xy.x() < xy_boundary->at(0) ||
2146 vehicle_xy.x() > xy_boundary->at(1) ||
2147 vehicle_xy.y() < xy_boundary->at(2) ||
2148 vehicle_xy.y() > xy_boundary->at(3)) {
2149 AERROR <<
"vehicle outside of xy boundary of parking ROI";
2152 AINFO <<
"success get ROI";
2156bool OpenSpaceRoiDecider::AddParkingSpaceBoundary(
2157 Frame *
const frame,
const hdmap::Path &nearby_path,
2158 std::vector<std::vector<common::math::Vec2d>> *
const roi_parking_boundary) {
2159 const auto &park_and_go_status =
2160 injector_->planning_context()->planning_status().park_and_go();
2161 const double adc_init_x = park_and_go_status.adc_init_position().x();
2162 const double adc_init_y = park_and_go_status.adc_init_position().y();
2163 const double adc_init_heading = park_and_go_status.adc_init_heading();
2164 common::math::Vec2d adc_init_position = {adc_init_x, adc_init_y};
2165 const double adc_length = vehicle_params_.
length();
2166 const double adc_width = vehicle_params_.
width();
2168 double shift_distance =
2170 adc_init_position = adc_init_position +
2172 Box2d adc_box(adc_init_position, adc_init_heading, adc_length, adc_width);
2174 std::vector<common::math::Vec2d> adc_corners;
2175 adc_box.GetAllCorners(&adc_corners);
2176 PrintCurves print_curves;
2177 for (
auto pt : adc_corners) {
2178 print_curves.AddPoint(
"adc_corners", pt);
2180 for (
const auto &parking_overlap : nearby_path.parking_space_overlaps()) {
2182 id.set_id(parking_overlap.object_id);
2183 const auto target_parking_spot = hdmap_->GetParkingSpaceById(
id);
2184 if (!target_parking_spot) {
2187 const auto parking_polygon = target_parking_spot->polygon();
2188 for (
const auto &pt : parking_polygon.points()) {
2189 print_curves.AddPoint(
id.
id() +
"parking_polygon", pt);
2191 bool is_in_polygon =
true;
2192 for (
const auto &pt : adc_corners) {
2193 if (!parking_polygon.IsPointIn(pt)) {
2194 is_in_polygon =
false;
2198 if (is_in_polygon) {
2199 auto points = parking_polygon.points();
2201 std::vector<Vec2d> parking_boundary;
2202 for (
size_t i = 0; i < points.size(); i++) {
2203 int t =
static_cast<int>(i + 1) %
static_cast<int>(points.size());
2204 parking_boundary.emplace_back(points.at(t).x(), points.at(t).y());
2206 roi_parking_boundary->push_back(parking_boundary);
2209 print_curves.PrintToLog();
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Rectangular (undirected) bounding box in 2-D.
Implements a class of 2-dimensional vectors.
static Vec2d CreateUnitVec2d(const double angle)
Creates a unit-vector with a given angle to the positive x semi-axis
static PointENU ToPointENU(const double x, const double y, const double z=0)
static const HDMap * BaseMapPtr()
static const HDMap & BaseMap()
int GetNearestLaneWithHeading(const apollo::common::PointENU &point, const double distance, const double central_heading, const double max_heading_difference, LaneInfoConstPtr *nearest_lane, double *nearest_s, double *nearest_l) const
get the nearest lane within a certain range by pose
int GetParkingSpaces(const apollo::common::PointENU &point, double distance, std::vector< ParkingSpaceInfoConstPtr > *parking_spaces) const
get all parking spaces in certain range
ParkingSpaceInfoConstPtr GetParkingSpaceById(const Id &id) const
int GetRoadBoundaries(const apollo::common::PointENU &point, double radius, std::vector< RoadROIBoundaryPtr > *road_boundaries, std::vector< JunctionBoundaryPtr > *junctions) const
get all road and junctions boundaries within certain range
Frame holds all data for one planning cycle.
const OpenSpaceInfo & open_space_info() const
const common::VehicleState & vehicle_state() const
OpenSpaceInfo * mutable_open_space_info()
ThreadSafeIndexedObstacles * GetObstacleList()
const std::list< ReferenceLineInfo > & reference_line_info() const
void set_parking_type(const ParkingType type)
const std::string target_parking_spot_id() const
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
static bool UpdateParkingPointsOrder(const apollo::hdmap::Path &nearby_path, std::vector< Vec2d > *points)
static void TransformByOriginPoint(const common::math::Vec2d &origin_point, const double heading, std::vector< std::vector< common::math::Vec2d > > *roi_parking_boundary)
static bool IsPolygonClockwise(const std::vector< Vec2d > &polygon)
static void GetRoiXYBoundary(const std::vector< std::vector< common::math::Vec2d > > &roi_parking_boundary, std::vector< double > *const XYBoundary)
get XY boundary which is minmax x or y in roi boundary
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.
double CrossProd(const Vec2d &start_point, const Vec2d &end_point_1, const Vec2d &end_point_2)
Cross product between two 2-D vectors from the common start point, and end at two other points.
double AngleDiff(const double from, const double to)
Calculate the difference between angle from and to
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
apollo::hdmap::Id MakeMapId(const std::string &id)
create a Map ID given a string.
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
std::shared_ptr< const ParkingSpaceInfo > ParkingSpaceInfoConstPtr
Define the Polygon2d class.
optional VehicleParam vehicle_param
optional double back_edge_to_center
optional double front_edge_to_center
optional double perception_obstacle_buffer
optional double curb_heading_tangent_change_upper_limit
optional double roi_line_segment_length
optional double end_pose_s_distance
optional double roi_longitudinal_range_end
optional RoiType roi_type
optional bool expand_polygon_of_obstacle_by_distance
optional double roi_longitudinal_range_start
optional double parking_depth_buffer
optional bool enable_perception_obstacles
optional double roi_line_segment_min_angle
optional double perception_obstacle_filtering_distance
optional double roi_line_segment_length_from_map
optional bool use_road_boundary_from_map
optional bool parking_inwards