Apollo 10.0
自动驾驶开放平台
apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface类 参考

#include <piecewise_jerk_speed_nonlinear_ipopt_interface.h>

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

Public 成员函数

 PiecewiseJerkSpeedNonlinearIpoptInterface (const double s_init, const double s_dot_init, const double s_ddot_init, const double delta_t, const int num_of_points, const double s_max_, const double s_dot_max, const double s_ddot_min, const double s_ddot_max, const double s_dddot_min, const double s_dddot_max)
 
virtual ~PiecewiseJerkSpeedNonlinearIpoptInterface ()=default
 
void set_warm_start (const std::vector< std::vector< double > > &speed_profile)
 
void set_curvature_curve (const PiecewiseJerkTrajectory1d &curvature_curve)
 
void get_optimization_results (std::vector< double > *ptr_opt_s, std::vector< double > *ptr_opt_v, std::vector< double > *ptr_opt_a)
 
void set_end_state_target (const double s_target, const double v_target, const double a_target)
 
void set_reference_speed (const double s_dot_ref)
 
void set_reference_spatial_distance (const std::vector< double > &s_ref)
 
void set_speed_limit_curve (const PiecewiseJerkTrajectory1d &v_bound_f)
 
void set_safety_bounds (const std::vector< std::pair< double, double > > &safety_bounds)
 
void set_soft_safety_bounds (const std::vector< std::pair< double, double > > &soft_safety_bounds)
 
void set_w_target_state (const double w_target_s, const double w_target_v, const double w_target_a)
 
void set_w_overall_a (const double w_overall_a)
 
void set_w_overall_j (const double w_overall_j)
 
void set_w_overall_centripetal_acc (const double w_overall_centripetal_acc)
 
void set_w_reference_speed (const double w_reference_speed)
 
void set_w_reference_spatial_distance (const double w_ref_s)
 
void set_w_soft_s_bound (const double w_soft_s_bound)
 
bool get_nlp_info (int &n, int &m, int &nnz_jac_g, int &nnz_h_lag, IndexStyleEnum &index_style) override
 Method to return some info about the nlp
 
bool get_bounds_info (int n, double *x_l, double *x_u, int m, double *g_l, double *g_u) override
 Method to return the bounds for my problem
 
bool get_starting_point (int n, bool init_x, double *x, bool init_z, double *z_L, double *z_U, int m, bool init_lambda, double *lambda) override
 Method to return the starting point for the algorithm
 
bool eval_f (int n, const double *x, bool new_x, double &obj_value) override
 Method to return the objective value
 
bool eval_grad_f (int n, const double *x, bool new_x, double *grad_f) override
 Method to return the gradient of the objective
 
bool eval_g (int n, const double *x, bool new_x, int m, double *g) override
 Method to return the constraint residuals
 
bool eval_jac_g (int n, const double *x, bool new_x, int m, int nele_jac, int *iRow, int *jCol, double *values) override
 Method to return: 1) The structure of the jacobian (if "values" is nullptr) 2) The values of the jacobian (if "values" is not nullptr)
 
bool eval_h (int n, const double *x, bool new_x, double obj_factor, int m, const double *lambda, bool new_lambda, int nele_hess, int *iRow, int *jCol, double *values) override
 Method to return: 1) The structure of the hessian of the lagrangian (if "values" is nullptr) 2) The values of the hessian of the lagrangian (if "values" is not nullptr)
 

Solution Methods

void finalize_solution (Ipopt::SolverReturn status, int n, const double *x, const double *z_L, const double *z_U, int m, const double *g, const double *lambda, double obj_value, const Ipopt::IpoptData *ip_data, Ipopt::IpoptCalculatedQuantities *ip_cq) override
 This method is called when the algorithm is complete so the TNLP can store/write the solution
 

详细描述

构造及析构函数说明

◆ PiecewiseJerkSpeedNonlinearIpoptInterface()

apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::PiecewiseJerkSpeedNonlinearIpoptInterface ( const double  s_init,
const double  s_dot_init,
const double  s_ddot_init,
const double  delta_t,
const int  num_of_points,
const double  s_max_,
const double  s_dot_max,
const double  s_ddot_min,
const double  s_ddot_max,
const double  s_dddot_min,
const double  s_dddot_max 
)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc29 行定义.

36 : curvature_curve_(0.0, 0.0, 0.0),
37 v_bound_func_(0.0, 0.0, 0.0),
38 s_init_(s_init),
39 s_dot_init_(s_dot_init),
40 s_ddot_init_(s_ddot_init),
41 delta_t_(delta_t),
42 num_of_points_(num_of_points),
43 s_max_(s_max),
44 s_dot_max_(s_dot_max),
45 s_ddot_min_(-std::abs(s_ddot_min)),
46 s_ddot_max_(s_ddot_max),
47 s_dddot_min_(-std::abs(s_dddot_min)),
48 s_dddot_max_(s_dddot_max),
49 v_offset_(num_of_points),
50 a_offset_(num_of_points * 2) {}

◆ ~PiecewiseJerkSpeedNonlinearIpoptInterface()

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

成员函数说明

◆ eval_f()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::eval_f ( int  n,
const double *  x,
bool  new_x,
double &  obj_value 
)
override

Method to return the objective value

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc291 行定义.

