Skip to content

Commit f54d5bb

Browse files
authored
Merge pull request #181 from compas-dev/pybullet
Pybullet
2 parents 5c99828 + 1cdcc53 commit f54d5bb

34 files changed

+1397
-38
lines changed

AUTHORS.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ If you use COMPAS FAB in a project, please use the following citation:
1919
Ma, Z. and
2020
Ariza, I. and
2121
Pacher, M. and
22-
Lytle, B.
22+
Lytle, B. and
23+
Huang, Y.
2324
},
2425
howpublished={https://github.com/compas-dev/compas\_fab/},
2526
note={Gramazio Kohler Research, ETH Z\"{u}rich},
@@ -43,3 +44,4 @@ Authors
4344
* Inés Ariza <[email protected]> `@inesariza <https://github.com/inesariza>`_
4445
* Matteo Pacher <[email protected]> `@matteo-pacher <https://github.com/matteo-pacher>`_
4546
* Beverly Lytle <[email protected]> `@beverlylytle <https://github.com/beverlylytle>`_
47+
* Yijiang Huang <[email protected]> `@yijiangh <https://github.com/yijiangh>`_

docs/backends/pybullet.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.. _pybullet_backend:
2+
3+
****************
4+
PyBullet
5+
****************
6+
7+
.. highlight:: bash
8+
9+
`PyBullet <https://pybullet.org/>`_ is a Python module extending Bullet, an open
10+
source collision detection and rigid dynamics library written in C++. PyBullet
11+
was written with the intention of being a "fast and easy to use Python module for
12+
robotics simulation and machine learning." It also provides bindings for rendering
13+
and visualization, and support for virtual reality headsets. While PyBullet
14+
is based on a client-server architecture, there is no need to spin up any Docker
15+
containers to run the server. This, along with its speed, may make PyBullet a
16+
preferable backend for COMPAS_FAB. However, it, alone, does not provide motion
17+
planning functionality. PyBullet is also not compatible with IronPython. Hence to use
18+
it with Rhinoceros and Grasshopper it must be invoked through :ref:``compas.rpc``
19+
(see `COMPAS RPC <https://compas-dev.github.io/main/api/compas.rpc.html>`_).

docs/examples/03_backends_ros/01_ros_examples.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Now open a second command prompt and start the listener:
104104

105105
python 01_ros_hello_world_listener.py
106106

107-
You should see the listener printing everytime it hears the other node talking.
107+
You should see the listener printing every time it hears the other node talking.
108108

109109
.. note::
110110

docs/examples/03_backends_ros/07_ros_create_urdf_ur5_with_measurement_tool.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ Paste the following into the file:
136136
Explanation
137137
-----------
138138

139-
The end-effector consists of one fixed joint (that will be attacted to the tool0
139+
The end-effector consists of one fixed joint (that will be attached to the tool0
140140
of the robot), one link with geometry (the tool geometry), one fixed joint (the
141141
tcp joint, defining the TCP frame) and the tcp link without geometry.
142142

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.. _examples_pybullet:
2+
3+
*******************************************************************************
4+
Backends: PyBullet
5+
*******************************************************************************
6+
7+
.. toctree::
8+
:maxdepth: 2
9+
:glob:
10+
11+
05_backends_pybullet/*
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.. _pybullet_examples:
2+
3+
*******************************************************************************
4+
Using PyBullet
5+
*******************************************************************************
6+
7+
First Step
8+
==========
9+
10+
The first step is to connect to PyBullet and verify that the system is working.
11+
12+
Copy and paste the following example into a Python script or REPL. If, when run,
13+
you see the output ``Connected: True``, then everything is working properly.
14+
15+
.. code-block:: python
16+
17+
from compas_fab.backends import PyBulletClient
18+
with PyBulletClient(connection_type='direct') as client:
19+
print('Connected:', client.is_connected)
20+
21+
.. note::
22+
23+
From the PyBullet user manual:
24+
The GUI connection will create a new graphical user interface (GUI) with 3D OpenGL
25+
rendering, within the same process space as PyBullet. On Linux and Windows this GUI
26+
runs in a separate thread, while on OSX it runs in the same thread due to operating
27+
system limitations. On Mac OSX you may see a spinning wheel in the OpenGL Window,
28+
until you run a 'stepSimulation' or other PyBullet command.
29+
30+
Our first example loads the UR5 robot from a URDF and then adds, then removes, a
31+
floor as a collision mesh. The calls to ``sleep`` are only necessary to prevent the
32+
gui from closing this example too quickly.
33+
34+
.. literalinclude :: files/01_add_collision_mesh.py
35+
:language: python
36+
37+
.. raw:: html
38+
39+
<div class="card bg-light">
40+
<div class="card-body">
41+
<div class="card-title">Downloads</div>
42+
43+
* :download:`Add Collision Mesh (.PY) <files/01_add_collision_mesh.py>`
44+
45+
.. raw:: html
46+
47+
</div>
48+
</div>
49+
50+
Adding and removing a collision mesh attached to the end effector link of the
51+
robot is similar. Again, the calls to ``sleep`` and ``step_simulation`` exist only
52+
to make the GUI rendering smoother.
53+
54+
.. literalinclude :: files/02_add_attached_collision_mesh.py
55+
:language: python
56+
57+
.. raw:: html
58+
59+
<div class="card bg-light">
60+
<div class="card-body">
61+
<div class="card-title">Downloads</div>
62+
63+
* :download:`Add Attached Collision Mesh (.PY) <files/02_add_attached_collision_mesh.py>`
64+
65+
.. raw:: html
66+
67+
</div>
68+
</div>
69+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import time
2+
from compas.datastructures import Mesh
3+
4+
import compas_fab
5+
from compas_fab.backends.pybullet import PyBulletClient
6+
from compas_fab.robots import CollisionMesh
7+
8+
with PyBulletClient() as client:
9+
urdf_filepath = compas_fab.get('universal_robot/ur_description/urdf/ur5.urdf')
10+
robot = client.load_robot(urdf_filepath)
11+
12+
mesh = Mesh.from_stl(compas_fab.get('planning_scene/floor.stl'))
13+
cm = CollisionMesh(mesh, 'floor')
14+
client.add_collision_mesh(cm)
15+
16+
time.sleep(1)
17+
18+
client.remove_collision_mesh('floor')
19+
20+
time.sleep(1)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import time
2+
3+
import compas_fab
4+
from compas_fab.backends.pybullet import PyBulletClient
5+
from compas_fab.robots import AttachedCollisionMesh
6+
from compas_fab.robots import CollisionMesh
7+
8+
from compas.datastructures import Mesh
9+
10+
with PyBulletClient() as client:
11+
urdf_filepath = compas_fab.get('universal_robot/ur_description/urdf/ur5.urdf')
12+
robot = client.load_robot(urdf_filepath)
13+
14+
mesh = Mesh.from_stl(compas_fab.get('planning_scene/cone.stl'))
15+
cm = CollisionMesh(mesh, 'tip')
16+
acm = AttachedCollisionMesh(cm, 'ee_link')
17+
client.add_attached_collision_mesh(acm, {'mass': 1, 'robot': robot})
18+
19+
time.sleep(1)
20+
client.step_simulation()
21+
time.sleep(1)
22+
23+
client.remove_attached_collision_mesh('tip')
24+
25+
time.sleep(1)

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# Until COMPAS reaches 1.0, we pin major.minor and allow patch version updates
1414
'compas>=0.16.1,<0.17',
1515
'roslibpy>=1.1.0',
16+
'pybullet',
1617
'pyserial',
1718
]
1819
keywords_list = ['robotic fabrication', 'digital fabrication', 'architecture', 'robotics', 'ros']

src/compas_fab/backends/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
RosFileServerLoader
2929
MoveItPlanner
3030
31+
PyBullet
32+
--------
33+
34+
.. autosummary::
35+
:toctree: generated/
36+
:nosignatures:
37+
38+
PyBulletClient
39+
PyBulletPlanner
40+
3141
Long-running tasks
3242
------------------
3343
@@ -52,6 +62,8 @@
5262
5363
"""
5464

65+
import compas
66+
5567
from .exceptions import * # noqa: F401,F403
5668
from .tasks import * # noqa: F401,F403
5769
from .ros.client import * # noqa: F401,F403
@@ -62,4 +74,8 @@
6274
from .vrep.helpers import * # noqa: F401,F403
6375
from .vrep.planner import * # noqa: F401,F403
6476

77+
if not compas.is_ironpython():
78+
from .pybullet.planner import * # noqa: F401,F403
79+
from .pybullet.client import * # noqa: F401,F403
80+
6581
__all__ = [name for name in dir() if not name.startswith('_')]

0 commit comments

Comments
 (0)