Apollo 11.0
自动驾驶开放平台
spline_1d_constraint.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
24
25#include <limits>
26
27#include "cyber/common/log.h"
28
29namespace apollo {
30namespace planning {
31
32using std::placeholders::_1;
33using std::placeholders::_2;
34using std::placeholders::_3;
35
37 : Spline1dConstraint(pss.x_knots(), pss.spline_order()) {}
38
39Spline1dConstraint::Spline1dConstraint(const std::vector<double>& x_knots,
40 const uint32_t spline_order)
41 : x_knots_(x_knots), spline_order_(spline_order) {
42 inequality_constraint_.SetIsEquality(false);
43 equality_constraint_.SetIsEquality(true);
44}
45
47 const Eigen::MatrixXd& constraint_matrix,
48 const Eigen::MatrixXd& constraint_boundary) {
49 return inequality_constraint_.AddConstraint(constraint_matrix,
50 constraint_boundary);
51}
52
54 const Eigen::MatrixXd& constraint_matrix,
55 const Eigen::MatrixXd& constraint_boundary) {
56 return equality_constraint_.AddConstraint(constraint_matrix,
57 constraint_boundary);
58}
59
60bool Spline1dConstraint::AddBoundary(const std::vector<double>& x_coord,
61 const std::vector<double>& lower_bound,
62 const std::vector<double>& upper_bound) {
63 std::vector<double> filtered_lower_bound;
64 std::vector<double> filtered_upper_bound;
65 std::vector<double> filtered_lower_bound_x;
66 std::vector<double> filtered_upper_bound_x;
67
68 if (x_knots_.size() < 2) {
69 return false;
70 }
71
72 if (!FilterConstraints(x_coord, lower_bound, upper_bound,
73 &filtered_lower_bound_x, &filtered_lower_bound,
74 &filtered_upper_bound_x, &filtered_upper_bound)) {
75 return false;
76 }
77 // emplace affine constraints
78 const uint32_t num_params = spline_order_ + 1;
79 Eigen::MatrixXd inequality_constraint = Eigen::MatrixXd::Zero(
80 filtered_upper_bound.size() + filtered_lower_bound.size(),
81 (x_knots_.size() - 1) * num_params);
82 Eigen::MatrixXd inequality_boundary = Eigen::MatrixXd::Zero(
83 filtered_upper_bound.size() + filtered_lower_bound.size(), 1);
84
85 for (uint32_t i = 0; i < filtered_lower_bound.size(); ++i) {
86 uint32_t index = FindIndex(filtered_lower_bound_x[i]);
87
88 const double corrected_x = filtered_lower_bound_x[i] - x_knots_[index];
89 double coef = 1.0;
90 for (uint32_t j = 0; j < num_params; ++j) {
91 inequality_constraint(i, j + index * num_params) = coef;
92 coef *= corrected_x;
93 }
94 inequality_boundary(i, 0) = filtered_lower_bound[i];
95 }
96
97 for (uint32_t i = 0; i < filtered_upper_bound.size(); ++i) {
98 uint32_t index = FindIndex(filtered_upper_bound_x[i]);
99 const double corrected_x = filtered_upper_bound_x[i] - x_knots_[index];
100 double coef = -1.0;
101 for (uint32_t j = 0; j < num_params; ++j) {
102 inequality_constraint(i + filtered_lower_bound.size(),
103 j + index * num_params) = coef;
104 coef *= corrected_x;
105 }
106 inequality_boundary(i + filtered_lower_bound.size(), 0) =
107 -filtered_upper_bound[i];
108 }
109
110 return inequality_constraint_.AddConstraint(inequality_constraint,
111 inequality_boundary);
112}
113
115 const std::vector<double>& x_coord, const std::vector<double>& lower_bound,
116 const std::vector<double>& upper_bound) {
117 std::vector<double> filtered_lower_bound;
118 std::vector<double> filtered_upper_bound;
119 std::vector<double> filtered_lower_bound_x;
120 std::vector<double> filtered_upper_bound_x;
121
122 if (x_knots_.size() < 2) {
123 return false;
124 }
125
126 if (!FilterConstraints(x_coord, lower_bound, upper_bound,
127 &filtered_lower_bound_x, &filtered_lower_bound,
128 &filtered_upper_bound_x, &filtered_upper_bound)) {
129 return false;
130 }
131
132 // emplace affine constraints
133 const uint32_t num_params = spline_order_ + 1;
134 Eigen::MatrixXd inequality_constraint = Eigen::MatrixXd::Zero(
135 filtered_upper_bound.size() + filtered_lower_bound.size(),
136 (x_knots_.size() - 1) * num_params);
137 Eigen::MatrixXd inequality_boundary = Eigen::MatrixXd::Zero(
138 filtered_upper_bound.size() + filtered_lower_bound.size(), 1);
139
140 for (uint32_t i = 0; i < filtered_lower_bound.size(); ++i) {
141 uint32_t index = FindIndex(filtered_lower_bound_x[i]);
142 const double corrected_x = filtered_lower_bound_x[i] - x_knots_[index];
143 double coef = 1.0;
144 for (uint32_t j = 1; j < num_params; ++j) {
145 inequality_constraint(i, j + index * num_params) = coef * j;
146 coef *= corrected_x;
147 }
148 inequality_boundary(i, 0) = filtered_lower_bound[i];
149 }
150
151 for (uint32_t i = 0; i < filtered_upper_bound.size(); ++i) {
152 uint32_t index = FindIndex(filtered_upper_bound_x[i]);
153 const double corrected_x = filtered_upper_bound_x[i] - x_knots_[index];
154 double coef = -1.0;
155 for (uint32_t j = 1; j < num_params; ++j) {
156 inequality_constraint(i + filtered_lower_bound.size(),
157 j + index * num_params) = coef * j;
158 coef *= corrected_x;
159 }
160 inequality_boundary(i + filtered_lower_bound.size(), 0) =
161 -filtered_upper_bound[i];
162 }
163 return inequality_constraint_.AddConstraint(inequality_constraint,
164 inequality_boundary);
165}
166
168 const std::vector<double>& x_coord, const std::vector<double>& lower_bound,
169 const std::vector<double>& upper_bound) {
170 std::vector<double> filtered_lower_bound;
171 std::vector<double> filtered_upper_bound;
172 std::vector<double> filtered_lower_bound_x;
173 std::vector<double> filtered_upper_bound_x;
174
175 if (x_knots_.size() < 2) {
176 return false;
177 }
178
179 if (!FilterConstraints(x_coord, lower_bound, upper_bound,
180 &filtered_lower_bound_x, &filtered_lower_bound,
181 &filtered_upper_bound_x, &filtered_upper_bound)) {
182 return false;
183 }
184
185 // emplace affine constraints
186 const uint32_t num_params = spline_order_ + 1;
187 Eigen::MatrixXd inequality_constraint = Eigen::MatrixXd::Zero(
188 filtered_upper_bound.size() + filtered_lower_bound.size(),
189 (x_knots_.size() - 1) * num_params);
190 Eigen::MatrixXd inequality_boundary = Eigen::MatrixXd::Zero(
191 filtered_upper_bound.size() + filtered_lower_bound.size(), 1);
192
193 for (uint32_t i = 0; i < filtered_lower_bound.size(); ++i) {
194 uint32_t index = FindIndex(filtered_lower_bound_x[i]);
195 const double corrected_x = filtered_lower_bound_x[i] - x_knots_[index];
196 double coef = 1.0;
197 for (uint32_t j = 2; j < num_params; ++j) {
198 inequality_constraint(i, j + index * num_params) = coef * j * (j - 1);
199 coef *= corrected_x;
200 }
201 inequality_boundary(i, 0) = filtered_lower_bound[i];
202 }
203
204 for (uint32_t i = 0; i < filtered_upper_bound.size(); ++i) {
205 uint32_t index = FindIndex(filtered_upper_bound_x[i]);
206 const double corrected_x = filtered_upper_bound_x[i] - x_knots_[index];
207 double coef = -1.0;
208 for (uint32_t j = 2; j < num_params; ++j) {
209 inequality_constraint(i + filtered_lower_bound.size(),
210 j + index * num_params) = coef * j * (j - 1);
211 coef *= corrected_x;
212 }
213 inequality_boundary(i + filtered_lower_bound.size(), 0) =
214 -filtered_upper_bound[i];
215 }
216 return inequality_constraint_.AddConstraint(inequality_constraint,
217 inequality_boundary);
218}
219
221 const std::vector<double>& x_coord, const std::vector<double>& lower_bound,
222 const std::vector<double>& upper_bound) {
223 std::vector<double> filtered_lower_bound;
224 std::vector<double> filtered_upper_bound;
225 std::vector<double> filtered_lower_bound_x;
226 std::vector<double> filtered_upper_bound_x;
227
228 if (!FilterConstraints(x_coord, lower_bound, upper_bound,
229 &filtered_lower_bound_x, &filtered_lower_bound,
230 &filtered_upper_bound_x, &filtered_upper_bound)) {
231 AERROR << "Fail to filter constraints.";
232 return false;
233 }
234
235 if (x_knots_.size() < 2) {
236 AERROR << "x_konts size cannot be < 2.";
237 return false;
238 }
239
240 // emplace affine constraints
241 const uint32_t num_params = spline_order_ + 1;
242 Eigen::MatrixXd inequality_constraint = Eigen::MatrixXd::Zero(
243 filtered_upper_bound.size() + filtered_lower_bound.size(),
244 (x_knots_.size() - 1) * num_params);
245 Eigen::MatrixXd inequality_boundary = Eigen::MatrixXd::Zero(
246 filtered_upper_bound.size() + filtered_lower_bound.size(), 1);
247
248 for (uint32_t i = 0; i < filtered_lower_bound.size(); ++i) {
249 uint32_t index = FindIndex(filtered_lower_bound_x[i]);
250 const double corrected_x = filtered_lower_bound_x[i] - x_knots_[index];
251 double coef = 1.0;
252 for (uint32_t j = 3; j < num_params; ++j) {
253 inequality_constraint(i, j + index * num_params) =
254 coef * j * (j - 1) * (j - 2);
255 coef *= corrected_x;
256 }
257 inequality_boundary(i, 0) = filtered_lower_bound[i];
258 }
259
260 for (uint32_t i = 0; i < filtered_upper_bound.size(); ++i) {
261 uint32_t index = FindIndex(filtered_upper_bound_x[i]);
262 const double corrected_x = filtered_upper_bound_x[i] - x_knots_[index];
263 double coef = -1.0;
264 for (uint32_t j = 3; j < num_params; ++j) {
265 inequality_constraint(i + filtered_lower_bound.size(),
266 j + index * num_params) =
267 coef * j * (j - 1) * (j - 2);
268 coef *= corrected_x;
269 }
270 inequality_boundary(i + filtered_lower_bound.size(), 0) =
271 -filtered_upper_bound[i];
272 }
273 return inequality_constraint_.AddConstraint(inequality_constraint,
274 inequality_boundary);
275}
276
277bool Spline1dConstraint::AddPointConstraint(const double x, const double fx) {
278 uint32_t index = FindIndex(x);
279 std::vector<double> power_x;
280 const uint32_t num_params = spline_order_ + 1;
281 GeneratePowerX(x - x_knots_[index], num_params, &power_x);
282 Eigen::MatrixXd equality_constraint =
283 Eigen::MatrixXd::Zero(1, (x_knots_.size() - 1) * num_params);
284 uint32_t index_offset = index * num_params;
285 for (uint32_t i = 0; i < num_params; ++i) {
286 equality_constraint(0, index_offset + i) = power_x[i];
287 }
288 Eigen::MatrixXd equality_boundary(1, 1);
289 equality_boundary(0, 0) = fx;
290 return AddEqualityConstraint(equality_constraint, equality_boundary);
291}
292
293bool Spline1dConstraint::AddConstraintInRange(AddConstraintInRangeFunc func,
294 const double x, const double val,
295 const double range) {
296 if (range < 0.0) {
297 return false;
298 }
299 std::vector<double> x_vec;
300 x_vec.push_back(x);
301
302 std::vector<double> lower_bound;
303 std::vector<double> upper_bound;
304 lower_bound.push_back(val - range);
305 upper_bound.push_back(val + range);
306 return func(x_vec, lower_bound, upper_bound);
307}
308
310 const double fx,
311 const double range) {
312 return AddConstraintInRange(
313 std::bind(&Spline1dConstraint::AddBoundary, this, _1, _2, _3), x, fx,
314 range);
315}
316
318 const double dfx) {
319 uint32_t index = FindIndex(x);
320 std::vector<double> power_x;
321 const uint32_t num_params = spline_order_ + 1;
322 GeneratePowerX(x - x_knots_[index], num_params, &power_x);
323 Eigen::MatrixXd equality_constraint =
324 Eigen::MatrixXd::Zero(1, (x_knots_.size() - 1) * num_params);
325 uint32_t index_offset = index * num_params;
326 for (uint32_t i = 1; i < num_params; ++i) {
327 equality_constraint(0, index_offset + i) = power_x[i - 1] * i;
328 }
329 Eigen::MatrixXd equality_boundary(1, 1);
330 equality_boundary(0, 0) = dfx;
331 return AddEqualityConstraint(equality_constraint, equality_boundary);
332}
333
335 const double x, const double dfx, const double range) {
336 return AddConstraintInRange(
337 std::bind(&Spline1dConstraint::AddDerivativeBoundary, this, _1, _2, _3),
338 x, dfx, range);
339}
340
342 const double ddfx) {
343 uint32_t index = FindIndex(x);
344 std::vector<double> power_x;
345 const uint32_t num_params = spline_order_ + 1;
346 GeneratePowerX(x - x_knots_[index], num_params, &power_x);
347 Eigen::MatrixXd equality_constraint =
348 Eigen::MatrixXd::Zero(1, (x_knots_.size() - 1) * num_params);
349 uint32_t index_offset = index * num_params;
350 for (uint32_t i = 2; i < num_params; ++i) {
351 equality_constraint(0, index_offset + i) = power_x[i - 2] * i * (i - 1);
352 }
353 Eigen::MatrixXd equality_boundary(1, 1);
354 equality_boundary(0, 0) = ddfx;
355 return AddEqualityConstraint(equality_constraint, equality_boundary);
356}
357
359 const double x, const double ddfx, const double range) {
360 return AddConstraintInRange(
362 _3),
363 x, ddfx, range);
364}
365
367 const double dddfx) {
368 uint32_t index = FindIndex(x);
369 std::vector<double> power_x;
370 const uint32_t num_params = spline_order_ + 1;
371 GeneratePowerX(x - x_knots_[index], num_params, &power_x);
372 Eigen::MatrixXd equality_constraint =
373 Eigen::MatrixXd::Zero(1, (x_knots_.size() - 1) * num_params);
374 uint32_t index_offset = index * num_params;
375 for (uint32_t i = 3; i < num_params; ++i) {
376 equality_constraint(0, index_offset + i) =
377 power_x[i - 3] * i * (i - 1) * (i - 2);
378 }
379 Eigen::MatrixXd equality_boundary(1, 1);
380 equality_boundary(0, 0) = dddfx;
381 return AddEqualityConstraint(equality_constraint, equality_boundary);
382}
383
385 const double x, const double dddfx, const double range) {
386 return AddConstraintInRange(
388 _3),
389 x, dddfx, range);
390}
391
393 if (x_knots_.size() < 3) {
394 return false;
395 }
396 const uint32_t num_params = spline_order_ + 1;
397 Eigen::MatrixXd equality_constraint = Eigen::MatrixXd::Zero(
398 x_knots_.size() - 2, (x_knots_.size() - 1) * num_params);
399 Eigen::MatrixXd equality_boundary =
400 Eigen::MatrixXd::Zero(x_knots_.size() - 2, 1);
401
402 for (uint32_t i = 0; i < x_knots_.size() - 2; ++i) {
403 double left_coef = 1.0;
404 double right_coef = -1.0;
405 const double x_left = x_knots_[i + 1] - x_knots_[i];
406 const double x_right = 0.0;
407 for (uint32_t j = 0; j < num_params; ++j) {
408 equality_constraint(i, num_params * i + j) = left_coef;
409 equality_constraint(i, num_params * (i + 1) + j) = right_coef;
410 left_coef *= x_left;
411 right_coef *= x_right;
412 }
413 }
414 return equality_constraint_.AddConstraint(equality_constraint,
415 equality_boundary);
416}
417
419 if (x_knots_.size() < 3) {
420 return false;
421 }
422
423 const uint32_t n_constraint =
424 (static_cast<uint32_t>(x_knots_.size()) - 2) * 2;
425 const uint32_t num_params = spline_order_ + 1;
426 Eigen::MatrixXd equality_constraint =
427 Eigen::MatrixXd::Zero(n_constraint, (x_knots_.size() - 1) * num_params);
428 Eigen::MatrixXd equality_boundary = Eigen::MatrixXd::Zero(n_constraint, 1);
429
430 for (uint32_t i = 0; i < n_constraint; i += 2) {
431 double left_coef = 1.0;
432 double right_coef = -1.0;
433 double left_dcoef = 1.0;
434 double right_dcoef = -1.0;
435 const double x_left = x_knots_[i / 2 + 1] - x_knots_[i / 2];
436 const double x_right = 0.0;
437 for (uint32_t j = 0; j < num_params; ++j) {
438 equality_constraint(i, num_params * (i / 2) + j) = left_coef;
439 equality_constraint(i, num_params * ((i / 2) + 1) + j) = right_coef;
440 if (j >= 1) {
441 equality_constraint(i + 1, num_params * (i / 2) + j) = left_dcoef * j;
442 equality_constraint(i + 1, num_params * ((i / 2) + 1) + j) =
443 right_dcoef * j;
444 left_dcoef = left_coef;
445 right_dcoef = right_coef;
446 }
447 left_coef *= x_left;
448 right_coef *= x_right;
449 }
450 }
451 return equality_constraint_.AddConstraint(equality_constraint,
452 equality_boundary);
453}
454
456 if (x_knots_.size() < 3) {
457 return false;
458 }
459
460 const uint32_t n_constraint =
461 (static_cast<uint32_t>(x_knots_.size()) - 2) * 3;
462 const uint32_t num_params = spline_order_ + 1;
463 Eigen::MatrixXd equality_constraint =
464 Eigen::MatrixXd::Zero(n_constraint, (x_knots_.size() - 1) * num_params);
465 Eigen::MatrixXd equality_boundary = Eigen::MatrixXd::Zero(n_constraint, 1);
466
467 for (uint32_t i = 0; i < n_constraint; i += 3) {
468 double left_coef = 1.0;
469 double right_coef = -1.0;
470 double left_dcoef = 1.0;
471 double right_dcoef = -1.0;
472 double left_ddcoef = 1.0;
473 double right_ddcoef = -1.0;
474
475 const double x_left = x_knots_[i / 3 + 1] - x_knots_[i / 3];
476 const double x_right = 0.0;
477 for (uint32_t j = 0; j < num_params; ++j) {
478 equality_constraint(i, num_params * (i / 3) + j) = left_coef;
479 equality_constraint(i, num_params * (i / 3 + 1) + j) = right_coef;
480
481 if (j >= 2) {
482 equality_constraint(i + 2, num_params * i / 3 + j) =
483 left_ddcoef * j * (j - 1);
484 equality_constraint(i + 2, num_params * (i / 3 + 1) + j) =
485 right_ddcoef * j * (j - 1);
486 left_ddcoef = left_dcoef;
487 right_ddcoef = right_dcoef;
488 }
489
490 if (j >= 1) {
491 equality_constraint(i + 1, num_params * (i / 3) + j) = left_dcoef * j;
492 equality_constraint(i + 1, num_params * (i / 3 + 1) + j) =
493 right_dcoef * j;
494 left_dcoef = left_coef;
495 right_dcoef = right_coef;
496 }
497 left_coef *= x_left;
498 right_coef *= x_right;
499 }
500 }
501 return equality_constraint_.AddConstraint(equality_constraint,
502 equality_boundary);
503}
504
506 if (x_knots_.size() < 3) {
507 return false;
508 }
509
510 const uint32_t n_constraint =
511 (static_cast<uint32_t>(x_knots_.size()) - 2) * 4;
512 const uint32_t num_params = spline_order_ + 1;
513 Eigen::MatrixXd equality_constraint =
514 Eigen::MatrixXd::Zero(n_constraint, (x_knots_.size() - 1) * num_params);
515 Eigen::MatrixXd equality_boundary = Eigen::MatrixXd::Zero(n_constraint, 1);
516
517 for (uint32_t i = 0; i < n_constraint; i += 4) {
518 double left_coef = 1.0;
519 double right_coef = -1.0;
520 double left_dcoef = 1.0;
521 double right_dcoef = -1.0;
522 double left_ddcoef = 1.0;
523 double right_ddcoef = -1.0;
524 double left_dddcoef = 1.0;
525 double right_dddcoef = -1.0;
526
527 const double x_left = x_knots_[i / 4 + 1] - x_knots_[i / 4];
528 const double x_right = 0.0;
529 for (uint32_t j = 0; j < num_params; ++j) {
530 equality_constraint(i, num_params * i / 4 + j) = left_coef;
531 equality_constraint(i, num_params * (i / 4 + 1) + j) = right_coef;
532
533 if (j >= 3) {
534 equality_constraint(i + 3, num_params * i / 4 + j) =
535 left_dddcoef * j * (j - 1) * (j - 2);
536 equality_constraint(i + 3, num_params * (i / 4 + 1) + j) =
537 right_dddcoef * j * (j - 1) * (j - 2);
538 left_dddcoef = left_ddcoef;
539 right_dddcoef = right_ddcoef;
540 }
541
542 if (j >= 2) {
543 equality_constraint(i + 2, num_params * i / 4 + j) =
544 left_ddcoef * j * (j - 1);
545 equality_constraint(i + 2, num_params * (i / 4 + 1) + j) =
546 right_ddcoef * j * (j - 1);
547 left_ddcoef = left_dcoef;
548 right_ddcoef = right_dcoef;
549 }
550
551 if (j >= 1) {
552 equality_constraint(i + 1, num_params * i / 4 + j) = left_dcoef * j;
553 equality_constraint(i + 1, num_params * (i / 4 + 1) + j) =
554 right_dcoef * j;
555 left_dcoef = left_coef;
556 right_dcoef = right_coef;
557 }
558
559 left_coef *= x_left;
560 right_coef *= x_right;
561 }
562 }
563 return equality_constraint_.AddConstraint(equality_constraint,
564 equality_boundary);
565}
566
568 const std::vector<double>& x_coord) {
569 if (x_coord.size() < 2) {
570 // Skip because NO inequality constraint is needed.
571 return false;
572 }
573
574 const uint32_t num_params = spline_order_ + 1;
575 Eigen::MatrixXd inequality_constraint = Eigen::MatrixXd::Zero(
576 x_coord.size() - 1, (x_knots_.size() - 1) * num_params);
577 Eigen::MatrixXd inequality_boundary =
578 Eigen::MatrixXd::Zero(x_coord.size() - 1, 1);
579
580 uint32_t prev_spline_index = FindIndex(x_coord[0]);
581 double prev_rel_x = x_coord[0] - x_knots_[prev_spline_index];
582 std::vector<double> prev_coef;
583 GeneratePowerX(prev_rel_x, num_params, &prev_coef);
584 for (uint32_t i = 1; i < x_coord.size(); ++i) {
585 uint32_t cur_spline_index = FindIndex(x_coord[i]);
586 double cur_rel_x = x_coord[i] - x_knots_[cur_spline_index];
587 std::vector<double> cur_coef;
588
589 GeneratePowerX(cur_rel_x, num_params, &cur_coef);
590 // if constraint on the same spline
591 if (cur_spline_index == prev_spline_index) {
592 for (uint32_t j = 0; j < cur_coef.size(); ++j) {
593 inequality_constraint(i - 1, cur_spline_index * num_params + j) =
594 cur_coef[j] - prev_coef[j];
595 }
596 } else {
597 // if not on the same spline
598 for (uint32_t j = 0; j < cur_coef.size(); ++j) {
599 inequality_constraint(i - 1, prev_spline_index * num_params + j) =
600 -prev_coef[j];
601 inequality_constraint(i - 1, cur_spline_index * num_params + j) =
602 cur_coef[j];
603 }
604 }
605 prev_coef = cur_coef;
606 prev_spline_index = cur_spline_index;
607 }
608
609 return inequality_constraint_.AddConstraint(inequality_constraint,
610 inequality_boundary);
611}
612
616
618 return inequality_constraint_;
619}
620
622 return equality_constraint_;
623}
624
625uint32_t Spline1dConstraint::FindIndex(const double x) const {
626 auto upper_bound = std::upper_bound(x_knots_.begin() + 1, x_knots_.end(), x);
627 return std::min(static_cast<uint32_t>(x_knots_.size() - 1),
628 static_cast<uint32_t>(upper_bound - x_knots_.begin())) -
629 1;
630}
631
632bool Spline1dConstraint::FilterConstraints(
633 const std::vector<double>& x_coord, const std::vector<double>& lower_bound,
634 const std::vector<double>& upper_bound,
635 std::vector<double>* const filtered_lower_bound_x,
636 std::vector<double>* const filtered_lower_bound,
637 std::vector<double>* const filtered_upper_bound_x,
638 std::vector<double>* const filtered_upper_bound) {
639 filtered_lower_bound->clear();
640 filtered_upper_bound->clear();
641 filtered_lower_bound_x->clear();
642 filtered_upper_bound_x->clear();
643
644 const double inf = std::numeric_limits<double>::infinity();
645
646 filtered_lower_bound->reserve(lower_bound.size());
647 filtered_lower_bound_x->reserve(lower_bound.size());
648
649 filtered_upper_bound->reserve(upper_bound.size());
650 filtered_upper_bound_x->reserve(upper_bound.size());
651
652 for (uint32_t i = 0; i < lower_bound.size(); ++i) {
653 if (std::isnan(lower_bound[i]) || lower_bound[i] == inf) {
654 return false;
655 }
656 if (lower_bound[i] < inf && lower_bound[i] > -inf) {
657 filtered_lower_bound->emplace_back(lower_bound[i]);
658 filtered_lower_bound_x->emplace_back(x_coord[i]);
659 }
660 }
661
662 for (uint32_t i = 0; i < upper_bound.size(); ++i) {
663 if (std::isnan(upper_bound[i]) || upper_bound[i] == -inf) {
664 return false;
665 }
666 if (upper_bound[i] < inf && upper_bound[i] > -inf) {
667 filtered_upper_bound->emplace_back(upper_bound[i]);
668 filtered_upper_bound_x->emplace_back(x_coord[i]);
669 }
670 }
671 return true;
672}
673
674void Spline1dConstraint::GeneratePowerX(
675 const double x, const uint32_t order,
676 std::vector<double>* const power_x) const {
677 double cur_x = 1.0;
678 for (uint32_t i = 0; i < order; ++i) {
679 power_x->push_back(cur_x);
680 cur_x *= x;
681 }
682}
683
684} // namespace planning
685} // namespace apollo
bool AddConstraint(const Eigen::MatrixXd &constraint_matrix, const Eigen::MatrixXd &constraint_boundary)
void SetIsEquality(const double is_equality)
bool AddPointSecondDerivativeConstraint(const double x, const double ddfx)
bool AddDerivativeBoundary(const std::vector< double > &x_coord, const std::vector< double > &lower_bound, const std::vector< double > &upper_bound)
bool AddPointThirdDerivativeConstraintInRange(const double x, const double dddfx, const double range)
const AffineConstraint & equality_constraint() const
bool AddBoundary(const std::vector< double > &x_coord, const std::vector< double > &lower_bound, const std::vector< double > &upper_bound)
: inequality boundary constraints if no boundary, do specify either by std::infinity or let vector....
bool AddEqualityConstraint(const Eigen::MatrixXd &constraint_matrix, const Eigen::MatrixXd &constraint_boundary)
bool AddThirdDerivativeBoundary(const std::vector< double > &x_coord, const std::vector< double > &lower_bound, const std::vector< double > &upper_bound)
bool AddPointDerivativeConstraint(const double x, const double dfx)
const AffineConstraint & inequality_constraint() const
: output interface inequality constraint
bool AddInequalityConstraint(const Eigen::MatrixXd &constraint_matrix, const Eigen::MatrixXd &constraint_boundary)
bool AddMonotoneInequalityConstraint(const std::vector< double > &x_coord)
: Add monotone constraint inequality, guarantee the monotone city at evaluated point.
bool AddSecondDerivativeBoundary(const std::vector< double > &x_coord, const std::vector< double > &lower_bound, const std::vector< double > &upper_bound)
bool AddPointSecondDerivativeConstraintInRange(const double x, const double ddfx, const double range)
bool AddPointDerivativeConstraintInRange(const double x, const double dfx, const double range)
bool AddPointThirdDerivativeConstraint(const double x, const double dddfx)
bool AddPointConstraintInRange(const double x, const double fx, const double range)
bool AddPointConstraint(const double x, const double fx)
: equality constraint to guarantee joint smoothness boundary equality constriant constraint on fx,...
Planning module main class.
#define AERROR
Definition log.h:44
class register implement
Definition arena_queue.h:37
: wrapp up solver constraint interface with direct methods and preset methods