293 {
294 obj_value = 0.0;
295 // difference between ref spatial distace
296 for (int i = 0; i < num_of_points_; ++i) {
297 double s_diff = x[i] - s_ref_[i];
298 obj_value += s_diff * s_diff * w_ref_s_;
299 }
300
301 // difference between ref speed
302 for (int i = 0; i < num_of_points_; ++i) {
303 double v_diff = x[v_offset_ + i] - v_ref_;
304 obj_value += v_diff * v_diff * w_ref_v_;
305 }
306
307 // acceleration obj.
308 for (int i = 0; i < num_of_points_; ++i) {
309 double a = x[a_offset_ + i];
310 obj_value += a * a * w_overall_a_;
311 }
312
313 // jerk obj.
314 for (int i = 0; i + 1 < num_of_points_; ++i) {
315 double j = (x[a_offset_ + i + 1] - x[a_offset_ + i]) / delta_t_;
316 obj_value += j * j * w_overall_j_;
317 }
318
319 // centripetal acceleration obj.
320 for (int i = 0; i < num_of_points_; ++i) {
321 double v = x[v_offset_ + i];
322 double s = x[i];
323 double kappa = curvature_curve_.Evaluate(0, s);
324 double a_lat = v * v * kappa;
325 obj_value += a_lat * a_lat * w_overall_centripetal_acc_;
326 }
327
328 if (has_end_state_target_) {
329 double s_diff = x[num_of_points_ - 1] - s_target_;
330 obj_value += s_diff * s_diff * w_target_s_;
331
332 double v_diff = x[v_offset_ + num_of_points_ - 1] - v_target_;
333 obj_value += v_diff * v_diff * w_target_v_;
334
335 double a_diff = x[a_offset_ + num_of_points_ - 1] - a_target_;
336 obj_value += a_diff * a_diff * w_target_a_;
337 }
338
339 if (use_soft_safety_bound_) {
340 for (int i = 0; i < num_of_points_; ++i) {
341 obj_value += x[lower_s_slack_offset_ + i] * w_soft_s_bound_;
342 obj_value += x[upper_s_slack_offset_ + i] * w_soft_s_bound_;
343 }
344 }
345
346 return true;
347}
double Evaluate(const std::uint32_t order, const double param) const

◆ eval_g()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::eval_g ( int  n,
const double *  x,
bool  new_x,
int  m,
double *  g 
)
override

Method to return the constraint residuals

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc420 行定义.

422 {
423 int offset = 0;
424
425 // s monotone constraints s_i+1 - s_i
426 for (int i = 0; i + 1 < num_of_points_; ++i) {
427 g[i] = x[offset + i + 1] - x[i];
428 }
429
430 offset += num_of_points_ - 1;
431
432 // jerk bound constraint, |s_ddot_i+1 - s_ddot_i| <= s_dddot_max
433 // position equality constraints,
434 // s_i+1 - s_i - s_dot_i * delta_t - 1/3 * s_ddot_i * delta_t^2 - 1/6 *
435 // s_ddot_i+1 * delta_t^2
436 // velocity equality constraints
437 // s_dot_i+1 - s_dot_i - 0.5 * delta_t * (s_ddot_i + s_ddot_i+1)
438 int coffset_jerk = offset;
439 int coffset_position = coffset_jerk + num_of_points_ - 1;
440 int coffset_velocity = coffset_position + num_of_points_ - 1;
441
442 double t = delta_t_;
443 double t2 = t * t;
444 double t3 = t2 * t;
445
446 for (int i = 0; i + 1 < num_of_points_; ++i) {
447 double s0 = x[i];
448 double s1 = x[i + 1];
449
450 double v0 = x[v_offset_ + i];
451 double v1 = x[v_offset_ + i + 1];
452
453 double a0 = x[a_offset_ + i];
454 double a1 = x[a_offset_ + i + 1];
455
456 double j = (a1 - a0) / t;
457
458 g[coffset_jerk + i] = j;
459 g[coffset_position + i] =
460 s1 - (s0 + v0 * t + 0.5 * a0 * t2 + 1.0 / 6.0 * j * t3);
461 g[coffset_velocity + i] = v1 - (v0 + a0 * t + 0.5 * j * t2);
462 }
463
464 offset += 3 * (num_of_points_ - 1);
465
466 if (use_v_bound_) {
467 // speed limit constraints
468 int coffset_speed_limit = offset;
469 // s_dot_i - v_bound_func_(s_i) <= 0.0
470 for (int i = 0; i < num_of_points_; ++i) {
471 double s = x[i];
472 double s_dot = x[v_offset_ + i];
473 g[coffset_speed_limit + i] = s_dot - v_bound_func_.Evaluate(0, s);
474 }
475
476 offset += num_of_points_;
477 }
478
479 if (use_soft_safety_bound_) {
480 // soft safety boundary constraints
481 int coffset_soft_lower_s = offset;
482 // s_i - soft_lower_s_i + lower_slack_i >= 0.0
483 for (int i = 0; i < num_of_points_; ++i) {
484 double s = x[i];
485 double lower_s_slack = x[lower_s_slack_offset_ + i];
486 g[coffset_soft_lower_s + i] =
487 s - soft_safety_bounds_[i].first + lower_s_slack;
488 }
489 offset += num_of_points_;
490
491 int coffset_soft_upper_s = offset;
492 // s_i - soft_upper_s_i - upper_slack_i <= 0.0
493 for (int i = 0; i < num_of_points_; ++i) {
494 double s = x[i];
495 double upper_s_slack = x[upper_s_slack_offset_ + i];
496 g[coffset_soft_upper_s + i] =
497 s - soft_safety_bounds_[i].second - upper_s_slack;
498 }
499
500 offset += num_of_points_;
501 }
502
503 return true;
504}

◆ eval_grad_f()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::eval_grad_f ( int  n,
const double *  x,
bool  new_x,
double *  grad_f 
)
override

Method to return the gradient of the objective

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc349 行定义.

