Bodies

class pyb_utils.bodies.BulletBody(position, collision_uid, visual_uid, mass=1, orientation=None, client_id=0, **kwargs)[source]

Bases: object

Generic rigid body in PyBullet.

Parameters:
  • position (iterable) – The (x, y, z) position of the body in the world.

  • collision_uid (int) – ID of the collision shape to use.

  • visual_uid (int) – ID of the visual shape to use.

  • mass (float) – mass of the body; defaults to 1.

  • orientation (iterable) – A quaternion (x, y, z, w) representing the orientation of the body; if not provided, orientation is aligned with the world frame axes.

  • client_id (int) – physics client ID; only required if connected to multiple servers.

apply_wrench(force=None, torque=None, position=None, frame=1)[source]

Apply a wrench (i.e., force and torque) to the body.

Parameters:
  • force – iterable of length 3; if not provided, no force is applied.

  • torque – iterable of length 3; if not provided, no torque is applied.

  • position – iterable of length 3; if not provided, force acts at the origin of the specified frame. Has no effect on the torque.

  • frame (int) – The coordinate frame. Can be either pyb.LINK_FRAME (the default) or pyb.WORLD_FRAME.

classmethod box(position, half_extents, color=(1, 0, 0, 1), client_id=0, **kwargs)[source]

Create a cuboid body.

Parameters:
  • position (iterable) – The (x, y, z) position of the box in the world.

  • half_extents (iterable) – The three half lengths of the box.

  • color (iterable) – The (r, g, b, α) color of the box.

  • client_id (int) – Physics client ID; only required if connected to multiple servers.

classmethod capsule(position, radius, height, color=(1, 0, 0, 1), client_id=0, **kwargs)[source]

Create a capsular body. A capsule is a cylinder with half-spheres on the ends.

The capsule is oriented along its z-axis, which corresponds to the height.

Parameters:
  • position – iterable of length 3; position in the world.

  • radius – radius of the capsule.

  • height – the height of the capsule.

  • color – 4-tuple (r, g, b, α).

  • client_id – physics client ID; only required if connected to multiple servers.

classmethod cylinder(position, radius, height, color=(1, 0, 0, 1), client_id=0, **kwargs)[source]

Create a cylindrical body.

The cylinder is oriented along its z-axis, which corresponds to the height.

Parameters:
  • position – iterable of length 3; position in the world.

  • radius – radius of the cylinder.

  • height – the height of the cylinder.

  • color – 4-tuple (r, g, b, α).

  • client_id – physics client ID; only required if connected to multiple servers.

get_pose()[source]

Get the position and orientation of the body.

Returns a tuple (position, orientation), where the position is of array of length 3 and orientation is an array of length 4 representing a quaternion (x, y, z, w).

get_velocity()[source]

Get the velocity of the body.

Returns a tuple (linear, angular) containing the linear and angular velocity, where each is an array of length 3.

set_pose(position=None, orientation=None)[source]

Set the position and orientation of the body.

Parameters:
  • position – iterable of length 3; if not provided, position is unchanged.

  • orientation – iterable of length 4 representing a quaternion (x, y, z, w); if not provided, orientation is unchanged.

set_velocity(linear=None, angular=None)[source]

Set the velocity of the body.

Parameters:
  • linear – iterable of length 3; if not provided, linear velocity is unchanged.

  • angular – iterable of length 3; if not provided, angular velocity is unchanged.

classmethod sphere(position, radius, color=(1, 0, 0, 1), client_id=0, **kwargs)[source]

Create a spherical body.

Parameters:
  • position – iterable of length 3; position in the world.

  • radius – radius of the sphere.

  • color – 4-tuple (r, g, b, α).

  • client_id – physics client ID; only required if connected to multiple servers.

Camera

Provides a utility Camera class for PyBullet.

class pyb_utils.camera.Camera(view_matrix, near=0.1, far=1000.0, fov=60.0, width=1280, height=720)[source]

Bases: object

A PyBullet camera.

classmethod from_camera_position(target_position, camera_position, near=0.1, far=1000.0, fov=60.0, width=1280, height=720)[source]

Construct a new camera from target and camera positions.

Parameters:
  • target_position – The position of the camera’s target point

  • camera_position – The position of the camera in the world

  • near – Near value

  • far – Far value

  • fov – Field of view

  • width – Width of the image

  • height – Height of the image

classmethod from_distance_rpy(target_position, distance, roll=0, pitch=0, yaw=0, near=0.1, far=1000.0, fov=60.0, width=1280, height=720)[source]

Construct a new camera from target position, distance, and roll, pitch, yaw angles.

Parameters:
  • target_position – The position of the camera’s target point

  • distance – Distance of camera from target.

  • roll – Roll of the camera.

  • pitch – Pitch of the camera.

  • yaw – Yaw of the camera.

  • near – Near value

  • far – Far value

  • fov – Field of view

  • width – Width of the image

  • height – Height of the image

get_frame()[source]

Get a frame from the camera.

Returns:

