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.39k stars 2.86k forks source link

Calling `removeBody` on objects loaded with `useMaximalCoordinates=True` produces unexpected behavior #4128

Closed tsoud closed 2 years ago

tsoud commented 2 years ago

system OS: Linux Mint 20.1 Python version: 3.8 pybullet version 3.17

Hello,

I came across this issue while working with my model and I haven't seen it mentioned here or on the PyBullet forums. I don't know if this is the intended behavior or an issue, but to me it seems like an issue.

If I load an object into the simulation (e.g. a simple cube for a manipulator to work with) with the option useMaximalCoordinates=True, then try to remove it later by calling pybullet.removeBody(body_id), the object is not removed and instead a link (often randomly) is removed from the robot. The following example reproduces the issue:

>>> import pybullet as p
>>> import pybullet_data
>>> p.connect(p.GUI)
>>> p.setGravity(0., 0., -9.8)
>>> p.setAdditionalSearchPath(pybullet_data.getDataPath())
>>> p.loadURDF('plane.urdf')
0
>>> robot_id = p.loadURDF('franka_panda/panda.urdf', useFixedBase=True)
>>> cube1_id = p.loadURDF('cube.urdf', (0.5, 0.5, 0.05), globalScaling=0.1)
>>> cube2_maxscale_id = p.loadURDF('cube.urdf', (0.5, -0.5, 0.05), globalScaling=0.1, useMaximalCoordinates=True)

As expected, the environment has 4 bodies (incl. ground):

>>> p.getNumBodies()
4

Checking body info for each cube produces the following results. For the second cube, the body name is replaced with the base name and the base name is an empty string :

>>> p.getBodyInfo(cube1_id)
(b'baseLink', b'cube')
>>> p.getBodyInfo(cube2_maxscale_id)
(b'', b'baseLink')

Removing the first cube (the one loaded without useMaximalCoordinates=True) works as expected:

>>> p.removeBody(cube1_id)
>>> p.getNumBodies()
3

However, trying to remove the second cube gives the following result:

>>> p.removeBody(cube2_maxscale_id)

And the simulator believes the cube was removed:

>>> p.getNumBodies()
2
>>> p.getBodyInfo(cube2_maxscale_id)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
pybullet.error: Couldn't get body info

The problem might be only visual because stepping the simulation shows that robot behavior does not seem to be affected (the arm operates as if the link is still there), but that is still a problem as debugging becomes difficult.

Please advise if there is a workaround or if this was addressed in a newer version of PyBullet. Thanks!

tsoud commented 2 years ago

Update: I tried this in a new environment with the latest version of PyBullet (3.2.1) and the issue persists.

erwincoumans commented 2 years ago

useMaximalCoordinates=True isn't well supported for articulated bodies. It likely won't be anytime soon, too many other projects and priorities. Please use useMaximalCoordinates=False for articulated bodies.