00001
00002
00003 import numpy as np, math
00004 import sys
00005
00006 import roslib; roslib.load_manifest('pr2_grasp_behaviors')
00007 import rospy
00008
00009 import actionlib
00010 from tf.transformations import *
00011 from std_msgs.msg import String
00012 from geometry_msgs.msg import PointStamped
00013 import object_manipulator.convert_functions as cf
00014 from object_manipulator.cluster_bounding_box_finder import ClusterBoundingBoxFinder
00015 from tabletop_object_detector.srv import TabletopSegmentation
00016 from pr2_controllers_msgs.msg import PointHeadAction, PointHeadGoal
00017
00018 from pr2_grasp_behaviors.msg import OverheadGraspAction, OverheadGraspResult
00019 from pr2_grasp_behaviors.msg import OverheadGraspSetupAction, OverheadGraspSetupResult
00020 from pr2_grasp_behaviors.msg import OverheadGraspFeedback
00021
00022
00023
00024 class GraspStates:
00025 ACTIONLIB_CALLED = 'Actionlib grasping goal called'
00026 PERCEIVING_OBJECTS = 'Perceiving table objects'
00027 GRASP_SETUP_MOVE = 'Moving to grasp setup'
00028 EXECUTE_APPROACH = 'Executing grasp motion'
00029 GRASP_OBJECT = 'Closing gripper on object'
00030 EXECUTE_RETREAT = 'Retreating grasp motion'
00031 ACTIONLIB_COMPLETE = 'Actionlib grasping goal completed'
00032
00033 class GraspBehaviorServer(object):
00034 def __init__(self, arm, grasp_manager):
00035 self.arm = arm
00036 self.gman = grasp_manager
00037
00038
00039
00040 def open_gripper(self, blocking = False):
00041 self.gman.cm.command_gripper(1.0, -1.0, False)
00042 if blocking:
00043 self.gman.cm.gripper_action_client.wait_for_result(rospy.Duration(4.0))
00044
00045
00046
00047
00048
00049 def detect_tabletop_objects(self):
00050 DETECT_ERROR = 0.
00051 cbbf = ClusterBoundingBoxFinder(tf_listener=self.gman.cm.tf_listener)
00052 object_detector = rospy.ServiceProxy("/object_detection", TabletopSegmentation)
00053 try:
00054 detects = object_detector()
00055 object_detector.close()
00056 except ServiceException as se:
00057 rospy.logerr("Tabletop segmentation crashed")
00058 return []
00059 if detects.result != 4:
00060 rospy.logerr("Detection failed (err %d)" % (detects.result))
00061 return []
00062 table_z = detects.table.pose.pose.position.z
00063 objects = []
00064 for cluster in detects.clusters:
00065 (object_points,
00066 object_bounding_box_dims,
00067 object_bounding_box,
00068 object_to_base_link_frame,
00069 object_to_cluster_frame) = cbbf.find_object_frame_and_bounding_box(cluster)
00070
00071 (object_pos, object_quat) = cf.mat_to_pos_and_quat(object_to_cluster_frame)
00072 angs = euler_from_quaternion(object_quat)
00073
00074 object_pos[2] = table_z + object_bounding_box[1][2] / 2. + DETECT_ERROR
00075 objects += [[object_pos, angs[2]]]
00076 return objects
00077
00078 def get_grasp_loc(self, obj):
00079 return obj[0][0], obj[0][1], obj[1], obj[0][2]
00080
00081
00082
00083
00084 def detect_closest_object(self, x, y, repeat=True, disable_head=False):
00085 def dist(o):
00086 return (o[0][0] - x) ** 2 + (o[0][1] - y) ** 2
00087
00088 grasped = False
00089 num_tries = 0
00090
00091 if not disable_head:
00092 self.point_head([x,y,-0.3])
00093
00094 while not grasped and num_tries < 4:
00095 rospy.loginfo("Detect in")
00096 rospy.sleep(0.6)
00097 detect_tries = 0
00098 objects = None
00099 while (objects is None or len(objects) == 0):
00100 objects = self.detect_tabletop_objects()
00101 rospy.sleep(0.6)
00102 detect_tries += 1
00103 if detect_tries == 3 and (objects is None or len(objects) == 0):
00104 rospy.logerr("Cannot detect any objects")
00105 return None
00106 rospy.loginfo("Detect out")
00107 if len(objects) > 0:
00108 try:
00109 obj = min(objects, key=dist)
00110
00111
00112 if not disable_head:
00113 obj_pt = obj[0]
00114 obj_pt[2] = -0.4
00115 self.point_head(obj_pt)
00116 rospy.sleep(0.2)
00117 rospy.loginfo("Detect2 in")
00118 objects = self.detect_tabletop_objects()
00119 rospy.loginfo("Detect2 out")
00120 obj = min(objects, key=dist)
00121 except:
00122 pass
00123
00124 return obj
00125 else:
00126 rospy.loginfo("No objects near point")
00127 return None
00128 return None
00129
00130
00131
00132 def point_head(self, point, velocity = 0.6, frame="/torso_lift_link", block = True):
00133 head_action_client = actionlib.SimpleActionClient("/head_traj_controller/point_head_action", PointHeadAction)
00134 head_action_client.wait_for_server()
00135 goal = PointHeadGoal()
00136 goal.target = cf.create_point_stamped(point, frame)
00137 goal.pointing_frame = "/openni_rgb_optical_frame"
00138 goal.max_velocity = velocity
00139
00140 head_action_client.send_goal(goal)
00141
00142 if not block:
00143 return 0
00144
00145 finished_within_time = head_action_client.wait_for_result(rospy.Duration(10))
00146 if not finished_within_time:
00147 head_action_client.cancel_goal()
00148 rospy.logerr("timed out when asking the head to point to a new goal")
00149 return 0
00150
00151 return 1
00152
00153
00154
00155 def setup_grasp(self, block = False, disable_head=False, open_gripper=False):
00156 if open_gripper:
00157 self.open_gripper(blocking=False)
00158 if not disable_head:
00159 self.point_head([0.3, 0.0, -0.3], block=False)
00160 self.gman.grasp_preparation_move()
00161 rospy.sleep(1.)
00162 if block:
00163 self.gman.arm_moving_wait(True, 8.0)
00164
00165
00166
00167 def start_grasping_server(self, grasp_server_name, setup_server_name):
00168 self.grasping_server = actionlib.SimpleActionServer(grasp_server_name, OverheadGraspAction, self.execute_grasping_goal, False)
00169 self.grasping_server.register_preempt_callback(self.gman.kill_arm_movement)
00170 self.grasping_server.start()
00171 self.setup_server = actionlib.SimpleActionServer(setup_server_name, OverheadGraspSetupAction, self.execute_grasping_setup, False)
00172 self.setup_server.register_preempt_callback(self.gman.kill_arm_movement)
00173 self.setup_server.start()
00174 rospy.loginfo("Grasping server launched on %s, setup at %s",
00175 grasp_server_name, setup_server_name)
00176
00177
00178
00179 def execute_grasping_setup(self, goal):
00180 result = OverheadGraspSetupResult()
00181 self.setup_grasp(block=True, disable_head=goal.disable_head, open_gripper=goal.open_gripper)
00182 rospy.loginfo("Finished setup")
00183 self.setup_server.set_succeeded(result)
00184
00185
00186
00187
00188
00189 def execute_grasping_goal(self, goal):
00190 result = OverheadGraspResult()
00191 feedback = OverheadGraspFeedback()
00192 def publish_state(state):
00193 feedback.state = state
00194 self.grasping_server.publish_feedback(feedback)
00195 publish_state(GraspStates.ACTIONLIB_CALLED)
00196
00197
00198 if goal.grasp_type == goal.MANUAL_GRASP:
00199 grasp_params = (goal.x, goal.y, goal.roll, goal.pitch)
00200
00201
00202 elif goal.grasp_type == goal.VISION_GRASP:
00203 obj = self.detect_closest_object(goal.x,
00204 goal.y,
00205 disable_head=goal.disable_head)
00206 publish_state(GraspStates.PERCEIVING_OBJECTS)
00207 if obj is None:
00208 rospy.loginfo("No objects detected")
00209 result.grasp_result = "No objects detected"
00210 self.grasping_server.set_aborted(result)
00211 return
00212 x, y, rot, z = self.get_grasp_loc(obj)
00213 grasp_params = (x, y, rot, goal.pitch)
00214
00215
00216 elif goal.grasp_type == goal.RANDOM_GRASP:
00217 grasp_params = self.random_generator()
00218
00219 else:
00220 rospy.logerr("Bad grasp type")
00221 self.grasping_server.set_aborted(result)
00222 return
00223
00224 feedback.x, feedback.y = grasp_params[0], grasp_params[1]
00225 feedback.roll, feedback.pitch = grasp_params[2], grasp_params[3]
00226 grasp_result = self.gman.perform_grasp(grasp_params, collide=not goal.disable_coll,
00227 behavior_name=goal.behavior_name,
00228 sig_level=goal.sig_level,
00229 is_place=not goal.is_grasp,
00230 publish_state=publish_state)
00231 result.grasp_result = grasp_result
00232 if goal.is_grasp:
00233 if grasp_result == "Object grasped":
00234 self.grasping_server.set_succeeded(result)
00235 else:
00236 self.grasping_server.set_aborted(result)
00237 else:
00238 if grasp_result == "Object placed":
00239 self.grasping_server.set_succeeded(result)
00240 else:
00241 self.grasping_server.set_aborted(result)
00242 publish_state(GraspStates.ACTIONLIB_COMPLETE)