Apollo 10.0
自动驾驶开放平台
lane_follow_map.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 *****************************************************************************/
21
22#include <algorithm>
23#include <limits>
24
25#include "absl/strings/str_cat.h"
26#include "google/protobuf/text_format.h"
27
28#include "modules/common_msgs/map_msgs/map_id.pb.h"
29
30#include "cyber/common/log.h"
37
38namespace apollo {
39namespace planning {
40
45
46namespace {
47
48// Maximum lateral error used in trajectory approximation.
49const double kTrajectoryApproximationMaxError = 2.0;
50
51} // namespace
52
53LaneFollowMap::LaneFollowMap() : hdmap_(hdmap::HDMapUtil::BaseMapPtr()) {}
54
56 return command.has_lane_follow_command();
57}
58
59hdmap::LaneWaypoint LaneFollowMap::ToLaneWaypoint(
60 const routing::LaneWaypoint &waypoint) const {
61 auto lane = hdmap_->GetLaneById(hdmap::MakeMapId(waypoint.id()));
62 ACHECK(lane) << "Invalid lane id: " << waypoint.id();
63 return hdmap::LaneWaypoint(lane, waypoint.s());
64}
65
66hdmap::LaneSegment LaneFollowMap::ToLaneSegment(
67 const routing::LaneSegment &segment) const {
68 auto lane = hdmap_->GetLaneById(hdmap::MakeMapId(segment.id()));
69 ACHECK(lane) << "Invalid lane id: " << segment.id();
70 return hdmap::LaneSegment(lane, segment.start_s(), segment.end_s());
71}
72
73void LaneFollowMap::UpdateNextRoutingWaypointIndex(int cur_index) {
74 if (cur_index < 0) {
75 next_routing_waypoint_index_ = 0;
76 return;
77 }
78 if (cur_index >= static_cast<int>(route_indices_.size())) {
79 next_routing_waypoint_index_ = routing_waypoint_index_.size() - 1;
80 return;
81 }
82 // Search backwards when the car is driven backward on the route.
83 while (next_routing_waypoint_index_ != 0 &&
84 next_routing_waypoint_index_ < routing_waypoint_index_.size() &&
85 routing_waypoint_index_[next_routing_waypoint_index_].index >
86 cur_index) {
87 --next_routing_waypoint_index_;
88 }
89 while (next_routing_waypoint_index_ != 0 &&
90 next_routing_waypoint_index_ < routing_waypoint_index_.size() &&
91 routing_waypoint_index_[next_routing_waypoint_index_].index ==
92 cur_index &&
94 routing_waypoint_index_[next_routing_waypoint_index_].waypoint.s) {
95 --next_routing_waypoint_index_;
96 }
97 // Search forwards
98 while (next_routing_waypoint_index_ < routing_waypoint_index_.size() &&
99 routing_waypoint_index_[next_routing_waypoint_index_].index <
100 cur_index) {
101 ++next_routing_waypoint_index_;
102 }
103 while (next_routing_waypoint_index_ < routing_waypoint_index_.size() &&
104 cur_index ==
105 routing_waypoint_index_[next_routing_waypoint_index_].index &&
107 routing_waypoint_index_[next_routing_waypoint_index_].waypoint.s) {
108 ++next_routing_waypoint_index_;
109 }
110 if (next_routing_waypoint_index_ >= routing_waypoint_index_.size()) {
111 next_routing_waypoint_index_ = routing_waypoint_index_.size() - 1;
112 }
113}
114
115std::vector<routing::LaneWaypoint> LaneFollowMap::FutureRouteWaypoints() const {
116 const auto &waypoints =
118 return std::vector<routing::LaneWaypoint>(
119 waypoints.begin() + next_routing_waypoint_index_, waypoints.end());
120}
121
123 std::shared_ptr<routing::LaneWaypoint> &end_point) const {
124 if (!last_command_.has_lane_follow_command() ||
125 !last_command_.lane_follow_command().has_routing_request()) {
126 end_point = nullptr;
127 return;
128 }
129 const auto &routing_request =
131 if (routing_request.waypoint().size() < 1) {
132 end_point = nullptr;
133 return;
134 }
135 end_point = std::make_shared<routing::LaneWaypoint>();
136 end_point->CopyFrom(*(routing_request.waypoint().rbegin()));
137}
138
140 if (nullptr == hdmap_) {
141 return nullptr;
142 }
143 return hdmap_->GetLaneById(id);
144}
145
146bool LaneFollowMap::IsValid(const planning::PlanningCommand &command) const {
147 if (!CanProcess(command)) {
148 return false;
149 }
150 const auto &routing = command.lane_follow_command();
151 const int num_road = routing.road_size();
152 if (num_road == 0) {
153 return false;
154 }
155 if (!routing.has_routing_request() ||
156 routing.routing_request().waypoint_size() < 2) {
157 AERROR << "Routing does not have request.";
158 return false;
159 }
160 for (const auto &waypoint : routing.routing_request().waypoint()) {
161 if (!waypoint.has_id() || !waypoint.has_s()) {
162 AERROR << "Routing waypoint has no lane_id or s.";
163 return false;
164 }
165 }
166 return true;
167}
168
169void LaneFollowMap::UpdateRoutingRange(int adc_index) {
170 // Track routing range.
171 range_lane_ids_.clear();
172 range_start_ = std::max(0, adc_index - 1);
173 range_end_ = range_start_;
174 while (range_end_ < static_cast<int>(route_indices_.size())) {
175 const auto &lane_id = route_indices_[range_end_].segment.lane->id().id();
176 if (range_lane_ids_.count(lane_id) != 0) {
177 break;
178 }
179 range_lane_ids_.insert(lane_id);
180 ++range_end_;
181 }
182}
183
184bool LaneFollowMap::UpdateVehicleState(const VehicleState &vehicle_state) {
185 if (!IsValid(last_command_)) {
186 AERROR << "The routing is invalid when updating vehicle state.";
187 route_segments_lane_ids_.clear();
188 return false;
189 }
190 if (!adc_state_.has_x() ||
191 (common::util::DistanceXY(adc_state_, vehicle_state) >
192 FLAGS_replan_lateral_distance_threshold +
193 FLAGS_replan_longitudinal_distance_threshold)) {
194 // Position is reset, but not replan.
195 next_routing_waypoint_index_ = 0;
196 adc_route_index_ = -1;
197 stop_for_destination_ = false;
198 }
199
200 adc_state_ = vehicle_state;
201 if (!GetNearestPointFromRouting(vehicle_state, &adc_waypoint_)) {
202 AERROR << "Failed to get waypoint from routing with point: " << "("
203 << vehicle_state.x() << ", " << vehicle_state.y() << ", "
204 << vehicle_state.z() << ").";
205 route_segments_lane_ids_.clear();
206 return false;
207 }
208 int route_index = GetWaypointIndex(adc_waypoint_);
209 if (route_index < 0 ||
210 route_index >= static_cast<int>(route_indices_.size())) {
211 AERROR << "Cannot find waypoint: " << adc_waypoint_.DebugString();
212 return false;
213 }
214 ADEBUG << "adc_waypoint_" << adc_waypoint_.DebugString() << "route_index"
215 << route_index;
216 // Track how many routing request waypoints the adc have passed.
217 UpdateNextRoutingWaypointIndex(route_index);
218 adc_route_index_ = route_index;
219 UpdateRoutingRange(adc_route_index_);
220
221 if (routing_waypoint_index_.empty()) {
222 AERROR << "No routing waypoint index.";
223 return false;
224 }
225
226 if (next_routing_waypoint_index_ == routing_waypoint_index_.size() - 1) {
227 stop_for_destination_ = true;
228 }
229 return true;
230}
231
233 const planning::PlanningCommand &command) {
234 if (!CanProcess(command)) {
235 AERROR << "Command cannot be processed by LaneFollowMap!";
236 return false;
237 }
238 if (!PncMapBase::UpdatePlanningCommand(command)) {
239 return false;
240 }
241 const auto &routing = command.lane_follow_command();
242 range_lane_ids_.clear();
243 route_indices_.clear();
244 all_lane_ids_.clear();
245 for (int road_index = 0; road_index < routing.road_size(); ++road_index) {
246 const auto &road_segment = routing.road(road_index);
247 for (int passage_index = 0; passage_index < road_segment.passage_size();
248 ++passage_index) {
249 const auto &passage = road_segment.passage(passage_index);
250 for (int lane_index = 0; lane_index < passage.segment_size();
251 ++lane_index) {
252 all_lane_ids_.insert(passage.segment(lane_index).id());
253 route_indices_.emplace_back();
254 route_indices_.back().segment =
255 ToLaneSegment(passage.segment(lane_index));
256 if (route_indices_.back().segment.lane == nullptr) {
257 AERROR << "Failed to get lane segment from passage.";
258 return false;
259 }
260 route_indices_.back().index = {road_index, passage_index, lane_index};
261 }
262 }
263 }
264
265 range_start_ = 0;
266 range_end_ = 0;
267 adc_route_index_ = -1;
268 next_routing_waypoint_index_ = 0;
269 UpdateRoutingRange(adc_route_index_);
270
271 routing_waypoint_index_.clear();
272 const auto &request_waypoints = routing.routing_request().waypoint();
273 if (request_waypoints.empty()) {
274 AERROR << "Invalid routing: no request waypoints.";
275 return false;
276 }
277 int i = 0;
278 for (size_t j = 0; j < route_indices_.size(); ++j) {
279 while (i < request_waypoints.size() &&
280 hdmap::RouteSegments::WithinLaneSegment(route_indices_[j].segment,
281 request_waypoints.Get(i))) {
282 routing_waypoint_index_.emplace_back(
283 hdmap::LaneWaypoint(route_indices_[j].segment.lane,
284 request_waypoints.Get(i).s()),
285 j);
286 ++i;
287 }
288 }
290 stop_for_destination_ = false;
291 return true;
292}
293
294int LaneFollowMap::SearchForwardWaypointIndex(
295 int start, const hdmap::LaneWaypoint &waypoint) const {
296 int i = std::max(start, 0);
297 while (i < static_cast<int>(route_indices_.size()) &&
298 !hdmap::RouteSegments::WithinLaneSegment(route_indices_[i].segment,
299 waypoint)) {
300 ++i;
301 }
302 return i;
303}
304
305int LaneFollowMap::SearchBackwardWaypointIndex(
306 int start, const hdmap::LaneWaypoint &waypoint) const {
307 int i = std::min(static_cast<int>(route_indices_.size() - 1), start);
309 route_indices_[i].segment, waypoint)) {
310 --i;
311 }
312 return i;
313}
314
315int LaneFollowMap::NextWaypointIndex(int index) const {
316 if (index >= static_cast<int>(route_indices_.size() - 1)) {
317 return static_cast<int>(route_indices_.size()) - 1;
318 } else if (index < 0) {
319 return 0;
320 } else {
321 return index + 1;
322 }
323}
324
325int LaneFollowMap::GetWaypointIndex(const hdmap::LaneWaypoint &waypoint) const {
326 int forward_index = SearchForwardWaypointIndex(adc_route_index_, waypoint);
327 if (forward_index >= static_cast<int>(route_indices_.size())) {
328 return SearchBackwardWaypointIndex(adc_route_index_, waypoint);
329 }
330 if (forward_index == adc_route_index_ ||
331 forward_index == adc_route_index_ + 1) {
332 return forward_index;
333 }
334 auto backward_index = SearchBackwardWaypointIndex(adc_route_index_, waypoint);
335 if (backward_index < 0) {
336 return forward_index;
337 }
338
339 return (backward_index + 1 == adc_route_index_) ? backward_index
340 : forward_index;
341}
342
343bool LaneFollowMap::PassageToSegments(routing::Passage passage,
344 hdmap::RouteSegments *segments) const {
345 CHECK_NOTNULL(segments);
346 segments->clear();
347 for (const auto &lane : passage.segment()) {
348 auto lane_ptr = hdmap_->GetLaneById(hdmap::MakeMapId(lane.id()));
349 if (!lane_ptr) {
350 AERROR << "Failed to find lane: " << lane.id();
351 return false;
352 }
353 segments->emplace_back(lane_ptr, std::max(0.0, lane.start_s()),
354 std::min(lane_ptr->total_length(), lane.end_s()));
355 }
356 return !segments->empty();
357}
358
359std::vector<int> LaneFollowMap::GetNeighborPassages(
360 const routing::RoadSegment &road, int start_passage) const {
361 CHECK_GE(start_passage, 0);
362 CHECK_LE(start_passage, road.passage_size());
363 std::vector<int> result;
364 const auto &source_passage = road.passage(start_passage);
365 result.emplace_back(start_passage);
366 if (source_passage.change_lane_type() == routing::FORWARD) {
367 return result;
368 }
369 if (source_passage.can_exit()) { // No need to change lane
370 return result;
371 }
372 hdmap::RouteSegments source_segments;
373 if (!PassageToSegments(source_passage, &source_segments)) {
374 AERROR << "Failed to convert passage to segments";
375 return result;
376 }
377 if (next_routing_waypoint_index_ < routing_waypoint_index_.size() &&
378 source_segments.IsWaypointOnSegment(
379 routing_waypoint_index_[next_routing_waypoint_index_].waypoint)) {
380 ADEBUG << "Need to pass next waypoint[" << next_routing_waypoint_index_
381 << "] before change lane";
382 return result;
383 }
384 std::unordered_set<std::string> neighbor_lanes;
385 if (source_passage.change_lane_type() == routing::LEFT) {
386 for (const auto &segment : source_segments) {
387 for (const auto &left_id :
388 segment.lane->lane().left_neighbor_forward_lane_id()) {
389 neighbor_lanes.insert(left_id.id());
390 }
391 }
392 } else if (source_passage.change_lane_type() == routing::RIGHT) {
393 for (const auto &segment : source_segments) {
394 for (const auto &right_id :
395 segment.lane->lane().right_neighbor_forward_lane_id()) {
396 neighbor_lanes.insert(right_id.id());
397 }
398 }
399 }
400
401 for (int i = 0; i < road.passage_size(); ++i) {
402 if (i == start_passage) {
403 continue;
404 }
405 const auto &target_passage = road.passage(i);
406 for (const auto &segment : target_passage.segment()) {
407 if (neighbor_lanes.count(segment.id())) {
408 result.emplace_back(i);
409 break;
410 }
411 }
412 }
413 return result;
414}
416 const VehicleState &vehicle_state,
417 std::list<hdmap::RouteSegments> *const route_segments) {
418 double look_forward_distance =
419 LookForwardDistance(vehicle_state.linear_velocity());
420 double look_backward_distance = FLAGS_look_backward_distance;
421 return GetRouteSegments(vehicle_state, look_backward_distance,
422 look_forward_distance, route_segments);
423}
424
426 const VehicleState &vehicle_state, const double backward_length,
427 const double forward_length,
428 std::list<hdmap::RouteSegments> *const route_segments) {
429 if (!UpdateVehicleState(vehicle_state)) {
430 AERROR << "Failed to update vehicle state in pnc_map.";
431 return false;
432 }
433 // Vehicle has to be this close to lane center before considering change
434 // lane
435 if (!adc_waypoint_.lane || adc_route_index_ < 0 ||
436 adc_route_index_ >= static_cast<int>(route_indices_.size())) {
437 AERROR << "Invalid vehicle state in pnc_map, update vehicle state first.";
438 return false;
439 }
440 const auto &route_index = route_indices_[adc_route_index_].index;
441 const int road_index = route_index[0];
442 const int passage_index = route_index[1];
443 const auto &road = last_command_.lane_follow_command().road(road_index);
444 // Raw filter to find all neighboring passages
445 auto drive_passages = GetNeighborPassages(road, passage_index);
446 for (const int index : drive_passages) {
447 const auto &passage = road.passage(index);
448 hdmap::RouteSegments segments;
449 if (!PassageToSegments(passage, &segments)) {
450 ADEBUG << "Failed to convert passage to lane segments.";
451 continue;
452 }
453 const PointENU nearest_point =
454 index == passage_index
455 ? adc_waypoint_.lane->GetSmoothPoint(adc_waypoint_.s)
456 : PointFactory::ToPointENU(adc_state_);
457 common::SLPoint sl;
458 hdmap::LaneWaypoint segment_waypoint;
459 if (!segments.GetProjection(nearest_point, &sl, &segment_waypoint)) {
460 ADEBUG << "Failed to get projection from point: "
461 << nearest_point.ShortDebugString();
462 continue;
463 }
464 if (index != passage_index) {
465 if (!segments.CanDriveFrom(adc_waypoint_)) {
466 ADEBUG << "You cannot drive from current waypoint to passage: "
467 << index;
468 continue;
469 }
470 }
471 route_segments->emplace_back();
472 const auto last_waypoint = segments.LastWaypoint();
473 if (!ExtendSegments(segments, sl.s() - backward_length,
474 sl.s() + forward_length, &route_segments->back())) {
475 AERROR << "Failed to extend segments with s=" << sl.s()
476 << ", backward: " << backward_length
477 << ", forward: " << forward_length;
478 return false;
479 }
480 if (route_segments->back().IsWaypointOnSegment(last_waypoint)) {
481 route_segments->back().SetRouteEndWaypoint(last_waypoint);
482 }
483 route_segments->back().SetCanExit(passage.can_exit());
484 route_segments->back().SetNextAction(passage.change_lane_type());
485 const std::string route_segment_id = absl::StrCat(road_index, "_", index);
486 route_segments->back().SetId(route_segment_id);
487 route_segments->back().SetStopForDestination(stop_for_destination_);
488 if (index == passage_index) {
489 route_segments->back().SetIsOnSegment(true);
490 route_segments->back().SetPreviousAction(routing::FORWARD);
491 } else if (sl.l() > 0) {
492 route_segments->back().SetPreviousAction(routing::RIGHT);
493 } else {
494 route_segments->back().SetPreviousAction(routing::LEFT);
495 }
496 }
497 UpdateRouteSegmentsLaneIds(route_segments);
498 return !route_segments->empty();
499}
500
502 const common::VehicleState &state, hdmap::LaneWaypoint *waypoint) const {
503 waypoint->lane = nullptr;
504 std::vector<hdmap::LaneInfoConstPtr> lanes;
505 const auto point = PointFactory::ToPointENU(state);
506 std::vector<hdmap::LaneInfoConstPtr> valid_lanes;
507 for (auto lane_id : all_lane_ids_) {
508 hdmap::Id id = hdmap::MakeMapId(lane_id);
509 auto lane = hdmap_->GetLaneById(id);
510 if (nullptr != lane) {
511 valid_lanes.emplace_back(lane);
512 }
513 }
514
515 // Get nearest_waypoints for current position
516 std::vector<hdmap::LaneWaypoint> valid_way_points;
517 for (const auto &lane : valid_lanes) {
518 if (range_lane_ids_.count(lane->id().id()) == 0) {
519 ADEBUG << "not in range" << lane->id().id();
520 continue;
521 }
522 if (route_segments_lane_ids_.size() > 0 &&
523 route_segments_lane_ids_.count(lane->id().id()) == 0) {
524 ADEBUG << "not in last frame route_segments: " << lane->id().id();
525 continue;
526 }
527 double s = 0.0;
528 double l = 0.0;
529 {
530 if (!lane->GetProjection({point.x(), point.y()}, &s, &l)) {
531 continue;
532 }
533 ADEBUG << lane->id().id() << "," << s << "," << l;
534 // Use large epsilon to allow projection diff
535 static constexpr double kEpsilon = 0.5;
536 if (s > (lane->total_length() + kEpsilon) || (s + kEpsilon) < 0.0) {
537 continue;
538 }
539 double lane_heading = lane->Heading(s);
540 if (std::fabs(common::math::AngleDiff(lane_heading, state.heading())) >
541 M_PI_2 * 1.5) {
542 continue;
543 }
544 }
545
546 valid_way_points.emplace_back();
547 auto &last = valid_way_points.back();
548 last.lane = lane;
549 last.s = s;
550 last.l = l;
551 ADEBUG << "distance:" << std::fabs(l);
552 }
553 if (valid_way_points.empty()) {
554 AERROR << "Failed to find nearest point: " << point.ShortDebugString();
555 return false;
556 }
557
558 // find closest lane that satisfy vehicle heading
559 int closest_index = -1;
560 double distance = std::numeric_limits<double>::max();
561 double lane_heading = 0.0;
562 double vehicle_heading = state.heading();
563 for (size_t i = 0; i < valid_way_points.size(); i++) {
564 lane_heading = valid_way_points[i].lane->Heading(valid_way_points[i].s);
565 if (std::abs(common::math::AngleDiff(lane_heading, vehicle_heading)) >
566 M_PI_2 * 1.5) {
567 continue;
568 }
569 if (std::fabs(valid_way_points[i].l) < distance) {
570 distance = std::fabs(valid_way_points[i].l);
571 closest_index = i;
572 }
573 }
574 if (closest_index == -1) {
575 AERROR << "Can not find nearest waypoint. vehicle heading:"
576 << vehicle_heading << "lane heading:" << lane_heading;
577 return false;
578 }
579 waypoint->lane = valid_way_points[closest_index].lane;
580 waypoint->s = valid_way_points[closest_index].s;
581 waypoint->l = valid_way_points[closest_index].l;
582 return true;
583}
584
585hdmap::LaneInfoConstPtr LaneFollowMap::GetRouteSuccessor(
586 hdmap::LaneInfoConstPtr lane) const {
587 if (lane->lane().successor_id().empty()) {
588 return nullptr;
589 }
590 hdmap::Id preferred_id = lane->lane().successor_id(0);
591 for (const auto &lane_id : lane->lane().successor_id()) {
592 if (range_lane_ids_.count(lane_id.id()) != 0) {
593 preferred_id = lane_id;
594 break;
595 }
596 }
597 return hdmap_->GetLaneById(preferred_id);
598}
599
600hdmap::LaneInfoConstPtr LaneFollowMap::GetRoutePredecessor(
601 hdmap::LaneInfoConstPtr lane) const {
602 if (lane->lane().predecessor_id().empty()) {
603 return nullptr;
604 }
605
606 std::unordered_set<std::string> predecessor_ids;
607 for (const auto &lane_id : lane->lane().predecessor_id()) {
608 predecessor_ids.insert(lane_id.id());
609 }
610
611 hdmap::Id preferred_id = lane->lane().predecessor_id(0);
612 for (const auto &route_index : route_indices_) {
613 auto &lane = route_index.segment.lane->id();
614 if (predecessor_ids.count(lane.id()) != 0) {
615 preferred_id = lane;
616 break;
617 }
618 }
619 return hdmap_->GetLaneById(preferred_id);
620}
621
622bool LaneFollowMap::ExtendSegments(const hdmap::RouteSegments &segments,
623 const common::PointENU &point,
624 double look_backward, double look_forward,
625 hdmap::RouteSegments *extended_segments) {
626 common::SLPoint sl;
627 hdmap::LaneWaypoint waypoint;
628 if (!segments.GetProjection(point, &sl, &waypoint)) {
629 AERROR << "point: " << point.ShortDebugString() << " is not on segment";
630 return false;
631 }
632 return ExtendSegments(segments, sl.s() - look_backward, sl.s() + look_forward,
633 extended_segments);
634}
635
637 const hdmap::RouteSegments &segments, double start_s, double end_s,
638 hdmap::RouteSegments *const truncated_segments) const {
639 if (segments.empty()) {
640 AERROR << "The input segments is empty";
641 return false;
642 }
643 CHECK_NOTNULL(truncated_segments);
644 truncated_segments->SetProperties(segments);
645
646 if (start_s >= end_s) {
647 AERROR << "start_s(" << start_s << " >= end_s(" << end_s << ")";
648 return false;
649 }
650 std::unordered_set<std::string> unique_lanes;
651 static constexpr double kRouteEpsilon = 1e-3;
652 // Extend the trajectory towards the start of the trajectory.
653 if (start_s < 0) {
654 const auto &first_segment = *segments.begin();
655 auto lane = first_segment.lane;
656 double s = first_segment.start_s;
657 double extend_s = -start_s;
658 std::vector<hdmap::LaneSegment> extended_lane_segments;
659 while (extend_s > kRouteEpsilon) {
660 if (s <= kRouteEpsilon) {
661 lane = GetRoutePredecessor(lane);
662 if (lane == nullptr ||
663 unique_lanes.find(lane->id().id()) != unique_lanes.end()) {
664 break;
665 }
666 s = lane->total_length();
667 } else {
668 const double length = std::min(s, extend_s);
669 extended_lane_segments.emplace_back(lane, s - length, s);
670 extend_s -= length;
671 s -= length;
672 unique_lanes.insert(lane->id().id());
673 }
674 }
675 truncated_segments->insert(truncated_segments->begin(),
676 extended_lane_segments.rbegin(),
677 extended_lane_segments.rend());
678 }
679 bool found_loop = false;
680 double router_s = 0;
681 for (const auto &lane_segment : segments) {
682 const double adjusted_start_s = std::max(
683 start_s - router_s + lane_segment.start_s, lane_segment.start_s);
684 const double adjusted_end_s =
685 std::min(end_s - router_s + lane_segment.start_s, lane_segment.end_s);
686 if (adjusted_start_s < adjusted_end_s) {
687 if (!truncated_segments->empty() &&
688 truncated_segments->back().lane->id().id() ==
689 lane_segment.lane->id().id()) {
690 truncated_segments->back().end_s = adjusted_end_s;
691 } else if (unique_lanes.find(lane_segment.lane->id().id()) ==
692 unique_lanes.end()) {
693 truncated_segments->emplace_back(lane_segment.lane, adjusted_start_s,
694 adjusted_end_s);
695 unique_lanes.insert(lane_segment.lane->id().id());
696 } else {
697 found_loop = true;
698 break;
699 }
700 }
701 router_s += (lane_segment.end_s - lane_segment.start_s);
702 if (router_s > end_s) {
703 break;
704 }
705 }
706 if (found_loop) {
707 return true;
708 }
709 // Extend the trajectory towards the end of the trajectory.
710 if (router_s < end_s && !truncated_segments->empty()) {
711 auto &back = truncated_segments->back();
712 if (back.lane->total_length() > back.end_s) {
713 double origin_end_s = back.end_s;
714 back.end_s =
715 std::min(back.end_s + end_s - router_s, back.lane->total_length());
716 router_s += back.end_s - origin_end_s;
717 }
718 }
719 auto last_lane = segments.back().lane;
720 while (router_s < end_s - kRouteEpsilon) {
721 last_lane = GetRouteSuccessor(last_lane);
722 if (last_lane == nullptr ||
723 unique_lanes.find(last_lane->id().id()) != unique_lanes.end()) {
724 break;
725 }
726 const double length = std::min(end_s - router_s, last_lane->total_length());
727 truncated_segments->emplace_back(last_lane, 0, length);
728 unique_lanes.insert(last_lane->id().id());
729 router_s += length;
730 }
731 return true;
732}
733
734void LaneFollowMap::AppendLaneToPoints(
735 hdmap::LaneInfoConstPtr lane, const double start_s, const double end_s,
736 std::vector<hdmap::MapPathPoint> *const points) {
737 if (points == nullptr || start_s >= end_s) {
738 return;
739 }
740 double accumulate_s = 0.0;
741 for (size_t i = 0; i < lane->points().size(); ++i) {
742 if (accumulate_s >= start_s && accumulate_s <= end_s) {
743 points->emplace_back(lane->points()[i], lane->headings()[i],
744 hdmap::LaneWaypoint(lane, accumulate_s));
745 }
746 if (i < lane->segments().size()) {
747 const auto &segment = lane->segments()[i];
748 const double next_accumulate_s = accumulate_s + segment.length();
749 if (start_s > accumulate_s && start_s < next_accumulate_s) {
750 points->emplace_back(segment.start() + segment.unit_direction() *
751 (start_s - accumulate_s),
752 lane->headings()[i],
753 hdmap::LaneWaypoint(lane, start_s));
754 }
755 if (end_s > accumulate_s && end_s < next_accumulate_s) {
756 points->emplace_back(
757 segment.start() + segment.unit_direction() * (end_s - accumulate_s),
758 lane->headings()[i], hdmap::LaneWaypoint(lane, end_s));
759 }
760 accumulate_s = next_accumulate_s;
761 }
762 if (accumulate_s > end_s) {
763 break;
764 }
765 }
766}
767
768void LaneFollowMap::UpdateRouteSegmentsLaneIds(
769 const std::list<hdmap::RouteSegments> *route_segments) {
770 route_segments_lane_ids_.clear();
771 for (auto &route_seg : *route_segments) {
772 for (auto &lane_seg : route_seg) {
773 if (nullptr == lane_seg.lane) {
774 continue;
775 }
776 route_segments_lane_ids_.insert(lane_seg.lane->id().id());
777 }
778 }
779}
780
784
786 if (adc_route_index_ < 0 || adc_route_index_ >= route_indices_.size()) {
787 AERROR << "adc_route_index error, can not get distance to destination, "
788 "return 0.";
789 return 0.0;
790 }
791 const auto &routing = last_command_.lane_follow_command();
792 int adc_road_index = route_indices_[adc_route_index_].index[0];
793 int adc_passage_index = route_indices_[adc_route_index_].index[1];
794 int adc_lane_index = route_indices_[adc_route_index_].index[2];
795
796 bool get_adc_exit_waypoint =
797 routing.road(adc_road_index).passage(adc_passage_index).can_exit();
798 int start_passage_index = adc_passage_index;
799 int start_lane_index = adc_lane_index;
800 double start_lane_s = adc_waypoint_.s;
801
802 double dis_to_destination = 0.0;
803
804 for (int road_index = adc_road_index; road_index < routing.road_size();
805 ++road_index) {
806 const auto &road_segment = routing.road(road_index);
807 for (int passage_index = 0; passage_index < road_segment.passage_size();
808 ++passage_index) {
809 const auto &passage = road_segment.passage(passage_index);
810 if (!passage.can_exit()) {
811 continue;
812 }
813 // check this passsage is can_exit
814 if (!get_adc_exit_waypoint) {
815 get_adc_exit_waypoint = true;
816 // find adc waypoint in passage which can exit
817 for (int index = 0; index < passage.segment_size(); ++index) {
818 auto lane = hdmap_->GetLaneById(
819 hdmap::MakeMapId(passage.segment(index).id()));
820 double s = 0.0;
821 double l = 0.0;
822 if (!lane->GetProjection({adc_state_.x(), adc_state_.y()}, &s, &l)) {
823 continue;
824 }
825 static constexpr double kEpsilon = 0.5;
826 if (s > (lane->total_length() + kEpsilon) || (s + kEpsilon) < 0.0) {
827 continue;
828 }
829 start_passage_index = passage_index;
830 start_lane_index = index;
831 start_lane_s = s;
832 }
833 }
834
835 // add distance by lane in can_exit passage
836 if (get_adc_exit_waypoint) {
837 if (road_index == adc_road_index &&
838 passage_index == start_passage_index) {
839 for (int lane_index = start_lane_index;
840 lane_index < passage.segment_size(); ++lane_index) {
841 if (lane_index == start_lane_index) {
842 dis_to_destination +=
843 passage.segment(lane_index).end_s() - start_lane_s;
844 } else {
845 dis_to_destination += passage.segment(lane_index).end_s() -
846 passage.segment(lane_index).start_s();
847 }
848 }
849 } else {
850 for (int lane_index = 0; lane_index < passage.segment_size();
851 ++lane_index) {
852 dis_to_destination += passage.segment(lane_index).end_s() -
853 passage.segment(lane_index).start_s();
854 }
855 }
856 break;
857 }
858 }
859 }
860 return dis_to_destination;
861}
862
863} // namespace planning
864} // namespace apollo
static PointENU ToPointENU(const double x, const double y, const double z=0)
LaneInfoConstPtr GetLaneById(const Id &id) const
Definition hdmap.cc:34
void SetProperties(const RouteSegments &other)
Copy the properties of other segments to current one
static bool WithinLaneSegment(const LaneSegment &lane_segment, const LaneWaypoint &waypoint)
std::vector< routing::LaneWaypoint > FutureRouteWaypoints() const override
apollo::hdmap::LaneWaypoint GetAdcWaypoint() const override
bool GetRouteSegments(const common::VehicleState &vehicle_state, std::list< apollo::hdmap::RouteSegments > *const route_segments) override
use heuristic forward length and backward length
hdmap::LaneInfoConstPtr GetLaneById(const hdmap::Id &id) const override
Get the Lane with the given id.
bool CanProcess(const planning::PlanningCommand &command) const override
bool UpdatePlanningCommand(const planning::PlanningCommand &command) override
double GetDistanceToDestination() const override
void GetEndLaneWayPoint(std::shared_ptr< routing::LaneWaypoint > &end_point) const override
Get the end point of PlanningCommand.
bool ExtendSegments(const apollo::hdmap::RouteSegments &segments, double start_s, double end_s, apollo::hdmap::RouteSegments *const truncated_segments) const override
bool GetNearestPointFromRouting(const common::VehicleState &state, apollo::hdmap::LaneWaypoint *waypoint) const override
static double LookForwardDistance(const double velocity)
virtual bool UpdatePlanningCommand(const planning::PlanningCommand &command)
apollo::hdmap::LaneWaypoint adc_waypoint_
The waypoint of the autonomous driving car
planning::PlanningCommand last_command_
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
Some util functions.
double AngleDiff(const double from, const double to)
Calculate the difference between angle from and to
Definition math_utils.cc:61
double DistanceXY(const U &u, const V &v)
calculate the distance beteween Point u and Point v, which are all have member function x() and y() i...
Definition util.h:97
apollo::hdmap::Id MakeMapId(const std::string &id)
create a Map ID given a string.
Definition hdmap_util.h:85
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
class register implement
Definition arena_queue.h:37
Some string util functions.
optional string id
Definition map_id.proto:7
std::string DebugString() const
Definition path.cc:68
LaneInfoConstPtr lane
Definition path.h:44
optional apollo::routing::RoutingResponse lane_follow_command
repeated apollo::routing::LaneWaypoint waypoint
Definition routing.proto:14
optional RoutingRequest routing_request
Definition routing.proto:27
repeated apollo::routing::RoadSegment road
Definition routing.proto:25