352 {
353 std::fill(grad_f, grad_f + n, 0.0);
354
355 // ref. spatial distance objective
356 for (int i = 0; i < num_of_points_; ++i) {
357 auto s_diff = x[i] - s_ref_[i];
358 grad_f[i] += 2.0 * s_diff * w_ref_s_;
359 }
360
361 // ref. speed objective
362 for (int i = 0; i < num_of_points_; ++i) {
363 auto v_diff = x[v_offset_ + i] - v_ref_;
364 grad_f[v_offset_ + i] += 2.0 * v_diff * w_ref_v_;
365 }
366
367 // jerk objective
368 double c = 2.0 / (delta_t_ * delta_t_) * w_overall_j_;
369 grad_f[a_offset_] += -c * (x[a_offset_ + 1] - x[a_offset_]);
370 for (int i = 1; i + 1 < num_of_points_; ++i) {
371 grad_f[a_offset_ + i] += c * (2.0 * x[a_offset_ + i] -
372 x[a_offset_ + i + 1] - x[a_offset_ + i - 1]);
373 }
374 grad_f[a_offset_ + num_of_points_ - 1] +=
375 c *
376 (x[a_offset_ + num_of_points_ - 1] - x[a_offset_ + num_of_points_ - 2]);
377
378 // acceleration objective
379 for (int i = 0; i < num_of_points_; ++i) {
380 grad_f[a_offset_ + i] += 2.0 * x[a_offset_ + i] * w_overall_a_;
381 }
382
383 // centripetal acceleration objective
384 for (int i = 0; i < num_of_points_; ++i) {
385 double v = x[v_offset_ + i];
386 double v2 = v * v;
387 double v3 = v2 * v;
388 double v4 = v3 * v;
389
390 double s = x[i];
391 double kappa = curvature_curve_.Evaluate(0, s);
392 double kappa_dot = curvature_curve_.Evaluate(1, s);
393
394 grad_f[i] += 2.0 * w_overall_centripetal_acc_ * v4 * kappa * kappa_dot;
395 grad_f[v_offset_ + i] +=
396 4.0 * w_overall_centripetal_acc_ * v3 * kappa * kappa;
397 }
398
399 if (has_end_state_target_) {
400 double s_diff = x[num_of_points_ - 1] - s_target_;
401 grad_f[num_of_points_ - 1] += 2.0 * s_diff * w_target_s_;
402
403 double v_diff = x[v_offset_ + num_of_points_ - 1] - v_target_;
404 grad_f[v_offset_ + num_of_points_ - 1] += 2.0 * v_diff * w_target_v_;
405
406 double a_diff = x[a_offset_ + num_of_points_ - 1] - a_target_;
407 grad_f[a_offset_ + num_of_points_ - 1] += 2.0 * a_diff * w_target_a_;
408 }
409
410 if (use_soft_safety_bound_) {
411 for (int i = 0; i < num_of_points_; ++i) {
412 grad_f[lower_s_slack_offset_ + i] += w_soft_s_bound_;
413 grad_f[upper_s_slack_offset_ + i] += w_soft_s_bound_;
414 }
415 }
416
417 return true;
418}

◆ eval_h()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::eval_h ( int  n,
const double *  x,
bool  new_x,
double  obj_factor,
int  m,
const double *  lambda,
bool  new_lambda,
int  nele_hess,
int *  iRow,
int *  jCol,
double *  values 
)
override

Method to return: 1) The structure of the hessian of the lagrangian (if "values" is nullptr) 2) The values of the hessian of the lagrangian (if "values" is not nullptr)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc758 行定义.

