36 from rosgraph.names
import ns_join
37 from .
import conversions
39 from moveit_msgs.msg
import PlanningScene, CollisionObject, AttachedCollisionObject
40 from moveit_msgs.msg
import AllowedCollisionMatrix, AllowedCollisionEntry
41 from moveit_ros_planning_interface
import _moveit_planning_scene_interface
42 from geometry_msgs.msg
import Pose, Point
43 from shape_msgs.msg
import SolidPrimitive, Plane, Mesh, MeshTriangle
44 from .exception
import MoveItCommanderException
45 from moveit_msgs.srv
import ApplyPlanningScene, ApplyPlanningSceneRequest
48 from pyassimp
import pyassimp
56 "Failed to import pyassimp, see https://github.com/moveit/moveit/issues/86 for more info"
62 Python interface for a C++ PlanningSceneInterface.
63 Uses both C++ wrapped methods and scene manipulation topics
64 to manipulate the PlanningScene managed by the PlanningSceneMonitor.
65 See wrap_python_planning_scene_interface.cpp for the wrapped methods.
69 self.
_psi = _moveit_planning_scene_interface.PlanningSceneInterface(ns)
74 ns_join(ns,
"collision_object"), CollisionObject, queue_size=100
77 ns_join(ns,
"attached_collision_object"),
78 AttachedCollisionObject,
82 def __submit(self, collision_object, attach=False):
84 scene = PlanningScene()
86 scene.robot_state.is_diff =
True
88 scene.robot_state.attached_collision_objects = [collision_object]
90 scene.world.collision_objects = [collision_object]
94 self.
_pub_aco.publish(collision_object)
96 self.
_pub_co.publish(collision_object)
99 """Add an object to the planning scene"""
100 self.
__submit(collision_object, attach=
False)
103 """Add a sphere to the planning scene"""
108 """Add a cylinder to the planning scene"""
113 """Add a cylinder to the planning scene"""
114 co = self.
make_cone(name, pose, height, radius)
117 def add_mesh(self, name, pose, filename, size=(1, 1, 1)):
118 """Add a mesh to the planning scene"""
119 co = self.
make_mesh(name, pose, filename, size)
122 def add_box(self, name, pose, size=(1, 1, 1)):
123 """Add a box to the planning scene"""
124 co = self.
make_box(name, pose, size)
127 def add_plane(self, name, pose, normal=(0, 0, 1), offset=0):
128 """Add a plane to the planning scene"""
129 co = self.
make_plane(name, pose, normal, offset)
133 """Attach an object to the given link"""
134 if isinstance(object, str):
136 if isinstance(object, CollisionObject):
137 object = AttachedCollisionObject(object=object)
140 object.link_name = link
141 object.touch_links = (
142 touch_links
if touch_links
is not None else [object.link_name]
148 self, link, name, pose=None, filename="", size=(1, 1, 1), touch_links=
None
150 """Create mesh and attach it to the given link"""
151 if (pose
is not None)
and filename:
152 co = self.
make_mesh(name, pose, filename, size)
157 def attach_box(self, link, name, pose=None, size=(1, 1, 1), touch_links=
None):
158 """Create box and attach it to the given link"""
160 co = self.
make_box(name, pose, size)
166 """Create sphere and attach it to the given link"""
174 self, link, name, pose=None, height=1, radius=1, touch_links=None
176 """Create cylinder and attach it to the given link"""
184 """Remove all objects from the planning scene"""
189 Remove an object from planning scene, or all if no name is provided
191 co = CollisionObject()
192 co.operation = CollisionObject.REMOVE
199 Remove an attached object from the robot, or all objects attached to the link if no name is provided,
200 or all attached objects in the scene if neither link nor name are provided.
202 Removed attached objects remain in the scene as world objects.
203 Call remove_world_object afterwards to remove them from the scene.
205 aco = AttachedCollisionObject()
206 aco.object.operation = CollisionObject.REMOVE
215 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.
220 self, minx, miny, minz, maxx, maxy, maxz, with_type=False
223 Get the names of known objects in the world that are located within a bounding region (specified in the frame reported by
224 get_planning_frame()). If with_type is set to true, only return objects that have a known type.
227 minx, miny, minz, maxx, maxy, maxz, with_type
232 Get the poses from the objects identified by the given object ids list.
238 conversions.msg_from_string(msg, ser_ops[key])
244 Get the objects identified by the given object ids list. If no ids are provided, return all the known objects.
249 msg = CollisionObject()
250 conversions.msg_from_string(msg, ser_objs[key])
256 Get the attached objects identified by the given object ids list. If no ids are provided, return all the attached objects.
260 for key
in ser_aobjs:
261 msg = AttachedCollisionObject()
262 conversions.msg_from_string(msg, ser_aobjs[key])
267 """Get move_group's current planning scene"""
268 msg = PlanningScene()
274 Applies the planning scene message.
277 conversions.msg_to_string(planning_scene_message)
283 Create an empty Collision Object. Used when the object already exists
285 co = CollisionObject()
291 co = CollisionObject()
292 co.operation = CollisionObject.ADD
294 co.header = pose.header
296 shape = SolidPrimitive()
298 shape.dimensions = list(shape_args)
299 co.primitives = [shape]
304 return PlanningSceneInterface.__make_primitive(
305 name, pose, SolidPrimitive.BOX, size
310 co = CollisionObject()
311 if pyassimp
is False:
313 "Pyassimp needs patch https://launchpadlibrarian.net/319496602/patchPyassim.txt"
315 scene = pyassimp.load(filename)
316 if not scene.meshes
or len(scene.meshes) == 0:
318 if len(scene.meshes[0].faces) == 0:
320 co.operation = CollisionObject.ADD
322 co.header = pose.header
326 first_face = scene.meshes[0].faces[0]
327 if hasattr(first_face,
"__len__"):
328 for face
in scene.meshes[0].faces:
330 triangle = MeshTriangle()
331 triangle.vertex_indices = [face[0], face[1], face[2]]
332 mesh.triangles.append(triangle)
333 elif hasattr(first_face,
"indices"):
334 for face
in scene.meshes[0].faces:
335 if len(face.indices) == 3:
336 triangle = MeshTriangle()
337 triangle.vertex_indices = [
342 mesh.triangles.append(triangle)
345 "Unable to build triangles from mesh due to mesh object structure"
347 for vertex
in scene.meshes[0].vertices:
349 point.x = vertex[0] * scale[0]
350 point.y = vertex[1] * scale[1]
351 point.z = vertex[2] * scale[2]
352 mesh.vertices.append(point)
354 pyassimp.release(scene)
359 return PlanningSceneInterface.__make_primitive(
360 name, pose, SolidPrimitive.SPHERE, [radius]
365 return PlanningSceneInterface.__make_primitive(
366 name, pose, SolidPrimitive.CYLINDER, [height, radius]
371 return PlanningSceneInterface.__make_primitive(
372 name, pose, SolidPrimitive.CONE, [height, radius]
375 def make_plane(self, name, pose, normal=(0, 0, 1), offset=0):
376 co = CollisionObject()
377 co.operation = CollisionObject.ADD
379 co.header = pose.header
381 p.coef = list(normal)
382 p.coef.append(offset)
384 co.plane_poses = [pose.pose]
389 """Set default collision behavior for obj"""
390 if obj
not in acm.default_entry_names:
391 acm.default_entry_names.append(obj)
392 acm.default_entry_values.append(allow)
394 idx = acm.default_entry_names.index(obj)
395 acm.default_entry_values[idx] = allow
399 """Allow collisions between obj and other"""
401 acm.set_default(obj, allow)
404 other_idx = acm.entry_names.index(other)
405 if obj
not in acm.entry_names:
406 acm.entry_names.append(obj)
407 for entry
in acm.entry_values:
408 entry.enabled.append(allow)
409 acm.entry_values.append(
410 AllowedCollisionEntry(enabled=[allow
for i
in range(len(acm.entry_names))])
412 acm.entry_values[-1].enabled[other_idx] = allow
414 obj_idx = acm.entry_names.index(obj)
415 acm.entry_values[obj_idx].enabled[other_idx] = allow
416 acm.entry_values[other_idx].enabled[obj_idx] = allow
419 AllowedCollisionMatrix.set_default = acm_set_default
420 AllowedCollisionMatrix.set_allowed = acm_set_allowed