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 
00016 
00017 
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     
00050 
00051     
00052     
00053     def grasp_preparation_move(self):
00054         rospy.logerr("UNIMPLEMENTED!")
00055     
00056     
00057     def grasp_setup_move(self, params):
00058         rospy.logerr("UNIMPLEMENTED!")
00059     
00060     
00061     def execute_approach(self, block):
00062         rospy.logerr("UNIMPLEMENTED!")
00063     
00064     
00065     
00066     def random_generator(self):
00067         rospy.logerr("UNIMPLEMENTED!")
00068     
00069     
00070     
00071     def jiggle_grasp_params(self, grasp_params):
00072         return grasp_params
00073 
00074     
00075 
00076     
00077     
00078     
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     
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     
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     
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     
00117     
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         
00123         
00124         
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     
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             
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     
00145     def grasp_approach_motion(self, coll_detect=False, behavior_name="", sig_level=0.99):
00146         
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             
00155             
00156             if coll_detect:
00157                 self.stop_detection()
00158             return "no solution"
00159 
00160         
00161 
00162         
00163         
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     
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     
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     
00202     
00203     
00204     
00205     
00206     
00207     
00208     
00209     
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             
00220             publish_state(GraspStates.GRASP_SETUP_MOVE)
00221             self.stage_grasp(grasp_params, not is_place)
00222             self.arm_moving_wait(True, 3.0) 
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                 
00236                 grasp_params = self.jiggle_grasp_params(grasp_params)
00237                 iters += 1
00238                 
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         
00264         self.arm_moving_wait(True, 3.0) 
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     
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