761 {
762 if (values == nullptr) {
763 int nz_index = 0;
764 for (int i = 0; i < num_of_points_; ++i) {
765 iRow[nz_index] = i;
766 jCol[nz_index] = i;
767 ++nz_index;
768 }
769
770 for (int i = 0; i < num_of_points_; ++i) {
771 iRow[nz_index] = i;
772 jCol[nz_index] = v_offset_ + i;
773 ++nz_index;
774 }
775
776 for (int i = 0; i < num_of_points_; ++i) {
777 iRow[nz_index] = v_offset_ + i;
778 jCol[nz_index] = v_offset_ + i;
779 ++nz_index;
780 }
781
782 for (int i = 0; i < num_of_points_; ++i) {
783 iRow[nz_index] = a_offset_ + i;
784 jCol[nz_index] = a_offset_ + i;
785 ++nz_index;
786 }
787
788 for (int i = 0; i + 1 < num_of_points_; ++i) {
789 iRow[nz_index] = a_offset_ + i;
790 jCol[nz_index] = a_offset_ + i + 1;
791 ++nz_index;
792 }
793
794 for (int i = 0; i < nz_index; ++i) {
795 int r = iRow[i];
796 int c = jCol[i];
797 hessian_mapper_[to_hash_key(r, c)] = i;
798 }
799
800 } else {
801 std::fill(values, values + nele_hess, 0.0);
802
803 // speed by curvature objective
804 for (int i = 0; i < num_of_points_; ++i) {
805 auto s_index = i;
806 auto v_index = v_offset_ + i;
807
808 auto s = x[s_index];
809 auto v = x[v_index];
810
811 auto kappa = curvature_curve_.Evaluate(0, s);
812 auto kappa_dot = curvature_curve_.Evaluate(1, s);
813 auto kappa_ddot = curvature_curve_.Evaluate(2, s);
814
815 auto v2 = v * v;
816 auto v3 = v2 * v;
817 auto v4 = v3 * v;
818
819 auto h_s_s_obj =
820 2.0 * kappa_dot * kappa_dot * v4 + 2.0 * kappa * kappa_ddot * v4;
821 auto h_s_s_index = hessian_mapper_[to_hash_key(s_index, s_index)];
822 values[h_s_s_index] +=
823 h_s_s_obj * w_overall_centripetal_acc_ * obj_factor;
824
825 auto h_s_v_obj = 8.0 * kappa * kappa_dot * v3;
826 auto h_s_v_index = hessian_mapper_[to_hash_key(s_index, v_index)];
827 values[h_s_v_index] +=
828 h_s_v_obj * w_overall_centripetal_acc_ * obj_factor;
829
830 auto h_v_v_obj = 12.0 * kappa * kappa * v2;
831 auto h_v_v_index = hessian_mapper_[to_hash_key(v_index, v_index)];
832 values[h_v_v_index] +=
833 h_v_v_obj * w_overall_centripetal_acc_ * obj_factor;
834 }
835
836 // spatial distance reference objective
837 for (int i = 0; i < num_of_points_; ++i) {
838 auto h_s_s_index = hessian_mapper_[to_hash_key(i, i)];
839 values[h_s_s_index] += 2.0 * w_ref_s_ * obj_factor;
840 }
841
842 // speed limit constraint
843 if (use_v_bound_) {
844 int lambda_offset = 4 * (num_of_points_ - 1);
845 for (int i = 0; i < num_of_points_; ++i) {
846 auto s_index = i;
847
848 auto s = x[s_index];
849
850 auto v_bound_ddot = v_bound_func_.Evaluate(2, s);
851
852 auto h_s_s_constr = -1.0 * v_bound_ddot;
853 auto h_s_s_index = hessian_mapper_[to_hash_key(s_index, s_index)];
854 values[h_s_s_index] += h_s_s_constr * lambda[lambda_offset + i];
855 }
856 }
857
858 for (int i = 0; i < num_of_points_; ++i) {
859 auto a_index = a_offset_ + i;
860 auto h_index = hessian_mapper_[to_hash_key(a_index, a_index)];
861 values[h_index] += 2.0 * w_overall_a_ * obj_factor;
862 }
863
864 auto c = 2.0 / delta_t_ / delta_t_ * w_overall_j_ * obj_factor;
865 for (int i = 0; i + 1 < num_of_points_; ++i) {
866 auto a0_index = a_offset_ + i;
867 auto a1_index = a_offset_ + i + 1;
868
869 auto h_a0_a0_index = hessian_mapper_[to_hash_key(a0_index, a0_index)];
870 values[h_a0_a0_index] += c;
871
872 auto h_a0_a1_index = hessian_mapper_[to_hash_key(a0_index, a1_index)];
873 values[h_a0_a1_index] += -c;
874
875 auto h_a1_a1_index = hessian_mapper_[to_hash_key(a1_index, a1_index)];
876 values[h_a1_a1_index] += c;
877 }
878
879 for (int i = 0; i < num_of_points_; ++i) {
880 auto v_index = i + v_offset_;
881 auto key = to_hash_key(v_index, v_index);
882 auto index = hessian_mapper_[key];
883 values[index] += 2.0 * w_ref_v_ * obj_factor;
884 }
885
886 if (has_end_state_target_) {
887 // target s
888 auto s_end_index = num_of_points_ - 1;
889 auto s_key = to_hash_key(s_end_index, s_end_index);
890
891 auto s_index = hessian_mapper_[s_key];
892
893 values[s_index] += 2.0 * w_target_s_ * obj_factor;
894
895 // target v
896 auto v_end_index = 2 * num_of_points_ - 1;
897 auto v_key = to_hash_key(v_end_index, v_end_index);
898
899 auto v_index = hessian_mapper_[v_key];
900
901 values[v_index] += 2.0 * w_target_v_ * obj_factor;
902
903 // target a
904 auto a_end_index = 3 * num_of_points_ - 1;
905 auto a_key = to_hash_key(a_end_index, a_end_index);
906
907 auto a_index = hessian_mapper_[a_key];
908
909 values[a_index] += 2.0 * w_target_a_ * obj_factor;
910 }
911 }
912 return true;
913}

◆ eval_jac_g()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::eval_jac_g ( int  n,
const double *  x,
bool  new_x,
int  m,
int  nele_jac,
int *  iRow,
int *  jCol,
double *  values 
)
override

Method to return: 1) The structure of the jacobian (if "values" is nullptr) 2) The values of the jacobian (if "values" is not nullptr)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc506 行定义.

