dartsim / dart

DART: Dynamic Animation and Robotics Toolkit
http://dartsim.github.io/
BSD 2-Clause "Simplified" License
877 stars 285 forks source link

Free joint representation and Jacobian #1824

Closed Nickick-ICRS closed 1 week ago

Nickick-ICRS commented 1 week ago

Hi,

Sorry this isn't so much an issue as a general question about implementation details and mathematical background. I am not aware of a better place to ask this question however (wouldn't it be great if there was a DART discord server haha), so I am asking it here.

I've been looking into the implementation details for various joints, as I'm working very closely with Featherstone's articulated rigid body algorithms in my research. I'm currently able to get very close to, but not quite matching DART's results with my own custom, linearised version of the algorithm when simulating my robot, but the errors (compared to DART's implementation) increase significantly as the transform from the origin to the base of my robot increases (particularly rotations), which is represented as a 6-dof free joint.

Obviously there are other ways of representing this, e.g. a pure SE3 matrix logarithm, but DART's implementation seems to have the free joint generalised position vector as the tangent space to the rotation (using the SO3 matrix logarithmic map and exponential map to convert between them) and the translation with respect to the parent body frame (with no conversion necessary). This corresponds simply to a rotation about the parent frame, followed by a translation, again with respect to the parent frame. Is this correct? DART then uses a fixed joint jacobian matrix equal to the adjoint of the transform of the child from the joint connection point, with the derivative equal to zero.

In Featherstone's book, Rigid Body Dynamics Algorithms, page 81, example 4.5:

A peculiar feature of both the planar joint and the 6-DoF joint in Table 4.1 is that the translational joint variables express the translation in Fs coordinates rather than Fp coordinates. The reason for doing this is to make the motion subspace matrix a simple constant, so that ˚S = 0, cJ = 0, and the simple form of S allows various optimizations to be applied to the dynamics algorithms.

That is, in order for the joint jacobian derivative to be zero, the joint parameterisation of the free joint should include the translation of the parent to the child, but in the coordinates of the child frame rather than the coordinates of the parent frame.

This leads to my question: Have I made a mistake in my understanding of the DART implementation, or the mathematics behind it? Or is the effect of the derivative of the joint jacobian minimal enough in stable simulation cases that a slight error here doesn't matter? Or can the jacobian derivative still be zero (and jacobian fixed) if the translation component is still given in the coordinates of the parent frame? The latter does not seem to be true later on in Featherstone's book, but using the child-frame translations instead makes calculating velocities from them that much harder.

Nickick-ICRS commented 1 week ago

The main relevant files of course being: https://github.com/dartsim/dart/blob/main/dart/dynamics/FreeJoint.hpp https://github.com/dartsim/dart/blob/main/dart/dynamics/FreeJoint.cpp

And functions:

convertToPositions
convertToTransform
updateRelativeJacobian
updateRelativeJacobianTimeDeriv
jslee02 commented 1 week ago

Thank you for your detailed question. I may need time to refresh the current implementation details and mathematical rationale. I'll aim to provide a more informed response by this weekend.