PyBullet¤
PyBullet wraps the Bullet physics engine. It runs in-process -no Docker, no server- and gives you forward kinematics, inverse kinematics (numerical), collision checking, and Cartesian motion planning.
Free-space plan_motion not yet implemented
PyBulletPlanner does not currently implement free-space
plan_motion. Cartesian motion via plan_cartesian_motion works.
For free-space planning, use one of the ROS backends.
When to use¤
- You want fast IK + collision checking without starting up ROS.
- You want to simulate multiple robots or kinematic tools in one scene.
- You are running headless (CI, batch planning) or from VS Code.
- You want a PyBullet GUI to visualize the planning scene.
PyBullet is difficult to install inside Rhino 8+.
Trade-offs¤
| What you get | What you give up |
|---|---|
| Numerical IK + collision checking + motion planning | Numerical IK is slower than analytical IK |
| Runs anywhere Python runs (no Docker) | PyBullet has no pre-built wheels for newest Python versions |
| Optional GUI showing the planning scene | Not usable from inside Rhino |
Setup¤
PyBullet is an optional dependency of compas_fab. It is not installed by
default because upstream does not ship wheels for the newest Python versions.
On macOS, PyBullet sometimes needs an extra build flag:
PyBulletClient supports three connection types:
direct— headless, no GUI (default)gui— opens a PyBullet OpenGL windowshared_memory— connect to an external PyBullet server
First example¤
Inverse + forward kinematics on a UR5 with a GUI:
from compas.geometry import Frame
from compas_fab.backends import PyBulletClient
from compas_fab.backends import PyBulletPlanner
from compas_fab.robots import FrameTarget
from compas_fab.robots import RigidBodyLibrary
from compas_fab.robots import RobotCellLibrary
from compas_fab.robots import TargetMode
with PyBulletClient() as client:
# Create a robot cell with a UR5 robot
robot_cell, robot_cell_state = RobotCellLibrary.ur5()
# Add a floor
floor = RigidBodyLibrary.floor()
robot_cell.rigid_body_models["floor"] = floor
robot_cell_state = robot_cell.default_cell_state()
planner = PyBulletPlanner(client)
planner.set_robot_cell(robot_cell)
# The FrameTarget represents the robot's planner coordinate frame (PCF)
# For the UR5 robot, the PCF is equal to the frame of the 'tool0' link
frame_WCF = Frame([0.3, 0.1, 0.5], [1, 0, 0], [0, 1, 0])
target = FrameTarget(frame_WCF, TargetMode.ROBOT)
config = planner.inverse_kinematics(target, robot_cell_state)
print("Inverse kinematics result: ", config)
input("Observe the IK result in PyBullet's GUI, Press Enter to continue...")
# To verify the IK result, we can compute the FK with the obtained joint positions
robot_cell_state.robot_configuration.merge(config)
frame_WCF = planner.forward_kinematics(robot_cell_state, TargetMode.ROBOT)
print("Forward kinematics result (main group): \n ", frame_WCF)
# The result is the same as the 'tool0' link's frame
frame_WCF = planner.forward_kinematics_to_link(robot_cell_state, "tool0")
print("Forward kinematics result: (tool0 link): \n ", frame_WCF)
# However, note that the 'flange' link's frame has a different orientation
frame_WCF = planner.forward_kinematics_to_link(robot_cell_state, "flange")
print("Forward kinematics result: (flange link): \n ", frame_WCF)
More examples¤
Setup:
01_set_robot_cell.py— building a cell with floor + obstacles01_set_robot_cell_state.py— populating cell state02_check_collision.py— collision checking against rigid bodies
Kinematics:
03_fk.py,03_fk_target_mode.py,03_fk_to_link.py— forward kinematics variants03_iter_ik.py— iterating over IK solutions04_ik_point_axis_target.py— IK with a free rotation axis (drilling, milling)04_ik_semi_constrained.py,04_ik_tool_target_mode.py— constrained / tool-frame variants04_ik_errors.py,04_ik_multiple_solutions.py— error handling and multi-solution patterns
Motion planning:
06_cartesian_motion_frame_waypoints.py— Cartesian path withFrameWaypoints06_cartesian_motion_point_axis_waypoints.py— Cartesian path withPointAxisWaypoints08_motion_plan_pick_and_place.py— assembling several trajectories + state changes into a serializableActionChain(see Concepts)
API reference¤
- compas_fab.backends.PyBulletClient
- compas_fab.backends.PyBulletPlanner
- compas_fab.backends.pybullet.backend_features — the underlying feature implementations