33 const std::vector<double>& x,
const std::vector<double>& dx,
34 const std::vector<double>& ddx,
const double delta_s,
35 const double start_s) {
43 for (std::size_t i = 1; i < x.size(); ++i) {
44 const auto dddl = (ddx[i] - ddx[i - 1]) / delta_s;
48 std::vector<common::FrenetFramePoint> frenet_frame_path;
49 double accumulated_s = 0.0;
50 while (accumulated_s < piecewise_jerk_traj.
ParamLength()) {
51 double l = piecewise_jerk_traj.
Evaluate(0, accumulated_s);
52 double dl = piecewise_jerk_traj.
Evaluate(1, accumulated_s);
53 double ddl = piecewise_jerk_traj.
Evaluate(2, accumulated_s);
56 frenet_frame_point.set_s(accumulated_s + start_s);
57 frenet_frame_point.set_l(l);
58 frenet_frame_point.set_dl(dl);
59 frenet_frame_point.set_ddl(ddl);
60 frenet_frame_path.push_back(std::move(frenet_frame_point));
62 accumulated_s += FLAGS_trajectory_space_resolution;
69 const auto& veh_param =
71 const double axis_distance = veh_param.
wheel_base();
72 const double max_yaw_rate =
73 veh_param.max_steer_angle_rate() / veh_param.steer_ratio();
74 return max_yaw_rate / axis_distance / vehicle_speed;
77std::vector<common::PathPoint>
80 std::vector<common::PathPoint> ret;
81 double front_to_rear_axe_distance =
87 new_path_point.set_x(path_point.x() - front_to_rear_axe_distance *
88 std::cos(path_point.theta()));
89 new_path_point.set_y(path_point.y() - front_to_rear_axe_distance *
90 std::sin(path_point.theta()));
91 ret.push_back(new_path_point);
97 const SLState& init_state,
const std::array<double, 3>& end_state,
98 std::vector<double> l_ref, std::vector<double> l_ref_weight,
100 const std::vector<std::pair<double, double>>& ddl_bounds,
double dddl_bound,
102 std::vector<double>* dx, std::vector<double>* ddx) {
104 const auto& lat_boundaries = path_boundary.
boundary();
105 const size_t kNumKnots = lat_boundaries.size();
106 AINFO <<
"kNumKnots: " << kNumKnots;
108 double delta_s = path_boundary.
delta_s();
115 std::vector<double> towing_l_ref;
116 for (
auto& path_boundary_pt : path_boundary) {
117 towing_l_ref.emplace_back(path_boundary_pt.towing_l);
120 for (
size_t i = 0; i < adc_vertex_constraints.size(); i++) {
121 print_curve.
AddPoint(path_boundary.
label() +
"_vertex_l_lower",
122 adc_vertex_constraints[i].rear_axle_s,
123 adc_vertex_constraints[i].lower_bound);
124 print_curve.
AddPoint(path_boundary.
label() +
"_vertex_l_upper",
125 adc_vertex_constraints[i].rear_axle_s,
126 adc_vertex_constraints[i].upper_bound);
128 for (
size_t i = 0; i < extra_bound.size(); i++) {
129 print_curve.
AddPoint(path_boundary.
label() +
"_conner_l_lower",
130 extra_bound[i].rear_axle_s,
131 extra_bound[i].lower_bound);
132 print_curve.
AddPoint(path_boundary.
label() +
"_conner_l_upper",
133 extra_bound[i].rear_axle_s,
134 extra_bound[i].upper_bound);
139 for (
size_t i = 0; i < kNumKnots; i++) {
141 print_curve.
AddPoint(path_boundary.
label() +
"_ref_l", s, l_ref[i]);
142 print_curve.
AddPoint(path_boundary.
label() +
"_towing_ref_l", s,
144 print_curve.
AddPoint(path_boundary.
label() +
"_ref_l_weight", s,
147 lat_boundaries[i].first);
149 lat_boundaries[i].second);
150 print_curve.
AddPoint(path_boundary.
label() +
"_ddl_lower", s,
151 ddl_bounds[i].first);
152 print_curve.
AddPoint(path_boundary.
label() +
"_ddl_upper", s,
153 ddl_bounds[i].second);
156 path_boundary.
start_s(), init_state.second[0]);
158 path_boundary.
start_s(), init_state.second[1]);
160 path_boundary.
start_s(), init_state.second[2]);
166 piecewise_jerk_problem.
set_x_ref(std::move(l_ref_weight), l_ref);
178 auto start_time = std::chrono::system_clock::now();
190 auto end_time = std::chrono::system_clock::now();
191 std::chrono::duration<double> diff = end_time - start_time;
192 ADEBUG <<
"Path Optimizer used time: " << diff.count() * 1000 <<
" ms.";
195 AERROR << path_boundary.
label() <<
"piecewise jerk path optimizer failed";
196 AINFO <<
"init s(" << init_state.first[0] <<
"," << init_state.first[1]
197 <<
"," << init_state.first[2] <<
") l (" << init_state.second[0]
198 <<
"," << init_state.second[1] <<
"," << init_state.second[2];
200 AINFO <<
"jerk bound" << dddl_bound;
205 *x = piecewise_jerk_problem.
opt_x();
206 *dx = piecewise_jerk_problem.
opt_dx();
207 *ddx = piecewise_jerk_problem.
opt_ddx();
209 for (
size_t i = 0; i < kNumKnots; i++) {
211 print_curve.
AddPoint(path_boundary.
label() +
"_opt_l", s, (*x)[i]);
212 print_curve.
AddPoint(path_boundary.
label() +
"_opt_dl", s, (*dx)[i]);
213 print_curve.
AddPoint(path_boundary.
label() +
"_opt_ddl", s, (*ddx)[i]);
214 print_box.
AddAdcBox(s, (*x)[i], std::atan((*dx)[i]),
true);
222 const SLState& init_state,
const std::array<double, 3>& end_state,
223 std::vector<double> l_ref, std::vector<double> l_ref_weight,
224 std::vector<double> towing_l_ref, std::vector<double> towing_l_ref_weight,
226 const std::vector<std::pair<double, double>>& ddl_bounds,
double dddl_bound,
228 std::vector<double>* dx, std::vector<double>* ddx) {
230 const auto& lat_boundaries = path_boundary.
boundary();
231 const size_t kNumKnots = lat_boundaries.size();
233 double delta_s = path_boundary.
delta_s();
239 for (
size_t i = 0; i < adc_vertex_constraints.size(); i++) {
240 print_curve.
AddPoint(path_boundary.
label() +
"_vertex_l_lower",
241 adc_vertex_constraints[i].rear_axle_s,
242 adc_vertex_constraints[i].lower_bound);
243 print_curve.
AddPoint(path_boundary.
label() +
"_vertex_l_upper",
244 adc_vertex_constraints[i].rear_axle_s,
245 adc_vertex_constraints[i].upper_bound);
247 for (
size_t i = 0; i < extra_bound.size(); i++) {
248 print_curve.
AddPoint(path_boundary.
label() +
"_conner_l_lower",
249 extra_bound[i].rear_axle_s,
250 extra_bound[i].lower_bound);
251 print_curve.
AddPoint(path_boundary.
label() +
"_conner_l_upper",
252 extra_bound[i].rear_axle_s,
253 extra_bound[i].upper_bound);
256 for (
size_t i = 0; i < kNumKnots; i++) {
258 print_curve.
AddPoint(path_boundary.
label() +
"_ref_l", s, l_ref[i]);
259 print_curve.
AddPoint(path_boundary.
label() +
"_towing_ref_l", s,
261 print_curve.
AddPoint(path_boundary.
label() +
"_ref_l_weight", s,
264 lat_boundaries[i].first);
266 lat_boundaries[i].second);
271 print_curve.
AddPoint(path_boundary.
label() +
"_ddl_lower", s,
272 ddl_bounds[i].first);
273 print_curve.
AddPoint(path_boundary.
label() +
"_ddl_upper", s,
274 ddl_bounds[i].second);
277 path_boundary.
start_s(), init_state.second[0]);
279 path_boundary.
start_s(), init_state.second[1]);
281 path_boundary.
start_s(), init_state.second[2]);
287 piecewise_jerk_problem.
set_x_ref(std::move(l_ref_weight), l_ref);
299 auto start_time = std::chrono::system_clock::now();
311 auto end_time = std::chrono::system_clock::now();
312 std::chrono::duration<double> diff = end_time - start_time;
313 ADEBUG <<
"Path Optimizer used time: " << diff.count() * 1000 <<
" ms.";
316 AERROR << path_boundary.
label() <<
"piecewise jerk path optimizer failed";
317 AINFO <<
"init s(" << init_state.first[0] <<
"," << init_state.first[1]
318 <<
"," << init_state.first[2] <<
") l (" << init_state.second[0]
319 <<
"," << init_state.second[1] <<
"," << init_state.second[2];
321 AINFO <<
"jerk bound" << dddl_bound;
326 *x = piecewise_jerk_problem.
opt_x();
327 *dx = piecewise_jerk_problem.
opt_dx();
328 *ddx = piecewise_jerk_problem.
opt_ddx();
329 for (
size_t i = 0; i < kNumKnots; i++) {
331 print_curve.
AddPoint(path_boundary.
label() +
"_opt_l", s, (*x)[i]);
332 print_curve.
AddPoint(path_boundary.
label() +
"_opt_dl", s, (*dx)[i]);
333 print_curve.
AddPoint(path_boundary.
label() +
"_opt_ddl", s, (*ddx)[i]);
341 std::vector<double>* ref_l, std::vector<double>* weight_ref_l) {
342 ref_l->resize(path_boundary.size());
343 weight_ref_l->resize(path_boundary.size());
344 const double kEpison = 1e-2;
345 bool need_update_by_left_boundary =
false;
346 bool need_update_by_right_boundary =
false;
347 for (
size_t i = 0; i < ref_l->size(); i++) {
348 need_update_by_left_boundary =
350 path_boundary[i].l_upper.l < path_boundary[i].towing_l + kEpison;
351 need_update_by_right_boundary =
353 path_boundary[i].l_lower.l > path_boundary[i].towing_l - kEpison;
355 if (!need_update_by_left_boundary && !need_update_by_right_boundary) {
356 weight_ref_l->at(i) = 0;
360 double center_ref_l =
361 (path_boundary[i].l_lower.l + path_boundary[i].l_upper.l) / 2.0;
362 weight_ref_l->at(i) = weight;
364 if ((path_boundary[i].l_upper.l - path_boundary[i].l_lower.l) <
365 (2 * FLAGS_path_obs_ref_shift_distance + kEpison)) {
366 ref_l->at(i) = center_ref_l;
370 if (need_update_by_left_boundary &&
371 std::fabs(path_boundary[i].l_upper.l -
372 FLAGS_path_obs_ref_shift_distance - ref_l->at(i)) <
373 std::fabs(center_ref_l - ref_l->at(i))) {
375 path_boundary[i].l_upper.l - FLAGS_path_obs_ref_shift_distance;
377 if (need_update_by_right_boundary &&
378 std::fabs(path_boundary[i].l_lower.l +
379 FLAGS_path_obs_ref_shift_distance - ref_l->at(i)) <
380 std::fabs(center_ref_l - ref_l->at(i))) {
382 path_boundary[i].l_lower.l + FLAGS_path_obs_ref_shift_distance;
384 ref_l->at(i) = center_ref_l;
386 AINFO <<
"need_update_path_ref: s: " << path_boundary[i].s
387 <<
", l: " << ref_l->at(i);
393 const std::vector<double>& towing_ref_l, std::vector<double>* ref_l,
394 std::vector<double>* weight_ref_l) {
395 ref_l->resize(path_boundary.size());
396 weight_ref_l->resize(path_boundary.size());
397 const double kEpison = 1e-2;
398 for (
size_t i = 0; i < ref_l->size(); i++) {
399 bool is_need_update_path_ref =
402 (path_boundary[i].l_lower.l > towing_ref_l[i] - kEpison ||
403 path_boundary[i].l_upper.l < towing_ref_l[i] + kEpison);
404 if (is_need_update_path_ref) {
406 (path_boundary[i].l_lower.l + path_boundary[i].l_upper.l) / 2.0;
407 weight_ref_l->at(i) = weight;
408 AINFO <<
"need_update_path_ref: s: " << path_boundary[i].s
409 <<
", l: " << ref_l->at(i);
411 weight_ref_l->at(i) = 0;
418 std::vector<double>* ref_l, std::vector<double>* weight_ref_l,
419 bool is_left_side_pass) {
420 ref_l->resize(path_boundary.size());
421 weight_ref_l->resize(path_boundary.size());
422 const double kEpison = 1e-2;
423 for (
size_t i = 0; i < ref_l->size(); i++) {
424 bool is_need_update_path_ref =
426 is_left_side_pass) ||
428 !is_left_side_pass)) &&
429 (path_boundary[i].l_lower.l > path_boundary[i].towing_l - kEpison ||
430 path_boundary[i].l_upper.l < path_boundary[i].towing_l + kEpison);
432 if (is_need_update_path_ref) {
434 (path_boundary[i].l_lower.l + path_boundary[i].l_upper.l) / 2.0;
435 weight_ref_l->at(i) = weight;
436 AINFO <<
"need_update_path_ref: s: " << path_boundary[i].s
437 <<
", l: " << ref_l->at(i);
439 weight_ref_l->at(i) = 0;
446 std::vector<std::pair<double, double>>* ddl_bounds) {
447 const auto& veh_param =
449 const double lat_acc_bound =
450 std::tan(veh_param.max_steer_angle() / veh_param.steer_ratio()) /
452 size_t path_boundary_size = path_boundary.
boundary().size();
453 for (
size_t i = 0; i < path_boundary_size; ++i) {
454 double s =
static_cast<double>(i) * path_boundary.
delta_s() +
457 ddl_bounds->emplace_back(-lat_acc_bound - kappa, lat_acc_bound - kappa);
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
const ObsCornerConstraints & extra_path_bound() const
const std::string & label() const
const ADCVertexConstraints & adc_vertex_bound() const
std::vector< std::pair< double, double > > boundary() const
const DiscretizedPath & discretized_path() const
static bool OptimizePathWithTowingPoints(const SLState &init_state, const std::array< double, 3 > &end_state, std::vector< double > l_ref, std::vector< double > l_ref_weight, std::vector< double > towing_l_ref, std::vector< double > towing_l_ref_weight, const PathBoundary &path_boundary, const std::vector< std::pair< double, double > > &ddl_bounds, double dddl_bound, const PiecewiseJerkPathConfig &config, std::vector< double > *x, std::vector< double > *dx, std::vector< double > *ddx)
static void UpdatePathRefWithBoundInSidePassDirection(const PathBoundary &path_boundary, double weight, std::vector< double > *ref_l, std::vector< double > *weight_ref_l, bool is_left_side_pass)
static std::vector< common::PathPoint > ConvertPathPointRefFromFrontAxeToRearAxe(const PathData &path_data)
static void CalculateAccBound(const PathBoundary &path_boundary, const ReferenceLine &reference_line, std::vector< std::pair< double, double > > *ddl_bounds)
calculate ddl bound by referenceline kappa and adc lat accleration
static FrenetFramePath ToPiecewiseJerkPath(const std::vector< double > &x, const std::vector< double > &dx, const std::vector< double > &ddx, const double delta_s, const double start_s)
Data format tramform from raw data to FrenetFramePath
static double EstimateJerkBoundary(const double vehicle_speed)
Calculation of jerk boundary based on vehicle kinematics model.
static bool OptimizePath(const SLState &init_state, const std::array< double, 3 > &end_state, std::vector< double > l_ref, std::vector< double > l_ref_weight, const PathBoundary &path_boundary, const std::vector< std::pair< double, double > > &ddl_bounds, double dddl_bound, const PiecewiseJerkPathConfig &config, std::vector< double > *x, std::vector< double > *dx, std::vector< double > *ddx)
Piecewise jerk path optimizer.
static void UpdatePathRefWithBound(const PathBoundary &path_boundary, double weight, std::vector< double > *ref_l, std::vector< double > *weight_ref_l)
If ref_l is below or above path boundary, will update its values and weights
void set_vertex_constraints(const ADCVertexConstraints &vertexs)
void set_extra_constraints(const ObsCornerConstraints &extra_constraints)
void set_x_ref(const double weight_x_ref, std::vector< double > x_ref)
Set the x ref object and the uniform x_ref weighting
const std::vector< double > & opt_x() const
void set_scale_factor(const std::array< double, 3 > &scale_factor)
void set_end_state_ref(const std::array< double, 3 > &weight_end_state, const std::array< double, 3 > &end_state_ref)
void set_dddx_bound(const double dddx_bound)
void set_x_bounds(std::vector< std::pair< double, double > > x_bounds)
virtual bool Optimize(const int max_iter=4000)
void set_weight_ddx(const double weight_ddx)
void set_dx_bounds(std::vector< std::pair< double, double > > dx_bounds)
const std::vector< double > & opt_dx() const
const std::vector< double > & opt_ddx() const
void set_towing_x_ref(const double weight_towing_x_ref, std::vector< double > towing_x_ref)
Set towing x ref object and piecewised towing_x_ref weightings
void set_weight_x(const double weight_x)
void set_weight_dx(const double weight_dx)
void set_weight_dddx(const double weight_dddx)
void set_ddx_bounds(std::vector< std::pair< double, double > > ddx_bounds)
double ParamLength() const
void AppendSegment(const double jerk, const double param)
double Evaluate(const std::uint32_t order, const double param) const
void AddAdcBox(double x, double y, double heading, bool is_rear_axle_point=true)
void AddPoint(std::string key, double x, double y)
add point to curve key
ReferencePoint GetNearestReferencePoint(const common::math::Vec2d &xy) const
Planning module main class.
Math-related util functions.
std::pair< std::array< double, 3 >, std::array< double, 3 > > SLState
optional VehicleParam vehicle_param
optional double wheel_base
optional double dl_weight
optional double ddl_weight
optional double weight_end_state_ddl
optional int64 max_iteration
optional double lateral_derivative_bound_default
optional double dddl_weight
optional double weight_end_state_l
optional double weight_end_state_dl