Skip to content

Commit ffc0df7

Browse files
authored
Merge pull request #345 from compas-dev/fix-mesh-poses-noetic
fix: pose of collision meshes was ignored in ROS Noetic
2 parents 4a21871 + 06a00bf commit ffc0df7

File tree

9 files changed

+27
-7
lines changed

9 files changed

+27
-7
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Unreleased
2626
* Fixed PyBullet loading of meshes.
2727
* Fixed missing flag in reset planning scene call.
2828
* Fixed issue on cartesian and kinematic planning when model contains passive joints.
29+
* Fixed pose of collision mesh in ROS Noetic being ignored.
2930

3031
**Deprecated**
3132

src/compas_fab/backends/ros/backend_features/move_it_add_attached_collision_mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ def add_attached_collision_mesh_async(self, callback, errback, attached_collisio
5555
aco.object.operation = CollisionObject.ADD
5656
robot_state = RobotState(attached_collision_objects=[aco], is_diff=True)
5757
scene = PlanningScene(robot_state=robot_state, is_diff=True)
58-
request = dict(scene=scene)
58+
request = scene.to_request(self.ros_client.ros_distro)
5959
self.APPLY_PLANNING_SCENE(self.ros_client, request, callback, errback)

src/compas_fab/backends/ros/backend_features/move_it_add_collision_mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ def add_collision_mesh_async(self, callback, errback, collision_mesh):
5353
co.operation = CollisionObject.ADD
5454
world = PlanningSceneWorld(collision_objects=[co])
5555
scene = PlanningScene(world=world, is_diff=True)
56-
request = dict(scene=scene)
56+
request = scene.to_request(self.ros_client.ros_distro)
5757
self.APPLY_PLANNING_SCENE(self.ros_client, request, callback, errback)

src/compas_fab/backends/ros/backend_features/move_it_append_collision_mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ def append_collision_mesh_async(self, callback, errback, collision_mesh):
5353
co.operation = CollisionObject.APPEND
5454
world = PlanningSceneWorld(collision_objects=[co])
5555
scene = PlanningScene(world=world, is_diff=True)
56-
request = dict(scene=scene)
56+
request = scene.to_request(self.ros_client.ros_distro)
5757
self.APPLY_PLANNING_SCENE(self.ros_client, request, callback, errback)

src/compas_fab/backends/ros/backend_features/move_it_remove_attached_collision_mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ def remove_attached_collision_mesh_async(self, callback, errback, id):
5555
aco.object.operation = CollisionObject.REMOVE
5656
robot_state = RobotState(attached_collision_objects=[aco], is_diff=True)
5757
scene = PlanningScene(robot_state=robot_state, is_diff=True)
58-
request = dict(scene=scene)
58+
request = scene.to_request(self.ros_client.ros_distro)
5959
self.APPLY_PLANNING_SCENE(self.ros_client, request, callback, errback)

src/compas_fab/backends/ros/backend_features/move_it_remove_collision_mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ def remove_collision_mesh_async(self, callback, errback, id):
5454
co.operation = CollisionObject.REMOVE
5555
world = PlanningSceneWorld(collision_objects=[co])
5656
scene = PlanningScene(world=world, is_diff=True)
57-
request = dict(scene=scene)
57+
request = scene.to_request(self.ros_client.ros_distro)
5858
self.APPLY_PLANNING_SCENE(self.ros_client, request, callback, errback)

src/compas_fab/backends/ros/backend_features/move_it_reset_planning_scene.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ def reset_planning_scene_async(self, callback, errback):
5151
collision_object.object['operation'] = CollisionObject.REMOVE
5252
scene.is_diff = True
5353
scene.robot_state.is_diff = True
54-
request = dict(scene=scene)
54+
request = scene.to_request(self.ros_client.ros_distro)
5555
self.APPLY_PLANNING_SCENE(self.ros_client, request, callback, errback)

src/compas_fab/backends/ros/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def __exit__(self, *args):
157157
def ros_distro(self):
158158
"""Retrieves the ROS version to which the client is connected (eg. kinetic)"""
159159
if not self._ros_distro:
160-
self._ros_distro = Param(self, '/rosdistro').get(timeout=1)
160+
self._ros_distro = Param(self, '/rosdistro').get(timeout=1).strip()
161161

162162
return self._ros_distro
163163

src/compas_fab/backends/ros/messages/moveit_msgs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from compas_fab.backends.ros.messages.geometry_msgs import Vector3
88
from compas_fab.backends.ros.messages.object_recognition_msgs import ObjectType
99
from compas_fab.backends.ros.messages.octomap_msgs import OctomapWithPose
10+
from compas_fab.backends.ros.messages.ros_releases import RosDistro
1011
from compas_fab.backends.ros.messages.sensor_msgs import JointState
1112
from compas_fab.backends.ros.messages.sensor_msgs import MultiDOFJointState
1213
from compas_fab.backends.ros.messages.shape_msgs import Mesh
@@ -38,6 +39,8 @@ def __init__(self, header=None, id="collision_obj", type=None,
3839
self.header = header or Header() # a header, used for interpreting the poses
3940
self.id = id # the id of the object (name used in MoveIt)
4041
self.type = type or ObjectType() # The object type in a database of known objects
42+
self.pose = pose or Pose() # currently not actively used in FAB, but needed to be present otherwise ROS Noetic complains about empty quaternion
43+
4144
# solid geometric primitives
4245
self.primitives = primitives or []
4346
self.primitive_poses = primitive_poses or []
@@ -59,6 +62,7 @@ def from_collision_mesh(cls, collision_mesh):
5962
kwargs['id'] = collision_mesh.id
6063
kwargs['meshes'] = [Mesh.from_mesh(collision_mesh.mesh)]
6164
kwargs['mesh_poses'] = [Pose.from_frame(collision_mesh.frame)]
65+
kwargs['pose'] = Pose()
6266

6367
return cls(**kwargs)
6468

@@ -69,6 +73,7 @@ def from_msg(cls, msg):
6973
kwargs['header'] = Header.from_msg(msg['header'])
7074
kwargs['id'] = msg['id']
7175
kwargs['type'] = ObjectType.from_msg(msg['type'])
76+
kwargs['pose'] = Pose.from_msg(msg['pose']) if 'pose' in msg else Pose()
7277

7378
kwargs['primitives'] = [SolidPrimitive.from_msg(i) for i in msg['primitives']]
7479
kwargs['primitive_poses'] = [Pose.from_msg(i) for i in msg['primitive_poses']]
@@ -555,6 +560,20 @@ def __init__(self, name='', robot_state=None, robot_model_name='',
555560
self.world = world or PlanningSceneWorld() # moveit_msgs/PlanningSceneWorld
556561
self.is_diff = is_diff # bool
557562

563+
def to_request(self, ros_distro):
564+
self.filter_fields_for_distro(ros_distro)
565+
return dict(scene=self)
566+
567+
def filter_fields_for_distro(self, ros_distro):
568+
"""To maintain backwards compatibility with older ROS distros,
569+
we need to make sure newly added fields are removed from the request."""
570+
# Remove the field `pose` for distros older than NOETIC
571+
if ros_distro in (RosDistro.KINETIC, RosDistro.MELODIC):
572+
for aco in self.robot_state.attached_collision_objects:
573+
del aco.object.pose
574+
for co in self.world.collision_objects:
575+
del co.pose
576+
558577
@classmethod
559578
def from_msg(cls, msg):
560579
robot_state = RobotState.from_msg(msg['robot_state'])

0 commit comments

Comments
 (0)