43 CHECK_NOTNULL(obstacle);
50 if (!feature.has_lane() || !feature.
lane().has_lane_graph()) {
51 AERROR <<
"Obstacle [" << obstacle->
id() <<
"] has no lane graph.";
55 std::string lane_id =
"";
56 if (feature.
lane().has_lane_feature()) {
57 lane_id = feature.
lane().lane_feature().lane_id();
59 int num_lane_sequence = feature.
lane().lane_graph().lane_sequence_size();
60 std::vector<bool> enable_lane_sequence(num_lane_sequence,
true);
62 obstacles_container->
GetObstacle(FLAGS_ego_vehicle_id);
64 adc_trajectory_container, &enable_lane_sequence);
65 for (
int i = 0; i < num_lane_sequence; ++i) {
69 ADEBUG <<
"Empty lane segments.";
73 if (!enable_lane_sequence[i]) {
76 <<
"] is disqualified.";
80 ADEBUG <<
"Obstacle [" << obstacle->
id()
81 <<
"] will draw a lane sequence trajectory [" <<
ToString(sequence)
82 <<
"] with probability [" << sequence.
probability() <<
"].";
84 std::vector<TrajectoryPoint> points;
85 auto end_time1 = std::chrono::system_clock::now();
87 bool is_about_to_stop =
false;
88 double acceleration = 0.0;
89 if (sequence.has_stop_sign()) {
90 double stop_distance =
92 is_about_to_stop =
SupposedToStop(feature, stop_distance, &acceleration);
95 if (is_about_to_stop) {
97 *obstacle, sequence, FLAGS_prediction_trajectory_time_length,
98 FLAGS_prediction_trajectory_time_resolution, acceleration, &points);
100 DrawMoveSequenceTrajectoryPoints(
101 *obstacle, sequence, FLAGS_prediction_trajectory_time_length,
102 FLAGS_prediction_trajectory_time_resolution, &points);
104 auto end_time2 = std::chrono::system_clock::now();
105 std::chrono::duration<double> diff = end_time2 - end_time1;
106 ADEBUG <<
" Time to draw trajectory: " << diff.count() * 1000 <<
" msec.";
109 trajectory.set_probability(sequence.
probability());
122bool MoveSequencePredictor::DrawMoveSequenceTrajectoryPoints(
124 const double total_time,
const double period,
125 std::vector<TrajectoryPoint>* points) {
128 CHECK_NOTNULL(points);
130 if (!feature.has_position() || !feature.has_velocity() ||
132 AERROR <<
"Obstacle [" << obstacle.
id()
133 <<
" is missing position or velocity";
139 double time_to_lat_end_state =
140 std::max(FLAGS_default_time_to_lat_end_state,
141 ComputeTimeToLatEndConditionByVelocity(obstacle, lane_sequence));
144 double feature_v = feature.
speed();
145 double feature_a = 0.0;
146 if (FLAGS_enable_lane_sequence_acc && lane_sequence.has_acceleration()) {
151 double ds0 = feature_v * std::cos(vel_heading - lane_heading);
152 double dds0 = feature_a * std::cos(vel_heading - lane_heading);
153 std::pair<double, double> lon_end_vt =
154 ComputeLonEndState({s0, ds0, dds0}, lane_sequence);
156 std::array<double, 4> lateral_coeffs;
157 std::array<double, 5> longitudinal_coeffs;
161 &longitudinal_coeffs);
166 std::string lane_id =
172 AERROR <<
"Failed in getting lane s and lane l";
175 double prev_lane_l = lane_l;
178 size_t total_num =
static_cast<size_t>(total_time / period);
179 for (
size_t i = 0; i < total_num; ++i) {
180 double relative_time =
static_cast<double>(i) * period;
181 Eigen::Vector2d point;
185 time_to_lat_end_state, 0.0);
188 lon_end_vt.second, lon_end_vt.first);
190 longitudinal_coeffs, relative_time - period,
191 0, lon_end_vt.second, lon_end_vt.first)
193 lane_s += std::max(0.0, (curr_s - prev_s));
194 if (curr_s + FLAGS_double_precision < prev_s) {
195 lane_l = prev_lane_l;
199 AERROR <<
"Unable to get smooth point from lane [" << lane_id
200 <<
"] with s [" << lane_s <<
"] and l [" << lane_l <<
"]";
204 prev_lane_l = lane_l;
207 lon_end_vt.second, lon_end_vt.first);
210 lon_end_vt.second, lon_end_vt.first);
212 TrajectoryPoint trajectory_point;
213 PathPoint path_point;
214 path_point.set_x(point.x());
215 path_point.set_y(point.y());
216 path_point.set_z(0.0);
217 path_point.set_theta(theta);
218 path_point.set_lane_id(lane_id);
219 trajectory_point.mutable_path_point()->CopyFrom(path_point);
220 trajectory_point.set_v(lane_speed);
221 trajectory_point.set_a(lane_acc);
222 trajectory_point.set_relative_time(relative_time);
223 points->emplace_back(std::move(trajectory_point));
226 lane_segment_index + 1 < lane_sequence.lane_segment_size()) {
227 lane_segment_index += 1;
235std::pair<double, double> MoveSequencePredictor::ComputeLonEndState(
236 const std::array<double, 3>& init_s,
const LaneSequence& lane_sequence) {
238 double max_kappa = 0.0;
239 double s_at_max_kappa = 0.0;
240 for (
int i = 0; i < lane_sequence.path_point_size(); ++i) {
241 const PathPoint& path_point = lane_sequence.path_point(i);
242 if (path_point.s() < init_s[0] + FLAGS_double_precision) {
245 if (max_kappa < path_point.kappa()) {
246 max_kappa = path_point.kappa();
247 s_at_max_kappa = path_point.s();
253 double v_init = init_s[1];
254 if (max_kappa < FLAGS_turning_curvature_lower_bound) {
255 return {v_init, FLAGS_prediction_trajectory_time_length};
259 init_s[1], max_kappa);
263 if (v_end + FLAGS_double_precision > v_init) {
264 return {v_init, FLAGS_prediction_trajectory_time_length};
268 double s_offset = s_at_max_kappa - init_s[0];
269 double t = 2.0 * s_offset / (v_init + v_end);
270 if (t < FLAGS_double_precision) {
271 return {v_init, FLAGS_prediction_trajectory_time_length};
275 double acc = (v_end - v_init) / t;
276 if (acc < FLAGS_vehicle_min_linear_acc) {
277 t = v_init / (-FLAGS_vehicle_min_linear_acc);
278 return {FLAGS_still_obstacle_speed_threshold, t};
285double MoveSequencePredictor::ComputeTimeToLatEndConditionByVelocity(
286 const Obstacle& obstacle,
const LaneSequence& lane_sequence) {
288 CHECK_GT(obstacle.history_size(), 0U);
289 CHECK_GT(lane_sequence.lane_segment_size(), 0);
290 CHECK_GT(lane_sequence.lane_segment(0).lane_point_size(), 0);
296 const Feature& feature = obstacle.latest_feature();
297 const LanePoint& first_lane_point =
298 lane_sequence.lane_segment(0).lane_point(0);
300 double v_y = feature.velocity().y();
301 double lane_heading = first_lane_point.heading();
302 double lane_l = first_lane_point.relative_l();
303 double v_l = v_y * std::cos(lane_heading) - v_x * std::sin(lane_heading);
308 if (std::fabs(v_l) < FLAGS_default_lateral_approach_speed ||
309 lane_l * v_l < 0.0) {
310 return std::fabs(lane_l / FLAGS_default_lateral_approach_speed);
312 return std::fabs(lane_l / v_l);
315std::vector<double> MoveSequencePredictor::GenerateCandidateTimes() {
316 std::vector<double> candidate_times;
317 double t = FLAGS_time_lower_bound_to_lane_center;
318 double time_gap = FLAGS_sample_time_gap;
319 while (t <= FLAGS_time_upper_bound_to_lane_center) {
320 candidate_times.push_back(t);
323 return candidate_times;
326double MoveSequencePredictor::CostFunction(
const double max_lat_acc,
327 const double time_to_end_state,
328 const double time_to_lane_edge,
329 const double bell_curve_mu) {
330 double cost_of_trajectory =
331 max_lat_acc + FLAGS_cost_function_alpha * time_to_end_state;
332 if (FLAGS_use_bell_curve_for_cost_function) {
333 double bell_curve_weight =
335 std::sqrt(2.0 * M_PI * FLAGS_cost_function_sigma *
336 FLAGS_cost_function_sigma) *
337 std::exp(-(time_to_lane_edge - bell_curve_mu) *
338 (time_to_lane_edge - bell_curve_mu) /
339 (2.0 * FLAGS_cost_function_sigma * FLAGS_cost_function_sigma));
340 cost_of_trajectory /= (bell_curve_weight + FLAGS_double_precision);
342 return cost_of_trajectory;
MoveSequencePredictor()
Constructor
bool Predict(const ADCTrajectoryContainer *adc_trajectory_container, Obstacle *obstacle, ObstaclesContainer *obstacles_container) override
Make prediction
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)
const Feature & latest_feature() const
Get the latest feature.
Obstacle * GetObstacle(const int id)
Get obstacle pointer
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
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
std::string ToString(const LaneSequence &sequence)
Convert a lane sequence to string
void Clear()
Clear private members
Define move sequence predictor
double EvaluateQuarticPolynomial(const std::array< double, 5 > &coeffs, const double t, const uint32_t order, const double end_t, const double end_v)
Evaluate quartic polynomial.
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.
double AdjustSpeedByCurvature(const double speed, const double curvature)
Adjust a speed value according to a curvature.
optional apollo::common::Point3D velocity
optional double velocity_heading
optional apollo::common::Point3D position
repeated LanePoint lane_point
optional int32 adc_lane_segment_idx
optional StopSign stop_sign
repeated LaneSegment lane_segment
optional double acceleration
optional double probability
@ MOVE_SEQUENCE_PREDICTOR
optional double lane_sequence_s