stack-of-tasks / pinocchio

A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
http://stack-of-tasks.github.io/pinocchio/
BSD 2-Clause "Simplified" License
1.78k stars 375 forks source link

Inconsistencies between crba() and rena() #2027

Closed Mr-Red331 closed 1 year ago

Mr-Red331 commented 1 year ago

Hi, This is a question about the inconsistencies between crba() and rena(). I used two ways (rnea and crba) to calculate tau, but the result was inconsistent:

  1. tau = rnea(model, data, q, v, a, extf)
  2. tau = Ma + Cv + G - JT*extf

Here is the specific process:

  1. define a set a const random input data: q, v, a, extf;
  2. calculate matrix M with crba(model, data, q);
  3. calculate matrix C with computeCoriolisMatrix(model, data, q, v,);
  4. calculate matrix G with computeGeneralizedGravity(model, data, q);
  5. calculate matrix J with computeJointJacobian(model, data, q, joint, J) and getJointJacobian(model, data, joint, LOCAL, J);
  6. calculate tau_crba = M*a + C*v + G - JT*extf;
  7. calculate tau_rnea = rnea(model, data, q, v, a, extf);

But, the final result tau_crba != tau_rnea.

At the same time, there is an interesting phenomenon: I let a.setZero() and the rest q, v, extf remains const random. After going through the above steps, I could get the result tau_crba = tau_rnea.

So, is there any wrong in calculating M or define a?

jcarpent commented 1 year ago

In C++, only the upper part of the mass matrix is filled, for performance issues. You can use the Eigen API to consider the full matrix (M.selfadjointView<Eigen::Upper>())

Mr-Red331 commented 1 year ago

Thanks! This method worked and my problem was solved.

And futhermore, I would be very grateful if you could tell me why this method could solve this problem.

jcarpent commented 1 year ago

Just display the mass matrix, and you will see that the lower part is full of 0s.

Mr-Red331 commented 1 year ago

That means, in C++, the matrix M calculated with crba() is unfilled and incorrect, and only the filled Matrix M is the correct for calculate dynamics?

fabinsch commented 1 year ago

This behavior is expected and described here in the official pinocchio documentation.

Mr-Red331 commented 1 year ago

Thanks very much, that is very helpful to me!