Apollo 11.0
自动驾驶开放平台
piecewise_jerk_speed_problem.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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
18
19#include "cyber/common/log.h"
21
22namespace apollo {
23namespace planning {
24
26 const size_t num_of_knots, const double delta_s,
27 const std::array<double, 3>& x_init)
28 : PiecewiseJerkProblem(num_of_knots, delta_s, x_init) {
29 penalty_dx_.resize(num_of_knots_, 0.0);
30 dx_ref_.resize(num_of_knots_, 0.0);
31 weight_dx_ref_.resize(num_of_knots_, 0.0);
32}
33
34void PiecewiseJerkSpeedProblem::set_dx_ref(const double weight_dx_ref,
35 const double dx_ref) {
36 weight_dx_ref_.resize(num_of_knots_, weight_dx_ref);
37 dx_ref_.resize(num_of_knots_, dx_ref);
38 has_dx_ref_ = true;
39}
40
42 const std::vector<double>& weight_dx_ref,
43 const std::vector<double>& dx_ref) {
44 weight_dx_ref_ = weight_dx_ref;
45 dx_ref_ = dx_ref;
46 has_dx_ref_ = true;
47}
48
49void PiecewiseJerkSpeedProblem::set_penalty_dx(std::vector<double> penalty_dx) {
50 CHECK_EQ(penalty_dx.size(), num_of_knots_);
51 penalty_dx_ = std::move(penalty_dx);
52}
53
54void PiecewiseJerkSpeedProblem::CalculateKernel(std::vector<c_float>* P_data,
55 std::vector<c_int>* P_indices,
56 std::vector<c_int>* P_indptr) {
57 const int n = static_cast<int>(num_of_knots_);
58 const int kNumParam = 3 * n;
59 const int kNumValue = 4 * n - 1;
60 std::vector<std::vector<std::pair<c_int, c_float>>> columns;
61 columns.resize(kNumParam);
62 int value_index = 0;
63
64 // x(i)^2 * w_x_ref
65 for (int i = 0; i < n - 1; ++i) {
66 columns[i].emplace_back(
68 ++value_index;
69 }
70 // x(n-1)^2 * (w_x_ref + w_end_x)
71 columns[n - 1].emplace_back(n - 1, (weight_x_ref_ + weight_end_state_[0]) /
73 ++value_index;
74
75 // x(i)'^2 * (w_dx_ref + penalty_dx)
76 for (int i = 0; i < n - 1; ++i) {
77 columns[n + i].emplace_back(n + i,
78 (weight_dx_ref_[i] + penalty_dx_[i]) /
80 ++value_index;
81 }
82 // x(n-1)'^2 * (w_dx_ref + penalty_dx + w_end_dx)
83 columns[2 * n - 1].emplace_back(
84 2 * n - 1,
85 (weight_dx_ref_[n - 1] + penalty_dx_[n - 1] + weight_end_state_[1]) /
87 ++value_index;
88
89 auto delta_s_square = delta_s_ * delta_s_;
90 // x(i)''^2 * (w_ddx + 2 * w_dddx / delta_s^2)
91 columns[2 * n].emplace_back(2 * n,
92 (weight_ddx_ + weight_dddx_ / delta_s_square) /
94 ++value_index;
95
96 for (int i = 1; i < n - 1; ++i) {
97 columns[2 * n + i].emplace_back(
98 2 * n + i, (weight_ddx_ + 2.0 * weight_dddx_ / delta_s_square) /
100 ++value_index;
101 }
102
103 columns[3 * n - 1].emplace_back(
104 3 * n - 1,
105 (weight_ddx_ + weight_dddx_ / delta_s_square + weight_end_state_[2]) /
106 (scale_factor_[2] * scale_factor_[2]));
107 ++value_index;
108
109 // -2 * w_dddx / delta_s^2 * x(i)'' * x(i + 1)''
110 for (int i = 0; i < n - 1; ++i) {
111 columns[2 * n + i].emplace_back(2 * n + i + 1,
112 -2.0 * weight_dddx_ / delta_s_square /
113 (scale_factor_[2] * scale_factor_[2]));
114 ++value_index;
115 }
116
117 CHECK_EQ(value_index, kNumValue);
118
119 int ind_p = 0;
120 for (int i = 0; i < kNumParam; ++i) {
121 P_indptr->push_back(ind_p);
122 for (const auto& row_data_pair : columns[i]) {
123 P_data->push_back(row_data_pair.second * 2.0);
124 P_indices->push_back(row_data_pair.first);
125 ++ind_p;
126 }
127 }
128 P_indptr->push_back(ind_p);
129}
130
131void PiecewiseJerkSpeedProblem::CalculateOffset(std::vector<c_float>* q) {
132 CHECK_NOTNULL(q);
133 const int n = static_cast<int>(num_of_knots_);
134 const int kNumParam = 3 * n;
135 q->resize(kNumParam);
136 for (int i = 0; i < n; ++i) {
137 if (has_x_ref_) {
138 q->at(i) += -2.0 * weight_x_ref_ * x_ref_[i] / scale_factor_[0];
139 }
140 if (has_dx_ref_) {
141 q->at(n + i) += -2.0 * weight_dx_ref_[i] * dx_ref_[i] / scale_factor_[1];
142 }
143 }
144
145 if (has_end_state_ref_) {
146 q->at(n - 1) +=
148 q->at(2 * n - 1) +=
150 q->at(3 * n - 1) +=
152 }
153}
154
156 // Define Solver default settings
157 OSQPSettings* settings =
158 reinterpret_cast<OSQPSettings*>(c_malloc(sizeof(OSQPSettings)));
159 osqp_set_default_settings(settings);
160 settings->eps_abs = 1e-2;
161 settings->eps_rel = 1e-2;
162 settings->eps_prim_inf = 1e-5;
163 settings->eps_dual_inf = 1e-5;
164 settings->polish = true;
165 settings->verbose = FLAGS_enable_osqp_debug;
166 settings->scaled_termination = true;
167 settings->time_limit = FLAGS_path_speed_osqp_setting_time_limit;
168 return settings;
169}
170
171} // namespace planning
172} // namespace apollo
void set_dx_ref(const double weight_dx_ref, const double dx_ref)
void set_penalty_dx(std::vector< double > penalty_dx)
void CalculateOffset(std::vector< c_float > *q) override
void CalculateKernel(std::vector< c_float > *P_data, std::vector< c_int > *P_indices, std::vector< c_int > *P_indptr) override
PiecewiseJerkSpeedProblem(const size_t num_of_knots, const double delta_s, const std::array< double, 3 > &x_init)
Planning module main class.
class register implement
Definition arena_queue.h:37