182 {
183
184
185
186 bool succ = true;
187
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);
192 if (check_mode_) {
193 AINFO <<
"print P_data in whole: ";
194 printMatrix(num_of_variables_, num_of_variables_, P_data, P_indices, P_indptr);
195 }
196
197 c_float q[num_of_variables_];
198 for (int i = 0; i < num_of_variables_; ++i) {
199 q[i] = 0.0;
200 if (i >= s_start_index_) {
201 q[i] = beta_;
202 }
203 }
204
205
206 std::vector<c_float> A_data;
207 std::vector<c_int> A_indices;
208 std::vector<c_int> A_indptr;
210 if (check_mode_) {
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);
214 }
215
216
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) {
221 lb[i] = 0.0;
222 if (i >= slack_indx) {
223 lb[i] = -2e19;
224 }
225
226 if (i < 2 * obstacles_num_ * (horizon_ + 1)) {
227 ub[i] = 0.0;
228 } else if (i < slack_indx) {
229 ub[i] = 2e19;
230 } else {
231 ub[i] = 0.0;
232 }
233 }
234
235
236 OSQPSettings* settings = reinterpret_cast<OSQPSettings*>(c_malloc(sizeof(OSQPSettings)));
237
238
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();
246
247
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());
252 data->q = q;
253 data->A = csc_matrix(data->m, data->n, A_data.size(), A_data.data(), A_indices.data(), A_indptr.data());
254 data->l = lb;
255 data->u = ub;
256
257
258 OSQPWorkspace* work = nullptr;
259
260 work = osqp_setup(data, settings);
261
262
263 osqp_solve(work);
264
265
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;
269 succ = false;
270 }
271
272
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);
280
281 double tmp1 = 0;
282 double tmp2 = 0;
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];
286 }
287
288
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));
292 } else {
293 lambda_norm.push_back(0.0);
294 }
295
296 edges_counter += current_edges_num;
297 l_index += current_edges_num;
298 }
299 }
300
301
302 int variable_index = 0;
303
304
305 for (int i = 0; i < horizon_ + 1; ++i) {
306 int r_index = 0;
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];
310 ++variable_index;
311 ++r_index;
312 }
313 }
314 }
315
316
317 for (int i = 0; i < horizon_ + 1; ++i) {
318 int r_index = 0;
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];
322 ++r_index;
323 ++variable_index;
324 }
325 }
326 }
327
328
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];
332 ++variable_index;
333 }
334 }
335
336 succ = succ & (work->info->obj_val <= 1.0);
337
338
339 osqp_cleanup(work);
340 c_free(data->A);
341 c_free(data->P);
342 c_free(data);
343 c_free(settings);
344
345 return succ;
346}
void assembleP(std::vector< c_float > *P_data, std::vector< c_int > *P_indices, std::vector< c_int > *P_indptr)
void assembleA(const int r, const int c, const std::vector< c_float > &P_data, const std::vector< c_int > &P_indices, const std::vector< c_int > &P_indptr)
void printMatrix(const int r, const int c, const std::vector< c_float > &P_data, const std::vector< c_int > &P_indices, const std::vector< c_int > &P_indptr)
void assembleConstraint(std::vector< c_float > *A_data, std::vector< c_int > *A_indices, std::vector< c_int > *A_indptr)
optional bool osqp_debug_log