24#include "modules/common/adapters/proto/adapter_config.pb.h"
50 CHECK_NOTNULL(obstacle);
53 BuildADCTrajectory(adc_trajectory_container,
54 FLAGS_collision_cost_time_resolution);
60 if (!feature_ptr->
lane().has_lane_graph()) {
61 AERROR <<
"Obstacle [" << obstacle->
id() <<
"] has no lane graph.";
64 auto* lane_graph = feature_ptr->mutable_lane()->mutable_lane_graph();
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,
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) {
80 best_lon_accelerations[i] = lon_acceleration;
84 double likelihood = ComputeLikelihood(smallest_cost);
86 double posterior = ComputePosterior(prior, likelihood);
87 posteriors[i] = posterior;
88 posterior_sum += posterior;
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;
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) {
112 double best_lon_acceleration = best_lon_accelerations[i];
113 if (lane_sequence.has_stop_sign()) {
114 double stop_acceleration = 0.0;
118 best_lon_acceleration =
119 std::min(best_lon_acceleration, stop_acceleration);
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);
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 =
135 SupposedToStop(*feature_ptr, stop_distance, &best_lon_acceleration);
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);
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";
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;
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) {
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";
183 Eigen::Vector2d position(feature.position().x(), feature.position().y());
184 double speed = feature.speed();
186 int lane_segment_index = 0;
187 std::string lane_id =
188 lane_sequence.lane_segment(lane_segment_index).lane_id();
193 AERROR <<
"Failed in getting lane s and lane l";
196 double approach_rate = FLAGS_go_approach_rate;
197 if (!lane_sequence.vehicle_on_lane()) {
198 approach_rate = FLAGS_cutin_approach_rate;
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;
207 AERROR <<
"Unable to get smooth point from lane [" << lane_id
208 <<
"] with s [" << lane_s <<
"] and l [" << lane_l <<
"]";
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));
225 0.0, speed * period + 0.5 * lon_acceleration * period * period);
226 speed += lon_acceleration * period;
229 lane_segment_index + 1 < lane_sequence.lane_segment_size()) {
230 lane_segment_index += 1;
232 lane_id = lane_sequence.lane_segment(lane_segment_index).lane_id();
235 lane_l *= approach_rate;
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;
249 double lon_acc_cost = LongitudinalAccelerationCost(acceleration);
250 total_cost += FLAGS_longitudinal_acceleration_cost_weight * lon_acc_cost;
252 double centri_acc_cost =
253 CentripetalAccelerationCost(lane_sequence, speed, acceleration);
254 total_cost += FLAGS_centripedal_acceleration_cost_weight * centri_acc_cost;
256 double collision_cost = 0.0;
257 if (LowerRightOfWayThanEgo(obstacle, lane_sequence,
258 adc_trajectory_container)) {
260 CollisionWithEgoVehicleCost(lane_sequence, speed, acceleration);
262 total_cost += FLAGS_collision_cost_weight * collision_cost;
264 if (FLAGS_prediction_offline_mode ==
266 std::vector<double> cost_values = {lon_acc_cost, centri_acc_cost,
269 "interaction", lane_sequence,
276double InteractionPredictor::LongitudinalAccelerationCost(
277 const double acceleration) {
278 return acceleration * acceleration;
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) {
289 double v = std::max(0.0, speed + acceleration * curr_time);
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;
296 return cost_sqr_sum / (cost_abs_sum + FLAGS_double_precision);
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();
307 double remained_s = lane_sequence.lane_segment(0).start_s();
308 int lane_seg_idx = 0;
311 for (
const TrajectoryPoint& adc_trajectory_point : adc_trajectory_) {
312 double relative_time = adc_trajectory_point.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 <<
"]";
327 double lane_length = lane_info_ptr->total_length();
328 if (remained_s < lane_length) {
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;
343 remained_s -= lane_length;
349 return cost_sqr_sum / (cost_abs_sum + FLAGS_double_precision);
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()) {
359 return lane_sequence.right_of_way() < 0;
362double InteractionPredictor::ComputeLikelihood(
const double cost) {
363 double alpha = FLAGS_likelihood_exp_coefficient;
364 return std::exp(-alpha * cost);
367double InteractionPredictor::ComputePosterior(
const double prior,
368 const double likelihood) {
369 return prior * likelihood;
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
InteractionPredictor()
Constructor
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
int id() const
Get the obstacle's ID.
size_t history_size() const
Get the number of historical features.
void SetPredictorType(const ObstacleConf::PredictorType &predictor_type)
static const int kDumpDataForTuning
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
ObstacleConf::PredictorType predictor_type_
bool SupposedToStop(const Feature &feature, const double stop_distance, double *acceleration)
Determine if an obstacle is supposed to stop within a distance
virtual void Clear()
Clear all trajectories
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
double GetSByConstantAcceleration(const double v0, const double acceleration, const double t)
Holds all global constants for the prediction module.
optional StopSign stop_sign
optional double probability
optional double lane_sequence_s