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

#include <dual_variable_warm_start_ipopt_interface.h>

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

Public 成员函数

 DualVariableWarmStartIPOPTInterface (size_t horizon, double ts, const Eigen::MatrixXd &ego, const Eigen::MatrixXi &obstacles_edges_num, const size_t obstacles_num, const Eigen::MatrixXd &obstacles_A, const Eigen::MatrixXd &obstacles_b, const Eigen::MatrixXd &xWS, const PlannerOpenSpaceConfig &planner_open_space_config)
 
virtual ~DualVariableWarmStartIPOPTInterface ()=default
 
void get_optimization_results (Eigen::MatrixXd *l_warm_up, Eigen::MatrixXd *n_warm_up) const
 
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
 
template<class T >
bool eval_obj (int n, const T *x, T *obj_value)
 Template to return the objective value
 
template<class T >
bool eval_constraints (int n, const T *x, int m, T *g)
 Template to compute constraints
 
void generate_tapes (int n, int m, int *nnz_h_lag)
 Method to generate the required tapes
 
 DualVariableWarmStartIPOPTInterface (size_t horizon, double ts, const Eigen::MatrixXd &ego, const Eigen::MatrixXi &obstacles_edges_num, const size_t obstacles_num, const Eigen::MatrixXd &obstacles_A, const Eigen::MatrixXd &obstacles_b, const Eigen::MatrixXd &xWS, const DualVariableWarmStartConfig &dual_variable_warm_start_config)
 

详细描述

构造及析构函数说明

◆ DualVariableWarmStartIPOPTInterface() [1/2]

apollo::planning::DualVariableWarmStartIPOPTInterface::DualVariableWarmStartIPOPTInterface ( size_t  horizon,
double  ts,
const Eigen::MatrixXd &  ego,
const Eigen::MatrixXi &  obstacles_edges_num,
const size_t  obstacles_num,
const Eigen::MatrixXd &  obstacles_A,
const Eigen::MatrixXd &  obstacles_b,
const Eigen::MatrixXd &  xWS,
const PlannerOpenSpaceConfig planner_open_space_config 
)

在文件 dual_variable_warm_start_ipopt_interface.cc32 行定义.

38 : ts_(ts),
39 ego_(ego),
40 obstacles_edges_num_(obstacles_edges_num),
41 obstacles_A_(obstacles_A),
42 obstacles_b_(obstacles_b),
43 xWS_(xWS) {
44 ACHECK(horizon < std::numeric_limits<int>::max())
45 << "Invalid cast on horizon in open space planner";
46 horizon_ = static_cast<int>(horizon);
47 ACHECK(obstacles_num < std::numeric_limits<int>::max())
48 << "Invalid cast on obstacles_num in open space planner";
49 obstacles_num_ = static_cast<int>(obstacles_num);
50 w_ev_ = ego_(1, 0) + ego_(3, 0);
51 l_ev_ = ego_(0, 0) + ego_(2, 0);
52 g_ = {l_ev_ / 2, w_ev_ / 2, l_ev_ / 2, w_ev_ / 2};
53 offset_ = (ego_(0, 0) + ego_(2, 0)) / 2 - ego_(2, 0);
54 obstacles_edges_sum_ = obstacles_edges_num_.sum();
55 l_start_index_ = 0;
56 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
57 d_start_index_ = n_start_index_ + 4 * obstacles_num_ * (horizon_ + 1);
58 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
59 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
60 weight_d_ =
61 planner_open_space_config.dual_variable_warm_start_config().weight_d();
62}
#define ACHECK(cond)
Definition log.h:80

◆ ~DualVariableWarmStartIPOPTInterface()

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

◆ DualVariableWarmStartIPOPTInterface() [2/2]

