Apollo 11.0
自动驾驶开放平台
navi_obstacle_decider.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
23
24#include <algorithm>
25#include <limits>
26#include <utility>
27
28#include "cyber/common/log.h"
33
34namespace apollo {
35namespace planning {
36
40
41namespace {
42constexpr double kEpislon = 1e-6;
43} // namespace
44
46
48 config_ = config.navi_obstacle_decider_config();
49 return true;
50}
51
52double NaviObstacleDecider::GetMinLaneWidth(
53 const std::vector<common::PathPoint>& path_data_points,
54 const ReferenceLine& reference_line) {
55 double min_lane_width = std::numeric_limits<double>::max();
56 double lane_left_width = 0.0;
57 double lane_right_width = 0.0;
58 for (const auto& path_data_point : path_data_points) {
59 bool ret = reference_line.GetLaneWidth(path_data_point.s(),
60 &lane_left_width, &lane_right_width);
61 if (ret) {
62 double lane_width = lane_left_width + lane_right_width;
63 if (lane_width < min_lane_width) {
64 min_lane_width = lane_width;
65 }
66 }
67 }
68 return min_lane_width;
69}
70
71void NaviObstacleDecider::AddObstacleOffsetDirection(
72 const common::PathPoint& projection_point,
73 const std::vector<common::PathPoint>& path_data_points,
74 const Obstacle* current_obstacle, const double proj_len, double* dist) {
75 Vec2d p1(projection_point.x(), projection_point.y());
76 Vec2d p2(0.0, 0.0);
77 if ((proj_len + 1) > path_data_points.back().s()) {
78 p2.set_x(path_data_points.back().x());
79 p2.set_y(path_data_points.back().y());
80 } else {
81 auto point = PathMatcher::MatchToPath(path_data_points, (proj_len + 1));
82 p2.set_x(point.x());
83 p2.set_y(point.y());
84 }
85 auto d = ((current_obstacle->Perception().position().x() - p1.x()) *
86 (p2.y() - p1.y())) -
87 ((current_obstacle->Perception().position().y() - p1.y()) *
88 (p2.x() - p1.x()));
89 if (d > 0) {
90 *dist = *dist * -1;
91 }
92}
93
94bool NaviObstacleDecider::IsNeedFilterObstacle(
95 const Obstacle* current_obstacle, const PathPoint& vehicle_projection_point,
96 const std::vector<common::PathPoint>& path_data_points,
97 const common::VehicleState& vehicle_state,
98 PathPoint* projection_point_ptr) {
99 bool is_filter = true;
100 *projection_point_ptr = PathMatcher::MatchToPath(
101 path_data_points, current_obstacle->Perception().position().x(),
102 current_obstacle->Perception().position().y());
103 ADEBUG << "obstacle distance : " << projection_point_ptr->s()
104 << "vehicle distance : " << vehicle_projection_point.s();
105 if ((projection_point_ptr->s() - vehicle_projection_point.s()) >
106 (config_.judge_dis_coeff() * vehicle_state.linear_velocity() +
107 config_.basis_dis_value())) {
108 return is_filter;
109 }
110 double vehicle_frontedge_position =
111 vehicle_projection_point.s() + VehicleParam().length();
112 double vehicle_backedge_position = vehicle_projection_point.s();
113
114 double obstacle_start_position =
115 projection_point_ptr->s() - current_obstacle->Perception().length() / 2.0;
116 double obstacle_end_position =
117 projection_point_ptr->s() + current_obstacle->Perception().length() / 2.0;
118 if ((vehicle_backedge_position - obstacle_end_position) >
119 config_.safe_distance()) {
120 return is_filter;
121 }
122 if ((obstacle_start_position - vehicle_frontedge_position) >
123 config_.safe_distance()) {
124 if (!current_obstacle->IsStatic()) {
125 if (current_obstacle->Perception().velocity().x() > 0.0) {
126 return is_filter;
127 }
128 }
129 }
130 is_filter = false;
131 return is_filter;
132}
133
134void NaviObstacleDecider::ProcessObstacle(
135 const std::vector<const Obstacle*>& obstacles,
136 const std::vector<common::PathPoint>& path_data_points,
137 const PathDecision& path_decision, const double min_lane_width,
138 const common::VehicleState& vehicle_state) {
139 auto func_distance = [](const PathPoint& point, const double x,
140 const double y) {
141 double dx = point.x() - x;
142 double dy = point.y() - y;
143 return sqrt(dx * dx + dy * dy);
144 };
145
146 PathPoint projection_point;
147 PathPoint vehicle_projection_point =
148 PathMatcher::MatchToPath(path_data_points, 0, 0);
149 for (const auto& current_obstacle : obstacles) {
150 bool is_continue = IsNeedFilterObstacle(
151 current_obstacle, vehicle_projection_point, path_data_points,
152 vehicle_state, &projection_point);
153 if (is_continue) {
154 continue;
155 }
156 auto dist = func_distance(projection_point,
157 current_obstacle->Perception().position().x(),
158 current_obstacle->Perception().position().y());
159
160 if (dist <
161 (config_.max_nudge_distance() + current_obstacle->Perception().width() +
162 VehicleParam().left_edge_to_center())) {
163 auto proj_len = projection_point.s();
164 if (std::fabs(proj_len) <= kEpislon ||
165 proj_len >= path_data_points.back().s()) {
166 continue;
167 }
168 AddObstacleOffsetDirection(projection_point, path_data_points,
169 current_obstacle, proj_len, &dist);
170 obstacle_lat_dist_.emplace(std::pair<double, double>(
171 current_obstacle->Perception().width(), dist));
172 }
173 }
174}
175
176double NaviObstacleDecider::GetObstacleActualOffsetDistance(
177 std::map<double, double>::iterator iter, const double right_nudge_lane,
178 const double left_nudge_lane, int* lane_obstacles_num) {
179 auto obs_width = iter->first;
180 auto lat_dist = iter->second;
181 ADEBUG << "get obstacle width : " << obs_width
182 << "get latitude distance : " << lat_dist;
183 auto actual_dist = std::fabs(lat_dist) - obs_width / 2.0 -
184 VehicleParam().left_edge_to_center();
185
186 if (last_nudge_dist_ > 0) {
187 if (lat_dist < 0) {
188 if (actual_dist < std::fabs(right_nudge_lane) + config_.safe_distance()) {
189 *lane_obstacles_num = *lane_obstacles_num + 1;
190 }
191 }
192 } else if (last_nudge_dist_ < 0) {
193 if (lat_dist > 0) {
194 if (actual_dist < std::fabs(left_nudge_lane) + config_.safe_distance()) {
195 *lane_obstacles_num = *lane_obstacles_num + 1;
196 }
197 }
198 }
199
200 if ((last_lane_obstacles_num_ != 0) && (*lane_obstacles_num == 0) &&
201 (!is_obstacle_stable_)) {
202 is_obstacle_stable_ = true;
203 statist_count_ = 0;
204 ADEBUG << "begin keep obstacles";
205 }
206
207 if (is_obstacle_stable_) {
208 ++statist_count_;
209 if (statist_count_ > config_.cycles_number()) {
210 is_obstacle_stable_ = false;
211 } else {
212 *lane_obstacles_num = last_lane_obstacles_num_;
213 }
214 ADEBUG << "statist_count_ : " << statist_count_;
215 }
216 last_lane_obstacles_num_ = *lane_obstacles_num;
217 ADEBUG << "last_nudge_dist : " << last_nudge_dist_
218 << "lat_dist : " << lat_dist << "actual_dist : " << actual_dist;
219 return actual_dist;
220}
221
222void NaviObstacleDecider::RecordLastNudgeDistance(const double nudge_dist) {
223 double tolerance = config_.nudge_allow_tolerance();
224
225 if (std::fabs(nudge_dist) > tolerance) {
226 if (std::fabs(nudge_dist) > std::fabs(last_nudge_dist_)) {
227 last_nudge_dist_ = nudge_dist;
228 }
229 no_nudge_num_ = 0;
230 } else {
231 ++no_nudge_num_;
232 }
233
234 if (no_nudge_num_ >= config_.cycles_number()) {
235 last_nudge_dist_ = 0.0;
236 }
237}
238
239void NaviObstacleDecider::SmoothNudgeDistance(
240 const common::VehicleState& vehicle_state, double* nudge_dist) {
241 CHECK_NOTNULL(nudge_dist);
242 if (vehicle_state.linear_velocity() < config_.max_allow_nudge_speed()) {
243 ++limit_speed_num_;
244 } else {
245 limit_speed_num_ = 0;
246 }
247 if (limit_speed_num_ < config_.cycles_number()) {
248 *nudge_dist = 0;
249 }
250 if (std::fabs(*nudge_dist) > config_.nudge_allow_tolerance()) {
251 ++eliminate_clutter_num_;
252 } else {
253 eliminate_clutter_num_ = 0;
254 }
255 if (eliminate_clutter_num_ < config_.cycles_number()) {
256 *nudge_dist = 0;
257 }
258 ADEBUG << "eliminate_clutter_num_: " << eliminate_clutter_num_;
259}
260
262 const std::vector<const Obstacle*>& obstacles,
263 const ReferenceLine& reference_line, const PathDecision& path_decision,
264 const std::vector<common::PathPoint>& path_data_points,
265 const common::VehicleState& vehicle_state, int* lane_obstacles_num) {
266 CHECK_NOTNULL(lane_obstacles_num);
267
268 // Calculating the left and right nudgeable distance on the lane
269 double left_nudge_lane = 0.0;
270 double right_nudge_lane = 0.0;
271 double routing_y = path_data_points[0].y();
272 double min_lane_width = GetMinLaneWidth(path_data_points, reference_line);
273
274 ADEBUG << "get min_lane_width: " << min_lane_width;
275 if (routing_y <= 0.0) {
276 left_nudge_lane = min_lane_width / 2.0 - std::fabs(routing_y) -
277 VehicleParam().left_edge_to_center();
278 right_nudge_lane = -1.0 * (min_lane_width / 2.0 + std::fabs(routing_y) -
279 VehicleParam().right_edge_to_center());
280 } else {
281 left_nudge_lane = min_lane_width / 2.0 + std::fabs(routing_y) -
282 VehicleParam().left_edge_to_center();
283 right_nudge_lane = -1.0 * (min_lane_width / 2.0 - std::fabs(routing_y) -
284 VehicleParam().right_edge_to_center());
285 }
286
287 // Calculating the left and right nudgable distance according to the
288 // position of the obstacle.
289 double left_nudge_obstacle = 0.0;
290 double right_nudge_obstacle = 0.0;
291
292 // Calculation of the number of current Lane obstacles
293 obstacle_lat_dist_.clear();
294 ProcessObstacle(obstacles, path_data_points, path_decision, min_lane_width,
295 vehicle_state);
296 for (auto iter = obstacle_lat_dist_.begin(); iter != obstacle_lat_dist_.end();
297 ++iter) {
298 auto actual_dist = GetObstacleActualOffsetDistance(
299 iter, right_nudge_lane, left_nudge_lane, lane_obstacles_num);
300 auto lat_dist = iter->second;
301 if (actual_dist > config_.min_nudge_distance() &&
302 actual_dist < config_.max_nudge_distance()) {
303 auto need_nudge_dist = config_.max_nudge_distance() - actual_dist;
304 if (lat_dist >= 0.0) {
305 right_nudge_obstacle =
306 -1.0 * std::max(std::fabs(right_nudge_obstacle), need_nudge_dist);
307 } else {
308 left_nudge_obstacle =
309 std::max(std::fabs(left_nudge_obstacle), need_nudge_dist);
310 }
311 }
312 }
313 ADEBUG << "get left_nudge_lane: " << left_nudge_lane
314 << "get right_nudge_lane : " << right_nudge_lane
315 << "get left_nudge_obstacle: " << left_nudge_obstacle
316 << "get right_nudge_obstacle : " << right_nudge_obstacle;
317 // Get the appropriate value of the nudge distance
318 double nudge_dist = 0.0;
319 if (std::fabs(left_nudge_obstacle) > kEpislon &&
320 std::fabs(right_nudge_obstacle) <= kEpislon) {
321 nudge_dist = std::min(left_nudge_lane, left_nudge_obstacle);
322 } else if (std::fabs(right_nudge_obstacle) > kEpislon &&
323 std::fabs(left_nudge_obstacle) <= kEpislon) {
324 nudge_dist = std::max(right_nudge_lane, right_nudge_obstacle);
325 }
326
327 ADEBUG << "get nudge distance : " << nudge_dist
328 << "get lane_obstacles_num : " << *lane_obstacles_num;
329 RecordLastNudgeDistance(nudge_dist);
330 SmoothNudgeDistance(vehicle_state, &nudge_dist);
331 KeepNudgePosition(nudge_dist, lane_obstacles_num);
332 ADEBUG << "last nudge distance : " << nudge_dist;
333 return nudge_dist;
334}
335
336void NaviObstacleDecider::KeepNudgePosition(const double nudge_dist,
337 int* lane_obstacles_num) {
338 if (std::fabs(nudge_dist) > config_.nudge_allow_tolerance() &&
339 std::fabs(last_nudge_dist_) < config_.nudge_allow_tolerance() &&
340 !keep_nudge_flag_) {
341 cycles_count_ = 0;
342 keep_nudge_flag_ = true;
343 }
344 if (keep_nudge_flag_) {
345 ++cycles_count_;
346 if (cycles_count_ > config_.max_keep_nudge_cycles()) {
347 *lane_obstacles_num = 0;
348 keep_nudge_flag_ = false;
349 } else {
350 *lane_obstacles_num = 1;
351 }
352 }
353 ADEBUG << "get lane_obstacles_num : " << *lane_obstacles_num;
354}
355
357 const std::vector<common::PathPoint>& path_data_points,
358 const std::vector<const Obstacle*>& obstacles) {
359 // Find start point of the reference line.
360 double reference_line_y = path_data_points[0].y();
361
362 // Judging unsafed range according to the position of the reference line.
363 double unsafe_refline_pos_y = 0.0;
364 double unsafe_car_pos_y = 0.0;
365 std::pair<double, double> unsafe_range;
366 if (reference_line_y < 0.0) {
367 unsafe_refline_pos_y = reference_line_y -
368 VehicleParam().right_edge_to_center() -
370 unsafe_car_pos_y = VehicleParam().right_edge_to_center() +
372 unsafe_range = std::make_pair(unsafe_refline_pos_y, unsafe_car_pos_y);
373 } else {
374 unsafe_refline_pos_y = reference_line_y +
375 VehicleParam().left_edge_to_center() +
377 unsafe_car_pos_y = -1.0 * (VehicleParam().left_edge_to_center() +
379 unsafe_range = std::make_pair(unsafe_car_pos_y, unsafe_refline_pos_y);
380 }
381 // Get obstacles'ID.
382 unsafe_obstacle_info_.clear();
383 PathPoint vehicle_projection_point =
384 PathMatcher::MatchToPath(path_data_points, 0, 0);
385 for (const auto& iter : obstacles) {
386 const double obstacle_y = iter->Perception().position().y();
387 if ((obstacle_y > unsafe_range.first && obstacle_y < unsafe_range.second) ||
388 std::abs(iter->Perception().velocity().y()) >
389 config_.lateral_velocity_value()) {
390 auto projection_point = PathMatcher::MatchToPath(
391 path_data_points, iter->Perception().position().x(), obstacle_y);
392 if (vehicle_projection_point.s() >= projection_point.s()) {
393 continue;
394 }
395 auto front_distance =
396 (projection_point.s() - iter->Perception().length() / 2.0) -
397 vehicle_projection_point.s();
398 auto ref_theta = projection_point.theta();
399 auto project_velocity =
400 iter->Perception().velocity().x() * std::cos(ref_theta) +
401 iter->Perception().velocity().y() * std::sin(ref_theta);
402 ADEBUG << "Lateral speed : " << iter->Perception().velocity().y();
403 unsafe_obstacle_info_.emplace_back(iter->Id(), front_distance,
404 project_velocity);
405 }
406 }
407}
408} // namespace planning
409} // namespace apollo
static PathPoint MatchToPath(const std::vector< PathPoint > &reference_line, const double x, const double y)
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
bool Init(const PlannerNaviConfig &config) override
Initialization parameters
void GetUnsafeObstaclesInfo(const std::vector< common::PathPoint > &path_data_points, const std::vector< const Obstacle * > &obstacles)
get the unsafe obstacles between trajectory and reference line.
double GetNudgeDistance(const std::vector< const Obstacle * > &obstacles, const ReferenceLine &reference_line, const PathDecision &path_decision, const std::vector< common::PathPoint > &path_data_points, const common::VehicleState &vehicle_state, int *lane_obstacles_num)
get the actual nudgable distance according to the position of the obstacle
PathDecision represents all obstacle decisions on one path.
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
Planning module main class.
Define the LineSegment2d class.
Linear interpolation functions.
#define ADEBUG
Definition log.h:41
class register implement
Definition arena_queue.h:37
This file provides the declaration of the class "NaviSpeedDecider".
optional NaviObstacleDeciderConfig navi_obstacle_decider_config