| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef _STRUCT_SE3_CURVE_H | ||
| 2 | #define _STRUCT_SE3_CURVE_H | ||
| 3 | |||
| 4 | #include <Eigen/Dense> | ||
| 5 | #include <boost/math/constants/constants.hpp> | ||
| 6 | |||
| 7 | #include "MathDefs.h" | ||
| 8 | #include "curve_abc.h" | ||
| 9 | #include "polynomial.h" | ||
| 10 | #include "so3_linear.h" | ||
| 11 | |||
| 12 | namespace ndcurves { | ||
| 13 | |||
| 14 | /// \class SE3Curve. | ||
| 15 | /// \brief Composition of a curve of any type of dimension 3 and a curve | ||
| 16 | /// representing an rotation (in current implementation, only SO3Linear can be | ||
| 17 | /// used for the rotation part) The output is a vector of size 7 | ||
| 18 | /// (pos_x,pos_y,pos_z,quat_x,quat_y,quat_z,quat_w) The output of the derivative | ||
| 19 | /// of any order is a vector of size 6 | ||
| 20 | /// (linear_x,linear_y,linear_z,angular_x,angular_y,angular_z) | ||
| 21 | /// | ||
| 22 | /// | ||
| 23 | template <typename Time = double, typename Numeric = Time, bool Safe = false> | ||
| 24 | struct SE3Curve : public curve_abc<Time, Numeric, Safe, | ||
| 25 | Eigen::Transform<Numeric, 3, Eigen::Affine>, | ||
| 26 | Eigen::Matrix<Numeric, 6, 1> > { | ||
| 27 | typedef Numeric Scalar; | ||
| 28 | typedef Eigen::Transform<Numeric, 3, Eigen::Affine> transform_t; | ||
| 29 | typedef transform_t point_t; | ||
| 30 | typedef Eigen::Matrix<Scalar, 6, 1> point_derivate_t; | ||
| 31 | typedef Eigen::Quaternion<Scalar> Quaternion; | ||
| 32 | typedef Time time_t; | ||
| 33 | typedef curve_abc<Time, Numeric, Safe, point_t, point_derivate_t> | ||
| 34 | curve_abc_t; // parent class | ||
| 35 | typedef polynomial<Time, Numeric, Safe, point_derivate_t> curve_derivate_t; | ||
| 36 | typedef curve_abc<Time, Numeric, Safe, pointX_t> | ||
| 37 | curve_X_t; // generic class of curve | ||
| 38 | typedef curve_abc<Time, Numeric, Safe, point3_t, point3_t> | ||
| 39 | curve_translation_t; // templated class used for the translation (return | ||
| 40 | // dimension are fixed) | ||
| 41 | typedef curve_abc<Time, Numeric, Safe, matrix3_t, point3_t> | ||
| 42 | curve_rotation_t; // templated class used for the rotation (return | ||
| 43 | // dimension are fixed) | ||
| 44 | typedef std::shared_ptr<curve_X_t> curve_ptr_t; | ||
| 45 | typedef std::shared_ptr<curve_rotation_t> curve_rotation_ptr_t; | ||
| 46 | typedef std::shared_ptr<curve_translation_t> curve_translation_ptr_t; | ||
| 47 | |||
| 48 | typedef SO3Linear<Time, Numeric, Safe> SO3Linear_t; | ||
| 49 | typedef polynomial<Time, Numeric, Safe, pointX_t> polynomial_t; | ||
| 50 | typedef SE3Curve<Time, Numeric, Safe> SE3Curve_t; | ||
| 51 | |||
| 52 | public: | ||
| 53 | /* Constructors - destructors */ | ||
| 54 | /// \brief Empty constructor. Curve obtained this way can not perform other | ||
| 55 | /// class functions. | ||
| 56 | /// | ||
| 57 | 24 | SE3Curve() | |
| 58 | : curve_abc_t(), | ||
| 59 | 24 | dim_(3), | |
| 60 | 24 | translation_curve_(), | |
| 61 | 24 | rotation_curve_(), | |
| 62 | 24 | T_min_(0), | |
| 63 | 24 | T_max_(0) {} | |
| 64 | |||
| 65 | /// \brief Destructor | ||
| 66 | 198 | virtual ~SE3Curve() { | |
| 67 | // should we delete translation_curve and rotation_curve here ? | ||
| 68 | // better switch to shared ptr | ||
| 69 | 198 | } | |
| 70 | |||
| 71 | /* Constructor without curve object for the translation : */ | ||
| 72 | /// \brief Constructor from init/end transform use polynomial of degree 1 for | ||
| 73 | /// position and SO3Linear for rotation | ||
| 74 | 11 | SE3Curve(const transform_t& init_transform, const transform_t& end_transform, | |
| 75 | const time_t& t_min, const time_t& t_max) | ||
| 76 | : curve_abc_t(), | ||
| 77 | 11 | dim_(6), | |
| 78 |
4/6✓ Branch 1 taken 10 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
12 | translation_curve_(new polynomial3_t( |
| 79 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
|
12 | point3_t(init_transform.translation()), |
| 80 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
|
12 | point3_t(end_transform.translation()), t_min, t_max)), |
| 81 |
5/12✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 10 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 10 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
10 | rotation_curve_(new SO3Linear_t( |
| 82 | init_transform.rotation(), end_transform.rotation(), t_min, t_max)), | ||
| 83 | 10 | T_min_(t_min), | |
| 84 |
1/2✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
11 | T_max_(t_max) { |
| 85 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | safe_check(); |
| 86 | 11 | } | |
| 87 | |||
| 88 | /// \brief Constructor from init/end pose, with quaternion. use polynomial of | ||
| 89 | /// degree 1 for position and SO3Linear for rotation | ||
| 90 | 2 | SE3Curve(const point3_t& init_pos, const point3_t& end_pos, | |
| 91 | const Quaternion& init_rot, const Quaternion& end_rot, | ||
| 92 | const time_t& t_min, const time_t& t_max) | ||
| 93 | : curve_abc_t(), | ||
| 94 | 2 | dim_(6), | |
| 95 |
2/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | translation_curve_(new polynomial3_t(init_pos, end_pos, t_min, t_max)), |
| 96 |
3/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 9 not taken.
✗ Branch 10 not taken.
|
2 | rotation_curve_(new SO3Linear_t(init_rot, end_rot, t_min, t_max)), |
| 97 | 2 | T_min_(t_min), | |
| 98 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | T_max_(t_max) { |
| 99 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | safe_check(); |
| 100 | 2 | } | |
| 101 | |||
| 102 | /// \brief Constructor from init/end pose, with rotation matrix. use | ||
| 103 | /// polynomial of degree 1 for position and SO3Linear for rotation | ||
| 104 | 1 | SE3Curve(const point3_t& init_pos, const point3_t& end_pos, | |
| 105 | const matrix3_t& init_rot, const matrix3_t& end_rot, | ||
| 106 | const time_t& t_min, const time_t& t_max) | ||
| 107 | : curve_abc_t(), | ||
| 108 | 1 | dim_(6), | |
| 109 |
2/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1 | translation_curve_(new polynomial3_t(init_pos, end_pos, t_min, t_max)), |
| 110 |
3/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
1 | rotation_curve_(new SO3Linear_t(init_rot, end_rot, t_min, t_max)), |
| 111 | 1 | T_min_(t_min), | |
| 112 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | T_max_(t_max) { |
| 113 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | safe_check(); |
| 114 | 1 | } | |
| 115 | |||
| 116 | /* Constructor with curve object for the translation : */ | ||
| 117 | /// \brief Constructor from curve for the translation and init/end rotation, | ||
| 118 | /// with quaternion. Use SO3Linear for rotation with the same time bounds as | ||
| 119 | /// the | ||
| 120 | 1 | SE3Curve(curve_translation_ptr_t translation_curve, | |
| 121 | const Quaternion& init_rot, const Quaternion& end_rot) | ||
| 122 | : curve_abc_t(), | ||
| 123 | 1 | dim_(6), | |
| 124 | 1 | translation_curve_(translation_curve), | |
| 125 |
3/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
2 | rotation_curve_(new SO3Linear_t(init_rot, end_rot, |
| 126 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | translation_curve->min(), |
| 127 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | translation_curve->max())), |
| 128 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | T_min_(translation_curve->min()), |
| 129 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | T_max_(translation_curve->max()) { |
| 130 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | safe_check(); |
| 131 | 1 | } | |
| 132 | /// \brief Constructor from curve for the translation and init/end rotation, | ||
| 133 | /// with rotation matrix. Use SO3Linear for rotation with the same time bounds | ||
| 134 | /// as the | ||
| 135 | 16 | SE3Curve(curve_translation_ptr_t translation_curve, const matrix3_t& init_rot, | |
| 136 | const matrix3_t& end_rot) | ||
| 137 | : curve_abc_t(), | ||
| 138 | 16 | dim_(6), | |
| 139 | 16 | translation_curve_(translation_curve), | |
| 140 |
3/8✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
32 | rotation_curve_(new SO3Linear_t(init_rot, end_rot, |
| 141 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | translation_curve->min(), |
| 142 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | translation_curve->max())), |
| 143 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | T_min_(translation_curve->min()), |
| 144 |
1/2✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
32 | T_max_(translation_curve->max()) { |
| 145 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | safe_check(); |
| 146 | 16 | } | |
| 147 | |||
| 148 | /* Constructor from translation and rotation curves object : */ | ||
| 149 | /// \brief Constructor from from translation and rotation curves object | ||
| 150 | 6 | SE3Curve(curve_translation_ptr_t translation_curve, | |
| 151 | curve_rotation_ptr_t rotation_curve) | ||
| 152 | : curve_abc_t(), | ||
| 153 | 6 | dim_(6), | |
| 154 | 6 | translation_curve_(translation_curve), | |
| 155 | 6 | rotation_curve_(rotation_curve), | |
| 156 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
6 | T_min_(translation_curve->min()), |
| 157 |
1/2✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
12 | T_max_(translation_curve->max()) { |
| 158 |
2/4✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
|
6 | if (translation_curve->dim() != 3) { |
| 159 | ✗ | throw std::invalid_argument( | |
| 160 | "The translation curve should be of dimension 3."); | ||
| 161 | } | ||
| 162 |
3/4✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 4 times.
|
6 | if (rotation_curve->min() != T_min_) { |
| 163 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | throw std::invalid_argument( |
| 164 | "Min bounds of translation and rotation curve are not the same."); | ||
| 165 | } | ||
| 166 |
3/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | if (rotation_curve->max() != T_max_) { |
| 167 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | throw std::invalid_argument( |
| 168 | "Max bounds of translation and rotation curve are not the same."); | ||
| 169 | } | ||
| 170 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | safe_check(); |
| 171 | 14 | } | |
| 172 | |||
| 173 | /// \brief Evaluation of the SE3Curve at time t | ||
| 174 | /// \param t : time when to evaluate the spline. | ||
| 175 | /// \return \f$x(t)\f$ point corresponding on spline at time t. | ||
| 176 | /// (pos_x,pos_y,pos_z,quat_x,quat_y,quat_z,quat_w) | ||
| 177 | 8668 | virtual point_t operator()(const time_t t) const { | |
| 178 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 8668 times.
|
8668 | if (translation_curve_->dim() != 3) { |
| 179 | ✗ | throw std::invalid_argument( | |
| 180 | "Translation curve should always be of dimension 3"); | ||
| 181 | } | ||
| 182 | 8668 | point_t res = point_t::Identity(); | |
| 183 |
3/4✓ Branch 2 taken 8660 times.
✓ Branch 3 taken 8 times.
✓ Branch 5 taken 8660 times.
✗ Branch 6 not taken.
|
8668 | res.translate(point3_t((*translation_curve_)(t))); |
| 184 |
2/4✓ Branch 2 taken 8660 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8660 times.
✗ Branch 6 not taken.
|
8660 | res.rotate((*rotation_curve_)(t)); |
| 185 | 8660 | return res; | |
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * @brief isApprox check if other and *this are approximately equals. | ||
| 190 | * Only two curves of the same class can be approximately equals, for | ||
| 191 | * comparison between different type of curves see isEquivalent | ||
| 192 | * @param other the other curve to check | ||
| 193 | * @param prec the precision threshold, default | ||
| 194 | * Eigen::NumTraits<Numeric>::dummy_precision() | ||
| 195 | * @return true is the two curves are approximately equals | ||
| 196 | */ | ||
| 197 | 18 | bool isApprox( | |
| 198 | const SE3Curve_t& other, | ||
| 199 | const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision()) const { | ||
| 200 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
36 | return ndcurves::isApprox<Numeric>(T_min_, other.min()) && |
| 201 |
2/2✓ Branch 2 taken 12 times.
✓ Branch 3 taken 6 times.
|
36 | ndcurves::isApprox<Numeric>(T_max_, other.max()) && |
| 202 | 18 | (translation_curve_ == other.translation_curve_ || | |
| 203 |
2/2✓ Branch 3 taken 7 times.
✓ Branch 4 taken 5 times.
|
12 | translation_curve_->isApprox(other.translation_curve_.get(), |
| 204 |
3/4✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 5 times.
|
44 | prec)) && |
| 205 | 13 | (rotation_curve_ == other.rotation_curve_ || | |
| 206 |
2/2✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
|
26 | rotation_curve_->isApprox(other.rotation_curve_.get(), prec)); |
| 207 | } | ||
| 208 | |||
| 209 | 7 | virtual bool isApprox( | |
| 210 | const curve_abc_t* other, | ||
| 211 | const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision()) const { | ||
| 212 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | const SE3Curve_t* other_cast = dynamic_cast<const SE3Curve_t*>(other); |
| 213 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (other_cast) |
| 214 | 7 | return isApprox(*other_cast, prec); | |
| 215 | else | ||
| 216 | ✗ | return false; | |
| 217 | } | ||
| 218 | |||
| 219 | 10 | virtual bool operator==(const SE3Curve_t& other) const { | |
| 220 | 10 | return isApprox(other); | |
| 221 | } | ||
| 222 | |||
| 223 | 4 | virtual bool operator!=(const SE3Curve_t& other) const { | |
| 224 | 4 | return !(*this == other); | |
| 225 | } | ||
| 226 | |||
| 227 | /// \brief Evaluation of the derivative of order N of spline at time t. | ||
| 228 | /// \param t : the time when to evaluate the spline. | ||
| 229 | /// \param order : order of derivative. | ||
| 230 | /// \return \f$\frac{d^Nx(t)}{dt^N}\f$ point corresponding on derivative | ||
| 231 | /// spline at time t. | ||
| 232 | 849 | virtual point_derivate_t derivate(const time_t t, | |
| 233 | const std::size_t order) const { | ||
| 234 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 849 times.
|
849 | if (translation_curve_->dim() != 3) { |
| 235 | ✗ | throw std::invalid_argument( | |
| 236 | "Translation curve should always be of dimension 3"); | ||
| 237 | } | ||
| 238 |
2/4✓ Branch 1 taken 849 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 849 times.
✗ Branch 5 not taken.
|
849 | point_derivate_t res = point_derivate_t::Zero(); |
| 239 |
4/6✓ Branch 2 taken 845 times.
✓ Branch 3 taken 4 times.
✓ Branch 5 taken 845 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 845 times.
✗ Branch 9 not taken.
|
849 | res.segment(0, 3) = point3_t(translation_curve_->derivate(t, order)); |
| 240 |
4/6✓ Branch 2 taken 842 times.
✓ Branch 3 taken 3 times.
✓ Branch 5 taken 842 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 842 times.
✗ Branch 9 not taken.
|
845 | res.segment(3, 3) = rotation_curve_->derivate(t, order); |
| 241 | 842 | return res; | |
| 242 | } | ||
| 243 | |||
| 244 | ✗ | curve_derivate_t compute_derivate(const std::size_t /*order*/) const { | |
| 245 | ✗ | throw std::logic_error("Compute derivate for SE3 is not implemented yet."); | |
| 246 | } | ||
| 247 | |||
| 248 | /// \brief Compute the derived curve at order N. | ||
| 249 | /// \param order : order of derivative. | ||
| 250 | /// \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the | ||
| 251 | /// curve. | ||
| 252 | ✗ | curve_derivate_t* compute_derivate_ptr(const std::size_t order) const { | |
| 253 | ✗ | return new curve_derivate_t(compute_derivate(order)); | |
| 254 | } | ||
| 255 | |||
| 256 | /*Helpers*/ | ||
| 257 | /// \brief Get dimension of curve. | ||
| 258 | /// \return dimension of curve. | ||
| 259 | 22 | std::size_t virtual dim() const { return dim_; }; | |
| 260 | /// \brief Get the minimum time for which the curve is defined | ||
| 261 | /// \return \f$t_{min}\f$ lower bound of time range. | ||
| 262 | 96 | time_t min() const { return T_min_; } | |
| 263 | /// \brief Get the maximum time for which the curve is defined. | ||
| 264 | /// \return \f$t_{max}\f$ upper bound of time range. | ||
| 265 | 146 | time_t max() const { return T_max_; } | |
| 266 | /// \brief Get the degree of the curve. | ||
| 267 | /// \return \f$degree\f$, the degree of the curve. | ||
| 268 | ✗ | virtual std::size_t degree() const { return translation_curve_->degree(); } | |
| 269 | /// \brief const accessor to the translation curve | ||
| 270 | 4 | const curve_translation_ptr_t translation_curve() const { | |
| 271 | 4 | return translation_curve_; | |
| 272 | } | ||
| 273 | /// \brief const accessor to the rotation curve | ||
| 274 | 4 | const curve_rotation_ptr_t rotation_curve() const { return rotation_curve_; } | |
| 275 | /*Helpers*/ | ||
| 276 | |||
| 277 | /*Attributes*/ | ||
| 278 | std::size_t dim_; // dim doesn't mean anything in this class ... | ||
| 279 | curve_translation_ptr_t translation_curve_; | ||
| 280 | curve_rotation_ptr_t rotation_curve_; | ||
| 281 | time_t T_min_, T_max_; | ||
| 282 | /*Attributes*/ | ||
| 283 | |||
| 284 | // Serialization of the class | ||
| 285 | friend class boost::serialization::access; | ||
| 286 | |||
| 287 | template <class Archive> | ||
| 288 | 88 | void serialize(Archive& ar, const unsigned int version) { | |
| 289 | if (version) { | ||
| 290 | // Do something depending on version ? | ||
| 291 | } | ||
| 292 |
2/4✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 44 times.
✗ Branch 6 not taken.
|
88 | ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(curve_abc_t); |
| 293 |
1/2✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
|
88 | ar& boost::serialization::make_nvp("dim", dim_); |
| 294 |
1/2✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
|
88 | ar& boost::serialization::make_nvp("translation_curve", translation_curve_); |
| 295 |
1/2✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
|
88 | ar& boost::serialization::make_nvp("rotation_curve", rotation_curve_); |
| 296 |
1/2✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
|
88 | ar& boost::serialization::make_nvp("T_min", T_min_); |
| 297 |
1/2✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
|
88 | ar& boost::serialization::make_nvp("T_max", T_max_); |
| 298 | 88 | } | |
| 299 | |||
| 300 | private: | ||
| 301 | 32 | void safe_check() { | |
| 302 | if (Safe) { | ||
| 303 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (T_min_ > T_max_) { |
| 304 | ✗ | throw std::invalid_argument("Tmin should be inferior to Tmax"); | |
| 305 | } | ||
| 306 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
|
32 | if (translation_curve_->dim() != 3) { |
| 307 | ✗ | throw std::invalid_argument( | |
| 308 | "Translation curve should always be of dimension 3"); | ||
| 309 | } | ||
| 310 | } | ||
| 311 | 32 | } | |
| 312 | |||
| 313 | }; // SE3Curve | ||
| 314 | |||
| 315 | } // namespace ndcurves | ||
| 316 | |||
| 317 | DEFINE_CLASS_TEMPLATE_VERSION( | ||
| 318 | SINGLE_ARG(typename Time, typename Numeric, bool Safe), | ||
| 319 | SINGLE_ARG(ndcurves::SE3Curve<Time, Numeric, Safe>)) | ||
| 320 | |||
| 321 | #endif // SE3_CURVE_H | ||
| 322 |