Apollo 11.0
自动驾驶开放平台
reference_line_info.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
22
23#include <algorithm>
24
25#include "absl/strings/str_cat.h"
26
27#include "modules/common_msgs/planning_msgs/sl_boundary.pb.h"
28#include "modules/planning/planning_base/proto/planning_status.pb.h"
29
30#include "cyber/task/task.h"
37
38namespace apollo {
39namespace planning {
40
49
50std::unordered_map<std::string, bool>
51 ReferenceLineInfo::junction_right_of_way_map_;
52
54 const TrajectoryPoint& adc_planning_point,
55 const ReferenceLine& reference_line,
56 const hdmap::RouteSegments& segments)
57 : vehicle_state_(vehicle_state),
58 adc_planning_point_(adc_planning_point),
59 reference_line_(reference_line),
60 lanes_(segments) {
61 if (lanes_.size() == 0) {
62 return;
63 }
64 std::ostringstream segs_id;
65 segs_id.setf(std::ios::fixed);
66 segs_id.precision(2);
67 segs_id.str("");
68 for (const auto& seg : lanes_) {
69 segs_id << "_" << seg.lane->id().id();
70 }
71
72 segs_id << "_" << lanes_.front().start_s << "_" << lanes_.back().end_s;
73 key_ = cyber::common::Hash(segs_id.str());
74 id_ = segs_id.str();
75}
76
77bool ReferenceLineInfo::Init(const std::vector<const Obstacle*>& obstacles,
78 double target_speed) {
79 const auto& param = VehicleConfigHelper::GetConfig().vehicle_param();
80 // stitching point
81 const auto& path_point = adc_planning_point_.path_point();
82 Vec2d position(path_point.x(), path_point.y());
83 Vec2d vec_to_center(
84 (param.front_edge_to_center() - param.back_edge_to_center()) / 2.0,
85 (param.left_edge_to_center() - param.right_edge_to_center()) / 2.0);
86 Vec2d center(position + vec_to_center.rotate(path_point.theta()));
87 Box2d box(center, path_point.theta(), param.length(), param.width());
88 // realtime vehicle position
89 Vec2d vehicle_position(vehicle_state_.x(), vehicle_state_.y());
90 Vec2d vehicle_center(vehicle_position +
91 vec_to_center.rotate(vehicle_state_.heading()));
92 Box2d vehicle_box(vehicle_center, vehicle_state_.heading(), param.length(),
93 param.width());
94
95 if (!reference_line_.GetSLBoundary(box, &adc_sl_boundary_)) {
96 AERROR << "Failed to get ADC boundary from box: " << box.DebugString();
97 return false;
98 }
99
100 InitFirstOverlaps();
101
102 if (adc_sl_boundary_.end_s() < 0 ||
103 adc_sl_boundary_.start_s() > reference_line_.Length()) {
104 AWARN << "Vehicle SL " << adc_sl_boundary_.ShortDebugString()
105 << " is not on reference line:[0, " << reference_line_.Length()
106 << "]";
107 }
108 static constexpr double kOutOfReferenceLineL = 14.0; // in meters
109 if (adc_sl_boundary_.start_l() > kOutOfReferenceLineL ||
110 adc_sl_boundary_.end_l() < -kOutOfReferenceLineL) {
111 AERROR << "Ego vehicle is too far away from reference line."
112 << "adc_sl_boundary_.start_l:" << adc_sl_boundary_.start_l()
113 << "adc_sl_boundary_.end_l:" << adc_sl_boundary_.end_l();
114 return false;
115 }
116 is_on_reference_line_ = reference_line_.IsOnLane(adc_sl_boundary_);
117 if (!AddObstacles(obstacles)) {
118 AERROR << "Failed to add obstacles to reference line";
119 return false;
120 }
121
122 const auto& map_path = reference_line_.map_path();
123 for (const auto& speed_bump : map_path.speed_bump_overlaps()) {
124 // -1 and + 1.0 are added to make sure it can be sampled.
125 reference_line_.AddSpeedLimit(speed_bump.start_s - 1.0,
126 speed_bump.end_s + 1.0,
127 FLAGS_speed_bump_speed_limit);
128 }
129
130 SetCruiseSpeed(target_speed);
131 // set lattice planning target speed limit;
132 SetLatticeCruiseSpeed(target_speed);
133
134 vehicle_signal_.Clear();
135
136 return true;
137}
138
139const std::vector<PathData>& ReferenceLineInfo::GetCandidatePathData() const {
140 return candidate_path_data_;
141}
142
144 std::vector<PathData>&& candidate_path_data) {
145 candidate_path_data_ = std::move(candidate_path_data);
146}
147
148const std::vector<PathBoundary>& ReferenceLineInfo::GetCandidatePathBoundaries()
149 const {
150 return candidate_path_boundaries_;
151}
152
154 std::vector<PathBoundary>&& path_boundaries) {
155 candidate_path_boundaries_ = std::move(path_boundaries);
156}
157
159 if (base_cruise_speed_ <= speed) {
160 return;
161 }
162 cruise_speed_ = speed;
163}
164
166 return base_cruise_speed_ > 0.0 ? base_cruise_speed_
167 : FLAGS_default_cruise_speed;
168}
169
171 return cruise_speed_ > 0.0 ? cruise_speed_ : FLAGS_default_cruise_speed;
172}
173
175 const double s) const {
176 std::vector<hdmap::LaneInfoConstPtr> lanes;
177 reference_line_.GetLaneFromS(s, &lanes);
178 if (lanes.empty()) {
179 AWARN << "cannot get any lane using s";
180 return nullptr;
181 }
182
183 return lanes.front();
184}
185
187 const ReferenceLineInfo::LaneType lane_type, const double s,
188 hdmap::Id* ptr_lane_id, double* ptr_lane_width) const {
189 auto ptr_lane_info = LocateLaneInfo(s);
190 if (ptr_lane_info == nullptr) {
191 return false;
192 }
193
194 switch (lane_type) {
196 if (ptr_lane_info->lane().left_neighbor_forward_lane_id().empty()) {
197 return false;
198 }
199 *ptr_lane_id = ptr_lane_info->lane().left_neighbor_forward_lane_id(0);
200 break;
201 }
203 if (ptr_lane_info->lane().left_neighbor_reverse_lane_id().empty()) {
204 return false;
205 }
206 *ptr_lane_id = ptr_lane_info->lane().left_neighbor_reverse_lane_id(0);
207 break;
208 }
210 if (ptr_lane_info->lane().right_neighbor_forward_lane_id().empty()) {
211 return false;
212 }
213 *ptr_lane_id = ptr_lane_info->lane().right_neighbor_forward_lane_id(0);
214 break;
215 }
217 if (ptr_lane_info->lane().right_neighbor_reverse_lane_id().empty()) {
218 return false;
219 }
220 *ptr_lane_id = ptr_lane_info->lane().right_neighbor_reverse_lane_id(0);
221 break;
222 }
223 default:
224 ACHECK(false);
225 }
226 auto ptr_neighbor_lane =
228 if (ptr_neighbor_lane == nullptr) {
229 return false;
230 }
231
232 auto ref_point = reference_line_.GetReferencePoint(s);
233
234 double neighbor_s = 0.0;
235 double neighbor_l = 0.0;
236 if (!ptr_neighbor_lane->GetProjection({ref_point.x(), ref_point.y()},
237 &neighbor_s, &neighbor_l)) {
238 return false;
239 }
240
241 *ptr_lane_width = ptr_neighbor_lane->GetWidth(neighbor_s);
242 return true;
243}
244
245bool ReferenceLineInfo::GetFirstOverlap(
246 const std::vector<hdmap::PathOverlap>& path_overlaps,
247 hdmap::PathOverlap* path_overlap) {
248 CHECK_NOTNULL(path_overlap);
249 const double start_s = adc_sl_boundary_.end_s();
250 static constexpr double kMaxOverlapRange = 500.0;
251 double overlap_min_s = kMaxOverlapRange;
252
253 auto overlap_min_s_iter = path_overlaps.end();
254 for (auto iter = path_overlaps.begin(); iter != path_overlaps.end(); ++iter) {
255 if (iter->end_s < start_s) {
256 continue;
257 }
258 if (overlap_min_s > iter->start_s) {
259 overlap_min_s_iter = iter;
260 overlap_min_s = iter->start_s;
261 }
262 }
263
264 // Ensure that the path_overlaps is not empty.
265 if (overlap_min_s_iter != path_overlaps.end()) {
266 *path_overlap = *overlap_min_s_iter;
267 }
268
269 return overlap_min_s < kMaxOverlapRange;
270}
271
272void ReferenceLineInfo::InitFirstOverlaps() {
273 const auto& map_path = reference_line_.map_path();
274 // clear_zone
275 hdmap::PathOverlap clear_area_overlap;
276 if (GetFirstOverlap(map_path.clear_area_overlaps(), &clear_area_overlap)) {
277 first_encounter_overlaps_.emplace_back(CLEAR_AREA, clear_area_overlap);
278 }
279
280 // crosswalk
281 hdmap::PathOverlap crosswalk_overlap;
282 if (GetFirstOverlap(map_path.crosswalk_overlaps(), &crosswalk_overlap)) {
283 first_encounter_overlaps_.emplace_back(CROSSWALK, crosswalk_overlap);
284 }
285
286 // pnc_junction
287 hdmap::PathOverlap pnc_junction_overlap;
288 if (GetFirstOverlap(map_path.pnc_junction_overlaps(),
289 &pnc_junction_overlap)) {
290 first_encounter_overlaps_.emplace_back(PNC_JUNCTION, pnc_junction_overlap);
291 }
292
293 // signal
294 hdmap::PathOverlap signal_overlap;
295 if (GetFirstOverlap(map_path.signal_overlaps(), &signal_overlap)) {
296 first_encounter_overlaps_.emplace_back(SIGNAL, signal_overlap);
297 }
298
299 // stop_sign
300 hdmap::PathOverlap stop_sign_overlap;
301 if (GetFirstOverlap(map_path.stop_sign_overlaps(), &stop_sign_overlap)) {
302 first_encounter_overlaps_.emplace_back(STOP_SIGN, stop_sign_overlap);
303 }
304
305 // yield_sign
306 hdmap::PathOverlap yield_sign_overlap;
307 if (GetFirstOverlap(map_path.yield_sign_overlaps(), &yield_sign_overlap)) {
308 first_encounter_overlaps_.emplace_back(YIELD_SIGN, yield_sign_overlap);
309 }
310
311 // area
312 hdmap::PathOverlap area_overlap;
313 if (GetFirstOverlap(map_path.area_overlaps(), &area_overlap)) {
314 first_encounter_overlaps_.emplace_back(AREA, area_overlap);
315 }
316
317 // sort by start_s
318 if (!first_encounter_overlaps_.empty()) {
319 std::sort(first_encounter_overlaps_.begin(),
320 first_encounter_overlaps_.end(),
321 [](const std::pair<OverlapType, hdmap::PathOverlap>& a,
322 const std::pair<OverlapType, hdmap::PathOverlap>& b) {
323 return a.second.start_s < b.second.start_s;
324 });
325 }
326}
327
328bool WithinOverlap(const hdmap::PathOverlap& overlap, double s) {
329 static constexpr double kEpsilon = 1e-2;
330 return overlap.start_s - kEpsilon <= s && s <= overlap.end_s + kEpsilon;
331}
332
333void ReferenceLineInfo::SetJunctionRightOfWay(const double junction_s,
334 const bool is_protected) const {
335 for (const auto& overlap : reference_line_.map_path().junction_overlaps()) {
336 if (WithinOverlap(overlap, junction_s)) {
337 junction_right_of_way_map_[overlap.object_id] = is_protected;
338 }
339 }
340}
341
343 for (const auto& overlap : reference_line_.map_path().junction_overlaps()) {
344 if (overlap.end_s < adc_sl_boundary_.start_s()) {
345 junction_right_of_way_map_.erase(overlap.object_id);
346 } else if (WithinOverlap(overlap, adc_sl_boundary_.end_s())) {
347 auto is_protected = junction_right_of_way_map_[overlap.object_id];
348 if (is_protected) {
350 }
351 }
352 }
354}
355
356const hdmap::RouteSegments& ReferenceLineInfo::Lanes() const { return lanes_; }
357
358std::list<hdmap::Id> ReferenceLineInfo::TargetLaneId() const {
359 std::list<hdmap::Id> lane_ids;
360 for (const auto& lane_seg : lanes_) {
361 lane_ids.push_back(lane_seg.lane->id());
362 }
363 return lane_ids;
364}
365
367 return adc_sl_boundary_;
368}
369
370PathDecision* ReferenceLineInfo::path_decision() { return &path_decision_; }
371
373 return path_decision_;
374}
375
377 return reference_line_;
378}
379
381 return &reference_line_;
382}
383
385 discretized_trajectory_ = trajectory;
386}
387
388bool ReferenceLineInfo::AddObstacleHelper(
389 const std::shared_ptr<Obstacle>& obstacle) {
390 return AddObstacle(obstacle.get()) != nullptr;
391}
392
393// AddObstacle is thread safe
395 if (!obstacle) {
396 AERROR << "The provided obstacle is empty";
397 return nullptr;
398 }
399 auto* mutable_obstacle = path_decision_.AddObstacle(*obstacle);
400 if (!mutable_obstacle) {
401 AERROR << "failed to add obstacle " << obstacle->Id();
402 return nullptr;
403 }
404
405 SLBoundary perception_sl;
406 if (!reference_line_.GetSLBoundary(obstacle->PerceptionPolygon(),
407 &perception_sl)) {
408 AERROR << "Failed to get sl boundary for obstacle: " << obstacle->Id();
409 return mutable_obstacle;
410 }
411 mutable_obstacle->SetPerceptionSlBoundary(perception_sl);
412 mutable_obstacle->CheckLaneBlocking(reference_line_);
413 if (mutable_obstacle->IsLaneBlocking()) {
414 ADEBUG << "obstacle [" << obstacle->Id() << "] is lane blocking.";
415 } else {
416 ADEBUG << "obstacle [" << obstacle->Id() << "] is NOT lane blocking.";
417 }
418
419 if (IsIrrelevantObstacle(*mutable_obstacle)) {
420 ObjectDecisionType ignore;
421 ignore.mutable_ignore();
422 path_decision_.AddLateralDecision("reference_line_filter", obstacle->Id(),
423 ignore);
424 path_decision_.AddLongitudinalDecision("reference_line_filter",
425 obstacle->Id(), ignore);
426 AINFO << "NO build reference line st boundary. id:" << obstacle->Id();
427 } else {
428 AINFO << "build reference line st boundary. id:" << obstacle->Id();
429 mutable_obstacle->BuildReferenceLineStBoundary(reference_line_,
430 adc_sl_boundary_.start_s());
431
432 ADEBUG << "reference line st boundary: t["
433 << mutable_obstacle->reference_line_st_boundary().min_t() << ", "
434 << mutable_obstacle->reference_line_st_boundary().max_t() << "] s["
435 << mutable_obstacle->reference_line_st_boundary().min_s() << ", "
436 << mutable_obstacle->reference_line_st_boundary().max_s() << "]";
437 }
438 return mutable_obstacle;
439}
440
442 const std::vector<const Obstacle*>& obstacles) {
443 if (FLAGS_use_multi_thread_to_add_obstacles) {
444 std::vector<std::future<Obstacle*>> results;
445 for (const auto* obstacle : obstacles) {
446 results.push_back(
447 cyber::Async(&ReferenceLineInfo::AddObstacle, this, obstacle));
448 }
449 for (auto& result : results) {
450 if (!result.get()) {
451 AERROR << "Fail to add obstacles.";
452 return false;
453 }
454 }
455 } else {
456 for (const auto* obstacle : obstacles) {
457 if (!AddObstacle(obstacle)) {
458 AERROR << "Failed to add obstacle " << obstacle->Id();
459 return false;
460 }
461 }
462 }
463
464 return true;
465}
466
467bool ReferenceLineInfo::IsIrrelevantObstacle(const Obstacle& obstacle) {
468 if (obstacle.IsCautionLevelObstacle()) {
469 return false;
470 }
471 // if adc is on the road, and obstacle behind adc, ignore
472 const auto& obstacle_boundary = obstacle.PerceptionSLBoundary();
473 if (obstacle_boundary.start_s() > reference_line_.Length()) {
474 return true;
475 }
476 if (is_on_reference_line_ && !IsChangeLanePath() &&
477 adc_sl_boundary_.start_s() - obstacle_boundary.end_s() >
478 FLAGS_obstacle_lon_ignore_buffer &&
479 (reference_line_.IsOnLane(obstacle_boundary) ||
480 obstacle_boundary.end_s() < 0.0)) { // if obstacle is far backward
481 return true;
482 }
483 return false;
484}
485
487 return discretized_trajectory_;
488}
489
491 planning_target_.mutable_stop_point()->CopyFrom(stop_point);
492}
493
495 planning_target_.set_cruise_speed(speed);
496}
497
499 const ReferenceLineInfo& previous_reference_line_info) const {
500 if (reference_line_.reference_points().empty()) {
501 return false;
502 }
503 auto start_point = reference_line_.reference_points().front();
504 const auto& prev_reference_line =
505 previous_reference_line_info.reference_line();
506 common::SLPoint sl_point;
507 prev_reference_line.XYToSL(start_point, &sl_point);
508 return previous_reference_line_info.reference_line_.IsOnLane(sl_point);
509}
510
511const PathData& ReferenceLineInfo::path_data() const { return path_data_; }
512
514 return fallback_path_data_;
515}
516
517const SpeedData& ReferenceLineInfo::speed_data() const { return speed_data_; }
518
520
522 return &fallback_path_data_;
523}
524
526
527const RSSInfo& ReferenceLineInfo::rss_info() const { return rss_info_; }
528
530
532 const double relative_time, const double start_s,
533 DiscretizedTrajectory* ptr_discretized_trajectory) {
534 ACHECK(ptr_discretized_trajectory != nullptr);
535 // use varied resolution to reduce data load but also provide enough data
536 // point for control module
537 const double kDenseTimeResoltuion = FLAGS_trajectory_time_min_interval;
538 const double kSparseTimeResolution = FLAGS_trajectory_time_max_interval;
539 const double kDenseTimeSec = FLAGS_trajectory_time_high_density_period;
540
541 if (path_data_.discretized_path().empty()) {
542 AERROR << "path data is empty";
543 return false;
544 }
545
546 if (speed_data_.empty()) {
547 AERROR << "speed profile is empty";
548 return false;
549 }
550
551 for (double cur_rel_time = 0.0; cur_rel_time < speed_data_.TotalTime();
552 cur_rel_time += (cur_rel_time < kDenseTimeSec ? kDenseTimeResoltuion
553 : kSparseTimeResolution)) {
554 common::SpeedPoint speed_point;
555 if (!speed_data_.EvaluateByTime(cur_rel_time, &speed_point)) {
556 AERROR << "Fail to get speed point with relative time " << cur_rel_time;
557 return false;
558 }
559
560 if (speed_point.s() > path_data_.discretized_path().Length()) {
561 break;
562 }
563 common::PathPoint path_point =
564 path_data_.GetPathPointWithPathS(speed_point.s());
565 path_point.set_s(path_point.s() + start_s);
566
567 common::TrajectoryPoint trajectory_point;
568 trajectory_point.mutable_path_point()->CopyFrom(path_point);
569 trajectory_point.set_v(speed_point.v());
570 trajectory_point.set_a(speed_point.a());
571 trajectory_point.set_relative_time(speed_point.t() + relative_time);
572 ptr_discretized_trajectory->AppendTrajectoryPoint(trajectory_point);
573 }
574 if (path_data_.is_reverse_path()) {
575 std::for_each(ptr_discretized_trajectory->begin(),
576 ptr_discretized_trajectory->end(),
577 [](common::TrajectoryPoint& trajectory_point) {
578 trajectory_point.set_v(-trajectory_point.v());
579 trajectory_point.set_a(-trajectory_point.a());
580 trajectory_point.mutable_path_point()->set_s(
581 -trajectory_point.path_point().s());
582 });
583 AINFO << "reversed path";
584 ptr_discretized_trajectory->SetIsReversed(true);
585 }
586 return true;
587}
588
589// TODO(all): It is a brutal way to insert the planning init point, one elegant
590// way would be bypassing trajectory stitching logics somehow, or use planing
591// init point from trajectory stitching to compute the trajectory at the very
592// start
594 const common::TrajectoryPoint& planning_start_point,
595 const std::vector<common::TrajectoryPoint>& trajectory,
596 DiscretizedTrajectory* adjusted_trajectory) {
597 ACHECK(adjusted_trajectory != nullptr);
598 // find insert index by check heading
599 static constexpr double kMaxAngleDiff = M_PI_2;
600 const double start_point_heading = planning_start_point.path_point().theta();
601 const double start_point_x = planning_start_point.path_point().x();
602 const double start_point_y = planning_start_point.path_point().y();
603 const double start_point_relative_time = planning_start_point.relative_time();
604
605 int insert_idx = -1;
606 for (size_t i = 0; i < trajectory.size(); ++i) {
607 // skip trajectory_points early than planning_start_point
608 if (trajectory[i].relative_time() <= start_point_relative_time) {
609 continue;
610 }
611
612 const double cur_point_x = trajectory[i].path_point().x();
613 const double cur_point_y = trajectory[i].path_point().y();
614 const double tracking_heading =
615 std::atan2(cur_point_y - start_point_y, cur_point_x - start_point_x);
616 if (std::fabs(common::math::AngleDiff(start_point_heading,
617 tracking_heading)) < kMaxAngleDiff) {
618 insert_idx = i;
619 break;
620 }
621 }
622 if (insert_idx == -1) {
623 AERROR << "All points are behind of planning init point";
624 return false;
625 }
626
627 DiscretizedTrajectory cut_trajectory(trajectory);
628 cut_trajectory.erase(cut_trajectory.begin(),
629 cut_trajectory.begin() + insert_idx);
630 cut_trajectory.insert(cut_trajectory.begin(), planning_start_point);
631
632 // In class TrajectoryStitcher, the stitched point which is also the planning
633 // init point is supposed have one planning_cycle_time ahead respect to
634 // current timestamp as its relative time. So the relative timelines
635 // of planning init point and the trajectory which start from current
636 // position(relative time = 0) are the same. Therefore any conflicts on the
637 // relative time including the one below should return false and inspected its
638 // cause.
639 if (cut_trajectory.size() > 1 && cut_trajectory.front().relative_time() >=
640 cut_trajectory[1].relative_time()) {
641 AERROR << "planning init point relative_time["
642 << cut_trajectory.front().relative_time()
643 << "] larger than its next point's relative_time["
644 << cut_trajectory[1].relative_time() << "]";
645 return false;
646 }
647
648 // In class TrajectoryStitcher, the planing_init_point is set to have s as 0,
649 // so adjustment is needed to be done on the other points
650 double accumulated_s = 0.0;
651 for (size_t i = 1; i < cut_trajectory.size(); ++i) {
652 const auto& pre_path_point = cut_trajectory[i - 1].path_point();
653 auto* cur_path_point = cut_trajectory[i].mutable_path_point();
654 accumulated_s += std::sqrt((cur_path_point->x() - pre_path_point.x()) *
655 (cur_path_point->x() - pre_path_point.x()) +
656 (cur_path_point->y() - pre_path_point.y()) *
657 (cur_path_point->y() - pre_path_point.y()));
658 cur_path_point->set_s(accumulated_s);
659 }
660
661 // reevaluate relative_time to make delta t the same
662 adjusted_trajectory->clear();
663 // use varied resolution to reduce data load but also provide enough data
664 // point for control module
665 const double kDenseTimeResoltuion = FLAGS_trajectory_time_min_interval;
666 const double kSparseTimeResolution = FLAGS_trajectory_time_max_interval;
667 const double kDenseTimeSec = FLAGS_trajectory_time_high_density_period;
668 for (double cur_rel_time = cut_trajectory.front().relative_time();
669 cur_rel_time <= cut_trajectory.back().relative_time();
670 cur_rel_time += (cur_rel_time < kDenseTimeSec ? kDenseTimeResoltuion
671 : kSparseTimeResolution)) {
672 adjusted_trajectory->AppendTrajectoryPoint(
673 cut_trajectory.Evaluate(cur_rel_time));
674 }
675 return true;
676}
677
678void ReferenceLineInfo::SetDrivable(bool drivable) { is_drivable_ = drivable; }
679
680bool ReferenceLineInfo::IsDrivable() const { return is_drivable_; }
681
683 return !Lanes().IsOnSegment();
684}
685
689
691 return absl::StrCat("path_data:", path_data_.DebugString(),
692 "speed_data:", speed_data_.DebugString());
693}
694
695bool ReferenceLineInfo::IsEgoOnRoutingLane() const {
696 double ego_x = vehicle_state_.x();
697 double ego_y = vehicle_state_.y();
698 double lane_left_width = 0;
699 double lane_right_width = 0;
700 common::SLPoint sl_point;
701 reference_line_.XYToSL({ego_x, ego_y}, &sl_point);
702 reference_line_.GetLaneWidth(sl_point.s(), &lane_left_width,
703 &lane_right_width);
704 ADEBUG << "s: " << sl_point.s() << " l: " << sl_point.l()
705 << " lane_left_width: " << lane_left_width
706 << " lane_right_width: " << lane_right_width;
707 if (lane_left_width >= sl_point.l() && -lane_right_width <= sl_point.l()) {
708 return true;
709 } else {
710 return false;
711 }
712}
713
714void ReferenceLineInfo::SetTurnSignalBasedOnLaneTurnType(
715 common::VehicleSignal* vehicle_signal) const {
716 CHECK_NOTNULL(vehicle_signal);
717 if (vehicle_signal->has_turn_signal() &&
718 vehicle_signal->turn_signal() != VehicleSignal::TURN_NONE) {
719 return;
720 }
721 vehicle_signal->set_turn_signal(VehicleSignal::TURN_NONE);
722
723 // Set turn signal based on lane-change.
724 if (IsChangeLanePath()) {
725 if (Lanes().PreviousAction() == routing::ChangeLaneType::LEFT) {
726 vehicle_signal->set_turn_signal(VehicleSignal::TURN_LEFT);
727 } else if (Lanes().PreviousAction() == routing::ChangeLaneType::RIGHT) {
728 vehicle_signal->set_turn_signal(VehicleSignal::TURN_RIGHT);
729 }
730 return;
731 }
732
733 // Set turn signal based on lane-borrow.
734 bool is_ego_on_routing_lane = IsEgoOnRoutingLane();
735 if (path_data_.path_label().find("left") != std::string::npos &&
736 is_ego_on_routing_lane) {
737 vehicle_signal->set_turn_signal(VehicleSignal::TURN_LEFT);
738 AINFO << "Set turn signal to left";
739 return;
740 }
741 if (path_data_.path_label().find("left") != std::string::npos &&
742 !is_ego_on_routing_lane) {
743 vehicle_signal->set_turn_signal(VehicleSignal::TURN_RIGHT);
744 AINFO << "Set turn signal to right";
745 return;
746 }
747 if (path_data_.path_label().find("right") != std::string::npos &&
748 is_ego_on_routing_lane) {
749 vehicle_signal->set_turn_signal(VehicleSignal::TURN_RIGHT);
750 AINFO << "Set turn signal to right";
751 return;
752 }
753 if (path_data_.path_label().find("right") != std::string::npos &&
754 !is_ego_on_routing_lane) {
755 vehicle_signal->set_turn_signal(VehicleSignal::TURN_LEFT);
756 AINFO << "Set turn signal to left";
757 return;
758 }
759
760 // Set turn signal based on lane's turn type.
761 double route_s = 0.0;
762 const double adc_s = adc_sl_boundary_.end_s();
763 for (const auto& seg : Lanes()) {
764 if (route_s > adc_s + FLAGS_turn_signal_distance) {
765 break;
766 }
767 route_s += seg.end_s - seg.start_s;
768 if (route_s < adc_s) {
769 continue;
770 }
771 const auto& turn = seg.lane->lane().turn();
772 if (turn == hdmap::Lane::LEFT_TURN) {
773 vehicle_signal->set_turn_signal(VehicleSignal::TURN_LEFT);
774 AINFO << "Set turn signal to left";
775 break;
776 } else if (turn == hdmap::Lane::RIGHT_TURN) {
777 vehicle_signal->set_turn_signal(VehicleSignal::TURN_RIGHT);
778 AINFO << "Set turn signal to right";
779 break;
780 } else if (turn == hdmap::Lane::U_TURN) {
781 // check left or right by geometry.
782 auto start_xy =
783 PointFactory::ToVec2d(seg.lane->GetSmoothPoint(seg.start_s));
784 auto middle_xy = PointFactory::ToVec2d(
785 seg.lane->GetSmoothPoint((seg.start_s + seg.end_s) / 2.0));
786 auto end_xy = PointFactory::ToVec2d(seg.lane->GetSmoothPoint(seg.end_s));
787 auto start_to_middle = middle_xy - start_xy;
788 auto start_to_end = end_xy - start_xy;
789 if (start_to_middle.CrossProd(start_to_end) < 0) {
790 vehicle_signal->set_turn_signal(VehicleSignal::TURN_RIGHT);
791 } else {
792 vehicle_signal->set_turn_signal(VehicleSignal::TURN_LEFT);
793 }
794 break;
795 }
796 }
797}
798
800 const VehicleSignal::TurnSignal& turn_signal) {
801 vehicle_signal_.set_turn_signal(turn_signal);
802}
803
805 vehicle_signal_.set_emergency_light(true);
806}
807
808void ReferenceLineInfo::ExportVehicleSignal(
809 common::VehicleSignal* vehicle_signal) const {
810 CHECK_NOTNULL(vehicle_signal);
811 *vehicle_signal = vehicle_signal_;
812 SetTurnSignalBasedOnLaneTurnType(vehicle_signal);
813}
814
816 const double distance_destination = SDistanceToDestination();
817 const double distance_ref_end = SDistanceToRefEnd();
818 AINFO << "distance_destination:" << distance_destination
819 << "distance_ref_end: " << distance_ref_end;
820 return distance_destination <= FLAGS_passed_destination_threshold ||
821 distance_ref_end <= FLAGS_passed_referenceline_end_threshold;
822}
823
825 double res = std::numeric_limits<double>::max();
826 const auto* dest_ptr = path_decision_.Find(FLAGS_destination_obstacle_id);
827 if (!dest_ptr) {
828 return res;
829 }
830 if (!dest_ptr->LongitudinalDecision().has_stop()) {
831 return res;
832 }
833 if (!reference_line_.IsOnLane(dest_ptr->PerceptionBoundingBox().center())) {
834 return res;
835 }
836 const double stop_s = dest_ptr->PerceptionSLBoundary().start_s() +
837 dest_ptr->LongitudinalDecision().stop().distance_s();
838 AINFO << "stop_s: " << stop_s << "end_s: " << adc_sl_boundary_.end_s();
839 return stop_s - adc_sl_boundary_.end_s();
840}
841
843 double res = std::numeric_limits<double>::max();
844
845 std::string ref_end_id;
846 for (const auto* obstacle : path_decision_.obstacles().Items()) {
847 std::string id = obstacle->Id();
848 if (id.find("REF_END") != std::string::npos) {
849 ref_end_id = id;
850 AINFO << "Found reference line end id: " << ref_end_id;
851 } else {
852 continue;
853 }
854 }
855 if (!ref_end_id.empty()) {
856 AINFO << "REF_END: " << ref_end_id;
857 const auto* ref_end_ptr = path_decision_.Find(ref_end_id);
858 AINFO << "ref_end_ptr:" << ref_end_ptr->DebugString();
859 if (!ref_end_ptr && !ref_end_ptr->LongitudinalDecision().has_stop() &&
860 !reference_line_.IsOnLane(
861 ref_end_ptr->PerceptionBoundingBox().center())) {
862 const double stop_s =
863 ref_end_ptr->PerceptionSLBoundary().start_s() +
864 ref_end_ptr->LongitudinalDecision().stop().distance_s();
865 AINFO << "REF_END: stop_s: " << stop_s
866 << "end_s: " << adc_sl_boundary_.end_s();
867 res = stop_s - adc_sl_boundary_.end_s();
868 }
869 }
870 return res;
871}
872
874 DecisionResult* decision_result, PlanningContext* planning_context) const {
875 MakeDecision(decision_result, planning_context);
876 ExportVehicleSignal(decision_result->mutable_vehicle_signal());
877 auto* main_decision = decision_result->mutable_main_decision();
878 if (main_decision->has_stop()) {
879 main_decision->mutable_stop()->set_change_lane_type(
880 Lanes().PreviousAction());
881 } else if (main_decision->has_cruise()) {
882 main_decision->mutable_cruise()->set_change_lane_type(
883 Lanes().PreviousAction());
884 }
885}
886
887void ReferenceLineInfo::MakeDecision(DecisionResult* decision_result,
888 PlanningContext* planning_context) const {
889 CHECK_NOTNULL(decision_result);
890 decision_result->Clear();
891
892 // cruise by default
893 decision_result->mutable_main_decision()->mutable_cruise();
894
895 // check stop decision
896 int error_code = MakeMainStopDecision(decision_result);
897 if (error_code < 0) {
898 MakeEStopDecision(decision_result);
899 }
900 MakeMainMissionCompleteDecision(decision_result, planning_context);
901 SetObjectDecisions(decision_result->mutable_object_decision());
902}
903
904void ReferenceLineInfo::MakeMainMissionCompleteDecision(
905 DecisionResult* decision_result, PlanningContext* planning_context) const {
906 if (!decision_result->main_decision().has_stop()) {
907 return;
908 }
909 auto main_stop = decision_result->main_decision().stop();
910 if (main_stop.reason_code() != STOP_REASON_DESTINATION &&
911 main_stop.reason_code() != STOP_REASON_PULL_OVER &&
912 main_stop.reason_code() != STOP_REASON_REFERENCE_END) {
913 return;
914 }
915 const double distance_destination = SDistanceToDestination();
916 const double distance_to_reference_end = SDistanceToRefEnd();
917 if (distance_destination > FLAGS_destination_check_distance &&
918 distance_to_reference_end > FLAGS_destination_check_distance) {
919 return;
920 }
921
922 auto mission_complete =
923 decision_result->mutable_main_decision()->mutable_mission_complete();
924 if (ReachedDestination()) {
925 planning_context->mutable_planning_status()
926 ->mutable_destination()
927 ->set_has_passed_destination(true);
928 } else {
929 mission_complete->mutable_stop_point()->CopyFrom(main_stop.stop_point());
930 mission_complete->set_stop_heading(main_stop.stop_heading());
931 }
932}
933
934int ReferenceLineInfo::MakeMainStopDecision(
935 DecisionResult* decision_result) const {
936 double min_stop_line_s = std::numeric_limits<double>::infinity();
937 const Obstacle* stop_obstacle = nullptr;
938 const ObjectStop* stop_decision = nullptr;
939
940 for (const auto* obstacle : path_decision_.obstacles().Items()) {
941 const auto& object_decision = obstacle->LongitudinalDecision();
942 if (!object_decision.has_stop()) {
943 continue;
944 }
945
946 apollo::common::PointENU stop_point = object_decision.stop().stop_point();
947 common::SLPoint stop_line_sl;
948 reference_line_.XYToSL(stop_point, &stop_line_sl);
949
950 double stop_line_s = stop_line_sl.s();
951 if (stop_line_s < 0 || stop_line_s > reference_line_.Length()) {
952 AERROR << "Ignore object:" << obstacle->Id() << " fence route_s["
953 << stop_line_s << "] not in range[0, " << reference_line_.Length()
954 << "]";
955 continue;
956 }
957
958 // check stop_line_s vs adc_s
959 if (stop_line_s < min_stop_line_s) {
960 min_stop_line_s = stop_line_s;
961 stop_obstacle = obstacle;
962 stop_decision = &(object_decision.stop());
963 }
964 }
965
966 if (stop_obstacle != nullptr) {
967 MainStop* main_stop =
968 decision_result->mutable_main_decision()->mutable_stop();
969 main_stop->set_reason_code(stop_decision->reason_code());
970 main_stop->set_reason("stop by " + stop_obstacle->Id());
971 main_stop->mutable_stop_point()->set_x(stop_decision->stop_point().x());
972 main_stop->mutable_stop_point()->set_y(stop_decision->stop_point().y());
973 main_stop->set_stop_heading(stop_decision->stop_heading());
974
975 ADEBUG << " main stop obstacle id:" << stop_obstacle->Id()
976 << " stop_line_s:" << min_stop_line_s << " stop_point: ("
977 << stop_decision->stop_point().x() << stop_decision->stop_point().y()
978 << " ) stop_heading: " << stop_decision->stop_heading();
979
980 return 1;
981 }
982
983 return 0;
984}
985
986void ReferenceLineInfo::SetObjectDecisions(
987 ObjectDecisions* object_decisions) const {
988 for (const auto obstacle : path_decision_.obstacles().Items()) {
989 if (!obstacle->HasNonIgnoreDecision()) {
990 continue;
991 }
992 auto* object_decision = object_decisions->add_decision();
993
994 object_decision->set_id(obstacle->Id());
995 object_decision->set_perception_id(obstacle->PerceptionId());
996 if (obstacle->HasLateralDecision() && !obstacle->IsLateralIgnore()) {
997 object_decision->add_object_decision()->CopyFrom(
998 obstacle->LateralDecision());
999 }
1000 if (obstacle->HasLongitudinalDecision() &&
1001 !obstacle->IsLongitudinalIgnore()) {
1002 object_decision->add_object_decision()->CopyFrom(
1003 obstacle->LongitudinalDecision());
1004 }
1005 }
1006}
1007
1009 EngageAdvice* engage_advice, PlanningContext* planning_context) const {
1010 static EngageAdvice prev_advice;
1011 static constexpr double kMaxAngleDiff = M_PI / 6.0;
1012
1013 bool engage = false;
1014 if (!IsDrivable()) {
1015 prev_advice.set_reason("Reference line not drivable");
1016 } else if (!is_on_reference_line_) {
1017 const auto& scenario_type =
1018 planning_context->planning_status().scenario().scenario_type();
1019 if (scenario_type == "PARK_AND_GO" || IsChangeLanePath()) {
1020 // note: when is_on_reference_line_ is FALSE
1021 // (1) always engage while in PARK_AND_GO scenario
1022 // (2) engage when "ChangeLanePath" is picked as Drivable ref line
1023 // where most likely ADC not OnLane yet
1024 engage = true;
1025 } else {
1026 prev_advice.set_reason("Not on reference line");
1027 }
1028 } else {
1029 // check heading
1030 auto ref_point =
1031 reference_line_.GetReferencePoint(adc_sl_boundary_.end_s());
1032 if (common::math::AngleDiff(vehicle_state_.heading(), ref_point.heading()) <
1033 kMaxAngleDiff) {
1034 engage = true;
1035 } else {
1036 prev_advice.set_reason("Vehicle heading is not aligned");
1037 }
1038 }
1039
1040 if (engage) {
1041 if (vehicle_state_.driving_mode() !=
1042 Chassis::DrivingMode::Chassis_DrivingMode_COMPLETE_AUTO_DRIVE) {
1043 // READY_TO_ENGAGE when in non-AUTO mode
1044 prev_advice.set_advice(EngageAdvice::READY_TO_ENGAGE);
1045 } else {
1046 // KEEP_ENGAGED when in AUTO mode
1047 prev_advice.set_advice(EngageAdvice::KEEP_ENGAGED);
1048 }
1049 prev_advice.clear_reason();
1050 } else {
1051 if (prev_advice.advice() != EngageAdvice::DISALLOW_ENGAGE) {
1052 prev_advice.set_advice(EngageAdvice::PREPARE_DISENGAGE);
1053 }
1054 }
1055 engage_advice->CopyFrom(prev_advice);
1056}
1057
1058void ReferenceLineInfo::MakeEStopDecision(
1059 DecisionResult* decision_result) const {
1060 decision_result->Clear();
1061
1062 MainEmergencyStop* main_estop =
1063 decision_result->mutable_main_decision()->mutable_estop();
1064 main_estop->set_reason_code(MainEmergencyStop::ESTOP_REASON_INTERNAL_ERR);
1065 main_estop->set_reason("estop reason to be added");
1066 main_estop->mutable_cruise_to_stop();
1067
1068 // set object decisions
1069 ObjectDecisions* object_decisions =
1070 decision_result->mutable_object_decision();
1071 for (const auto obstacle : path_decision_.obstacles().Items()) {
1072 auto* object_decision = object_decisions->add_decision();
1073 object_decision->set_id(obstacle->Id());
1074 object_decision->set_perception_id(obstacle->PerceptionId());
1075 object_decision->add_object_decision()->mutable_avoid();
1076 }
1077}
1078
1080 const double forward_buffer = 20.0;
1081 double route_s = 0.0;
1082 for (const auto& seg : Lanes()) {
1083 if (route_s > s + forward_buffer) {
1084 break;
1085 }
1086 route_s += seg.end_s - seg.start_s;
1087 if (route_s < s) {
1088 continue;
1089 }
1090 const auto& turn_type = seg.lane->lane().turn();
1091 if (turn_type == hdmap::Lane::LEFT_TURN ||
1092 turn_type == hdmap::Lane::RIGHT_TURN ||
1093 turn_type == hdmap::Lane::U_TURN) {
1094 return turn_type;
1095 }
1096 }
1097
1098 return hdmap::Lane::NO_TURN;
1099}
1100
1102 const hdmap::PathOverlap& pnc_junction_overlap) const {
1103 if (GetPathTurnType(pnc_junction_overlap.start_s) != hdmap::Lane::NO_TURN) {
1104 return false;
1105 }
1106
1107 // TODO(all): iterate exits of intersection to check/compare speed-limit
1108 return true;
1109}
1110
1112 const double s, hdmap::PathOverlap* pnc_junction_overlap) const {
1113 CHECK_NOTNULL(pnc_junction_overlap);
1114 const std::vector<hdmap::PathOverlap>& pnc_junction_overlaps =
1115 reference_line_.map_path().pnc_junction_overlaps();
1116
1117 static constexpr double kError = 1.0; // meter
1118 for (const auto& overlap : pnc_junction_overlaps) {
1119 if (s >= overlap.start_s - kError && s <= overlap.end_s + kError) {
1120 *pnc_junction_overlap = overlap;
1121 return 1;
1122 }
1123 }
1124 return 0;
1125}
1126
1128 hdmap::PathOverlap* junction_overlap) const {
1129 CHECK_NOTNULL(junction_overlap);
1130 const std::vector<hdmap::PathOverlap>& junction_overlaps =
1131 reference_line_.map_path().junction_overlaps();
1132
1133 static constexpr double kError = 1.0; // meter
1134 for (const auto& overlap : junction_overlaps) {
1135 if (s >= overlap.start_s - kError && s <= overlap.end_s + kError) {
1136 *junction_overlap = overlap;
1137 return 1;
1138 }
1139 }
1140 return 0;
1141}
1142
1144 hdmap::PathOverlap* area_overlap) const {
1145 CHECK_NOTNULL(area_overlap);
1146 const std::vector<hdmap::PathOverlap>& area_overlaps =
1147 reference_line_.map_path().area_overlaps();
1148
1149 static constexpr double kError = 1.0; // meter
1150 for (const auto& overlap : area_overlaps) {
1151 if (s >= overlap.start_s - kError && s <= overlap.end_s + kError) {
1152 *area_overlap = overlap;
1153 return 1;
1154 }
1155 }
1156 return 0;
1157}
1158
1160 const std::string& blocking_obstacle_id) {
1161 blocking_obstacle_ = path_decision_.Find(blocking_obstacle_id);
1162}
1163
1165 const {
1166 std::vector<common::SLPoint> result;
1167 for (const auto* obstacle : path_decision_.obstacles().Items()) {
1168 const auto& object_decision = obstacle->LongitudinalDecision();
1169 if (!object_decision.has_stop()) {
1170 continue;
1171 }
1172 apollo::common::PointENU stop_point = object_decision.stop().stop_point();
1173 common::SLPoint stop_line_sl;
1174 reference_line_.XYToSL(stop_point, &stop_line_sl);
1175 if (stop_line_sl.s() <= 0 || stop_line_sl.s() >= reference_line_.Length()) {
1176 continue;
1177 }
1178 result.push_back(stop_line_sl);
1179 }
1180
1181 // sort by s
1182 if (!result.empty()) {
1183 std::sort(result.begin(), result.end(),
1184 [](const common::SLPoint& a, const common::SLPoint& b) {
1185 return a.s() < b.s();
1186 });
1187 }
1188
1189 return result;
1190}
1191
1193 const std::string& overlap_id, const OverlapType& overlap_type) const {
1194 if (overlap_type == ReferenceLineInfo::SIGNAL) {
1195 // traffic_light_overlap
1196 const auto& traffic_light_overlaps =
1197 reference_line_.map_path().signal_overlaps();
1198 for (const auto& traffic_light_overlap : traffic_light_overlaps) {
1199 if (traffic_light_overlap.object_id == overlap_id) {
1200 return const_cast<hdmap::PathOverlap*>(&traffic_light_overlap);
1201 }
1202 }
1203 } else if (overlap_type == ReferenceLineInfo::STOP_SIGN) {
1204 // stop_sign_overlap
1205 const auto& stop_sign_overlaps =
1206 reference_line_.map_path().stop_sign_overlaps();
1207 for (const auto& stop_sign_overlap : stop_sign_overlaps) {
1208 if (stop_sign_overlap.object_id == overlap_id) {
1209 return const_cast<hdmap::PathOverlap*>(&stop_sign_overlap);
1210 }
1211 }
1212 } else if (overlap_type == ReferenceLineInfo::PNC_JUNCTION) {
1213 // pnc_junction_overlap
1214 const auto& pnc_junction_overlaps =
1215 reference_line_.map_path().pnc_junction_overlaps();
1216 for (const auto& pnc_junction_overlap : pnc_junction_overlaps) {
1217 if (pnc_junction_overlap.object_id == overlap_id) {
1218 return const_cast<hdmap::PathOverlap*>(&pnc_junction_overlap);
1219 }
1220 }
1221 } else if (overlap_type == ReferenceLineInfo::YIELD_SIGN) {
1222 // yield_sign_overlap
1223 const auto& yield_sign_overlaps =
1224 reference_line_.map_path().yield_sign_overlaps();
1225 for (const auto& yield_sign_overlap : yield_sign_overlaps) {
1226 if (yield_sign_overlap.object_id == overlap_id) {
1227 return const_cast<hdmap::PathOverlap*>(&yield_sign_overlap);
1228 }
1229 }
1230 } else if (overlap_type == ReferenceLineInfo::JUNCTION) {
1231 // junction_overlap
1232 const auto& junction_overlaps =
1233 reference_line_.map_path().junction_overlaps();
1234 for (const auto& junction_overlap : junction_overlaps) {
1235 if (junction_overlap.object_id == overlap_id) {
1236 return const_cast<hdmap::PathOverlap*>(&junction_overlap);
1237 }
1238 }
1239 } else if (overlap_type == ReferenceLineInfo::AREA) {
1240 // area_overlap
1241 const auto& area_overlaps = reference_line_.map_path().area_overlaps();
1242 for (const auto& area_overlap : area_overlaps) {
1243 if (area_overlap.object_id == overlap_id) {
1244 return const_cast<hdmap::PathOverlap*>(&area_overlap);
1245 }
1246 }
1247 }
1248
1249 return nullptr;
1250}
1252 return &candidate_path_data_;
1253}
1254
1256 std::vector<hdmap::PathOverlap>* path_overlaps, double start_s,
1257 double end_s) {
1258 CHECK_NOTNULL(path_overlaps);
1259 const std::vector<hdmap::PathOverlap>& junction_overlaps =
1260 reference_line_.map_path().junction_overlaps();
1261
1262 static constexpr double kError = 0.1; // meter
1263 AINFO << "GetRangeOverlaps start_s: " << start_s << ", end_s: " << end_s;
1264 for (const auto& overlap : junction_overlaps) {
1265 if (start_s >= overlap.end_s - kError) {
1266 continue;
1267 } else if (end_s < overlap.start_s - kError) {
1268 break;
1269 } else {
1270 AINFO << "overlap emplace_back " << overlap.start_s << ", "
1271 << overlap.end_s << " ]";
1272 path_overlaps->emplace_back(overlap);
1273 }
1274 }
1275}
1276
1277const std::vector<double>& ReferenceLineInfo::reference_line_towing_l() const {
1278 return reference_line_towing_l_;
1279}
1280
1282 return &reference_line_towing_l_;
1283}
1284
1286 const {
1287 return reference_line_towing_path_boundary_;
1288}
1289
1291 return &reference_line_towing_path_boundary_;
1292}
1293
1294const std::vector<SLPolygon>& ReferenceLineInfo::obs_sl_polygons() const {
1295 return obs_sl_polygons_;
1296}
1297
1299 return &obs_sl_polygons_;
1300}
1301
1303 PrintCurves print_curve;
1304 const auto& lane_segments = reference_line_.GetMapPath().lane_segments();
1305 for (size_t i = 0; i < lane_segments.size(); ++i) {
1306 for (const auto& seg :
1307 lane_segments.at(i).lane->lane().left_boundary().curve().segment()) {
1308 for (const auto& pt : seg.line_segment().point()) {
1309 print_curve.AddPoint(std::to_string(index_) + "_left_pt_print", pt.x(),
1310 pt.y());
1311 }
1312 }
1313 for (const auto& seg :
1314 lane_segments.at(i).lane->lane().right_boundary().curve().segment()) {
1315 for (const auto& pt : seg.line_segment().point()) {
1316 print_curve.AddPoint(std::to_string(index_) + "_right_pt_print", pt.x(),
1317 pt.y());
1318 }
1319 }
1320 for (const auto& pt : lane_segments.at(i).lane->points()) {
1321 print_curve.AddPoint(std::to_string(index_) + "_center_pt_print", pt.x(),
1322 pt.y());
1323 }
1324 }
1325 print_curve.PrintToLog();
1326}
1327
1328} // namespace planning
1329} // namespace apollo
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Rectangular (undirected) bounding box in 2-D.
Definition box2d.h:52
std::string DebugString() const
Gets a human-readable description of the box
Definition box2d.cc:418
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
Vec2d rotate(const double angle) const
rotate the vector by angle.
Definition vec2d.cc:65
static math::Vec2d ToVec2d(const XY &xy)
static const HDMap * BaseMapPtr()
LaneInfoConstPtr GetLaneById(const Id &id) const
Definition hdmap.cc:34
const std::vector< PathOverlap > & area_overlaps() const
Definition path.h:331
const std::vector< PathOverlap > & junction_overlaps() const
Definition path.h:313
const std::vector< PathOverlap > & signal_overlaps() const
Definition path.h:301
const std::vector< PathOverlap > & yield_sign_overlaps() const
Definition path.h:304
const std::vector< PathOverlap > & pnc_junction_overlaps() const
Definition path.h:316
const std::vector< PathOverlap > & stop_sign_overlaps() const
Definition path.h:307
const std::vector< LaneSegment > & lane_segments() const
Definition path.h:280
virtual void AppendTrajectoryPoint(const common::TrajectoryPoint &trajectory_point)
virtual common::TrajectoryPoint Evaluate(const double relative_time) const
const std::vector< const T * > & Items() const
List all the items in the container.
This is the class that associates an Obstacle with its path properties.
Definition obstacle.h:62
std::string DebugString() const
Definition obstacle.cc:675
bool IsLongitudinalIgnore() const
Definition obstacle.cc:589
const ObjectDecisionType & LateralDecision() const
return the merged lateral decision Lateral decision is one of {Nudge, Ignore}
Definition obstacle.cc:581
bool HasLongitudinalDecision() const
Definition obstacle.cc:636
const ObjectDecisionType & LongitudinalDecision() const
return the merged longitudinal decision Longitudinal decision is one of {Stop, Yield,...
Definition obstacle.cc:577
const std::string & Id() const
Definition obstacle.h:75
int32_t PerceptionId() const
Definition obstacle.h:80
bool IsCautionLevelObstacle() const
Definition obstacle.h:124
bool IsLateralIgnore() const
Definition obstacle.cc:593
bool HasLateralDecision() const
Definition obstacle.cc:631
bool HasNonIgnoreDecision() const
Definition obstacle.cc:641
const SLBoundary & PerceptionSLBoundary() const
Definition obstacle.cc:694
const common::math::Polygon2d & PerceptionPolygon() const
Definition obstacle.h:93
bool is_reverse_path() const
Definition path_data.h:113
const std::string & path_label() const
Definition path_data.cc:264
common::PathPoint GetPathPointWithPathS(const double s) const
Definition path_data.cc:112
std::string DebugString() const
Definition path_data.cc:161
const DiscretizedPath & discretized_path() const
Definition path_data.cc:90
PathDecision represents all obstacle decisions on one path.
const Obstacle * Find(const std::string &object_id) const
const IndexedList< std::string, Obstacle > & obstacles() const
bool AddLateralDecision(const std::string &tag, const std::string &object_id, const ObjectDecisionType &decision)
bool AddLongitudinalDecision(const std::string &tag, const std::string &object_id, const ObjectDecisionType &decision)
Obstacle * AddObstacle(const Obstacle &obstacle)
const PlanningStatus & planning_status() const
void AddPoint(std::string key, double x, double y)
add point to curve key
ReferenceLineInfo holds all data for one reference line.
void SetBlockingObstacle(const std::string &blocking_obstacle_id)
std::list< hdmap::Id > TargetLaneId() const
std::vector< double > * mutable_reference_line_towing_l()
void GetRangeOverlaps(std::vector< hdmap::PathOverlap > *path_overlaps, double start_s, double end_s)
const PathBoundary & reference_line_towing_path_boundary() const
void SetCandidatePathData(std::vector< PathData > &&candidate_path_data)
void SetTrajectory(const DiscretizedTrajectory &trajectory)
const std::vector< SLPolygon > & obs_sl_polygons() const
void SetLatticeStopPoint(const StopPoint &stop_point)
bool GetNeighborLaneInfo(const ReferenceLineInfo::LaneType lane_type, const double s, hdmap::Id *ptr_lane_id, double *ptr_lane_width) const
int GetJunction(const double s, hdmap::PathOverlap *junction_overlap) const
const std::vector< PathData > & GetCandidatePathData() const
hdmap::Lane::LaneTurn GetPathTurnType(const double s) const
void SetDrivable(bool drivable)
Set if the vehicle can drive following this reference line A planner need to set this value to true i...
const std::vector< PathBoundary > & GetCandidatePathBoundaries() const
bool AddObstacles(const std::vector< const Obstacle * > &obstacles)
bool CombinePathAndSpeedProfile(const double relative_time, const double start_s, DiscretizedTrajectory *discretized_trajectory)
bool IsNeighborLanePath() const
Check if the current reference line is the neighbor of the vehicle current position
void ExportDecision(DecisionResult *decision_result, PlanningContext *planning_context) const
const std::vector< double > & reference_line_towing_l() const
bool GetIntersectionRightofWayStatus(const hdmap::PathOverlap &pnc_junction_overlap) const
std::vector< SLPolygon > * mutable_obs_sl_polygons()
void LimitCruiseSpeed(double speed)
Limit the cruise speed based on the "base_cruise_speed_".
void SetTurnSignal(const common::VehicleSignal::TurnSignal &turn_signal)
bool IsStartFrom(const ReferenceLineInfo &previous_reference_line_info) const
check if current reference line is started from another reference line info line.
const hdmap::RouteSegments & Lanes() const
bool Init(const std::vector< const Obstacle * > &obstacles, double target_speed)
ADCTrajectory::RightOfWayStatus GetRightOfWayStatus() const
const ReferenceLine & reference_line() const
std::vector< common::SLPoint > GetAllStopDecisionSLPoint() const
hdmap::PathOverlap * GetOverlapOnReferenceLine(const std::string &overlap_id, const OverlapType &overlap_type) const
const PathData & fallback_path_data() const
void SetCandidatePathBoundaries(std::vector< PathBoundary > &&candidate_path_boundaries)
void ExportEngageAdvice(common::EngageAdvice *engage_advice, PlanningContext *planning_context) const
const DiscretizedTrajectory & trajectory() const
Obstacle * AddObstacle(const Obstacle *obstacle)
hdmap::LaneInfoConstPtr LocateLaneInfo(const double s) const
std::vector< PathData > * MutableCandidatePathData()
const SLBoundary & AdcSlBoundary() const
int GetArea(const double s, hdmap::PathOverlap *area_overlap) const
void SetJunctionRightOfWay(const double junction_s, const bool is_protected) const
bool AdjustTrajectoryWhichStartsFromCurrentPos(const common::TrajectoryPoint &planning_start_point, const std::vector< common::TrajectoryPoint > &trajectory, DiscretizedTrajectory *adjusted_trajectory)
bool IsChangeLanePath() const
Check if the current reference line is a change lane reference line, i.e., ADC's current position is ...
int GetPnCJunction(const double s, hdmap::PathOverlap *pnc_junction_overlap) const
const hdmap::Path & GetMapPath() const
const hdmap::Path & map_path() const
bool IsOnLane(const common::SLPoint &sl_point) const
: check if a box/point is on lane along reference line
void AddSpeedLimit(double start_s, double end_s, double speed_limit)
ReferencePoint GetReferencePoint(const double s) const
bool GetSLBoundary(const common::math::Box2d &box, SLBoundary *const sl_boundary, double warm_start_s=-1.0) const
Get the SL Boundary of the box.
void GetLaneFromS(const double s, std::vector< hdmap::LaneInfoConstPtr > *lanes) const
bool XYToSL(const common::math::Vec2d &xy_point, common::SLPoint *const sl_point, double warm_start_s=-1.0) const
Transvert Cartesian coordinates to Frenet.
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
const std::vector< ReferencePoint > & reference_points() const
virtual std::string DebugString() const
bool EvaluateByTime(const double time, common::SpeedPoint *const speed_point) const
Definition speed_data.cc:60
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
Some util functions.
double AngleDiff(const double from, const double to)
Calculate the difference between angle from and to
Definition math_utils.cc:61
std::size_t Hash(const std::string &key)
Definition util.h:27
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
bool WithinOverlap(const hdmap::PathOverlap &overlap, double s)
class register implement
Definition arena_queue.h:37
optional VehicleParam vehicle_param
optional apollo::canbus::Chassis::DrivingMode driving_mode