apollo::planning::DualVariableWarmStartIPOPTInterface::DualVariableWarmStartIPOPTInterface ( size_t  horizon,
double  ts,
const Eigen::MatrixXd &  ego,
const Eigen::MatrixXi &  obstacles_edges_num,
const size_t  obstacles_num,
const Eigen::MatrixXd &  obstacles_A,
const Eigen::MatrixXd &  obstacles_b,
const Eigen::MatrixXd &  xWS,
const DualVariableWarmStartConfig dual_variable_warm_start_config 
)

成员函数说明

◆ eval_constraints()

template<class T >
bool apollo::planning::DualVariableWarmStartIPOPTInterface::eval_constraints ( int  n,
const T *  x,
int  m,
T *  g 
)

Template to compute constraints

在文件 dual_variable_warm_start_ipopt_interface.cc610 行定义.

611 {
612 ADEBUG << "eval_constraints";
613 // state start index
614
615 // 1. Three obstacles related equal constraints, one equality constraints,
616 // [0, horizon_] * [0, obstacles_num_-1] * 4
617
618 int l_index = l_start_index_;
619 int n_index = n_start_index_;
620 int d_index = d_start_index_;
621 int constraint_index = 0;
622
623 for (int i = 0; i < horizon_ + 1; ++i) {
624 int edges_counter = 0;
625 // assume: stationary obstacles
626 for (int j = 0; j < obstacles_num_; ++j) {
627 int current_edges_num = obstacles_edges_num_(j, 0);
628 Eigen::MatrixXd Aj =
629 obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
630 Eigen::MatrixXd bj =
631 obstacles_b_.block(edges_counter, 0, current_edges_num, 1);
632
633 // norm(A* lambda) <= 1
634 T tmp1 = 0.0;
635 T tmp2 = 0.0;
636 for (int k = 0; k < current_edges_num; ++k) {
637 tmp1 += Aj(k, 0) * x[l_index + k];
638 tmp2 += Aj(k, 1) * x[l_index + k];
639 }
640 g[constraint_index] = tmp1 * tmp1 + tmp2 * tmp2;
641
642 // G' * mu + R' * A' * lambda == 0
643 g[constraint_index + 1] = x[n_index] - x[n_index + 2] +
644 cos(xWS_(2, i)) * tmp1 + sin(xWS_(2, i)) * tmp2;
645
646 g[constraint_index + 2] = x[n_index + 1] - x[n_index + 3] -
647 sin(xWS_(2, i)) * tmp1 + cos(xWS_(2, i)) * tmp2;
648
649 // d - (-g'*mu + (A*t - b)*lambda) = 0
650 // TODO(QiL): Need to revise according to dual modeling
651 T tmp3 = 0.0;
652 for (int k = 0; k < 4; ++k) {
653 tmp3 += g_[k] * x[n_index + k];
654 }
655
656 T tmp4 = 0.0;
657 for (int k = 0; k < current_edges_num; ++k) {
658 tmp4 += bj(k, 0) * x[l_index + k];
659 }
660
661 g[constraint_index + 3] =
662 x[d_index] + tmp3 - (xWS_(0, i) + cos(xWS_(2, i)) * offset_) * tmp1 -
663 (xWS_(1, i) + sin(xWS_(2, i)) * offset_) * tmp2 + tmp4;
664
665 // Update index
666 edges_counter += current_edges_num;
667 l_index += current_edges_num;
668 n_index += 4;
669 d_index += 1;
670 constraint_index += 4;
671 }
672 }
673 l_index = l_start_index_;
674 n_index = n_start_index_;
675 d_index = d_start_index_;
676 for (int i = 0; i < lambda_horizon_; ++i) {
677 g[constraint_index] = x[l_index];
678 constraint_index++;
679 l_index++;
680 }
681 for (int i = 0; i < miu_horizon_; ++i) {
682 g[constraint_index] = x[n_index];
683 constraint_index++;
684 n_index++;
685 }
686 for (int i = 0; i < dual_formulation_horizon_; ++i) {
687 g[constraint_index] = x[d_index];
688 constraint_index++;
689 d_index++;
690 }
691
692 CHECK_EQ(constraint_index, m)
693 << "No. of constraints wrong in eval_g. n : " << n;
694 return true;
695}
#define ADEBUG
Definition log.h:41
float cos(Angle16 a)
Definition angle.cc:42
float sin(Angle16 a)
Definition angle.cc:25