508 {
509 if (values == nullptr) {
510 int non_zero_index = 0;
511 int constraint_index = 0;
512
513 // s monotone constraints s_i+1 - s_i
514 for (int i = 0; i + 1 < num_of_points_; ++i) {
515 // s_i
516 iRow[non_zero_index] = constraint_index;
517 jCol[non_zero_index] = i;
518 ++non_zero_index;
519
520 // s_i+1
521 iRow[non_zero_index] = constraint_index;
522 jCol[non_zero_index] = i + 1;
523 ++non_zero_index;
524
525 ++constraint_index;
526 }
527
528 // jerk bound constraint, |s_ddot_i+1 - s_ddot_i| / delta_t <= s_dddot_max
529 for (int i = 0; i + 1 < num_of_points_; ++i) {
530 // a_i
531 iRow[non_zero_index] = constraint_index;
532 jCol[non_zero_index] = a_offset_ + i;
533 ++non_zero_index;
534
535 // a_i+1
536 iRow[non_zero_index] = constraint_index;
537 jCol[non_zero_index] = a_offset_ + i + 1;
538 ++non_zero_index;
539
540 ++constraint_index;
541 }
542
543 // position equality constraints
544 for (int i = 0; i + 1 < num_of_points_; ++i) {
545 // s_i
546 iRow[non_zero_index] = constraint_index;
547 jCol[non_zero_index] = i;
548 ++non_zero_index;
549
550 // v_i
551 iRow[non_zero_index] = constraint_index;
552 jCol[non_zero_index] = v_offset_ + i;
553 ++non_zero_index;
554
555 // a_i
556 iRow[non_zero_index] = constraint_index;
557 jCol[non_zero_index] = a_offset_ + i;
558 ++non_zero_index;
559
560 // s_i+1
561 iRow[non_zero_index] = constraint_index;
562 jCol[non_zero_index] = i + 1;
563 ++non_zero_index;
564
565 // a_i+1
566 iRow[non_zero_index] = constraint_index;
567 jCol[non_zero_index] = a_offset_ + i + 1;
568 ++non_zero_index;
569
570 ++constraint_index;
571 }
572
573 // velocity equality constraints
574 for (int i = 0; i + 1 < num_of_points_; ++i) {
575 // v_i
576 iRow[non_zero_index] = constraint_index;
577 jCol[non_zero_index] = v_offset_ + i;
578 ++non_zero_index;
579
580 // a_i
581 iRow[non_zero_index] = constraint_index;
582 jCol[non_zero_index] = a_offset_ + i;
583 ++non_zero_index;
584
585 // v_i+1
586 iRow[non_zero_index] = constraint_index;
587 jCol[non_zero_index] = v_offset_ + i + 1;
588 ++non_zero_index;
589
590 // a_i+1
591 iRow[non_zero_index] = constraint_index;
592 jCol[non_zero_index] = a_offset_ + i + 1;
593 ++non_zero_index;
594
595 ++constraint_index;
596 }
597
598 if (use_v_bound_) {
599 // speed limit constraints
600 // s_dot_i - v_bound_func_(s_i) <= 0.0
601 for (int i = 0; i < num_of_points_; ++i) {
602 // s_i
603 iRow[non_zero_index] = constraint_index;
604 jCol[non_zero_index] = i;
605 ++non_zero_index;
606
607 // v_i
608 iRow[non_zero_index] = constraint_index;
609 jCol[non_zero_index] = v_offset_ + i;
610 ++non_zero_index;
611
612 ++constraint_index;
613 }
614 }
615
616 if (use_soft_safety_bound_) {
617 // soft_s_bound constraints
618 // s_i - soft_lower_s_i + lower_slack_i >= 0.0
619 for (int i = 0; i < num_of_points_; ++i) {
620 // s_i
621 iRow[non_zero_index] = constraint_index;
622 jCol[non_zero_index] = i;
623 ++non_zero_index;
624
625 // lower_slack_i
626 iRow[non_zero_index] = constraint_index;
627 jCol[non_zero_index] = lower_s_slack_offset_ + i;
628 ++non_zero_index;
629
630 ++constraint_index;
631 }
632 // s_i - soft_upper_s_i - upper_slack_i <= 0.0
633
634 for (int i = 0; i < num_of_points_; ++i) {
635 // s_i
636 iRow[non_zero_index] = constraint_index;
637 jCol[non_zero_index] = i;
638 ++non_zero_index;
639
640 // upper_slack_i
641 iRow[non_zero_index] = constraint_index;
642 jCol[non_zero_index] = upper_s_slack_offset_ + i;
643 ++non_zero_index;
644
645 ++constraint_index;
646 }
647 }
648
649 } else {
650 int non_zero_index = 0;
651 // s monotone constraints s_i+1 - s_i
652 for (int i = 0; i + 1 < num_of_points_; ++i) {
653 // s_i
654 values[non_zero_index] = -1.0;
655 ++non_zero_index;
656
657 // s_i+1
658 values[non_zero_index] = 1.0;
659 ++non_zero_index;
660 }
661
662 // jerk bound constraint, |s_ddot_i+1 - s_ddot_i| / delta_t <= s_dddot_max
663 for (int i = 0; i + 1 < num_of_points_; ++i) {
664 // a_i
665 values[non_zero_index] = -1.0 / delta_t_;
666 ++non_zero_index;
667
668 // a_i+1
669 values[non_zero_index] = 1.0 / delta_t_;
670 ++non_zero_index;
671 }
672
673 // position equality constraints
674 for (int i = 0; i + 1 < num_of_points_; ++i) {
675 // s_i
676 values[non_zero_index] = -1.0;
677 ++non_zero_index;
678
679 // v_i
680 values[non_zero_index] = -delta_t_;
681 ++non_zero_index;
682
683 // a_i
684 values[non_zero_index] = -1.0 / 3.0 * delta_t_ * delta_t_;
685 ++non_zero_index;
686
687 // s_i+1
688 values[non_zero_index] = 1.0;
689 ++non_zero_index;
690
691 // a_i+1
692 values[non_zero_index] = -1.0 / 6.0 * delta_t_ * delta_t_;
693 ++non_zero_index;
694 }
695
696 // velocity equality constraints
697 for (int i = 0; i + 1 < num_of_points_; ++i) {
698 // v_i
699 values[non_zero_index] = -1.0;
700 ++non_zero_index;
701
702 // a_i
703 values[non_zero_index] = -0.5 * delta_t_;
704 ++non_zero_index;
705
706 // v_i+1
707 values[non_zero_index] = 1.0;
708 ++non_zero_index;
709
710 // a_i+1
711 values[non_zero_index] = -0.5 * delta_t_;
712 ++non_zero_index;
713 }
714
715 if (use_v_bound_) {
716 // speed limit constraints
717 // s_dot_i - v_bound_func_(s_i) <= 0.0
718 for (int i = 0; i < num_of_points_; ++i) {
719 // s_i
720 double s = x[i];
721 values[non_zero_index] = -1.0 * v_bound_func_.Evaluate(1, s);
722 ++non_zero_index;
723
724 // v_i
725 values[non_zero_index] = 1.0;
726 ++non_zero_index;
727 }
728 }
729
730 if (use_soft_safety_bound_) {
731 // soft_s_bound constraints
732 // s_i - soft_lower_s_i + lower_slack_i >= 0.0
733 for (int i = 0; i < num_of_points_; ++i) {
734 // s_i
735 values[non_zero_index] = 1.0;
736 ++non_zero_index;
737
738 // lower_slack_i
739 values[non_zero_index] = 1.0;
740 ++non_zero_index;
741 }
742
743 // s_i - soft_upper_s_i - upper_slack_i <= 0.0
744 for (int i = 0; i < num_of_points_; ++i) {
745 // s_i
746 values[non_zero_index] = 1.0;
747 ++non_zero_index;
748
749 // upper_slack_i
750 values[non_zero_index] = -1.0;
751 ++non_zero_index;
752 }
753 }
754 }
755 return true;
756}

