Apollo 11.0
自动驾驶开放平台
junction_predictor.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 <limits>
21#include <memory>
22#include <utility>
23
26
27namespace apollo {
28namespace prediction {
29
35
39
41 const ADCTrajectoryContainer* adc_trajectory_container, Obstacle* obstacle,
42 ObstaclesContainer* obstacles_container) {
43 Clear();
44 CHECK_NOTNULL(obstacle);
45 CHECK_GT(obstacle->history_size(), 0U);
46
48
49 const Feature& latest_feature = obstacle->latest_feature();
50 std::vector<JunctionExit> junction_exits =
51 MostLikelyJunctions(latest_feature);
52 for (const auto& junction_exit : junction_exits) {
53 std::vector<TrajectoryPoint> trajectory_points;
54 DrawJunctionTrajectoryPoints(
55 latest_feature, junction_exit, FLAGS_prediction_trajectory_time_length,
56 FLAGS_prediction_trajectory_time_resolution, &trajectory_points);
57 Trajectory trajectory = GenerateTrajectory(trajectory_points);
58 obstacle->mutable_latest_feature()->add_predicted_trajectory()->CopyFrom(
59 trajectory);
60 }
61 return true;
62}
63
64void JunctionPredictor::DrawJunctionTrajectoryPoints(
65 const Feature& feature, const JunctionExit& junction_exit,
66 const double total_time, const double period,
67 std::vector<TrajectoryPoint>* trajectory_points) {
68 double speed = feature.speed();
69 const std::array<double, 2> start_x = {feature.position().x(),
70 feature.raw_velocity().x()};
71 const std::array<double, 2> end_x = {
72 junction_exit.exit_position().x(),
73 std::cos(junction_exit.exit_heading()) * speed};
74 const std::array<double, 2> start_y = {feature.position().y(),
75 feature.raw_velocity().y()};
76 const std::array<double, 2> end_y = {
77 junction_exit.exit_position().y(),
78 std::sin(junction_exit.exit_heading()) * speed};
79 double exit_time = GetBestTime(start_x, end_x, start_y, end_y);
80 std::array<double, 4> x_coeffs =
81 ComputePolynomial<3>(start_x, end_x, exit_time);
82 std::array<double, 4> y_coeffs =
83 ComputePolynomial<3>(start_y, end_y, exit_time);
84 double t = 0.0;
85 // Trajectory in junction
86 while (t <= exit_time) {
87 PathPoint path_point;
88 path_point.set_x(EvaluateCubicPolynomial(x_coeffs, t, 0));
89 path_point.set_y(EvaluateCubicPolynomial(y_coeffs, t, 0));
90 path_point.set_z(0.0);
91 path_point.set_theta(std::atan2(EvaluateCubicPolynomial(y_coeffs, t, 1),
92 EvaluateCubicPolynomial(x_coeffs, t, 1)));
93 TrajectoryPoint trajectory_point;
94 trajectory_point.mutable_path_point()->CopyFrom(path_point);
95 trajectory_point.set_v(std::hypot(EvaluateCubicPolynomial(x_coeffs, t, 1),
96 EvaluateCubicPolynomial(y_coeffs, t, 1)));
97 trajectory_point.set_relative_time(t);
98 trajectory_points->emplace_back(std::move(trajectory_point));
99 t += period;
100 }
101 std::string lane_id = junction_exit.exit_lane_id();
102 std::shared_ptr<const LaneInfo> lane_info = PredictionMap::LaneById(lane_id);
103 Eigen::Vector2d pos(junction_exit.exit_position().x(),
104 junction_exit.exit_position().y());
105 double lane_s = 0.0;
106 double lane_l = 0.0;
107 double theta = M_PI;
108 PredictionMap::GetProjection(pos, lane_info, &lane_s, &lane_l);
109 // Trajectory after junction
110 while (t <= total_time) {
111 if (!PredictionMap::SmoothPointFromLane(lane_id, lane_s, 0.0, &pos,
112 &theta)) {
113 AERROR << "Unable to get smooth point from lane [" << lane_id
114 << "] with s [" << lane_s << "] and l [" << 0.0 << "]";
115 return;
116 }
117 TrajectoryPoint trajectory_point;
118 PathPoint path_point;
119 path_point.set_x(pos.x());
120 path_point.set_y(pos.y());
121 path_point.set_z(0.0);
122 path_point.set_theta(theta);
123 path_point.set_lane_id(lane_id);
124 trajectory_point.mutable_path_point()->CopyFrom(path_point);
125 trajectory_point.set_v(speed);
126 trajectory_point.set_a(0.0);
127 trajectory_point.set_relative_time(t);
128 trajectory_points->emplace_back(std::move(trajectory_point));
129 lane_s += speed * period;
130 while (lane_s > PredictionMap::LaneById(lane_id)->total_length()) {
131 lane_s = lane_s - PredictionMap::LaneById(lane_id)->total_length();
132 if (PredictionMap::LaneById(lane_id)->lane().successor_id_size() < 1) {
133 return;
134 }
135 // TODO(all) consider the logic to choose successor_id
136 lane_id = PredictionMap::LaneById(lane_id)->lane().successor_id(0).id();
137 }
138 t += period;
139 }
140}
141
142std::vector<JunctionExit> JunctionPredictor::MostLikelyJunctions(
143 const Feature& feature) {
144 if (!feature.has_junction_feature()) {
145 AERROR << "No junction_feature exist!";
146 return {};
147 }
148 if (feature.junction_feature().junction_exit_size() < 1 ||
149 feature.junction_feature().junction_mlp_probability_size() != 12) {
150 AERROR << "No junction_exit"
151 << "or no enough junction_mlp_probability to process!";
152 return {};
153 }
154 int max_idx = 0;
155 double max_prob = 0.0;
156 for (int i = 0; i < 12; ++i) {
157 if (feature.junction_feature().junction_mlp_probability(i) > max_prob) {
158 max_prob = feature.junction_feature().junction_mlp_probability(i);
159 max_idx = i;
160 }
161 }
162 std::vector<JunctionExit> junction_exits;
163 for (const JunctionExit& junction_exit :
164 feature.junction_feature().junction_exit()) {
165 double x = junction_exit.exit_position().x() - feature.position().x();
166 double y = junction_exit.exit_position().y() - feature.position().y();
167 double angle = std::atan2(y, x) - std::atan2(feature.raw_velocity().y(),
168 feature.raw_velocity().x());
169 double d_idx = (angle / (2.0 * M_PI)) * 12.0;
170 int idx = static_cast<int>(floor(d_idx >= 0 ? d_idx : d_idx + 12));
171 if (idx == max_idx) {
172 junction_exits.push_back(junction_exit);
173 }
174 }
175 return junction_exits;
176}
177
178double JunctionPredictor::GetBestTime(const std::array<double, 2>& start_x,
179 const std::array<double, 2>& end_x,
180 const std::array<double, 2>& start_y,
181 const std::array<double, 2>& end_y) {
182 // Generate candidate finish times.
183 std::vector<double> candidate_times = GenerateCandidateTimes();
184 double best_time = 0.0;
185 double best_cost = std::numeric_limits<double>::infinity();
186 for (size_t i = 0; i < candidate_times.size(); ++i) {
187 double time_to_exit = candidate_times[i];
188 std::array<double, 4> x_coeffs =
189 ComputePolynomial<3>(start_x, end_x, time_to_exit);
190 std::array<double, 4> y_coeffs =
191 ComputePolynomial<3>(start_y, end_y, time_to_exit);
192 double cost_of_trajectory = CostFunction(x_coeffs, y_coeffs, time_to_exit);
193 if (cost_of_trajectory <= best_cost) {
194 best_cost = cost_of_trajectory;
195 best_time = time_to_exit;
196 }
197 }
198 return best_time;
199}
200
201double JunctionPredictor::CostFunction(const std::array<double, 4>& x_coeffs,
202 const std::array<double, 4>& y_coeffs,
203 const double time_to_exit) {
204 double t = 0.0;
205 double cost = 0.0;
206 while (t <= time_to_exit) {
207 double x_1 = EvaluateCubicPolynomial(x_coeffs, t, 1);
208 double x_2 = EvaluateCubicPolynomial(x_coeffs, t, 2);
209 double y_1 = EvaluateCubicPolynomial(y_coeffs, t, 1);
210 double y_2 = EvaluateCubicPolynomial(y_coeffs, t, 2);
211 // cost = curvature * v^2 + time_to_exit
212 cost =
213 std::max(cost, std::abs(x_1 * y_2 - y_1 * x_2) / std::hypot(x_1, y_1) +
214 time_to_exit);
215 t += FLAGS_prediction_trajectory_time_resolution;
216 }
217 return cost;
218}
219
220std::vector<double> JunctionPredictor::GenerateCandidateTimes() {
221 std::vector<double> candidate_times;
222 double t = 1.0;
223 double time_gap = 0.5;
224 while (t <= FLAGS_prediction_trajectory_time_length) {
225 candidate_times.push_back(t);
226 t += time_gap;
227 }
228 return candidate_times;
229}
230
231} // namespace prediction
232} // namespace apollo
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
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
const Feature & latest_feature() const
Get the latest feature.
Definition obstacle.cc:78
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
virtual void Clear()
Clear all trajectories
Definition predictor.cc:55
Define junction predictor
#define AERROR
Definition log.h:44
double EvaluateCubicPolynomial(const std::array< double, 4 > &coefs, const double t, const uint32_t order, const double end_t, const double end_v)
Evaluate cubic polynomial.
std::array< double, 2 *N - 2 > ComputePolynomial(const std::array< double, N - 1 > &start_state, const std::array< double, N - 1 > &end_state, const double param)
class register implement
Definition arena_queue.h:37
optional apollo::common::Point3D raw_velocity
Definition feature.proto:91
optional apollo::common::Point3D position
Definition feature.proto:88
optional apollo::common::Point3D exit_position
Definition feature.proto:44