◆ eval_f()

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

Method to return the objective value

在文件 dual_variable_warm_start_ipopt_interface.cc227 行定义.

229 {
230 eval_obj(n, x, &obj_value);
231 return true;
232}
bool eval_obj(int n, const T *x, T *obj_value)
Template to return the objective value

◆ eval_g()

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

Method to return the constraint residuals

在文件 dual_variable_warm_start_ipopt_interface.cc250 行定义.

251 {
252 eval_constraints(n, x, m, g);
253 return true;
254}
bool eval_constraints(int n, const T *x, int m, T *g)
Template to compute constraints

◆ eval_grad_f()

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

Method to return the gradient of the objective

在文件 dual_variable_warm_start_ipopt_interface.cc234 行定义.

236 {
237 // gradient(tag_f, n, x, grad_f);
238 // return true;
239 std::fill(grad_f, grad_f + n, 0.0);
240 int d_index = d_start_index_;
241 for (int i = 0; i < horizon_ + 1; ++i) {
242 for (int j = 0; j < obstacles_num_; ++j) {
243 grad_f[d_index] = weight_d_;
244 ++d_index;
245 }
246 }
247 return true;
248}

◆ eval_h()

bool apollo::planning::DualVariableWarmStartIPOPTInterface::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)

在文件 dual_variable_warm_start_ipopt_interface.cc521 行定义.

526 {
527 if (values == nullptr) {
528 // return the structure. This is a symmetric matrix, fill the lower left
529 // triangle only.
530 for (int idx = 0; idx < nnz_L; idx++) {
531 iRow[idx] = rind_L[idx];
532 jCol[idx] = cind_L[idx];
533 }
534 } else {
535 // return the values. This is a symmetric matrix, fill the lower left
536 // triangle only
537 obj_lam[0] = obj_factor;
538 for (int idx = 0; idx < m; idx++) {
539 obj_lam[1 + idx] = lambda[idx];
540 }
541 set_param_vec(tag_L, m + 1, obj_lam);
542 sparse_hess(tag_L, n, 1, const_cast<double*>(x), &nnz_L, &rind_L, &cind_L,
543 &hessval, options_L);
544
545 for (int idx = 0; idx < nnz_L; idx++) {
546 values[idx] = hessval[idx];
547 }
548 }
549
550 return true;
551}
#define tag_L

◆ eval_jac_g()

bool apollo::planning::DualVariableWarmStartIPOPTInterface::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)

在文件 dual_variable_warm_start_ipopt_interface.cc256 行定义.