◆ finalize_solution()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::finalize_solution ( Ipopt::SolverReturn  status,
int  n,
const double *  x,
const double *  z_L,
const double *  z_U,
int  m,
const double *  g,
const double *  lambda,
double  obj_value,
const Ipopt::IpoptData *  ip_data,
Ipopt::IpoptCalculatedQuantities *  ip_cq 
)
override

This method is called when the algorithm is complete so the TNLP can store/write the solution

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc923 行定义.

927 {
928 opt_s_.clear();
929 opt_v_.clear();
930 opt_a_.clear();
931
932 for (int i = 0; i < num_of_points_; ++i) {
933 double s = x[i];
934 double v = x[v_offset_ + i];
935 double a = x[a_offset_ + i];
936
937 opt_s_.push_back(s);
938 opt_v_.push_back(v);
939 opt_a_.push_back(a);
940 }
941
942 if (use_soft_safety_bound_) {
943 // statistic analysis on soft bound intrusion by inspecting slack variable
944 double lower_s_mean_intrusion = 0.0;
945 double lower_s_highest_intrusion = -std::numeric_limits<double>::infinity();
946 int lower_s_highest_intrustion_index = 0.0;
947 double upper_s_mean_intrusion = 0.0;
948 double upper_s_highest_intrusion = -std::numeric_limits<double>::infinity();
949 int upper_s_highest_intrustion_index = 0.0;
950
951 for (int i = 0; i < num_of_points_; ++i) {
952 double lower_s_slack = x[lower_s_slack_offset_ + i];
953 double upper_s_slack = x[upper_s_slack_offset_ + i];
954
955 lower_s_mean_intrusion += lower_s_slack;
956 upper_s_mean_intrusion += upper_s_slack;
957
958 if (lower_s_highest_intrusion < lower_s_slack) {
959 lower_s_highest_intrusion = lower_s_slack;
960 lower_s_highest_intrustion_index = i;
961 }
962
963 if (upper_s_highest_intrusion < upper_s_slack) {
964 upper_s_highest_intrusion = upper_s_slack;
965 upper_s_highest_intrustion_index = i;
966 }
967 }
968
969 lower_s_mean_intrusion /= static_cast<double>(num_of_points_);
970 upper_s_mean_intrusion /= static_cast<double>(num_of_points_);
971
972 ADEBUG << "lower soft s boundary average intrustion is ["
973 << lower_s_mean_intrusion << "] with highest value of ["
974 << lower_s_highest_intrusion << "] at time ["
975 << delta_t_ * static_cast<double>(lower_s_highest_intrustion_index)
976 << "].";
977 ADEBUG << "upper soft s boundary average intrustion is ["
978 << upper_s_mean_intrusion << "] with highest value of ["
979 << upper_s_highest_intrusion << "] at time ["
980 << delta_t_ * static_cast<double>(upper_s_highest_intrustion_index)
981 << "].";
982 }
983}
#define ADEBUG
Definition log.h:41

◆ get_bounds_info()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::get_bounds_info ( int  n,
double *  x_l,
double *  x_u,
int  m,
double *  g_l,
double *  g_u 
)
override

Method to return the bounds for my problem

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc137 行定义.

