GCC Code Coverage Report


Directory: ./
File: include/parametric-curves/spline.hpp
Date: 2025-04-07 13:04:42
Exec Total Coverage
Lines: 180 225 80.0%
Branches: 328 678 48.4%

Line Branch Exec Source
1 /**
2 * \file exact_cubic.h
3 * \brief class allowing to create an Exact cubic spline.
4 * \author Steve T.
5 * \version 0.1
6 * \date 06/17/2013
7 *
8 * This file contains definitions for the Spline class.
9 */
10
11 #ifndef _parameteric_curves_spline_hpp
12 #define _parameteric_curves_spline_hpp
13
14 #include <parametric-curves/MathDefs.h>
15
16 #include <boost/archive/text_iarchive.hpp>
17 #include <boost/archive/text_oarchive.hpp>
18 #include <boost/serialization/split_member.hpp>
19 #include <boost/serialization/vector.hpp>
20 #include <fstream>
21 #include <parametric-curves/abstract-curve.hpp>
22 #include <parametric-curves/curve-constraint.hpp>
23 #include <parametric-curves/polynomial.hpp>
24 #include <vector>
25 namespace parametriccurves {
26
27 /// \brief Creates coefficient vector of a cubic spline defined on the interval
28 /// [tBegin, tEnd]. It follows the equation
29 /// x(t) = a + b(t - t_min_) + c(t - t_min_)^2 + d(t - t_min_)^3
30 ///
31 template <typename Point, typename T_Point>
32 50 T_Point make_cubic_vector(Point const& a, Point const& b, Point const& c,
33 Point const& d) {
34 50 T_Point res;
35
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
50 res.push_back(a);
36
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
50 res.push_back(b);
37
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
50 res.push_back(c);
38
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
50 res.push_back(d);
39 50 return res;
40 }
41
42 template <typename Numeric, Eigen::Index Dim, typename Point, typename T_Point>
43 50 Polynomial<Numeric, Dim, Point> create_cubic(Point const& a, Point const& b,
44 Point const& c, Point const& d,
45 const Numeric min,
46 const Numeric max) {
47
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
50 T_Point coeffs = make_cubic_vector<Point, T_Point>(a, b, c, d);
48 return Polynomial<Numeric, Dim, Point>(coeffs.begin(), coeffs.end(), min,
49
1/2
✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
100 max);
50 50 }
51 /// \brief Creates coefficient vector of a quintic spline defined on the
52 /// interval [tBegin, tEnd]. It follows the equation x(t) = a + b(t - t_min_) +
53 /// c(t - t_min_)^2 + d(t - t_min_)^3 + e(t - t_min_)^4 + f(t - t_min_)^5
54 ///
55 template <typename Point, typename T_Point>
56 2 T_Point make_quintic_vector(Point const& a, Point const& b, Point const& c,
57 Point const& d, Point const& e, Point const& f) {
58 2 T_Point res;
59
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.push_back(a);
60
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.push_back(b);
61
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.push_back(c);
62
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.push_back(d);
63
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.push_back(e);
64
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 res.push_back(f);
65 2 return res;
66 }
67
68 template <typename Numeric, Eigen::Index Dim, typename Point, typename T_Point>
69 2 Polynomial<Numeric, Dim, Point> create_quintic(Point const& a, Point const& b,
70 Point const& c, Point const& d,
71 Point const& e, Point const& f,
72 const Numeric min,
73 const Numeric max) {
74
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 T_Point coeffs = make_quintic_vector<Point, T_Point>(a, b, c, d, e, f);
75 return Polynomial<Numeric, Dim, Point>(coeffs.begin(), coeffs.end(), min,
76
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
4 max);
77 2 }
78
79 /// \class Spline
80 /// \brief Represents a set of cubic splines defining a continuous function
81 /// crossing each of the waypoint given in its initialization
82 ///
83 template <typename Numeric = double, Eigen::Index Dim = Eigen::Dynamic,
84 typename Point = Eigen::Matrix<Numeric, Dim, 1>,
85 typename SplineBase = Polynomial<Numeric, Dim, Point> >
86 struct Spline : public AbstractCurve<Numeric, Point> {
87 typedef Point point_t;
88 typedef std::vector<Point, Eigen::aligned_allocator<Point> > t_point_t;
89 typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
90 typedef Numeric time_t;
91 typedef Numeric num_t;
92 typedef SplineBase spline_t;
93 typedef typename std::vector<spline_t, Eigen::aligned_allocator<spline_t> >
94 t_spline_t;
95 typedef typename t_spline_t::iterator it_spline_t;
96 typedef typename t_spline_t::const_iterator cit_spline_t;
97 typedef curve_constraints<point_t> spline_constraints;
98 typedef AbstractCurve<Numeric, Point> curve_abc_t;
99
100 public:
101 ///\brief Constructor
102
103
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
17 Spline() : curve_abc_t() {}
104
105 ///\brief Constructor
106 ///\param subSplines: vector of subsplines
107 Spline(const t_spline_t& subSplines)
108 : curve_abc_t(subSplines.front().tmin(), subSplines.back().tmax()),
109 subSplines_(subSplines) {}
110
111 ///\brief Copy Constructor
112 Spline(const Spline& other)
113 : curve_abc_t(other.subSplines_.front().tmin(),
114 other.subSplines_.front().tmax()),
115 subSplines_(other.subSplines_) {}
116
117 ///\brief Destructor
118 22 ~Spline() {}
119
120 public:
121 /* Given a set of waypoints (x_i*) and timestep (t_i), it provides the unique
122 * set of cubic splines fulfulling those 4 restrictions :
123 * - x_i(t_i) = x_i* ; this means that the curve passes through each waypoint
124 * - x_i(t_i+1) = x_i+1* ;
125 * - its derivative is continous at t_i+1
126 * - its 2nd derivative is continous at t_i+1
127 * more details in paper "Task-Space Trajectories via Cubic Spline
128 * Optimization" By J. Zico Kolter and Andrew Y.ng (ICRA 2009) */
129 template <typename In>
130 8 void createSplineFromWayPoints(In wayPointsBegin, In wayPointsEnd) {
131
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 std::size_t const size(std::distance(wayPointsBegin, wayPointsEnd));
132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 if (size < 1) {
133 throw; // TODO
134 }
135 8 subSplines_.clear();
136
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 subSplines_.reserve(size);
137
138 // refer to the paper to understand all this.
139
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX h1 = MatrixX::Zero(size, size);
140
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX h2 = MatrixX::Zero(size, size);
141
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX h3 = MatrixX::Zero(size, size);
142
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX h4 = MatrixX::Zero(size, size);
143
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX h5 = MatrixX::Zero(size, size);
144
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX h6 = MatrixX::Zero(size, size);
145
146
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX a = MatrixX::Zero(size, Dim);
147
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX b = MatrixX::Zero(size, Dim);
148
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX c = MatrixX::Zero(size, Dim);
149
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX d = MatrixX::Zero(size, Dim);
150
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 MatrixX x = MatrixX::Zero(size, Dim);
151 8 In it(wayPointsBegin), next(wayPointsBegin);
152 8 ++next;
153
154
2/2
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 4 times.
34 for (std::size_t i(0); next != wayPointsEnd; ++next, ++it, ++i) {
155 26 num_t const dTi((*next).first - (*it).first);
156 26 num_t const dTi_sqr(dTi * dTi);
157 26 num_t const dTi_cube(dTi_sqr * dTi);
158 // filling matrices values
159
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h3(i, i) = -3 / dTi_sqr;
160
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h3(i, i + 1) = 3 / dTi_sqr;
161
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h4(i, i) = -2 / dTi;
162
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h4(i, i + 1) = -1 / dTi;
163
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h5(i, i) = 2 / dTi_cube;
164
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h5(i, i + 1) = -2 / dTi_cube;
165
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h6(i, i) = 1 / dTi_sqr;
166
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 h6(i, i + 1) = 1 / dTi_sqr;
167
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4 times.
26 if (i + 2 < size) {
168 18 In it2(next);
169 18 ++it2;
170 18 num_t const dTi_1((*it2).first - (*next).first);
171 18 num_t const dTi_1sqr(dTi_1 * dTi_1);
172 // this can be optimized but let's focus on clarity as long as not
173 // needed
174
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 h1(i + 1, i) = 2 / dTi;
175
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 h1(i + 1, i + 1) = 4 / dTi + 4 / dTi_1;
176
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 h1(i + 1, i + 2) = 2 / dTi_1;
177
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 h2(i + 1, i) = -6 / dTi_sqr;
178
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 h2(i + 1, i + 1) = (6 / dTi_1sqr) - (6 / dTi_sqr);
179
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 h2(i + 1, i + 2) = 6 / dTi_1sqr;
180 }
181
3/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
26 x.row(i) = (*it).second.transpose();
182 }
183 // adding last x
184
3/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
8 x.row(size - 1) = (*it).second.transpose();
185
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 a = x;
186
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 parametriccurves::PseudoInverse(h1);
187
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
8 b = h1 * h2 * x; // h1 * b = h2 * x => b = (h1)^-1 * h2 * x
188
4/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
8 c = h3 * x + h4 * b;
189
4/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
8 d = h5 * x + h6 * b;
190 8 it = wayPointsBegin, next = wayPointsBegin;
191 8 ++next;
192
193
2/2
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 4 times.
34 for (int i = 0; next != wayPointsEnd; ++i, ++it, ++next) {
194 26 Numeric min = (*it).first;
195 26 Numeric max = (*next).first;
196
13/26
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 13 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 13 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 13 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 13 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 13 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 13 times.
✗ Branch 38 not taken.
26 Point a_ = a.row(i) - b.row(i) * min + c.row(i) * min * min -
197
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 d.row(i) * min * min * min;
198
11/22
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 13 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 13 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 13 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 13 times.
✗ Branch 32 not taken.
26 Point b_ = b.row(i) - 2 * c.row(i) * min + 3 * d.row(i) * min * min;
199
6/12
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
26 Point c_ = c.row(i) - 3 * d.row(i) * min;
200
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 Point d_ = d.row(i);
201
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 subSplines_.push_back(create_cubic<Numeric, Dim, Point, t_point_t>(
202 a_, b_, c_, d_, min, max));
203 }
204 8 Numeric min = (*it).first;
205
12/24
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 4 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 4 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 4 times.
✗ Branch 35 not taken.
16 Point a_ = a.row(size - 1) - b.row(size - 1) * min +
206
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
16 c.row(size - 1) * min * min - d.row(size - 1) * min * min * min;
207
9/18
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
8 Point b_ = b.row(size - 1) - 2 * c.row(size - 1) * min +
208
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 3 * d.row(size - 1) * min * min;
209
6/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
8 Point c_ = c.row(size - 1) - 3 * d.row(size - 1) * min;
210
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 Point d_ = d.row(size - 1);
211
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 subSplines_.push_back(
212 create_cubic<Numeric, Dim, Point, t_point_t>(a_, b_, c_, d_, min, min));
213
214
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 this->t_min = subSplines_.front().tmin();
215
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 this->t_max = subSplines_.back().tmax();
216 16 return;
217 8 }
218
219 template <typename In>
220 2 void createSplineFromWayPointsConstr(In wayPointsBegin, In wayPointsEnd,
221 const spline_constraints& constraints) {
222
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 std::size_t const size(std::distance(wayPointsBegin, wayPointsEnd));
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (size < 1) throw; // TODO
224 2 subSplines_.clear();
225
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 subSplines_.reserve(size);
226
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 spline_constraints cons = constraints;
227 2 In it(wayPointsBegin), next(wayPointsBegin), end(wayPointsEnd - 1);
228 2 ++next;
229
2/2
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
10 for (std::size_t i(0); next != end; ++next, ++it, ++i)
230
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 compute_one_spline<In>(it, next, cons, subSplines_);
231
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 compute_end_spline<In>(it, next, cons, subSplines_);
232 4 return;
233 2 }
234
235 public:
236 50 virtual const point_t operator()(const time_t& t) const {
237
7/10
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 25 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 24 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 24 times.
50 if ((t < subSplines_.front().tmin() || t > subSplines_.back().tmax())) {
238
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 throw std::out_of_range("t is out of range");
239 }
240
1/2
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
116 for (cit_spline_t it = subSplines_.begin(); it != subSplines_.end(); ++it) {
241
7/10
✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 58 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✓ Branch 11 taken 34 times.
✓ Branch 12 taken 24 times.
✓ Branch 13 taken 34 times.
116 if (t >= (it->tmin()) && t <= (it->tmax())) {
242
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
48 return it->operator()(t);
243 }
244 }
245 const point_t dummy;
246 return dummy;
247 }
248
249 16 virtual const point_t derivate(const time_t& t,
250 const std::size_t& order) const {
251
5/10
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
16 if ((t < subSplines_.front().tmin() || t > subSplines_.back().tmax())) {
252 throw std::out_of_range("derivative call out of range");
253 }
254
1/2
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
48 for (cit_spline_t it = subSplines_.begin(); it != subSplines_.end(); ++it) {
255
7/10
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 16 times.
✓ Branch 12 taken 8 times.
✓ Branch 13 taken 16 times.
48 if (t >= (it->tmin()) && t <= (it->tmax())) {
256
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
16 return it->derivate(t, order);
257 }
258 }
259
260 const point_t dummy;
261 return dummy;
262 }
263
264 virtual const std::size_t& size() const { return subSplines_[0].size(); }
265 const t_spline_t& getSubsplines() const { return subSplines_; }
266
267 virtual bool setInitialPoint(const point_t& /*x_init*/) { return false; }
268 virtual bool setInitialPoint(const num_t& /*x_init*/) { return false; }
269
270 protected:
271 /*Attributes*/
272 t_spline_t subSplines_; // const
273
274 private:
275 template <typename In>
276 8 void compute_one_spline(In wayPointsBegin, In wayPointsNext,
277 spline_constraints& constraints,
278 t_spline_t& subSplines) const {
279
1/2
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 const point_t &a0 = wayPointsBegin->second, a1 = wayPointsNext->second;
280
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 const point_t &b0 = constraints.init_vel, c0 = constraints.init_acc / 2.;
281 8 const num_t &init_t = wayPointsBegin->first, end_t = wayPointsNext->first;
282 8 const num_t dt = end_t - init_t, dt_2 = dt * dt, dt_3 = dt_2 * dt;
283
7/14
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
8 const point_t d0 = (a1 - a0 - b0 * dt - c0 * dt_2) / dt_3;
284
285
10/20
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 8 times.
✗ Branch 29 not taken.
8 Point a_ =
286 a0 - b0 * init_t + c0 * init_t * init_t - d0 * init_t * init_t * init_t;
287
8/16
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 23 not taken.
8 Point b_ = b0 - 2 * c0 * init_t + 3 * d0 * init_t * init_t;
288
4/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
8 Point c_ = c0 - 3 * d0 * init_t;
289
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 Point d_ = d0;
290
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 subSplines.push_back(create_cubic<Numeric, Dim, Point, t_point_t>(
291 a_, b_, c_, d_, init_t, end_t));
292
293
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
8 constraints.init_vel = subSplines.back().derivate(end_t, 1);
294
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
8 constraints.init_acc = subSplines.back().derivate(end_t, 2);
295 8 }
296
297 template <typename In>
298 2 void compute_end_spline(In wayPointsBegin, In wayPointsNext,
299 spline_constraints& constraints,
300 t_spline_t& subSplines) const {
301
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 const point_t &a0 = wayPointsBegin->second, a1 = wayPointsNext->second;
302
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 const point_t &b0 = constraints.init_vel, b1 = constraints.end_vel,
303
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
2 c0 = constraints.init_acc / 2., c1 = constraints.end_acc;
304 2 const num_t &init_t = wayPointsBegin->first, end_t = wayPointsNext->first;
305 2 const num_t dt = end_t - init_t, dt_2 = dt * dt, dt_3 = dt_2 * dt,
306 2 dt_4 = dt_3 * dt, dt_5 = dt_4 * dt;
307 // solving a system of four linear eq with 4 unknows: d0, e0
308
6/12
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
2 const point_t alpha_0 = a1 - a0 - b0 * dt - c0 * dt_2;
309
5/10
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
2 const point_t alpha_1 = b1 - b0 - 2 * c0 * dt;
310
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
2 const point_t alpha_2 = c1 - 2 * c0;
311 2 const num_t x_d_0 = dt_3, x_d_1 = 3 * dt_2, x_d_2 = 6 * dt;
312 2 const num_t x_e_0 = dt_4, x_e_1 = 4 * dt_3, x_e_2 = 12 * dt_2;
313 2 const num_t x_f_0 = dt_5, x_f_1 = 5 * dt_4, x_f_2 = 20 * dt_3;
314
315
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
2 point_t d, e, f;
316
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 Eigen::MatrixXd rhs = Eigen::MatrixXd::Zero(3, Dim);
317
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 rhs.row(0) = alpha_0;
318
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 rhs.row(1) = alpha_1;
319
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 rhs.row(2) = alpha_2;
320
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 Eigen::Matrix3d eq = Eigen::Matrix3d::Zero();
321
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(0, 0) = x_d_0;
322
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(0, 1) = x_e_0;
323
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(0, 2) = x_f_0;
324
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(1, 0) = x_d_1;
325
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(1, 1) = x_e_1;
326
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(1, 2) = x_f_1;
327
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(2, 0) = x_d_2;
328
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(2, 1) = x_e_2;
329
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 eq(2, 2) = x_f_2;
330
4/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
2 rhs = eq.inverse().eval() * rhs;
331
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 d = rhs.row(0);
332
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 e = rhs.row(1);
333
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 f = rhs.row(2);
334 2 num_t min = init_t;
335 2 Numeric min2 = min * min;
336 2 Numeric min3 = min2 * min;
337 2 Numeric min4 = min3 * min;
338 2 Numeric min5 = min4 * min;
339
11/22
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 32 not taken.
2 Point a_ = a0 - b0 * min + c0 * min2 - d * min3 + e * min4 - f * min5;
340
13/26
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 2 times.
✗ Branch 38 not taken.
2 Point b_ = b0 - 2 * c0 * min + 3 * d * min2 - 4 * e * min3 + 5 * f * min4;
341
10/20
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
2 Point c_ = c0 - 3 * d * min + 6 * e * min2 - 10 * f * min3;
342
7/14
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
2 Point d_ = d - 4 * e * min + 10 * f * min2;
343
4/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
2 Point e_ = e - 5 * f * min;
344
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 Point f_ = f;
345
346
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 subSplines.push_back(create_quintic<Numeric, Dim, Point, t_point_t>(
347 a_, b_, c_, d_, e_, f_, init_t, end_t));
348 2 }
349
350 // Serialization of the class
351 friend class boost::serialization::access;
352 template <class Archive>
353 void save(Archive& ar, const unsigned int /*version*/) const {
354 ar& subSplines_;
355
356 return;
357 }
358
359 template <class Archive>
360 void load(Archive& ar, const unsigned int /*version*/) {
361 ar& subSplines_;
362
363 this->t_min = subSplines_.front().tmin();
364 this->t_max = subSplines_.back().tmax();
365 return;
366 }
367
368 BOOST_SERIALIZATION_SPLIT_MEMBER()
369
370 public:
371 bool loadFromFile(const std::string& filename) {
372 std::ifstream ifs(filename.c_str());
373 if (ifs) {
374 boost::archive::text_iarchive ia(ifs);
375 Spline& cubic_spline = *static_cast<Spline*>(this);
376 ia >> cubic_spline;
377 } else {
378 const std::string exception_message(filename +
379 " does not seem to be a valid file.");
380 throw std::invalid_argument(exception_message);
381 return false;
382 }
383 return true;
384 }
385
386 /// \brief Saved a Derived object as a text file.
387 bool saveToFile(const std::string& filename) const {
388 std::ofstream ofs(filename.c_str());
389 if (ofs) {
390 boost::archive::text_oarchive oa(ofs);
391 oa << *static_cast<const Spline*>(this);
392 } else {
393 const std::string exception_message(filename +
394 " does not seem to be a valid file.");
395 throw std::invalid_argument(exception_message);
396 return false;
397 }
398 return true;
399 }
400
401 // BOOST_SERIALIZATION_SPLIT_MEMBER()
402 };
403 } // namespace parametriccurves
404 #endif //_CLASS_EXACTCUBIC
405