grasp_behavior_server.py
Go to the documentation of this file.
00001 #! /usr/bin/python
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 #from laser_interface.pkg import CURSOR_TOPIC, MOUSE_DOUBLE_CLICK_TOPIC, CURSOR_TOPIC, MOUSE_R_CLICK_TOPIC, MOUSE_R_DOUBLE_CLICK_TOPIC
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     # Open gripper fully.
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     # Uses the object_detection service detect objects on the table. Returns a list
00047     # of pairs [ [ x, y, z], rot ] which represent the centers and z orientation of
00048     # each object detected on the table.
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             # rospy.loginfo("bounding box:", object_bounding_box)
00071             (object_pos, object_quat) = cf.mat_to_pos_and_quat(object_to_cluster_frame)
00072             angs = euler_from_quaternion(object_quat)
00073             # position is half of height
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     # Given an (x, y) location on a table, grasp the closest object detected.
00083     # If repeat is True, will keep trying if the grasp fails.
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                     # Get better look
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     # Points head at given point in given frame.
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     # Move the arm to a suitable setup position for moving to a grasp position
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     # Launch actionlib srv calls.
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     # Wraps setup_grasp
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     # Executes grasping goal requested on actionlib srvs. Actions differ based
00188     # on type of grasp requested.
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         # User specifies parameters
00198         if goal.grasp_type == goal.MANUAL_GRASP:
00199             grasp_params = (goal.x, goal.y, goal.roll, goal.pitch)
00200 
00201         # Robot finds parameters
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         # execute a random grasp
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)


pr2_grasp_behaviors
Author(s): Kelsey Hawkins, Advisor: Prof. Charlie Kemp (Healthcare Robotics Lab at Georgia Tech)
autogenerated on Wed Nov 27 2013 11:40:53