138 {
139 // default nlp_lower_bound_inf value in Ipopt
140 double INF = 1.0e19;
141 double LARGE_VELOCITY_VALUE = s_dot_max_;
142
143 // bounds for variables
144 // s
145 x_l[0] = s_init_;
146 x_u[0] = s_init_;
147 for (int i = 1; i < num_of_points_; ++i) {
148 x_l[i] = safety_bounds_[i].first;
149 x_u[i] = safety_bounds_[i].second;
150 }
151
152 // s_dot
153 x_l[v_offset_] = s_dot_init_;
154 x_u[v_offset_] = s_dot_init_;
155 for (int i = 1; i < num_of_points_; ++i) {
156 x_l[v_offset_ + i] = 0.0;
157 x_u[v_offset_ + i] = LARGE_VELOCITY_VALUE;
158 }
159
160 // s_ddot
161 x_l[a_offset_] = s_ddot_init_;
162 x_u[a_offset_] = s_ddot_init_;
163 for (int i = 1; i < num_of_points_; ++i) {
164 x_l[a_offset_ + i] = s_ddot_min_;
165 x_u[a_offset_ + i] = s_ddot_max_;
166 }
167
168 if (use_soft_safety_bound_) {
169 // lower_s_slack
170 for (int i = 0; i < num_of_points_; ++i) {
171 x_l[lower_s_slack_offset_ + i] = 0.0;
172 x_u[lower_s_slack_offset_ + i] = INF;
173 }
174
175 // upper_s_slack
176 for (int i = 0; i < num_of_points_; ++i) {
177 x_l[upper_s_slack_offset_ + i] = 0.0;
178 x_u[upper_s_slack_offset_ + i] = INF;
179 }
180 }
181
182 // bounds for constraints
183 // s monotone constraints s_i+1 - s_i
184 for (int i = 0; i + 1 < num_of_points_; ++i) {
185 g_l[i] = 0.0;
186 g_u[i] = LARGE_VELOCITY_VALUE * delta_t_;
187 }
188
189 // jerk bound constraint
190 // |s_ddot_i+1 - s_ddot_i| / delta_t <= s_dddot_max
191 int offset = num_of_points_ - 1;
192 for (int i = 0; i + 1 < num_of_points_; ++i) {
193 g_l[offset + i] = s_dddot_min_;
194 g_u[offset + i] = s_dddot_max_;
195 }
196
197 // position equality constraints,
198 // s_i+1 - s_i - s_dot_i * delta_t - 1/3 * s_ddot_i * delta_t^2 - 1/6 *
199 // s_ddot_i+1 * delta_t^2
200 offset += num_of_points_ - 1;
201 for (int i = 0; i + 1 < num_of_points_; ++i) {
202 g_l[offset + i] = 0.0;
203 g_u[offset + i] = 0.0;
204 }
205
206 // velocity equality constraints,
207 // s_dot_i+1 - s_dot_i - 0.5 * delta_t * s_ddot_i - 0.5 * delta_t *
208 // s_ddot_i+1
209 offset += num_of_points_ - 1;
210 for (int i = 0; i + 1 < num_of_points_; ++i) {
211 g_l[offset + i] = 0.0;
212 g_u[offset + i] = 0.0;
213 }
214
215 if (use_v_bound_) {
216 // speed limit constraints
217 // s_dot_i - v_bound_func_(s_i) <= 0.0
218 offset += num_of_points_ - 1;
219 for (int i = 0; i < num_of_points_; ++i) {
220 g_l[offset + i] = -INF;
221 g_u[offset + i] = 0.0;
222 }
223 }
224
225 if (use_soft_safety_bound_) {
226 // soft_s_bound constraints
227 // s_i - soft_lower_s_i + lower_slack_i >= 0.0
228 offset += num_of_points_;
229 for (int i = 0; i < num_of_points_; ++i) {
230 g_l[offset + i] = 0.0;
231 g_u[offset + i] = INF;
232 }
233
234 // s_i - soft_upper_s_i - upper_slack_i <= 0.0
235 offset += num_of_points_;
236 for (int i = 0; i < num_of_points_; ++i) {
237 g_l[offset + i] = -INF;
238 g_u[offset + i] = 0.0;
239 }
240 }
241
242 return true;
243}

◆ get_nlp_info()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::get_nlp_info ( int &  n,
int &  m,
int &  nnz_jac_g,
int &  nnz_h_lag,
IndexStyleEnum &  index_style 
)
override

Method to return some info about the nlp

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc52 行定义.

54 {
55 num_of_variables_ = num_of_points_ * 3;
56
57 if (use_soft_safety_bound_) {
58 // complementary slack variable for soft upper and lower s bound
59 num_of_variables_ += num_of_points_ * 2;
60
61 lower_s_slack_offset_ = num_of_points_ * 3;
62
63 upper_s_slack_offset_ = num_of_points_ * 4;
64 }
65
66 n = num_of_variables_;
67
68 // s monotone constraints s_i+1 - s_i >= 0.0
69 num_of_constraints_ = num_of_points_ - 1;
70
71 // jerk bound constraint
72 // |s_ddot_i+1 - s_ddot_i| / delta_t <= s_dddot_max
73 num_of_constraints_ += num_of_points_ - 1;
74
75 // position equality constraints
76 // s_i+1 - s_i - s_dot_i * delta_t - 1/3 * s_ddot_i * delta_t^2 - 1/6 *
77 // s_ddot_i+1 * delta_t^2
78 num_of_constraints_ += num_of_points_ - 1;
79
80 // velocity equality constraints
81 // s_dot_i+1 - s_dot_i - 0.5 * delta_t * s_ddot_i - 0.5 * delta_t * s_ddot_i+1
82 num_of_constraints_ += num_of_points_ - 1;
83
84 if (use_v_bound_) {
85 // speed limit constraints
86 // s_dot_i - v_bound_func_(s_i) <= 0.0
87 num_of_constraints_ += num_of_points_;
88 }
89
90 if (use_soft_safety_bound_) {
91 // soft safety boundary constraints
92 // s_i - soft_lower_s_i + lower_slack_i >= 0.0
93 num_of_constraints_ += num_of_points_;
94
95 // s_i - soft_upper_s_i - upper_slack_i <= 0.0
96 num_of_constraints_ += num_of_points_;
97 }
98
99 m = num_of_constraints_;
100
101 nnz_jac_g = 0;
102 // s_i+1 - s_i
103 nnz_jac_g += (num_of_points_ - 1) * 2;
104
105 // (s_ddot_i+1 - s_ddot_i) / delta_t
106 nnz_jac_g += (num_of_points_ - 1) * 2;
107
108 // s_i+1 - s_i - s_dot_i * delta_t - 1/3 * s_ddot_i * delta_t^2 - 1/6 *
109 // s_ddot_i+1 * delta_t^2
110 nnz_jac_g += (num_of_points_ - 1) * 5;
111
112 // s_dot_i+1 - s_dot_i - 0.5 * s_ddot_i * delta_t - 0.5 * s_ddot_i+1 * delta_t
113 nnz_jac_g += (num_of_points_ - 1) * 4;
114
115 if (use_v_bound_) {
116 // speed limit constraints
117 // s_dot_i - v_bound_func_(s_i) <= 0.0
118 nnz_jac_g += num_of_points_ * 2;
119 }
120
121 if (use_soft_safety_bound_) {
122 // soft safety boundary constraints
123 // s_i - soft_lower_s_i + lower_slack_i >= 0.0
124 nnz_jac_g += num_of_points_ * 2;
125
126 // s_i - soft_upper_s_i - upper_slack_i <= 0.0
127 nnz_jac_g += num_of_points_ * 2;
128 }
129
130 nnz_h_lag = num_of_points_ * 5 - 1;
131
132 index_style = IndexStyleEnum::C_STYLE;
133
134 return true;
135}