260 {
261 // if (values == nullptr) {
262 // // return the structure of the jacobian
263
264 // for (int idx = 0; idx < nnz_jac; idx++) {
265 // iRow[idx] = rind_g[idx];
266 // jCol[idx] = cind_g[idx];
267 // }
268 // } else {
269 // // return the values of the jacobian of the constraints
270
271 // sparse_jac(tag_g, m, n, 1, x, &nnz_jac, &rind_g, &cind_g, &jacval,
272 // options_g);
273
274 // for (int idx = 0; idx < nnz_jac; idx++) {
275 // values[idx] = jacval[idx];
276 // }
277 // }
278 // return true;
279 ADEBUG << "eval_jac_g";
280
281 if (values == nullptr) {
282 int nz_index = 0;
283 int constraint_index = 0;
284
285 // 1. Three obstacles related equal constraints, one equality
286 // constraints,
287 // [0, horizon_] * [0, obstacles_num_-1] * 4
288 int l_index = l_start_index_;
289 int n_index = n_start_index_;
290 int d_index = d_start_index_;
291 for (int i = 0; i < horizon_ + 1; ++i) {
292 for (int j = 0; j < obstacles_num_; ++j) {
293 int current_edges_num = obstacles_edges_num_(j, 0);
294
295 // 1. norm(A* lambda <= 1)
296 for (int k = 0; k < current_edges_num; ++k) {
297 // with respect to l
298 iRow[nz_index] = constraint_index;
299 jCol[nz_index] = l_index + k;
300 ++nz_index;
301 }
302
303 // 2. G' * mu + R' * lambda == 0, part 1
304 // with respect to l
305 for (int k = 0; k < current_edges_num; ++k) {
306 iRow[nz_index] = constraint_index + 1;
307 jCol[nz_index] = l_index + k;
308 ++nz_index;
309 }
310
311 // With respect to n
312 iRow[nz_index] = constraint_index + 1;
313 jCol[nz_index] = n_index;
314 ++nz_index;
315
316 iRow[nz_index] = constraint_index + 1;
317 jCol[nz_index] = n_index + 2;
318 ++nz_index;
319
320 // 2. G' * mu + R' * lambda == 0, part 2
321 // with respect to l
322 for (int k = 0; k < current_edges_num; ++k) {
323 iRow[nz_index] = constraint_index + 2;
324 jCol[nz_index] = l_index + k;
325 ++nz_index;
326 }
327
328 // With respect to n
329 iRow[nz_index] = constraint_index + 2;
330 jCol[nz_index] = n_index + 1;
331 ++nz_index;
332
333 iRow[nz_index] = constraint_index + 2;
334 jCol[nz_index] = n_index + 3;
335 ++nz_index;
336
337 // -g'*mu + (A*t - b)*lambda > 0
338 // with respect to l
339 for (int k = 0; k < current_edges_num; ++k) {
340 iRow[nz_index] = constraint_index + 3;
341 jCol[nz_index] = l_index + k;
342 ++nz_index;
343 }
344
345 // with respect to n
346 for (int k = 0; k < 4; ++k) {
347 iRow[nz_index] = constraint_index + 3;
348 jCol[nz_index] = n_index + k;
349 ++nz_index;
350 }
351
352 // with resepct to d
353 iRow[nz_index] = constraint_index + 3;
354 jCol[nz_index] = d_index;
355 ++nz_index;
356
357 // Update index
358 l_index += current_edges_num;
359 n_index += 4;
360 d_index += 1;
361 constraint_index += 4;
362 }
363 }
364
365 l_index = l_start_index_;
366 n_index = n_start_index_;
367 d_index = d_start_index_;
368 for (int i = 0; i < lambda_horizon_; ++i) {
369 iRow[nz_index] = constraint_index;
370 jCol[nz_index] = l_index;
371 ++nz_index;
372 ++constraint_index;
373 ++l_index;
374 }
375 for (int i = 0; i < miu_horizon_; ++i) {
376 iRow[nz_index] = constraint_index;
377 jCol[nz_index] = n_index;
378 ++nz_index;
379 ++constraint_index;
380 ++n_index;
381 }
382 for (int i = 0; i < dual_formulation_horizon_; ++i) {
383 iRow[nz_index] = constraint_index;
384 jCol[nz_index] = d_index;
385 ++nz_index;
386 ++constraint_index;
387 ++d_index;
388 }
389
390 CHECK_EQ(constraint_index, m) << "No. of constraints wrong in eval_jac_g.";
391
392 ADEBUG << "nz_index here : " << nz_index << " nele_jac is : " << nele_jac;
393 } else {
394 std::fill(values, values + nele_jac, 0.0);
395 int nz_index = 0;
396
397 // 1. Three obstacles related equal constraints, one equality
398 // constraints,
399 // [0, horizon_] * [0, obstacles_num_-1] * 4
400 int l_index = l_start_index_;
401 int n_index = n_start_index_;
402
403 for (int i = 0; i < horizon_ + 1; ++i) {
404 int edges_counter = 0;
405 for (int j = 0; j < obstacles_num_; ++j) {
406 int current_edges_num = obstacles_edges_num_(j, 0);
407 Eigen::MatrixXd Aj =
408 obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
409 Eigen::MatrixXd bj =
410 obstacles_b_.block(edges_counter, 0, current_edges_num, 1);
411
412 // TODO(QiL) : Remove redundant calculation
413 double tmp1 = 0;
414 double tmp2 = 0;
415 for (int k = 0; k < current_edges_num; ++k) {
416 // TODO(QiL) : replace this one directly with x
417 tmp1 += Aj(k, 0) * x[l_index + k];
418 tmp2 += Aj(k, 1) * x[l_index + k];
419 }
420
421 // 1. norm(A* lambda == 1)
422 for (int k = 0; k < current_edges_num; ++k) {
423 // with respect to l
424 values[nz_index] =
425 2 * tmp1 * Aj(k, 0) + 2 * tmp2 * Aj(k, 1); // t0~tk
426 ++nz_index;
427 }
428
429 // 2. G' * mu + R' * lambda == 0, part 1
430
431 // with respect to l
432 for (int k = 0; k < current_edges_num; ++k) {
433 values[nz_index] = std::cos(xWS_(2, i)) * Aj(k, 0) +
434 std::sin(xWS_(2, i)) * Aj(k, 1); // v0~vn
435 ++nz_index;
436 }
437
438 // With respect to n
439 values[nz_index] = 1.0; // w0
440 ++nz_index;
441
442 values[nz_index] = -1.0; // w2
443 ++nz_index;
444
445 ADEBUG << "eval_jac_g, after adding part 2";
446 // 3. G' * mu + R' * lambda == 0, part 2
447
448 // with respect to l
449 for (int k = 0; k < current_edges_num; ++k) {
450 values[nz_index] = -std::sin(xWS_(2, i)) * Aj(k, 0) +
451 std::cos(xWS_(2, i)) * Aj(k, 1); // y0~yn
452 ++nz_index;
453 }
454
455 // With respect to n
456 values[nz_index] = 1.0; // z1
457 ++nz_index;
458
459 values[nz_index] = -1.0; // z3
460 ++nz_index;
461
462 // 3. -g'*mu + (A*t - b)*lambda > 0
463 // TODO(QiL): Revise dual variables modeling here.
464 double tmp3 = 0.0;
465 double tmp4 = 0.0;
466 for (int k = 0; k < 4; ++k) {
467 tmp3 += -g_[k] * x[n_index + k];
468 }
469
470 for (int k = 0; k < current_edges_num; ++k) {
471 tmp4 += bj(k, 0) * x[l_index + k];
472 }
473
474 // with respect to l
475 for (int k = 0; k < current_edges_num; ++k) {
476 values[nz_index] =
477 -(xWS_(0, i) + std::cos(xWS_(2, i)) * offset_) * Aj(k, 0) -
478 (xWS_(1, i) + std::sin(xWS_(2, i)) * offset_) * Aj(k, 1) +
479 bj(k, 0); // ddk
480 ++nz_index;
481 }
482
483 // with respect to n
484 for (int k = 0; k < 4; ++k) {
485 values[nz_index] = g_[k]; // eek
486 ++nz_index;
487 }
488
489 // with respect to d
490 values[nz_index] = 1.0; // ffk
491 ++nz_index;
492
493 // Update index
494 edges_counter += current_edges_num;
495 l_index += current_edges_num;
496 n_index += 4;
497 }
498 }
499
500 for (int i = 0; i < lambda_horizon_; ++i) {
501 values[nz_index] = 1.0;
502 ++nz_index;
503 }
504 for (int i = 0; i < miu_horizon_; ++i) {
505 values[nz_index] = 1.0;
506 ++nz_index;
507 }
508 for (int i = 0; i < dual_formulation_horizon_; ++i) {
509 values[nz_index] = 1.0;
510 ++nz_index;
511 }
512
513 ADEBUG << "eval_jac_g, fulfilled obstacle constraint values";
514 CHECK_EQ(nz_index, nele_jac);
515 }
516
517 ADEBUG << "eval_jac_g done";
518 return true;
519}

