Package: pyb-utils
pyb_utils: utilities for PyBulletThis 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 accompanyingblog 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 returnnamedtuples, for easy
field access.Basic quaternion functions.Install and runThis package supportsPython 3.8–3.11. It has been tested on Ubuntu 16.04,
18.04, and 20.04.From pippip install pyb_utilsFrom sourceClone the repository:gitclonehttps://github.com/adamheins/pyb_utilscdpyb_utilsInstall usingpoetry:poetryinstall
poetryrunpythonexamples/collision_detection_example.py# for exampleOr using pip:python-mpipinstall.DocumentationThe project's documentation is availablehere.Usage and examplesThis package provides a few basic quality-of-life utilities. 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 (usingscipyunder the hood):>>>importpyb_utils>>>q=pyb_utils.quatz(np.pi/2)# 90 deg rotation about z-axis>>>qarray([0.,0.,0.70710678,0.70710678])>>>pyb_utils.quaternion_to_matrix(q)# convert to rotation matrixarray([[-0.,-1.,0.],[1.,-0.,0.],[0.,0.,1.]])>>>pyb_utils.quaternion_multiply(q,q)# rotate two quaternions togetherarray([0,0,1,0])# 180 deg rotate about z>>>pyb_utils.quaternion_rotate(q,[1,0,0])# rotate a pointarray([0,1,0])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:>>>importpybulletaspyb>>>importpyb_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])Third, we wrap some PyBullet functions to returnnamedtuples, 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.mass1.0>>>info.localInertiaDiagonal(0.16666666666666666,0.16666666666666666,0.16666666666666666),The functions we've wrapped in this way aregetClosestPoints,getConstraintInfo,getContactPoints,getDynamicsInfo,getJointInfo,getJointState(s), andgetLinkState(s). There are two differences from the
vanilla PyBullet API. The first is that in pyb_utilsgetJointInfoalso
accepts an optional argumentdecode, which will convert the byte strings
returned by PyBullet to the specified encoding. For example,decode="utf8".
The second difference is that in pyb_utilsgetLinkState(s)will always returnLinkStatetuples with 8 fields, even ifcomputeLinkVelocity=False. WhencomputeLinkVelocity=False, thenworldLinkLinearVelocityandworldLinkAngularVelocityare both set toNone.And there's more! You can find example scripts of all of this package's
utilities in theexamples/directory:rigid bodiescameracollision detectionghost objectsnamed tuplesvideoVideo OutputWriting a video with theVideoRecorderdefaults to using themp4vcodec,
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 thecv2Python module); using an alternative codec may require a
different version of OpenCV.Known issuesFeel 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 namelocalInerialPosin theDynamicsInfonamed tuple is spelled
incorrectly. This will be fixed in a future major version.The deprecatedGhostSphereclass will be removed in a future major version.
UseGhostObject.sphereinstead.DevelopmentRuntoxto run the tests.Sphinx is used to build the documentation. With Sphinx installed, runmake htmlin thedocsdirectory.LicenseMIT