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])
 
   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()
 
   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
 
  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])],
 
  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/",
 
  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
 
  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)
 
  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])
 
  544         Rd[:, i] = (
pin.rnea(robot.model, robot.data, qdq, vq, aq) - r0) / eps
 
  545     print(
"Check drnea    \t\t\t", norm(Rd - R))