Directory: | ./ |
---|---|
File: | python/ndcurves/optimization_python.cpp |
Date: | 2025-03-05 17:18:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 74 | 127 | 58.3% |
Branches: | 54 | 138 | 39.1% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <boost/python.hpp> | ||
2 | #include <boost/python/bases.hpp> | ||
3 | #include <boost/python/enum.hpp> | ||
4 | |||
5 | #include "archive_python_binding.h" | ||
6 | #include "namespace.h" | ||
7 | #include "ndcurves/optimization/definitions.h" | ||
8 | #include "ndcurves/optimization/quadratic_problem.h" | ||
9 | #include "python_variables.h" | ||
10 | |||
11 | namespace ndcurves { | ||
12 | namespace optimization { | ||
13 | namespace python { | ||
14 | static const bool safe = true; | ||
15 | typedef problem_definition<pointX_t, real> problem_definition_t; | ||
16 | typedef problem_data<pointX_t, real> problem_data_t; | ||
17 | typedef quadratic_problem<pointX_t, real> quadratic_problem_t; | ||
18 | |||
19 | 9 | problem_data_t setup_control_points_t(problem_definition_t& pDef) { | |
20 | 9 | problem_data_t pData = setup_control_points<pointX_t, real, safe>(pDef); | |
21 | 8 | return pData; // return new problem_data_t(pData); | |
22 | } | ||
23 | |||
24 | ✗ | quadratic_variable_t problem_t_cost(const quadratic_problem_t& p) { | |
25 | ✗ | return p.cost; | |
26 | } | ||
27 | ✗ | Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> problem_t_ineqMatrix( | |
28 | const quadratic_problem_t& p) { | ||
29 | ✗ | return p.ineqMatrix; | |
30 | } | ||
31 | ✗ | Eigen::Matrix<real, Eigen::Dynamic, 1> problem_t_ineqVector( | |
32 | const quadratic_problem_t& p) { | ||
33 | ✗ | return p.ineqVector; | |
34 | } | ||
35 | |||
36 | ✗ | Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> cost_t_quad( | |
37 | const quadratic_variable_t& p) { | ||
38 | ✗ | Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> A = p.A(); | |
39 | ✗ | return A; | |
40 | } | ||
41 | ✗ | Eigen::Matrix<real, Eigen::Dynamic, 1> cost_t_linear( | |
42 | const quadratic_variable_t& p) { | ||
43 | ✗ | Eigen::Matrix<real, Eigen::Dynamic, 1> b = p.b(); | |
44 | ✗ | return b; | |
45 | } | ||
46 | ✗ | real cost_t_constant(const quadratic_variable_t& p) { return p.c(); } | |
47 | |||
48 | ✗ | quadratic_problem_t generate_problem_t(const problem_definition_t& pDef, | |
49 | const quadratic_variable_t& c) { | ||
50 | ✗ | return generate_problem<pointX_t, real, true>(pDef, c); | |
51 | } | ||
52 | |||
53 | 1 | quadratic_problem_t generate_integral_problem_t( | |
54 | const problem_definition_t& pDef, const integral_cost_flag c) { | ||
55 | 1 | return generate_problem<problem_definition_t::point_t, real, true>(pDef, c); | |
56 | } | ||
57 | |||
58 | 4 | void set_pd_flag(problem_definition_t* pDef, const int flag) { | |
59 | 4 | pDef->flag = (constraint_flag)(flag); | |
60 | 4 | } | |
61 | 2 | void set_start(problem_definition_t* pDef, const pointX_t& val) { | |
62 | 2 | pDef->init_pos = val; | |
63 | 2 | } | |
64 | 2 | void set_end(problem_definition_t* pDef, const pointX_t& val) { | |
65 | 2 | pDef->end_pos = val; | |
66 | 2 | } | |
67 | 5 | void set_degree(problem_definition_t* pDef, const std::size_t val) { | |
68 | 5 | pDef->degree = val; | |
69 | 5 | } | |
70 | ✗ | void set_total_time(problem_definition_t* pDef, const double val) { | |
71 | ✗ | pDef->totalTime = val; | |
72 | } | ||
73 | ✗ | void set_split_time(problem_definition_t* pDef, const Eigen::VectorXd& val) { | |
74 | ✗ | pDef->splitTimes_ = val; | |
75 | } | ||
76 | ✗ | Eigen::VectorXd get_split_times(const problem_definition_t* pDef) { | |
77 | ✗ | return pDef->splitTimes_; | |
78 | } | ||
79 | |||
80 | ✗ | constraint_flag get_pd_flag(const problem_definition_t* pDef) { | |
81 | ✗ | return pDef->flag; | |
82 | } | ||
83 | 2 | Eigen::VectorXd get_start(const problem_definition_t* pDef) { | |
84 | 2 | return pDef->init_pos; | |
85 | } | ||
86 | ✗ | Eigen::VectorXd get_end(const problem_definition_t* pDef) { | |
87 | ✗ | return pDef->end_pos; | |
88 | } | ||
89 | 1 | std::size_t get_degree(const problem_definition_t* pDef) { | |
90 | 1 | return pDef->degree; | |
91 | } | ||
92 | ✗ | double get_total_time(const problem_definition_t* pDef) { | |
93 | ✗ | return pDef->totalTime; | |
94 | } | ||
95 | |||
96 | ✗ | matrix_pair* get_ineq_at(const problem_definition_t* pDef, | |
97 | const std::size_t idx) { | ||
98 | ✗ | if (idx > pDef->inequalityMatrices_.size() - 1) | |
99 | ✗ | throw std::runtime_error( | |
100 | ✗ | "required id is beyond number of inequality matrices"); | |
101 | ✗ | matrix_pair* res = new matrix_pair(pDef->inequalityMatrices_[idx], | |
102 | ✗ | pDef->inequalityVectors_[idx]); | |
103 | ✗ | return res; | |
104 | } | ||
105 | ✗ | bool del_ineq_at(problem_definition_t* pDef, const std::size_t idx) { | |
106 | ✗ | if (idx > pDef->inequalityMatrices_.size() - 1) return false; | |
107 | ✗ | pDef->inequalityMatrices_.erase(pDef->inequalityMatrices_.begin() + idx - 1); | |
108 | ✗ | pDef->inequalityVectors_.erase(pDef->inequalityVectors_.begin() + idx - 1); | |
109 | ✗ | return true; | |
110 | } | ||
111 | ✗ | bool add_ineq_at(problem_definition_t* pDef, const Eigen::MatrixXd ineq, | |
112 | const Eigen::VectorXd vec) { | ||
113 | ✗ | if (ineq.rows() != vec.rows()) | |
114 | ✗ | throw std::runtime_error( | |
115 | ✗ | "ineq vector and matrix do not have the same number of rows"); | |
116 | ✗ | if (!(pDef->inequalityMatrices_.empty()) && | |
117 | ✗ | ineq.cols() != pDef->inequalityMatrices_.back().cols()) | |
118 | ✗ | throw std::runtime_error( | |
119 | "inequality matrix does not have the same variable dimension as " | ||
120 | ✗ | "existing matrices"); | |
121 | ✗ | pDef->inequalityMatrices_.push_back(ineq); | |
122 | ✗ | pDef->inequalityVectors_.push_back(vec); | |
123 | ✗ | return true; | |
124 | } | ||
125 | |||
126 | 8 | bezier_linear_variable_t* pDataBezier(const problem_data_t* pData) { | |
127 | 8 | const bezier_linear_variable_t& b = *pData->bezier; | |
128 | return new bezier_linear_variable_t( | ||
129 |
4/8✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
|
8 | b.waypoints().begin(), b.waypoints().end(), b.min(), b.max(), b.mult_T_); |
130 | } | ||
131 | |||
132 | ✗ | problem_definition_t* wrapProblemDefinitionConstructor( | |
133 | const curve_constraints_t* c) { | ||
134 | ✗ | return new problem_definition_t(*c); | |
135 | } | ||
136 | |||
137 | 8 | void exposeOptimization() { | |
138 | // using the optimization scope | ||
139 | bp::scope current_scope = | ||
140 |
3/6✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
|
16 | ndcurves::python::getOrCreatePythonNamespace("optimization"); |
141 | /** BEGIN enums**/ | ||
142 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | bp::enum_<constraint_flag>("constraint_flag") |
143 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("INIT_POS", INIT_POS) |
144 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("INIT_VEL", INIT_VEL) |
145 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("INIT_ACC", INIT_ACC) |
146 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("INIT_JERK", INIT_JERK) |
147 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("END_POS", END_POS) |
148 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("END_VEL", END_VEL) |
149 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("END_ACC", END_ACC) |
150 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("END_JERK", END_JERK) |
151 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("ALL", ALL) |
152 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("NONE", NONE) |
153 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .export_values(); |
154 | |||
155 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | bp::enum_<integral_cost_flag>("integral_cost_flag") |
156 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("DISTANCE", DISTANCE) |
157 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("VELOCITY", VELOCITY) |
158 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("ACCELERATION", ACCELERATION) |
159 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("JERK", JERK) |
160 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("FOURTH", FOURTH) |
161 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .value("FIFTH", FIFTH) |
162 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .export_values(); |
163 | /** END enum**/ | ||
164 | |||
165 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
16 | bp::class_<quadratic_problem_t>("quadratic_problem", bp::init<>()) |
166 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("cost", &problem_t_cost) |
167 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("A", &problem_t_ineqMatrix) |
168 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("b", &problem_t_ineqVector); |
169 | |||
170 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | bp::def("setup_control_points", &setup_control_points_t); |
171 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | bp::def("generate_problem", &generate_problem_t); |
172 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | bp::def("generate_integral_problem", &generate_integral_problem_t); |
173 | |||
174 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | bp::class_<problem_data_t>("problem_data", bp::no_init) |
175 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def("bezier", &pDataBezier, |
176 | ✗ | bp::return_value_policy<bp::manage_new_object>()) | |
177 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def_readonly("numControlPoints", &problem_data_t::numControlPoints) |
178 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def_readonly("numVariables", &problem_data_t::numVariables) |
179 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def_readonly("startVariableIndex", &problem_data_t::startVariableIndex) |
180 | 8 | .def_readonly("numStateConstraints", | |
181 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | &problem_data_t::numStateConstraints); |
182 | |||
183 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | bp::class_<problem_definition_t, bp::bases<curve_constraints_t> >( |
184 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | "problem_definition", bp::init<int>()) |
185 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
16 | .def("__init__", bp::make_constructor(&wrapProblemDefinitionConstructor)) |
186 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("flag", &get_pd_flag, &set_pd_flag) |
187 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("init_pos", &get_start, &set_start) |
188 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("end_pos", &get_end, &set_end) |
189 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("degree", &get_degree, &set_degree) |
190 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("totalTime", &get_total_time, &set_total_time) |
191 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .add_property("splits", &get_split_times, &set_split_time) |
192 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def("inequality", &get_ineq_at, |
193 | 8 | bp::return_value_policy<bp::manage_new_object>()) | |
194 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def("removeInequality", &del_ineq_at) |
195 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | .def("addInequality", &add_ineq_at); |
196 | 8 | } | |
197 | |||
198 | } // namespace python | ||
199 | } // namespace optimization | ||
200 | } // namespace ndcurves | ||
201 |