35 const Eigen::MatrixXd& ego,
36 const Eigen::MatrixXi& obstacles_edges_num,
37 const size_t obstacles_num,
38 const Eigen::MatrixXd& obstacles_A,
39 const Eigen::MatrixXd& obstacles_b,
40 const Eigen::MatrixXd& xWS,
44 obstacles_edges_num_(obstacles_edges_num),
45 obstacles_A_(obstacles_A),
46 obstacles_b_(obstacles_b),
48 ACHECK(horizon < std::numeric_limits<int>::max()) <<
"Invalid cast on horizon in open space planner";
49 horizon_ =
static_cast<int>(horizon);
50 ACHECK(obstacles_num < std::numeric_limits<int>::max()) <<
"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();
58 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
59 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
60 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
63 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
65 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
68 num_of_variables_ = lambda_horizon_ + miu_horizon_;
70 num_of_constraints_ = 3 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
80 const Eigen::MatrixXd& ego,
81 const Eigen::MatrixXi& obstacles_edges_num,
82 const size_t obstacles_num,
83 const Eigen::MatrixXd& obstacles_A,
84 const Eigen::MatrixXd& obstacles_b,
85 const Eigen::MatrixXd& xWS,
89 obstacles_edges_num_(obstacles_edges_num),
90 obstacles_A_(obstacles_A),
91 obstacles_b_(obstacles_b),
93 ACHECK(horizon < std::numeric_limits<int>::max()) <<
"Invalid cast on horizon in open space planner";
94 horizon_ =
static_cast<int>(horizon);
95 ACHECK(obstacles_num < std::numeric_limits<int>::max()) <<
"Invalid cast on obstacles_num in open space planner";
96 obstacles_num_ =
static_cast<int>(obstacles_num);
97 w_ev_ = ego_(1, 0) + ego_(3, 0);
98 l_ev_ = ego_(0, 0) + ego_(2, 0);
99 g_ = {l_ev_ / 2, w_ev_ / 2, l_ev_ / 2, w_ev_ / 2};
100 offset_ = (ego_(0, 0) + ego_(2, 0)) / 2 - ego_(2, 0);
101 obstacles_edges_sum_ = obstacles_edges_num_.sum();
103 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
104 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
105 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
108 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
110 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
113 num_of_variables_ = lambda_horizon_ + miu_horizon_;
115 num_of_constraints_ = 3 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
153 const std::vector<c_float>& P_data,
154 const std::vector<c_int>& P_indices,
155 const std::vector<c_int>& P_indptr) {
156 constraint_A_ = Eigen::MatrixXf::Zero(r, c);
158 for (
size_t i = 0; i < P_indptr.size() - 1; ++i) {
159 if (P_indptr[i] < 0 || P_indptr[i] >=
static_cast<int>(P_indices.size())) {
163 for (
auto idx = P_indptr[i]; idx < P_indptr[i + 1]; ++idx) {
164 int tmp_c =
static_cast<int>(i);
165 int tmp_r =
static_cast<int>(P_indices[idx]);
166 constraint_A_(tmp_r, tmp_c) =
static_cast<float>(P_data[idx]);
172 int kNumParam = num_of_variables_;
173 int kNumConst = num_of_constraints_;
177 std::vector<c_float> P_data;
178 std::vector<c_int> P_indices;
179 std::vector<c_int> P_indptr;
182 AINFO <<
"print P_data in whole: ";
183 printMatrix(kNumParam, kNumParam, P_data, P_indices, P_indptr);
186 c_float q[kNumParam];
187 for (
int i = 0; i < kNumParam; ++i) {
192 std::vector<c_float> A_data;
193 std::vector<c_int> A_indices;
194 std::vector<c_int> A_indptr;
197 AINFO <<
"print A_data in whole: ";
198 printMatrix(kNumConst, kNumParam, A_data, A_indices, A_indptr);
199 assembleA(kNumConst, kNumParam, A_data, A_indices, A_indptr);
203 c_float lb[kNumConst];
204 c_float ub[kNumConst];
205 for (
int i = 0; i < kNumConst; ++i) {
207 if (i >= 2 * obstacles_num_ * (horizon_ + 1) && i < 3 * obstacles_num_ * (horizon_ + 1)) {
208 lb[i] = min_safety_distance_;
210 if (i < 2 * obstacles_num_ * (horizon_ + 1)) {
218 OSQPSettings* settings =
reinterpret_cast<OSQPSettings*
>(c_malloc(
sizeof(OSQPSettings)));
221 osqp_set_default_settings(settings);
222 settings->alpha = osqp_config_.
alpha();
223 settings->eps_abs = osqp_config_.
eps_abs();
224 settings->eps_rel = osqp_config_.
eps_rel();
225 settings->max_iter = osqp_config_.
max_iter();
226 settings->polish = osqp_config_.
polish();
230 OSQPData* data =
reinterpret_cast<OSQPData*
>(c_malloc(
sizeof(OSQPData)));
233 data->P = csc_matrix(data->n, data->n, P_data.size(), P_data.data(), P_indices.data(), P_indptr.data());
235 data->A = csc_matrix(data->m, data->n, A_data.size(), A_data.data(), A_indices.data(), A_indptr.data());
240 OSQPWorkspace* work =
nullptr;
242 work = osqp_setup(data, settings);
248 if (work->info->status_val != 1 && work->info->status_val != 2) {
249 AWARN <<
"OSQP dual warm up unsuccess, "
250 <<
"return status: " << work->info->status;
255 int variable_index = 0;
258 for (
int i = 0; i < horizon_ + 1; ++i) {
259 for (
int j = 0; j < obstacles_edges_sum_; ++j) {
260 l_warm_up_(j, i) = work->solution->x[variable_index];
266 for (
int i = 0; i < horizon_ + 1; ++i) {
267 for (
int j = 0; j < 4 * obstacles_num_; ++j) {
268 n_warm_up_(j, i) = work->solution->x[variable_index];
273 succ = succ & (work->info->obj_val <= 1.0);
286 const Eigen::MatrixXd& l_warm_up,
287 const Eigen::MatrixXd& n_warm_up) {
288 Eigen::MatrixXf x(num_of_variables_, 1);
289 Eigen::MatrixXf g(num_of_constraints_, 1);
292 int variable_index = 0;
295 for (
int i = 0; i < horizon_ + 1; ++i) {
296 for (
int j = 0; j < obstacles_edges_sum_; ++j) {
297 x(variable_index, 0) =
static_cast<float>(l_warm_up(j, i));
303 for (
int i = 0; i < horizon_ + 1; ++i) {
304 for (
int j = 0; j < 4 * obstacles_num_; ++j) {
305 x(variable_index, 0) =
static_cast<float>(n_warm_up(j, i));
310 g = constraint_A_ * x;
312 int r2_index = 2 * obstacles_num_ * (horizon_ + 1);
313 int r3_index = 3 * obstacles_num_ * (horizon_ + 1);
314 int r4_index = 3 * obstacles_num_ * (horizon_ + 1) + lambda_horizon_;
316 for (
int idx = r1_index; idx < r2_index; ++idx) {
317 if (std::abs(g(idx, 0)) > 1e-6) {
318 AERROR <<
"G' * mu + R' * A * lambda == 0 constraint fails, "
319 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
323 for (
int idx = r2_index; idx < r3_index; ++idx) {
324 if (g(idx, 0) < min_safety_distance_) {
325 AERROR <<
"-g' * mu + (A * t - b) * lambda) >= d_min constraint fails, "
326 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
330 for (
int idx = r3_index; idx < r4_index; ++idx) {
332 AERROR <<
"lambda box constraint fails, "
333 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
337 for (
int idx = r4_index; idx < num_of_constraints_; ++idx) {
339 AERROR <<
"miu box constraint fails, "
340 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
346 std::vector<c_float>* P_data,
347 std::vector<c_int>* P_indices,
348 std::vector<c_int>* P_indptr) {
350 std::vector<c_float> P_tmp;
351 int edges_counter = 0;
353 for (
int j = 0; j < obstacles_num_; ++j) {
354 int current_edges_num = obstacles_edges_num_(j, 0);
356 Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
358 Aj = Aj * Aj.transpose();
360 CHECK_EQ(current_edges_num, Aj.cols());
361 CHECK_EQ(current_edges_num, Aj.rows());
363 for (
int c = 0; c < current_edges_num; ++c) {
364 for (
int r = 0; r < current_edges_num; ++r) {
365 P_tmp.emplace_back(Aj(r, c));
370 edges_counter += current_edges_num;
373 int l_index = l_start_index_;
374 int first_row_location = 0;
376 for (
int i = 0; i < horizon_ + 1; ++i) {
379 for (
auto item : P_tmp) {
380 P_data->emplace_back(item);
383 for (
int j = 0; j < obstacles_num_; ++j) {
384 int current_edges_num = obstacles_edges_num_(j, 0);
386 for (
int c = 0; c < current_edges_num; ++c) {
387 P_indptr->emplace_back(first_row_location);
388 for (
int r = 0; r < current_edges_num; ++r) {
389 P_indices->emplace_back(r + l_index);
391 first_row_location += current_edges_num;
395 edges_counter += current_edges_num;
396 l_index += current_edges_num;
400 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(lambda_horizon_));
401 for (
int i = lambda_horizon_; i < num_of_variables_ + 1; ++i) {
402 P_indptr->emplace_back(first_row_location);
405 CHECK_EQ(P_data->size(), P_indices->size());
406 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);
410 std::vector<c_float>* A_data,
411 std::vector<c_int>* A_indices,
412 std::vector<c_int>* A_indptr) {
421 int r2_index = 2 * obstacles_num_ * (horizon_ + 1);
422 int r3_index = 3 * obstacles_num_ * (horizon_ + 1);
423 int r4_index = 3 * obstacles_num_ * (horizon_ + 1) + lambda_horizon_;
424 int first_row_location = 0;
427 for (
int i = 0; i < horizon_ + 1; ++i) {
428 int edges_counter = 0;
430 Eigen::MatrixXd R(2, 2);
431 R << cos(xWS_(2, i)), sin(xWS_(2, i)), sin(xWS_(2, i)), cos(xWS_(2, i));
433 Eigen::MatrixXd t_trans(1, 2);
434 t_trans << (xWS_(0, i) + cos(xWS_(2, i)) * offset_), (xWS_(1, i) + sin(xWS_(2, i)) * offset_);
437 for (
int j = 0; j < obstacles_num_; ++j) {
438 int current_edges_num = obstacles_edges_num_(j, 0);
439 Eigen::MatrixXd Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
440 Eigen::MatrixXd bj = obstacles_b_.block(edges_counter, 0, current_edges_num, 1);
442 Eigen::MatrixXd r1_block(2, current_edges_num);
443 r1_block = R * Aj.transpose();
445 Eigen::MatrixXd r2_block(1, current_edges_num);
446 r2_block = t_trans * Aj.transpose() - bj.transpose();
449 for (
int k = 0; k < current_edges_num; ++k) {
450 A_data->emplace_back(r1_block(0, k));
451 A_indices->emplace_back(r1_index);
453 A_data->emplace_back(r1_block(1, k));
454 A_indices->emplace_back(r1_index + 1);
456 A_data->emplace_back(r2_block(0, k));
457 A_indices->emplace_back(r2_index);
459 A_data->emplace_back(1.0);
460 A_indices->emplace_back(r3_index);
463 A_indptr->emplace_back(first_row_location);
464 first_row_location += 4;
468 edges_counter += current_edges_num;
478 r2_index = 2 * obstacles_num_ * (horizon_ + 1);
479 for (
int i = 0; i < horizon_ + 1; ++i) {
480 for (
int j = 0; j < obstacles_num_; ++j) {
481 for (
int k = 0; k < 4; ++k) {
484 A_data->emplace_back(1.0);
486 A_data->emplace_back(-1.0);
488 A_indices->emplace_back(r1_index + k % 2);
491 A_data->emplace_back(-g_[k]);
492 A_indices->emplace_back(r2_index);
495 A_data->emplace_back(1.0);
496 A_indices->emplace_back(r4_index);
500 A_indptr->emplace_back(first_row_location);
501 first_row_location += 3;
510 A_indptr->emplace_back(first_row_location);
512 CHECK_EQ(A_data->size(), A_indices->size());
513 CHECK_EQ(A_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);