Someone familiar with btMultiBody please let me know if this is correct.
Posted: Mon Apr 30, 2018 8:30 pm
Before my questions I have a little reference diagram attached that I'll reference.
The purple frame is the world coordinate system.
The red frame is the center of mass and principle axis orientation.
The black frame is a revolute joint location, the axis is along the z in this image.
The gold frame is the axis I currently have set for the origins of the visual bodies which I have displayed in opengl and a custom engine.
This image is a stand-in for an extremely detailed robot model.
Since I am trying to get as accurate physics as bullet will get me, I want to make sure I am feeding the inertia, and frame relationships in correctly. Here I will step through what I think needs to be done and please correct where things are messed up. I've worked with ODE and several in house dynamics engines over the years and excited to use bullet for this project since featherstone is now used.
Assume that I have inertial frames initially aligned to world coordinates, then I would need to diagonalize to get the principle axis.
i.e.,
inertia.diagonalize(&rotation);
btMultiBody(1, mass link 1, inertia link 1 diagonalized, ...)
btMultiBody->setBasePos(vector to com 1);
Do I need to set the a rotation from world to base com to account for diagonlization?
btMultiBody->setWordlToBaseRot(rotation);
----Okay so assuming that setup the base correctly I now add the next link via a revolute joint. This is where things get really unclear to me. I can't tell which things need to be with respect to which coordinate frames.
rotParentToThis: Is this the rotation which aligns the COM frame of parent with the joint frame? Since in my example the joint frame is aligned with world frame this rotation would be the rotation found in step 1 for diagonalizing the inertia correct?
jointAxis: I am assuming this axis of rotation is in the joints frame?
parentComToThisPivotOffset: The translation from parent COM to joint frame. The comment says in parent frame. Let's assume I have this translation pre-diagonalization, i.e., in the world frame. I'm assuming then I need to rotate this translation by the same transform as the parent frame.
thisPivotToThisComOffset: Vector from joint frame to link 2 COM.
91 void setupRevolute(int linkIndex, // 0 to num_links-1
92 btScalar mass,
93 const btVector3 &inertia,
94 int parentIndex,
95 const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0
96 const btVector3 &jointAxis, // in my frame
97 const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame
98 const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame
99 bool disableParentCollision=false);
Thank you so much for clarifying! I believe this little example is general enough that if cleared up should well explain the basics of btmultibody.
PS: The "documentation" which consists of the multibody demo and urdf importer are a bit murky. The bullet code seems to lack comments almost entirely o_O? Also, the names are often ambiguous so I want to make sure I"m setting this up correctly. I'm not familiar with bullet history but surprising to see such a large library hurting for comments so badly. Too much to do, too little contributors?
The purple frame is the world coordinate system.
The red frame is the center of mass and principle axis orientation.
The black frame is a revolute joint location, the axis is along the z in this image.
The gold frame is the axis I currently have set for the origins of the visual bodies which I have displayed in opengl and a custom engine.
This image is a stand-in for an extremely detailed robot model.
Since I am trying to get as accurate physics as bullet will get me, I want to make sure I am feeding the inertia, and frame relationships in correctly. Here I will step through what I think needs to be done and please correct where things are messed up. I've worked with ODE and several in house dynamics engines over the years and excited to use bullet for this project since featherstone is now used.
Assume that I have inertial frames initially aligned to world coordinates, then I would need to diagonalize to get the principle axis.
i.e.,
inertia.diagonalize(&rotation);
btMultiBody(1, mass link 1, inertia link 1 diagonalized, ...)
btMultiBody->setBasePos(vector to com 1);
Do I need to set the a rotation from world to base com to account for diagonlization?
btMultiBody->setWordlToBaseRot(rotation);
----Okay so assuming that setup the base correctly I now add the next link via a revolute joint. This is where things get really unclear to me. I can't tell which things need to be with respect to which coordinate frames.
rotParentToThis: Is this the rotation which aligns the COM frame of parent with the joint frame? Since in my example the joint frame is aligned with world frame this rotation would be the rotation found in step 1 for diagonalizing the inertia correct?
jointAxis: I am assuming this axis of rotation is in the joints frame?
parentComToThisPivotOffset: The translation from parent COM to joint frame. The comment says in parent frame. Let's assume I have this translation pre-diagonalization, i.e., in the world frame. I'm assuming then I need to rotate this translation by the same transform as the parent frame.
thisPivotToThisComOffset: Vector from joint frame to link 2 COM.
91 void setupRevolute(int linkIndex, // 0 to num_links-1
92 btScalar mass,
93 const btVector3 &inertia,
94 int parentIndex,
95 const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0
96 const btVector3 &jointAxis, // in my frame
97 const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame
98 const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame
99 bool disableParentCollision=false);
Thank you so much for clarifying! I believe this little example is general enough that if cleared up should well explain the basics of btmultibody.
PS: The "documentation" which consists of the multibody demo and urdf importer are a bit murky. The bullet code seems to lack comments almost entirely o_O? Also, the names are often ambiguous so I want to make sure I"m setting this up correctly. I'm not familiar with bullet history but surprising to see such a large library hurting for comments so badly. Too much to do, too little contributors?