36 from rosgraph.names
import ns_join
37 from .
import conversions
39 from moveit_msgs.msg import PlanningScene, CollisionObject, AttachedCollisionObject
40 from moveit_ros_planning_interface
import _moveit_planning_scene_interface
41 from geometry_msgs.msg
import Pose, Point
42 from shape_msgs.msg
import SolidPrimitive, Plane, Mesh, MeshTriangle
43 from .exception
import MoveItCommanderException
44 from moveit_msgs.srv
import ApplyPlanningScene, ApplyPlanningSceneRequest
47 from pyassimp
import pyassimp
55 "Failed to import pyassimp, see https://github.com/ros-planning/moveit/issues/86 for more info"
61 Python interface for a C++ PlanningSceneInterface.
62 Uses both C++ wrapped methods and scene manipulation topics
63 to manipulate the PlanningScene managed by the PlanningSceneMonitor.
64 See wrap_python_planning_scene_interface.cpp for the wrapped methods.
67 def __init__(self, ns="", synchronous=False, service_timeout=5.0):
68 """Create a planning scene interface; it uses both C++ wrapped methods and scene manipulation topics."""
69 self.
_psi_psi = _moveit_planning_scene_interface.PlanningSceneInterface(ns)
71 self.
_pub_co_pub_co = rospy.Publisher(
72 ns_join(ns,
"collision_object"), CollisionObject, queue_size=100
74 self.
_pub_aco_pub_aco = rospy.Publisher(
75 ns_join(ns,
"attached_collision_object"),
76 AttachedCollisionObject,
82 ns_join(ns,
"apply_planning_scene"), ApplyPlanningScene
86 def __submit(self, collision_object, attach=False):
92 self.
_pub_aco_pub_aco.publish(collision_object)
94 self.
_pub_co_pub_co.publish(collision_object)
97 """Add an object to the planning scene"""
98 self.
__submit__submit(collision_object, attach=
False)
101 """Add a sphere to the planning scene"""
103 self.
__submit__submit(co, attach=
False)
106 """Add a cylinder to the planning scene"""
108 self.
__submit__submit(co, attach=
False)
110 def add_mesh(self, name, pose, filename, size=(1, 1, 1)):
111 """Add a mesh to the planning scene"""
112 co = self.
__make_mesh__make_mesh(name, pose, filename, size)
113 self.
__submit__submit(co, attach=
False)
115 def add_box(self, name, pose, size=(1, 1, 1)):
116 """Add a box to the planning scene"""
117 co = self.
__make_box__make_box(name, pose, size)
118 self.
__submit__submit(co, attach=
False)
120 def add_plane(self, name, pose, normal=(0, 0, 1), offset=0):
121 """Add a plane to the planning scene"""
122 co = CollisionObject()
123 co.operation = CollisionObject.ADD
125 co.header = pose.header
127 p.coef = list(normal)
128 p.coef.append(offset)
130 co.plane_poses = [pose.pose]
131 self.
__submit__submit(co, attach=
False)
134 """Attach an object in the planning scene"""
135 self.
__submit__submit(attached_collision_object, attach=
True)
138 self, link, name, pose=None, filename="", size=(1, 1, 1), touch_links=[]
140 aco = AttachedCollisionObject()
141 if (pose
is not None)
and filename:
142 aco.object = self.
__make_mesh__make_mesh(name, pose, filename, size)
146 aco.touch_links = [link]
147 if len(touch_links) > 0:
148 aco.touch_links = touch_links
149 self.
__submit__submit(aco, attach=
True)
151 def attach_box(self, link, name, pose=None, size=(1, 1, 1), touch_links=[]):
152 aco = AttachedCollisionObject()
154 aco.object = self.
__make_box__make_box(name, pose, size)
158 if len(touch_links) > 0:
159 aco.touch_links = touch_links
161 aco.touch_links = [link]
162 self.
__submit__submit(aco, attach=
True)
165 """Remove all objects from the planning scene"""
171 Remove an object from planning scene, or all if no name is provided
173 co = CollisionObject()
174 co.operation = CollisionObject.REMOVE
177 self.
__submit__submit(co, attach=
False)
181 Remove an attached object from the robot, or all objects attached to the link if no name is provided,
182 or all attached objects in the scene if neither link nor name are provided.
184 Removed attached objects remain in the scene as world objects.
185 Call remove_world_object afterwards to remove them from the scene.
187 aco = AttachedCollisionObject()
188 aco.object.operation = CollisionObject.REMOVE
193 self.
__submit__submit(aco, attach=
True)
197 Get the names of all known objects in the world. If with_type is set to true, only return objects that have a known type.
202 self, minx, miny, minz, maxx, maxy, maxz, with_type=False
205 Get the names of known objects in the world that are located within a bounding region (specified in the frame reported by
206 get_planning_frame()). If with_type is set to true, only return objects that have a known type.
209 minx, miny, minz, maxx, maxy, maxz, with_type
214 Get the poses from the objects identified by the given object ids list.
220 conversions.msg_from_string(msg, ser_ops[key])
226 Get the objects identified by the given object ids list. If no ids are provided, return all the known objects.
231 msg = CollisionObject()
232 conversions.msg_from_string(msg, ser_objs[key])
238 Get the attached objects identified by the given object ids list. If no ids are provided, return all the attached objects.
242 for key
in ser_aobjs:
243 msg = AttachedCollisionObject()
244 conversions.msg_from_string(msg, ser_aobjs[key])
250 Applies the planning scene message.
253 conversions.msg_to_string(planning_scene_message)
257 def __make_existing(name):
259 Create an empty Collision Object. Used when the object already exists
261 co = CollisionObject()
266 def __make_box(name, pose, size):
267 co = CollisionObject()
268 co.operation = CollisionObject.ADD
270 co.header = pose.header
272 box = SolidPrimitive()
273 box.type = SolidPrimitive.BOX
274 box.dimensions = list(size)
275 co.primitives = [box]
279 def __make_mesh(name, pose, filename, scale=(1, 1, 1)):
280 co = CollisionObject()
281 if pyassimp
is False:
283 "Pyassimp needs patch https://launchpadlibrarian.net/319496602/patchPyassim.txt"
285 scene = pyassimp.load(filename)
286 if not scene.meshes
or len(scene.meshes) == 0:
288 if len(scene.meshes[0].faces) == 0:
290 co.operation = CollisionObject.ADD
292 co.header = pose.header
296 first_face = scene.meshes[0].faces[0]
297 if hasattr(first_face,
"__len__"):
298 for face
in scene.meshes[0].faces:
300 triangle = MeshTriangle()
301 triangle.vertex_indices = [face[0], face[1], face[2]]
302 mesh.triangles.append(triangle)
303 elif hasattr(first_face,
"indices"):
304 for face
in scene.meshes[0].faces:
305 if len(face.indices) == 3:
306 triangle = MeshTriangle()
307 triangle.vertex_indices = [
312 mesh.triangles.append(triangle)
315 "Unable to build triangles from mesh due to mesh object structure"
317 for vertex
in scene.meshes[0].vertices:
319 point.x = vertex[0] * scale[0]
320 point.y = vertex[1] * scale[1]
321 point.z = vertex[2] * scale[2]
322 mesh.vertices.append(point)
324 pyassimp.release(scene)
328 def __make_sphere(name, pose, radius):
329 co = CollisionObject()
330 co.operation = CollisionObject.ADD
332 co.header = pose.header
334 sphere = SolidPrimitive()
335 sphere.type = SolidPrimitive.SPHERE
336 sphere.dimensions = [radius]
337 co.primitives = [sphere]
341 def __make_cylinder(name, pose, height, radius):
342 co = CollisionObject()
343 co.operation = CollisionObject.ADD
345 co.header = pose.header
347 cylinder = SolidPrimitive()
348 cylinder.type = SolidPrimitive.CYLINDER
349 cylinder.dimensions = [height, radius]
350 co.primitives = [cylinder]
354 def __make_planning_scene_diff_req(collision_object, attach=False):
355 scene = PlanningScene()
357 scene.robot_state.is_diff =
True
359 scene.robot_state.attached_collision_objects = [collision_object]
361 scene.world.collision_objects = [collision_object]
362 planning_scene_diff_req = ApplyPlanningSceneRequest()
363 planning_scene_diff_req.scene = scene
364 return planning_scene_diff_req
def attach_box(self, link, name, pose=None, size=(1, 1, 1), touch_links=[])
def get_object_poses(self, object_ids)
def apply_planning_scene(self, planning_scene_message)
def add_box(self, name, pose, size=(1, 1, 1))
def attach_object(self, attached_collision_object)
def add_plane(self, name, pose, normal=(0, 0, 1), offset=0)
def __make_box(name, pose, size)
def attach_mesh(self, link, name, pose=None, filename="", size=(1, 1, 1), touch_links=[])
def __make_mesh(name, pose, filename, scale=(1, 1, 1))
def get_attached_objects(self, object_ids=[])
def __make_existing(name)
_apply_planning_scene_diff
def __init__(self, ns="", synchronous=False, service_timeout=5.0)
def __make_planning_scene_diff_req(collision_object, attach=False)
def get_known_object_names_in_roi(self, minx, miny, minz, maxx, maxy, maxz, with_type=False)
def __make_cylinder(name, pose, height, radius)
def remove_attached_object(self, link=None, name=None)
def __submit(self, collision_object, attach=False)
def add_object(self, collision_object)
def get_known_object_names(self, with_type=False)
def add_sphere(self, name, pose, radius=1)
def get_objects(self, object_ids=[])
def __make_sphere(name, pose, radius)
def add_cylinder(self, name, pose, height, radius)
def add_mesh(self, name, pose, filename, size=(1, 1, 1))
def remove_world_object(self, name=None)
void print(PropagationDistanceField &pdf, int numX, int numY, int numZ)