Skip to main content

pyb_utils: utilities for PyBullet

This is a collection of utilities I've found useful for working with PyBullet, including:

  • Collision detection: conveniently set up shortest distance computations and collision checking between arbitrary objects in arbitrary configurations with PyBullet. See the accompanying blog post.
  • Ghost objects: add purely visual objects to the simulation, optionally attached to another body.
  • Camera: virtual camera from which to get RGBA, depth, segmentation, and point cloud data. Also provides video recording using OpenCV.
  • Convenience class for easily creating rigid bodies.
  • Versions of some PyBullet functions that return named tuples, for easy field access.
  • Basic quaternion functions.
  • Load a URDF directly from a string.

Install and run

This package requires at least Python 3.8. It has been tested on Ubuntu 16.04, 18.04, 20.04, and 24.04.

From pip

pip install pyb_utils

From source

git clone https://github.com/adamheins/pyb_utils
cd pyb_utils
python -m pip install .

Documentation

The project's documentation is available here.

Usage and examples

This package provides a few basic quality-of-life utilities.

Quaternions

First, PyBullet represents rotations using quaternions (in [x, y, z, w] order). We provide a few helper routines to create quaternions about the principal axes, convert quaternions to rotation matrices, and to rotate points (using scipy under the hood):

>>> import pyb_utils
>>> q = pyb_utils.quatz(np.pi / 2) # 90 deg rotation about z-axis
>>> q
array([0., 0., 0.70710678, 0.70710678])

>>> pyb_utils.quaternion_to_matrix(q)  # convert to rotation matrix
array([[-0.,  -1.,  0.],
       [ 1.,  -0.,  0.],
       [ 0.,   0.,  1.]])

>>> pyb_utils.quaternion_multiply(q, q)  # rotate two quaternions together
array([0, 0, 1, 0])                      # 180 deg rotate about z

>>> pyb_utils.quaternion_rotate(q, [1, 0, 0])  # rotate a point
array([0, 1, 0])

Rigid bodies

Second, we provide a simple class to quickly create rigid bodies programmatically, which is useful for adding basic objects to manipulate or act as obstacles:

>>> import pybullet as pyb
>>> import pyb_utils

>>> pyb.connect(pyb.GUI)

# create a 1x1x1 cube at the origin
>>> box = pyb_utils.BulletBody.box(position=[0, 0, 0], half_extents=[0.5, 0.5, 0.5])

# put a ball on top
>>> ball = pyb_utils.BulletBody.sphere(position=[0, 0, 1.5], radius=0.5)

# now put it somewhere else
>>> ball.set_pose(position=[2, 0, 0.5])

Named tuples

Third, we wrap some PyBullet functions to return named tuples, rather than normal tuples. When the tuples have 10+ fields in them, it is rather helpful to have names! The names and arguments of these functions are the same as the underlying PyBullet ones, to make swapping effortless. Continuing our previous example:

# built-in PyBullet method
# the output is not easy to read!
>>> pyb.getDynamicsInfo(box.uid, -1)
(1.0,
 0.5,
 (0.16666666666666666, 0.16666666666666666, 0.16666666666666666),
 (0.0, 0.0, 0.0),
 (0.0, 0.0, 0.0, 1.0),
 0.0,
 0.0,
 0.0,
 -1.0,
 -1.0,
 2,
 0.001)

# switch to the pyb_utils version
# now we can access fields by name
>>> info = pyb_utils.getDynamicsInfo(box.uid, -1)
>>> info.mass
1.0
>>> info.localInertiaDiagonal
(0.16666666666666666, 0.16666666666666666, 0.16666666666666666),

The functions we've wrapped in this way are getClosestPoints, getConstraintInfo, getContactPoints, getDynamicsInfo, getJointInfo, getJointState(s), and getLinkState(s). There are two differences from the vanilla PyBullet API. The first is that in pyb_utils getJointInfo also accepts an optional argument decode, which will convert the byte strings returned by PyBullet to the specified encoding. For example, decode="utf8". The second difference is that in pyb_utils getLinkState(s) will always return LinkState tuples with 8 fields, even if computeLinkVelocity=False. When computeLinkVelocity=False, then worldLinkLinearVelocity and worldLinkAngularVelocity are both set to None.

Load a URDF from a string

PyBullet can only load URDFs from files, using pybullet.loadURDF. We provide the alternative function pyb_utils.load_urdf_from_string to load a URDF directly from a string. The optional keyword arguments are all the same as loadURDF.

More

And there's more! You can find example scripts of all of this package's utilities in the examples/ directory:

URDF Viewer

pyb_utils includes a simple URDF viewer. On the command line, run:

pybview <urdf_file>

which loads the given URDF file in PyBullet for visualization and prints information about its links and joints.

To install pybview as a standalone executable on your system, it is recommended to use either uv or pipx:

uv tool install pyb_utils
# or
pipx install pyb_utils

Video Output

Writing a video with the VideoRecorder defaults to using the mp4v codec, which is widely supported but (at least on my computer running Ubuntu 20.04) does not play natively in web browsers. The availability of codecs depends on what is compiled into the version of OpenCV you have installed (i.e., the one backing the cv2 Python module); using an alternative codec may require a different version of OpenCV.

Known issues

Feel free to open issues (or better yet, a pull request!) if you find a problem. Currently known issues:

  • Ghost objects sometimes flicker (spooky, but undesirable). This is probably because they are updated by directly changing the object pose; we cannot have them updated automatically by, e.g., constraints since they are not dynamic objects (and we wouldn't want them to be; then they would influence the simulation).
  • The field name localInerialPos in the DynamicsInfo named tuple is spelled incorrectly. This will be fixed in a future major version.
  • The deprecated GhostSphere class will be removed in a future major version. Use GhostObject.sphere instead.

Development

uv is used for managing dependencies, testing, building, and publishing. Create a virtual environment for the project:

uv venv
uv sync --dev

Run the tests:

uv run pytest

Run the tests for various Python versions:

# for example, test with Python 3.8 (in an isolated environment)
uv run --locked --isolated --python=3.8 pytest

Sphinx is used to build the documentation. With Sphinx installed, run make html in the docs directory.

License

MIT

Metadata

Release files for pyb_utils 2.4.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyb_utils 2.4.2
File Size Uploaded Provenance Actions
pyb_utils-2.4.2.tar.gz 136.4 kB Without provenance Details for pyb_utils-2.4.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyb_utils 2.4.2
File Interpreter ABI Platform Actions
pyb_utils-2.4.2-py3-none-any.whl Python 3 none any Details for pyb_utils-2.4.2-py3-none-any.whl

Total release size: 163.8 kB

Release files / pyb_utils-2.4.2.tar.gz

Download URL pyb_utils-2.4.2.tar.gz
Size 136.4 kB
Tags Source
SHA-256 checksum
How to use checksums
0776371867da65b4d2ee09ba01335ebb29a71b68e5c9bbbd9f3a12786d918c4d
BLAKE2b-256 checksum
How to use checksums
b2603b0d8dbe5d22949905406a17556f0213f5e0af0bc9b47e7445430e8ff8df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pyb_utils-2.4.2-py3-none-any.whl

Download URL pyb_utils-2.4.2-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
98c9651eb9ea4a2c10e187fa76118000732e25baaf4e1538c7edc21ef8cb381e
BLAKE2b-256 checksum
How to use checksums
8f2fd14fbf45fac36f49e609bd54b249f8421c5ac73147c567604ac996c63f3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for pyb_utils 2.4.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page