Apollo 11.0
自动驾驶开放平台
apollo::planning::SpiralReferenceLineSmoother类 参考

#include <spiral_reference_line_smoother.h>

类 apollo::planning::SpiralReferenceLineSmoother 继承关系图:
apollo::planning::SpiralReferenceLineSmoother 的协作图:

Public 成员函数

 SpiralReferenceLineSmoother (const ReferenceLineSmootherConfig &config)
 
virtual ~SpiralReferenceLineSmoother ()=default
 
bool Smooth (const ReferenceLine &raw_reference_line, ReferenceLine *const smoothed_reference_line) override
 Smooth a given reference line
 
int SmoothStandAlone (std::vector< Eigen::Vector2d > point2d, std::vector< double > *ptr_theta, std::vector< double > *ptr_kappa, std::vector< double > *ptr_dkappa, std::vector< double > *ptr_s, std::vector< double > *ptr_x, std::vector< double > *ptr_y) const
 
void SetAnchorPoints (const std::vector< AnchorPoint > &) override
 Smoothing constraints
 
std::vector< common::PathPoint > Interpolate (const std::vector< double > &theta, const std::vector< double > &kappa, const std::vector< double > &dkappa, const std::vector< double > &s, const std::vector< double > &x, const std::vector< double > &y, const double resolution) const
 
- Public 成员函数 继承自 apollo::planning::ReferenceLineSmoother
 ReferenceLineSmoother (const ReferenceLineSmootherConfig &config)
 
virtual ~ReferenceLineSmoother ()=default
 

额外继承的成员函数

- Protected 属性 继承自 apollo::planning::ReferenceLineSmoother
ReferenceLineSmootherConfig config_
 

详细描述

在文件 spiral_reference_line_smoother.h 第 36 行定义.

构造及析构函数说明

◆ SpiralReferenceLineSmoother()

apollo::planning::SpiralReferenceLineSmoother::SpiralReferenceLineSmoother ( const ReferenceLineSmootherConfig &  config)
explicit

在文件 spiral_reference_line_smoother.cc 第 36 行定义.

38 : ReferenceLineSmoother(config) {}
ReferenceLineSmoother(const ReferenceLineSmootherConfig &config)

◆ ~SpiralReferenceLineSmoother()

virtual apollo::planning::SpiralReferenceLineSmoother::~SpiralReferenceLineSmoother ( )
virtualdefault

成员函数说明

◆ Interpolate()

std::vector< common::PathPoint > apollo::planning::SpiralReferenceLineSmoother::Interpolate ( const std::vector< double > &  theta,
const std::vector< double > &  kappa,
const std::vector< double > &  dkappa,
const std::vector< double > &  s,
const std::vector< double > &  x,
const std::vector< double > &  y,
const double  resolution 
) const

在文件 spiral_reference_line_smoother.cc 第 300 行定义.

304 {
305 std::vector<common::PathPoint> smoothed_point2d;
306 double start_s = 0.0;
307 common::PathPoint first_point =
308 to_path_point(x.front(), y.front(), start_s, theta.front(), kappa.front(),
309 dkappa.front());
310 smoothed_point2d.push_back(first_point);
311
312 for (size_t i = 0; i + 1 < theta.size(); ++i) {
313 double start_x = x[i];
314 double start_y = y[i];
315
316 auto path_point_seg = Interpolate(
317 start_x, start_y, start_s, theta[i], kappa[i], dkappa[i], theta[i + 1],
318 kappa[i + 1], dkappa[i + 1], s[i], resolution);
319
320 smoothed_point2d.insert(smoothed_point2d.end(), path_point_seg.begin(),
321 path_point_seg.end());
322
323 start_s = smoothed_point2d.back().s();
324 }
325 return smoothed_point2d;
326}
std::vector< common::PathPoint > Interpolate(const std::vector< double > &theta, const std::vector< double > &kappa, const std::vector< double > &dkappa, const std::vector< double > &s, const std::vector< double > &x, const std::vector< double > &y, const double resolution) const

◆ SetAnchorPoints()

void apollo::planning::SpiralReferenceLineSmoother::SetAnchorPoints ( const std::vector< AnchorPoint > &  achor_points)
overridevirtual

Smoothing constraints

实现了 apollo::planning::ReferenceLineSmoother.

在文件 spiral_reference_line_smoother.cc 第 372 行定义.

373 {
374 anchor_points_ = std::move(anchor_points);
375
376 CHECK_GT(anchor_points_.size(), 1U);
377 zero_x_ = anchor_points_.front().path_point.x();
378 zero_y_ = anchor_points_.front().path_point.y();
379
380 std::for_each(anchor_points_.begin(), anchor_points_.end(),
381 [this](AnchorPoint& p) {
382 auto curr_x = p.path_point.x();
383 auto curr_y = p.path_point.y();
384 p.path_point.set_x(curr_x - zero_x_);
385 p.path_point.set_y(curr_y - zero_y_);
386 });
387}

