22#include "modules/common_msgs/basic_msgs/geometry.pb.h"
40 CHECK_NOTNULL(obstacle);
48 std::string str_lane_sequence =
"";
49 if (sequence.lane_segment_size() > 0) {
52 for (
int i = 1; i < sequence.lane_segment_size(); ++i) {
55 return str_lane_sequence;
59 const Feature& feature,
const std::string& lane_id,
62 std::vector<bool>* enable_lane_sequence) {
63 if (!feature.has_lane() || !feature.
lane().has_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);
78 for (
int i = 0; i < num_lane_sequence; ++i) {
81 (*enable_lane_sequence)[i] =
false;
96 adc_trajectory_container);
97 ADEBUG <<
"Distance to ADC " << std::fixed << std::setprecision(6)
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++) {
104 std::shared_ptr<const LaneInfo> lane_info =
106 if (lane_info ==
nullptr) {
107 obs_within_its_own_lane =
false;
117 lane_info->GetWidth(lane_s, &left, &right);
119 if (lane_l > left || lane_l < -right) {
120 obs_within_its_own_lane =
false;
125 if (obs_within_its_own_lane) {
126 (*enable_lane_sequence)[i] =
false;
128 <<
"] due to small distance " << distance <<
".";
136 for (
int i = 0; i < num_lane_sequence; ++i) {
139 if (!(*enable_lane_sequence)[i]) {
140 ADEBUG <<
"Disabled lane sequence [" <<
ToString(sequence) <<
"].";
145 if (LaneSequenceWithMaxProb(lane_change_type[i], probability, all.second)) {
147 all.second = probability;
149 if (LaneChangeWithMaxProb(lane_change_type[i], probability,
152 change.second = probability;
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;
161 for (
int i = 0; i < num_lane_sequence; ++i) {
164 if (!(*enable_lane_sequence)[i]) {
165 ADEBUG <<
"Disabled lane sequence [" <<
ToString(sequence) <<
"].";
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 &&
175 lane_change_type[i] != lane_change_type[change.first]) {
176 (*enable_lane_sequence)[i] =
false;
182 const std::string& lane_id,
const LaneSequence& lane_sequence) {
183 if (lane_id.empty()) {
188 if (lane_id == lane_change_id) {
206 if (!adc_trajectory_container->
HasOverlap(lane_sequence)) {
208 <<
"] has no overlap with ADC.";
209 return std::numeric_limits<double>::max();
212 Eigen::Vector2d adc_position;
213 if (ego_vehicle_ptr !=
nullptr && ego_vehicle_ptr->
history_size() > 0) {
215 adc_position[0] = position.
x();
216 adc_position[1] = position.y();
225 ADEBUG <<
"Distance with ADC is " << std::fabs(lane_s - obstacle_lane_s);
226 return obstacle_lane_s - lane_s;
230 ADEBUG <<
"Invalid ADC pose.";
231 return std::numeric_limits<double>::max();
234bool SequencePredictor::LaneSequenceWithMaxProb(
const LaneChangeType& type,
235 const double probability,
236 const double max_prob) {
237 if (probability > max_prob) {
240 double prob_diff = std::fabs(probability - max_prob);
241 if (prob_diff <= std::numeric_limits<double>::epsilon() &&
249bool SequencePredictor::LaneChangeWithMaxProb(
const LaneChangeType& type,
250 const double probability,
251 const double max_prob) {
253 if (probability > max_prob) {
262 const double total_time,
const double period,
const double acceleration,
263 std::vector<TrajectoryPoint>* points) {
265 if (!feature.has_position() || !feature.has_velocity() ||
267 AERROR <<
"Obstacle [" << obstacle.
id()
268 <<
" is missing position or velocity";
273 double speed = feature.
speed();
275 int lane_segment_index = 0;
276 std::string lane_id =
282 AERROR <<
"Failed in getting lane s and lane l";
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;
292 AERROR <<
"Unable to get smooth point from lane [" << lane_id
293 <<
"] with s [" << lane_s <<
"] and l [" << lane_l <<
"]";
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));
309 if (speed < FLAGS_double_precision) {
313 lane_s += speed * period + 0.5 * acceleration * period * period;
314 speed += acceleration * period;
317 lane_segment_index + 1 < lane_sequence.lane_segment_size()) {
318 lane_segment_index += 1;
323 lane_l *= FLAGS_go_approach_rate;
329 CHECK_GT(lane_sequence.lane_segment_size(), 0);
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;
339 return lane_info_ptr->Curvature(lane_s);
342 ADEBUG <<
"Outside lane sequence range, use 0.0 to approximate.";
348 const std::pair<double, double>& lon_end_vt,
349 std::array<double, 5>* coefficients) {
351 CHECK_NOTNULL(coefficients);
353 CHECK_GT(lane_sequence.lane_segment_size(), 0);
354 CHECK_GT(lane_sequence.
lane_segment(0).lane_point_size(), 0);
359 double v = feature.
speed();
363 if (FLAGS_enable_lane_sequence_acc && lane_sequence.has_acceleration()) {
367 int lane_point_start_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;
374 double lane_heading = lane_sequence.
lane_segment(lane_seg_start_idx)
380 double ds0 = v * std::cos(theta - lane_heading);
381 double dds0 = a * std::cos(theta - lane_heading);
384 double ds1 = lon_end_vt.first;
386 double p = lon_end_vt.second;
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;
396 coefficients->operator[](3) = b0 / p2 - b1 / 3.0 / p;
397 coefficients->operator[](4) = -0.5 / p3 * b0 + 0.25 / p2 * b1;
403 const double time_to_end_state, std::array<double, 4>* coefficients) {
405 CHECK_NOTNULL(coefficients);
407 CHECK_GT(lane_sequence.lane_segment_size(), 0);
408 CHECK_GT(lane_sequence.
lane_segment(0).lane_point_size(), 0);
413 double v = feature.
speed();
416 int lane_point_start_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;
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());
435 lane_heading_x * pos_delta_y - lane_heading_y * pos_delta_x;
436 double shift = std::hypot(pos_delta_x, pos_delta_y);
439 double l0 = (cross_prod > 0) ? shift : -shift;
440 double dl0 = v * std::sin(theta - start_lane_point.
heading());
445 coefficients->operator[](0) = l0;
446 coefficients->operator[](1) = dl0;
447 double p = time_to_end_state;
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;
bool HasOverlap(const LaneSequence &lane_sequence) const
Has overlap with ADC trajectory
int id() const
Get the obstacle's ID.
size_t history_size() const
Get the number of historical features.
const Feature & latest_feature() const
Get the latest feature.
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
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
void Clear()
Clear private members
double GetLaneSequenceCurvatureByS(const LaneSequence &lane_sequence, const double s)
Get lane sequence curvature by s
Use container manager to manage all containers
Define the sequence predictor base class
optional double velocity_heading
optional apollo::common::Point3D position
repeated apollo::common::Point3D polygon_point
repeated LaneSequence lane_sequence
optional apollo::common::Point3D position
optional int32 adc_lane_point_idx
repeated LanePoint lane_point
optional int32 adc_lane_segment_idx
repeated LaneSegment lane_segment
optional double acceleration
optional double probability
optional apollo::hdmap::Lane::LaneType lane_type