Apollo 10.0
自动驾驶开放平台
route_segments.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
26
27namespace apollo {
28namespace hdmap {
29namespace {
30
31// Minimum error in lane segmentation.
32constexpr double kSegmentationEpsilon = 0.5;
33} // namespace
34
35const std::string &RouteSegments::Id() const { return id_; }
36
37void RouteSegments::SetId(const std::string &id) { id_ = id; }
38
39void RouteSegments::SetCanExit(bool can_exit) { can_exit_ = can_exit; }
40
41bool RouteSegments::CanExit() const { return can_exit_; }
42
43bool RouteSegments::StopForDestination() const { return stop_for_destination_; }
44
45void RouteSegments::SetStopForDestination(bool stop_for_destination) {
46 stop_for_destination_ = stop_for_destination;
47}
48
50 const LaneWaypoint &waypoint) {
51 return waypoint.lane &&
52 lane_segment.lane->id().id() == waypoint.lane->id().id() &&
53 lane_segment.start_s - kSegmentationEpsilon <= waypoint.s &&
54 lane_segment.end_s + kSegmentationEpsilon >= waypoint.s;
55}
56
58 const routing::LaneWaypoint &waypoint) {
59 return lane_segment.lane && lane_segment.lane->id().id() == waypoint.id() &&
60 lane_segment.start_s - kSegmentationEpsilon <= waypoint.s() &&
61 lane_segment.end_s + kSegmentationEpsilon >= waypoint.s();
62}
63
65 const LaneWaypoint &waypoint) {
66 return waypoint.lane && lane_segment.id() == waypoint.lane->id().id() &&
67 lane_segment.start_s() - kSegmentationEpsilon <= waypoint.s &&
68 lane_segment.end_s() + kSegmentationEpsilon >= waypoint.s;
69}
70
72 const routing::LaneWaypoint &waypoint) {
73 return lane_segment.id() == waypoint.id() &&
74 lane_segment.start_s() - kSegmentationEpsilon <= waypoint.s() &&
75 lane_segment.end_s() + kSegmentationEpsilon >= waypoint.s();
76}
77
79 auto first_waypoint = FirstWaypoint();
80 bool has_overlap = IsWaypointOnSegment(other.FirstWaypoint());
81 if (other.IsWaypointOnSegment(first_waypoint)) {
82 auto iter = other.begin();
83 while (iter != other.end() && !WithinLaneSegment(*iter, first_waypoint)) {
84 ++iter;
85 }
86 begin()->start_s = std::min(begin()->start_s, iter->start_s);
87 begin()->end_s = std::max(begin()->end_s, iter->end_s);
88 insert(begin(), other.begin(), iter);
89 has_overlap = true;
90 }
91 auto last_waypoint = LastWaypoint();
92 if (other.IsWaypointOnSegment(last_waypoint)) {
93 auto iter = other.rbegin();
94 while (iter != other.rend() && !WithinLaneSegment(*iter, last_waypoint)) {
95 ++iter;
96 }
97 back().start_s = std::min(back().start_s, iter->start_s);
98 back().end_s = std::max(back().end_s, iter->end_s);
99 insert(end(), iter.base(), other.end());
100 has_overlap = true;
101 }
102 return has_overlap;
103}
104
106 return route_end_waypoint_;
107}
108
109bool RouteSegments::IsOnSegment() const { return is_on_segment_; }
110
111void RouteSegments::SetIsOnSegment(bool on_segment) {
112 is_on_segment_ = on_segment;
113}
114
115bool RouteSegments::IsNeighborSegment() const { return is_neighbor_; }
116
118 is_neighbor_ = is_neighbor;
119}
120
122 route_end_waypoint_ = waypoint;
123}
124
126 return LaneWaypoint(front().lane, front().start_s, 0.0);
127}
128
130 return LaneWaypoint(back().lane, back().end_s, 0.0);
131}
132
134 route_end_waypoint_ = other.RouteEndWaypoint();
135 can_exit_ = other.CanExit();
136 is_on_segment_ = other.IsOnSegment();
137 next_action_ = other.NextAction();
138 previous_action_ = other.PreviousAction();
139 id_ = other.Id();
140 stop_for_destination_ = other.StopForDestination();
141}
142
143double RouteSegments::Length(const RouteSegments &segments) {
144 double s = 0.0;
145 for (const auto &seg : segments) {
146 s += seg.Length();
147 }
148 return s;
149}
150
152 common::SLPoint *sl_point,
153 LaneWaypoint *waypoint) const {
154 return GetProjection({point_enu.x(), point_enu.y()}, sl_point, waypoint);
155}
156
158 if (empty() || other.empty()) {
159 return false;
160 }
161 if (IsWaypointOnSegment(other.FirstWaypoint())) {
162 return true;
163 }
164 if (IsWaypointOnSegment(other.LastWaypoint())) {
165 return true;
166 }
167 if (other.IsWaypointOnSegment(FirstWaypoint())) {
168 return true;
169 }
170 if (other.IsWaypointOnSegment(LastWaypoint())) {
171 return true;
172 }
173 return false;
174}
175
177 const double look_backward,
178 const double look_forward) {
179 common::SLPoint sl_point;
180 LaneWaypoint waypoint;
181 if (!GetProjection(point, &sl_point, &waypoint)) {
182 AERROR << "failed to project " << point.DebugString() << " to segment";
183 return false;
184 }
185 return Shrink(sl_point.s(), look_backward, look_forward);
186}
187
188bool RouteSegments::Shrink(const double s, const double look_backward,
189 const double look_forward) {
190 LaneWaypoint waypoint;
191 if (!GetWaypoint(s, &waypoint)) {
192 return false;
193 }
194 return Shrink(s, waypoint, look_backward, look_forward);
195}
196
197bool RouteSegments::Shrink(const double s, const LaneWaypoint &waypoint,
198 const double look_backward,
199 const double look_forward) {
200 double acc_s = 0.0;
201 auto iter = begin();
202 while (iter != end() && acc_s + iter->Length() < s - look_backward) {
203 acc_s += iter->Length();
204 ++iter;
205 }
206 if (iter == end()) {
207 return true;
208 }
209 iter->start_s =
210 std::max(iter->start_s, s - look_backward - acc_s + iter->start_s);
211 if (iter->Length() < kSegmentationEpsilon) {
212 ++iter;
213 }
214 erase(begin(), iter);
215
216 iter = begin();
217 acc_s = 0.0;
218 while (iter != end() && !WithinLaneSegment(*iter, waypoint)) {
219 ++iter;
220 }
221 if (iter == end()) {
222 return true;
223 }
224 acc_s = iter->end_s - waypoint.s;
225 if (acc_s >= look_forward) {
226 iter->end_s = waypoint.s + look_forward;
227 ++iter;
228 erase(iter, end());
229 return true;
230 }
231 ++iter;
232 while (iter != end() && acc_s + iter->Length() < look_forward) {
233 acc_s += iter->Length();
234 ++iter;
235 }
236 if (iter == end()) {
237 return true;
238 }
239 iter->end_s = std::min(iter->end_s, look_forward - acc_s + iter->start_s);
240 erase(iter + 1, end());
241 return true;
242}
243
244bool RouteSegments::GetWaypoint(const double s, LaneWaypoint *waypoint) const {
245 double accumulated_s = 0.0;
246 bool has_projection = false;
247 for (auto iter = begin(); iter != end();
248 accumulated_s += (iter->end_s - iter->start_s), ++iter) {
249 if (accumulated_s - kSegmentationEpsilon < s &&
250 s < accumulated_s + iter->end_s - iter->start_s +
251 kSegmentationEpsilon) {
252 waypoint->lane = iter->lane;
253 waypoint->s = s - accumulated_s + iter->start_s;
254 if (waypoint->s < iter->start_s) {
255 waypoint->s = iter->start_s;
256 } else if (waypoint->s > iter->end_s) {
257 waypoint->s = iter->end_s;
258 }
259 has_projection = true;
260 break;
261 }
262 }
263 return has_projection;
264}
265
267 common::SLPoint *sl_point,
268 LaneWaypoint *waypoint) const {
269 double min_l = std::numeric_limits<double>::infinity();
270 double accumulated_s = 0.0;
271 bool has_projection = false;
272 for (auto iter = begin(); iter != end();
273 accumulated_s += (iter->end_s - iter->start_s), ++iter) {
274 double lane_s = 0.0;
275 double lane_l = 0.0;
276 if (!iter->lane->GetProjection(point, &lane_s, &lane_l)) {
277 AERROR << "Failed to get projection from point " << point.DebugString()
278 << " on lane " << iter->lane->id().id();
279 return false;
280 }
281 if (lane_s < iter->start_s - kSegmentationEpsilon ||
282 lane_s > iter->end_s + kSegmentationEpsilon) {
283 continue;
284 }
285 if (std::fabs(lane_l) < min_l) {
286 has_projection = true;
287 lane_s = std::max(iter->start_s, lane_s);
288 lane_s = std::min(iter->end_s, lane_s);
289 min_l = std::fabs(lane_l);
290 sl_point->set_l(lane_l);
291 sl_point->set_s(lane_s - iter->start_s + accumulated_s);
292 waypoint->lane = iter->lane;
293 waypoint->s = lane_s;
294 }
295 }
296 return has_projection;
297}
298
300 const double heading,
301 common::SLPoint *sl_point,
302 LaneWaypoint *waypoint) const {
303 double min_l = std::numeric_limits<double>::infinity();
304 double accumulated_s = 0.0;
305 bool has_projection = false;
306 for (auto iter = begin(); iter != end();
307 accumulated_s += (iter->end_s - iter->start_s), ++iter) {
308 double lane_s = 0.0;
309 double lane_l = 0.0;
310 if (!iter->lane->GetProjection(point, heading, &lane_s, &lane_l)) {
311 AERROR << "Failed to get projection from point " << point.DebugString()
312 << " on lane " << iter->lane->id().id();
313 return false;
314 }
315 if (lane_s < iter->start_s - kSegmentationEpsilon ||
316 lane_s > iter->end_s + kSegmentationEpsilon) {
317 continue;
318 }
319 if (std::fabs(lane_l) < min_l) {
320 has_projection = true;
321 lane_s = std::max(iter->start_s, lane_s);
322 lane_s = std::min(iter->end_s, lane_s);
323 min_l = std::fabs(lane_l);
324 sl_point->set_l(lane_l);
325 sl_point->set_s(lane_s - iter->start_s + accumulated_s);
326 waypoint->lane = iter->lane;
327 waypoint->s = lane_s;
328 }
329 }
330 return has_projection;
331}
332
334 previous_action_ = action;
335}
336
338 return previous_action_;
339}
340
342 next_action_ = action;
343}
344
346 return next_action_;
347}
348
350 for (auto iter = begin(); iter != end(); ++iter) {
351 if (WithinLaneSegment(*iter, waypoint)) {
352 return true;
353 }
354 }
355 return false;
356}
357
358bool RouteSegments::CanDriveFrom(const LaneWaypoint &waypoint) const {
359 auto point = waypoint.lane->GetSmoothPoint(waypoint.s);
360
361 // 0 if waypoint is on segment, ok
362 if (IsWaypointOnSegment(waypoint)) {
363 return true;
364 }
365
366 // 1. should have valid projection.
367 LaneWaypoint segment_waypoint;
368 common::SLPoint route_sl;
369 bool has_projection = GetProjection(point, &route_sl, &segment_waypoint);
370 if (!has_projection) {
371 AERROR << "No projection from waypoint: " << waypoint.DebugString();
372 return false;
373 }
374 static constexpr double kMaxLaneWidth = 10.0;
375 if (std::fabs(route_sl.l()) > 2 * kMaxLaneWidth) {
376 return false;
377 }
378
379 // 2. heading should be the same.
380 double waypoint_heading = waypoint.lane->Heading(waypoint.s);
381 double segment_heading = segment_waypoint.lane->Heading(segment_waypoint.s);
382 double heading_diff =
383 common::math::AngleDiff(waypoint_heading, segment_heading);
384 if (std::fabs(heading_diff) > M_PI / 2) {
385 ADEBUG << "Angle diff too large:" << heading_diff;
386 return false;
387 }
388
389 // 3. the waypoint and the projected lane should not be separated apart.
390 double waypoint_left_width = 0.0;
391 double waypoint_right_width = 0.0;
392 waypoint.lane->GetWidth(waypoint.s, &waypoint_left_width,
393 &waypoint_right_width);
394 double segment_left_width = 0.0;
395 double segment_right_width = 0.0;
396 segment_waypoint.lane->GetWidth(segment_waypoint.s, &segment_left_width,
397 &segment_right_width);
398 auto segment_projected_point =
399 segment_waypoint.lane->GetSmoothPoint(segment_waypoint.s);
400 double dist = common::util::DistanceXY(point, segment_projected_point);
401 const double kLaneSeparationDistance = 0.3;
402 if (route_sl.l() < 0) { // waypoint at right side
403 if (dist >
404 waypoint_left_width + segment_right_width + kLaneSeparationDistance) {
405 AERROR << "waypoint is too far to reach: " << dist;
406 return false;
407 }
408 } else { // waypoint at left side
409 if (dist >
410 waypoint_right_width + segment_left_width + kLaneSeparationDistance) {
411 AERROR << "waypoint is too far to reach: " << dist;
412 return false;
413 }
414 }
415
416 return true;
417}
418
419} // namespace hdmap
420} // namespace apollo
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
std::string DebugString() const
Returns a human-readable string representing this object
Definition vec2d.cc:125
void SetId(const std::string &id)
bool GetWaypoint(const double s, LaneWaypoint *waypoint) const
bool Stitch(const RouteSegments &other)
Stitch current route segments with the other route segment.
void SetStopForDestination(bool stop_for_destination)
bool Shrink(const common::math::Vec2d &point, const double look_backward, const double look_forward)
bool IsWaypointOnSegment(const LaneWaypoint &waypoint) const
Check if a waypoint is on segment
const std::string & Id() const
LaneWaypoint LastWaypoint() const
Get the last waypoint from the lane segments.
bool IsConnectedSegment(const RouteSegments &other) const
Check if we can reach the other segment from current segment just by following lane.
void SetIsNeighborSegment(bool is_neighbor)
void SetProperties(const RouteSegments &other)
Copy the properties of other segments to current one
LaneWaypoint FirstWaypoint() const
Get the first waypoint from the lane segments.
bool CanExit() const
Whether the passage region that generate this route segment can lead to another passage region in rou...
void SetRouteEndWaypoint(const LaneWaypoint &waypoint)
void SetIsOnSegment(bool on_segment)
static bool WithinLaneSegment(const LaneSegment &lane_segment, const LaneWaypoint &waypoint)
bool CanDriveFrom(const LaneWaypoint &waypoint) const
Check whether the map allows a vehicle can reach current RouteSegment from a point on a lane (LaneWay...
void SetPreviousAction(routing::ChangeLaneType action)
routing::ChangeLaneType PreviousAction() const
Get the previous change lane action need to take by the vehicle to reach current segment,...
static double Length(const RouteSegments &segments)
const LaneWaypoint & RouteEndWaypoint() const
routing::ChangeLaneType NextAction() const
Get the next change lane action need to take by the vehicle, if the vehicle is on this RouteSegments.
bool GetProjection(const common::PointENU &point_enu, common::SLPoint *sl_point, LaneWaypoint *waypoint) const
Project a point to this route segment.
void SetCanExit(bool can_exit)
void SetNextAction(routing::ChangeLaneType action)
#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
class register implement
Definition arena_queue.h:37
LaneInfoConstPtr lane
Definition path.h:77
std::string DebugString() const
Definition path.cc:68
LaneInfoConstPtr lane
Definition path.h:44