Directory: | ./ |
---|---|
File: | include/ndcurves/constant_curve.h |
Date: | 2025-03-05 17:18:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 48 | 54 | 88.9% |
Branches: | 34 | 54 | 63.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * \file constant_curve.h | ||
3 | * \brief class allowing to create a constant_curve curve. | ||
4 | * \author Pierre Fernbach | ||
5 | * \version 0.4 | ||
6 | * \date 29/04/2020 | ||
7 | */ | ||
8 | |||
9 | #ifndef _CLASS_CONSTANTCURVE | ||
10 | #define _CLASS_CONSTANTCURVE | ||
11 | |||
12 | #include "curve_abc.h" | ||
13 | |||
14 | namespace ndcurves { | ||
15 | /// \class constant_curve. | ||
16 | /// \brief Represents a constant_curve curve, always returning the same value | ||
17 | /// and a null derivative | ||
18 | /// | ||
19 | template <typename Time = double, typename Numeric = Time, bool Safe = false, | ||
20 | typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1>, | ||
21 | typename Point_derivate = Point> | ||
22 | struct constant_curve | ||
23 | : public curve_abc<Time, Numeric, Safe, Point, Point_derivate> { | ||
24 | typedef Point point_t; | ||
25 | typedef Point_derivate point_derivate_t; | ||
26 | typedef Time time_t; | ||
27 | typedef Numeric num_t; | ||
28 | typedef constant_curve<Time, Numeric, Safe, Point, Point_derivate> | ||
29 | constant_curve_t; | ||
30 | typedef constant_curve<Time, Numeric, Safe, Point_derivate> curve_derivate_t; | ||
31 | typedef curve_abc<Time, Numeric, Safe, point_t, Point_derivate> | ||
32 | curve_abc_t; // parent class | ||
33 | |||
34 | /* Constructors - destructors */ | ||
35 | public: | ||
36 | /// \brief Empty constructor. Curve obtained this way can not perform other | ||
37 | /// class functions. | ||
38 | /// | ||
39 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | constant_curve() : T_min_(0), T_max_(0), dim_(0) {} |
40 | |||
41 | /// \brief Constructor.. | ||
42 | /// \param value : The constant value | ||
43 | /// \param T_min : lower bound of the time interval | ||
44 | /// \param T_max : upper bound of the time interval | ||
45 | /// | ||
46 | 78 | constant_curve(const Point& value, const time_t T_min = 0., | |
47 | const time_t T_max = std::numeric_limits<time_t>::max()) | ||
48 |
1/2✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
|
78 | : value_(value), T_min_(T_min), T_max_(T_max), dim_(value.size()) { |
49 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 36 times.
|
78 | if (Safe && T_min_ > T_max_) { |
50 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | throw std::invalid_argument( |
51 | "can't create constant curve: min bound is higher than max bound"); | ||
52 | } | ||
53 | 84 | } | |
54 | |||
55 | /// \brief Copy constructor | ||
56 | /// \param other | ||
57 | 2 | constant_curve(const constant_curve_t& other) | |
58 | 2 | : value_(other.value_), | |
59 | 2 | T_min_(other.T_min_), | |
60 | 2 | T_max_(other.T_max_), | |
61 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | dim_(other.dim_) {} |
62 | |||
63 | /// \brief Destructor. | ||
64 | 144 | virtual ~constant_curve() {} | |
65 | /* Constructors - destructors */ | ||
66 | |||
67 | /*Operations*/ | ||
68 | /// \brief Evaluation of the cubic spline at time t. | ||
69 | /// \param t : time when to evaluate the spine | ||
70 | /// \return \f$x(t)\f$, point corresponding on curve at time t. | ||
71 | 128 | virtual point_t operator()(const time_t t) const { | |
72 |
4/4✓ Branch 0 taken 61 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 59 times.
|
128 | if (Safe && (t < T_min_ || t > T_max_)) { |
73 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
10 | throw std::invalid_argument( |
74 | "error in constant curve : time t to evaluate should be in range " | ||
75 | "[Tmin, Tmax] of the curve"); | ||
76 | } | ||
77 | 118 | return value_; | |
78 | } | ||
79 | |||
80 | /// \brief Compute the derived curve at order N. | ||
81 | /// Computes the derivative order N, \f$\frac{d^Nx(t)}{dt^N}\f$ of bezier | ||
82 | /// curve of parametric equation x(t). \param order : order of derivative. | ||
83 | /// \return \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve. | ||
84 | 10 | curve_derivate_t compute_derivate() const { | |
85 | size_t derivate_size; | ||
86 | if (point_derivate_t::RowsAtCompileTime == Eigen::Dynamic) { | ||
87 | 6 | derivate_size = dim_; | |
88 | } else { | ||
89 | 4 | derivate_size = point_derivate_t::RowsAtCompileTime; | |
90 | } | ||
91 |
2/4✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
|
10 | point_derivate_t value(point_derivate_t::Zero(derivate_size)); |
92 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
20 | return curve_derivate_t(value, T_min_, T_max_); |
93 | } | ||
94 | |||
95 | /// \brief Compute the derived curve at order N. | ||
96 | /// \param order : order of derivative. | ||
97 | /// \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the | ||
98 | /// curve. | ||
99 | 6 | virtual curve_derivate_t* compute_derivate_ptr(const std::size_t) const { | |
100 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | return new curve_derivate_t(compute_derivate()); |
101 | } | ||
102 | |||
103 | /// \brief Evaluate the derivative of order N of curve at time t. | ||
104 | /// \param t : time when to evaluate the spline. | ||
105 | /// \param order : order of derivative. | ||
106 | /// \return \f$\frac{d^Nx(t)}{dt^N}\f$, point corresponding on derivative | ||
107 | /// curve of order N at time t. | ||
108 | 452 | virtual point_derivate_t derivate(const time_t t, const std::size_t) const { | |
109 |
4/4✓ Branch 0 taken 223 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 220 times.
|
452 | if (Safe && (t < T_min_ || t > T_max_)) { |
110 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
12 | throw std::invalid_argument( |
111 | "error in constant curve : time t to derivate should be in range " | ||
112 | "[Tmin, Tmax] of the curve"); | ||
113 | } | ||
114 | size_t derivate_size; | ||
115 | if (point_derivate_t::RowsAtCompileTime == Eigen::Dynamic) { | ||
116 | 434 | derivate_size = dim_; | |
117 | } else { | ||
118 | 6 | derivate_size = point_derivate_t::RowsAtCompileTime; | |
119 | } | ||
120 |
1/2✓ Branch 2 taken 220 times.
✗ Branch 3 not taken.
|
440 | return point_derivate_t::Zero(derivate_size); |
121 | } | ||
122 | |||
123 | /** | ||
124 | * @brief isApprox check if other and *this are approximately equals given a | ||
125 | * precision threshold Only two curves of the same class can be approximately | ||
126 | * equals, for comparison between different type of curves see isEquivalent. | ||
127 | * @param other the other curve to check | ||
128 | * @param prec the precision threshold, default | ||
129 | * Eigen::NumTraits<Numeric>::dummy_precision() | ||
130 | * @return true is the two curves are approximately equals | ||
131 | */ | ||
132 | 50 | virtual bool isApprox( | |
133 | const constant_curve_t& other, | ||
134 | const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision()) const { | ||
135 |
2/2✓ Branch 2 taken 21 times.
✓ Branch 3 taken 2 times.
|
96 | return ndcurves::isApprox<num_t>(T_min_, other.min()) && |
136 | 46 | ndcurves::isApprox<num_t>(T_max_, other.max()) && | |
137 |
6/6✓ Branch 0 taken 23 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 3 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 1 times.
|
96 | dim_ == other.dim() && value_.isApprox(other.value_, prec); |
138 | } | ||
139 | |||
140 | ✗ | virtual bool isApprox( | |
141 | const curve_abc_t* other, | ||
142 | const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision()) const { | ||
143 | ✗ | const constant_curve_t* other_cast = | |
144 | ✗ | dynamic_cast<const constant_curve_t*>(other); | |
145 | ✗ | if (other_cast) | |
146 | ✗ | return isApprox(*other_cast, prec); | |
147 | else | ||
148 | ✗ | return false; | |
149 | } | ||
150 | |||
151 | 46 | virtual bool operator==(const constant_curve_t& other) const { | |
152 | 46 | return isApprox(other); | |
153 | } | ||
154 | |||
155 | 14 | virtual bool operator!=(const constant_curve_t& other) const { | |
156 | 14 | return !(*this == other); | |
157 | } | ||
158 | |||
159 | /*Helpers*/ | ||
160 | /// \brief Get dimension of curve. | ||
161 | /// \return dimension of curve. | ||
162 | 86 | std::size_t virtual dim() const { return dim_; } | |
163 | /// \brief Get the minimum time for which the curve is defined | ||
164 | /// \return \f$t_{min}\f$ lower bound of time range. | ||
165 | 126 | num_t virtual min() const { return T_min_; } | |
166 | /// \brief Get the maximum time for which the curve is defined. | ||
167 | /// \return \f$t_{max}\f$ upper bound of time range. | ||
168 | 374 | num_t virtual max() const { return T_max_; } | |
169 | /// \brief Get the degree of the curve. | ||
170 | /// \return \f$degree\f$, the degree of the curve. | ||
171 | 20 | virtual std::size_t degree() const { return 0; } | |
172 | /*Helpers*/ | ||
173 | |||
174 | /*Attributes*/ | ||
175 | Point value_; | ||
176 | time_t T_min_, T_max_; // const | ||
177 | std::size_t dim_; // const | ||
178 | /*Attributes*/ | ||
179 | |||
180 | // Serialization of the class | ||
181 | friend class boost::serialization::access; | ||
182 | |||
183 | template <class Archive> | ||
184 | 48 | void serialize(Archive& ar, const unsigned int version) { | |
185 | if (version) { | ||
186 | // Do something depending on version ? | ||
187 | } | ||
188 |
1/2✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
|
48 | ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(curve_abc_t); |
189 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
48 | ar& boost::serialization::make_nvp("value", value_); |
190 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
48 | ar& boost::serialization::make_nvp("T_min", T_min_); |
191 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
48 | ar& boost::serialization::make_nvp("T_max", T_max_); |
192 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
48 | ar& boost::serialization::make_nvp("dim", dim_); |
193 | 48 | } | |
194 | |||
195 | }; // struct constant_curve | ||
196 | } // namespace ndcurves | ||
197 | |||
198 | DEFINE_CLASS_TEMPLATE_VERSION( | ||
199 | SINGLE_ARG(typename Time, typename Numeric, bool Safe, typename Point, | ||
200 | typename Point_derivate), | ||
201 | SINGLE_ARG( | ||
202 | ndcurves::constant_curve<Time, Numeric, Safe, Point, Point_derivate>)) | ||
203 | |||
204 | #endif // _CLASS_CONSTANTCURVE | ||
205 |