◆ Smooth()

bool apollo::planning::SpiralReferenceLineSmoother::Smooth ( const ReferenceLine &  ,
ReferenceLine *const   
)
overridevirtual

Smooth a given reference line

实现了 apollo::planning::ReferenceLineSmoother.

在文件 spiral_reference_line_smoother.cc 第 40 行定义.

42 {
43 std::vector<double> opt_x;
44 std::vector<double> opt_y;
45 std::vector<double> opt_theta;
46 std::vector<double> opt_kappa;
47 std::vector<double> opt_dkappa;
48 std::vector<double> opt_s;
49
50 if (anchor_points_.empty()) {
51 const double piecewise_length = config_.spiral().piecewise_length();
52 const double length = raw_reference_line.Length();
53 ADEBUG << "Length = " << length;
54 uint32_t num_of_pieces =
55 std::max(1u, static_cast<uint32_t>(length / piecewise_length));
56
57 const double delta_s = length / num_of_pieces;
58 double s = 0.0;
59
60 std::vector<Eigen::Vector2d> raw_point2d;
61 for (std::uint32_t i = 0; i <= num_of_pieces;
62 ++i, s = std::fmin(s + delta_s, length)) {
63 ReferencePoint rlp = raw_reference_line.GetReferencePoint(s);
64 raw_point2d.emplace_back(rlp.x(), rlp.y());
65 }
66
67 Smooth(raw_point2d, &opt_theta, &opt_kappa, &opt_dkappa, &opt_s, &opt_x,
68 &opt_y);
69 } else {
70 size_t start_index = 0;
71 for (const auto& anchor_point : anchor_points_) {
72 if (anchor_point.enforced) {
73 start_index++;
74 } else {
75 break;
76 }
77 }
78
79 std::vector<Eigen::Vector2d> raw_point2d;
80 if (start_index == 0) {
81 for (const auto& anchor_point : anchor_points_) {
82 raw_point2d.emplace_back(anchor_point.path_point.x(),
83 anchor_point.path_point.y());
84 }
85 } else {
86 std::vector<double> overhead_s;
87 for (size_t i = 0; i + 1 < start_index; ++i) {
88 const auto& p0 = anchor_points_[i];
89 const auto& p1 = anchor_points_[i + 1];
90 overhead_s.push_back(p1.path_point.s() - p0.path_point.s());
91 }
92
93 std::vector<double> overhead_theta;
94 std::vector<double> overhead_kappa;
95 std::vector<double> overhead_dkappa;
96 std::vector<double> overhead_x;
97 std::vector<double> overhead_y;
98 for (size_t i = 0; i < anchor_points_.size(); ++i) {
99 const auto& p = anchor_points_[i];
100 if (i + 1 < start_index) {
101 overhead_theta.push_back(p.path_point.theta());
102 overhead_kappa.push_back(p.path_point.kappa());
103 overhead_dkappa.push_back(p.path_point.dkappa());
104 overhead_x.push_back(p.path_point.x());
105 overhead_y.push_back(p.path_point.y());
106 } else {
107 raw_point2d.emplace_back(p.path_point.x(), p.path_point.y());
108 }
109 }
110
111 const auto& start_anchor_point = anchor_points_[start_index - 1];
112 fixed_start_point_ = true;
113 fixed_start_x_ = start_anchor_point.path_point.x();
114 fixed_start_y_ = start_anchor_point.path_point.y();
115 fixed_start_theta_ =
116 common::math::NormalizeAngle(start_anchor_point.path_point.theta());
117 fixed_start_kappa_ = start_anchor_point.path_point.kappa();
118 fixed_start_dkappa_ = start_anchor_point.path_point.dkappa();
119
120 const auto& end_anchor_point = anchor_points_.back();
121 fixed_end_x_ = end_anchor_point.path_point.x();
122 fixed_end_y_ = end_anchor_point.path_point.y();
123
124 Smooth(raw_point2d, &opt_theta, &opt_kappa, &opt_dkappa, &opt_s, &opt_x,
125 &opt_y);
126
127 opt_theta.insert(opt_theta.begin(), overhead_theta.begin(),
128 overhead_theta.end());
129 opt_kappa.insert(opt_kappa.begin(), overhead_kappa.begin(),
130 overhead_kappa.end());
131 opt_dkappa.insert(opt_dkappa.begin(), overhead_dkappa.begin(),
132 overhead_dkappa.end());
133 opt_s.insert(opt_s.begin(), overhead_s.begin(), overhead_s.end());
134 opt_x.insert(opt_x.begin(), overhead_x.begin(), overhead_x.end());
135 opt_y.insert(opt_y.begin(), overhead_y.begin(), overhead_y.end());
136
137 std::for_each(opt_x.begin(), opt_x.end(),
138 [this](double& x) { x += zero_x_; });
139
140 std::for_each(opt_y.begin(), opt_y.end(),
141 [this](double& y) { y += zero_y_; });
142 }
143 }
144
145 std::vector<common::PathPoint> smoothed_point2d =
146 Interpolate(opt_theta, opt_kappa, opt_dkappa, opt_s, opt_x, opt_y,
148
149 std::vector<ReferencePoint> ref_points;
150 for (const auto& p : smoothed_point2d) {
151 const double heading = p.theta();
152 const double kappa = p.kappa();
153 const double dkappa = p.dkappa();
154
155 common::SLPoint ref_sl_point;
156 if (!raw_reference_line.XYToSL(p, &ref_sl_point)) {
157 return false;
158 }
159 if (ref_sl_point.s() < 0 ||
160 ref_sl_point.s() > raw_reference_line.Length()) {
161 continue;
162 }
163
164 ReferencePoint rlp = raw_reference_line.GetReferencePoint(ref_sl_point.s());
165 ref_points.emplace_back(
166 ReferencePoint(hdmap::MapPathPoint(common::math::Vec2d(p.x(), p.y()),
167 heading, rlp.lane_waypoints()),
168 kappa, dkappa));
169 }
170
172 if (ref_points.size() < 2) {
173 AERROR << "Fail to generate smoothed reference line.";
174 return false;
175 }
176 *smoothed_reference_line = ReferenceLine(ref_points);
177 return true;
178}
static void RemoveDuplicates(std::vector< ReferencePoint > *points)
bool Smooth(const ReferenceLine &raw_reference_line, ReferenceLine *const smoothed_reference_line) override
Smooth a given reference line
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53

◆ SmoothStandAlone()

int apollo::planning::SpiralReferenceLineSmoother::SmoothStandAlone ( std::vector< Eigen::Vector2d >  point2d,
std::vector< double > *  ptr_theta,
std::vector< double > *  ptr_kappa,
std::vector< double > *  ptr_dkappa,
std::vector< double > *  ptr_s,
std::vector< double > *  ptr_x,
std::vector< double > *  ptr_y 
) const

在文件 spiral_reference_line_smoother.cc 第 180 行定义.

184 {
185 CHECK_GT(point2d.size(), 1U);
186
187 SpiralProblemInterface* ptop = new SpiralProblemInterface(point2d);
188
189 ptop->set_default_max_point_deviation(config_.spiral().max_deviation());
190 ptop->set_element_weight_curve_length(config_.spiral().weight_curve_length());
191 ptop->set_element_weight_kappa(config_.spiral().weight_kappa());
192 ptop->set_element_weight_dkappa(config_.spiral().weight_dkappa());
193
194 Ipopt::SmartPtr<Ipopt::TNLP> problem = ptop;
195
196 // Create an instance of the IpoptApplication
197 Ipopt::SmartPtr<Ipopt::IpoptApplication> app = IpoptApplicationFactory();
198
199 app->Options()->SetStringValue("hessian_approximation", "limited-memory");
200 app->Options()->SetIntegerValue("max_iter", config_.spiral().max_iteration());
201 app->Options()->SetNumericValue("tol", config_.spiral().opt_tol());
202 app->Options()->SetNumericValue("acceptable_tol",
203 config_.spiral().opt_acceptable_tol());
204
205 Ipopt::ApplicationReturnStatus status = app->Initialize();
206 if (status != Ipopt::Solve_Succeeded) {
207 ADEBUG << "*** Error during initialization!";
208 return -1;
209 }
210
211 status = app->OptimizeTNLP(problem);
212
213 if (status == Ipopt::Solve_Succeeded ||
214 status == Ipopt::Solved_To_Acceptable_Level) {
215 // Retrieve some statistics about the solve
216 Ipopt::Index iter_count = app->Statistics()->IterationCount();
217 ADEBUG << "*** The problem solved in " << iter_count << " iterations!";
218
219 Ipopt::Number final_obj = app->Statistics()->FinalObjective();
220 ADEBUG << "*** The final value of the objective function is " << final_obj
221 << '.';
222 } else {
223 ADEBUG << "Return status: " << int(status);
224 }
225
226 ptop->get_optimization_results(ptr_theta, ptr_kappa, ptr_dkappa, ptr_s, ptr_x,
227 ptr_y);
228
229 if (!(status == Ipopt::Solve_Succeeded) &&
230 !(status == Ipopt::Solved_To_Acceptable_Level)) {
231 return -1;
232 }
233 return app->Statistics()->IterationCount();
234}

该类的文档由以下文件生成: