35 size_t horizon,
double ts,
const Eigen::MatrixXd& ego,
36 const Eigen::MatrixXi& obstacles_edges_num,
const size_t obstacles_num,
37 const Eigen::MatrixXd& obstacles_A,
const Eigen::MatrixXd& obstacles_b,
38 const Eigen::MatrixXd& xWS,
42 obstacles_edges_num_(obstacles_edges_num),
43 obstacles_A_(obstacles_A),
44 obstacles_b_(obstacles_b),
46 ACHECK(horizon < std::numeric_limits<int>::max())
47 <<
"Invalid cast on horizon in open space planner";
48 horizon_ =
static_cast<int>(horizon);
49 ACHECK(obstacles_num < std::numeric_limits<int>::max())
50 <<
"Invalid cast on obstacles_num in open space planner";
51 obstacles_num_ =
static_cast<int>(obstacles_num);
52 w_ev_ = ego_(1, 0) + ego_(3, 0);
53 l_ev_ = ego_(0, 0) + ego_(2, 0);
54 g_ = {l_ev_ / 2, w_ev_ / 2, l_ev_ / 2, w_ev_ / 2};
55 offset_ = (ego_(0, 0) + ego_(2, 0)) / 2 - ego_(2, 0);
56 obstacles_edges_sum_ = obstacles_edges_num_.sum();
59 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
60 s_start_index_ = n_start_index_ + 4 * obstacles_num_ * (horizon_ + 1);
62 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
63 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
64 slacks_ = Eigen::MatrixXd::Zero(obstacles_num_, horizon_ + 1);
67 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
68 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
69 slack_horizon_ = obstacles_num_ * (horizon_ + 1);
72 num_of_variables_ = lambda_horizon_ + miu_horizon_ + slack_horizon_;
74 num_of_constraints_ = 3 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
76 min_safety_distance_ =
135 std::vector<c_float> P_data;
136 std::vector<c_int> P_indices;
137 std::vector<c_int> P_indptr;
138 assembleP(&P_data, &P_indices, &P_indptr);
140 AINFO <<
"print P_data in whole: ";
141 printMatrix(num_of_variables_, num_of_variables_, P_data, P_indices,
145 c_float q[num_of_variables_];
146 for (
int i = 0; i < num_of_variables_; ++i) {
148 if (i >= s_start_index_) {
154 std::vector<c_float> A_data;
155 std::vector<c_int> A_indices;
156 std::vector<c_int> A_indptr;
159 AINFO <<
"print A_data in whole: ";
160 printMatrix(num_of_constraints_, num_of_variables_, A_data, A_indices,
162 assembleA(num_of_constraints_, num_of_variables_, A_data, A_indices,
167 c_float lb[num_of_constraints_];
168 c_float ub[num_of_constraints_];
169 int slack_indx = num_of_constraints_ - slack_horizon_;
170 for (
int i = 0; i < num_of_constraints_; ++i) {
172 if (i >= slack_indx) {
176 if (i < 2 * obstacles_num_ * (horizon_ + 1)) {
178 }
else if (i < slack_indx) {
186 OSQPSettings* settings =
187 reinterpret_cast<OSQPSettings*
>(c_malloc(
sizeof(OSQPSettings)));
190 osqp_set_default_settings(settings);
191 settings->alpha = osqp_config_.
alpha();
192 settings->eps_abs = osqp_config_.
eps_abs();
193 settings->eps_rel = osqp_config_.
eps_rel();
194 settings->max_iter = osqp_config_.
max_iter();
195 settings->polish = osqp_config_.
polish();
199 OSQPData* data =
reinterpret_cast<OSQPData*
>(c_malloc(
sizeof(OSQPData)));
200 data->n = num_of_variables_;
201 data->m = num_of_constraints_;
202 data->P = csc_matrix(data->n, data->n, P_data.size(), P_data.data(),
203 P_indices.data(), P_indptr.data());
205 data->A = csc_matrix(data->m, data->n, A_data.size(), A_data.data(),
206 A_indices.data(), A_indptr.data());
211 OSQPWorkspace* work =
nullptr;
213 work = osqp_setup(data, settings);
219 if (work->info->status_val != 1 && work->info->status_val != 2) {
220 AWARN <<
"OSQP dual warm up unsuccess, "
221 <<
"return status: " << work->info->status;
226 std::vector<double> lambda_norm;
227 int l_index = l_start_index_;
228 for (
int i = 0; i < horizon_ + 1; ++i) {
229 int edges_counter = 0;
230 for (
int j = 0; j < obstacles_num_; ++j) {
231 int current_edges_num = obstacles_edges_num_(j, 0);
233 obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
237 for (
int k = 0; k < current_edges_num; ++k) {
238 tmp1 += Aj(k, 0) * work->solution->x[l_index + k];
239 tmp2 += Aj(k, 1) * work->solution->x[l_index + k];
243 double tmp_norm = tmp1 * tmp1 + tmp2 * tmp2;
244 if (tmp_norm >= 1e-5) {
245 lambda_norm.push_back(0.75 / std::sqrt(tmp_norm));
247 lambda_norm.push_back(0.0);
250 edges_counter += current_edges_num;
251 l_index += current_edges_num;
256 int variable_index = 0;
259 for (
int i = 0; i < horizon_ + 1; ++i) {
261 for (
int j = 0; j < obstacles_num_; ++j) {
262 for (
int k = 0; k < obstacles_edges_num_(j, 0); ++k) {
263 l_warm_up_(r_index, i) = lambda_norm[i * obstacles_num_ + j] *
264 work->solution->x[variable_index];
272 for (
int i = 0; i < horizon_ + 1; ++i) {
274 for (
int j = 0; j < obstacles_num_; ++j) {
275 for (
int k = 0; k < 4; ++k) {
276 n_warm_up_(r_index, i) = lambda_norm[i * obstacles_num_ + j] *
277 work->solution->x[variable_index];
285 for (
int i = 0; i < horizon_ + 1; ++i) {
286 for (
int j = 0; j < obstacles_num_; ++j) {
287 slacks_(j, i) = lambda_norm[i * obstacles_num_ + j] *
288 work->solution->x[variable_index];
293 succ = succ & (work->info->obj_val <= 1.0);
311 std::vector<c_float>* P_data, std::vector<c_int>* P_indices,
312 std::vector<c_int>* P_indptr) {
314 std::vector<c_float> P_tmp;
315 int edges_counter = 0;
317 for (
int j = 0; j < obstacles_num_; ++j) {
318 int current_edges_num = obstacles_edges_num_(j, 0);
320 Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
322 Aj = Aj * Aj.transpose();
324 CHECK_EQ(current_edges_num, Aj.cols());
325 CHECK_EQ(current_edges_num, Aj.rows());
327 for (
int c = 0; c < current_edges_num; ++c) {
328 for (
int r = 0; r < current_edges_num; ++r) {
329 P_tmp.emplace_back(Aj(r, c));
334 edges_counter += current_edges_num;
337 int l_index = l_start_index_;
338 int first_row_location = 0;
340 for (
int i = 0; i < horizon_ + 1; ++i) {
343 for (
auto item : P_tmp) {
344 P_data->emplace_back(item);
347 for (
int j = 0; j < obstacles_num_; ++j) {
348 int current_edges_num = obstacles_edges_num_(j, 0);
350 for (
int c = 0; c < current_edges_num; ++c) {
351 P_indptr->emplace_back(first_row_location);
352 for (
int r = 0; r < current_edges_num; ++r) {
353 P_indices->emplace_back(r + l_index);
355 first_row_location += current_edges_num;
359 edges_counter += current_edges_num;
360 l_index += current_edges_num;
364 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(lambda_horizon_));
365 for (
int i = lambda_horizon_; i < num_of_variables_ + 1; ++i) {
366 P_indptr->emplace_back(first_row_location);
369 CHECK_EQ(P_data->size(), P_indices->size());
370 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);
374 std::vector<c_float>* A_data, std::vector<c_int>* A_indices,
375 std::vector<c_int>* A_indptr) {
385 int r2_index = 2 * obstacles_num_ * (horizon_ + 1);
386 int r3_index = 3 * obstacles_num_ * (horizon_ + 1);
387 int r4_index = 3 * obstacles_num_ * (horizon_ + 1) + lambda_horizon_;
388 int r5_index = r4_index + miu_horizon_;
389 int first_row_location = 0;
393 for (
int i = 0; i < horizon_ + 1; ++i) {
394 int edges_counter = 0;
396 Eigen::MatrixXd R(2, 2);
397 R << cos(xWS_(2, i)), sin(xWS_(2, i)), sin(xWS_(2, i)), cos(xWS_(2, i));
399 Eigen::MatrixXd t_trans(1, 2);
400 t_trans << (xWS_(0, i) + cos(xWS_(2, i)) * offset_),
401 (xWS_(1, i) + sin(xWS_(2, i)) * offset_);
404 for (
int j = 0; j < obstacles_num_; ++j) {
405 int current_edges_num = obstacles_edges_num_(j, 0);
407 obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
409 obstacles_b_.block(edges_counter, 0, current_edges_num, 1);
411 Eigen::MatrixXd r1_block(2, current_edges_num);
412 r1_block = R * Aj.transpose();
414 Eigen::MatrixXd r2_block(1, current_edges_num);
415 r2_block = t_trans * Aj.transpose() - bj.transpose();
418 for (
int k = 0; k < current_edges_num; ++k) {
419 A_data->emplace_back(r1_block(0, k));
420 A_indices->emplace_back(r1_index);
422 A_data->emplace_back(r1_block(1, k));
423 A_indices->emplace_back(r1_index + 1);
425 A_data->emplace_back(r2_block(0, k));
426 A_indices->emplace_back(r2_index);
428 A_data->emplace_back(1.0);
429 A_indices->emplace_back(r3_index);
432 A_indptr->emplace_back(first_row_location);
433 first_row_location += 4;
437 edges_counter += current_edges_num;
447 r2_index = 2 * obstacles_num_ * (horizon_ + 1);
448 for (
int i = 0; i < horizon_ + 1; ++i) {
449 for (
int j = 0; j < obstacles_num_; ++j) {
450 for (
int k = 0; k < 4; ++k) {
453 A_data->emplace_back(1.0);
455 A_data->emplace_back(-1.0);
457 A_indices->emplace_back(r1_index + k % 2);
460 A_data->emplace_back(-g_[k]);
461 A_indices->emplace_back(r2_index);
464 A_data->emplace_back(1.0);
465 A_indices->emplace_back(r4_index);
469 A_indptr->emplace_back(first_row_location);
470 first_row_location += 3;
481 r2_index = 2 * obstacles_num_ * (horizon_ + 1);
482 for (
int i = 0; i < horizon_ + 1; ++i) {
483 for (
int j = 0; j < obstacles_num_; ++j) {
484 A_data->emplace_back(1.0);
485 A_indices->emplace_back(r2_index);
488 A_data->emplace_back(1.0);
489 A_indices->emplace_back(r5_index);
492 A_indptr->emplace_back(first_row_location);
493 first_row_location += 2;
497 A_indptr->emplace_back(first_row_location);
499 CHECK_EQ(A_data->size(), A_indices->size());
500 CHECK_EQ(A_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);