Skip to content

Commit b9192fa

Browse files
committed
Spline - use the true cumulative form of the spline
1 parent b40b500 commit b9192fa

File tree

1 file changed

+49
-21
lines changed

1 file changed

+49
-21
lines changed

include/pinocchio/multibody/joint/joint-spline.hpp

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -205,27 +205,29 @@ namespace pinocchio
205205
void calc(JointDataDerived & data, const typename Eigen::MatrixBase<ConfigVector> & qs) const
206206
{
207207
data.joint_q = qs.template segment<NQ>(idx_q());
208+
int index_span = findSpan(qs);
209+
int first_index = index_span - degree;
210+
208211
// Basis functions and their derivatives
209212
data.N.setZero();
210213
data.N_der.setZero();
211-
for (int i = 0; i < nbCtrlFrames; i++)
214+
for (int i = first_index; i < index_span + 1; i++)
212215
{
213216
data.N[i] = bsplineBasis(i, degree, data.joint_q[0]);
214217
data.N_der[i] = bsplineBasisDerivative(i, degree, data.joint_q[0]);
215218
}
216-
217219
// Compute joint transform M
218-
data.M = ctrlFrames[0];
220+
data.M = ctrlFrames[first_index];
219221
// joint subspace S
220222
data.S.matrix().setZero();
221-
for (int i = 0; i < nbCtrlFrames - 1; ++i)
223+
for (int i = first_index + 1; i < index_span + 1; i++)
222224
{
223-
const Scalar phi_i = data.N.tail(nbCtrlFrames - (i + 1)).sum();
224-
const Scalar phi_dot_i = data.N_der.tail(nbCtrlFrames - (i + 1)).sum();
225+
const Scalar phi_i = data.N.segment(i, index_span - i + 1).sum();
226+
const Scalar phi_dot_i = data.N_der.segment(i, index_span - i + 1).sum();
225227

226-
data.M = data.M * exp6(relativeMotions[i] * phi_i);
227-
data.S.matrix() = exp6(relativeMotions[i] * phi_i).actInv(data.S)
228-
+ relativeMotions[i].toVector() * phi_dot_i;
228+
data.M = data.M * exp6(relativeMotions[i - 1] * phi_i);
229+
data.S.matrix() = exp6(relativeMotions[i - 1] * phi_i).actInv(data.S)
230+
+ relativeMotions[i - 1].toVector() * phi_dot_i;
229231
}
230232
}
231233

@@ -238,11 +240,14 @@ namespace pinocchio
238240
data.joint_q = qs.template segment<NQ>(idx_q());
239241
data.joint_v = vs.template segment<NV>(idx_v());
240242

243+
int index_span = findSpan(qs);
244+
int first_index = index_span - degree;
245+
241246
// Basis functions and their derivatives
242247
data.N.setZero();
243248
data.N_der.setZero();
244249
data.N_der2.setZero();
245-
for (int i = 0; i < nbCtrlFrames; ++i)
250+
for (int i = first_index; i < index_span + 1; i++)
246251
{
247252
data.N[i] = bsplineBasis(i, degree, data.joint_q[0]);
248253
data.N_der[i] = bsplineBasisDerivative(i, degree, data.joint_q[0]);
@@ -252,20 +257,20 @@ namespace pinocchio
252257
// Compute time derivative of S (for bias acceleration c)
253258
data.S.matrix().setZero();
254259
data.c.setZero();
255-
data.M = ctrlFrames[0];
256-
for (int i = 0; i < nbCtrlFrames - 1; ++i)
260+
data.M = ctrlFrames[first_index];
261+
for (int i = first_index + 1; i < index_span + 1; i++)
257262
{
258-
const Scalar phi_i = data.N.tail(nbCtrlFrames - (i + 1)).sum();
259-
const Scalar phi_dot_i = data.N_der.tail(nbCtrlFrames - (i + 1)).sum();
260-
const Scalar phi_ddot_i = data.N_der2.tail(nbCtrlFrames - (i + 1)).sum();
263+
const Scalar phi_i = data.N.segment(i, index_span - i + 1).sum();
264+
const Scalar phi_dot_i = data.N_der.segment(i, index_span - i + 1).sum();
265+
const Scalar phi_ddot_i = data.N_der2.segment(i, index_span - i + 1).sum();
261266

262-
data.M = data.M * exp6(relativeMotions[i] * phi_i);
267+
data.M = data.M * exp6(relativeMotions[i - 1] * phi_i);
263268
data.c =
264-
relativeMotions[i] * phi_ddot_i
265-
+ exp6(relativeMotions[i] * phi_i)
266-
.actInv(data.c + Motion(data.S.matrix()).cross(relativeMotions[i]) * phi_dot_i);
267-
data.S.matrix() = exp6(relativeMotions[i] * phi_i).actInv(data.S)
268-
+ relativeMotions[i].toVector() * phi_dot_i;
269+
relativeMotions[i - 1] * phi_ddot_i
270+
+ exp6(relativeMotions[i - 1] * phi_i)
271+
.actInv(data.c + Motion(data.S.matrix()).cross(relativeMotions[i - 1]) * phi_dot_i);
272+
data.S.matrix() = exp6(relativeMotions[i - 1] * phi_i).actInv(data.S)
273+
+ relativeMotions[i - 1].toVector() * phi_dot_i;
269274
}
270275

271276
data.c = data.c * data.joint_v[0];
@@ -383,6 +388,29 @@ namespace pinocchio
383388
PINOCCHIO_ALIGNED_STD_VECTOR(Motion) relativeMotions;
384389

385390
private:
391+
template<typename ConfigVector>
392+
int findSpan(const typename Eigen::MatrixBase<ConfigVector> & qs) const
393+
{
394+
// Edge case
395+
if (qs[0] >= Scalar(1.0))
396+
return nbCtrlFrames - 1;
397+
398+
int low = degree;
399+
int high = nbCtrlFrames;
400+
int mid = low;
401+
402+
while (low < high)
403+
{
404+
mid = low + (high - low) / 2;
405+
if (qs[0] < knots[mid])
406+
high = mid;
407+
else
408+
low = mid + 1;
409+
}
410+
411+
return low - 1;
412+
}
413+
386414
Scalar bsplineBasis(int i, int k, const Scalar x) const
387415
{
388416
if (k == 0)

0 commit comments

Comments
 (0)