33 size_t horizon,
double ts,
const Eigen::MatrixXd& ego,
34 const Eigen::MatrixXi& obstacles_edges_num,
const size_t obstacles_num,
35 const Eigen::MatrixXd& obstacles_A,
const Eigen::MatrixXd& obstacles_b,
36 const Eigen::MatrixXd& xWS,
40 obstacles_edges_num_(obstacles_edges_num),
41 obstacles_A_(obstacles_A),
42 obstacles_b_(obstacles_b),
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();
56 n_start_index_ = l_start_index_ + obstacles_edges_sum_ * (horizon_ + 1);
57 l_warm_up_ = Eigen::MatrixXd::Zero(obstacles_edges_sum_, horizon_ + 1);
58 n_warm_up_ = Eigen::MatrixXd::Zero(4 * obstacles_num_, horizon_ + 1);
61 lambda_horizon_ = obstacles_edges_sum_ * (horizon_ + 1);
63 miu_horizon_ = obstacles_num_ * 4 * (horizon_ + 1);
66 num_of_variables_ = lambda_horizon_ + miu_horizon_;
68 num_of_constraints_ = 3 * obstacles_num_ * (horizon_ + 1) + num_of_variables_;
70 min_safety_distance_ =
79void printMatrix(
const int r,
const int c,
const std::vector<c_float>& P_data,
80 const std::vector<c_int>& P_indices,
81 const std::vector<c_int>& P_indptr) {
82 Eigen::MatrixXf tmp = Eigen::MatrixXf::Zero(r, c);
84 for (
size_t i = 0; i < P_indptr.size() - 1; ++i) {
85 if (P_indptr[i] < 0 || P_indptr[i] >=
static_cast<int>(P_indices.size())) {
89 for (
auto idx = P_indptr[i]; idx < P_indptr[i + 1]; ++idx) {
90 int tmp_c =
static_cast<int>(i);
91 int tmp_r =
static_cast<int>(P_indices[idx]);
92 tmp(tmp_r, tmp_c) =
static_cast<float>(P_data[idx]);
96 AINFO <<
"row number: " << r;
97 AINFO <<
"col number: " << c;
98 for (
int i = 0; i < r; ++i) {
99 AINFO <<
"row number: " << i;
105 const int r,
const int c,
const std::vector<c_float>& P_data,
106 const std::vector<c_int>& P_indices,
const std::vector<c_int>& P_indptr) {
107 constraint_A_ = Eigen::MatrixXf::Zero(r, c);
109 for (
size_t i = 0; i < P_indptr.size() - 1; ++i) {
110 if (P_indptr[i] < 0 || P_indptr[i] >=
static_cast<int>(P_indices.size())) {
114 for (
auto idx = P_indptr[i]; idx < P_indptr[i + 1]; ++idx) {
115 int tmp_c =
static_cast<int>(i);
116 int tmp_r =
static_cast<int>(P_indices[idx]);
117 constraint_A_(tmp_r, tmp_c) =
static_cast<float>(P_data[idx]);
123 int kNumParam = num_of_variables_;
124 int kNumConst = num_of_constraints_;
128 std::vector<c_float> P_data;
129 std::vector<c_int> P_indices;
130 std::vector<c_int> P_indptr;
133 AINFO <<
"print P_data in whole: ";
134 printMatrix(kNumParam, kNumParam, P_data, P_indices, P_indptr);
137 c_float q[kNumParam];
138 for (
int i = 0; i < kNumParam; ++i) {
143 std::vector<c_float> A_data;
144 std::vector<c_int> A_indices;
145 std::vector<c_int> A_indptr;
148 AINFO <<
"print A_data in whole: ";
149 printMatrix(kNumConst, kNumParam, A_data, A_indices, A_indptr);
150 assembleA(kNumConst, kNumParam, A_data, A_indices, A_indptr);
154 c_float lb[kNumConst];
155 c_float ub[kNumConst];
156 for (
int i = 0; i < kNumConst; ++i) {
158 if (i >= 2 * obstacles_num_ * (horizon_ + 1) &&
159 i < 3 * obstacles_num_ * (horizon_ + 1)) {
160 lb[i] = min_safety_distance_;
162 if (i < 2 * obstacles_num_ * (horizon_ + 1)) {
170 OSQPSettings* settings =
171 reinterpret_cast<OSQPSettings*
>(c_malloc(
sizeof(OSQPSettings)));
174 osqp_set_default_settings(settings);
175 settings->alpha = osqp_config_.
alpha();
176 settings->eps_abs = osqp_config_.
eps_abs();
177 settings->eps_rel = osqp_config_.
eps_rel();
178 settings->max_iter = osqp_config_.
max_iter();
179 settings->polish = osqp_config_.
polish();
183 OSQPData* data =
reinterpret_cast<OSQPData*
>(c_malloc(
sizeof(OSQPData)));
186 data->P = csc_matrix(data->n, data->n, P_data.size(), P_data.data(),
187 P_indices.data(), P_indptr.data());
189 data->A = csc_matrix(data->m, data->n, A_data.size(), A_data.data(),
190 A_indices.data(), A_indptr.data());
195 OSQPWorkspace* work =
nullptr;
197 work = osqp_setup(data, settings);
203 if (work->info->status_val != 1 && work->info->status_val != 2) {
204 AWARN <<
"OSQP dual warm up unsuccess, "
205 <<
"return status: " << work->info->status;
210 int variable_index = 0;
213 for (
int i = 0; i < horizon_ + 1; ++i) {
214 for (
int j = 0; j < obstacles_edges_sum_; ++j) {
215 l_warm_up_(j, i) = work->solution->x[variable_index];
221 for (
int i = 0; i < horizon_ + 1; ++i) {
222 for (
int j = 0; j < 4 * obstacles_num_; ++j) {
223 n_warm_up_(j, i) = work->solution->x[variable_index];
228 succ = succ & (work->info->obj_val <= 1.0);
241 const Eigen::MatrixXd& l_warm_up,
const Eigen::MatrixXd& n_warm_up) {
242 Eigen::MatrixXf x(num_of_variables_, 1);
243 Eigen::MatrixXf g(num_of_constraints_, 1);
246 int variable_index = 0;
249 for (
int i = 0; i < horizon_ + 1; ++i) {
250 for (
int j = 0; j < obstacles_edges_sum_; ++j) {
251 x(variable_index, 0) =
static_cast<float>(l_warm_up(j, i));
257 for (
int i = 0; i < horizon_ + 1; ++i) {
258 for (
int j = 0; j < 4 * obstacles_num_; ++j) {
259 x(variable_index, 0) =
static_cast<float>(n_warm_up(j, i));
264 g = constraint_A_ * x;
266 int r2_index = 2 * obstacles_num_ * (horizon_ + 1);
267 int r3_index = 3 * obstacles_num_ * (horizon_ + 1);
268 int r4_index = 3 * obstacles_num_ * (horizon_ + 1) + lambda_horizon_;
270 for (
int idx = r1_index; idx < r2_index; ++idx) {
271 if (std::abs(g(idx, 0)) > 1e-6) {
272 AERROR <<
"G' * mu + R' * A * lambda == 0 constraint fails, "
273 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
277 for (
int idx = r2_index; idx < r3_index; ++idx) {
278 if (g(idx, 0) < min_safety_distance_) {
279 AERROR <<
"-g' * mu + (A * t - b) * lambda) >= d_min constraint fails, "
280 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
284 for (
int idx = r3_index; idx < r4_index; ++idx) {
286 AERROR <<
"lambda box constraint fails, "
287 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
291 for (
int idx = r4_index; idx < num_of_constraints_; ++idx) {
293 AERROR <<
"miu box constraint fails, "
294 <<
"constraint_index: " << idx <<
", g: " << g(idx, 0);
300 std::vector<c_float>* P_data, std::vector<c_int>* P_indices,
301 std::vector<c_int>* P_indptr) {
303 std::vector<c_float> P_tmp;
304 int edges_counter = 0;
306 for (
int j = 0; j < obstacles_num_; ++j) {
307 int current_edges_num = obstacles_edges_num_(j, 0);
309 Aj = obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
311 Aj = Aj * Aj.transpose();
313 CHECK_EQ(current_edges_num, Aj.cols());
314 CHECK_EQ(current_edges_num, Aj.rows());
316 for (
int c = 0; c < current_edges_num; ++c) {
317 for (
int r = 0; r < current_edges_num; ++r) {
318 P_tmp.emplace_back(Aj(r, c));
323 edges_counter += current_edges_num;
326 int l_index = l_start_index_;
327 int first_row_location = 0;
329 for (
int i = 0; i < horizon_ + 1; ++i) {
332 for (
auto item : P_tmp) {
333 P_data->emplace_back(item);
336 for (
int j = 0; j < obstacles_num_; ++j) {
337 int current_edges_num = obstacles_edges_num_(j, 0);
339 for (
int c = 0; c < current_edges_num; ++c) {
340 P_indptr->emplace_back(first_row_location);
341 for (
int r = 0; r < current_edges_num; ++r) {
342 P_indices->emplace_back(r + l_index);
344 first_row_location += current_edges_num;
348 edges_counter += current_edges_num;
349 l_index += current_edges_num;
353 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(lambda_horizon_));
354 for (
int i = lambda_horizon_; i < num_of_variables_ + 1; ++i) {
355 P_indptr->emplace_back(first_row_location);
358 CHECK_EQ(P_data->size(), P_indices->size());
359 CHECK_EQ(P_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);
363 std::vector<c_float>* A_data, std::vector<c_int>* A_indices,
364 std::vector<c_int>* A_indptr) {
373 int r2_index = 2 * obstacles_num_ * (horizon_ + 1);
374 int r3_index = 3 * obstacles_num_ * (horizon_ + 1);
375 int r4_index = 3 * obstacles_num_ * (horizon_ + 1) + lambda_horizon_;
376 int first_row_location = 0;
379 for (
int i = 0; i < horizon_ + 1; ++i) {
380 int edges_counter = 0;
382 Eigen::MatrixXd R(2, 2);
383 R << cos(xWS_(2, i)), sin(xWS_(2, i)), sin(xWS_(2, i)), cos(xWS_(2, i));
385 Eigen::MatrixXd t_trans(1, 2);
386 t_trans << (xWS_(0, i) + cos(xWS_(2, i)) * offset_),
387 (xWS_(1, i) + sin(xWS_(2, i)) * offset_);
390 for (
int j = 0; j < obstacles_num_; ++j) {
391 int current_edges_num = obstacles_edges_num_(j, 0);
393 obstacles_A_.block(edges_counter, 0, current_edges_num, 2);
395 obstacles_b_.block(edges_counter, 0, current_edges_num, 1);
397 Eigen::MatrixXd r1_block(2, current_edges_num);
398 r1_block = R * Aj.transpose();
400 Eigen::MatrixXd r2_block(1, current_edges_num);
401 r2_block = t_trans * Aj.transpose() - bj.transpose();
404 for (
int k = 0; k < current_edges_num; ++k) {
405 A_data->emplace_back(r1_block(0, k));
406 A_indices->emplace_back(r1_index);
408 A_data->emplace_back(r1_block(1, k));
409 A_indices->emplace_back(r1_index + 1);
411 A_data->emplace_back(r2_block(0, k));
412 A_indices->emplace_back(r2_index);
414 A_data->emplace_back(1.0);
415 A_indices->emplace_back(r3_index);
418 A_indptr->emplace_back(first_row_location);
419 first_row_location += 4;
423 edges_counter += current_edges_num;
433 r2_index = 2 * obstacles_num_ * (horizon_ + 1);
434 for (
int i = 0; i < horizon_ + 1; ++i) {
435 for (
int j = 0; j < obstacles_num_; ++j) {
436 for (
int k = 0; k < 4; ++k) {
439 A_data->emplace_back(1.0);
441 A_data->emplace_back(-1.0);
443 A_indices->emplace_back(r1_index + k % 2);
446 A_data->emplace_back(-g_[k]);
447 A_indices->emplace_back(r2_index);
450 A_data->emplace_back(1.0);
451 A_indices->emplace_back(r4_index);
455 A_indptr->emplace_back(first_row_location);
456 first_row_location += 3;
465 A_indptr->emplace_back(first_row_location);
467 CHECK_EQ(A_data->size(), A_indices->size());
468 CHECK_EQ(A_indptr->size(),
static_cast<size_t>(num_of_variables_) + 1);