Apollo 11.0
自动驾驶开放平台
obstacle_blocking_analyzer.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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
18
19#include <algorithm>
20#include <memory>
21#include <vector>
22#include <limits>
28
29namespace apollo {
30namespace planning {
31
34
35constexpr double kAdcDistanceThreshold = 35.0; // unit: m
36constexpr double kObstaclesDistanceThreshold = 15.0;
37constexpr double kIntersectionClearanceDist = 20.0;
38constexpr double kJunctionClearanceDist = 15.0;
39
40bool IsNonmovableObstacle(const ReferenceLineInfo& reference_line_info,
41 const Obstacle& obstacle) {
42 // Obstacle is far away.
43 const SLBoundary& adc_sl_boundary = reference_line_info.AdcSlBoundary();
44 if (obstacle.PerceptionSLBoundary().start_s() >
45 adc_sl_boundary.end_s() + kAdcDistanceThreshold) {
46 ADEBUG << " - It is too far ahead and we are not so sure of its status.";
47 return false;
48 }
49
50 // Obstacle is parked obstacle.
51 if (IsParkedVehicle(reference_line_info.reference_line(), &obstacle)) {
52 ADEBUG << "It is Parked and NON-MOVABLE.";
53 return true;
54 }
55
56 // Obstacle is blocked by others too.
57 for (const auto* other_obstacle :
58 reference_line_info.path_decision().obstacles().Items()) {
59 if (other_obstacle->Id() == obstacle.Id()) {
60 continue;
61 }
62 if (other_obstacle->IsVirtual()) {
63 continue;
64 }
65 if (other_obstacle->Perception().type() !=
67 continue;
68 }
69 const auto& other_boundary = other_obstacle->PerceptionSLBoundary();
70 const auto& this_boundary = obstacle.PerceptionSLBoundary();
71 if (other_boundary.start_l() > this_boundary.end_l() ||
72 other_boundary.end_l() < this_boundary.start_l()) {
73 // not blocking the backside vehicle
74 continue;
75 }
76 double delta_s = other_boundary.start_s() - this_boundary.end_s();
77 if (delta_s < 0.0 || delta_s > kObstaclesDistanceThreshold) {
78 continue;
79 }
80 return false;
81 }
82 ADEBUG << "IT IS NON-MOVABLE!";
83 return true;
84}
85
86// This is the side-pass condition for every obstacle.
87// TODO(all): if possible, transform as many function parameters into GFLAGS.
88bool IsBlockingObstacleToSidePass(const Frame& frame, const Obstacle* obstacle,
89 double block_obstacle_min_speed,
90 double min_front_sidepass_distance,
91 bool enable_obstacle_blocked_check) {
92 // Get the necessary info.
93 const auto& reference_line_info = frame.reference_line_info().front();
94 const auto& reference_line = reference_line_info.reference_line();
95 const SLBoundary& adc_sl_boundary = reference_line_info.AdcSlBoundary();
96 const PathDecision& path_decision = reference_line_info.path_decision();
97 ADEBUG << "Evaluating Obstacle: " << obstacle->Id();
98
99 // Obstacle is virtual.
100 if (obstacle->IsVirtual()) {
101 ADEBUG << " - It is virtual.";
102 return false;
103 }
104
105 // Obstacle is moving.
106 if (!obstacle->IsStatic() || obstacle->speed() > block_obstacle_min_speed) {
107 ADEBUG << " - It is non-static.";
108 return false;
109 }
110
111 // Obstacle is behind ADC.
112 if (obstacle->PerceptionSLBoundary().start_s() <= adc_sl_boundary.end_s()) {
113 ADEBUG << " - It is behind ADC.";
114 return false;
115 }
116
117 // Obstacle is far away.
118 static constexpr double kAdcDistanceSidePassThreshold = 15.0;
119 if (obstacle->PerceptionSLBoundary().start_s() >
120 adc_sl_boundary.end_s() + kAdcDistanceSidePassThreshold) {
121 ADEBUG << " - It is too far ahead.";
122 return false;
123 }
124
125 // Obstacle is too close.
126 if (adc_sl_boundary.end_s() + min_front_sidepass_distance >
127 obstacle->PerceptionSLBoundary().start_s()) {
128 ADEBUG << " - It is too close to side-pass.";
129 return false;
130 }
131
132 // Obstacle is not blocking our path.
133 if (!IsBlockingDrivingPathObstacle(reference_line, obstacle)) {
134 ADEBUG << " - It is not blocking our way.";
135 return false;
136 }
137
138 // Obstacle is blocked by others too.
139 if (enable_obstacle_blocked_check &&
140 !IsParkedVehicle(reference_line, obstacle)) {
141 for (const auto* other_obstacle : path_decision.obstacles().Items()) {
142 if (other_obstacle->Id() == obstacle->Id()) {
143 continue;
144 }
145 if (other_obstacle->IsVirtual()) {
146 continue;
147 }
148 if (other_obstacle->PerceptionSLBoundary().start_l() >
149 obstacle->PerceptionSLBoundary().end_l() ||
150 other_obstacle->PerceptionSLBoundary().end_l() <
151 obstacle->PerceptionSLBoundary().start_l()) {
152 // not blocking the backside vehicle
153 continue;
154 }
155 double delta_s = other_obstacle->PerceptionSLBoundary().start_s() -
156 obstacle->PerceptionSLBoundary().end_s();
157 if (delta_s < 0.0 || delta_s > kAdcDistanceThreshold) {
158 continue;
159 }
160
161 // TODO(All): Fix the segmentation bug for large vehicles, otherwise
162 // the follow line will be problematic.
163 ADEBUG << " - It is blocked by others, too.";
164 return false;
165 }
166 }
167
168 ADEBUG << "IT IS BLOCKING!";
169 return true;
170}
171
173 const Obstacle* obstacle) {
174 const auto& reference_line_info = frame.reference_line_info().front();
175 const SLBoundary& adc_sl_boundary = reference_line_info.AdcSlBoundary();
176 double distance_between_adc_and_obstacle =
177 obstacle->PerceptionSLBoundary().start_s() - adc_sl_boundary.end_s();
178 return distance_between_adc_and_obstacle;
179}
180
182 const Obstacle* obstacle) {
183 const double driving_width =
184 reference_line.GetDrivingWidth(obstacle->PerceptionSLBoundary());
185 const double adc_width =
186 VehicleConfigHelper::GetConfig().vehicle_param().width();
187 ADEBUG << " (driving width = " << driving_width
188 << ", adc_width = " << adc_width << ")";
189 if (driving_width > adc_width + FLAGS_static_obstacle_nudge_l_buffer +
190 FLAGS_side_pass_driving_width_l_buffer) {
191 // TODO(jiacheng): make this a GFLAG:
192 // side_pass_context_.scenario_config_.min_l_nudge_buffer()
193 ADEBUG << "It is NOT blocking our path.";
194 return false;
195 }
196
197 ADEBUG << "It is blocking our path.";
198 return true;
199}
200
201bool IsParkedVehicle(const ReferenceLine& reference_line,
202 const Obstacle* obstacle) {
203 if (!FLAGS_enable_scenario_side_pass_multiple_parked_obstacles) {
204 return false;
205 }
206 double road_left_width = 0.0;
207 double road_right_width = 0.0;
208 double max_road_right_width = 0.0;
209 reference_line.GetRoadWidth(obstacle->PerceptionSLBoundary().start_s(),
210 &road_left_width, &road_right_width);
211 max_road_right_width = road_right_width;
212 reference_line.GetRoadWidth(obstacle->PerceptionSLBoundary().end_s(),
213 &road_left_width, &road_right_width);
214 max_road_right_width = std::max(max_road_right_width, road_right_width);
215 bool is_at_road_edge = std::abs(obstacle->PerceptionSLBoundary().start_l()) >
216 max_road_right_width - 0.1;
217
218 std::vector<std::shared_ptr<const hdmap::LaneInfo>> lanes;
219 auto obstacle_box = obstacle->PerceptionBoundingBox();
221 common::util::PointFactory::ToPointENU(obstacle_box.center().x(),
222 obstacle_box.center().y()),
223 std::min(obstacle_box.width(), obstacle_box.length()), &lanes);
224 bool is_on_parking_lane = false;
225 if (lanes.size() == 1 &&
226 lanes.front()->lane().type() == apollo::hdmap::Lane::PARKING) {
227 is_on_parking_lane = true;
228 }
229
230 bool is_parked = is_on_parking_lane || is_at_road_edge;
231 return is_parked && obstacle->IsStatic();
232}
233
235 const ReferenceLineInfo& reference_line_info,
236 const std::string& blocking_obstacle_id) {
237 if (blocking_obstacle_id.empty()) {
238 ADEBUG << "There is no blocking obstacle.";
239 return true;
240 }
241 const Obstacle* blocking_obstacle =
242 reference_line_info.path_decision().obstacles().Find(
243 blocking_obstacle_id);
244 if (blocking_obstacle == nullptr) {
245 ADEBUG << "Blocking obstacle is no longer there.";
246 return true;
247 }
248
249 // Get blocking obstacle's s.
250 double blocking_obstacle_s =
251 blocking_obstacle->PerceptionSLBoundary().end_s();
252 ADEBUG << "Blocking obstacle is at s = " << blocking_obstacle_s;
253 // Get intersection's s and compare with threshold.
254 const auto& first_encountered_overlaps =
255 reference_line_info.FirstEncounteredOverlaps();
256 for (const auto& overlap : first_encountered_overlaps) {
257 ADEBUG << overlap.first << ", " << overlap.second.DebugString();
258 if (overlap.first != ReferenceLineInfo::SIGNAL &&
259 overlap.first != ReferenceLineInfo::STOP_SIGN) {
260 continue;
261 }
262
263 auto distance = overlap.second.start_s - blocking_obstacle_s;
264 if (overlap.first == ReferenceLineInfo::SIGNAL ||
265 overlap.first == ReferenceLineInfo::STOP_SIGN) {
266 if (distance < kIntersectionClearanceDist) {
267 ADEBUG << "Too close to signal intersection (" << distance
268 << "m); don't SIDE_PASS.";
269 return false;
270 }
271 } else {
272 if (distance < kJunctionClearanceDist) {
273 ADEBUG << "Too close to overlap_type[" << overlap.first << "] ("
274 << distance << "m); don't SIDE_PASS";
275 return false;
276 }
277 }
278 }
279
280 return true;
281}
282
284 const ReferenceLineInfo& reference_line_info,
285 const std::string& blocking_obstacle_id) {
286 if (blocking_obstacle_id.empty()) {
287 ADEBUG << "There is no blocking obstacle.";
288 return true;
289 }
290 const Obstacle* blocking_obstacle =
291 reference_line_info.path_decision().obstacles().Find(
292 blocking_obstacle_id);
293 if (blocking_obstacle == nullptr) {
294 ADEBUG << "Blocking obstacle is no longer there.";
295 return true;
296 }
297
298 // Get blocking obstacle's s.
299 double blocking_obstacle_s =
300 blocking_obstacle->PerceptionSLBoundary().end_s();
301 double min_distance = std::numeric_limits<double>::max();
302 ADEBUG << "Blocking obstacle is at s = " << blocking_obstacle_s;
303 // Get intersection's s and compare with threshold.
304 const auto& first_encountered_overlaps =
305 reference_line_info.FirstEncounteredOverlaps();
306 for (const auto& overlap : first_encountered_overlaps) {
307 ADEBUG << overlap.first << ", " << overlap.second.DebugString();
308 if (overlap.first != ReferenceLineInfo::SIGNAL &&
309 overlap.first != ReferenceLineInfo::STOP_SIGN) {
310 continue;
311 }
312 min_distance =
313 std::min(min_distance, overlap.second.start_s - blocking_obstacle_s);
314 }
315
316 return min_distance;
317}
318
320 const ReferenceLineInfo& reference_line_info,
321 const std::string& blocking_obstacle_id) {
322 if (blocking_obstacle_id.empty()) {
323 ADEBUG << "There is no blocking obstacle.";
324 return true;
325 }
326 const Obstacle* blocking_obstacle =
327 reference_line_info.path_decision().obstacles().Find(
328 blocking_obstacle_id);
329 if (blocking_obstacle == nullptr) {
330 ADEBUG << "Blocking obstacle is no longer there.";
331 return true;
332 }
333
334 // Get blocking obstacle's s.
335 double blocking_obstacle_start_s =
336 blocking_obstacle->PerceptionSLBoundary().start_s();
337 double blocking_obstacle_end_s =
338 blocking_obstacle->PerceptionSLBoundary().end_s();
339 double min_distance = std::numeric_limits<double>::max();
340 AINFO << "Blocking obstacle start s = " << blocking_obstacle_start_s
341 << ", end_s: " << blocking_obstacle_end_s;
342 // Get intersection's s and compare with threshold.
343 const auto& first_encountered_overlaps =
344 reference_line_info.FirstEncounteredOverlaps();
345 for (const auto& overlap :
346 reference_line_info.reference_line().map_path().junction_overlaps()) {
347 AINFO << overlap.DebugString();
348 double distance = std::numeric_limits<double>::max();
349 if ((blocking_obstacle_start_s >= overlap.start_s &&
350 blocking_obstacle_start_s <= overlap.end_s) ||
351 (blocking_obstacle_end_s >= overlap.start_s &&
352 blocking_obstacle_end_s <= overlap.end_s)) {
353 distance = 0.0;
354 } else if (blocking_obstacle_end_s < overlap.start_s) {
355 distance = overlap.start_s - blocking_obstacle_end_s;
356 } else {
357 distance = blocking_obstacle_start_s - overlap.end_s;
358 }
359 min_distance = std::min(min_distance, distance);
360 }
361
362 return min_distance;
363}
364
366 const ReferenceLineInfo& reference_line_info,
367 const std::string& blocking_obstacle_id, const double threshold) {
368 if (blocking_obstacle_id.empty()) {
369 ADEBUG << "There is no blocking obstacle.";
370 return true;
371 }
372 const Obstacle* blocking_obstacle =
373 reference_line_info.path_decision().obstacles().Find(
374 blocking_obstacle_id);
375 if (blocking_obstacle == nullptr) {
376 ADEBUG << "Blocking obstacle is no longer there.";
377 return true;
378 }
379
380 double blocking_obstacle_s =
381 blocking_obstacle->PerceptionSLBoundary().start_s();
382 double adc_end_s = reference_line_info.AdcSlBoundary().end_s();
383 ADEBUG << "Blocking obstacle is at s = " << blocking_obstacle_s;
384 ADEBUG << "ADC is at s = " << adc_end_s;
385 ADEBUG << "Destination is at s = "
386 << reference_line_info.SDistanceToDestination() + adc_end_s;
387 if (blocking_obstacle_s - adc_end_s + threshold >
388 reference_line_info.SDistanceToDestination()) {
389 return false;
390 }
391 return true;
392}
393
394} // namespace planning
395} // namespace apollo
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
static PointENU ToPointENU(const double x, const double y, const double z=0)
static const HDMap * BaseMapPtr()
int GetLanes(const apollo::common::PointENU &point, double distance, std::vector< LaneInfoConstPtr > *lanes) const
get all lanes in certain range
Definition hdmap.cc:90
const std::vector< PathOverlap > & junction_overlaps() const
Definition path.h:313
Frame holds all data for one planning cycle.
Definition frame.h:62
const std::list< ReferenceLineInfo > & reference_line_info() const
Definition frame.cc:123
T * Find(const I id)
Find object by id in the container
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
const std::string & Id() const
Definition obstacle.h:75
const SLBoundary & PerceptionSLBoundary() const
Definition obstacle.cc:694
double speed() const
Definition obstacle.h:78
const common::math::Box2d & PerceptionBoundingBox() const
Definition obstacle.h:90
PathDecision represents all obstacle decisions on one path.
const IndexedList< std::string, Obstacle > & obstacles() const
ReferenceLineInfo holds all data for one reference line.
const ReferenceLine & reference_line() const
const std::vector< std::pair< OverlapType, hdmap::PathOverlap > > & FirstEncounteredOverlaps() const
const SLBoundary & AdcSlBoundary() const
const hdmap::Path & map_path() const
double GetDrivingWidth(const SLBoundary &sl_boundary) const
bool GetRoadWidth(const double s, double *const road_left_width, double *const road_right_width) const
Planning module main class.
#define ADEBUG
Definition log.h:41
#define AINFO
Definition log.h:42
bool IsBlockingObstacleToSidePass(const Frame &frame, const Obstacle *obstacle, double block_obstacle_min_speed, double min_front_sidepass_distance, bool enable_obstacle_blocked_check)
Decide whether an obstacle is a blocking one that needs to be side-passed.
constexpr double kAdcDistanceThreshold
bool IsBlockingObstacleWithinDestination(const ReferenceLineInfo &reference_line_info, const std::string &blocking_obstacle_id, const double threshold)
double DistanceBlockingObstacleToJunction(const ReferenceLineInfo &reference_line_info, const std::string &blocking_obstacle_id)
constexpr double kJunctionClearanceDist
constexpr double kIntersectionClearanceDist
double DistanceBlockingObstacleToIntersection(const ReferenceLineInfo &reference_line_info, const std::string &blocking_obstacle_id)
constexpr double kObstaclesDistanceThreshold
bool IsNonmovableObstacle(const ReferenceLineInfo &reference_line_info, const Obstacle &obstacle)
bool IsBlockingDrivingPathObstacle(const ReferenceLine &reference_line, const Obstacle *obstacle)
double GetDistanceBetweenADCAndObstacle(const Frame &frame, const Obstacle *obstacle)
bool IsParkedVehicle(const ReferenceLine &reference_line, const Obstacle *obstacle)
bool IsBlockingObstacleFarFromIntersection(const ReferenceLineInfo &reference_line_info, const std::string &blocking_obstacle_id)
class register implement
Definition arena_queue.h:37