The RGBA colour data of shape (height, width, 4) depth: Depth buffer of shape (height, width) seg: Segmentation mask of shape (height, width)

Return type:

rgba

get_point_cloud(depth=None)[source]

Convert depth buffer to 3D point cloud in world coordinates.

See <https://stackoverflow.com/a/62247245> for the main source of this code.

Parameters:

depth – Optional, depth buffer provided by Camera.get_frame(). If not provided, self.get_frame() is called to retrieve this data.

Returns: A size (height, width, 3) array of points seen by the

camera.

linearize_depth(depth=None)[source]

Convert depth map to actual distance from camera plane.

See <https://stackoverflow.com/a/6657284>.

Parameters:

depth – Optional, depth buffer provided by Camera.get_frame(). If not provided, self.get_frame() is called to retrieve this data.

Returns: linearized depth buffer: actual depth values from the camera

plane

save_frame(filename, rgba=None)[source]

Save a frame to a file.

Parameters:
  • filename – The name of the image file

  • rgba – Optional, RGBA data provided by Camera.get_frame(). If not provided, self.get_frame() is called to retrieve this data.

set_camera_pose(position, target)[source]

Change position and target of the camera.

class pyb_utils.camera.VideoRecorder(filename, camera, fps, codec='mp4v')[source]

Bases: object

Recorder for a video of a PyBullet simulation.

capture_frame(rgba=None)[source]

Capture a frame and write it to the video.

Parameters:
  • rgba – If provided, write this data to the video (this can be used

  • Otherwise (to avoid multiple renderings with the camera).) –

  • the (get) –

  • camera. (frame data from the) –

Collision

class pyb_utils.collision.CollisionDetector(col_id, bodies, named_collision_pairs)[source]

Bases: object

compute_distances(q=None, max_distance=1.0)[source]

Compute closest distances for a given configuration.

Parameters:
  • q – Iterable representing the desired configuration. This is applied directly to PyBullet body with index bodies[“robot”].

  • max_distance – Bodies farther apart than this distance are not queried by PyBullet, the return value for the distance between such bodies will be max_distance.

Returns: A NumPy array of distances, one per pair of collision objects.

in_collision(q=None, margin=0)[source]

Returns True if configuration q is in collision, False otherwise.

Parameters:
  • q – Iterable representing the desired configuration.

  • margin – Distance at which objects are considered in collision. Default is 0.0.

class pyb_utils.collision.IndexedCollisionObject(body_uid: int, link_uid: int)[source]

Bases: object

Index of a body and one of its links.

body_uid: int
class pyb_utils.collision.NamedCollisionObject(body_name: str, link_name: str | None = None)[source]

Bases: object

Name of a body and one of its links.

The body name must correspond to the key in the bodies dict, but is otherwise arbitrary. The link name should match the URDF. The link name may also be None, in which case the base link (index -1) is used.

body_name: str
pyb_utils.collision.index_collision_pairs(physics_uid, bodies, named_collision_pairs)[source]

Convert a list of named collision pairs to indexed collision pairs.

In other words, convert named bodies and links to the indexes used by PyBullet to facilate computing collisions between the objects.

Parameters:
  • physics_uid – Index of the PyBullet physics server to use.

  • bodies – dict with body name keys and corresponding indices as values

  • named_collision_pairs – a list of 2-tuples of NamedCollisionObject

Returns: a list of 2-tuples of IndexedCollisionObject

Frame

pyb_utils.frame.debug_frame(size, obj_uid, link_index)[source]

Attach a frame to a link for debugging purposes.

pyb_utils.frame.debug_frame_world(size, origin, orientation=(0, 0, 0, 1), line_width=1)[source]

Attach a frame to the world for debugging purposes.

Ghost

class pyb_utils.ghost.GhostObject(visual_uid, position=None, orientation=None, parent_body_uid=None, parent_link_index=-1)[source]

Bases: object

A purely visual PyBullet object.

The GhostObject can be “attached” to another body and positioned relative to that body, or it can be positioned at an absolute location in the world frame.

classmethod sphere(radius, position=None, parent_body_uid=None, parent_link_index=-1, color=(1, 0, 0, 0))[source]

Spherical ghost object.

update(position=None, orientation=None)[source]

Update the pose of the object, optionally updating position and/or orientation.

If the object has a parent, then this should be called every time the simulation rendering is updated. The object’s pose in the world is updated to reflect the parent’s new pose. If position or orientation is supplied, then the pose relative to the parent is updated.

Otherwise, this function can be used to change the object’s absolute pose in the world.

pyb_utils.ghost.GhostSphere(*args, **kwargs)[source]

Math

pyb_utils.math.matrix_to_quaternion(C)[source]

Convert rotation matrix C to quaternion.

pyb_utils.math.quaternion_multiply(q0, q1, normalize=True)[source]

Hamilton product of two quaternions.

pyb_utils.math.quaternion_rotate(q, r)[source]

Rotate point r by rotation represented by quaternion q.

pyb_utils.math.quaternion_to_matrix(q)[source]

Convert quaternion q to rotation matrix.

