Apollo 11.0
自动驾驶开放平台
sequence_predictor.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
18
19#include <limits>
20#include <memory>
21
22#include "modules/common_msgs/basic_msgs/geometry.pb.h"
26
27namespace apollo {
28namespace prediction {
29
34
36 const ADCTrajectoryContainer* adc_trajectory_container, Obstacle* obstacle,
37 ObstaclesContainer* obstacles_container) {
38 Clear();
39
40 CHECK_NOTNULL(obstacle);
41 CHECK_GT(obstacle->history_size(), 0U);
42 return true;
43}
44
46
47std::string SequencePredictor::ToString(const LaneSequence& sequence) {
48 std::string str_lane_sequence = "";
49 if (sequence.lane_segment_size() > 0) {
50 str_lane_sequence += sequence.lane_segment(0).lane_id();
51 }
52 for (int i = 1; i < sequence.lane_segment_size(); ++i) {
53 str_lane_sequence += ("->" + sequence.lane_segment(i).lane_id());
54 }
55 return str_lane_sequence;
56}
57
59 const Feature& feature, const std::string& lane_id,
60 const Obstacle* ego_vehicle_ptr,
61 const ADCTrajectoryContainer* adc_trajectory_container,
62 std::vector<bool>* enable_lane_sequence) {
63 if (!feature.has_lane() || !feature.lane().has_lane_graph()) {
64 return;
65 }
66 const LaneGraph& lane_graph = feature.lane().lane_graph();
67 int num_lane_sequence = lane_graph.lane_sequence_size();
68 std::vector<LaneChangeType> lane_change_type(num_lane_sequence,
70 std::pair<int, double> change(-1, -1.0);
71 std::pair<int, double> all(-1, -1.0);
72
78 for (int i = 0; i < num_lane_sequence; ++i) {
79 const LaneSequence& sequence = lane_graph.lane_sequence(i);
80 if (sequence.lane_type() == apollo::hdmap::Lane::PARKING) {
81 (*enable_lane_sequence)[i] = false;
82 ADEBUG << "Ignore lane sequence [" << ToString(sequence) << "].";
83 continue;
84 }
85 lane_change_type[i] = GetLaneChangeType(lane_id, sequence);
86
87 if (lane_change_type[i] != LaneChangeType::LEFT &&
88 lane_change_type[i] != LaneChangeType::RIGHT &&
89 lane_change_type[i] != LaneChangeType::ONTO_LANE) {
90 ADEBUG << "Ignore lane sequence [" << ToString(sequence) << "].";
91 continue;
92 }
93
94 // The obstacle has interference with ADC within a small distance
95 double distance = GetLaneChangeDistanceWithADC(sequence, ego_vehicle_ptr,
96 adc_trajectory_container);
97 ADEBUG << "Distance to ADC " << std::fixed << std::setprecision(6)
98 << distance;
99 if (distance > 0.0 && distance < FLAGS_lane_change_dist) {
100 bool obs_within_its_own_lane = true;
101 for (int j = 0; j < feature.polygon_point_size(); j++) {
102 Eigen::Vector2d position(feature.polygon_point(j).x(),
103 feature.polygon_point(j).y());
104 std::shared_ptr<const LaneInfo> lane_info =
106 if (lane_info == nullptr) {
107 obs_within_its_own_lane = false;
108 break;
109 }
110
111 double lane_s = 0.0;
112 double lane_l = 0.0;
113 PredictionMap::GetProjection(position, lane_info, &lane_s, &lane_l);
114
115 double left = 0.0;
116 double right = 0.0;
117 lane_info->GetWidth(lane_s, &left, &right);
118
119 if (lane_l > left || lane_l < -right) {
120 obs_within_its_own_lane = false;
121 break;
122 }
123 }
124
125 if (obs_within_its_own_lane) {
126 (*enable_lane_sequence)[i] = false;
127 ADEBUG << "Filter trajectory [" << ToString(sequence)
128 << "] due to small distance " << distance << ".";
129 }
130 }
131 }
132
136 for (int i = 0; i < num_lane_sequence; ++i) {
137 const LaneSequence& sequence = lane_graph.lane_sequence(i);
138
139 if (!(*enable_lane_sequence)[i]) {
140 ADEBUG << "Disabled lane sequence [" << ToString(sequence) << "].";
141 continue;
142 }
143
144 double probability = sequence.probability();
145 if (LaneSequenceWithMaxProb(lane_change_type[i], probability, all.second)) {
146 all.first = i;
147 all.second = probability;
148 }
149 if (LaneChangeWithMaxProb(lane_change_type[i], probability,
150 change.second)) {
151 change.first = i;
152 change.second = probability;
153 }
154 }
155
156 double lane_sequence_threshold = FLAGS_lane_sequence_threshold_cruise;
157 if (feature.has_junction_feature()) {
158 lane_sequence_threshold = FLAGS_lane_sequence_threshold_junction;
159 }
160
161 for (int i = 0; i < num_lane_sequence; ++i) {
162 const LaneSequence& sequence = lane_graph.lane_sequence(i);
163
164 if (!(*enable_lane_sequence)[i]) {
165 ADEBUG << "Disabled lane sequence [" << ToString(sequence) << "].";
166 continue;
167 }
168
169 double probability = sequence.probability();
170 if (probability < lane_sequence_threshold && i != all.first) {
171 (*enable_lane_sequence)[i] = false;
172 } else if (change.first >= 0 && change.first < num_lane_sequence &&
173 (lane_change_type[i] == LaneChangeType::LEFT ||
174 lane_change_type[i] == LaneChangeType::RIGHT) &&
175 lane_change_type[i] != lane_change_type[change.first]) {
176 (*enable_lane_sequence)[i] = false;
177 }
178 }
179}
180
182 const std::string& lane_id, const LaneSequence& lane_sequence) {
183 if (lane_id.empty()) {
185 }
186
187 std::string lane_change_id = lane_sequence.lane_segment(0).lane_id();
188 if (lane_id == lane_change_id) {
190 } else {
191 auto ptr_change_lane = PredictionMap::LaneById(lane_change_id);
192 auto ptr_current_lane = PredictionMap::LaneById(lane_id);
193 if (PredictionMap::IsLeftNeighborLane(ptr_change_lane, ptr_current_lane)) {
195 } else if (PredictionMap::IsRightNeighborLane(ptr_change_lane,
196 ptr_current_lane)) {
198 }
199 }
201}
202
204 const LaneSequence& lane_sequence, const Obstacle* ego_vehicle_ptr,
205 const ADCTrajectoryContainer* adc_trajectory_container) {
206 if (!adc_trajectory_container->HasOverlap(lane_sequence)) {
207 ADEBUG << "The sequence [" << ToString(lane_sequence)
208 << "] has no overlap with ADC.";
209 return std::numeric_limits<double>::max();
210 }
211
212 Eigen::Vector2d adc_position;
213 if (ego_vehicle_ptr != nullptr && ego_vehicle_ptr->history_size() > 0) {
214 const auto& position = ego_vehicle_ptr->latest_feature().position();
215 adc_position[0] = position.x();
216 adc_position[1] = position.y();
217
218 std::string obstacle_lane_id = lane_sequence.lane_segment(0).lane_id();
219 double obstacle_lane_s = lane_sequence.lane_segment(0).start_s();
220 double lane_s = 0.0;
221 double lane_l = 0.0;
222 if (PredictionMap::GetProjection(adc_position,
223 PredictionMap::LaneById(obstacle_lane_id),
224 &lane_s, &lane_l)) {
225 ADEBUG << "Distance with ADC is " << std::fabs(lane_s - obstacle_lane_s);
226 return obstacle_lane_s - lane_s;
227 }
228 }
229
230 ADEBUG << "Invalid ADC pose.";
231 return std::numeric_limits<double>::max();
232}
233
234bool SequencePredictor::LaneSequenceWithMaxProb(const LaneChangeType& type,
235 const double probability,
236 const double max_prob) {
237 if (probability > max_prob) {
238 return true;
239 } else {
240 double prob_diff = std::fabs(probability - max_prob);
241 if (prob_diff <= std::numeric_limits<double>::epsilon() &&
242 type == LaneChangeType::STRAIGHT) {
243 return true;
244 }
245 }
246 return false;
247}
248
249bool SequencePredictor::LaneChangeWithMaxProb(const LaneChangeType& type,
250 const double probability,
251 const double max_prob) {
252 if (type == LaneChangeType::LEFT || type == LaneChangeType::RIGHT) {
253 if (probability > max_prob) {
254 return true;
255 }
256 }
257 return false;
258}
259
261 const Obstacle& obstacle, const LaneSequence& lane_sequence,
262 const double total_time, const double period, const double acceleration,
263 std::vector<TrajectoryPoint>* points) {
264 const Feature& feature = obstacle.latest_feature();
265 if (!feature.has_position() || !feature.has_velocity() ||
266 !feature.position().has_x() || !feature.position().has_y()) {
267 AERROR << "Obstacle [" << obstacle.id()
268 << " is missing position or velocity";
269 return;
270 }
271
272 Eigen::Vector2d position(feature.position().x(), feature.position().y());
273 double speed = feature.speed();
274
275 int lane_segment_index = 0;
276 std::string lane_id =
277 lane_sequence.lane_segment(lane_segment_index).lane_id();
278 std::shared_ptr<const LaneInfo> lane_info = PredictionMap::LaneById(lane_id);
279 double lane_s = 0.0;
280 double lane_l = 0.0;
281 if (!PredictionMap::GetProjection(position, lane_info, &lane_s, &lane_l)) {
282 AERROR << "Failed in getting lane s and lane l";
283 return;
284 }
285 size_t total_num = static_cast<size_t>(total_time / period);
286 for (size_t i = 0; i < total_num; ++i) {
287 double relative_time = static_cast<double>(i) * period;
288 Eigen::Vector2d point;
289 double theta = M_PI;
290 if (!PredictionMap::SmoothPointFromLane(lane_id, lane_s, lane_l, &point,
291 &theta)) {
292 AERROR << "Unable to get smooth point from lane [" << lane_id
293 << "] with s [" << lane_s << "] and l [" << lane_l << "]";
294 break;
295 }
296 TrajectoryPoint trajectory_point;
297 PathPoint path_point;
298 path_point.set_x(point.x());
299 path_point.set_y(point.y());
300 path_point.set_z(0.0);
301 path_point.set_theta(theta);
302 path_point.set_lane_id(lane_id);
303 trajectory_point.mutable_path_point()->CopyFrom(path_point);
304 trajectory_point.set_v(speed);
305 trajectory_point.set_a(0.0);
306 trajectory_point.set_relative_time(relative_time);
307 points->emplace_back(std::move(trajectory_point));
308
309 if (speed < FLAGS_double_precision) {
310 continue;
311 }
312
313 lane_s += speed * period + 0.5 * acceleration * period * period;
314 speed += acceleration * period;
315
316 while (lane_s > PredictionMap::LaneById(lane_id)->total_length() &&
317 lane_segment_index + 1 < lane_sequence.lane_segment_size()) {
318 lane_segment_index += 1;
319 lane_s = lane_s - PredictionMap::LaneById(lane_id)->total_length();
320 lane_id = lane_sequence.lane_segment(lane_segment_index).lane_id();
321 }
322
323 lane_l *= FLAGS_go_approach_rate;
324 }
325}
326
328 const LaneSequence& lane_sequence, const double s) {
329 CHECK_GT(lane_sequence.lane_segment_size(), 0);
330 double lane_s = s + lane_sequence.lane_segment(0).start_s();
331 for (const LaneSegment& lane_segment : lane_sequence.lane_segment()) {
332 std::string lane_id = lane_segment.lane_id();
333 std::shared_ptr<const LaneInfo> lane_info_ptr =
335 double lane_length = lane_info_ptr->total_length();
336 if (lane_s > lane_length + FLAGS_double_precision) {
337 lane_s -= lane_length;
338 } else {
339 return lane_info_ptr->Curvature(lane_s);
340 }
341 }
342 ADEBUG << "Outside lane sequence range, use 0.0 to approximate.";
343 return 0.0;
344}
345
347 const Obstacle& obstacle, const LaneSequence& lane_sequence,
348 const std::pair<double, double>& lon_end_vt,
349 std::array<double, 5>* coefficients) {
350 // Sanity check.
351 CHECK_NOTNULL(coefficients);
352 CHECK_GT(obstacle.history_size(), 0U);
353 CHECK_GT(lane_sequence.lane_segment_size(), 0);
354 CHECK_GT(lane_sequence.lane_segment(0).lane_point_size(), 0);
355
356 // Get obstacle info.
357 const Feature& feature = obstacle.latest_feature();
358 double theta = feature.velocity_heading();
359 double v = feature.speed();
360 double a = 0.0;
361
362 // Get lane info.
363 if (FLAGS_enable_lane_sequence_acc && lane_sequence.has_acceleration()) {
364 a = lane_sequence.acceleration();
365 }
366 int lane_seg_start_idx = lane_sequence.adc_lane_segment_idx();
367 int lane_point_start_idx =
368 lane_sequence.lane_segment(lane_seg_start_idx).adc_lane_point_idx();
369 if (lane_point_start_idx >=
370 lane_sequence.lane_segment(lane_seg_start_idx).lane_point_size()) {
371 lane_point_start_idx =
372 lane_sequence.lane_segment(lane_seg_start_idx).lane_point_size() - 1;
373 }
374 double lane_heading = lane_sequence.lane_segment(lane_seg_start_idx)
375 .lane_point(lane_point_start_idx)
376 .heading();
377
378 // Set the initial conditions for the diff. eqn.
379 double s0 = 0.0;
380 double ds0 = v * std::cos(theta - lane_heading);
381 double dds0 = a * std::cos(theta - lane_heading);
382 // double min_end_speed = std::min(FLAGS_still_obstacle_speed_threshold, ds0);
383 // double ds1 = std::max(min_end_speed, ds0 + dds0 * time_to_end_state);
384 double ds1 = lon_end_vt.first;
385 double dds1 = 0.0;
386 double p = lon_end_vt.second; // time to lon end state
387
388 // Solve for the coefficients.
389 coefficients->operator[](0) = s0;
390 coefficients->operator[](1) = ds0;
391 coefficients->operator[](2) = 0.5 * dds0;
392 double b0 = ds1 - dds0 * p - ds0;
393 double b1 = dds1 - dds0;
394 double p2 = p * p;
395 double p3 = p2 * p;
396 coefficients->operator[](3) = b0 / p2 - b1 / 3.0 / p;
397 coefficients->operator[](4) = -0.5 / p3 * b0 + 0.25 / p2 * b1;
398 return true;
399}
400
402 const Obstacle& obstacle, const LaneSequence& lane_sequence,
403 const double time_to_end_state, std::array<double, 4>* coefficients) {
404 // Sanity check.
405 CHECK_NOTNULL(coefficients);
406 CHECK_GT(obstacle.history_size(), 0U);
407 CHECK_GT(lane_sequence.lane_segment_size(), 0);
408 CHECK_GT(lane_sequence.lane_segment(0).lane_point_size(), 0);
409
410 // Get obstacle info.
411 const Feature& feature = obstacle.latest_feature();
412 double theta = feature.velocity_heading();
413 double v = feature.speed();
414 Point3D position = feature.position();
415 int lane_seg_start_idx = lane_sequence.adc_lane_segment_idx();
416 int lane_point_start_idx =
417 lane_sequence.lane_segment(lane_seg_start_idx).adc_lane_point_idx();
418 if (lane_point_start_idx >=
419 lane_sequence.lane_segment(lane_seg_start_idx).lane_point_size()) {
420 lane_point_start_idx =
421 lane_sequence.lane_segment(lane_seg_start_idx).lane_point_size() - 1;
422 }
423 const LanePoint& start_lane_point =
424 lane_sequence.lane_segment(lane_seg_start_idx)
425 .lane_point(lane_point_start_idx);
426
427 // Get lane info.
428 double pos_delta_x = position.x() - start_lane_point.position().x();
429 double pos_delta_y = position.y() - start_lane_point.position().y();
430 double lane_heading_x = std::cos(start_lane_point.heading());
431 double lane_heading_y = std::sin(start_lane_point.heading());
432
433 // Check if obstacle is to the left(+) or right(-) of the lane.
434 double cross_prod =
435 lane_heading_x * pos_delta_y - lane_heading_y * pos_delta_x;
436 double shift = std::hypot(pos_delta_x, pos_delta_y);
437
438 // Set the initial conditions for solving diff. eqn.
439 double l0 = (cross_prod > 0) ? shift : -shift;
440 double dl0 = v * std::sin(theta - start_lane_point.heading());
441 double l1 = 0.0;
442 double dl1 = 0.0;
443
444 // Solve for the coefficients.
445 coefficients->operator[](0) = l0;
446 coefficients->operator[](1) = dl0;
447 double p = time_to_end_state;
448 double p2 = p * p;
449 double p3 = p2 * p;
450 double tmp_var1 = (l1 - dl0) * p;
451 double tmp_var2 = dl1 - l0 - dl0 * p;
452 coefficients->operator[](2) = (3.0 * tmp_var2 - tmp_var1) / p2;
453 coefficients->operator[](3) = (tmp_var1 - 2.0 * tmp_var2) / p3;
454
455 return true;
456}
457
458} // namespace prediction
459} // namespace apollo
bool HasOverlap(const LaneSequence &lane_sequence) const
Has overlap with ADC trajectory
Prediction obstacle.
Definition obstacle.h:52
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
const Feature & latest_feature() const
Get the latest feature.
Definition obstacle.cc:78
static bool IsRightNeighborLane(std::shared_ptr< const hdmap::LaneInfo > target_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if a lane is a right neighbor of another lane.
static bool IsLeftNeighborLane(std::shared_ptr< const hdmap::LaneInfo > target_lane, std::shared_ptr< const hdmap::LaneInfo > curr_lane)
Check if a lane is a left neighbor of another lane.
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.
virtual void Clear()
Clear all trajectories
Definition predictor.cc:55
bool GetLateralPolynomial(const Obstacle &obstacle, const LaneSequence &lane_sequence, const double time_to_end_state, std::array< double, 4 > *coefficients)
bool GetLongitudinalPolynomial(const Obstacle &obstacle, const LaneSequence &lane_sequence, const std::pair< double, double > &lon_end_state, std::array< double, 5 > *coefficients)
void FilterLaneSequences(const Feature &feature, const std::string &lane_id, const Obstacle *ego_vehicle_ptr, const ADCTrajectoryContainer *adc_trajectory_container, std::vector< bool > *enable_lane_sequence)
Filter lane sequences
void DrawConstantAccelerationTrajectory(const Obstacle &obstacle, const LaneSequence &lane_sequence, const double total_time, const double period, const double acceleration, std::vector< apollo::common::TrajectoryPoint > *points)
Draw constant acceleration trajectory points
LaneChangeType GetLaneChangeType(const std::string &lane_id, const LaneSequence &lane_sequence)
Get lane change type
std::string ToString(const LaneSequence &sequence)
Convert a lane sequence to string
bool Predict(const ADCTrajectoryContainer *adc_trajectory_container, Obstacle *obstacle, ObstaclesContainer *obstacles_container) override
Make prediction
double GetLaneChangeDistanceWithADC(const LaneSequence &lane_sequence, const Obstacle *ego_vehicle_ptr, const ADCTrajectoryContainer *adc_trajectory_container)
Get lane change distance with ADC
double GetLaneSequenceCurvatureByS(const LaneSequence &lane_sequence, const double s)
Get lane sequence curvature by s
Use container manager to manage all containers
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
class register implement
Definition arena_queue.h:37
Obstacles container
Define the sequence predictor base class
optional double velocity_heading
Definition feature.proto:93
optional apollo::common::Point3D position
Definition feature.proto:88
repeated apollo::common::Point3D polygon_point
Definition feature.proto:87
repeated LaneSequence lane_sequence
optional apollo::common::Point3D position
repeated LaneSegment lane_segment
optional apollo::hdmap::Lane::LaneType lane_type