Apollo 11.0
自动驾驶开放平台
collision_checker.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 <utility>
24
25#include "modules/common_msgs/prediction_msgs/prediction_obstacle.pb.h"
26
27#include "cyber/common/log.h"
32
33namespace apollo {
34namespace planning {
35
41
43 const std::vector<const Obstacle*>& obstacles, const double ego_vehicle_s,
44 const double ego_vehicle_d,
45 const std::vector<PathPoint>& discretized_reference_line,
46 const ReferenceLineInfo* ptr_reference_line_info,
47 const std::shared_ptr<PathTimeGraph>& ptr_path_time_graph) {
48 ptr_reference_line_info_ = ptr_reference_line_info;
49 ptr_path_time_graph_ = ptr_path_time_graph;
50 BuildPredictedEnvironment(obstacles, ego_vehicle_s, ego_vehicle_d,
51 discretized_reference_line);
52}
53
55 const std::vector<const Obstacle*>& obstacles,
56 const DiscretizedTrajectory& ego_trajectory, const double ego_length,
57 const double ego_width, const double ego_back_edge_to_center) {
58 for (size_t i = 0; i < ego_trajectory.NumOfPoints(); ++i) {
59 const auto& ego_point =
60 ego_trajectory.TrajectoryPointAt(static_cast<std::uint32_t>(i));
61 const auto relative_time = ego_point.relative_time();
62 const auto ego_theta = ego_point.path_point().theta();
63
64 Box2d ego_box({ego_point.path_point().x(), ego_point.path_point().y()},
65 ego_theta, ego_length, ego_width);
66
67 // correct the inconsistency of reference point and center point
68 // TODO(all): move the logic before constructing the ego_box
69 double shift_distance = ego_length / 2.0 - ego_back_edge_to_center;
70 Vec2d shift_vec(shift_distance * std::cos(ego_theta),
71 shift_distance * std::sin(ego_theta));
72 ego_box.Shift(shift_vec);
73
74 std::vector<Box2d> obstacle_boxes;
75 for (const auto obstacle : obstacles) {
76 auto obtacle_point = obstacle->GetPointAtTime(relative_time);
77 Box2d obstacle_box = obstacle->GetBoundingBox(obtacle_point);
78 if (ego_box.HasOverlap(obstacle_box)) {
79 return true;
80 }
81 }
82 }
83 return false;
84}
85
87 const DiscretizedTrajectory& discretized_trajectory) {
88 CHECK_LE(discretized_trajectory.NumOfPoints(),
89 predicted_bounding_rectangles_.size());
90 const auto& vehicle_config =
91 common::VehicleConfigHelper::Instance()->GetConfig();
92 double ego_length = vehicle_config.vehicle_param().length();
93 double ego_width = vehicle_config.vehicle_param().width();
94
95 for (size_t i = 0; i < discretized_trajectory.NumOfPoints(); ++i) {
96 const auto& trajectory_point =
97 discretized_trajectory.TrajectoryPointAt(static_cast<std::uint32_t>(i));
98 double ego_theta = trajectory_point.path_point().theta();
99 Box2d ego_box(
100 {trajectory_point.path_point().x(), trajectory_point.path_point().y()},
101 ego_theta, ego_length, ego_width);
102 double shift_distance =
103 ego_length / 2.0 - vehicle_config.vehicle_param().back_edge_to_center();
104 Vec2d shift_vec{shift_distance * std::cos(ego_theta),
105 shift_distance * std::sin(ego_theta)};
106 ego_box.Shift(shift_vec);
107
108 for (const auto& obstacle_box : predicted_bounding_rectangles_[i]) {
109 if (ego_box.HasOverlap(obstacle_box)) {
110 return true;
111 }
112 }
113 }
114 return false;
115}
116
117void CollisionChecker::BuildPredictedEnvironment(
118 const std::vector<const Obstacle*>& obstacles, const double ego_vehicle_s,
119 const double ego_vehicle_d,
120 const std::vector<PathPoint>& discretized_reference_line) {
121 ACHECK(predicted_bounding_rectangles_.empty());
122
123 // If the ego vehicle is in lane,
124 // then, ignore all obstacles from the same lane.
125 bool ego_vehicle_in_lane = IsEgoVehicleInLane(ego_vehicle_s, ego_vehicle_d);
126 std::vector<const Obstacle*> obstacles_considered;
127 for (const Obstacle* obstacle : obstacles) {
128 if (obstacle->IsVirtual()) {
129 continue;
130 }
131 if (ego_vehicle_in_lane &&
132 (IsObstacleBehindEgoVehicle(obstacle, ego_vehicle_s,
133 discretized_reference_line) ||
134 !ptr_path_time_graph_->IsObstacleInGraph(obstacle->Id()))) {
135 continue;
136 }
137
138 obstacles_considered.push_back(obstacle);
139 }
140
141 double relative_time = 0.0;
142 while (relative_time < FLAGS_trajectory_time_length) {
143 std::vector<Box2d> predicted_env;
144 for (const Obstacle* obstacle : obstacles_considered) {
145 // If an obstacle has no trajectory, it is considered as static.
146 // Obstacle::GetPointAtTime has handled this case.
147 TrajectoryPoint point = obstacle->GetPointAtTime(relative_time);
148 Box2d box = obstacle->GetBoundingBox(point);
149 box.LongitudinalExtend(2.0 * FLAGS_lon_collision_buffer);
150 box.LateralExtend(2.0 * FLAGS_lat_collision_buffer);
151 predicted_env.push_back(std::move(box));
152 }
153 predicted_bounding_rectangles_.push_back(std::move(predicted_env));
154 relative_time += FLAGS_trajectory_time_resolution;
155 }
156}
157
158bool CollisionChecker::IsEgoVehicleInLane(const double ego_vehicle_s,
159 const double ego_vehicle_d) {
160 double left_width = FLAGS_default_reference_line_width * 0.5;
161 double right_width = FLAGS_default_reference_line_width * 0.5;
162 ptr_reference_line_info_->reference_line().GetLaneWidth(
163 ego_vehicle_s, &left_width, &right_width);
164 return ego_vehicle_d < left_width && ego_vehicle_d > -right_width;
165}
166
167bool CollisionChecker::IsObstacleBehindEgoVehicle(
168 const Obstacle* obstacle, const double ego_vehicle_s,
169 const std::vector<PathPoint>& discretized_reference_line) {
170 double half_lane_width = FLAGS_default_reference_line_width * 0.5;
171 TrajectoryPoint point = obstacle->GetPointAtTime(0.0);
172 auto obstacle_reference_line_position = PathMatcher::GetPathFrenetCoordinate(
173 discretized_reference_line, point.path_point().x(),
174 point.path_point().y());
175
176 if (obstacle_reference_line_position.first < ego_vehicle_s &&
177 std::fabs(obstacle_reference_line_position.second) < half_lane_width) {
178 ADEBUG << "Ignore obstacle [" << obstacle->Id() << "]";
179 return true;
180 }
181 return false;
182}
183
184} // namespace planning
185} // namespace apollo
Rectangular (undirected) bounding box in 2-D.
Definition box2d.h:52
static std::pair< double, double > GetPathFrenetCoordinate(const std::vector< PathPoint > &reference_line, const double x, const double y)
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
CollisionChecker(const std::vector< const Obstacle * > &obstacles, const double ego_vehicle_s, const double ego_vehicle_d, const std::vector< common::PathPoint > &discretized_reference_line, const ReferenceLineInfo *ptr_reference_line_info, const std::shared_ptr< PathTimeGraph > &ptr_path_time_graph)
bool InCollision(const DiscretizedTrajectory &discretized_trajectory)
const common::TrajectoryPoint & TrajectoryPointAt(const size_t index) const
This is the class that associates an Obstacle with its path properties.
Definition obstacle.h:62
ReferenceLineInfo holds all data for one reference line.
const ReferenceLine & reference_line() const
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
class register implement
Definition arena_queue.h:37
Defines the Vec2d class.