◆ eval_obj()

template<class T >
bool apollo::planning::DualVariableWarmStartIPOPTInterface::eval_obj ( int  n,
const T *  x,
T *  obj_value 
)

Template to return the objective value

在文件 dual_variable_warm_start_ipopt_interface.cc594 行定义.

595 {
596 ADEBUG << "eval_obj";
597 *obj_value = 0.0;
598 int d_index = d_start_index_;
599 for (int i = 0; i < horizon_ + 1; ++i) {
600 for (int j = 0; j < obstacles_num_; ++j) {
601 *obj_value += weight_d_ * x[d_index];
602 ++d_index;
603 }
604 }
605 return true;
606}

◆ finalize_solution()

void apollo::planning::DualVariableWarmStartIPOPTInterface::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

在文件 dual_variable_warm_start_ipopt_interface.cc553 行定义.

557 {
558 int variable_index = 0;
559 // 1. lagrange constraint l, [0, obstacles_edges_sum_ - 1] * [0,
560 // horizon_]
561 for (int i = 0; i < horizon_ + 1; ++i) {
562 for (int j = 0; j < obstacles_edges_sum_; ++j) {
563 l_warm_up_(j, i) = x[variable_index];
564 ++variable_index;
565 }
566 }
567 ADEBUG << "variable_index after adding lagrange l : " << variable_index;
568
569 // 2. lagrange constraint n, [0, 4*obstacles_num-1] * [0, horizon_]
570 for (int i = 0; i < horizon_ + 1; ++i) {
571 for (int j = 0; j < 4 * obstacles_num_; ++j) {
572 n_warm_up_(j, i) = x[variable_index];
573 ++variable_index;
574 }
575 }
576 ADEBUG << "variable_index after adding lagrange n : " << variable_index;
577
578 // memory deallocation of ADOL-C variables
579 delete[] obj_lam;
580 free(rind_L);
581 free(cind_L);
582 free(hessval);
583}

