|
| 1 | +******************************************************************************* |
| 2 | +Introduction to the Reachability Map |
| 3 | +******************************************************************************* |
| 4 | + |
| 5 | +For workspace planning or robot path planning, it is useful to calculate and |
| 6 | +visualize the space of the robot's reachability, depending on its attached tool, |
| 7 | +obstacles in the environment and its own kinematic and geometric constraints. |
| 8 | + |
| 9 | +The ``ReachabilityMap`` is a collection of all valid IK solutions, i.e. poses that the end-effector can reach, at specified locations. The map is built by discretizing the robot's environment, defining frames to be checked, and calculating the IK solutions for each frame. |
| 10 | + |
| 11 | +The creation of this map depends on the availability of an analytical inverse |
| 12 | +kinematic solver for the used robot. Please checkout the kinematic backend for |
| 13 | +available robots. |
| 14 | + |
| 15 | +Links |
| 16 | +===== |
| 17 | +* `Realuex (ROS's reachability map) <http://wiki.ros.org/reuleaux>`_ |
| 18 | + |
| 19 | + |
| 20 | +Example 01: reachability map 1D |
| 21 | +=============================== |
| 22 | + |
| 23 | +Let's consider the following (abstract) example: |
| 24 | + |
| 25 | +We have a UR5 and want the TCP of the robot to always orient itself towards a |
| 26 | +defined position in front of the robot. Therefore, we define a (half-)sphere |
| 27 | +with a certain radius and we evaluate points on this sphere. At each point, we then |
| 28 | +create a plane whose normal vector points towards the center of this sphere. From these planes |
| 29 | +we create frames for the robot's TCP. The function is written as a generator |
| 30 | +because the ``ReachabilityMap`` takes a ``Frame`` generator as input. |
| 31 | + |
| 32 | +.. figure:: files/00_robot_halfsphere.jpg |
| 33 | + :figclass: figure |
| 34 | + :class: figure-img img-fluid |
| 35 | + |
| 36 | + |
| 37 | +.. code-block:: python |
| 38 | +
|
| 39 | + import math |
| 40 | +
|
| 41 | + from compas.geometry import Frame |
| 42 | + from compas.geometry import Plane |
| 43 | + from compas.geometry import Point |
| 44 | + from compas.geometry import Sphere |
| 45 | +
|
| 46 | + # 1. Define frames on a sphere |
| 47 | + sphere = Sphere((0.4, 0, 0), 0.15) |
| 48 | +
|
| 49 | + def points_on_sphere_generator(sphere): |
| 50 | + for theta_deg in range(0, 360, 20): |
| 51 | + for phi_deg in range(0, 90, 10): # only half-sphere |
| 52 | + theta = math.radians(theta_deg) |
| 53 | + phi = math.radians(phi_deg) |
| 54 | + x = sphere.point.x + sphere.radius * math.cos(theta) * math.sin(phi) |
| 55 | + y = sphere.point.y + sphere.radius * math.sin(theta) * math.sin(phi) |
| 56 | + z = sphere.point.z + sphere.radius * math.cos(phi) |
| 57 | + point = Point(x, y, z) |
| 58 | + axis = sphere.point - point |
| 59 | + plane = Plane((x, y, z), axis) |
| 60 | + f = Frame.from_plane(plane) |
| 61 | + # for the old UR5 model from ROS Kinetic is zaxis the xaxis |
| 62 | + yield [Frame(f.point, f.zaxis, f.yaxis)] |
| 63 | +
|
| 64 | +
|
| 65 | +Then we create a ``PyBulletClient`` (for collision checking), load the UR5 robot, |
| 66 | +set the analytical IK solver and define options for the IK solver. |
| 67 | +For simplicity, we do not add any tool or obstacles in the environment here, but in a |
| 68 | +real robot cell, this will usually be the case. |
| 69 | + |
| 70 | + |
| 71 | +.. code-block:: python |
| 72 | +
|
| 73 | + # 2. Set up robot cell |
| 74 | + from compas_fab.backends import AnalyticalInverseKinematics |
| 75 | + from compas_fab.backends import PyBulletClient |
| 76 | +
|
| 77 | + with PyBulletClient(connection_type='direct') as client: |
| 78 | + # load robot and define settings |
| 79 | + robot = client.load_ur5(load_geometry=True) |
| 80 | + ik = AnalyticalInverseKinematics(client) |
| 81 | + client.inverse_kinematics = ik.inverse_kinematics |
| 82 | + options = {"solver": "ur5", "check_collision": True, "keep_order": True} |
| 83 | +
|
| 84 | +Now we create a ``ReachabilityMap``. We calculate it passing the ``Frame`` |
| 85 | +generator, the robot and the IK options. After calculation, we save the map as |
| 86 | +json for later visualization in Rhino/GH. |
| 87 | + |
| 88 | +>>> # 3. Create reachability map 1D |
| 89 | +>>> map = ReachabilityMap() # doctest: +SKIP |
| 90 | +>>> map.calculate(points_on_sphere_generator(sphere), robot, options) # doctest: +SKIP |
| 91 | +>>> map.to_json(os.path.join(DATA, "reachability", "map1D.json")) # doctest: +SKIP |
| 92 | + |
| 93 | + |
| 94 | +`Link to full script <files/01_example_1D.py>`_ |
| 95 | + |
| 96 | + |
| 97 | +Visualization |
| 98 | +============= |
| 99 | + |
| 100 | +We can source the reachability map from the json file and use the ``Artist`` to |
| 101 | +visualize the saved frames by using the artist's function ``draw_frames``. |
| 102 | + |
| 103 | +>>> map = ReachabilityMap.from_json(filepath) # doctest: +SKIP |
| 104 | +>>> artist = Artist(map) # doctest: +SKIP |
| 105 | +>>> frames = artist.draw_frames() # doctest: +SKIP |
| 106 | + |
| 107 | + |
| 108 | +.. figure:: files/00_robot_halfsphere.jpg |
| 109 | + :figclass: figure |
| 110 | + :class: figure-img img-fluid |
| 111 | + |
| 112 | + |
| 113 | +By default, the ``artist.draw()`` method returns points and colors for a point cloud, |
| 114 | +where the points are the positions of the frames and the colors are calculated |
| 115 | +from the score at the respective frame. The ``ReachabilityMap.score`` is |
| 116 | +the number of valid IK solutions for a frame. The default colormap is 'viridis'. |
| 117 | + |
| 118 | +In the example below, the highest score is 4 (yellow) and the lowest score is 2 (violet). |
| 119 | + |
| 120 | +.. figure:: files/01_robot_map1D.jpg |
| 121 | + :figclass: figure |
| 122 | + :class: figure-img img-fluid |
| 123 | + |
| 124 | + |
| 125 | +If you want to visualize the frames at a specific IK index (= number between 0-7), use the method |
| 126 | +``artist.draw_frames(ik_index=ik_index)``. If you compare the figure below |
| 127 | +with the figure of ``draw_frames``, you will see that a certain portion is not |
| 128 | +reachable at the selected IK index. |
| 129 | + |
| 130 | +.. figure:: files/02_robot_frames_at_ik.jpg |
| 131 | + :figclass: figure |
| 132 | + :class: figure-img img-fluid |
| 133 | + |
| 134 | + |
| 135 | +Projects where the reachability map was applied |
| 136 | +=============================================== |
| 137 | + |
| 138 | +------------------------------------------------------------------------------------------ |
| 139 | +`Adaptive Detailing <https://gramaziokohler.arch.ethz.ch/web/forschung/e/0/0/0/361.html>`_ |
| 140 | +------------------------------------------------------------------------------------------ |
| 141 | + |
| 142 | +In this project, connections between structural elements are 3D printed in place, |
| 143 | +directly on top of parts, i.e. collision objects. A ``ReachabilityMap`` was created |
| 144 | +to capture the space where connections can be placed and ultimately find connecting |
| 145 | +geometries that the robot can print in between these objects. Printing process |
| 146 | +constraints can be included in the reachability map by choosing a meaningful |
| 147 | +``max_alpha`` in the ``DeviationVectorsGenerator``. |
| 148 | + |
| 149 | +.. figure:: files/adaptive_detailing.png |
| 150 | + :figclass: figure |
| 151 | + :class: figure-img img-fluid |
| 152 | + |
| 153 | +-------------------------------------------------------------------------------------------------------- |
| 154 | +`Robotic 360° Light Painting Workshop <https://gramaziokohler.arch.ethz.ch/web/lehre/e/0/0/0/439.html>`_ |
| 155 | +-------------------------------------------------------------------------------------------------------- |
| 156 | + |
| 157 | +This project served as inspiration for the presented examples 01-03. The robot TCP |
| 158 | +had to be oriented towards the 360° camera. The light paths were mapped on a hemisphere |
| 159 | +to maintain equal distance to the camera and little distortion of the designed paths. |
| 160 | +The reachability map was used to determine the best position and radius for the |
| 161 | +sphere with the UR5e robot model, the light tool, and the camera and tripods as |
| 162 | +collision objects. |
| 163 | + |
| 164 | +.. |logo1| image:: files/workshop_sjsu_1.png |
| 165 | + :scale: 45% |
| 166 | + :align: middle |
| 167 | +.. |logo2| image:: files/workshop_sjsu_2.jpg |
| 168 | + :scale: 45% |
| 169 | + :align: middle |
| 170 | + |
| 171 | ++---------+---------+ |
| 172 | +| |logo1| | |logo2| | |
| 173 | ++---------+---------+ |
0 commit comments