bulletphysics / bullet3

Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.
http://bulletphysics.org
Other
12.37k stars 2.86k forks source link

Bullet SDF parser does not parse correctly SDF files with <use_parent_model_frame>1</use_parent_model_frame> #1707

Closed traversaro closed 4 years ago

traversaro commented 6 years ago

In SDF files, the joint axis can be expressed in the "joint frame", or in the parent "model frame" if the option use_parent_model_frame is set to true:

Represents the x,y,z components of the axis unit vector. The axis is expressed in the joint frame unless the use_parent_model_frame flag is set to true. The vector should be normalized.

http://sdformat.org/spec?ver=1.6&elem=joint#axis_xyz

See https://bitbucket.org/osrf/gazebo/issues/494 for an historical discussion on the use_parent_model_frame option.

Currently the Bullet SDF parser only supports the case in which the axis is expressed in joint frame: https://github.com/bulletphysics/bullet3/blob/f90bd1f713ba63d6ce6e92350704ee3edc9234c4/examples/Importers/ImportURDFDemo/UrdfParser.cpp#L1283 and it silently loads the wrong axis if a joint contains the <use_parent_model_frame>1</use_parent_model_frame> option.

It would be great if bullet at least printed an error when trying to load this files.

The main reason why this may be problematic is that SDF models generated with the URDF to SDF converter provided by sdformat always contain the use_parent_model_frame option set to 1

traversaro commented 6 years ago

cc @diegoferigo @DanielePucci @anqingd

erwincoumans commented 6 years ago

Indeed, PyBullet doesn't support this legacy support option of Gazebo (latest version of Gazebo uses the same default as PyBullet, using the joint axis in child joint frame). Adding a print is easy, somewhere in UrdfParser.cpp (which is also used for SDF files).

If someone wants to implement the backward compatibility, it is a bit more work. Aside from adding the element in UrdfParser (UrdfJoint), the conversion code would happen in Urdf2Bullet, around this block of code:

  btTransform offsetInA,offsetInB;
            offsetInA = parentLocalInertialFrame.inverse()*parent2joint;
            offsetInB = localInertialFrame.inverse();
            btQuaternion parentRotToThis = offsetInB.getRotation() * offsetInA.inverse().getRotation();
traversaro commented 4 years ago

Since sdformat > 8.4, the URDF --> SDF converter does not export any more SDF files with use_parent_model_frame set to 1, so i think we can close the issue as this was actually just affecting SDF that were generated from URDF . See https://bitbucket.org/osrf/sdformat/issues/189/convert-urdf-files-to-sdf-with .