Apollo 11.0
自动驾驶开放平台
interaction_predictor.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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 <limits>
21#include <memory>
22#include <string>
23
24#include "modules/common/adapters/proto/adapter_config.pb.h"
25
33
34namespace apollo {
35namespace prediction {
36
41
45
47 const ADCTrajectoryContainer* adc_trajectory_container, Obstacle* obstacle,
48 ObstaclesContainer* obstacles_container) {
49 Clear();
50 CHECK_NOTNULL(obstacle);
51 CHECK_GT(obstacle->history_size(), 0U);
52
53 BuildADCTrajectory(adc_trajectory_container,
54 FLAGS_collision_cost_time_resolution);
55
57
58 Feature* feature_ptr = obstacle->mutable_latest_feature();
59
60 if (!feature_ptr->lane().has_lane_graph()) {
61 AERROR << "Obstacle [" << obstacle->id() << "] has no lane graph.";
62 return false;
63 }
64 auto* lane_graph = feature_ptr->mutable_lane()->mutable_lane_graph();
65
66 int num_lane_sequence = lane_graph->lane_sequence_size();
67 std::vector<double> best_lon_accelerations(num_lane_sequence, 0.0);
68 std::vector<double> candidate_lon_accelerations = {0.0, -0.5, -1.0, -1.5,
69 -2.0, -2.5, -3.0};
70 double smallest_cost = std::numeric_limits<double>::max();
71 std::vector<double> posteriors(num_lane_sequence, 0.0);
72 double posterior_sum = 0.0;
73 for (int i = 0; i < num_lane_sequence; ++i) {
74 const LaneSequence& lane_sequence = lane_graph->lane_sequence(i);
75 for (const double lon_acceleration : candidate_lon_accelerations) {
76 double cost = ComputeTrajectoryCost(
77 *obstacle, lane_sequence, lon_acceleration, adc_trajectory_container);
78 if (cost < smallest_cost) {
79 smallest_cost = cost;
80 best_lon_accelerations[i] = lon_acceleration;
81 }
82 }
83
84 double likelihood = ComputeLikelihood(smallest_cost);
85 double prior = lane_sequence.probability();
86 double posterior = ComputePosterior(prior, likelihood);
87 posteriors[i] = posterior;
88 posterior_sum += posterior;
89 }
90
91 int best_seq_idx = 0;
92 double largest_posterior = 0.0;
93 CHECK_EQ(posteriors.size(),
94 static_cast<size_t>(lane_graph->lane_sequence_size()));
95 for (int i = 0; i < num_lane_sequence; ++i) {
96 double normalized_posterior =
97 posteriors[i] / (posterior_sum + FLAGS_double_precision);
98 lane_graph->mutable_lane_sequence(i)->set_probability(normalized_posterior);
99 if (normalized_posterior > largest_posterior) {
100 largest_posterior = normalized_posterior;
101 best_seq_idx = i;
102 }
103 }
104
105 double probability_threshold = 0.5;
106 if (largest_posterior > probability_threshold) {
107 for (int i = 0; i < num_lane_sequence; ++i) {
108 const LaneSequence& lane_sequence = lane_graph->lane_sequence(i);
109 if (lane_sequence.probability() < probability_threshold) {
110 continue;
111 }
112 double best_lon_acceleration = best_lon_accelerations[i];
113 if (lane_sequence.has_stop_sign()) {
114 double stop_acceleration = 0.0;
115 double stop_distance = lane_sequence.stop_sign().lane_sequence_s() -
116 lane_sequence.lane_s();
117 SupposedToStop(*feature_ptr, stop_distance, &stop_acceleration);
118 best_lon_acceleration =
119 std::min(best_lon_acceleration, stop_acceleration);
120 }
121 std::vector<TrajectoryPoint> points;
122 DrawTrajectory(*obstacle, lane_sequence, best_lon_acceleration,
123 FLAGS_prediction_trajectory_time_length,
124 FLAGS_prediction_trajectory_time_resolution, &points);
125 Trajectory trajectory = GenerateTrajectory(points);
126 obstacle->mutable_latest_feature()->add_predicted_trajectory()->CopyFrom(
127 trajectory);
128 }
129 } else {
130 const LaneSequence& sequence = lane_graph->lane_sequence(best_seq_idx);
131 double best_lon_acceleration = best_lon_accelerations[best_seq_idx];
132 if (sequence.has_stop_sign()) {
133 double stop_distance =
134 sequence.stop_sign().lane_sequence_s() - sequence.lane_s();
135 SupposedToStop(*feature_ptr, stop_distance, &best_lon_acceleration);
136 }
137 std::vector<TrajectoryPoint> points;
138 DrawTrajectory(*obstacle, lane_graph->lane_sequence(best_seq_idx),
139 best_lon_acceleration,
140 FLAGS_prediction_trajectory_time_length,
141 FLAGS_prediction_trajectory_time_resolution, &points);
142 Trajectory trajectory = GenerateTrajectory(points);
143 obstacle->mutable_latest_feature()->add_predicted_trajectory()->CopyFrom(
144 trajectory);
145 }
146 return true;
147}
148
149void InteractionPredictor::Clear() { Predictor::Clear(); }
150
151void InteractionPredictor::BuildADCTrajectory(
152 const ADCTrajectoryContainer* adc_trajectory_container,
153 const double time_resolution) {
154 if (adc_trajectory_container == nullptr) {
155 AERROR << "Null adc trajectory container";
156 return;
157 }
158 const auto& adc_trajectory = adc_trajectory_container->adc_trajectory();
159 double curr_timestamp = 0.0;
160 for (const TrajectoryPoint& point : adc_trajectory.trajectory_point()) {
161 if (point.relative_time() + FLAGS_double_precision > curr_timestamp) {
162 adc_trajectory_.push_back(point);
163 curr_timestamp += time_resolution;
164 }
165 }
166}
167
168bool InteractionPredictor::DrawTrajectory(
169 const Obstacle& obstacle, const LaneSequence& lane_sequence,
170 const double lon_acceleration, const double total_time, const double period,
171 std::vector<TrajectoryPoint>* trajectory_points) {
172 // Sanity check.
173 CHECK_NOTNULL(trajectory_points);
174 trajectory_points->clear();
175 const Feature& feature = obstacle.latest_feature();
176 if (!feature.has_position() || !feature.has_velocity() ||
177 !feature.position().has_x() || !feature.position().has_y()) {
178 AERROR << "Obstacle [" << obstacle.id()
179 << " is missing position or velocity";
180 return false;
181 }
182
183 Eigen::Vector2d position(feature.position().x(), feature.position().y());
184 double speed = feature.speed();
185
186 int lane_segment_index = 0;
187 std::string lane_id =
188 lane_sequence.lane_segment(lane_segment_index).lane_id();
189 std::shared_ptr<const LaneInfo> lane_info = PredictionMap::LaneById(lane_id);
190 double lane_s = 0.0;
191 double lane_l = 0.0;
192 if (!PredictionMap::GetProjection(position, lane_info, &lane_s, &lane_l)) {
193 AERROR << "Failed in getting lane s and lane l";
194 return false;
195 }
196 double approach_rate = FLAGS_go_approach_rate;
197 if (!lane_sequence.vehicle_on_lane()) {
198 approach_rate = FLAGS_cutin_approach_rate;
199 }
200 size_t total_num = static_cast<size_t>(total_time / period);
201 for (size_t i = 0; i < total_num; ++i) {
202 double relative_time = static_cast<double>(i) * period;
203 Eigen::Vector2d point;
204 double theta = M_PI;
205 if (!PredictionMap::SmoothPointFromLane(lane_id, lane_s, lane_l, &point,
206 &theta)) {
207 AERROR << "Unable to get smooth point from lane [" << lane_id
208 << "] with s [" << lane_s << "] and l [" << lane_l << "]";
209 break;
210 }
211 TrajectoryPoint trajectory_point;
212 PathPoint path_point;
213 path_point.set_x(point.x());
214 path_point.set_y(point.y());
215 path_point.set_z(0.0);
216 path_point.set_theta(theta);
217 path_point.set_lane_id(lane_id);
218 trajectory_point.mutable_path_point()->CopyFrom(path_point);
219 trajectory_point.set_v(speed);
220 trajectory_point.set_a(lon_acceleration);
221 trajectory_point.set_relative_time(relative_time);
222 trajectory_points->emplace_back(std::move(trajectory_point));
223
224 lane_s += std::max(
225 0.0, speed * period + 0.5 * lon_acceleration * period * period);
226 speed += lon_acceleration * period;
227
228 while (lane_s > PredictionMap::LaneById(lane_id)->total_length() &&
229 lane_segment_index + 1 < lane_sequence.lane_segment_size()) {
230 lane_segment_index += 1;
231 lane_s = lane_s - PredictionMap::LaneById(lane_id)->total_length();
232 lane_id = lane_sequence.lane_segment(lane_segment_index).lane_id();
233 }
234
235 lane_l *= approach_rate;
236 }
237
238 return true;
239}
240
241double InteractionPredictor::ComputeTrajectoryCost(
242 const Obstacle& obstacle, const LaneSequence& lane_sequence,
243 const double acceleration,
244 const ADCTrajectoryContainer* adc_trajectory_container) {
245 CHECK_GT(obstacle.history_size(), 0U);
246 double speed = obstacle.latest_feature().speed();
247 double total_cost = 0.0;
248
249 double lon_acc_cost = LongitudinalAccelerationCost(acceleration);
250 total_cost += FLAGS_longitudinal_acceleration_cost_weight * lon_acc_cost;
251
252 double centri_acc_cost =
253 CentripetalAccelerationCost(lane_sequence, speed, acceleration);
254 total_cost += FLAGS_centripedal_acceleration_cost_weight * centri_acc_cost;
255
256 double collision_cost = 0.0;
257 if (LowerRightOfWayThanEgo(obstacle, lane_sequence,
258 adc_trajectory_container)) {
259 collision_cost =
260 CollisionWithEgoVehicleCost(lane_sequence, speed, acceleration);
261 }
262 total_cost += FLAGS_collision_cost_weight * collision_cost;
263
264 if (FLAGS_prediction_offline_mode ==
266 std::vector<double> cost_values = {lon_acc_cost, centri_acc_cost,
267 collision_cost};
268 FeatureOutput::InsertDataForTuning(obstacle.latest_feature(), cost_values,
269 "interaction", lane_sequence,
270 adc_trajectory_);
271 }
272
273 return total_cost;
274}
275
276double InteractionPredictor::LongitudinalAccelerationCost(
277 const double acceleration) {
278 return acceleration * acceleration;
279}
280
281double InteractionPredictor::CentripetalAccelerationCost(
282 const LaneSequence& lane_sequence, const double speed,
283 const double acceleration) {
284 double cost_abs_sum = 0.0;
285 double cost_sqr_sum = 0.0;
286 double curr_time = 0.0;
287 while (curr_time < FLAGS_prediction_trajectory_time_length) {
288 double s = GetSByConstantAcceleration(speed, acceleration, curr_time);
289 double v = std::max(0.0, speed + acceleration * curr_time);
290 double kappa = GetLaneSequenceCurvatureByS(lane_sequence, s);
291 double centri_acc = v * v * kappa;
292 cost_abs_sum += std::abs(centri_acc);
293 cost_sqr_sum += centri_acc * centri_acc;
294 curr_time += FLAGS_collision_cost_time_resolution;
295 }
296 return cost_sqr_sum / (cost_abs_sum + FLAGS_double_precision);
297}
298
299double InteractionPredictor::CollisionWithEgoVehicleCost(
300 const LaneSequence& lane_sequence, const double speed,
301 const double acceleration) {
302 CHECK_GT(lane_sequence.lane_segment_size(), 0);
303 double cost_abs_sum = 0.0;
304 double cost_sqr_sum = 0.0;
305 int num_lane_segment = lane_sequence.lane_segment_size();
306
307 double remained_s = lane_sequence.lane_segment(0).start_s();
308 int lane_seg_idx = 0;
309 double prev_s = 0.0;
310
311 for (const TrajectoryPoint& adc_trajectory_point : adc_trajectory_) {
312 double relative_time = adc_trajectory_point.relative_time();
313 double curr_s =
314 GetSByConstantAcceleration(speed, acceleration, relative_time);
315 double delta_s = curr_s - prev_s;
316 remained_s += delta_s;
317 while (lane_seg_idx < num_lane_segment) {
318 const LaneSegment& lane_segment =
319 lane_sequence.lane_segment(lane_seg_idx);
320 const std::string& lane_id = lane_segment.lane_id();
321 std::shared_ptr<const LaneInfo> lane_info_ptr =
323 if (lane_info_ptr == nullptr) {
324 AERROR << "Null lane info ptr found with lane ID [" << lane_id << "]";
325 continue;
326 }
327 double lane_length = lane_info_ptr->total_length();
328 if (remained_s < lane_length) {
329 apollo::common::PointENU point_enu =
330 lane_info_ptr->GetSmoothPoint(remained_s);
331 double obs_x = point_enu.x();
332 double obs_y = point_enu.y();
333 double adc_x = adc_trajectory_point.path_point().x();
334 double adc_y = adc_trajectory_point.path_point().y();
335 double distance = std::hypot(adc_x - obs_x, adc_y - obs_y);
336 double cost = std::exp(-FLAGS_collision_cost_exp_coefficient *
337 distance * distance);
338 cost_abs_sum += std::abs(cost);
339 cost_sqr_sum += cost * cost;
340 break;
341 } else {
342 ++lane_seg_idx;
343 remained_s -= lane_length;
344 }
345 }
346 // Out of the while loop
347 prev_s = curr_s;
348 }
349 return cost_sqr_sum / (cost_abs_sum + FLAGS_double_precision);
350}
351
352bool InteractionPredictor::LowerRightOfWayThanEgo(
353 const Obstacle& obstacle, const LaneSequence& lane_sequence,
354 const ADCTrajectoryContainer* adc_trajectory_container) {
355 if (adc_trajectory_container != nullptr &&
356 adc_trajectory_container->IsProtected()) {
357 return true;
358 }
359 return lane_sequence.right_of_way() < 0;
360}
361
362double InteractionPredictor::ComputeLikelihood(const double cost) {
363 double alpha = FLAGS_likelihood_exp_coefficient;
364 return std::exp(-alpha * cost);
365}
366
367double InteractionPredictor::ComputePosterior(const double prior,
368 const double likelihood) {
369 return prior * likelihood;
370}
371
372} // namespace prediction
373} // namespace apollo
ADC trajectory container
static void InsertDataForTuning(const Feature &feature, const std::vector< double > &feature_values, const std::string &category, const LaneSequence &lane_sequence, const std::vector< apollo::common::TrajectoryPoint > &adc_trajectory)
Insert a data_for_tuning
bool Predict(const ADCTrajectoryContainer *adc_trajectory_container, Obstacle *obstacle, ObstaclesContainer *obstacles_container) override
Make prediction
Prediction obstacle.
Definition obstacle.h:52
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
Definition obstacle.cc:88
int id() const
Get the obstacle's ID.
Definition obstacle.cc:60
size_t history_size() const
Get the number of historical features.
Definition obstacle.cc:93
void SetPredictorType(const ObstacleConf::PredictorType &predictor_type)
Definition obstacle.cc:1489
static bool SmoothPointFromLane(const std::string &id, const double s, const double l, Eigen::Vector2d *point, double *heading)
Get the smooth point on a lane by a longitudinal coordinate.
static std::shared_ptr< const hdmap::LaneInfo > LaneById(const std::string &id)
Get a shared pointer to a lane by lane ID.
static bool GetProjection(const Eigen::Vector2d &position, const std::shared_ptr< const hdmap::LaneInfo > lane_info, double *s, double *l)
Get the frenet coordinates (s, l) on a lane by a position.
static Trajectory GenerateTrajectory(const std::vector< apollo::common::TrajectoryPoint > &points)
Generate trajectory from trajectory points
Definition predictor.cc:34
ObstacleConf::PredictorType predictor_type_
Definition predictor.h:125
bool SupposedToStop(const Feature &feature, const double stop_distance, double *acceleration)
Determine if an obstacle is supposed to stop within a distance
Definition predictor.cc:125
virtual void Clear()
Clear all trajectories
Definition predictor.cc:55
double GetLaneSequenceCurvatureByS(const LaneSequence &lane_sequence, const double s)
Get lane sequence curvature by s
Use container manager to manage all containers
Define interaction predictor
#define AERROR
Definition log.h:44
double GetSByConstantAcceleration(const double v0, const double acceleration, const double t)
class register implement
Definition arena_queue.h:37
Holds all global constants for the prediction module.