27#include "modules/planning/planning_open_space/proto/planner_open_space_config.pb.h"
50 const auto& vehicle_param =
51 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
52 ego_length_ = vehicle_param.length();
53 ego_width_ = vehicle_param.width();
54 center_shift_distance_ =
55 ego_length_ / 2.0 - vehicle_param.back_edge_to_center();
56 planner_open_space_config_ = planner_open_space_config;
57 AINFO <<
"config:" << planner_open_space_config_.DebugString();
61 const Eigen::MatrixXd& xWS,
const double init_a,
const double init_v,
62 const std::vector<std::vector<Vec2d>>& obstacles_vertices_vec,
65 AERROR <<
"reference points size smaller than two, smoother early "
69 const auto start_timestamp = std::chrono::system_clock::now();
72 gear_ = CheckGear(xWS);
75 std::vector<std::vector<LineSegment2d>> obstacles_linesegments_vec;
76 for (
const auto& obstacle_vertices : obstacles_vertices_vec) {
77 size_t vertices_num = obstacle_vertices.size();
78 std::vector<LineSegment2d> obstacle_linesegments;
79 for (
size_t i = 0; i + 1 < vertices_num; ++i) {
81 LineSegment2d(obstacle_vertices[i], obstacle_vertices[i + 1]);
82 obstacle_linesegments.emplace_back(line_segment);
84 obstacles_linesegments_vec.emplace_back(obstacle_linesegments);
86 obstacles_linesegments_vec_ = std::move(obstacles_linesegments_vec);
90 size_t xWS_size = xWS.cols();
91 double accumulated_s = 0.0;
92 Vec2d last_path_point(xWS(0, 0), xWS(1, 0));
93 for (
size_t i = 0; i < xWS_size; ++i) {
94 Vec2d cur_path_point(xWS(0, i), xWS(1, i));
95 accumulated_s += cur_path_point.
DistanceTo(last_path_point);
97 path_point.set_x(xWS(0, i));
98 path_point.set_y(xWS(1, i));
99 path_point.set_theta(xWS(2, i));
100 path_point.set_s(accumulated_s);
101 warm_start_path.push_back(std::move(path_point));
102 last_path_point = cur_path_point;
105 const double interpolated_delta_s =
108 std::vector<std::pair<double, double>> interpolated_warm_start_point2ds;
109 double path_length = warm_start_path.
Length();
110 double delta_s = path_length / std::ceil(path_length / interpolated_delta_s);
111 path_length += delta_s * 1.0e-6;
112 for (
double s = 0; s < path_length; s += delta_s) {
113 const auto point2d = warm_start_path.
Evaluate(s);
114 interpolated_warm_start_point2ds.emplace_back(point2d.x(), point2d.y());
117 const size_t interpolated_size = interpolated_warm_start_point2ds.size();
118 if (interpolated_size < 4) {
119 AERROR <<
"interpolated_warm_start_path smaller than 4, can't enforce "
120 "heading continuity";
122 }
else if (interpolated_size < 6) {
123 ADEBUG <<
"interpolated_warm_start_path smaller than 4, can't enforce "
124 "initial zero kappa";
125 enforce_initial_kappa_ =
false;
127 enforce_initial_kappa_ =
true;
131 AdjustStartEndHeading(xWS, &interpolated_warm_start_point2ds);
135 if (!SetPathProfile(interpolated_warm_start_point2ds,
136 &interpolated_warm_start_path)) {
137 AERROR <<
"Set path profile fails";
142 std::vector<double> bounds;
143 if (!GenerateInitialBounds(interpolated_warm_start_path, &bounds)) {
144 AERROR <<
"Generate initial bounds failed, path point to close to obstacle";
150 input_colliding_point_index_.clear();
151 if (!CheckCollisionAvoidance(interpolated_warm_start_path,
152 &input_colliding_point_index_)) {
153 AERROR <<
"Interpolated input path points colliding with obstacle";
160 const auto path_smooth_start_timestamp = std::chrono::system_clock::now();
164 if (!SmoothPath(interpolated_warm_start_path, bounds,
165 &smoothed_path_points)) {
190 const auto path_smooth_end_timestamp = std::chrono::system_clock::now();
191 std::chrono::duration<double> path_smooth_diff =
192 path_smooth_end_timestamp - path_smooth_start_timestamp;
193 ADEBUG <<
"iterative anchoring path smoother time: "
194 << path_smooth_diff.count() * 1000.0 <<
" ms.";
196 const auto speed_smooth_start_timestamp = std::chrono::system_clock::now();
200 if (!SmoothSpeed(init_a, init_v, smoothed_path_points.
Length(),
212 const auto speed_smooth_end_timestamp = std::chrono::system_clock::now();
213 std::chrono::duration<double> speed_smooth_diff =
214 speed_smooth_end_timestamp - speed_smooth_start_timestamp;
215 ADEBUG <<
"iterative anchoring speed smoother time: "
216 << speed_smooth_diff.count() * 1000.0 <<
" ms.";
219 if (!CombinePathAndSpeed(smoothed_path_points, smoothed_speeds,
220 discretized_trajectory)) {
224 AdjustPathAndSpeedByGear(discretized_trajectory);
226 const auto end_timestamp = std::chrono::system_clock::now();
227 std::chrono::duration<double> diff = end_timestamp - start_timestamp;
228 ADEBUG <<
"iterative anchoring smoother total time: " << diff.count() * 1000.0
231 ADEBUG <<
"discretized_trajectory size " << discretized_trajectory->size();
235void IterativeAnchoringSmoother::AdjustStartEndHeading(
236 const Eigen::MatrixXd& xWS,
237 std::vector<std::pair<double, double>>*
const point2d) {
239 CHECK_NOTNULL(point2d);
240 CHECK_GT(xWS.cols(), 1);
241 CHECK_GT(point2d->size(), 3U);
244 const double initial_heading = xWS(2, 0);
245 const double end_heading = xWS(2, xWS.cols() - 1);
250 const double first_to_second_dx = point2d->at(1).first - point2d->at(0).first;
251 const double first_to_second_dy =
252 point2d->at(1).second - point2d->at(0).second;
253 const double first_to_second_s =
254 std::sqrt(first_to_second_dx * first_to_second_dx +
255 first_to_second_dy * first_to_second_dy);
256 Vec2d first_point(point2d->at(0).first, point2d->at(0).second);
257 Vec2d initial_vec(first_to_second_s, 0);
258 initial_vec.SelfRotate(gear_ ? initial_heading
259 : NormalizeAngle(initial_heading + M_PI));
260 initial_vec += first_point;
261 point2d->at(1) = std::make_pair(initial_vec.x(), initial_vec.y());
263 const size_t path_size = point2d->size();
264 const double second_last_to_last_dx =
265 point2d->at(path_size - 1).first - point2d->at(path_size - 2).first;
266 const double second_last_to_last_dy =
267 point2d->at(path_size - 1).second - point2d->at(path_size - 2).second;
268 const double second_last_to_last_s =
269 std::sqrt(second_last_to_last_dx * second_last_to_last_dx +
270 second_last_to_last_dy * second_last_to_last_dy);
271 Vec2d last_point(point2d->at(path_size - 1).first,
272 point2d->at(path_size - 1).second);
273 Vec2d end_vec(second_last_to_last_s, 0);
274 end_vec.SelfRotate(gear_ ? NormalizeAngle(end_heading + M_PI) : end_heading);
275 end_vec += last_point;
276 point2d->at(path_size - 2) = std::make_pair(end_vec.x(), end_vec.y());
279bool IterativeAnchoringSmoother::ReAnchoring(
280 const std::vector<size_t>& colliding_point_index,
281 DiscretizedPath* path_points) {
282 CHECK_NOTNULL(path_points);
283 if (colliding_point_index.empty()) {
284 ADEBUG <<
"no point needs to be re-anchored";
288 CHECK_GT(path_points->size(),
289 *(std::max_element(colliding_point_index.begin(),
290 colliding_point_index.end())));
292 for (
const auto index : colliding_point_index) {
293 if (index == 0 || index == path_points->size() - 1) {
294 AERROR <<
"Initial and end points collision avoid condition failed.";
297 if (index == 1 || index == path_points->size() - 2) {
298 AERROR <<
"second to last point or second point pos reanchored. Heading "
299 "discontinuity might "
305 const size_t reanchoring_trails_num =
static_cast<size_t>(
308 const double reanchoring_pos_stddev =
311 const double reanchoring_length_stddev =
314 std::random_device rd;
315 std::default_random_engine gen = std::default_random_engine(rd());
316 std::normal_distribution<> pos_dis{0, reanchoring_pos_stddev};
317 std::normal_distribution<> length_dis{0, reanchoring_length_stddev};
319 for (
const auto index : colliding_point_index) {
320 bool reanchoring_success =
false;
321 for (
size_t i = 0; i < reanchoring_trails_num; ++i) {
323 bool is_colliding =
false;
324 for (
size_t j = index - 1; j < index + 2; ++j) {
325 const double heading =
326 gear_ ? path_points->at(j).theta()
328 Box2d ego_box({path_points->at(j).x() +
329 center_shift_distance_ * std::cos(heading),
330 path_points->at(j).y() +
331 center_shift_distance_ * std::sin(heading)},
332 heading, ego_length_, ego_width_);
333 for (
const auto& obstacle_linesegments : obstacles_linesegments_vec_) {
334 for (
const LineSegment2d& linesegment : obstacle_linesegments) {
335 if (ego_box.HasOverlap(linesegment)) {
352 const double adjust_theta = path_points->at(index - 1).theta();
353 const double delta_s = std::abs(path_points->at(index).s() -
354 path_points->at(index - 1).s());
356 double adjusted_delta_s = delta_s * (1.0 + rand_dev);
357 path_points->at(index).set_x(path_points->at(index - 1).x() +
359 std::cos(adjust_theta));
360 path_points->at(index).set_y(path_points->at(index - 1).y() +
362 std::sin(adjust_theta));
363 }
else if (index == path_points->size() - 2) {
364 const double adjust_theta =
366 const double delta_s = std::abs(path_points->at(index + 1).s() -
367 path_points->at(index).s());
369 double adjusted_delta_s = delta_s * (1.0 + rand_dev);
370 path_points->at(index).set_x(path_points->at(index + 1).x() +
372 std::cos(adjust_theta));
373 path_points->at(index).set_y(path_points->at(index + 1).y() +
375 std::sin(adjust_theta));
379 -2.0 * reanchoring_pos_stddev);
382 -2.0 * reanchoring_pos_stddev);
383 path_points->at(index).set_x(path_points->at(index).x() + rand_dev_x);
384 path_points->at(index).set_y(path_points->at(index).y() + rand_dev_y);
390 for (
size_t i = index - 1; i < index + 2; ++i) {
391 path_points->at(i).set_theta(CalcHeadings(*path_points, i));
394 reanchoring_success =
true;
399 if (!reanchoring_success) {
400 AERROR <<
"interpolated points at index " << index
401 <<
"can't be successfully reanchored";
408bool IterativeAnchoringSmoother::GenerateInitialBounds(
409 const DiscretizedPath& path_points, std::vector<double>* initial_bounds) {
410 CHECK_NOTNULL(initial_bounds);
411 initial_bounds->clear();
413 const bool estimate_bound =
416 const double default_bound =
419 const double vehicle_shortest_dimension =
422 const double kEpislon = 1e-8;
424 if (!estimate_bound) {
425 std::vector<double> default_bounds(path_points.size(), default_bound);
426 *initial_bounds = std::move(default_bounds);
431 for (
const auto& path_point : path_points) {
432 double min_bound = std::numeric_limits<double>::infinity();
433 for (
const auto& obstacle_linesegments : obstacles_linesegments_vec_) {
434 for (
const LineSegment2d& linesegment : obstacle_linesegments) {
437 linesegment.DistanceTo({path_point.x(), path_point.y()}));
440 min_bound -= vehicle_shortest_dimension;
441 min_bound = min_bound < kEpislon ? 0.0 : min_bound;
442 initial_bounds->push_back(min_bound);
447bool IterativeAnchoringSmoother::SmoothPath(
448 const DiscretizedPath& raw_path_points,
449 const std::vector<double>& bounds,
450 DiscretizedPath* smoothed_path_points,
451 std::vector<std::vector<common::math::Vec2d>> point_box) {
452 std::vector<std::pair<double, double>> raw_point2d;
453 std::vector<double> flexible_bounds;
454 for (
const auto& path_point : raw_path_points) {
455 raw_point2d.emplace_back(path_point.x(), path_point.y());
457 flexible_bounds = bounds;
459 FemPosDeviationSmoother fem_pos_smoother(
464 const size_t max_iteration_num = 50;
466 bool is_collision_free =
false;
467 std::vector<size_t> colliding_point_index;
468 std::vector<std::pair<double, double>> smoothed_point2d;
471 while (!is_collision_free) {
472 if (counter > max_iteration_num) {
473 AERROR <<
"Maximum iteration reached, path smoother early stops";
477 AdjustPathBounds(colliding_point_index, &flexible_bounds);
479 std::vector<double> opt_x;
480 std::vector<double> opt_y;
481 if (!fem_pos_smoother.Solve(raw_point2d, flexible_bounds, &opt_x, &opt_y)) {
482 AERROR <<
"Smoothing path fails";
486 if (opt_x.size() < 2 || opt_y.size() < 2) {
487 AERROR <<
"Return by fem_pos_smoother is wrong. Size smaller than 2 ";
491 CHECK_EQ(opt_x.size(), opt_y.size());
493 size_t point_size = opt_x.size();
494 smoothed_point2d.clear();
495 for (
size_t i = 0; i < point_size; ++i) {
496 smoothed_point2d.emplace_back(opt_x[i], opt_y[i]);
499 if (!SetPathProfile(smoothed_point2d, smoothed_path_points)) {
500 AERROR <<
"Set path profile fails";
505 CheckCollisionAvoidance(*smoothed_path_points, &colliding_point_index);
507 ADEBUG <<
"loop iteration number is " << counter;
513bool IterativeAnchoringSmoother::CheckCollisionAvoidance(
514 const DiscretizedPath& path_points,
515 std::vector<size_t>* colliding_point_index) {
516 CHECK_NOTNULL(colliding_point_index);
518 colliding_point_index->clear();
519 size_t path_points_size = path_points.size();
520 for (
size_t i = 0; i < path_points_size; ++i) {
522 bool skip_checking =
false;
523 for (
const auto index : input_colliding_point_index_) {
525 skip_checking =
true;
533 const double heading = gear_
534 ? path_points[i].theta()
537 {path_points[i].x() + center_shift_distance_ * std::cos(heading),
538 path_points[i].y() + center_shift_distance_ * std::sin(heading)},
539 heading, ego_length_, ego_width_);
541 bool is_colliding =
false;
542 for (
const auto& obstacle_linesegments : obstacles_linesegments_vec_) {
543 for (
const LineSegment2d& linesegment : obstacle_linesegments) {
544 if (ego_box.HasOverlap(linesegment)) {
545 colliding_point_index->push_back(i);
546 ADEBUG <<
"point at " << i <<
"collied with LineSegment "
547 << linesegment.DebugString();
558 if (!colliding_point_index->empty()) {
564void IterativeAnchoringSmoother::AdjustPathBounds(
565 const std::vector<size_t>& colliding_point_index,
566 std::vector<double>* bounds) {
567 CHECK_NOTNULL(bounds);
569 const double collision_decrease_ratio =
573 for (
const auto index : colliding_point_index) {
574 bounds->at(index) *= collision_decrease_ratio;
581 bounds->at(bounds->size() - 1) = 0.0;
582 bounds->at(bounds->size() - 2) = 0.0;
583 if (enforce_initial_kappa_) {
588bool IterativeAnchoringSmoother::SetPathProfile(
589 const std::vector<std::pair<double, double>>& point2d,
590 DiscretizedPath* raw_path_points) {
591 CHECK_NOTNULL(raw_path_points);
592 raw_path_points->clear();
594 std::vector<double> headings;
595 std::vector<double> kappas;
596 std::vector<double> dkappas;
597 std::vector<double> accumulated_s;
599 point2d, &headings, &accumulated_s, &kappas, &dkappas)) {
602 CHECK_EQ(point2d.size(), headings.size());
603 CHECK_EQ(point2d.size(), kappas.size());
604 CHECK_EQ(point2d.size(), dkappas.size());
605 CHECK_EQ(point2d.size(), accumulated_s.size());
608 size_t points_size = point2d.size();
609 for (
size_t i = 0; i < points_size; ++i) {
610 PathPoint path_point;
611 path_point.set_x(point2d[i].first);
612 path_point.set_y(point2d[i].second);
613 path_point.set_theta(headings[i]);
614 path_point.set_s(accumulated_s[i]);
615 path_point.set_kappa(kappas[i]);
616 path_point.set_dkappa(dkappas[i]);
617 raw_path_points->push_back(std::move(path_point));
622bool IterativeAnchoringSmoother::CheckGear(
const Eigen::MatrixXd& xWS) {
623 CHECK_GT(xWS.size(), 1);
624 double init_heading_angle = xWS(2, 0);
625 const Vec2d init_tracking_vector(xWS(0, 1) - xWS(0, 0),
626 xWS(1, 1) - xWS(1, 0));
627 double init_tracking_angle = init_tracking_vector.Angle();
628 return std::abs(
NormalizeAngle(init_tracking_angle - init_heading_angle)) <
632bool IterativeAnchoringSmoother::SmoothSpeed(
const double init_a,
634 const double path_length,
635 SpeedData* smoothed_speeds) {
636 const double max_forward_v =
639 const double max_reverse_v =
642 const double max_forward_acc =
645 const double max_reverse_acc =
648 const double max_acc_jerk =
651 const double delta_t =
655 const double total_t = 2 * path_length / max_reverse_acc * 10;
656 ADEBUG <<
"total_t is : " << total_t <<
"path_length" << path_length;
657 const size_t num_of_knots =
static_cast<size_t>(total_t / delta_t) + 1;
659 PiecewiseJerkSpeedProblem piecewise_jerk_problem(
660 num_of_knots, delta_t, {0.0, std::abs(init_v), 0.0});
662 auto s_curve_config =
667 std::vector<std::pair<double, double>> x_bounds(num_of_knots,
670 const double max_v = gear_ ? max_forward_v : max_reverse_v;
671 const double max_acc = gear_ ? max_forward_acc : max_reverse_acc;
673 const auto upper_dx = std::fmax(max_v, std::abs(init_v));
674 std::vector<std::pair<double, double>> dx_bounds(num_of_knots,
676 std::vector<std::pair<double, double>> ddx_bounds(num_of_knots,
677 {-max_acc, max_acc});
679 x_bounds[num_of_knots - 1] = std::make_pair(path_length, path_length);
680 dx_bounds[num_of_knots - 1] = std::make_pair(0.0, 0.0);
681 ddx_bounds[num_of_knots - 1] = std::make_pair(0.0, 0.0);
683 std::vector<double> x_ref(num_of_knots, path_length);
684 piecewise_jerk_problem.set_x_ref(s_curve_config.ref_s_weight(),
686 piecewise_jerk_problem.set_weight_ddx(s_curve_config.acc_weight());
687 piecewise_jerk_problem.set_weight_dddx(s_curve_config.jerk_weight());
688 piecewise_jerk_problem.set_x_bounds(x_bounds);
689 piecewise_jerk_problem.set_dx_bounds(dx_bounds);
690 piecewise_jerk_problem.set_ddx_bounds(ddx_bounds);
691 piecewise_jerk_problem.set_dddx_bound(max_acc_jerk);
694 if (!piecewise_jerk_problem.Optimize()) {
695 AERROR <<
"Piecewise jerk speed optimizer failed!";
696 AERROR <<
"init v" << init_v <<
",a" << init_a <<
"jerk bound"
698 AERROR <<
"xbounds; dxbounds;ddxbounds";
699 for (
size_t i = 0; i < num_of_knots; i++) {
700 AERROR << x_bounds[i].first <<
", " << x_bounds[i].second <<
";"
701 << dx_bounds[i].first <<
"," << dx_bounds[i].second <<
";"
702 << ddx_bounds[i].first <<
"," << ddx_bounds[i].second;
708 const std::vector<double>& s = piecewise_jerk_problem.opt_x();
709 const std::vector<double>& ds = piecewise_jerk_problem.opt_dx();
710 const std::vector<double>& dds = piecewise_jerk_problem.opt_ddx();
713 smoothed_speeds->AppendSpeedPoint(s[0], 0.0, ds[0], dds[0], 0.0);
714 const double kEpislon = 1.0e-4;
715 const double sEpislon = 1.0e-4;
716 for (
size_t i = 1; i < num_of_knots; ++i) {
717 if (s[i - 1] - s[i] > kEpislon) {
718 AERROR <<
"unexpected decreasing s in speed smoothing at time "
719 <<
static_cast<double>(i) * delta_t <<
"with total time "
723 smoothed_speeds->AppendSpeedPoint(s[i], delta_t *
static_cast<double>(i),
725 (dds[i] - dds[i - 1]) / delta_t);
727 if (path_length - s[i] < sEpislon) {
734bool IterativeAnchoringSmoother::CombinePathAndSpeed(
735 const DiscretizedPath& path_points,
const SpeedData& speed_points,
736 DiscretizedTrajectory* discretized_trajectory) {
737 CHECK_NOTNULL(discretized_trajectory);
738 discretized_trajectory->clear();
740 const double kDenseTimeResolution = 0.1;
741 const double time_horizon =
742 speed_points.TotalTime() + kDenseTimeResolution * 1.0e-6;
743 if (path_points.empty()) {
744 AERROR <<
"path data is empty";
747 ADEBUG <<
"speed_points.TotalTime() " << speed_points.TotalTime();
748 for (
double cur_rel_time = 0.0; cur_rel_time < time_horizon;
749 cur_rel_time += kDenseTimeResolution) {
750 common::SpeedPoint speed_point;
751 if (!speed_points.EvaluateByTime(cur_rel_time, &speed_point)) {
752 AERROR <<
"Fail to get speed point with relative time " << cur_rel_time;
756 if (speed_point.s() > path_points.Length()) {
760 common::PathPoint path_point = path_points.Evaluate(speed_point.s());
762 common::TrajectoryPoint trajectory_point;
763 trajectory_point.mutable_path_point()->CopyFrom(path_point);
764 trajectory_point.set_v(speed_point.v());
765 trajectory_point.set_a(speed_point.a());
766 trajectory_point.set_relative_time(speed_point.t());
767 discretized_trajectory->AppendTrajectoryPoint(trajectory_point);
769 ADEBUG <<
"path length before combine " << path_points.Length();
770 ADEBUG <<
"trajectory length after combine "
771 << discretized_trajectory->GetSpatialLength();
775void IterativeAnchoringSmoother::AdjustPathAndSpeedByGear(
776 DiscretizedTrajectory* discretized_trajectory) {
781 discretized_trajectory->begin(), discretized_trajectory->end(),
782 [](TrajectoryPoint& trajectory_point) {
783 trajectory_point.mutable_path_point()->set_theta(
784 NormalizeAngle(trajectory_point.path_point().theta() + M_PI));
785 trajectory_point.mutable_path_point()->set_s(
786 -1.0 * trajectory_point.path_point().s());
787 trajectory_point.mutable_path_point()->set_kappa(
788 -1.0 * trajectory_point.path_point().kappa());
790 trajectory_point.set_v(-1.0 * trajectory_point.v());
791 trajectory_point.set_a(-1.0 * trajectory_point.a());
795bool IterativeAnchoringSmoother::GenerateStopProfileFromPolynomial(
796 const double init_acc,
const double init_speed,
const double stop_distance,
797 SpeedData* smoothed_speeds) {
798 static constexpr double kMaxT = 8.0;
799 static constexpr double kUnitT = 0.2;
800 for (
double t = 2.0; t <= kMaxT; t += kUnitT) {
801 QuinticPolynomialCurve1d curve(0.0, init_speed, init_acc, stop_distance,
803 if (!IsValidPolynomialProfile(curve)) {
806 for (
double curve_t = 0.0; curve_t <= t; curve_t += kUnitT) {
807 const double curve_s = curve.Evaluate(0, curve_t);
808 const double curve_v = curve.Evaluate(1, curve_t);
809 const double curve_a = curve.Evaluate(2, curve_t);
810 const double curve_da = curve.Evaluate(3, curve_t);
811 smoothed_speeds->AppendSpeedPoint(curve_s, curve_t, curve_v, curve_a,
816 AERROR <<
"GenerateStopProfileFromPolynomial fails.";
820bool IterativeAnchoringSmoother::IsValidPolynomialProfile(
821 const QuinticPolynomialCurve1d& curve) {
822 for (
double evaluate_t = 0.1; evaluate_t <= curve.ParamLength();
824 const double v = curve.Evaluate(1, evaluate_t);
825 const double a = curve.Evaluate(2, evaluate_t);
826 static constexpr double kEpsilon = 1e-3;
827 if (v < -kEpsilon || a > 1.0) {
834double IterativeAnchoringSmoother::CalcHeadings(
835 const DiscretizedPath& path_points,
const size_t index) {
836 CHECK_GT(path_points.size(), 2U);
840 dx = path_points[index + 1].x() - path_points[index].x();
841 dy = path_points[index + 1].y() - path_points[index].y();
842 }
else if (index == path_points.size() - 1) {
843 dx = path_points[index].x() - path_points[index - 1].x();
844 dy = path_points[index].y() - path_points[index - 1].y();
846 dx = 0.5 * (path_points[index + 1].x() - path_points[index - 1].x());
847 dy = 0.5 * (path_points[index + 1].y() - path_points[index - 1].y());
849 return std::atan2(dy, dx);
Rectangular (undirected) bounding box in 2-D.
Implements a class of 2-dimensional vectors.
double DistanceTo(const Vec2d &other) const
Returns the distance to the given vector
static bool ComputePathProfile(const std::vector< std::pair< double, double > > &xy_points, std::vector< double > *headings, std::vector< double > *accumulated_s, std::vector< double > *kappas, std::vector< double > *dkappas)
common::PathPoint Evaluate(const double path_s) const
bool Smooth(const Eigen::MatrixXd &xWS, const double init_a, const double init_v, const std::vector< std::vector< common::math::Vec2d > > &obstacles_vertices_vec, DiscretizedTrajectory *discretized_trajectory)
IterativeAnchoringSmoother(const PlannerOpenSpaceConfig &planner_open_space_config)
Planning module main class.
Math-related util functions.
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
optional double max_forward_v
optional bool estimate_bound
optional double max_forward_acc
optional double interpolated_delta_s
optional FemPosDeviationSmootherConfig fem_pos_deviation_smoother_config
optional double max_acc_jerk
optional int32 reanchoring_trails_num
optional double max_reverse_acc
optional double max_reverse_v
optional double vehicle_shortest_dimension
optional double default_bound
optional SpeedOptimizerConfig s_curve_config
optional double reanchoring_pos_stddev
optional double reanchoring_length_stddev
optional double collision_decrease_ratio
optional IterativeAnchoringConfig iterative_anchoring_smoother_config