36 const Eigen::MatrixXd& ego,
37 const Eigen::MatrixXi& obstacles_edges_num,
38 const size_t obstacles_num,
39 const Eigen::MatrixXd& obstacles_A,
40 const Eigen::MatrixXd& obstacles_b,
41 const Eigen::MatrixXd& xWS,
45 obstacles_edges_num_(obstacles_edges_num),
46 obstacles_A_(obstacles_A),
47 obstacles_b_(obstacles_b),
49 ACHECK(horizon < std::numeric_limits<int>::max()) <<
"Invalid cast on horizon in open space planner";
50 horizon_ =
static_cast<int>(horizon);
51 ACHECK(obstacles_num < std::numeric_limits<int>::max()) <<
"Invalid cast on obstacles_num in open space planner";
52 obstacles_num_ =
static_cast<int>(obstacles_num);
53 w_ev_ = ego_(1, 0) + ego_(3, 0);
54 l_ev_ = ego_(0, 0) + ego_(2, 0);
55 g_ = {l_ev_ / 2, w_ev_ / 2, l_ev_ / 2, w_ev_ / 2};
56 offset_ = (ego_(0, 0) + ego_(2, 0)) / 2 - ego_(2, 0);
57 obstacles_edges_sum_ = obstacles_edges_num_.sum();
60 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
61 s_start_index_ = n_start_index_ + 4 * obstacles_num_ * (horizon_ + 1);
63 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
64 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
65 slacks_ = Eigen::MatrixXd::Zero(obstacles_num_, horizon_ + 1);
68 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
69 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
70 slack_horizon_ = obstacles_num_ * (horizon_ + 1);
73 num_of_variables_ = lambda_horizon_ + miu_horizon_ + slack_horizon_;
75 num_of_constraints_ = 3 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
86 const Eigen::MatrixXd& ego,
87 const Eigen::MatrixXi& obstacles_edges_num,
88 const size_t obstacles_num,
89 const Eigen::MatrixXd& obstacles_A,
90 const Eigen::MatrixXd& obstacles_b,
91 const Eigen::MatrixXd& xWS,
95 obstacles_edges_num_(obstacles_edges_num),
96 obstacles_A_(obstacles_A),
97 obstacles_b_(obstacles_b),
99 ACHECK(horizon < std::numeric_limits<int>::max()) <<
"Invalid cast on horizon in open space planner";
100 horizon_ =
static_cast<int>(horizon);
101 ACHECK(obstacles_num < std::numeric_limits<int>::max()) <<
"Invalid cast on obstacles_num in open space planner";
102 obstacles_num_ =
static_cast<int>(obstacles_num);
103 w_ev_ = ego_(1, 0) + ego_(3, 0);
104 l_ev_ = ego_(0, 0) + ego_(2, 0);
105 g_ = {l_ev_ / 2, w_ev_ / 2, l_ev_ / 2, w_ev_ / 2};
106 offset_ = (ego_(0, 0) + ego_(2, 0)) / 2 - ego_(2, 0);
107 obstacles_edges_sum_ = obstacles_edges_num_.sum();
110 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
111 s_start_index_ = n_start_index_ + 4 * obstacles_num_ * (horizon_ + 1);
113 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
114 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
115 slacks_ = Eigen::MatrixXd::Zero(obstacles_num_, horizon_ + 1);
118 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
119 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
120 slack_horizon_ = obstacles_num_ * (horizon_ + 1);
123 num_of_variables_ = lambda_horizon_ + miu_horizon_ + slack_horizon_;
125 num_of_constraints_ = 3 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
128 check_mode_ = dual_variable_warm_start_config.
debug_osqp();
129 beta_ = dual_variable_warm_start_config.
beta();
130 osqp_config_ = dual_variable_warm_start_config.
osqp_config();
188 std::vector<c_float> P_data;
189 std::vector<c_int> P_indices;
190 std::vector<c_int> P_indptr;
191 assembleP(&P_data, &P_indices, &P_indptr);
193 AINFO <<
"print P_data in whole: ";
194 printMatrix(num_of_variables_, num_of_variables_, P_data, P_indices, P_indptr);
197 c_float q[num_of_variables_];
198 for (
int i = 0; i < num_of_variables_; ++i) {
200 if (i >= s_start_index_) {
206 std::vector<c_float> A_data;
207 std::vector<c_int> A_indices;
208 std::vector<c_int> A_indptr;
211 AINFO <<
"print A_data in whole: ";
212 printMatrix(num_of_constraints_, num_of_variables_, A_data, A_indices, A_indptr);
213 assembleA(num_of_constraints_, num_of_variables_, A_data, A_indices, A_indptr);
217 c_float lb[num_of_constraints_];
218 c_float ub[num_of_constraints_];
219 int slack_indx = num_of_constraints_ - slack_horizon_;
220 for (
int i = 0; i < num_of_constraints_; ++i) {
222 if (i >= slack_indx) {
226 if (i < 2 * obstacles_num_ * (horizon_ + 1)) {
228 }
else if (i < slack_indx) {
236 OSQPSettings* settings =
reinterpret_cast<OSQPSettings*
>(c_malloc(
sizeof(OSQPSettings)));
239 osqp_set_default_settings(settings);
240 settings->alpha = osqp_config_.
alpha();
241 settings->eps_abs = osqp_config_.
eps_abs();
242 settings->eps_rel = osqp_config_.
eps_rel();
243 settings->max_iter = osqp_config_.
max_iter();
244 settings->polish = osqp_config_.
polish();
248 OSQPData* data =
reinterpret_cast<OSQPData*
>(c_malloc(
sizeof(OSQPData)));
249 data->n = num_of_variables_;
250 data->m = num_of_constraints_;
251 data->P = csc_matrix(data->n, data->n, P_data.size(), P_data.data(), P_indices.data(), P_indptr.data());
253 data->A = csc_matrix(data->m, data->n, A_data.size(), A_data.data(), A_indices.data(), A_indptr.data());
258 OSQPWorkspace* work =
nullptr;
260 work = osqp_setup(data, settings);
266 if (work->info->status_val != 1 && work->info->status_val != 2) {
267 AWARN <<
"OSQP dual warm up unsuccess, "
268 <<
"return status: " << work->info->status;
273 std::vector<double> lambda_norm;
274 int l_index = l_start_index_;
275 for (
int i = 0; i < horizon_ + 1; ++i) {
276 int edges_counter = 0;
277 for (
int j = 0; j < obstacles_num_; ++j) {
278 int current_edges_num = obstacles_edges_num_(j, 0);
279 Eigen::MatrixXd Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
283 for (
int k = 0; k < current_edges_num; ++k) {
284 tmp1 += Aj(k, 0) * work->solution->x[l_index + k];
285 tmp2 += Aj(k, 1) * work->solution->x[l_index + k];
289 double tmp_norm = tmp1 * tmp1 + tmp2 * tmp2;
290 if (tmp_norm >= 1e-5) {
291 lambda_norm.push_back(0.75 / std::sqrt(tmp_norm));
293 lambda_norm.push_back(0.0);
296 edges_counter += current_edges_num;
297 l_index += current_edges_num;
302 int variable_index = 0;
305 for (
int i = 0; i < horizon_ + 1; ++i) {
307 for (
int j = 0; j < obstacles_num_; ++j) {
308 for (
int k = 0; k < obstacles_edges_num_(j, 0); ++k) {
309 l_warm_up_(r_index, i) = lambda_norm[i * obstacles_num_ + j] * work->solution->x[variable_index];
317 for (
int i = 0; i < horizon_ + 1; ++i) {
319 for (
int j = 0; j < obstacles_num_; ++j) {
320 for (
int k = 0; k < 4; ++k) {
321 n_warm_up_(r_index, i) = lambda_norm[i * obstacles_num_ + j] * work->solution->x[variable_index];
329 for (
int i = 0; i < horizon_ + 1; ++i) {
330 for (
int j = 0; j < obstacles_num_; ++j) {
331 slacks_(j, i) = lambda_norm[i * obstacles_num_ + j] * work->solution->x[variable_index];
336 succ = succ & (work->info->obj_val <= 1.0);
355 std::vector<c_float>* P_data,
356 std::vector<c_int>* P_indices,
357 std::vector<c_int>* P_indptr) {
359 std::vector<c_float> P_tmp;
360 int edges_counter = 0;
362 for (
int j = 0; j < obstacles_num_; ++j) {
363 int current_edges_num = obstacles_edges_num_(j, 0);
365 Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
367 Aj = Aj * Aj.transpose();
369 CHECK_EQ(current_edges_num, Aj.cols());
370 CHECK_EQ(current_edges_num, Aj.rows());
372 for (
int c = 0; c < current_edges_num; ++c) {
373 for (
int r = 0; r < current_edges_num; ++r) {
374 P_tmp.emplace_back(Aj(r, c));
379 edges_counter += current_edges_num;
382 int l_index = l_start_index_;
383 int first_row_location = 0;
385 for (
int i = 0; i < horizon_ + 1; ++i) {
388 for (
auto item : P_tmp) {
389 P_data->emplace_back(item);
392 for (
int j = 0; j < obstacles_num_; ++j) {
393 int current_edges_num = obstacles_edges_num_(j, 0);
395 for (
int c = 0; c < current_edges_num; ++c) {
396 P_indptr->emplace_back(first_row_location);
397 for (
int r = 0; r < current_edges_num; ++r) {
398 P_indices->emplace_back(r + l_index);
400 first_row_location += current_edges_num;
404 edges_counter += current_edges_num;
405 l_index += current_edges_num;
409 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(lambda_horizon_));
410 for (
int i = lambda_horizon_; i < num_of_variables_ + 1; ++i) {
411 P_indptr->emplace_back(first_row_location);
414 CHECK_EQ(P_data->size(), P_indices->size());
415 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);
419 std::vector<c_float>* A_data,
420 std::vector<c_int>* A_indices,
421 std::vector<c_int>* A_indptr) {
431 int r2_index = 2 * obstacles_num_ * (horizon_ + 1);
432 int r3_index = 3 * obstacles_num_ * (horizon_ + 1);
433 int r4_index = 3 * obstacles_num_ * (horizon_ + 1) + lambda_horizon_;
434 int r5_index = r4_index + miu_horizon_;
435 int first_row_location = 0;
439 for (
int i = 0; i < horizon_ + 1; ++i) {
440 int edges_counter = 0;
442 Eigen::MatrixXd R(2, 2);
443 R << cos(xWS_(2, i)), sin(xWS_(2, i)), sin(xWS_(2, i)), cos(xWS_(2, i));
445 Eigen::MatrixXd t_trans(1, 2);
446 t_trans << (xWS_(0, i) + cos(xWS_(2, i)) * offset_), (xWS_(1, i) + sin(xWS_(2, i)) * offset_);
449 for (
int j = 0; j < obstacles_num_; ++j) {
450 int current_edges_num = obstacles_edges_num_(j, 0);
451 Eigen::MatrixXd Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
452 Eigen::MatrixXd bj = obstacles_b_.block(edges_counter, 0, current_edges_num, 1);
454 Eigen::MatrixXd r1_block(2, current_edges_num);
455 r1_block = R * Aj.transpose();
457 Eigen::MatrixXd r2_block(1, current_edges_num);
458 r2_block = t_trans * Aj.transpose() - bj.transpose();
461 for (
int k = 0; k < current_edges_num; ++k) {
462 A_data->emplace_back(r1_block(0, k));
463 A_indices->emplace_back(r1_index);
465 A_data->emplace_back(r1_block(1, k));
466 A_indices->emplace_back(r1_index + 1);
468 A_data->emplace_back(r2_block(0, k));
469 A_indices->emplace_back(r2_index);
471 A_data->emplace_back(1.0);
472 A_indices->emplace_back(r3_index);
475 A_indptr->emplace_back(first_row_location);
476 first_row_location += 4;
480 edges_counter += current_edges_num;
490 r2_index = 2 * obstacles_num_ * (horizon_ + 1);
491 for (
int i = 0; i < horizon_ + 1; ++i) {
492 for (
int j = 0; j < obstacles_num_; ++j) {
493 for (
int k = 0; k < 4; ++k) {
496 A_data->emplace_back(1.0);
498 A_data->emplace_back(-1.0);
500 A_indices->emplace_back(r1_index + k % 2);
503 A_data->emplace_back(-g_[k]);
504 A_indices->emplace_back(r2_index);
507 A_data->emplace_back(1.0);
508 A_indices->emplace_back(r4_index);
512 A_indptr->emplace_back(first_row_location);
513 first_row_location += 3;
524 r2_index = 2 * obstacles_num_ * (horizon_ + 1);
525 for (
int i = 0; i < horizon_ + 1; ++i) {
526 for (
int j = 0; j < obstacles_num_; ++j) {
527 A_data->emplace_back(1.0);
528 A_indices->emplace_back(r2_index);
531 A_data->emplace_back(1.0);
532 A_indices->emplace_back(r5_index);
535 A_indptr->emplace_back(first_row_location);
536 first_row_location += 2;
540 A_indptr->emplace_back(first_row_location);
542 CHECK_EQ(A_data->size(), A_indices->size());
543 CHECK_EQ(A_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);