Does btMultiBody::compTreeLinkVelocities need to be private?

Post Reply
meridian12
Posts: 2
Joined: Tue Jan 17, 2017 2:17 pm

Does btMultiBody::compTreeLinkVelocities need to be private?

Post by meridian12 »

Greetings,

in my current project I'm implementing a constraint-based coupling between deformables and (articulated) rigid bodies [for which we're using bulletphysics' btRigidBodies and btMultiBodies]. Our framework incorporates coupled objects' velocities into the forces it computes, which can easily be obtained in cartesian coordinates for btRigidBodies and btMultiBody bases, but not for btMultiBody links. Velocities of the latter are only publicly obtainable as reduced coordinates from the getJointVel[MultiDof] function(s), even though cartesian velocities can be computed within the compTreeLinkVelocities function - which, however, is private to btMultiBody.

It isn't quite clear to me why this function is a private class member - I am required to basically re-write its functionality in my own class if I need to compute linear and angular velocities of MultiBody links, which wouldn't really be necessary, since the code is already there. Also, from a software engineering perspective, it's probably smarter to have the class itself provide this kind of conversion due to the direct access to the neccessary member variables - apart from the fact that forced re-implementation on the user's side is error-prone and not exactly big on reusability.

So, could someone shed a little light on why this functionality exists, but isn't available to users?
Thanks in advance.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Does btMultiBody::compTreeLinkVelocities need to be priv

Post by Erwin Coumans »

No good reasons, I make it public, see pull request here https://github.com/bulletphysics/bullet3/pull/930

Thanks for the feedback!
Erwin
meridian12
Posts: 2
Joined: Tue Jan 17, 2017 2:17 pm

Re: Does btMultiBody::compTreeLinkVelocities need to be priv

Post by meridian12 »

Thanks a lot for this change. After doing some background reading and double-checking with my code, I do have two more issues with the compTreeLinkVelocities function, though:
  • Currently, compTreeLinkVelocities computes its omegas and vels using getJointVel(i) * m_links.getAxisTop(0) or getJointVel(i) * m_links.getAxisBottom(0), respectively. This may be sufficient for 1-DOF joints, such as revolutes and prismatics, but is not general enough for multiDofs, e.g. sphericals.
    If I'm not mistaken, this generalisation should look something like

    Code: Select all

    btMultibodyLink li = m_links[i];
    btVector3 qVec;
    for (int j = 0; j < 3; ++j)
    {
    // q-dot vector, according to the amount of link DOFs
    qVec[j] = li.m_dofCount < j + 1 ? 0.0f : mbody.getJointVelMultiDof(i)[j];
    }
    
    btMatrix3x3 jMat = btMatrix3x3(li.getAxisTop(0)[0], li.getAxisTop(1)[0], li.getAxisTop(2)[0],
    				li.getAxisTop(0)[1], li.getAxisTop(1)[1], li.getAxisTop(2)[1],
    				li.getAxisTop(0)[2], li.getAxisTop(1)[2], li.getAxisTop(2)[2]);
    omega[i+1] += jMat * qVec;
    
    (and analogously with jMat constructed using getAxisBottom for vels[i+1]).
  • The SpatialTransform(...) function call had me confused at one point. As far as I can tell, the implementation here is mostly based on Brian Mirtich's PhD thesis (chapter 4[.5]), however, there are slightly contradictory formulations present, as in Equation (4.2) a link's velocity is stated as based on the previous(/parent) link's angular velocity (omega_i-1 x r), while in the algorithmic examples, this term is for some reasons usually written as omega_i x r, i.e. based on the current link's angular velocity.
    The implementation of SpatialTransform seems to follow the algorithmic examples by implementing bottom_out = -displacement.cross(top_out) + rotation_matrix * bottom_in;, yet I'm not quite sure where this change stems from.
    Does anyone here know why this is and could explain that to me?
Post Reply