53 int &n,
int &m,
int &nnz_jac_g,
int &nnz_h_lag,
54 IndexStyleEnum &index_style) {
55 num_of_variables_ = num_of_points_ * 3;
57 if (use_soft_safety_bound_) {
59 num_of_variables_ += num_of_points_ * 2;
61 lower_s_slack_offset_ = num_of_points_ * 3;
63 upper_s_slack_offset_ = num_of_points_ * 4;
66 n = num_of_variables_;
69 num_of_constraints_ = num_of_points_ - 1;
73 num_of_constraints_ += num_of_points_ - 1;
78 num_of_constraints_ += num_of_points_ - 1;
82 num_of_constraints_ += num_of_points_ - 1;
87 num_of_constraints_ += num_of_points_;
90 if (use_soft_safety_bound_) {
93 num_of_constraints_ += num_of_points_;
96 num_of_constraints_ += num_of_points_;
99 m = num_of_constraints_;
103 nnz_jac_g += (num_of_points_ - 1) * 2;
106 nnz_jac_g += (num_of_points_ - 1) * 2;
110 nnz_jac_g += (num_of_points_ - 1) * 5;
113 nnz_jac_g += (num_of_points_ - 1) * 4;
118 nnz_jac_g += num_of_points_ * 2;
121 if (use_soft_safety_bound_) {
124 nnz_jac_g += num_of_points_ * 2;
127 nnz_jac_g += num_of_points_ * 2;
130 nnz_h_lag = num_of_points_ * 5 - 1;
132 index_style = IndexStyleEnum::C_STYLE;
138 int n,
double *x_l,
double *x_u,
int m,
double *g_l,
double *g_u) {
141 double LARGE_VELOCITY_VALUE = s_dot_max_;
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;
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;
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_;
168 if (use_soft_safety_bound_) {
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;
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;
184 for (
int i = 0; i + 1 < num_of_points_; ++i) {
186 g_u[i] = LARGE_VELOCITY_VALUE * delta_t_;
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_;
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;
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;
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;
225 if (use_soft_safety_bound_) {
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;
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;
246 int n,
bool init_x,
double *x,
bool init_z,
double *z_L,
double *z_U,
int m,
247 bool init_lambda,
double *lambda) {
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];
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;
266 for (
int i = 0; i < num_of_points_; ++i) {
267 x[i] = std::min(5.0 * delta_t_ * i + s_init_, s_max_);
271 for (
int i = 0; i < num_of_points_; ++i) {
272 x[v_offset_ + i] = 5.0;
274 x[v_offset_] = s_dot_init_;
276 for (
int i = 0; i < num_of_points_; ++i) {
277 x[a_offset_ + i] = 0.0;
279 x[a_offset_] = s_ddot_init_;
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;
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_;
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_;
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_;
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_;
320 for (
int i = 0; i < num_of_points_; ++i) {
321 double v = x[v_offset_ + 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_;
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_;
332 double v_diff = x[v_offset_ + num_of_points_ - 1] - v_target_;
333 obj_value += v_diff * v_diff * w_target_v_;
335 double a_diff = x[a_offset_ + num_of_points_ - 1] - a_target_;
336 obj_value += a_diff * a_diff * w_target_a_;
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_;
353 std::fill(grad_f, grad_f + n, 0.0);
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_;
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_;
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]);
374 grad_f[a_offset_ + num_of_points_ - 1] +=
376 (x[a_offset_ + num_of_points_ - 1] - x[a_offset_ + num_of_points_ - 2]);
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_;
384 for (
int i = 0; i < num_of_points_; ++i) {
385 double v = x[v_offset_ + i];
391 double kappa = curvature_curve_.
Evaluate(0, s);
392 double kappa_dot = curvature_curve_.
Evaluate(1, s);
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;
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_;
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_;
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_;
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_;
426 for (
int i = 0; i + 1 < num_of_points_; ++i) {
427 g[i] = x[offset + i + 1] - x[i];
430 offset += num_of_points_ - 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;
446 for (
int i = 0; i + 1 < num_of_points_; ++i) {
448 double s1 = x[i + 1];
450 double v0 = x[v_offset_ + i];
451 double v1 = x[v_offset_ + i + 1];
453 double a0 = x[a_offset_ + i];
454 double a1 = x[a_offset_ + i + 1];
456 double j = (a1 - a0) / t;
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);
464 offset += 3 * (num_of_points_ - 1);
468 int coffset_speed_limit = offset;
470 for (
int i = 0; i < num_of_points_; ++i) {
472 double s_dot = x[v_offset_ + i];
473 g[coffset_speed_limit + i] = s_dot - v_bound_func_.
Evaluate(0, s);
476 offset += num_of_points_;
479 if (use_soft_safety_bound_) {
481 int coffset_soft_lower_s = offset;
483 for (
int i = 0; i < num_of_points_; ++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;
489 offset += num_of_points_;
491 int coffset_soft_upper_s = offset;
493 for (
int i = 0; i < num_of_points_; ++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;
500 offset += num_of_points_;
507 int n,
const double *x,
bool new_x,
int m,
int nele_jac,
int *iRow,
508 int *jCol,
double *values) {
509 if (values ==
nullptr) {
510 int non_zero_index = 0;
511 int constraint_index = 0;
514 for (
int i = 0; i + 1 < num_of_points_; ++i) {
516 iRow[non_zero_index] = constraint_index;
517 jCol[non_zero_index] = i;
521 iRow[non_zero_index] = constraint_index;
522 jCol[non_zero_index] = i + 1;
529 for (
int i = 0; i + 1 < num_of_points_; ++i) {
531 iRow[non_zero_index] = constraint_index;
532 jCol[non_zero_index] = a_offset_ + i;
536 iRow[non_zero_index] = constraint_index;
537 jCol[non_zero_index] = a_offset_ + i + 1;
544 for (
int i = 0; i + 1 < num_of_points_; ++i) {
546 iRow[non_zero_index] = constraint_index;
547 jCol[non_zero_index] = i;
551 iRow[non_zero_index] = constraint_index;
552 jCol[non_zero_index] = v_offset_ + i;
556 iRow[non_zero_index] = constraint_index;
557 jCol[non_zero_index] = a_offset_ + i;
561 iRow[non_zero_index] = constraint_index;
562 jCol[non_zero_index] = i + 1;
566 iRow[non_zero_index] = constraint_index;
567 jCol[non_zero_index] = a_offset_ + i + 1;
574 for (
int i = 0; i + 1 < num_of_points_; ++i) {
576 iRow[non_zero_index] = constraint_index;
577 jCol[non_zero_index] = v_offset_ + i;
581 iRow[non_zero_index] = constraint_index;
582 jCol[non_zero_index] = a_offset_ + i;
586 iRow[non_zero_index] = constraint_index;
587 jCol[non_zero_index] = v_offset_ + i + 1;
591 iRow[non_zero_index] = constraint_index;
592 jCol[non_zero_index] = a_offset_ + i + 1;
601 for (
int i = 0; i < num_of_points_; ++i) {
603 iRow[non_zero_index] = constraint_index;
604 jCol[non_zero_index] = i;
608 iRow[non_zero_index] = constraint_index;
609 jCol[non_zero_index] = v_offset_ + i;
616 if (use_soft_safety_bound_) {
619 for (
int i = 0; i < num_of_points_; ++i) {
621 iRow[non_zero_index] = constraint_index;
622 jCol[non_zero_index] = i;
626 iRow[non_zero_index] = constraint_index;
627 jCol[non_zero_index] = lower_s_slack_offset_ + i;
634 for (
int i = 0; i < num_of_points_; ++i) {
636 iRow[non_zero_index] = constraint_index;
637 jCol[non_zero_index] = i;
641 iRow[non_zero_index] = constraint_index;
642 jCol[non_zero_index] = upper_s_slack_offset_ + i;
650 int non_zero_index = 0;
652 for (
int i = 0; i + 1 < num_of_points_; ++i) {
654 values[non_zero_index] = -1.0;
658 values[non_zero_index] = 1.0;
663 for (
int i = 0; i + 1 < num_of_points_; ++i) {
665 values[non_zero_index] = -1.0 / delta_t_;
669 values[non_zero_index] = 1.0 / delta_t_;
674 for (
int i = 0; i + 1 < num_of_points_; ++i) {
676 values[non_zero_index] = -1.0;
680 values[non_zero_index] = -delta_t_;
684 values[non_zero_index] = -1.0 / 3.0 * delta_t_ * delta_t_;
688 values[non_zero_index] = 1.0;
692 values[non_zero_index] = -1.0 / 6.0 * delta_t_ * delta_t_;
697 for (
int i = 0; i + 1 < num_of_points_; ++i) {
699 values[non_zero_index] = -1.0;
703 values[non_zero_index] = -0.5 * delta_t_;
707 values[non_zero_index] = 1.0;
711 values[non_zero_index] = -0.5 * delta_t_;
718 for (
int i = 0; i < num_of_points_; ++i) {
721 values[non_zero_index] = -1.0 * v_bound_func_.
Evaluate(1, s);
725 values[non_zero_index] = 1.0;
730 if (use_soft_safety_bound_) {
733 for (
int i = 0; i < num_of_points_; ++i) {
735 values[non_zero_index] = 1.0;
739 values[non_zero_index] = 1.0;
744 for (
int i = 0; i < num_of_points_; ++i) {
746 values[non_zero_index] = 1.0;
750 values[non_zero_index] = -1.0;
759 int n,
const double *x,
bool new_x,
double obj_factor,
int m,
760 const double *lambda,
bool new_lambda,
int nele_hess,
int *iRow,
int *jCol,
762 if (values ==
nullptr) {
764 for (
int i = 0; i < num_of_points_; ++i) {
770 for (
int i = 0; i < num_of_points_; ++i) {
772 jCol[nz_index] = v_offset_ + i;
776 for (
int i = 0; i < num_of_points_; ++i) {
777 iRow[nz_index] = v_offset_ + i;
778 jCol[nz_index] = v_offset_ + i;
782 for (
int i = 0; i < num_of_points_; ++i) {
783 iRow[nz_index] = a_offset_ + i;
784 jCol[nz_index] = a_offset_ + i;
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;
794 for (
int i = 0; i < nz_index; ++i) {
797 hessian_mapper_[to_hash_key(r, c)] = i;
801 std::fill(values, values + nele_hess, 0.0);
804 for (
int i = 0; i < num_of_points_; ++i) {
806 auto v_index = v_offset_ + i;
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);
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;
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;
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;
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;
844 int lambda_offset = 4 * (num_of_points_ - 1);
845 for (
int i = 0; i < num_of_points_; ++i) {
850 auto v_bound_ddot = v_bound_func_.
Evaluate(2, s);
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];
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;
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;
869 auto h_a0_a0_index = hessian_mapper_[to_hash_key(a0_index, a0_index)];
870 values[h_a0_a0_index] += c;
872 auto h_a0_a1_index = hessian_mapper_[to_hash_key(a0_index, a1_index)];
873 values[h_a0_a1_index] += -c;
875 auto h_a1_a1_index = hessian_mapper_[to_hash_key(a1_index, a1_index)];
876 values[h_a1_a1_index] += c;
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;
886 if (has_end_state_target_) {
888 auto s_end_index = num_of_points_ - 1;
889 auto s_key = to_hash_key(s_end_index, s_end_index);
891 auto s_index = hessian_mapper_[s_key];
893 values[s_index] += 2.0 * w_target_s_ * obj_factor;
896 auto v_end_index = 2 * num_of_points_ - 1;
897 auto v_key = to_hash_key(v_end_index, v_end_index);
899 auto v_index = hessian_mapper_[v_key];
901 values[v_index] += 2.0 * w_target_v_ * obj_factor;
904 auto a_end_index = 3 * num_of_points_ - 1;
905 auto a_key = to_hash_key(a_end_index, a_end_index);
907 auto a_index = hessian_mapper_[a_key];
909 values[a_index] += 2.0 * w_target_a_ * obj_factor;
924 Ipopt::SolverReturn status,
int n,
const double *x,
const double *z_L,
925 const double *z_U,
int m,
const double *g,
const double *lambda,
926 double obj_value,
const Ipopt::IpoptData *ip_data,
927 Ipopt::IpoptCalculatedQuantities *ip_cq) {
932 for (
int i = 0; i < num_of_points_; ++i) {
934 double v = x[v_offset_ + i];
935 double a = x[a_offset_ + i];
942 if (use_soft_safety_bound_) {
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;
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];
955 lower_s_mean_intrusion += lower_s_slack;
956 upper_s_mean_intrusion += upper_s_slack;
958 if (lower_s_highest_intrusion < lower_s_slack) {
959 lower_s_highest_intrusion = lower_s_slack;
960 lower_s_highest_intrustion_index = i;
963 if (upper_s_highest_intrusion < upper_s_slack) {
964 upper_s_highest_intrusion = upper_s_slack;
965 upper_s_highest_intrustion_index = i;
969 lower_s_mean_intrusion /=
static_cast<double>(num_of_points_);
970 upper_s_mean_intrusion /=
static_cast<double>(num_of_points_);
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)
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)