bulletphysics / bullet3

Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.

Home Page:http://bulletphysics.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

createCollisionShape sometimes fails

LucaBonfiglioli opened this issue · comments

Hello, I am currently writing a software that should physically simulate objects falling on various types of containers, and to achieve this we decided to use pybullet binding for bullet3.

I am currently stuck on this situation: 99.99% of the time the code runs smoothly, the simulation result is reasonable and its actually pretty fast. The remaining 0.01% of the time, the program crashes with the following error:

pybullet.error: createCollisionShape failed.

No other information is provided, which makes this very hard for me to debug.

This occurs randomly, and I still haven't figured out a way to replicate this. This is especially annoying because our runs are usually tens of thousands of simulations and can take hours, and I have to manually implement a fallback mechanism in case pybullet decides to stop working.

I cannot provide you an exact copy of my source code, so I have this (non-working) snippet to show you what I am doing. Some parts are omitted, others are simplified and many parameters are simply hardcoded to keep things simple.

import pybullet as pb


class PyBulletPhysicsProcessor:
    def __init__(self) -> None:
        self._pb_client = None

    def process(self):
        if self._pb_client is None:
            self._pb_client = pb.connect(pb.DIRECT)

        my_list_of_objects = [...]  # A list of objects to load into the simulation
        gravity = 9.81
        dt = 1 / 100
        steps = 10000

        # Set the simulation parameters
        pb.setGravity(0, 0, gravity, physicsClientId=self._pb_client)
        pb.setTimeStep(dt, physicsClientId=self._pb_client)

        obj_ids = []

        # Import the objects into the simulation
        for obj in my_list_of_objects:
            # [OMITTED] Retrieve information about the object to load
            fileobj = ...  # A string with an absolute path to a .obj file
            translation = ...  # A 3D XYZ vector
            rotation = ...  # A quaternion
            mass = ...  # A float

            # Import the object into the simulation
            pb_obj = pb.createCollisionShape(
                shapeType=pb.GEOM_MESH,
                fileName=fileobj,
                physicsClientId=self._pb_client,
            )
            pb_obj_id = pb.createMultiBody(
                baseMass=mass,
                baseCollisionShapeIndex=pb_obj,
                basePosition=translation,
                baseOrientation=rotation,
                physicsClientId=self._pb_client,
            )

            # Save the object ID
            obj_ids.append(pb_obj_id)

        # Run the simulation
        for _ in range(steps):
            pb.stepSimulation(physicsClientId=self._pb_client)

        # Get the final object poses
        for obj, obj_id in zip(my_list_of_objects, obj_ids):
            # Get the object pose
            translation, rotation = pb.getBasePositionAndOrientation(
                obj_id, physicsClientId=self._pb_client
            )

            # [OMITTED] Do stuff with the object pose
            ...

        # Clear the scene
        pb.resetSimulation(physicsClientId=self._pb_client)

Some observations that may help:

  • The first simulation seems to have a higher failure chance. I would say, 30% of the times it fails, it does so on the first call to createCollisionShape.
  • The issue also occurs with both single and multi-processing.
  • When using a high number of concurrent workers (>=16) the problem is even more likely to occur.
  • I tested this on four different machines with completely different hardware and software stacks, same exact behavior.
  • After the first call fails:
    • The client is still connected to the server.
    • All subsequent calls to createCollisionShape fail too, but not other pybullet3 methods.
    • The other workers are competely fine.
  • Workers fail randomly even though the method is called with the exact same input file.

Reproduced this bug on:

  • Ubuntu 18.04 / 20.04 / 22.04
  • Python 3.8 / 3.9 / 3.10