◆ generate_tapes()

void apollo::planning::DualVariableWarmStartIPOPTInterface::generate_tapes ( int  n,
int  m,
int *  nnz_h_lag 
)

Method to generate the required tapes

在文件 dual_variable_warm_start_ipopt_interface.cc698 行定义.

699 {
700 std::vector<double> xp(n);
701 std::vector<double> lamp(m);
702 std::vector<double> zl(m);
703 std::vector<double> zu(m);
704
705 std::vector<adouble> xa(n);
706 std::vector<adouble> g(m);
707 std::vector<double> lam(m);
708 double sig = 0.0;
709 adouble obj_value;
710
711 double dummy = 0.0;
712
713 obj_lam = new double[m + 1];
714
715 get_starting_point(n, 1, &xp[0], 0, &zl[0], &zu[0], m, 0, &lamp[0]);
716
717 // trace_on(tag_f);
718
719 // for (int idx = 0; idx < n; idx++) xa[idx] <<= xp[idx];
720
721 // eval_obj(n, xa, &obj_value);
722
723 // obj_value >>= dummy;
724
725 // trace_off();
726
727 // trace_on(tag_g);
728
729 // for (int idx = 0; idx < n; idx++) xa[idx] <<= xp[idx];
730
731 // eval_constraints(n, xa, m, g);
732
733 // for (int idx = 0; idx < m; idx++) g[idx] >>= dummy;
734
735 // trace_off();
736
737 trace_on(tag_L);
738
739 for (int idx = 0; idx < n; idx++) {
740 xa[idx] <<= xp[idx];
741 }
742 for (int idx = 0; idx < m; idx++) {
743 lam[idx] = 1.0;
744 }
745 sig = 1.0;
746
747 eval_obj(n, &xa[0], &obj_value);
748
749 obj_value *= mkparam(sig);
750 eval_constraints(n, &xa[0], m, &g[0]);
751
752 for (int idx = 0; idx < m; idx++) {
753 obj_value += g[idx] * mkparam(lam[idx]);
754 }
755
756 obj_value >>= dummy;
757
758 trace_off();
759
760 rind_L = nullptr;
761 cind_L = nullptr;
762
763 hessval = nullptr;
764
765 options_L[0] = 0;
766 options_L[1] = 1;
767
768 sparse_hess(tag_L, n, 0, &xp[0], &nnz_L, &rind_L, &cind_L, &hessval,
769 options_L);
770 *nnz_h_lag = nnz_L;
771}
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