◆ get_optimization_results()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::get_optimization_results ( std::vector< double > *  ptr_opt_s,
std::vector< double > *  ptr_opt_v,
std::vector< double > *  ptr_opt_a 
)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc915 行定义.

917 {
918 *ptr_opt_s = opt_s_;
919 *ptr_opt_v = opt_v_;
920 *ptr_opt_a = opt_a_;
921}

◆ get_starting_point()

bool apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::get_starting_point ( int  n,
bool  init_x,
double *  x,
bool  init_z,
double *  z_L,
double *  z_U,
int  m,
bool  init_lambda,
double *  lambda 
)
override

Method to return the starting point for the algorithm

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc245 行定义.

247 {
248 if (!x_warm_start_.empty()) {
249 for (int i = 0; i < num_of_points_; ++i) {
250 x[i] = x_warm_start_[i][0];
251 x[v_offset_ + i] = x_warm_start_[i][1];
252 x[a_offset_ + i] = x_warm_start_[i][2];
253 }
254 }
255
256 if (use_soft_safety_bound_) {
257 for (int i = 0; i < num_of_points_; ++i) {
258 x[lower_s_slack_offset_ + i] = 0.0;
259 x[upper_s_slack_offset_ + i] = 0.0;
260 }
261 }
262
263 return true;
264
265 // TODO(Jinyun): Implement better default warm start based on safety_bounds
266 for (int i = 0; i < num_of_points_; ++i) {
267 x[i] = std::min(5.0 * delta_t_ * i + s_init_, s_max_);
268 }
269 x[0] = s_init_;
270
271 for (int i = 0; i < num_of_points_; ++i) {
272 x[v_offset_ + i] = 5.0;
273 }
274 x[v_offset_] = s_dot_init_;
275
276 for (int i = 0; i < num_of_points_; ++i) {
277 x[a_offset_ + i] = 0.0;
278 }
279 x[a_offset_] = s_ddot_init_;
280
281 if (use_soft_safety_bound_) {
282 for (int i = 0; i < num_of_points_; ++i) {
283 x[lower_s_slack_offset_ + i] = 0.0;
284 x[upper_s_slack_offset_ + i] = 0.0;
285 }
286 }
287
288 return true;
289}

◆ set_curvature_curve()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_curvature_curve ( const PiecewiseJerkTrajectory1d curvature_curve)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc985 行定义.

986 {
987 curvature_curve_ = curvature_curve;
988}

◆ set_end_state_target()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_end_state_target ( const double  s_target,
const double  v_target,
const double  a_target 
)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1017 行定义.

1018 {
1019 s_target_ = s_target;
1020 v_target_ = v_target;
1021 a_target_ = a_target;
1022 has_end_state_target_ = true;
1023}

◆ set_reference_spatial_distance()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_reference_spatial_distance ( const std::vector< double > &  s_ref)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1067 行定义.

1068 {
1069 s_ref_ = s_ref;
1070}

◆ set_reference_speed()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_reference_speed ( const double  s_dot_ref)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc996 行定义.

997 {
998 v_ref_ = v_ref;
999}

◆ set_safety_bounds()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_safety_bounds ( const std::vector< std::pair< double, double > > &  safety_bounds)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1001 行定义.

1002 {
1003 safety_bounds_ = safety_bounds;
1004}

◆ set_soft_safety_bounds()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_soft_safety_bounds ( const std::vector< std::pair< double, double > > &  soft_safety_bounds)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1006 行定义.

1007 {
1008 soft_safety_bounds_ = soft_safety_bounds;
1009 use_soft_safety_bound_ = true;
1010}

◆ set_speed_limit_curve()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_speed_limit_curve ( const PiecewiseJerkTrajectory1d v_bound_f)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc990 行定义.

991 {
992 v_bound_func_ = v_bound_f;
993 use_v_bound_ = true;
994}

◆ set_w_overall_a()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_overall_a ( const double  w_overall_a)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1032 行定义.

1033 {
1034 w_overall_a_ = w_overall_a;
1035}

◆ set_w_overall_centripetal_acc()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_overall_centripetal_acc ( const double  w_overall_centripetal_acc)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1042 行定义.

1043 {
1044 w_overall_centripetal_acc_ = w_overall_centripetal_acc;
1045}

◆ set_w_overall_j()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_overall_j ( const double  w_overall_j)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1037 行定义.

1038 {
1039 w_overall_j_ = w_overall_j;
1040}

◆ set_w_reference_spatial_distance()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_reference_spatial_distance ( const double  w_ref_s)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1052 行定义.

1053 {
1054 w_ref_s_ = w_ref_s;
1055}

◆ set_w_reference_speed()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_reference_speed ( const double  w_reference_speed)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1047 行定义.

1048 {
1049 w_ref_v_ = w_reference_speed;
1050}

◆ set_w_soft_s_bound()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_soft_s_bound ( const double  w_soft_s_bound)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1057 行定义.

1058 {
1059 w_soft_s_bound_ = w_soft_s_bound;
1060}

◆ set_w_target_state()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_w_target_state ( const double  w_target_s,
const double  w_target_v,
const double  w_target_a 
)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1025 行定义.

1026 {
1027 w_target_s_ = w_target_s;
1028 w_target_v_ = w_target_v;
1029 w_target_a_ = w_target_a;
1030}

◆ set_warm_start()

void apollo::planning::PiecewiseJerkSpeedNonlinearIpoptInterface::set_warm_start ( const std::vector< std::vector< double > > &  speed_profile)

在文件 piecewise_jerk_speed_nonlinear_ipopt_interface.cc1062 行定义.

1063 {
1064 x_warm_start_ = speed_profile;
1065}

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