| 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 | 6 | } | |
| 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/4✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 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 |
2/4✓ Branch 1 taken 220 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 220 times.
✗ Branch 5 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 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 24 times.
✗ Branch 6 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 |