63 const std::shared_ptr<relative_map::MapMsg> &relative_map)
64 : vehicle_state_provider_(vehicle_state_provider) {
65 current_pnc_map_ =
nullptr;
66 if (!FLAGS_use_navigation_mode) {
67 relative_map_ =
nullptr;
69 relative_map_ = relative_map;
74 <<
"Failed to load smoother config file "
75 << FLAGS_smoother_config_filename;
76 if (smoother_config_.has_qp_spline()) {
78 }
else if (smoother_config_.has_spiral()) {
80 }
else if (smoother_config_.has_discrete_points()) {
83 ACHECK(
false) <<
"unknown smoother config "
84 << smoother_config_.DebugString();
87 pnc_map_list_.clear();
89 if (
nullptr == reference_line_config ||
94 "apollo::planning::LaneFollowMap");
95 pnc_map_list_.emplace_back(pnc_map);
97 const auto &pnc_map_names = reference_line_config->
pnc_map_class();
98 for (
const auto &map_name : pnc_map_names) {
102 pnc_map_list_.emplace_back(pnc_map);
106 is_initialized_ =
true;
111 std::lock_guard<std::mutex> routing_lock(routing_mutex_);
112 bool find_matched_pnc_map =
false;
113 for (
const auto &pnc_map : pnc_map_list_) {
114 if (pnc_map->CanProcess(command)) {
115 current_pnc_map_ = pnc_map;
116 find_matched_pnc_map =
true;
120 if (
nullptr == current_pnc_map_) {
121 AERROR <<
"Cannot find pnc map to process input command!"
122 << command.DebugString();
125 if (!find_matched_pnc_map) {
126 AWARN <<
"Find no pnc map for the input command and the old one will be "
130 std::lock_guard<std::mutex> lock(pnc_map_mutex_);
131 if (current_pnc_map_->IsNewPlanningCommand(command)) {
132 is_new_command_ =
true;
133 if (!current_pnc_map_->UpdatePlanningCommand(command)) {
134 AERROR <<
"Failed to update routing in pnc map: "
135 << command.DebugString();
139 planning_command_ = command;
140 has_planning_command_ =
true;
144std::vector<routing::LaneWaypoint>
146 if (!FLAGS_use_navigation_mode &&
nullptr != current_pnc_map_) {
147 std::lock_guard<std::mutex> lock(pnc_map_mutex_);
148 return current_pnc_map_->FutureRouteWaypoints();
152 return std::vector<routing::LaneWaypoint>();
156 std::shared_ptr<routing::LaneWaypoint> &end_point)
const {
157 if (
nullptr == current_pnc_map_) {
161 current_pnc_map_->GetEndLaneWayPoint(end_point);
166 if (
nullptr == current_pnc_map_) {
169 return current_pnc_map_->GetLaneById(
id);
174 std::lock_guard<std::mutex> lock(vehicle_state_mutex_);
175 vehicle_state_ = vehicle_state;
179 if (FLAGS_use_navigation_mode) {
182 if (!is_initialized_) {
183 AERROR <<
"ReferenceLineProvider has NOT been initiated.";
187 if (FLAGS_enable_reference_line_provider_thread) {
188 task_future_ = cyber::Async(&ReferenceLineProvider::GenerateThread,
this);
195 if (FLAGS_enable_reference_line_provider_thread) {
201 std::lock_guard<std::mutex> lock(routing_mutex_);
202 has_planning_command_ =
false;
203 is_new_command_ =
false;
204 reference_lines_.clear();
205 route_segments_.clear();
206 is_reference_line_updated_ =
false;
207 planning_command_.Clear();
208 while (!reference_line_history_.empty()) {
209 reference_line_history_.pop();
213void ReferenceLineProvider::UpdateReferenceLine(
214 const std::list<ReferenceLine> &reference_lines,
215 const std::list<hdmap::RouteSegments> &route_segments) {
216 if (reference_lines.size() != route_segments.size()) {
217 AERROR <<
"The calculated reference line size(" << reference_lines.size()
218 <<
") and route_segments size(" << route_segments.size()
219 <<
") are different";
222 if (reference_lines.empty()) {
225 std::lock_guard<std::mutex> lock(reference_lines_mutex_);
226 if (reference_lines_.size() != reference_lines.size()) {
227 reference_lines_ = reference_lines;
228 route_segments_ = route_segments;
230 auto segment_iter = route_segments.begin();
231 auto internal_iter = reference_lines_.begin();
232 auto internal_segment_iter = route_segments_.begin();
233 for (
auto iter = reference_lines.begin();
234 iter != reference_lines.end() &&
235 segment_iter != route_segments.end() &&
236 internal_iter != reference_lines_.end() &&
237 internal_segment_iter != route_segments_.end();
238 ++iter, ++segment_iter, ++internal_iter, ++internal_segment_iter) {
239 if (iter->reference_points().empty()) {
240 *internal_iter = *iter;
241 *internal_segment_iter = *segment_iter;
245 iter->reference_points().front(),
246 internal_iter->reference_points().front()) &&
248 internal_iter->reference_points().back()) &&
249 std::fabs(iter->Length() - internal_iter->Length()) <
253 *internal_iter = *iter;
254 *internal_segment_iter = *segment_iter;
258 reference_line_history_.push(reference_lines_);
259 route_segments_history_.push(route_segments_);
260 static constexpr int kMaxHistoryNum = 3;
261 if (reference_line_history_.size() > kMaxHistoryNum) {
262 reference_line_history_.pop();
263 route_segments_history_.pop();
267void ReferenceLineProvider::GenerateThread() {
269 static constexpr int32_t kSleepTime = 50;
270 cyber::SleepFor(std::chrono::milliseconds(kSleepTime));
272 if (!has_planning_command_) {
275 std::list<ReferenceLine> reference_lines;
276 std::list<hdmap::RouteSegments> segments;
277 if (!CreateReferenceLine(&reference_lines, &segments)) {
278 is_reference_line_updated_ =
false;
279 AERROR <<
"Fail to get reference line";
282 UpdateReferenceLine(reference_lines, segments);
284 std::lock_guard<std::mutex> lock(reference_lines_mutex_);
285 last_calculation_time_ = end_time - start_time;
286 is_reference_line_updated_ =
true;
291 if (FLAGS_enable_reference_line_provider_thread &&
292 !FLAGS_use_navigation_mode) {
293 std::lock_guard<std::mutex> lock(reference_lines_mutex_);
294 return last_calculation_time_;
296 return last_calculation_time_;
301 std::list<ReferenceLine> *reference_lines,
302 std::list<hdmap::RouteSegments> *segments) {
303 CHECK_NOTNULL(reference_lines);
304 CHECK_NOTNULL(segments);
305 if (!has_planning_command_) {
308 if (FLAGS_use_navigation_mode) {
310 bool result = GetReferenceLinesFromRelativeMap(reference_lines, segments);
312 AERROR <<
"Failed to get reference line from relative map";
315 last_calculation_time_ = end_time - start_time;
319 if (FLAGS_enable_reference_line_provider_thread) {
320 std::lock_guard<std::mutex> lock(reference_lines_mutex_);
321 if (!reference_lines_.empty()) {
322 reference_lines->assign(reference_lines_.begin(), reference_lines_.end());
323 segments->assign(route_segments_.begin(), route_segments_.end());
328 if (CreateReferenceLine(reference_lines, segments)) {
329 UpdateReferenceLine(*reference_lines, *segments);
331 last_calculation_time_ = end_time - start_time;
336 AINFO <<
"Reference line is NOT ready.";
337 if (reference_line_history_.empty()) {
338 AINFO <<
"Failed to use reference line latest history";
342 reference_lines->assign(reference_line_history_.back().begin(),
343 reference_line_history_.back().end());
344 segments->assign(route_segments_history_.back().begin(),
345 route_segments_history_.back().end());
346 AWARN <<
"Use reference line from history!";
350void ReferenceLineProvider::PrioritizeChangeLane(
351 std::list<hdmap::RouteSegments> *route_segments) {
352 CHECK_NOTNULL(route_segments);
353 auto iter = route_segments->begin();
354 while (iter != route_segments->end()) {
355 if (!iter->IsOnSegment()) {
356 route_segments->splice(route_segments->begin(), *route_segments, iter);
363bool ReferenceLineProvider::GetReferenceLinesFromRelativeMap(
364 std::list<ReferenceLine> *reference_lines,
365 std::list<hdmap::RouteSegments> *segments) {
366 CHECK_GE(relative_map_->navigation_path_size(), 0);
367 CHECK_NOTNULL(reference_lines);
368 CHECK_NOTNULL(segments);
370 if (relative_map_->navigation_path().empty()) {
371 AERROR <<
"There isn't any navigation path in current relative map.";
377 AERROR <<
"hdmap is null";
382 std::unordered_set<std::string> navigation_lane_ids;
383 for (
const auto &path_pair : relative_map_->navigation_path()) {
384 const auto lane_id = path_pair.first;
385 navigation_lane_ids.insert(lane_id);
387 if (navigation_lane_ids.empty()) {
388 AERROR <<
"navigation path ids is empty";
392 common::VehicleState vehicle_state = vehicle_state_provider_->
vehicle_state();
393 hdmap::LaneWaypoint adc_lane_way_point;
394 if (!GetNearestWayPointFromNavigationPath(vehicle_state, navigation_lane_ids,
395 &adc_lane_way_point)) {
398 const std::string adc_lane_id = adc_lane_way_point.lane->id().id();
399 auto *adc_navigation_path = apollo::common::util::FindOrNull(
400 relative_map_->navigation_path(), adc_lane_id);
401 if (adc_navigation_path ==
nullptr) {
402 AERROR <<
"adc lane cannot be found in relative_map_->navigation_path";
405 const uint32_t adc_lane_priority = adc_navigation_path->path_priority();
407 std::vector<std::string> left_neighbor_lane_ids;
408 auto left_lane_ptr = adc_lane_way_point.lane;
409 while (left_lane_ptr !=
nullptr &&
410 left_lane_ptr->lane().left_neighbor_forward_lane_id_size() > 0) {
411 auto neighbor_lane_id =
412 left_lane_ptr->lane().left_neighbor_forward_lane_id(0);
413 left_neighbor_lane_ids.emplace_back(neighbor_lane_id.id());
414 left_lane_ptr = hdmap->GetLaneById(neighbor_lane_id);
417 <<
" left neighbor size : " << left_neighbor_lane_ids.size();
418 for (
const auto &neighbor : left_neighbor_lane_ids) {
419 ADEBUG << adc_lane_id <<
" left neighbor : " << neighbor;
422 std::vector<std::string> right_neighbor_lane_ids;
423 auto right_lane_ptr = adc_lane_way_point.lane;
424 while (right_lane_ptr !=
nullptr &&
425 right_lane_ptr->lane().right_neighbor_forward_lane_id_size() > 0) {
426 auto neighbor_lane_id =
427 right_lane_ptr->lane().right_neighbor_forward_lane_id(0);
428 right_neighbor_lane_ids.emplace_back(neighbor_lane_id.id());
429 right_lane_ptr = hdmap->GetLaneById(neighbor_lane_id);
432 <<
" right neighbor size : " << right_neighbor_lane_ids.size();
433 for (
const auto &neighbor : right_neighbor_lane_ids) {
434 ADEBUG << adc_lane_id <<
" right neighbor : " << neighbor;
438 using LaneIdPair = std::pair<std::string, uint32_t>;
439 std::vector<LaneIdPair> high_priority_lane_pairs;
440 ADEBUG <<
"relative_map_->navigation_path_size = "
441 << relative_map_->navigation_path_size();
442 for (
const auto &path_pair : relative_map_->navigation_path()) {
443 const auto lane_id = path_pair.first;
444 const uint32_t priority = path_pair.second.path_priority();
445 ADEBUG <<
"lane_id = " << lane_id <<
" priority = " << priority
446 <<
" adc_lane_id = " << adc_lane_id
447 <<
" adc_lane_priority = " << adc_lane_priority;
449 if (adc_lane_id != lane_id && priority < adc_lane_priority) {
450 high_priority_lane_pairs.emplace_back(lane_id, priority);
454 bool is_lane_change_needed =
false;
455 LaneIdPair target_lane_pair;
456 if (!high_priority_lane_pairs.empty()) {
457 std::sort(high_priority_lane_pairs.begin(), high_priority_lane_pairs.end(),
458 [](
const LaneIdPair &left,
const LaneIdPair &right) {
459 return left.second < right.second;
461 ADEBUG <<
"need to change lane";
463 target_lane_pair = high_priority_lane_pairs.front();
464 is_lane_change_needed =
true;
469 std::string nearest_neighbor_lane_id;
470 if (is_lane_change_needed) {
472 if (left_neighbor_lane_ids.end() !=
473 std::find(left_neighbor_lane_ids.begin(), left_neighbor_lane_ids.end(),
474 target_lane_pair.first)) {
478 nearest_neighbor_lane_id =
479 adc_lane_way_point.lane->lane().left_neighbor_forward_lane_id(0).id();
480 }
else if (right_neighbor_lane_ids.end() !=
481 std::find(right_neighbor_lane_ids.begin(),
482 right_neighbor_lane_ids.end(),
483 target_lane_pair.first)) {
488 nearest_neighbor_lane_id = adc_lane_way_point.lane->lane()
489 .right_neighbor_forward_lane_id(0)
494 for (
const auto &path_pair : relative_map_->navigation_path()) {
495 const auto &lane_id = path_pair.first;
496 const auto &path_points = path_pair.second.path().path_point();
498 RouteSegments segment;
499 segment.emplace_back(lane_ptr, 0.0, lane_ptr->total_length());
500 segment.SetCanExit(
true);
501 segment.SetId(lane_id);
503 segment.SetStopForDestination(
false);
506 if (is_lane_change_needed) {
507 if (lane_id == nearest_neighbor_lane_id) {
508 ADEBUG <<
"adc lane_id = " << adc_lane_id
509 <<
" nearest_neighbor_lane_id = " << lane_id;
510 segment.SetIsNeighborSegment(
true);
511 segment.SetPreviousAction(lane_change_type);
512 }
else if (lane_id == adc_lane_id) {
513 segment.SetIsOnSegment(
true);
514 segment.SetNextAction(lane_change_type);
518 segments->emplace_back(segment);
519 std::vector<ReferencePoint> ref_points;
520 for (
const auto &path_point : path_points) {
521 ref_points.emplace_back(
522 MapPathPoint{Vec2d{path_point.x(), path_point.y()},
524 LaneWaypoint(lane_ptr, path_point.s())},
525 path_point.kappa(), path_point.dkappa());
527 reference_lines->emplace_back(ref_points.begin(), ref_points.end());
528 reference_lines->back().SetPriority(path_pair.second.path_priority());
530 return !segments->empty();
533bool ReferenceLineProvider::GetNearestWayPointFromNavigationPath(
534 const common::VehicleState &state,
535 const std::unordered_set<std::string> &navigation_lane_ids,
536 hdmap::LaneWaypoint *waypoint) {
537 const double kMaxDistance = 10.0;
538 waypoint->lane =
nullptr;
539 std::vector<hdmap::LaneInfoConstPtr> lanes;
541 if (std::isnan(point.x()) || std::isnan(point.y())) {
542 AERROR <<
"vehicle state is invalid";
547 AERROR <<
"hdmap is null";
553 const int status = hdmap->GetLanesWithHeading(
554 point, kMaxDistance, state.heading(), M_PI / 2.0, &lanes);
556 AERROR <<
"failed to get lane from point " << point.ShortDebugString();
561 std::vector<hdmap::LaneInfoConstPtr> valid_lanes;
562 std::copy_if(lanes.begin(), lanes.end(), std::back_inserter(valid_lanes),
564 return navigation_lane_ids.count(ptr->lane().id().id()) > 0;
566 if (valid_lanes.empty()) {
567 AERROR <<
"no valid lane found within " << kMaxDistance
568 <<
" meters with heading " << state.heading();
573 double min_distance = std::numeric_limits<double>::infinity();
574 for (
const auto &lane : valid_lanes) {
578 if (!lane->GetProjection({point.x(), point.y()}, state.heading(), &s, &l)) {
581 static constexpr double kEpsilon = 1e-6;
582 if (s > (lane->total_length() + kEpsilon) || (s + kEpsilon) < 0.0) {
587 double distance = 0.0;
588 common::PointENU map_point =
589 lane->GetNearestPoint({point.x(), point.y()}, &distance);
591 if (distance < min_distance) {
594 if (!lane->GetProjection({map_point.x(), map_point.y()}, &s, &l)) {
595 AERROR <<
"failed to get projection for map_point "
596 << map_point.DebugString();
599 min_distance = distance;
600 waypoint->lane = lane;
605 if (waypoint->lane ==
nullptr) {
606 AERROR <<
"failed to find nearest point " << point.ShortDebugString();
608 return waypoint->lane !=
nullptr;
611bool ReferenceLineProvider::CreateRouteSegments(
612 const common::VehicleState &vehicle_state,
613 std::list<hdmap::RouteSegments> *segments) {
615 std::lock_guard<std::mutex> lock(pnc_map_mutex_);
616 if (!current_pnc_map_->GetRouteSegments(vehicle_state, segments)) {
617 AERROR <<
"Failed to extract segments from routing";
621 for (
auto &seg : *segments) {
622 ADEBUG << seg.DebugString();
624 if (FLAGS_prioritize_change_lane) {
625 PrioritizeChangeLane(segments);
627 return !segments->empty();
630bool ReferenceLineProvider::CreateReferenceLine(
631 std::list<ReferenceLine> *reference_lines,
632 std::list<hdmap::RouteSegments> *segments) {
633 CHECK_NOTNULL(reference_lines);
634 CHECK_NOTNULL(segments);
636 common::VehicleState vehicle_state;
638 std::lock_guard<std::mutex> lock(vehicle_state_mutex_);
639 vehicle_state = vehicle_state_;
642 planning::PlanningCommand command;
644 std::lock_guard<std::mutex> lock(routing_mutex_);
645 command = planning_command_;
647 if (
nullptr == current_pnc_map_) {
648 AERROR <<
"Current pnc map is null! " << command.DebugString();
652 if (!CreateRouteSegments(vehicle_state, segments)) {
653 AERROR <<
"Failed to create reference line from routing";
656 if (is_new_command_ || !FLAGS_enable_reference_line_stitching) {
657 for (
auto iter = segments->begin(); iter != segments->end();) {
658 reference_lines->emplace_back();
659 if (!SmoothRouteSegment(*iter, &reference_lines->back())) {
660 AERROR <<
"Failed to create reference line from route segments";
661 reference_lines->pop_back();
662 iter = segments->erase(iter);
665 if (!reference_lines->back().XYToSL(
666 vehicle_state.heading(),
667 common::math::Vec2d(vehicle_state.x(), vehicle_state.y()),
669 AWARN <<
"Failed to project point: {" << vehicle_state.x() <<
","
670 << vehicle_state.y() <<
"} to stitched reference line";
672 Shrink(sl, &reference_lines->back(), &(*iter));
676 is_new_command_ =
false;
679 for (
auto iter = segments->begin(); iter != segments->end();) {
680 reference_lines->emplace_back();
681 if (!ExtendReferenceLine(vehicle_state, &(*iter),
682 &reference_lines->back())) {
683 AERROR <<
"Failed to extend reference line";
684 reference_lines->pop_back();
685 iter = segments->erase(iter);
694bool ReferenceLineProvider::ExtendReferenceLine(
const VehicleState &state,
695 RouteSegments *segments,
696 ReferenceLine *reference_line) {
697 RouteSegments segment_properties;
698 segment_properties.SetProperties(*segments);
699 auto prev_segment = route_segments_.begin();
700 auto prev_ref = reference_lines_.begin();
701 while (prev_segment != route_segments_.end()) {
702 if (prev_segment->IsConnectedSegment(*segments)) {
708 if (prev_segment == route_segments_.end()) {
709 if (!route_segments_.empty() && segments->IsOnSegment()) {
710 AWARN <<
"Current route segment is not connected with previous route "
713 return SmoothRouteSegment(*segments, reference_line);
715 common::SLPoint sl_point;
716 Vec2d vec2d(state.x(), state.y());
717 LaneWaypoint waypoint;
718 if (!prev_segment->GetProjection(vec2d, state.heading(), &sl_point,
720 AWARN <<
"Vehicle current point: " << vec2d.DebugString()
721 <<
" not on previous reference line";
722 return SmoothRouteSegment(*segments, reference_line);
725 const double remain_s = prev_segment_length - sl_point.s();
726 const double look_forward_required_distance =
728 if (remain_s > look_forward_required_distance) {
729 *segments = *prev_segment;
730 segments->SetProperties(segment_properties);
731 *reference_line = *prev_ref;
732 ADEBUG <<
"Reference line remain " << remain_s
733 <<
", which is more than required " << look_forward_required_distance
734 <<
" and no need to extend";
737 double future_start_s =
738 std::max(sl_point.s(), prev_segment_length -
739 FLAGS_reference_line_stitch_overlap_distance);
740 double future_end_s =
741 prev_segment_length + FLAGS_look_forward_extend_distance;
742 RouteSegments shifted_segments;
743 std::unique_lock<std::mutex> lock(pnc_map_mutex_);
744 if (!current_pnc_map_->ExtendSegments(*prev_segment, future_start_s,
745 future_end_s, &shifted_segments)) {
747 AERROR <<
"Failed to shift route segments forward";
748 return SmoothRouteSegment(*segments, reference_line);
751 if (prev_segment->IsWaypointOnSegment(shifted_segments.LastWaypoint())) {
752 *segments = *prev_segment;
753 segments->SetProperties(segment_properties);
754 *reference_line = *prev_ref;
755 ADEBUG <<
"Could not further extend reference line";
758 hdmap::Path path(shifted_segments);
759 ReferenceLine new_ref(path);
760 if (!SmoothPrefixedReferenceLine(*prev_ref, new_ref, reference_line)) {
761 AWARN <<
"Failed to smooth forward shifted reference line";
762 return SmoothRouteSegment(*segments, reference_line);
764 if (!reference_line->Stitch(*prev_ref)) {
765 AWARN <<
"Failed to stitch reference line";
766 return SmoothRouteSegment(*segments, reference_line);
768 if (!shifted_segments.Stitch(*prev_segment)) {
769 AWARN <<
"Failed to stitch route segments";
770 return SmoothRouteSegment(*segments, reference_line);
772 *segments = shifted_segments;
773 segments->SetProperties(segment_properties);
775 if (!reference_line->XYToSL(state.heading(), vec2d, &sl)) {
776 AWARN <<
"Failed to project point: " << vec2d.DebugString()
777 <<
" to stitched reference line";
779 return Shrink(sl, reference_line, segments);
782bool ReferenceLineProvider::Shrink(
const common::SLPoint &sl,
783 ReferenceLine *reference_line,
784 RouteSegments *segments) {
786 double new_backward_distance = sl.s();
787 double new_forward_distance = reference_line->Length() - sl.s();
788 bool need_shrink =
false;
789 if (sl.s() > planning::FLAGS_look_backward_distance * 1.5) {
790 ADEBUG <<
"reference line back side is " << sl.s()
791 <<
", shrink reference line: origin length: "
792 << reference_line->Length();
793 new_backward_distance = planning::FLAGS_look_backward_distance;
797 const auto index = reference_line->GetNearestReferenceIndex(sl.s());
798 const auto &ref_points = reference_line->reference_points();
799 const double cur_heading = ref_points[index].heading();
800 auto last_index = index;
801 while (last_index < ref_points.size() &&
802 std::fabs(
AngleDiff(cur_heading, ref_points[last_index].heading())) <
803 FLAGS_reference_line_max_forward_heading_diff) {
807 if (last_index != ref_points.size() - 1) {
809 common::SLPoint forward_sl;
810 reference_line->XYToSL(ref_points[last_index], &forward_sl);
811 new_forward_distance = forward_sl.s() - sl.s();
816 while (last_index > 0 &&
817 abs(
AngleDiff(cur_heading, ref_points[last_index].heading())) <
818 FLAGS_reference_line_max_backward_heading_diff) {
821 if (last_index != 0) {
823 common::SLPoint backward_sl;
824 reference_line->XYToSL(ref_points[last_index], &backward_sl);
825 new_backward_distance = sl.s() - backward_sl.s();
829 if (!reference_line->Segment(sl.s(), new_backward_distance,
830 new_forward_distance)) {
831 AWARN <<
"Failed to shrink reference line";
833 if (!segments->Shrink(sl.s(), new_backward_distance,
834 new_forward_distance)) {
835 AWARN <<
"Failed to shrink route segment";
841bool ReferenceLineProvider::IsReferenceLineSmoothValid(
842 const ReferenceLine &raw,
const ReferenceLine &smoothed)
const {
843 static constexpr double kReferenceLineDiffCheckStep = 10.0;
844 for (
double s = 0.0; s < smoothed.Length();
845 s += kReferenceLineDiffCheckStep) {
846 auto xy_new = smoothed.GetReferencePoint(s);
848 common::SLPoint sl_new;
849 if (!raw.XYToSL(xy_new, &sl_new)) {
850 AERROR <<
"Fail to change xy point on smoothed reference line to sl "
851 "point respect to raw reference line.";
855 const double diff = std::fabs(sl_new.l());
856 if (diff > FLAGS_smoothed_reference_line_max_diff) {
857 AERROR <<
"Fail to provide reference line because too large diff "
858 "between smoothed and raw reference lines. diff: "
866AnchorPoint ReferenceLineProvider::GetAnchorPoint(
867 const ReferenceLine &reference_line,
double s)
const {
870 auto ref_point = reference_line.GetReferencePoint(s);
871 if (ref_point.lane_waypoints().empty()) {
872 anchor.path_point = ref_point.ToPathPoint(s);
877 const double adc_width =
879 const Vec2d left_vec =
881 auto waypoint = ref_point.lane_waypoints().front();
882 double left_width = 0.0;
883 double right_width = 0.0;
884 waypoint.lane->GetWidth(waypoint.s, &left_width, &right_width);
885 const double kEpislon = 1e-8;
886 double effective_width = 0.0;
889 double safe_lane_width = left_width + right_width;
890 safe_lane_width -= adc_width;
891 bool is_lane_width_safe =
true;
893 if (safe_lane_width < kEpislon) {
894 ADEBUG <<
"lane width [" << left_width + right_width <<
"] "
895 <<
"is smaller than adc width [" << adc_width <<
"]";
896 effective_width = kEpislon;
897 is_lane_width_safe =
false;
900 double center_shift = 0.0;
902 safe_lane_width -= smoother_config_.
curb_shift();
903 if (safe_lane_width < kEpislon) {
904 ADEBUG <<
"lane width smaller than adc width and right curb shift";
905 effective_width = kEpislon;
906 is_lane_width_safe =
false;
908 center_shift += 0.5 * smoother_config_.
curb_shift();
912 safe_lane_width -= smoother_config_.
curb_shift();
913 if (safe_lane_width < kEpislon) {
914 ADEBUG <<
"lane width smaller than adc width and left curb shift";
915 effective_width = kEpislon;
916 is_lane_width_safe =
false;
918 center_shift -= 0.5 * smoother_config_.
curb_shift();
923 const double buffered_width =
926 buffered_width < kEpislon ? safe_lane_width : buffered_width;
929 if (is_lane_width_safe) {
930 effective_width = 0.5 * safe_lane_width;
933 ref_point += left_vec * center_shift;
934 anchor.path_point = ref_point.ToPathPoint(s);
941void ReferenceLineProvider::GetAnchorPoints(
942 const ReferenceLine &reference_line,
943 std::vector<AnchorPoint> *anchor_points)
const {
944 CHECK_NOTNULL(anchor_points);
947 std::max(2,
static_cast<int>(reference_line.Length() / interval + 0.5));
948 std::vector<double> anchor_s;
951 for (
const double s : anchor_s) {
952 AnchorPoint anchor = GetAnchorPoint(reference_line, s);
953 anchor_points->emplace_back(anchor);
955 anchor_points->front().longitudinal_bound = 1e-6;
956 anchor_points->front().lateral_bound = 1e-6;
957 anchor_points->front().enforced =
true;
958 anchor_points->back().longitudinal_bound = 1e-6;
959 anchor_points->back().lateral_bound = 1e-6;
960 anchor_points->back().enforced =
true;
963bool ReferenceLineProvider::SmoothRouteSegment(
const RouteSegments &segments,
964 ReferenceLine *reference_line) {
965 hdmap::Path path(segments);
966 return SmoothReferenceLine(ReferenceLine(path), reference_line);
969bool ReferenceLineProvider::SmoothPrefixedReferenceLine(
970 const ReferenceLine &prefix_ref,
const ReferenceLine &raw_ref,
971 ReferenceLine *reference_line) {
972 if (!FLAGS_enable_smooth_reference_line) {
973 *reference_line = raw_ref;
977 std::vector<AnchorPoint> anchor_points;
978 GetAnchorPoints(raw_ref, &anchor_points);
980 for (
auto &point : anchor_points) {
981 common::SLPoint sl_point;
982 if (!prefix_ref.XYToSL(point.path_point, &sl_point)) {
985 if (sl_point.s() < 0 || sl_point.s() > prefix_ref.Length()) {
988 auto prefix_ref_point = prefix_ref.GetNearestReferencePoint(sl_point.s());
989 point.path_point.set_x(prefix_ref_point.x());
990 point.path_point.set_y(prefix_ref_point.y());
991 point.path_point.set_z(0.0);
992 point.path_point.set_theta(prefix_ref_point.heading());
993 point.longitudinal_bound = 1e-6;
994 point.lateral_bound = 1e-6;
995 point.enforced =
true;
999 smoother_->SetAnchorPoints(anchor_points);
1000 if (!smoother_->Smooth(raw_ref, reference_line)) {
1001 AERROR <<
"Failed to smooth prefixed reference line with anchor points";
1004 if (!IsReferenceLineSmoothValid(raw_ref, *reference_line)) {
1005 AERROR <<
"The smoothed reference line error is too large";
1011bool ReferenceLineProvider::SmoothReferenceLine(
1012 const ReferenceLine &raw_reference_line, ReferenceLine *reference_line) {
1013 if (!FLAGS_enable_smooth_reference_line) {
1014 *reference_line = raw_reference_line;
1018 std::vector<AnchorPoint> anchor_points;
1019 GetAnchorPoints(raw_reference_line, &anchor_points);
1020 smoother_->SetAnchorPoints(anchor_points);
1021 if (!smoother_->Smooth(raw_reference_line, reference_line)) {
1022 AERROR <<
"Failed to smooth reference line with anchor points";
1025 if (!IsReferenceLineSmoothValid(raw_reference_line, *reference_line)) {
1026 AERROR <<
"The smoothed reference line error is too large";
1033 if (
nullptr == current_pnc_map_) {
1034 AERROR <<
"Cannot find pnc map to get adc waypoint!";
1037 *waypoint = current_pnc_map_->GetAdcWaypoint();
1042 if (
nullptr == current_pnc_map_) {
1043 AERROR <<
"Cannot find pnc map to get adc distance to destination!";
1046 *dis = current_pnc_map_->GetDistanceToDestination();
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
The class of vehicle state.
const VehicleState & vehicle_state() const
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)
a singleton clock that can be used to get the current timestamp.
static double NowInSeconds()
gets the current time in second.
static PluginManager * Instance()
get singleton instance of PluginManager
std::shared_ptr< Base > CreateInstance(const std::string &derived_class)
create plugin instance of derived class based on Base
static const HDMap * BaseMapPtr()
static double Length(const RouteSegments &segments)
static double LookForwardDistance(const double velocity)
bool GetAdcDis2Destination(double *dis) const
ReferenceLineProvider()=default
bool GetReferenceLines(std::list< ReferenceLine > *reference_lines, std::list< hdmap::RouteSegments > *segments)
void UpdateVehicleState(const common::VehicleState &vehicle_state)
void GetEndLaneWayPoint(std::shared_ptr< routing::LaneWaypoint > &end_point) const
bool GetAdcWaypoint(hdmap::LaneWaypoint *waypoint) const
~ReferenceLineProvider()
Default destructor.
bool UpdatePlanningCommand(const planning::PlanningCommand &command)
Update when new PlanningCommand is received.
hdmap::LaneInfoConstPtr GetLaneById(const hdmap::Id &id) const
std::vector< routing::LaneWaypoint > FutureRouteWaypoints()
Planning module main class.
Math-related util functions.
constexpr double kMathEpsilon
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
double AngleDiff(const double from, const double to)
Calculate the difference between angle from and to
bool SamePointXY(const U &u, const V &v)
Check if two points u and v are the same point on XY dimension.
void uniform_slice(const T start, const T end, uint32_t num, std::vector< T > *sliced)
uniformly slice a segment [start, end] to num + 1 pieces the result sliced will contain the n + 1 poi...
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
apollo::hdmap::Id MakeMapId(const std::string &id)
create a Map ID given a string.
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
LaneBoundaryType::Type LeftBoundaryType(const LaneWaypoint &waypoint)
get left boundary type at a waypoint.
LaneBoundaryType::Type RightBoundaryType(const LaneWaypoint &waypoint)
get left boundary type at a waypoint.
float diff(Image< float > *I, int x1, int y1, int x2, int y2)
Dissimilarity measure between pixels
T abs(const T &x)
Get absolute value of x
Declaration of the class ReferenceLineProvider.
optional VehicleParam vehicle_param
repeated string pnc_map_class
optional double max_lateral_boundary_bound
optional double lateral_buffer
optional double max_constraint_interval
optional double longitudinal_boundary_bound
optional double curb_shift
optional double min_lateral_boundary_bound