@@ -32,7 +32,7 @@ namespace pinocchio
3232 };
3333 typedef JointDataSplineTpl<Scalar, Options> JointDataDerived;
3434 typedef JointModelSplineTpl<Scalar, Options> JointModelDerived;
35- // typedef JointMotionSubspace1d Constraint_t;
35+
3636 typedef JointMotionSubspaceTpl<1 , Scalar, Options, 1 > Constraint_t;
3737 typedef SE3Tpl<Scalar, Options> Transformation_t;
3838 typedef MotionTpl<Scalar, Options> Motion_t;
@@ -137,14 +137,15 @@ namespace pinocchio
137137
138138 }; // struct JointDataSplinerTpl
139139
140+ PINOCCHIO_JOINT_CAST_TYPE_SPECIALIZATION (JointModelSplineTpl);
141+
140142 // / @brief Spline joint in \f$SE(3)\f$.
141143 // /
142144 // / A spline joint constrains the movement of the child frame to follow the spline defined by the
143145 // / controlFrames and the degree of the spline. Implementation of the joint is based on the paper
144146 // / from Lee et al. Spline Joints for Multibody Dynamics
145147 // / (https://web.cs.ucla.edu/~dt/papers/siggraph08/siggraph08.pdf)
146148 // /
147- PINOCCHIO_JOINT_CAST_TYPE_SPECIALIZATION (JointModelSplineTpl);
148149 template <typename _Scalar, int _Options>
149150 struct JointModelSplineTpl : public JointModelBase <JointModelSplineTpl<_Scalar, _Options>>
150151 {
@@ -181,6 +182,7 @@ namespace pinocchio
181182 buildJoint ();
182183 }
183184
185+ // / TODO To remove in pinocchio 4
184186 JointModelSplineTpl (const std::vector<Transformation_t> & controlFrames, const int degree = 3 )
185187 : degree(degree)
186188 {
@@ -222,10 +224,10 @@ namespace pinocchio
222224 template <typename ConfigVector>
223225 void calc (JointDataDerived & data, const Eigen::MatrixBase<ConfigVector> & qs) const
224226 {
225- // TODO : Fix it with casadi, or not include include when compiled with casadi
226- // assert(
227- // qs[0] >= 0.0 && qs[0] <= 1.0 && "Spline joint configuration (q) must be between 0
228- // and 1.");
227+ assert (
228+ check_expression_if_real<Scalar>(qs[ 0 ] >= 0.0 && qs[ 0 ] <= 1.0 )
229+ && " Spline joint configuration (q) must be between 0 and 1. " );
230+
229231 data.joint_q = qs.template segment <NQ>(idx_q ());
230232
231233 SpanIndexes indexes = FindSpan<Scalar, Options>::run (qs, degree, nbCtrlFrames, knots);
@@ -261,9 +263,9 @@ namespace pinocchio
261263 const Eigen::MatrixBase<ConfigVector> & qs,
262264 const Eigen::MatrixBase<TangentVector> & vs) const
263265 {
264- // assert(
265- // qs[0] >= 0.0 && qs[0] <= 1.0 && "Spline joint configuration (q) must be between 0
266- // and 1.");
266+ assert (
267+ check_expression_if_real<Scalar>( qs[0 ] >= 0.0 && qs[0 ] <= 1.0 )
268+ && " Spline joint configuration (q) must be between 0 and 1. " );
267269
268270 data.joint_q = qs.template segment <NQ>(idx_q ());
269271 data.joint_v = vs.template segment <NV>(idx_v ());
@@ -307,8 +309,7 @@ namespace pinocchio
307309
308310 template <typename TangentVector>
309311 void
310- calc (JointDataDerived & data, const Blank not_used, const Eigen::MatrixBase<TangentVector> & vs)
311- const
312+ calc (JointDataDerived & data, const Blank, const Eigen::MatrixBase<TangentVector> & vs) const
312313 {
313314 data.joint_v = vs.template segment <NV>(idx_v ());
314315
@@ -378,11 +379,11 @@ namespace pinocchio
378379 ReturnType res;
379380 res.degree = degree;
380381 res.nbCtrlFrames = nbCtrlFrames;
382+ res.ctrlFrames .reserve (ctrlFrames.size ());
381383 for (size_t k = 0 ; k < ctrlFrames.size (); k++)
382384 res.ctrlFrames .push_back (ctrlFrames[k].template cast <NewScalar>());
383385
384- res.makeKnots ();
385- res.computeRelativeMotions ();
386+ res.buildJoint ();
386387 res.setIndexes (id (), idx_q (), idx_v (), idx_vExtended ());
387388 return res;
388389 }
@@ -410,13 +411,19 @@ namespace pinocchio
410411 relativeMotions.push_back (log6 (ctrlFrames[i].inverse () * ctrlFrames[i + 1 ]));
411412 }
412413
414+ void buildJoint ()
415+ {
416+ makeKnots ();
417+ computeRelativeMotions ();
418+ }
419+
413420 Scalar bsplineBasis (int i, int k, const Scalar x) const
414421 {
415422 using internal::if_then_else;
416423 if (k == 0 )
417424 {
418425 // clang-format off
419- // if(knots[i] <= x && x <= knots[i])
426+ // if(knots[i] <= x && x <= knots[i + 1 ])
420427 // return 1;
421428 // else
422429 // return 0;
@@ -427,12 +434,24 @@ namespace pinocchio
427434 }
428435
429436 // Calculate the left term
437+ // clang-format off
438+ // if(den1 > dummy_precision)
439+ // left = (x - knots[i]) / den1 * bsplineBasis(i, k - 1, x)
440+ // else
441+ // left = 0
442+ // clang-format on
430443 const Scalar den1 = knots[i + k] - knots[i];
431444 const Scalar left = if_then_else (
432445 internal::GT, den1, Eigen::NumTraits<Scalar>::dummy_precision (),
433446 (x - knots[i]) / den1 * bsplineBasis (i, k - 1 , x), Scalar (0 ));
434447
435448 // Calculate the right term
449+ // clang-format off
450+ // if(den2 > dummy_precision)
451+ // right = (knots[i + k + 1] - x) / den2 * bsplineBasis(i + 1, k - 1, x)
452+ // else
453+ // right = 0
454+ // clang-format on
436455 const Scalar den2 = knots[i + k + 1 ] - knots[i + 1 ];
437456 const Scalar right = if_then_else (
438457 internal::GT, den2, Eigen::NumTraits<Scalar>::dummy_precision (),
@@ -451,12 +470,24 @@ namespace pinocchio
451470 const Scalar k_scalar = static_cast <Scalar>(k);
452471
453472 // Calculate the first term of the derivative
473+ // clang-format off
474+ // if(den1 > dummy_precision)
475+ // term1 = (k_scalar / den1) * bsplineBasis(i, k - 1, x)
476+ // else
477+ // term1 = 0
478+ // clang-format on
454479 const Scalar den1 = knots[i + k] - knots[i];
455480 const Scalar term1 = if_then_else (
456481 internal::GT, den1, Eigen::NumTraits<Scalar>::dummy_precision (),
457482 (k_scalar / den1) * bsplineBasis (i, k - 1 , x), Scalar (0 ));
458483
459484 // Calculate the second term of the derivative
485+ // clang-format off
486+ // if(den2 > dummy_precision)
487+ // term2 = (k_scalar / den2) * bsplineBasis(i + 1, k - 1, x)
488+ // else
489+ // term2 = 0
490+ // clang-format on
460491 const Scalar den2 = knots[i + k + 1 ] - knots[i + 1 ];
461492 const Scalar term2 = if_then_else (
462493 internal::GT, den2, Eigen::NumTraits<Scalar>::dummy_precision (),
@@ -477,12 +508,24 @@ namespace pinocchio
477508 const Scalar k_scalar = static_cast <Scalar>(k);
478509
479510 // Calculate the first term
511+ // clang-format off
512+ // if(den1 > dummy_precision)
513+ // term1 = (k_scalar / den1) * bsplineBasisDerivative(i, k - 1, x)
514+ // else
515+ // term1 = 0
516+ // clang-format on
480517 const Scalar den1 = knots[i + k] - knots[i];
481518 const Scalar term1 = if_then_else (
482519 internal::GT, den1, Eigen::NumTraits<Scalar>::dummy_precision (),
483520 (k_scalar / den1) * bsplineBasisDerivative (i, k - 1 , x), Scalar (0 ));
484521
485522 // Calculate the second term
523+ // clang-format off
524+ // if(den2 > dummy_precision)
525+ // term2 = (k_scalar / den2) * bsplineBasisDerivative(i + 1, k - 1, x)
526+ // else
527+ // term2 = 0
528+ // clang-format on
486529 const Scalar den2 = knots[i + k + 1 ] - knots[i + 1 ];
487530 const Scalar term2 = if_then_else (
488531 internal::GT, den2, Eigen::NumTraits<Scalar>::dummy_precision (),
@@ -497,13 +540,6 @@ namespace pinocchio
497540 Vector knots;
498541 PINOCCHIO_ALIGNED_STD_VECTOR (Transformation_t) ctrlFrames;
499542 PINOCCHIO_ALIGNED_STD_VECTOR (Motion_t) relativeMotions;
500-
501- private:
502- void buildJoint ()
503- {
504- makeKnots ();
505- computeRelativeMotions ();
506- }
507543 }; // struct JointModelSplineTpl
508544
509545} // namespace pinocchio
0 commit comments