29 std::vector<std::pair<double, double>> points, std::vector<double> bounds) {
30 CHECK_GT(points.size(), 1U);
31 CHECK_GT(bounds.size(), 1U);
32 bounds_around_refs_ = std::move(bounds);
33 ref_points_ = std::move(points);
34 num_of_points_ = ref_points_.size();
38 std::vector<double>* ptr_x, std::vector<double>* ptr_y)
const {
45 IndexStyleEnum& index_style) {
46 CHECK_GT(num_of_points_, 3U);
49 num_of_slack_var_ = num_of_points_ - 2;
50 n =
static_cast<int>(num_of_points_ * 2 + num_of_slack_var_);
51 num_of_variables_ = n;
56 num_of_curvature_constr_ = num_of_points_ - 2;
57 num_of_slack_constr_ = num_of_points_ - 2;
58 m =
static_cast<int>(num_of_points_ * 2 + num_of_curvature_constr_ +
59 num_of_slack_constr_);
60 num_of_constraints_ = m;
65 slack_var_start_index_ = num_of_points_ * 2;
66 slack_var_end_index_ = slack_var_start_index_ + num_of_slack_var_;
67 curvature_constr_start_index_ = num_of_points_ * 2;
68 curvature_constr_end_index_ =
69 curvature_constr_start_index_ + num_of_curvature_constr_;
70 slack_constr_start_index_ = curvature_constr_end_index_;
71 slack_constr_end_index_ = slack_constr_start_index_ + num_of_slack_constr_;
75 index_style = IndexStyleEnum::C_STYLE;
81 double* g_l,
double* g_u) {
82 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
83 CHECK_EQ(
static_cast<size_t>(m), num_of_constraints_);
86 for (
size_t i = 0; i < num_of_points_; ++i) {
93 x_l[index + 1] = -1e20;
94 x_u[index + 1] = 1e20;
97 for (
size_t i = slack_var_start_index_; i < slack_var_end_index_; ++i) {
104 for (
size_t i = 0; i < num_of_points_; ++i) {
105 size_t index = i * 2;
107 g_l[index] = ref_points_[i].first - bounds_around_refs_[i];
108 g_u[index] = ref_points_[i].first + bounds_around_refs_[i];
111 g_l[index + 1] = ref_points_[i].second - bounds_around_refs_[i];
112 g_u[index + 1] = ref_points_[i].second + bounds_around_refs_[i];
116 double ref_total_length = 0.0;
117 auto pre_point = ref_points_.front();
118 for (
size_t i = 1; i < num_of_points_; ++i) {
119 auto cur_point = ref_points_[i];
120 double x_diff = cur_point.first - pre_point.first;
121 double y_diff = cur_point.second - pre_point.second;
122 ref_total_length += std::sqrt(x_diff * x_diff + y_diff * y_diff);
123 pre_point = cur_point;
125 double average_delta_s =
126 ref_total_length /
static_cast<double>(num_of_points_ - 1);
127 double curvature_constr_upper =
128 average_delta_s * average_delta_s * curvature_constraint_;
130 for (
size_t i = curvature_constr_start_index_;
131 i < curvature_constr_end_index_; ++i) {
133 g_u[i] = curvature_constr_upper * curvature_constr_upper;
137 for (
size_t i = slack_constr_start_index_; i < slack_constr_end_index_; ++i) {
146 double* x,
bool init_z,
147 double* z_L,
double* z_U,
148 int m,
bool init_lambda,
150 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
151 for (
size_t i = 0; i < num_of_points_; ++i) {
152 size_t index = i * 2;
153 x[index] = ref_points_[i].first;
154 x[index + 1] = ref_points_[i].second;
157 for (
size_t i = slack_var_start_index_; i < slack_var_end_index_; ++i) {
166 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
173 bool new_x,
double* grad_f) {
174 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
176 gradient(
tag_f, n, x, grad_f);
182 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
183 CHECK_EQ(
static_cast<size_t>(m), num_of_constraints_);
190 bool new_x,
int m,
int nele_jac,
191 int* iRow,
int* jCol,
193 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
194 CHECK_EQ(
static_cast<size_t>(m), num_of_constraints_);
196 if (values ==
nullptr) {
198 for (
int idx = 0; idx < nnz_jac_; idx++) {
199 iRow[idx] = rind_g_[idx];
200 jCol[idx] = cind_g_[idx];
204 sparse_jac(
tag_g, m, n, 1, x, &nnz_jac_, &rind_g_, &cind_g_, &jacval_,
206 for (
int idx = 0; idx < nnz_jac_; idx++) {
207 values[idx] = jacval_[idx];
214 double obj_factor,
int m,
215 const double* lambda,
216 bool new_lambda,
int nele_hess,
217 int* iRow,
int* jCol,
219 if (values ==
nullptr) {
222 for (
int idx = 0; idx < nnz_L_; idx++) {
223 iRow[idx] = rind_L_[idx];
224 jCol[idx] = cind_L_[idx];
229 obj_lam_[0] = obj_factor;
230 for (
int idx = 0; idx < m; idx++) {
231 obj_lam_[1 + idx] = lambda[idx];
233 set_param_vec(
tag_L, m + 1, &obj_lam_[0]);
234 sparse_hess(
tag_L, n, 1,
const_cast<double*
>(x), &nnz_L_, &rind_L_,
235 &cind_L_, &hessval_, options_L_);
237 for (
int idx = 0; idx < nnz_L_; idx++) {
238 values[idx] = hessval_[idx];
245 Ipopt::SolverReturn status,
int n,
const double* x,
const double* z_L,
246 const double* z_U,
int m,
const double* g,
const double* lambda,
247 double obj_value,
const Ipopt::IpoptData* ip_data,
248 Ipopt::IpoptCalculatedQuantities* ip_cq) {
249 opt_x_.reserve(num_of_points_);
250 opt_y_.reserve(num_of_points_);
251 for (
size_t i = 0; i < num_of_points_; ++i) {
252 size_t index = i * 2;
253 opt_x_.emplace_back(x[index]);
254 opt_y_.emplace_back(x[index + 1]);
272 for (
size_t i = 0; i < num_of_points_; ++i) {
273 size_t index = i * 2;
275 weight_ref_deviation_ *
276 ((x[index] - ref_points_[i].first) * (x[index] - ref_points_[i].first) +
277 (x[index + 1] - ref_points_[i].second) *
278 (x[index + 1] - ref_points_[i].second));
282 for (
size_t i = 0; i + 2 < num_of_points_; ++i) {
283 size_t findex = i * 2;
284 size_t mindex = findex + 2;
285 size_t lindex = mindex + 2;
287 *obj_value += weight_fem_pos_deviation_ *
288 (((x[findex] + x[lindex]) - 2.0 * x[mindex]) *
289 ((x[findex] + x[lindex]) - 2.0 * x[mindex]) +
290 ((x[findex + 1] + x[lindex + 1]) - 2.0 * x[mindex + 1]) *
291 ((x[findex + 1] + x[lindex + 1]) - 2.0 * x[mindex + 1]));
295 for (
size_t i = 0; i + 1 < num_of_points_; ++i) {
296 size_t findex = i * 2;
297 size_t nindex = findex + 2;
299 weight_path_length_ *
300 ((x[findex] - x[nindex]) * (x[findex] - x[nindex]) +
301 (x[findex + 1] - x[nindex + 1]) * (x[findex + 1] - x[nindex + 1]));
305 for (
size_t i = slack_var_start_index_; i < slack_var_end_index_; ++i) {
306 *obj_value += weight_curvature_constraint_slack_var_ * x[i];
317 for (
size_t i = 0; i < num_of_points_; ++i) {
318 size_t index = i * 2;
320 g[index + 1] = x[index + 1];
324 for (
size_t i = 0; i + 2 < num_of_points_; ++i) {
325 size_t findex = i * 2;
326 size_t mindex = findex + 2;
327 size_t lindex = mindex + 2;
328 g[curvature_constr_start_index_ + i] =
329 (((x[findex] + x[lindex]) - 2.0 * x[mindex]) *
330 ((x[findex] + x[lindex]) - 2.0 * x[mindex]) +
331 ((x[findex + 1] + x[lindex + 1]) - 2.0 * x[mindex + 1]) *
332 ((x[findex + 1] + x[lindex + 1]) - 2.0 * x[mindex + 1])) -
333 x[slack_var_start_index_ + i];
337 size_t slack_var_index = 0;
338 for (
size_t i = slack_constr_start_index_; i < slack_constr_end_index_; ++i) {
339 g[i] = x[slack_var_start_index_ + slack_var_index];
348 std::vector<double> xp(n, 0.0);
349 std::vector<double> lamp(m, 0.0);
350 std::vector<double> zl(m, 0.0);
351 std::vector<double> zu(m, 0.0);
352 std::vector<adouble> xa(n, 0.0);
353 std::vector<adouble> g(m, 0.0);
354 std::vector<double> lam(m, 0.0);
361 obj_lam_.resize(m + 1, 0.0);
366 for (
int idx = 0; idx < n; idx++) {
375 for (
int idx = 0; idx < n; idx++) {
379 for (
int idx = 0; idx < m; idx++) {
386 for (
int idx = 0; idx < n; idx++) {
389 for (
int idx = 0; idx < m; idx++) {
394 obj_value *= mkparam(sig);
396 for (
int idx = 0; idx < m; idx++) {
397 obj_value += g[idx] * mkparam(lam[idx]);
415 sparse_jac(
tag_g, m, n, 0, &xp[0], &nnz_jac_, &rind_g_, &cind_g_, &jacval_,
417 *nnz_jac_g = nnz_jac_;
420 sparse_hess(
tag_L, n, 0, &xp[0], &nnz_L_, &rind_L_, &cind_L_, &hessval_,
void get_optimization_results(std::vector< double > *ptr_x, std::vector< double > *ptr_y) const
bool get_bounds_info(int n, double *x_l, double *x_u, int m, double *g_l, double *g_u) override
Method to return the bounds for my problem
bool eval_g(int n, const double *x, bool new_x, int m, double *g) override
Method to return the constraint residuals
bool eval_grad_f(int n, const double *x, bool new_x, double *grad_f) override
Method to return the gradient of the objective
bool get_starting_point(int n, bool init_x, double *x, bool init_z, double *z_L, double *z_U, int m, bool init_lambda, double *lambda) override
Method to return the starting point for the algorithm
bool eval_obj(int n, const T *x, T *obj_value)
Template to return the objective value
bool get_nlp_info(int &n, int &m, int &nnz_jac_g, int &nnz_h_lag, IndexStyleEnum &index_style) override
Method to return some info about the nlp
FemPosDeviationIpoptInterface(std::vector< std::pair< double, double > > points, std::vector< double > bounds)
void finalize_solution(Ipopt::SolverReturn status, int n, const double *x, const double *z_L, const double *z_U, int m, const double *g, const double *lambda, double obj_value, const Ipopt::IpoptData *ip_data, Ipopt::IpoptCalculatedQuantities *ip_cq) override
This method is called when the algorithm is complete so the TNLP can store/write the solution
bool eval_constraints(int n, const T *x, int m, T *g)
Template to compute contraints
bool eval_jac_g(int n, const double *x, bool new_x, int m, int nele_jac, int *iRow, int *jCol, double *values) override
Method to return: 1) The structure of the jacobian (if "values" is nullptr) 2) The values of the jaco...
bool eval_h(int n, const double *x, bool new_x, double obj_factor, int m, const double *lambda, bool new_lambda, int nele_hess, int *iRow, int *jCol, double *values) override
Method to return: 1) The structure of the hessian of the lagrangian (if "values" is nullptr) 2) The v...
virtual void generate_tapes(int n, int m, int *nnz_jac_g, int *nnz_h_lag)
Method to generate the required tapes
bool eval_f(int n, const double *x, bool new_x, double &obj_value) override
Method to return the objective value
Planning module main class.