12 #ifndef _CLASS_SPLINEOPTIMIZER
13 #define _CLASS_SPLINEOPTIMIZER
15 #include <Eigen/SparseCore>
18 #include "mosek/mosek.h"
19 #include "spline/MathDefs.h"
20 #include "spline/exact_cubic.h"
25 template <
typename Time = double,
typename Numeric =
Time, Eigen::Index Dim = 3,
26 bool Safe =
false,
typename Point = Eigen::Matrix<Numeric, Dim, 1> >
28 typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic>
MatrixX;
39 MSKrescodee r_ = MSK_makeenv(&env_, NULL);
40 assert(r_ == MSK_RES_OK);
57 template <
typename In>
59 In wayPointsEnd)
const;
63 template <
typename In>
64 void ComputeHMatrices(In wayPointsBegin, In wayPointsEnd,
MatrixX& h1,
73 typedef std::pair<time_t, Point> waypoint_t;
74 typedef std::vector<waypoint_t> T_waypoints_t;
77 template <
typename Time,
typename Numeric, Eigen::Index Dim,
bool Safe,
79 template <
typename In>
81 In wayPointsBegin, In wayPointsEnd, MatrixX& h1, MatrixX& h2, MatrixX& h3,
83 std::size_t
const size(std::distance(wayPointsBegin, wayPointsEnd));
84 assert((!Safe) || (size > 1));
86 In it(wayPointsBegin), next(wayPointsBegin);
88 Numeric t_previous((*it).first);
90 for (std::size_t i(0); next != wayPointsEnd; ++next, ++it, ++i) {
91 num_t
const dTi((*next).first - (*it).first);
92 num_t
const dTi_sqr(dTi * dTi);
94 h3(i, i) = -3 / dTi_sqr;
95 h3(i, i + 1) = 3 / dTi_sqr;
97 h4(i, i + 1) = -1 / dTi;
101 num_t
const dTi_1((*it2).first - (*next).first);
102 num_t
const dTi_1sqr(dTi_1 * dTi_1);
104 h1(i + 1, i) = 2 / dTi;
105 h1(i + 1, i + 1) = 4 / dTi + 4 / dTi_1;
106 h1(i + 1, i + 2) = 2 / dTi_1;
107 h2(i + 1, i) = -6 / dTi_sqr;
108 h2(i + 1, i + 1) = (6 / dTi_1sqr) - (6 / dTi_sqr);
109 h2(i + 1, i + 2) = 6 / dTi_1sqr;
114 template <
typename Time,
typename Numeric, std::size_t Dim,
bool Safe,
116 template <
typename In>
117 inline exact_cubic<Time, Numeric, Dim, Safe, Point>*
119 In wayPointsBegin, In wayPointsEnd)
const {
121 int const size((
int)std::distance(wayPointsBegin, wayPointsEnd));
122 if (Safe && size < 1) {
126 MatrixX h1 = MatrixX::Zero(size, size);
127 MatrixX h2 = MatrixX::Zero(size, size);
128 MatrixX h3 = MatrixX::Zero(size, size);
129 MatrixX h4 = MatrixX::Zero(size, size);
137 ComputeHMatrices(wayPointsBegin, wayPointsEnd, h1, h2, h3, h4);
143 const MSKint32t numvar = (size)*Dim * 3;
157 int ptOff = (int)Dim * size;
158 int ptptOff = (int)Dim * 2 * size;
165 MatrixX h2x_h1x = MatrixX::Zero(size * Dim, numvar);
175 for (
int i = 0; i < size * Dim; i = i + 3) {
176 for (
int j = 0; j < Dim; ++j) {
178 h2x_h1x.block(
id, j * size, 1, size) = h2.row(i % 3);
179 h2x_h1x.block(
id, j * size + ptOff, 1, size) -= h1.row(i % 3);
188 MatrixX g1x_g2x = MatrixX::Zero(size * Dim, numvar);
216 MatrixX g3x_g4x = MatrixX::Zero(size * Dim, numvar);
245 MatrixX h3x_h4x = MatrixX::Zero(size * Dim, numvar);
255 for (
int i = 0; i < size * Dim; i = i + Dim) {
256 for (
int j = 0; j < Dim; ++j) {
258 h3x_h4x.block(
id, j * size, 1, size) = h3.row(i % 3);
259 h3x_h4x.block(
id, j * size + ptOff, 1, size) = h4.row(i % 3);
260 h3x_h4x.block(
id, j * size + ptptOff, 1, size) =
261 MatrixX::Ones(1, size) * -2;
268 MatrixX x0_x0 = MatrixX::Zero(Dim, numvar);
269 for (
int j = 0; j < Dim; ++j) {
272 x0_x0(2, size * 2) = 1;
276 MatrixX x0p_0 = MatrixX::Zero(Dim, numvar);
277 for (
int j = 0; j < Dim; ++j) {
279 x0p_0(1, ptOff + size) = 1;
280 x0p_0(2, ptOff + size * 2) = 1;
284 MatrixX xt_xt = MatrixX::Zero(Dim, numvar);
285 for (
int j = 0; j < Dim; ++j) {
286 xt_xt(0, size - 1) = 1;
287 xt_xt(1, 2 * size - 1) = 1;
288 xt_xt(2, 3 * size - 1) = 1;
292 MatrixX xtp_0 = MatrixX::Zero(Dim, numvar);
293 for (
int j = 0; j < Dim; ++j) {
294 xtp_0(0, ptOff + size - 1) = 1;
295 xtp_0(1, ptOff + size + size - 1) = 1;
296 xtp_0(2, ptOff + size * 2 + size - 1) = 1;
310 const MSKint32t numcon = Dim * 2 * size + 4 * Dim;
313 MatrixX a = MatrixX::Zero(numcon, numvar);
314 a.block(0, 0, size * Dim, numvar) = h2x_h1x;
315 a.block(size * Dim, 0, size * Dim, numvar) = h3x_h4x;
316 a.block(size * Dim * 2, 0, Dim, numvar) = x0p_0;
317 a.block(size * Dim * 2 + Dim, 0, Dim, numvar) = xtp_0;
318 a.block(size * Dim * 2 + Dim * 2, 0, Dim, numvar) = x0_x0;
319 a.block(size * Dim * 2 + Dim * 3, 0, Dim, numvar) = xt_xt;
322 Eigen::SparseMatrix<Numeric> spA;
323 spA = a.sparseView();
328 int nonZeros = spA.nonZeros();
332 double* aval =
new double[nonZeros];
333 MSKint32t* asub =
new MSKint32t[nonZeros];
334 MSKint32t* aptrb =
new MSKint32t[numvar];
335 MSKint32t* aptre =
new MSKint32t[numvar];
337 int currentIndex = 0;
338 for (
int j = 0; j < numvar; ++j) {
339 bool nonZeroAtThisCol =
false;
340 for (
int i = 0; i < numcon; ++i) {
342 if (!nonZeroAtThisCol) {
343 aptrb[j] = currentIndex;
344 nonZeroAtThisCol =
true;
346 aval[currentIndex] = a(i, j);
347 asub[currentIndex] = i;
348 aptre[j] = currentIndex + 1;
362 const MSKint32t numqz = size * Dim * 2;
363 MSKint32t* qsubi =
new MSKint32t[numqz];
364 MSKint32t* qsubj =
new MSKint32t[numqz];
365 double* qval =
new double[numqz];
366 for (
int id = 0;
id < numqz; ++id) {
367 qsubi[id] =
id + ptOff;
368 qsubj[id] =
id + ptOff;
373 MSKboundkeye* bkc =
new MSKboundkeye[numcon];
375 double* blc =
new double[numcon];
376 double* buc =
new double[numcon];
378 for (
int i = 0; i < numcon - Dim * 2; ++i) {
383 for (
int i = numcon - Dim * 2; i < numcon - Dim; ++i)
386 blc[i] = wayPointsBegin->second(i - (numcon - Dim * 2));
387 buc[i] = wayPointsBegin->second(i - (numcon - Dim * 2));
389 In last(wayPointsEnd);
391 for (
int i = numcon - 3; i < numcon; ++i)
394 blc[i] = last->second(i - (numcon - Dim));
395 buc[i] = last->second(i - (numcon - Dim));
399 MSKboundkeye* bkx =
new MSKboundkeye[numvar];
401 double* blx =
new double[numvar];
402 double* bux =
new double[numvar];
404 for (
int i = 0; i < numvar; ++i) {
406 blx[i] = -MSK_INFINITY;
407 bux[i] = +MSK_INFINITY;
411 MSKtask_t task = NULL;
413 r = MSK_maketask(env_, numcon, numvar, &task);
421 if (r == MSK_RES_OK) r = MSK_appendcons(task, numcon);
425 if (r == MSK_RES_OK) r = MSK_appendvars(task, numvar);
427 for (
int j = 0; j < numvar && r == MSK_RES_OK; ++j) {
429 if (r == MSK_RES_OK) r = MSK_putcj(task, j, 0);
434 r = MSK_putvarbound(task, j,
441 r = MSK_putacol(task, j,
449 for (
int i = 0; i < numcon && r == MSK_RES_OK; ++i)
450 r = MSK_putconbound(task, i,
456 if (r == MSK_RES_OK) r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MINIMIZE);
458 if (r == MSK_RES_OK) {
461 r = MSK_putqobj(task, numqz, qsubi, qsubj, qval);
464 if (r == MSK_RES_OK) {
468 r = MSK_optimizetrm(task, &trmcode);
469 if (r == MSK_RES_OK) {
470 double* xx = (
double*)calloc(numvar,
sizeof(
double));
473 MSK_getxx(task, MSK_SOL_ITR, xx);
474 T_waypoints_t nwaypoints;
475 In begin(wayPointsBegin);
476 for (
int i = 0; i < size; i = ++i, ++begin) {
478 for (
int j = 0; j < Dim; ++j) {
479 target(j) = xx[i + j * size];
481 nwaypoints.push_back(std::make_pair(begin->first, target));
483 res =
new exact_cubic_t(nwaypoints.begin(), nwaypoints.end());
489 MSK_deletetask(&task);
double Time
Definition: effector_spline.h:27
Eigen::Matrix< Numeric, 3, 1 > Point
Definition: effector_spline.h:28
double Numeric
Definition: effector_spline.h:26
spline_deriv_constraint_t::exact_cubic_t exact_cubic_t
Definition: effector_spline.h:35
Definition: bernstein.h:20
Mosek connection to produce optimized splines.
Definition: OptimizeSpline.h:27
Numeric num_t
Definition: OptimizeSpline.h:31
Eigen::Matrix< Numeric, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Definition: OptimizeSpline.h:28
SplineOptimizer()
Initializes optimizer environment.
Definition: OptimizeSpline.h:38
exact_cubic< time_t, Numeric, Dim, Safe, Point > exact_cubic_t
Definition: OptimizeSpline.h:32
Point point_t
Definition: OptimizeSpline.h:29
SplineOptimizer< time_t, Numeric, Dim, Safe, Point > splineOptimizer_t
Definition: OptimizeSpline.h:33
exact_cubic_t * GenerateOptimizedCurve(In wayPointsBegin, In wayPointsEnd) const
Starts an optimization loop to create curve.
~SplineOptimizer()
Destructor.
Definition: OptimizeSpline.h:44
Time time_t
Definition: OptimizeSpline.h:30