◆ get_bounds_info()

bool apollo::planning::DualVariableWarmStartIPOPTInterface::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

在文件 dual_variable_warm_start_ipopt_interface.cc141 行定义.

144 {
145 int variable_index = 0;
146 // 1. lagrange constraint l, [0, obstacles_edges_sum_ - 1] * [0,
147 // horizon_]
148 for (int i = 0; i < horizon_ + 1; ++i) {
149 for (int j = 0; j < obstacles_edges_sum_; ++j) {
150 x_l[variable_index] = -2e19;
151 x_u[variable_index] = 2e19;
152 ++variable_index;
153 }
154 }
155 ADEBUG << "variable_index after adding lagrange l : " << variable_index;
156
157 // 2. lagrange constraint n, [0, 4*obstacles_num-1] * [0, horizon_]
158 for (int i = 0; i < horizon_ + 1; ++i) {
159 for (int j = 0; j < 4 * obstacles_num_; ++j) {
160 x_l[variable_index] = -2e19;
161 x_u[variable_index] = 2e19; // nlp_upper_bound_limit
162 ++variable_index;
163 }
164 }
165 ADEBUG << "variable_index after adding lagrange n : " << variable_index;
166
167 // 3. d, [0, obstacles_num-1] * [0, horizon_]
168 for (int i = 0; i < horizon_ + 1; ++i) {
169 for (int j = 0; j < obstacles_num_; ++j) {
170 // TODO(QiL): Load this from configuration
171 x_l[variable_index] = -2e19;
172 x_u[variable_index] = 2e19; // nlp_upper_bound_limit
173 ++variable_index;
174 }
175 }
176 ADEBUG << "variable_index after adding d : " << variable_index;
177
178 int constraint_index = 0;
179 for (int i = 0; i < horizon_ + 1; ++i) {
180 for (int j = 0; j < obstacles_num_; ++j) {
181 // a. norm(A'*lambda) <= 1
182 g_l[constraint_index] = -2e19;
183 g_u[constraint_index] = 1.0;
184
185 // b. G'*mu + R'*A*lambda = 0
186 g_l[constraint_index + 1] = 0.0;
187 g_u[constraint_index + 1] = 0.0;
188 g_l[constraint_index + 2] = 0.0;
189 g_u[constraint_index + 2] = 0.0;
190
191 // c. d - (-g'*mu + (A*t - b)*lambda) = 0
192 g_l[constraint_index + 3] = 0.0;
193 g_u[constraint_index + 3] = 0.0;
194 constraint_index += 4;
195 }
196 }
197
198 int l_index = l_start_index_;
199 int n_index = n_start_index_;
200 int d_index = d_start_index_;
201
202 for (int i = 0; i < lambda_horizon_; ++i) {
203 g_l[constraint_index] = 0.0;
204 g_u[constraint_index] = 2e19;
205 constraint_index++;
206 l_index++;
207 }
208 for (int i = 0; i < miu_horizon_; ++i) {
209 g_l[constraint_index] = 0.0;
210 g_u[constraint_index] = 2e19;
211 constraint_index++;
212 n_index++;
213 }
214 for (int i = 0; i < dual_formulation_horizon_; ++i) {
215 g_l[constraint_index] = 0.0;
216 g_u[constraint_index] = 2e19;
217 constraint_index++;
218 d_index++;
219 }
220
221 ADEBUG << "constraint_index after adding obstacles constraints: "
222 << constraint_index;
223
224 return true;
225}

