Pybullet Quickstart Guide
Pybullet Quickstart Guide
Pybullet Quickstart Guide
setPhysicsEngineParameter
19
19
resetSimulation 20
guide Synthetic Camera Rendering 20
Erwin Coumans, 2017
computeViewMatrix 20
Check most up-to-date Google Docs version
online ,comments are welcome online.
computeViewMatrixFromYawPitchRoll
21
computeProjectionMatrix 21
Introduction 2 computeProjectionMatrixFOV 21
Hello pybullet World 2 getCameraImage 22
connect, disconnect 3 getVisualShapeData 23
setGravity 5 resetVisualShapeData 24
loadURDF 5 loadTexture 24
loadBullet, loadSDF, loadMJCF 6
saveWorld 6 Collision Detection Queries 24
getQuaternionFromEuler and getOverlappingObjects 24
getEulerFromQuaternion 7 getContactPoints 25
getMatrixFromQuaternion 7 getClosestPoints 25
stepSimulation 7 rayTest 26
setRealTimeSimulation 8 Inverse Dynamics 26
getBasePositionAndOrientation 8 calculateInverseDynamics 26
resetBasePositionAndOrientation 8
Inverse Kinematics 27
Controlling a robot 10 calculateInverseKinematics 27
Base, Joints, Links 10
getNumJoints, getJointInfo 10 Virtual Reality 28
setmotorcontrolsetJointMotorControl2 11 getVREvents 28
getJointState 13 setVRCameraState 29
resetJointState 13 Debug GUI, Lines, Text, Parameters 29
enableJointForceTorqueSensor 14 addUserDebugLine 29
getLinkState 14 addUserDebugText 30
getBaseVelocity, resetBaseVelocity 15 addUserDebugParameter,
applyExternalForce, readUserDebugParameter 30
applyExternalTorque 16 removeUserDebugItem 31
getNumBodies, getBodyInfo, setDebugObjectColor 31
getBodyUniqueId 16
createConstraint, removeConstraint, Build and install pybullet 31
changeConstraint 17 Using cmake on Linux and Mac OSX 32
getNumConstraints 18 Using premake for Window 32
getConstraintInfo 18 FAQ and Tips 33
Introduction
pybullet is an easy to use Python module for physics simulation, robotics and machine learning.
With pybullet you can load articulated bodies from URDF, SDF and other file formats. pybullet
provides forward dynamics simulation, inverse dynamics computation, forward and inverse
kinematics and collision detection and ray intersection queries.
Aside from physics simulation, there are bindings to rendering, with a CPU renderer
(TinyRenderer) and OpenGL visualization and support for Virtual Reality headsets such as HTC
Vive and Oculus Rift. pybullet has also functionality to perform collision detection queries
(closest points, overlapping pairs, ray intersection test etc) and to add debug rendering (debug
lines and text).
pybullet wraps the new Bullet C-API, which is designed to be independent from the underlying
physics engine and render engine, so we can easily migrate to newer versions of Bullet, or use
a different physics engine or render engine. By default, pybullet uses the Bullet 2.x API on the
CPU. We will expose Bullet 3.x running on GPU using OpenCL as well.
pybullet can be easily used with TensorFlow and frameworks such as OpenAI Gym.
import pybullet as p
physicsClient = p.connect(p.DIRECT)
p.setGravity(0,0,-10)
planeId = p.loadURDF("plane.urdf")
cubeStartPos = [0,0,1]
cubeStartOrientation = p.getQuaternionFromEuler([0,0,0])
boxId = p.loadURDF("r2d2.urdf",cubeStartPos, cubeStartOrientation)
p.stepSimulation()
cubePos, cubeOrn = p.getBasePositionAndOrientation(boxId)
print(cubePos,cubeOrn)
p.disconnect()
connect, disconnect
After importing the pybullet module, the first thing to do is 'connecting' to the physics simulation.
pybullet is designed around a command-status driven API, with a client sending commands and
a physics server returning the status. pybullet has some build-in physics servers: DIRECT and
GUI. DIRECT connection will execute the physics simulation and rendering in the same process
as pybullet.
The GUI connection will create a new graphical user interface (GUI) with 3D OpenGL rendering,
within the same process space as pybullet. On Linux and Windows this GUI runs in a separate
thread, while on OSX it runs in the same thread due to operating system limitations. The
commands and status messages are sent between pybullet client and the GUI physics
simulation server using an ordinary memory buffer.
It is also possible to connect to a physics server in a different process on the same machine or
on a remote machine using SHARED_MEMORY or UDP networking. See the section about
Shared Memory and UDP for details.
Unlike almost all other methods, this method doesn't parse keyword arguments, due to
backward compatibility.
required connection mode integer: DIRECT mode create a new physics engine and directly
DIRECT, communicates with it. GUI will create a physics engine
GUI, with graphical GUI frontend and communicates with it.
SHARED_M SHARED_MEMORY will connect to an existing physics
EMORY, engine process on the same machine, and communicates
UDP with ot over shared memory. UDP will connect to an
existing physics server over UDP networking.
connect returns a physics client id or -1 if not connected. The physics client Id is an optional
argument to most of the other pybullet commands. If you don't provide it, it will assume physics
client id = 0. You can connect to multiple different physics servers, except for GUI.
For example:
pybullet.connect(pybullet.DIRECT)
pybullet.connect(pybullet.SHARED_MEMORY,1234)
pybullet.connect(pybullet.UDP,"192.168.0.1")
pybullet.connect(pybullet.UDP,"localhost", 1234)
You can also connect over shared memory to the App_SharedMemoryPhysics_VR, the Virtual
Reality application with support for head-mounted display and 6-dof tracked controllers such as
HTC Vive and Oculus Rift with Touch controllers. Since the Valve OpenVR SDK only works
properly under Windows, the App_SharedMemoryPhysics_VR can only be build under Windows
using premake.
For UDP networking, there is a App_PhysicsServerUDP that listens to a certain UDP port. It
uses the open source enet library for reliable UDP networking. This allows you to execute the
physics simulation and rendering on a separate machine.
disconnect
You can disconnect from a physics server, using the physics client Id returned by the connect
call (if non-negative). A 'DIRECT' or 'GUI' physics server will shutdown. A separate
(out-of-process) physics server will keep on running. See also 'resetSimulation' to remove all
items.
setGravity
By default, there is no gravitational force enabled. setGravity lets you set the default gravity
force for all objects.
The setGravity input parameters are: (no return value)
optional physicsClientId int if you connect to multiple physics servers, you can pick which one.
loadURDF
The loadURDF will send a command to the physics server to load a physics model from a
Universal Robot Description File (URDF). The URDF file is used by the ROS project (Robot
Operating System) to describe robots and other objects, it was created by the WillowGarage
and the Open Source Robotics Foundation (OSRF). Many robots have public URDF files, you
can find a description and tutorial here: http://wiki.ros.org/urdf/Tutorials
Important note: most joints (slider, revolute, continuous) have motors enabled by default that
prevent free motion. This is similar to a robot joint with a very high-friction harmonic drive. You
should set the joint motor control mode and target settings using pybullet.setJointMotorControl2.
See the setJointMotorControl2 API for more information.
required fileName string a relative or absolute path to the URDF file on the file
system of the physics server.
optional basePosition vec3 create the base of the object at the specified position in
world space coordinates [X,Y,Z]
optional baseOrientation vec4 create the base of the object at the specified orientation
as world space quaternion [X,Y,Z,W]
optional useMaximalCoordinates int Experimental. By default, the joints in the URDF file are
created using the reduced coordinate method: the
joints are simulated using the Featherstone Articulated
Body algorithm (btMultiBody in Bullet 2.x). The
useMaximalCoordinates option will create a 6 degree of
freedom rigid body for each link, and constraints
between those rigid bodies are used to model joints.
optional useFixedBase int force the base of the loaded object to be static
optional physicsClientId int if you connected to multiple servers, you can pick one.
loadURDF returns a body unique id, a non-negative integer value. If the URDF file cannot be
loaded, this integer will be negative and not a valid body unique id.
saveWorld
You can create a snapshot of the current world as a pybullet Python file, stored on the server.
saveWorld can be useful as a basic editing feature, setting up the robot, joint angles, object
positions and environment for example in VR. Later you can just load the pybullet Python file to
re-create the world. Note that not all settings are stored in the world file at the moment.
The input arguments are:
optional clientServerId int if you connected to multiple servers, you can pick one
getQuaternionFromEuler and getEulerFromQuaternion
The pybullet API uses quaternions to represent orientations. Since quaternions are not very
intuitive for people, there are two APIs to convert between quaternions and Euler angles.
The getQuaternionFromEuler input arguments are:
required eulerAngle vec3: list of 3 floats The X,Y,Z Euler angles are in radians, accumulating 3 rotations
around the X, Y and Z axis.
getMatrixFromQuaternion
getMatrixFromQuaternion is a utility API to create a 3x3 matrix from a quaternion. The input is a
quaternion and output a list of 9 floats, representing the matrix.
stepSimulation
stepSimulation will perform all the actions in a single forward dynamics simulation step such as
collision detection, constraint solving and integration.
See also setRealTimeSimulation to automatically let the physics server run forward dynamics
simulation based on its real-time clock.
setRealTimeSimulation
By default, the physics server will not step the simulation, unless you explicitly send a
'stepSimulation' command. This way you can maintain control determinism of the simulation. It
is possible to run the simulation in real-time by letting the physics server automatically step the
simulation according to its real-time-clock (RTC) using the setRealTimeSimulation command. If
you enable the real-time simulation, you don't need to call 'stepSimulation'.
optional physicsClientId int if you connected to multiple servers, you can pick one.
getBasePositionAndOrientation
getBasePositionAndOrientation reports the current position and orientation of the base (or root
link) of the body in Cartesian world coordinates. The orientation is a quaternion in [x,y,z,w]
format.
optional physicsClientId int if you connected to multiple servers, you can pick one.
See also resetBasePositionAndOrientation to reset the position and orientation of the object.
This completes the first pybullet script. Bullet ships with several URDF files in the Bullet/data
folder.
resetBasePositionAndOrientation
You can reset the position and orientation of the base (root) of each object. It is best only to do
this at the start, and not during a running simulation, since the command will override the effect
of all physics simulation.
The input arguments to resetBasePositionAndOrientation are:
required basePosition vec3 reset the base of the object at the specified position in world
space coordinates [X,Y,Z]
required baseOrientation vec4 reset the base of the object at the specified orientation as world
space quaternion [X,Y,Z,W]
optional physicsClientId int if you connected to multiple servers, you can pick one.
A simulated robot as described in a URDF file has a base, and optionally links connected by
joints. Each joint connects one parent link to a child link. At the root of the hierarchy there is a
single root parent that we call base. The base can be either fully fixed, 0 degrees of freedom, or
fully free, with 6 degrees of freedom. Since each link is connected to a parent with a single joint,
the number of joints is equal to the number of links. Regular links have link indices in the range
[0..getNumJoints()] Since the base is not a regular 'link', we use the convention of -1 as its link
index. We use the convention that joint frames are expressed relative to the parents center of
mass inertial frame, which is aligned with the principle axis of inertia.
getNumJoints, getJointInfo
After you load a robot you can query the number of joints using the getNumJoints API. For the
r2d2.urdf this should return 15.
getJointInfo
For each joint we can query some information, such as its name and type.
required bodyUniqueId int the body unique id, as returned by loadURDF etc.
optional physicsClientId int if you connected to multiple servers, you can pick one.
jointName string the name of the joint, as specified in the URDF (or SDF etc) file
jointType int type of the joint, this also implies the number of position and velocity variables.
JOINT_REVOLUTE, JOINT_PRISMATIC, JOINT_SPHERICAL, JOINT_PLANAR,
JOINT_FIXED. See the section on Base, Joint and Links for more details.
qIndex int the first position index in the positional state variables for this body
uIndex int the first velocity index in the velocity state variables for this body
jointDamp float the joint damping value, as specified in the URDF file
ing
jointFrictio float the joint friction value, as specified in the URDF file
n
setJointMotorControl2
Note: setJointMotorControl is obsolete and replaced by setJointMotorControl2 API.
We can control a robot by setting a desired control mode for one or more joint motors. During
the stepSimulation the physics engine will simulate the motors to reach the given target value
that can be reached within the maximum motor forces and other constraints. Each revolute joint
and prismatic joint is motorized by default. There are 3 different motor control modes: position
control, velocity control and torque control.
You can effectively disable the motor by using a force of 0, for example:
maxForce = 0
mode = p.VELOCITY_CONTROL
p.setJointMotorControl2(objUid, linkIndex, controlMode=mode, force=maxForce)
If you want a wheel to maintain a constant velocity, with a max force you can use:
maxForce = 500
p.setJointMotorControl2(bodyUniqueId=objUid,
linkIndex=0,
controlMode=p.VELOCITY_CONTROL,
targetVelocity = targetVel,
force = maxForce)
optional physicsClientId int if you connected to multiple servers, you can pick one.
Note: the actual implementation of the joint motor controller is as a constraint for
POSITION_CONTROL and VELOCITY_CONTROL, and as an external force for
TORQUE_CONTROL:
getJointState
We can query several state variables from the joint using getJointState, such as the joint
position, velocity, joint reaction forces and joint motor torque.
optional physicsClientId int if you connected to multiple servers, you can pick one.
getJointState output
jointReactionForces list of 6 floats There are the joint reaction forces, if a torque sensor is enabled for
this joint. Without torque sensor, it is [0,0,0,0,0,0].
appliedJointMotorTorque float This is the motor torque applied during the last stepSimulation
resetJointState
You can reset the state of the joint. It is best only to do this at the start, while not running the
simulation: resetJointState overrides all physics simulation.
optional physicsClientId int if you connected to multiple servers, you can pick one.
enableJointForceTorqueSensor
You can enable or disable a joint force/torque sensor in each joint. Once enabled, if you perform
a stepSimulation, the 'getJointState' will report the joint reaction forces in the fixed degrees of
freedom: a fixed joint will measure all 6DOF joint forces/torques. A revolute/hinge joint
force/torque sensor will measure 5DOF reaction forces along all axis except the hinge axis. The
applied force by a joint motor is available in the appliedJointMotorTorque of getJointState.
optional enableSensor int 1/True to enable, 0/False to disable the force/torque sensor
optional physicsClientId int if you connected to multiple servers, you can pick one.
getLinkState
You can also query the Cartesian world position and orientation for the center of mass of each
link using getLinkState. It will also report the local inertial frame of the center of mass to the
URDF link frame, to make it easier to compute the graphics/visualization frame.
localInertialFramePosition vec3, list of 3 floats local position offset of inertial frame (center of
mass) to URDF link frame
localInertialFrameOrientation vec4, list of 4 floats local orientation (quaternion [x,y,z,w]) offset of
the inertial frame to the URDF link frame.
examples/pybullet/testrender.py load a URDF file and render an image, get the pixels
(RGB, depth, segmentation mask) and display the
image using MatPlotLib.
getBaseVelocity, resetBaseVelocity
You get access to the linear and angular velocity of the base of a body using getBaseVelocity.
The input parameters are:
required bodyUniqueId int body unique id, as returned from the load* methods.
optional physicsClientId int if you connected to multiple servers, you can pick one.
This returns a list of two vector3 values (3 floats in a list) representing the linear velocity [x,y,z]
and angular velocity [wx,wy,wz] in Cartesian worldspace coordinates.
You can reset the linear and/or angular velocity of the base of a body using resetBaseVelocity.
The input parameters are:
required objectUniqueId int body unique id, as returned from the load* methods.
optional linearVelocity vec3, list of 3 floats linear velocity [x,y,z] in Cartesian world coordinates.
optional angularVelocity vec3, list of 3 floats angular velocity [wx,wy,wz] in Cartesian world coordinates.
optional physicsClientId int if you connected to multiple servers, you can pick one.
applyExternalForce, applyExternalTorque
You can apply a force or torque to a body using applyExternalForce and applyExternalForce.
Note that this method will only work when explicitly stepping the simulation using
stepSimulation, in other words: setRealTimeSimulation(0). After each simulation step, the
external forces are cleared to zero. If you are using 'setRealTimeSimulation(1),
applyExternalForce/Torque will have undefined behavior (either 0, 1 or multiple force/torque
applications).
required forceObj vec3, list of 3 floats force vector to be applied [x,y,z]. See flags for coordinate
system.
required posObj vec3, list of 3 floats position on the link where the force is applied. See flags
for coordinate system.
getBodyInfo will return the base name, as extracted from the URDF, SDF, MJCF or other file.
createConstraint, removeConstraint, changeConstraint
URDF, SDF and MJCF specify articulated bodies as a tree-structures without loops. The
'createConstraint' allows you to connect specific links of bodies to close those loops. See
Bullet/examples/pybullet/quadruped.py how to connect the legs of a quadruped 5-bar closed
loop linkage. In addition, you can create arbitrary constraints between objects, and between an
object and a specific world frame. See Bullet/examples/pybullet/constraint.py for an example.
It can also be used to control the motion of physics objects, driven by animated frames, such as
a VR controller. It is better to use constraints, instead of setting the position or velocity directly
for such purpose, since those constraints are solved together with other dynamics constraints.
required parentLinkIndex int parent link index (or -1 for the base)
required childBodyUniqueId int child body unique id, or -1 for no body (specify a
non-dynamic child frame in world coordinates)
required jointAxis vec3, list of 3 floats joint axis, in child link frame
required parentFramePosition vec3, list of 3 floats position of the joint frame relative to parent center
of mass frame.
required childFramePosition vec3, list of 3 floats position of the joint frame relative to a given child
center of mass frame (or world origin if no child
specified)
optional parentFrameOrientation vec4, list of 4 floats the orientation of the joint frame relative to parent
center of mass coordinate frame
optional childFrameOrientation vec4, list of 4 floats the orientation of the joint frame relative to the
child center of mass coordinate frame (or world
origin frame if no child specified)
optional physicsClientId int if you connected to multiple servers, you can pick
one.
createConstraint will return an integer unique id, that can be used to change or remove the
constraint.
changeConstraint allows you to change parameters of an existing constraint. The input
parameters are:
required userConstraintUniqueId int unique id returned by createConstraint
optional jointChildPivot vec3, list of 3 floats updated child pivot, see 'createConstraint'
removeConstraint will remove a constraint, given by its unique id. Its input parameters are:
getNumConstraints
You can query for the total number of constraints, created using 'createConstraint'. Optional
parameter is the int physicsClientId.
getConstraintInfo
You can query the constraint info give a constraint unique id.
The input parameters are
setTimeStep
You can set the physics engine timestep that is used when calling 'stepSimulation'. It is best to
only call this method at the start of a simulation. Don't change this time step regularly.
setTimeStep can also be achieved using the new setPhysicsEngineParameter API.
required timeStep float Each time you call 'stepSimulation' the timeStep will proceed with
'timeStep'.
optional physicsClientId int if you connected to multiple servers, you can pick one.
setPhysicsEngineParameter
You can set physics engine parameters using the setPhysicsEngineParameter API. The
following input parameters are exposed:
resetSimulation
resetSimulation will remove all objects from the world and reset the world to initial conditions. It
takes one optional parameter: the physics client Id (in case you created multiple physics server
connections).
The synthetic camera is specified by two 4 by 4 matrices: the view matrix and the projection
matrix. Since those are not very intuitive, there are some helper methods to compute the view
and projection matrix from understandable parameters.
computeViewMatrix
The computeViewMatrix input parameters are
required cameraTargetPosition vec3, list of 3 floats position of the target (focus) point, in
Cartesian world coordinates
computeViewMatrixFromYawPitchRoll
The input parameters are
required cameraTargetPosition list of 3 floats target focus point in Cartesian world coordinates
computeProjectionMatrix
The input parameters are
computeProjectionMatrixFOV
This command also will return a 4x4 projection matrix, using different parameters. You can
check out OpenGL documentation for the meaning of the parameters.
The input parameters are:
getCameraImage
The getCameraImage API will return a RGB image, a depth buffer and a segmentation mask
buffer with body unique ids of visible objects for each pixel. Note that pybullet can be compiled
using the numpy option: using numpy will improve the performance of copying the camera
pixels from C to Python. Note: the old renderImage API is obsolete and replaced by
getCameraImage.
optional lightColor vec3, list of 3 floats light color in [RED,GREEN,BLUE] in range 0..1
rgbPixels list of [char RED,char GREEN,char BLUE] list of pixel colors in R,G,B format, in
[0..width*height] range [0..255] for each color
segmentationMaskBuffer list of int [0..width*height] for each pixels the visible object
index
getVisualShapeData
You can access visual shape information using getVisualShapeData. You could use this to
bridge your own rendering method with pybullet simulation, and synchronize the world
transforms manually after each simulation step.
The output is a list of visual shape data, each visual shape is in the following format:
dimensions vec3, list of 3 floats dimensions (size, local scale) of the geometry
meshAssetFileName string, list of chars path to the triangle mesh, if any. Typically relative to the
URDF, SDF or MJCF file location, but could be absolute.
localVisualFrame position vec3, list of 3 floats position of local visual frame, relative to link/joint frame
localVisualFrame orientation vec4, list of 4 floats orientation of local visual frame relative to link/joint frame
rgbaColor vec4, list of 4 floats URDF color (if any specified) in red/green/blue/alpha
The physics simulation uses center of mass as a reference for the Cartesian world transforms,
in getBasePositionAndOrientation and in getLinkState. If you implement your own rendering,
you need to transform the local visual transform to world space, making use of the center of
mass world transform and the (inverse) localInertialFrame. You can access the
localInertialFrame using the getLinkState API.
resetVisualShapeData
You can use resetVisualShapeData to change the texture of a shape. This texture will currently
only affect the software renderer (see getCameraImage), not the OpenGL visualization window
(yet).
loadTexture
Load a texture from file and return a non-negative texture unique id if the loading succeeds. This
unique id can be used with resetVisualShapeData.
You can query the contact point information that existed during the last 'stepSimulation'. To get
the contact points you can use the 'getContactPoints' API. Note that the 'getContactPoints' will
not recompute any contact point information.
getOverlappingObjects
This query will return all the unique ids of objects that have axis aligned bounding box overlap
with a given axis aligned bounding box.
getContactPoints
The getContactPoints input parameters are as follows:
optional filterBodyUniqueIdA int only report contact points that involve body A
optional filterBodyUniqueIdB int only report contact points that involve body B
optional physicsClientId int if you connected to multiple servers, you can pick one.
getContactPoints will return a list of contact points. Each contact point has the following fields:
contactDistance float contact distance, positive for separation, negative for penetration
getClosestPoints
It is also possible to compute the closest points, independent from stepSimulation. This also lets
you compute closest points of objects with an arbitrary separating distance. In this query there
will be no normal forces reported.
getClosestPoints input parameters:
required maxDistance float If the distance between objects exceeds this maximum distance,
no points may be returned.
optional physicsClientId int if you connected to multiple servers, you can pick one.
getClosestPoints returns a list of closest points in the same format as getContactPoints (but
normalForce is always zero in this case)
rayTest
You can perform a raycast to find the intersection information of the first object hit.
required rayToPosition vec3, list of 3 floats end of the ray in world coordinates
optional physicsClientId int if you connected to multiple servers, you can pick
one.
The raytest query will return the following information in case of an intersection:
hit fraction float hit fraction along the ray in range [0,1] along the ray.
hit position vec3, list of 3 floats hit position in Cartesian world coordinates
hit normal vec3, list of 3 floats hit normal in Cartesian world coordinates
Inverse Dynamics
calculateInverseDynamics
calculateInverseDynamics will compute the forces needed to reach the given joint accelerations,
starting from specified joint positions and velocities.
The calculateInverseDynamics input parameters are:
required bodyUniqueId int body unique id, as returned by loadURDF etc.
optional physicsClientId int if you connected to multiple servers, you can pick one.
Inverse Kinematics
You can compute the joint angles that makes the end-effector reach a given target position in
Cartesian world space. Optionally you can also specify the target orientation of the end effector.
In addition, there is an option to use the null-space to specify joint limits and rest poses. This
optional null-space support requires all 4 lists (lowerLimits, upperLimits, jointRanges,
restPoses), otherwise regular IK will be used. See also inverse_kinematics.py example in
Bullet/examples/pybullet folder for details.
calculateInverseKinematics
calculateInverseKinematics input parameters are:
required targetPosition vec3, list of 3 floats target position in Cartesian world space
optional targetOrientation vec3, list of 4 floats target orientation in Cartesian world space,
quaternion [x,y,w,z]. If not specified, pure
position IK will be used.
optional lowerLimits list of floats [0..nDof] Optional null-space IK requires all 4 lists
(lowerLimits, upperLimits, jointRanges,
restPoses). Otherwise regular IK will be used.
Virtual Reality
getVREvents
getVREvents will return a list of controllers that changed state since the last call to
getVREvents. getVREvents has one optional input parameter, physicsClientId.
controllerPosition vec3, list of 3 floats controller position, in world space Cartesian coordinates
controllerOrientation vec4, list of 4 floats controller orientation quaternion [x,y,z,w] in world space
buttons int[8], list of 8 integers flags for each button: VR_BUTTON_IS_DOWN (currently
held down), VR_BUTTON_WAS_TRIGGERED (went down
at least once since last cal to getVREvents,
VR_BUTTON_WAS_RELEASED (was released at least
once since last call to getVREvents). Note that only
VR_BUTTON_IS_DOWN reports actual current state. For
example if the button went down and up, you can tell from
the RELEASE/TRIGGERED flags, even though IS_DOWN is
still false.
See Bullet/examples/pybullet/vrEvents.py for an example of VR drawing.
setVRCameraState
setVRCameraState allows to set the camera root transform offset position and orientation. This
allows to control the position of the VR camera in the virtual world. It is also possible to let the
VR Camera track an object, such as a vehicle.
optional physicsClientId int if you connected to multiple servers, you can pick
one.
addUserDebugLine
You can add a 3d line specified by a 3d starting point (from) and end point (to), a color
[red,green,blue], a line width and a duration in seconds. The arguments to addUserDebugline
are:
required lineFromXYZ vec3, list of 3 floats starting point of the line in Cartesian world coordinates
required lineToXYZ vec3, list of 3 floats end point of the line in Cartesian world coordinates
optional lineColorRGB vec3, list of 3 floats RGB color [Red, Green, Blue] each component in
range [0..1]
optional lifeTime float use 0 for permanent line, or positive time in seconds
(afterwards the line with be removed automatically)
optional physicsClientId int if you connected to multiple servers, you can pick one
addUserDebugLine will return a non-negative unique id, that lets you remove the line using
removeUserDebugItem.
addUserDebugText
You can add some 3d text at a specific location using a color and size. The input arguments
are:
required textPosition vec3, list of 3 floats 3d position of the text in Cartesian world coordinates
[x,y,z]
optional textColorRGB vec3, list of 3 floats RGB color [Red, Green, Blue] each component in
range [0..1]
optional lifeTime float use 0 for permanent text, or positive time in seconds
(afterwards the text with be removed automatically)
optional physicsClientId int if you connected to multiple servers, you can pick one
addUserDebugText will return a non-negative unique id, that lets you remove the line using
removeUserDebugItem.
addUserDebugParameter, readUserDebugParameter
addUserDebugParameter lets you add custom sliders to tune parameters. It will return a unique
id. This lets you read the value of the parameter using readUserDebugParameter. The input
parameters of addUserDebugParameter are:
optional physicsClientI int if you connected to multiple servers, you can pick one
d
optional physicsClientId int if you connected to multiple servers, you can pick one
removeUserDebugItem
The functions to add user debug lines, text or parameters will return a non-negative unique id if
it succeeded. You can remove the debug item using this unique id using the
removeUserDebugItem method.The input parameters are:
required itemUniqueId int unique id of the debug item to be removed (line, text etc)
optional physicsClientId int if you connected to multiple servers, you can pick one
setDebugObjectColor
The built-in OpenGL visualizers have a wireframe debug rendering feature: press 'w' to toggle.
The wireframe has some default colors. You can override the color of a specific object and link
using setDebugObjectColor. The input parameters are:
That's it. Test pybullet by running a python interpreter and enter 'import pybullet' to see if the
module loads. If so, you can play with the pybullet scripts in Bullet/examples/pybullet.
Possible Linux Issues
● Make sure OpenGL is installed
● When using Anaconda as Python distribution, conda install libgcc so that ‘GLIBCXX’ is
found (see
http://askubuntu.com/questions/575505/glibcxx-3-4-20-not-found-how-to-fix-this-error)
● It is possible that cmake cannot find the python libs when using Anaconda as Python
distribution. You can add them manually by going to the ../build_cmake/CMakeCache.txt
file and changing following line:
‘PYTHON_LIBRARY:FILEPATH=/usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7
.so’
Make sure some Python version is installed in c:\python-3.5.2 (or other version folder name)
Question: What happens to Bullet 2.x and the Bullet 3 OpenCL implementation?
Answer: ullet C-API. We will put the Bullet 3 OpenCL GPU API
pybullet is wrapping the B
(and future Bullet 4.x API) behind this C-API. So if you use pybullet or the C-API
you are future-proof.
Question: How can I improve the performance and stability of the collision detection?
Answer: There are many ways to optimize, for example:
shape type
1) Choose one or multiple primitive collision shape types such as box, sphere, capsule,
cylinder to approximate an object, instead of using convex or concave triangle meshes.
2) If you really need to use triangle meshes, create a convex decomposition using
Hierarchical Approximate Convex Decomposition (v-HACD). The test_hacd utility
converts convex triangle mesh in an OBJ file into a new OBJ file with multiple convex
hull objects. See for example Bullet/data/teddy_vhacd.urdf pointing to
Bullet/data/teddy2_VHACD_CHs.obj, or duck_vhacd.urdf pointing to duck_vhacd.obj.
3) Reduce the number of vertices in a triangle mesh. For example Blender 3D has a great
mesh decimation modifier that interactively lets you see the result of the mesh
simplification.
4) Use rolling friction and spinning friction for round objects such as sphere and capsules
and robotic grippers using the <rolling_friction> and <spinning_friction> nodes inside
<link><contact> nodes. See for example Bullet/data/sphere2.urdf
5) Use a small amount of compliance for wheels using the <stiffness value="30000"/>
<damping value="1000"/> inside the URDF <link><contact> xml node. See for example
the Bullet/data/husky/husky.urdf vehicle.
6) Use the double precision build of Bullet, this is good both for contact stability and
collision accuracy. Choose some good constraint solver setting and time step.
7) Decouple the physics simulation from the graphics. pybullet already does this for the GUI
and various physics servers: the OpenGL graphics visualization runs in its own thread,
independent of the physics simulation.
Question: What kind of constant or threshold inside Bullet, that makes high speeds impossible?
Answer: By default, Bullet relies on discrete collision detection in combination with
penetration recovery. Relying purely on discrete collision detection means that an object
should not travel faster than its own radius within one timestep. Bullet has is an option
for continuous collision detection to catch collisions for objects that move faster than
their own radius within one timestep. This will be enabled in pybullet.