8 import pinocchio
as pin
21 from numpy.linalg
import norm
28 Compute the Hessian tensor of all the robot joints.
29 If crossterms, then also compute the Si x Si terms,
30 that are not part of the true Hessian but enters in some computations like VRNEA.
33 H = np.zeros([6, robot.model.nv, robot.model.nv])
34 pin.computeJointJacobians(robot.model, robot.data, q)
36 skiplast = -1
if not crossterms
else None
37 for joint_i
in range(1, robot.model.njoints):
38 for joint_j
in ancestors(joint_i)[:skiplast]:
43 H[:, i, j] = np.asarray(
Mcross(Sj, Si))[:, 0]
61 Compute the derivative (tangent application) of the mass matrix M wrt q,
62 which is a NVxNVxNV tensor.
72 self.
J = robot.data.J.copy()
73 pin.crba(robot.model, robot.data, q)
75 (robot.data.oMi[i] * robot.data.Ycrb[i]).matrix()
76 for i
in range(0, robot.model.njoints)
93 for j
in range(robot.model.njoints - 1, 0, -1):
94 for joint_diff
in range(
95 1, robot.model.njoints
101 i0, i1 =
iv(i)[0],
iv(i)[-1] + 1
102 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
107 for d
in iv(joint_diff):
108 T_iSd = np.array(H[:, d, i0:i1])
109 T_jSd = np.array(H[:, d, j0:j1])
113 assert( norm(T_iSd)<1e-6 or not joint_diff<i )
115 assert( norm(T_jSd)<1e-6 or not joint_diff<j )
117 assert( norm(T_jSd)<1e-6 or not norm(T_iSd)<1e-6 )
118 assert( norm(T_iSd)>1e-6 )
121 Yd = Y[
max(j, joint_diff)]
123 dM[i0:i1, j0:j1, d] = T_iSd.T * Yd * Sj
125 dM[i0:i1, j0:j1, d] += Si.T * Yd * T_jSd
130 dM[j0:j1, i0:i1, d] = dM[i0:i1, j0:j1, d].T
132 dM[j0:j1, i0:i1, d] += np.triu(dM[i0:i1, j0:j1, d], 1).T
142 Compute the C tensor so that nle(q,vq) = vq C vq.
143 Noting Cv = C*vq for an arbitrary robot velocity vq:
144 Since Mdot = (Cv+Cv')/2, then C = dCv/dvq and dM/dq = (Cv+Cv')
146 Q is index by i,j,k i.e. tau_k = v.T*Q[:,:,k]*v
147 At level k, Qk is a lower triangular matrix (same shape as H) where:
148 * rows i s.t. i>k are equals to Sk.T*Ycrb_i*S_ixS_j (j the col index),
149 * rows i s.t. i<=k are equals to Sk.T*Ycrb_k*S_ixS_j (j the col index)
150 To avoid the call to Ycrb_i>k, the first par is set up while computing Q_k
156 self.
YJ = np.zeros([6, robot.model.nv])
166 H =
hessian(robot, q, crossterms=
True)
173 for k
in range(robot.model.njoints - 1, 0, -1):
174 k0, k1 =
iv(k)[0],
iv(k)[-1] + 1
175 Yk = (robot.data.oMi[k] * robot.data.Ycrb[k]).matrix()
178 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
179 YJ[:, j0:j1] = Yk * J[:, j0:j1]
183 i0, i1 =
iv(i)[0],
iv(i)[-1] + 1
186 Q[k0:k1, i0:i1, i0:i1] = -
td(
187 H[:, k0:k1, i0:i1], YJ[:, i0:i1], [0, 0]
192 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
196 Q[k0:k1, i0:i1, j0:j1] =
td(
197 YJ[:, k0:k1], H[:, i0:i1, j0:j1], [0, 0]
200 Q[k0:k1, i0:i1, j0:j1] -=
td(
201 H[:, k0:k1, i0:i1], YJ[:, j0:j1], [0, 0]
204 Q[k0:k1, j0:j1, i0:i1] = -
td(
205 H[:, k0:k1, j0:j1], YJ[:, i0:i1], [0, 0]
211 kk0, kk1 =
iv(kk)[0],
iv(kk)[-1] + 1
215 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
220 Q[kk0:kk1, k0:k1, j0:j1] =
td(
221 YJ[:, kk0:kk1], H[:, k0:k1, j0:j1], [0, 0]
224 Q[kk0:kk1, k0:k1, j0:j1] +=
td(
225 H[:, k0:k1, kk0:kk1].T, YJ[:, j0:j1], [2, 0]
230 Q[kk0:kk1, j0:j1, k0:k1] = -Q[j0:j1, kk0:kk1, k0:k1].transpose(
234 Q[kk0:kk1, j0:j1, k0:k1] =
td(
235 H[:, j0:j1, kk0:kk1].T, YJ[:, k0:k1], [2, 0]
249 _NJ = robot.model.njoints
250 self.
C = np.zeros([NV, NV])
251 self.
YS = np.zeros([6, NV])
252 self.
Sxv = np.zeros([6, NV])
257 NJ = robot.model.njoints
263 pin.computeAllTerms(robot.model, robot.data, q, vq)
266 v = [(oMi[i] * robot.data.v[i]).vector
for i
in range(NJ)]
267 Y = [(oMi[i] * robot.data.Ycrb[i]).matrix()
for i
in range(NJ)]
272 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
273 YS[:, j0:j1] = Y[j] * J[:, j0:j1]
277 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
279 Sxv[:, j0:j1] =
adj(vj) * J[:, j0:j1]
282 for i
in range(NJ - 1, 0, -1):
283 i0, i1 =
iv(i)[0],
iv(i)[-1] + 1
286 vp = v[robot.model.parents[i]]
288 SxvY = Sxv[:, i0:i1].T * Yi
290 j0, j1 =
iv(j)[0],
iv(j)[-1] + 1
294 C[i0:i1, j0:j1] = YS[:, i0:i1].T * Sxv[:, j0:j1]
296 C[i0:i1, j0:j1] -= SxvY * Sj
299 YSxv = Yi * Sxv[:, i0:i1]
302 ii0, ii1 =
iv(ii)[0],
iv(ii)[-1] + 1
305 C[ii0:ii1, i0:i1] = Sii.T * YSxv
307 C[ii0:ii1, i0:i1] += Sii.T * vxYS
309 C[ii0:ii1, i0:i1] += np.array(
310 td(H[:, i0:i1, ii0:ii1], Yv, [0, 0])[:, :, 0]
328 pin.rnea(robot.model, robot.data, q, vq, aq)
329 NJ = robot.model.njoints
333 v = [(oMi[i] * robot.data.v[i]).vector
for i
in range(NJ)]
334 a = [(oMi[i] * robot.data.a_gf[i]).vector
for i
in range(NJ)]
335 f = [(oMi[i] * robot.data.f[i]).vector
for i
in range(NJ)]
336 Y = [(oMi[i] * robot.model.inertias[i]).matrix()
for i
in range(NJ)]
337 Ycrb = [(oMi[i] * robot.data.Ycrb[i]).matrix()
for i
in range(NJ)]
339 Tkf = [np.zeros([6, NV])
for i
in range(NJ)]
340 Yvx = [np.zeros([6, 6])
for i
in range(NJ)]
345 [np.zeros([3, 3]), pin.skew(f[:3])],
346 [pin.skew(f[:3]), pin.skew(f[3:])],
350 R = self.
R = np.zeros([NV, NV])
355 i0, i1 =
iv(i)[0],
iv(i)[-1] + 1
367 Yvx[i] += Y[i] *
adj(v[i])
368 Yvx[i] -= adjf(Y[i] * v[i])
374 k0, k1 =
iv(k)[0],
iv(k)[-1] + 1
384 Tkf += Yvx[i] *
MCross(Sk, v[lk])
386 R[i0:i1, k0:k1] = Si.T * Tkf
389 kk0, kk1 =
iv(kk)[0],
iv(kk)[-1] + 1
391 R[kk0:kk1, k0:k1] = Skk.T *
FCross(Sk, f[i])
392 R[kk0:kk1, k0:k1] += Skk.T * Tkf
408 if __name__ ==
"__main__":
412 "/home/nmansard/src/pinocchio/pinocchio/models/romeo/urdf/romeo.urdf",
414 "/home/nmansard/src/pinocchio/pinocchio/models/romeo/",
416 pin.JointModelFreeFlyer(),
419 q[3:7] /= norm(q[3:7])
429 Htrue = np.zeros([6, robot.model.nv, robot.model.nv])
430 for joint_i
in range(1, robot.model.njoints):
432 for i
in iv(joint_i):
433 for j
in iv(joint_j):
435 vq1[i] = vq1[j] = 1.0
436 pin.computeAllTerms(robot.model, robot.data, q, vq1)
438 robot.data.oMi[joint_i] * robot.data.a[joint_i]
441 print(
"Check hessian = \t\t", norm(H - Htrue))
459 dq = np.zeros(robot.model.nv)
461 for diff
in range(robot.model.nv):
462 dM[:, :, diff] = -pin.crba(robot.model, robot.data, q)
466 qdq = pin.integrate(robot.model, q, dq)
468 dM[:, :, diff] += pin.crba(robot.model, robot.data, qdq)
473 "Check dCRBA = \t\t\t",
474 max([norm(Mp[:, :, diff] - dM[:, :, diff])
for diff
in range(robot.model.nv)]),
485 robot.model.gravity = pin.Motion.Zero()
488 return pin.nle(robot.model, robot.data, q, vq)
497 for i
in range(robot.model.nv):
500 C[:, i, i] =
rnea0(q, vq1).T
502 for i
in range(robot.model.nv):
503 for j
in range(robot.model.nv):
507 vq1[i] = vq1[j] = 1.0
508 C[:, i, j] = (
rnea0(q, vq1).T - C[:, i, i] - C[:, j, j]) / 2
510 print(
"Check d/dv rnea = \t\t", norm(
quad(Q, vq) -
rnea0(q, vq)))
511 print(
"Check C = Q+Q.T = \t\t", norm((Q + Q.transpose(0, 2, 1)) / 2 - C))
512 print(
"Check dM = C+C.T /2 \t\t", norm(Mp - (C + C.transpose(1, 0, 2))))
514 "Check dM = Q+Q.T+Q.T+Q.T /2 \t",
517 - (Q + Q.transpose(0, 2, 1) + Q.transpose(1, 0, 2) + Q.transpose(2, 0, 1))
527 print(
"Check coriolis \t\t\t", norm(C * vq -
rnea0(q, vq)))
537 Rd = np.zeros([NV, NV])
539 r0 = pin.rnea(robot.model, robot.data, q, vq, aq).
copy()
543 qdq = pin.integrate(robot.model, q, dq)
544 Rd[:, i] = (pin.rnea(robot.model, robot.data, qdq, vq, aq) - r0) / eps
545 print(
"Check drnea \t\t\t", norm(Rd - R))