grasp_manager.py
Go to the documentation of this file.
00001 import numpy as np
00002 
00003 import roslib; roslib.load_manifest('pr2_grasp_behaviors')
00004 import rospy
00005 from std_msgs.msg import String, Bool
00006 import std_srvs.srv
00007 from tf.transformations import *
00008 import object_manipulator.convert_functions as cf
00009 
00010 from hrl_pr2_lib.hrl_controller_manager import HRLControllerManager as ControllerManager
00011 from pr2_collision_monitor.srv import JointDetectionStart, ArmMovingWait
00012 from pr2_grasp_behaviors.grasp_behavior_server import GraspStates
00013 
00014 ##
00015 # Abstract class for a grasping behavior.  Implements much of the framework for
00016 # a generic behavior-based grasp and provides virtual template functions for specific
00017 # behaviors to override.
00018 class GraspBehavior(object):
00019     def __init__(self, arm, use_coll_detection=False):
00020         self.arm = arm
00021         self.use_coll_detection = use_coll_detection
00022         self.GRIPPER_POINT = np.array([0.23, 0.0, 0.0])
00023 
00024         self.cm = ControllerManager(self.arm)
00025         class CollisionState:
00026             def __init__(self):
00027                 self.collided = False
00028             def callback(self, msg):
00029                 if msg.data:
00030                     self.collided = True
00031         self.coll_state = CollisionState()
00032         if self.use_coll_detection:
00033             rospy.loginfo("Waiting for start_detection")
00034             rospy.wait_for_service(self.arm + '_joint_coll_detect/start_detection')
00035             self.start_detection = rospy.ServiceProxy(self.arm + '_joint_coll_detect/start_detection', JointDetectionStart, persistent=True)
00036             rospy.loginfo("Waiting for stop_detection")
00037             rospy.wait_for_service(self.arm + '_joint_coll_detect/stop_detection')
00038             self.stop_detection = rospy.ServiceProxy(self.arm + '_joint_coll_detect/stop_detection', std_srvs.srv.Empty, persistent=True)
00039             self.stop_detection()
00040             rospy.Subscriber(self.arm + "_joint_coll_detect/arm_collision_detected", Bool, self.coll_state.callback)
00041 
00042         rospy.loginfo("Waiting for arm_moving_wait")
00043         rospy.wait_for_service(self.arm + '_arm_moving_server/arm_moving_wait')
00044         self.arm_moving_wait = rospy.ServiceProxy(self.arm + '_arm_moving_server/arm_moving_wait', ArmMovingWait, persistent=True)
00045 
00046         rospy.loginfo("[grasp_manager] GraspBehavior loaded.")
00047 
00048     ################################################################################
00049     # virtual functions to be implemented by specific grasp
00050 
00051     ##
00052     # Move arm to preparatory pose
00053     def grasp_preparation_move(self):
00054         rospy.logerr("UNIMPLEMENTED!")
00055     ##
00056     # Move arm to grasp setup, just before approach.
00057     def grasp_setup_move(self, params):
00058         rospy.logerr("UNIMPLEMENTED!")
00059     ##
00060     # Execute the grasping arm motion
00061     def execute_approach(self, block):
00062         rospy.logerr("UNIMPLEMENTED!")
00063     ##
00064     # Generate a random behavior parameterization for sampling
00065     # the workspace of possible grasps
00066     def random_generator(self):
00067         rospy.logerr("UNIMPLEMENTED!")
00068     ##
00069     # Attempt to slightly adjust grasp parameters to get a close configuration
00070     # which will hopefully find an IK solution.
00071     def jiggle_grasp_params(self, grasp_params):
00072         return grasp_params
00073 
00074     ################################################################################
00075 
00076     ##
00077     # Transforms the given position by the offset position in the given quaternion
00078     # rotation frame
00079     def transform_in_frame(self, pos, quat, off_point):
00080         quatmat = np.mat(quaternion_matrix(quat))
00081         quatmat[0:3,3] = np.mat(pos).T
00082         trans = np.matrix([off_point[0],off_point[1],off_point[2],1.]).T
00083         transpos = quatmat * trans
00084         return transpos.T.A[0,0:3]
00085 
00086     ##
00087     # Returns same gripper rotation normalized to [0, pi) range.
00088     def normalize_rot(self, gripper_rot):
00089         while gripper_rot >= np.pi:
00090             gripper_rot -= np.pi
00091         while gripper_rot < 0.:
00092             gripper_rot += np.pi
00093         return gripper_rot
00094 
00095     ##
00096     # Creates a PoseStamped in the torso_lift_link frame
00097     def create_goal_pose(self, x, y, z, gripper_pose):
00098         point = [x, y, z]
00099         point = self.transform_in_frame(point, gripper_pose, -self.GRIPPER_POINT).tolist()
00100         pose = point + gripper_pose.tolist()
00101         goal_pose = cf.create_pose_stamped(pose, "torso_lift_link")
00102         goal_pose.header.stamp = rospy.Time.now()
00103         return goal_pose
00104 
00105     ##
00106     # Returns the position of the end effector
00107     def get_end_effector_pos(self):
00108         wrist_pose = self.cm.get_current_wrist_pose_stamped("torso_lift_link")
00109         p = wrist_pose.pose.position
00110         o = wrist_pose.pose.orientation
00111         affector_pos = self.transform_in_frame([p.x, p.y, p.z],
00112                                           [o.x, o.y, o.z, o.w], self.GRIPPER_POINT)
00113         return affector_pos
00114 
00115     ##
00116     # Takes special care to kill the arm's movement by canceling
00117     # the action client and accounting for some edge cases.
00118     def kill_arm_movement(self):
00119         rospy.loginfo("Killing arm movement")
00120         self.cm.joint_action_client.cancel_all_goals()
00121         rospy.sleep(0.01) 
00122         # Needed for lag time in the case that the collision occurs
00123         # before the action is dispatched and due to the fact that
00124         # the arm doesn't necessarily respond the first time
00125         while not self.cm.check_joint_trajectory_done():
00126             self.cm.joint_action_client.cancel_all_goals()
00127             rospy.sleep(0.01)
00128             if rospy.is_shutdown():
00129                 self.cm.joint_action_client.cancel_all_goals()
00130 
00131     ##
00132     # Readys arm for grasp motion.
00133     def stage_grasp(self, grasp_params, open_gripper=True):
00134         rospy.loginfo("Staging grasp motion")
00135         self.grasp_setup_move(grasp_params)
00136         if open_gripper:
00137             # open gripper
00138             rospy.loginfo("Opening gripper")
00139             self.cm.command_gripper(1.00, -1.0, False)
00140             self.cm.gripper_action_client.wait_for_result(rospy.Duration(2.0))
00141         self.cm.wait_joint_trajectory_done()
00142 
00143     ##
00144     # Performs motion where arm approaches object
00145     def grasp_approach_motion(self, coll_detect=False, behavior_name="", sig_level=0.99):
00146         # move arm down
00147         rospy.loginfo("Moving arm down")
00148         startt = rospy.Time.now().to_sec()
00149         if coll_detect:
00150             self.start_detection(behavior_name, sig_level)
00151         result = self.execute_approach(False)
00152 
00153         if result == "no solution":
00154             # break without completing the grasp
00155             #self.apm.end_collision_detection()
00156             if coll_detect:
00157                 self.stop_detection()
00158             return "no solution"
00159 
00160         # grasp motion should be successful and moving now
00161 
00162         # wait until the trajectory is complete.
00163         # this loop will not exit until the arm has stopped moving
00164         while not self.cm.check_joint_trajectory_done():
00165             if rospy.is_shutdown():
00166                 self.kill_arm_movement()
00167                 return "shutdown"
00168             if self.coll_state.collided:
00169                 self.kill_arm_movement()
00170                 break
00171             rospy.sleep(0.005)
00172 
00173         if coll_detect:
00174             self.stop_detection()
00175         if self.coll_state.collided and coll_detect:
00176             grasp_result = "Collision"
00177         else:
00178             grasp_result = "No collision"
00179         self.coll_state.collided = False
00180         endt = rospy.Time.now().to_sec()
00181         rospy.loginfo("Grasp duration: %f", endt - startt)
00182         rospy.loginfo("Finished moving arm")
00183         return grasp_result
00184 
00185     ##
00186     # Gripper graping action
00187     def grasping_action(self):
00188         rospy.loginfo("Closing gripper")
00189         self.cm.command_gripper(0.0, 30.0, True)
00190         rospy.loginfo("Gripper closed")
00191 
00192     ##
00193     # Gripper placing action
00194     def placing_action(self):
00195         rospy.loginfo("Opening gripper")
00196         self.cm.command_gripper(1.00, -1.0, False)
00197         rospy.sleep(0.5)
00198         rospy.loginfo("Gripper opened")
00199 
00200     ##
00201     # Performs full grasping behavior.
00202     #
00203     # @param grasp_params A tuple containing the parameters for the behavior.
00204     # @param is_place If False, perform a grasp.  If True, perform a place.
00205     # @param collide Whether or not we should detect for collisions.
00206     # @param data_collecting If True, only perform the approach motion and return after that.
00207     # @param num_jiggle How many times the parameters should be jiggled before giving up
00208     # @param publish_state Callback function which takes a string and publishes the current state
00209     # @return grasp_result Result of grasp.
00210     def perform_grasp(self, grasp_params, is_place=False, collide=True, 
00211                                           behavior_name="", sig_level=0.99, 
00212                                           data_collecting=False, num_jiggle=2,
00213                                           publish_state=lambda x: x):
00214         self.collide = collide
00215 
00216         rospy.loginfo("Performing grasp with parameters: " + str(grasp_params))
00217         iters = 0
00218         while not rospy.is_shutdown():
00219             # Move to grasp position
00220             publish_state(GraspStates.GRASP_SETUP_MOVE)
00221             self.stage_grasp(grasp_params, not is_place)
00222             self.arm_moving_wait(True, 3.0) # Wait for the arm to stop moving
00223             publish_state(GraspStates.EXECUTE_APPROACH)
00224             approach_result = self.grasp_approach_motion(self.use_coll_detection and self.collide,
00225                                                          behavior_name=behavior_name, 
00226                                                          sig_level=sig_level)
00227             rospy.sleep(0.1)
00228             if approach_result != "no solution":
00229                 break
00230             else:
00231                 if num_jiggle == 0:
00232                     rospy.loginfo("Interpolated IK failed, cannot perform grasp for x = %1.2f, y = %1.2f, rot = %1.2f" % (x, y, gripper_rot))
00233                     return "IK failure"
00234                 rospy.loginfo("Interpolated IK failed, jiggling configuration for nearby trajectory")
00235                 # Jiggle it to see if it works
00236                 grasp_params = self.jiggle_grasp_params(grasp_params)
00237                 iters += 1
00238                 # Tried too many times
00239                 if iters >= num_jiggle:
00240                     rospy.loginfo("Cannot find IK solution")
00241                     return "IK failure"
00242                 else:
00243                     continue
00244 
00245         if data_collecting:
00246             return "Grasp motion success"
00247 
00248         if approach_result == "Collision":
00249             if not is_place:
00250                 publish_state(GraspStates.GRASP_OBJECT)
00251                 self.grasping_action()
00252             else:
00253                 self.placing_action()
00254 
00255         if not is_place:
00256             rospy.loginfo("Picking object up")
00257         else:
00258             rospy.loginfo("Pulling arm away")
00259         publish_state(GraspStates.EXECUTE_RETREAT)
00260         self.execute_retreat()
00261         
00262         ################################################################################
00263         # determine return result
00264         self.arm_moving_wait(True, 3.0) # Wait for the arm to stop moving
00265         if approach_result == "Collision":
00266             if not is_place:
00267                 if self.is_obj_in_gripper():
00268                     grasp_result = "Object grasped"
00269                 else:
00270                     grasp_result = "Object missed"
00271             else:
00272                 grasp_result = "Object placed"
00273         else:
00274             if not is_place: 
00275                 grasp_result = "No collision for grasp"
00276             else:
00277                 if self.is_obj_in_gripper():
00278                     grasp_result = "No collision for place"
00279                 else:
00280                     grasp_result = "Object dropped before place"
00281         ################################################################################
00282         rospy.loginfo("Grasp result: %s" % grasp_result)
00283         rospy.loginfo("Grasp complete!")
00284         return grasp_result
00285 
00286     ##
00287     # Checks to see if anything is in the gripper currently (gripper is not fully closed).
00288     def is_obj_in_gripper(self):
00289         last_opening = self.cm.get_current_gripper_opening()
00290         while not rospy.is_shutdown():
00291             rospy.sleep(0.2)
00292             next_opening = self.cm.get_current_gripper_opening()
00293             print next_opening
00294             if abs(last_opening - next_opening) < 0.001:
00295                 break
00296             last_opening = next_opening
00297         return self.cm.get_current_gripper_opening() > 0.01
00298     


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