◆ get_nlp_info()

bool apollo::planning::DualVariableWarmStartIPOPTInterface::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

在文件 dual_variable_warm_start_ipopt_interface.cc64 行定义.

66 {
67 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
68
69 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
70
71 dual_formulation_horizon_ = obstacles_num_ * (horizon_ + 1);
72
73 num_of_variables_ =
74 lambda_horizon_ + miu_horizon_ + dual_formulation_horizon_;
75
76 num_of_constraints_ = 4 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
77
78 // number of variables
79 n = num_of_variables_;
80
81 // number of constraints
82 m = num_of_constraints_;
83
84 // number of nonzero Jacobian and Lagrangian.
85 generate_tapes(n, m, &nnz_h_lag);
86
87 int tmp = 0;
88 for (int i = 0; i < horizon_ + 1; ++i) {
89 for (int j = 0; j < obstacles_num_; ++j) {
90 int current_edges_num = obstacles_edges_num_(j, 0);
91 tmp += current_edges_num * 4 + 2 + 2 + 4 + 1;
92 }
93 }
94 nnz_jac_g = tmp + num_of_variables_;
95
96 ADEBUG << "nnz_jac_g : " << nnz_jac_g;
97 index_style = IndexStyleEnum::C_STYLE;
98 return true;
99}
void generate_tapes(int n, int m, int *nnz_h_lag)
Method to generate the required tapes

◆ get_optimization_results()

void apollo::planning::DualVariableWarmStartIPOPTInterface::get_optimization_results ( Eigen::MatrixXd *  l_warm_up,
Eigen::MatrixXd *  n_warm_up 
) const

在文件 dual_variable_warm_start_ipopt_interface.cc585 行定义.

586 {
587 *l_warm_up = l_warm_up_;
588 *n_warm_up = n_warm_up_;
589}

◆ get_starting_point()

bool apollo::planning::DualVariableWarmStartIPOPTInterface::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

在文件 dual_variable_warm_start_ipopt_interface.cc101 行定义.

103 {
104 ADEBUG << "get_starting_point";
105 ACHECK(init_x) << "Warm start init_x setting failed";
106 ACHECK(!init_z) << "Warm start init_z setting failed";
107 ACHECK(!init_lambda) << "Warm start init_lambda setting failed";
108
109 int l_index = l_start_index_;
110 int n_index = n_start_index_;
111 int d_index = d_start_index_;
112 ADEBUG << "l_start_index_ : " << l_start_index_;
113 ADEBUG << "n_start_index_ : " << n_start_index_;
114 ADEBUG << "d_start_index_ : " << d_start_index_;
115 // 1. lagrange constraint l, obstacles_edges_sum_ * (horizon_+1)
116 for (int i = 0; i < horizon_ + 1; ++i) {
117 for (int j = 0; j < obstacles_edges_sum_; ++j) {
118 x[l_index] = 0.0;
119 ++l_index;
120 }
121 }
122
123 // 2. lagrange constraint n, 4*obstacles_num * (horizon_+1)
124 for (int i = 0; i < horizon_ + 1; ++i) {
125 for (int j = 0; j < 4 * obstacles_num_; ++j) {
126 x[n_index] = 0.0;
127 ++n_index;
128 }
129 }
130 // 3. d, [0, obstacles_num] * [0, horizon_]
131 for (int i = 0; i < horizon_ + 1; ++i) {
132 for (int j = 0; j < obstacles_num_; ++j) {
133 x[d_index] = 0.0;
134 ++d_index;
135 }
136 }
137 ADEBUG << "get_starting_point out";
138 return true;
139}

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