Named Tuples

Wrappers for PyBullet methods that return large tuples.

This submodule returns the same info in a named tuple, so the fields can be easily identified.

class pyb_utils.named_tuples.ConstraintInfo(parentBodyUniqueId, parentJointIndex, childBodyUniqueId, childLinkIndex, constraintType, jointAxis, jointPivotInParent, jointPivotInChild, jointFrameOrientationParent, jointFrameOrientationChild, maxAppliedForce, gearRatio, gearAuxLink, relativePositionTarget, erp)

Bases: tuple

childBodyUniqueId

Alias for field number 2

childLinkIndex

Alias for field number 3

constraintType

Alias for field number 4

erp

Alias for field number 14

Alias for field number 12

gearRatio

Alias for field number 11

jointAxis

Alias for field number 5

jointFrameOrientationChild

Alias for field number 9

jointFrameOrientationParent

Alias for field number 8

jointPivotInChild

Alias for field number 7

jointPivotInParent

Alias for field number 6

maxAppliedForce

Alias for field number 10

parentBodyUniqueId

Alias for field number 0

parentJointIndex

Alias for field number 1

relativePositionTarget

Alias for field number 13

class pyb_utils.named_tuples.ContactPoint(contactFlag, bodyUniqueIdA, bodyUniqueIdB, linkIndexA, linkIndexB, positionOnA, positionOnB, contactNormalOnB, contactDistance, normalForce, lateralFriction1, lateralFrictionDir1, lateralFriction2, lateralFrictionDir2)

Bases: tuple

bodyUniqueIdA

Alias for field number 1

bodyUniqueIdB

Alias for field number 2

contactDistance

Alias for field number 8

contactFlag

Alias for field number 0

contactNormalOnB

Alias for field number 7

lateralFriction1

Alias for field number 10

lateralFriction2

Alias for field number 12

lateralFrictionDir1

Alias for field number 11

lateralFrictionDir2

Alias for field number 13

linkIndexA

Alias for field number 3

linkIndexB

Alias for field number 4

normalForce

Alias for field number 9

positionOnA

Alias for field number 5

positionOnB

Alias for field number 6

class pyb_utils.named_tuples.DynamicsInfo(mass, lateralFriction, localInertiaDiagonal, localInerialPos, localInertialOrn, restitution, rollingFriction, spinningFriction, contactDamping, contactStiffness, bodyType, collisionMargin)

Bases: tuple

bodyType

Alias for field number 10

collisionMargin

Alias for field number 11

contactDamping

Alias for field number 8

contactStiffness

Alias for field number 9

lateralFriction

Alias for field number 1

localInerialPos

Alias for field number 3

localInertiaDiagonal

Alias for field number 2

localInertialOrn

Alias for field number 4

mass

Alias for field number 0

restitution

Alias for field number 5

rollingFriction

Alias for field number 6

spinningFriction

Alias for field number 7

class pyb_utils.named_tuples.JointInfo(jointIndex, jointName, jointType, qIndex, uIndex, flags, jointDamping, jointFriction, jointLowerLimit, jointUpperLimit, jointMaxForce, jointMaxVelocity, linkName, jointAxis, parentFramePos, parentFrameOrn, parentIndex)

Bases: tuple

flags

Alias for field number 5

jointAxis

Alias for field number 13

jointDamping

Alias for field number 6

jointFriction

Alias for field number 7

jointIndex

Alias for field number 0

jointLowerLimit

Alias for field number 8

jointMaxForce

Alias for field number 10

jointMaxVelocity

Alias for field number 11

jointName

Alias for field number 1

jointType

Alias for field number 2

jointUpperLimit

Alias for field number 9

linkName

Alias for field number 12

parentFrameOrn

Alias for field number 15

parentFramePos

Alias for field number 14

parentIndex

Alias for field number 16

qIndex

Alias for field number 3

uIndex

Alias for field number 4

pyb_utils.named_tuples.getClosestPoints(bodyA, bodyB, distance, linkIndexA=-2, linkIndexB=-2, physicsClientId=0)[source]
pyb_utils.named_tuples.getConstraintInfo(constraintUniqueId, physicsClientId=0)[source]
pyb_utils.named_tuples.getContactPoints(bodyA=-1, bodyB=-1, linkIndexA=-2, linkIndexB=-2, physicsClientId=0)[source]
pyb_utils.named_tuples.getDynamicsInfo(bodyUniqueId, linkIndex, physicsClientId=0)[source]
pyb_utils.named_tuples.getJointInfo(bodyUniqueId, jointIndex, physicsClientId=0, decode=None)[source]

The one difference from the PyBullet API is the addition of the optional decode argument.

If decode is not None, then it is used to decode the strings of bytes returned by the PyBullet API for the jointName and linkName fields.

Robots

class pyb_utils.robots.Robot(uid)[source]

Bases: object

Wrapper for a PyBullet robot.

command_velocity(u)[source]

Send a joint velocity command to the robot.

get_joint_states()[source]

Get position and velocity of the robot’s joints.