grasping_learning_sm.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 
00004 import roslib; roslib.load_manifest('estirabot_apps')
00005 import rospy
00006 import smach
00007 import smach_ros
00008 
00009 from pprint import pprint
00010 
00011 from smach_ros import SimpleActionState
00012 from smach_ros import ServiceState
00013 from smach import CBState
00014 
00015 import tf
00016 
00017 from iri_common_smach.st_get_pcl import GetPCL
00018 from iri_common_smach.utils_msg  import build_pose
00019 from iri_common_smach.utils_msg  import build_transform_msg
00020 from iri_common_smach.utils_msg  import build_pose_stamped_msg
00021 from iri_common_smach.get_keystroke import GetKeyStroke
00022 #from iri_common_smach.st_transform_pose   import TransformPoseStamped
00023 from iri_common_smach.homogeneous_product import homogeneous_product_pose_transform
00024 from iri_wam_smach.sm_wam_move_from_pose  import SM_WAM_MoveFromPose
00025 from estirabot_apps_base.sm_move          import SM_ESTIRABOT_GoHome
00026 
00027 from actionlib import *
00028 from actionlib.msg import *
00029 
00030 # used msgs
00031 from geometry_msgs.msg import PoseStamped,Quaternion
00032 from estirabot_msgs.srv import TransformPose
00033 from iri_wam_common_msgs.srv import wamdriver, wamdriverRequest
00034 from iri_dynamixel_gripper.msg import closeAction, openAction
00035 from iri_bow_object_detector.msg import *
00036 from iri_wam_common_msgs.msg import *
00037 from iri_perception_msgs.srv import PclToDescriptorSet
00038 from iri_perception_msgs.srv import PclToImg
00039 from iri_grasping_learner.srv import FindGoodPoint,LearnNewGrasp
00040 from iri_learning_msgs.msg import GraspInfo
00041 
00042 import ipdb
00043 
00044 @smach.cb_interface(input_keys=['grasp_point'],
00045                                         output_keys=['grasp_pose_st', 'target_frame'],
00046                                         outcomes=['done'])
00047 def build_grasp_pose_from_point_cb(ud):
00048         p                 = PoseStamped()
00049         p.pose            = build_pose(ud.grasp_point.x, ud.grasp_point.y, ud.grasp_point.z, 0, 1, 0, 0)
00050         p.header.frame_id = '/camera_rgb_optical_frame'
00051         p.header.stamp = rospy.Time.now()
00052         pub = rospy.Publisher('/debug/grasp_point', PoseStamped, None, False, True)
00053         rospy.sleep(1) # wait for subscribers
00054         pub.publish(p)
00055         ud.grasp_pose_st = p
00056         
00057         # transform pose
00058         #tf_manager = TransformManager()
00059         #p_transformed = tf_manager.transform_pose('wam_link0', p)
00060         #ud.grasp_pose_st = p_transformed
00061         
00062         ud.target_frame = '/wam_link0'
00063         
00064         return 'done'
00065 
00066 def grasping_point_goal_cb(userdata, goal):
00067         goal = GetGraspingPointGoal()
00068         goal.pointcloud = userdata.pcl_RGB
00069         return goal
00070 
00071 
00072 def build_pick_up_goal_from_grasping_pose(pose_st):
00073         goal = SimpleBhandPickUpGoal()
00074         
00075         #goal.fingers_position_for_pre_grasp=["GM 5000"]
00076         #goal.fingers_position_for_grasp=["GTC"]
00077         goal.fingers_position_for_pre_grasp=["open"]
00078         goal.fingers_position_for_grasp=["close"]
00079         
00080         # Grasp pose is pose_st
00081         goal.grasp_pose = pose_st
00082         
00083         # Pre-grasp pose -0.15m above grasp
00084         goal.pre_grasp_modifier.position.x = 0
00085         goal.pre_grasp_modifier.position.y = 0
00086         goal.pre_grasp_modifier.position.z = -0.15
00087         goal.pre_grasp_modifier.orientation.x = 0
00088         goal.pre_grasp_modifier.orientation.y = 0
00089         goal.pre_grasp_modifier.orientation.z = 0
00090         goal.pre_grasp_modifier.orientation.w = 1
00091         
00092         # Lift modifier -0.20 on Z
00093         goal.lift.direction.header.frame_id = "wam_link0"
00094         goal.lift.direction.header.stamp = pose_st.header.stamp
00095         goal.lift.direction.vector.x = 0
00096         goal.lift.direction.vector.y = 0
00097         goal.lift.direction.vector.z = 1
00098         goal.lift.desired_distance = 0.40
00099         
00100         return goal
00101 
00102 
00103 def move_pose_away(pose, z_offset):
00104         transform = build_transform_msg(0, 0, z_offset, 0, 0, 0, 1)
00105         return homogeneous_product_pose_transform(pose, transform)
00106 
00107 
00108 def grasp_cloth_goal_cb(userdata, goal):
00109         #ipdb.set_trace()
00110         pose_st = userdata.sm_transformed_pose_st
00111         
00112         # Set orientation pointing to the table
00113         pose_st.pose.orientation.x = 0
00114         pose_st.pose.orientation.y = 1
00115         pose_st.pose.orientation.z = 0
00116         pose_st.pose.orientation.w = 0
00117         pose_st.pose = move_pose_away(pose_st.pose, 0.2)
00118         
00119         pub = rospy.Publisher('/debug/grasp_point2', PoseStamped, None, False, True)
00120         rospy.sleep(1) # wait for subscribers
00121         pub.publish(pose_st)
00122         
00123         goal = build_pick_up_goal_from_grasping_pose(pose_st)
00124         return goal
00125 
00126         
00127         
00128         
00129         
00130 
00131 class MovePoseAway(smach.State):
00132         def __init__(self, dist_):
00133                 smach.State.__init__(self, outcomes=['succeeded','aborted'],
00134                                      input_keys=['pose_st'],
00135                                      output_keys=['pose_st'])
00136                 self.dist = dist_
00137         
00138         def execute(self, userdata):
00139                 userdata.pose_st.pose.orientation.x = 0.0
00140                 userdata.pose_st.pose.orientation.y = 0.0
00141                 userdata.pose_st.pose.orientation.z = 0.0
00142                 userdata.pose_st.pose.orientation.w = 1.0
00143                 userdata.pose_st.pose = move_pose_away(userdata.pose_st.pose, self.dist)
00144                 print userdata.pose_st
00145                 return 'succeeded'
00146 
00147 
00148 
00149 class TransformPoseStamped(smach.State):
00150         def __init__(self, sm_target_frame_):
00151                 smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'],
00152                                      input_keys=['sm_grasp_pose'],
00153                                      output_keys=['target_pose'])
00154                 self.service_topic = '/iri_transform_pose/transform_pose'
00155                 self.sm_target_frame = sm_target_frame_
00156         
00157         def execute(self, userdata):
00158                 rospy.logdebug('Executing state TransformPoseStamped')
00159                 rospy.wait_for_service(self.service_topic)
00160                 try:
00161                         get_target_pose = rospy.ServiceProxy(self.service_topic, TransformPose)
00162                         resp = get_target_pose(userdata.sm_grasp_pose, self.sm_target_frame)
00163                         
00164                         userdata.target_pose = resp.target_pose_st
00165                         return 'succeeded'
00166                 
00167                 except rospy.ServiceException, e:
00168                         print "Service call failed: %s"%e
00169                         return 'aborted'
00170 
00171 
00172 class GetFindddState(smach.State):
00173         def __init__(self, topic_):
00174                 smach.State.__init__(self, outcomes=['succeeded','aborted'],
00175                                      input_keys=['pcl_RGB'],
00176                                      output_keys=['descriptor_set'])
00177                 self.service_topic = topic_
00178 
00179         def execute(self, userdata):
00180                 rospy.logdebug('Executing state GetFinddd')
00181                 rospy.wait_for_service(self.service_topic)
00182                 try:
00183                         get_finddd = rospy.ServiceProxy(self.service_topic, PclToDescriptorSet)
00184                         resp = get_finddd(userdata.pcl_RGB)
00185                         userdata.descriptor_set = resp.descriptor_set
00186                         return 'succeeded'
00187 
00188                 except rospy.ServiceException, e:
00189                         print "Service call failed: %s"%e
00190                         return 'aborted'
00191 
00192 
00193 class PclToImageState(smach.State):
00194         def __init__(self, topic_):
00195                 smach.State.__init__(self, outcomes=['succeeded','aborted'],
00196                                      input_keys=['pcl_RGB'],
00197                                      output_keys=['image'])
00198                 self.service_topic = topic_
00199 
00200         def execute(self, userdata):
00201                 rospy.logdebug('Executing state PclToImageState')
00202                 rospy.wait_for_service(self.service_topic)
00203                 try:
00204                         get_image = rospy.ServiceProxy(self.service_topic, PclToImg)
00205                         resp = get_image(userdata.pcl_RGB)
00206                         userdata.image = resp.image
00207                         return 'succeeded'
00208 
00209                 except rospy.ServiceException, e:
00210                         print "Service call failed: %s"%e
00211                         return 'aborted'
00212 
00213 
00214 
00215 class GetGraspPointState(smach.State):
00216         def __init__(self, topic_):
00217                 smach.State.__init__(self, outcomes=['succeeded','aborted','unknown'],
00218                                      input_keys=['image','descriptor_set'],
00219                                      output_keys=['grasp_info','descriptor_idx','grasp_pose_stamped'])
00220                 self.service_topic = topic_
00221 
00222         def execute(self, userdata):
00223                 rospy.logdebug('Executing state GetGraspPointState')
00224                 rospy.wait_for_service(self.service_topic)
00225                 try:
00226                         get_grasp_point = rospy.ServiceProxy(self.service_topic, FindGoodPoint)
00227                         resp = get_grasp_point(userdata.descriptor_set, userdata.image)
00228                         
00229                         userdata.grasp_info = resp.grasp_info
00230                         userdata.descriptor_idx = resp.desc_index
00231                         pose_st = PoseStamped()
00232                         pose_st.pose.position.x = userdata.descriptor_set.descriptors[resp.desc_index].point3d.x
00233                         pose_st.pose.position.y = userdata.descriptor_set.descriptors[resp.desc_index].point3d.y
00234                         pose_st.pose.position.z = userdata.descriptor_set.descriptors[resp.desc_index].point3d.z
00235                         pose_st.pose.orientation.w = 1.0 # assuming x,y,z are initialized to 0.0
00236                         pose_st.header.frame_id = '/camera_rgb_optical_frame'
00237                         userdata.grasp_pose_stamped = pose_st
00238                         if resp.knows:
00239                                 return 'succeeded'
00240                         else:
00241                                 return 'unknown'
00242 
00243                 except rospy.ServiceException, e:
00244                         print "Service call failed: %s"%e
00245                         return 'aborted'
00246 
00247 
00248 class WaitUserInputState(smach.State):
00249         def __init__(self):
00250                 smach.State.__init__(self, outcomes=['succeeded','aborted'])
00251 
00252         def execute(self, userdata):
00253                 rospy.loginfo('Press key when arm is positioned (q for aborting)')
00254                 print 'Press key when arm is positioned (q for aborting)'
00255                 getch = GetKeyStroke()
00256                 key = getch()
00257                 if key == 'q':
00258                         return 'aborted'
00259                 else:
00260                         return 'succeeded'
00261 
00262 
00263 class GetGraspInfoFromDemoState(smach.State):
00264         def __init__(self):
00265                 smach.State.__init__(self, outcomes=['succeeded','aborted'],
00266                                                 output_keys=['grasp_info','grasp_pose_link0'])
00267                 self.listener = tf.TransformListener()
00268 
00269         def execute(self, userdata):
00270                 time_common = self.listener.getLatestCommonTime('/wam_link0','/wam_tcp')
00271                 res = self.listener.lookupTransform('/wam_link0','/wam_tcp',time_common)
00272                 pos = res[0]
00273                 ori = res[1]
00274                 grasp_info = GraspInfo()
00275                 grasp_info.orientation = Quaternion(*ori)
00276                 userdata.grasp_info = grasp_info
00277                 
00278                 # TODO get profundidad
00279                 
00280                 return 'succeeded'
00281 
00282 
00283 class GraspingLearnerAddPointState(smach.State):
00284         def __init__(self, topic_):
00285                 smach.State.__init__(self, outcomes=['succeeded','aborted'],
00286                                      input_keys=['descriptor_set','descriptor_idx','grasp_info'])
00287                 self.service_topic = topic_
00288 
00289         def execute(self, userdata):
00290                 rospy.logdebug('Executing state GraspingLearnerAddPointState')
00291                 rospy.wait_for_service(self.service_topic)
00292                 try:
00293                         add_grasp_point = rospy.ServiceProxy(self.service_topic, LearnNewGrasp)
00294                         resp = add_grasp_point(userdata.descriptor_set, userdata.descriptor_idx, userdata.grasp_info)
00295                         if resp.update_ok:
00296                                 return 'succeeded'
00297                         else:
00298                                 return 'aborted'
00299 
00300                 except rospy.ServiceException, e:
00301                         print "Service call failed: %s"%e
00302                         return 'aborted'
00303 
00304 
00305 
00306 
00307 def main():
00308         rospy.init_node('sm_pick_up_cloths')
00309         
00310         sm_move_factory = SM_WAM_MoveFromPose('/estirabot/wam_wrapper/joints_move',
00311                                               '/estirabot/wam_ik/pose_move')
00312         sm_move         = sm_move_factory.build_sm()
00313         sm_goHome_factory = SM_ESTIRABOT_GoHome()
00314         sm_goHome         = sm_goHome_factory.build_sm()
00315         
00316         # Create a SMACH state machine
00317         sm = smach.StateMachine(outcomes=['finishOk','failedVision','failedLearn','failedMoveArm'])
00318 
00319         # Open the container
00320         with sm:
00321                 # Add states to the container
00322                 
00323                 # Get pointcloud from Kinect
00324                 smach.StateMachine.add('GetPCL', GetPCL('/estirabot/ceiling_kinect/camera/rgb/points'),
00325                                 transitions={'success':'GetFindddState', 
00326                                                 'fail':'failedVision'},
00327                                 remapping={'pcl_RGB':'pcl_RGB'})
00328                 
00329                 # Get Finddd
00330                 smach.StateMachine.add('GetFindddState', GetFindddState('/iri_finddd/get_finddd_from_pointcloud'),
00331                                 transitions={'succeeded':'PclToImageState', 
00332                                                 'aborted':'failedVision'},
00333                                 remapping={'descriptor_set':'descriptor_set'})
00334                 
00335                 # Get image from pointcloud
00336                 smach.StateMachine.add('PclToImageState', PclToImageState('/convert_pcl_to_image'),
00337                                 transitions={'succeeded':'GetGraspPointState', 
00338                                                 'aborted':'failedVision'},
00339                                 remapping={'image':'image'})
00340                 
00341                 # Get grasp point and, if unknown trigger learning action
00342                 smach.StateMachine.add('GetGraspPointState', GetGraspPointState('/get_grasping_point'),
00343                                 transitions={'succeeded':'TransformPoseStamped2', 
00344                                                 'unknown':'TransformPoseStamped1', 
00345                                                 'aborted':'failedVision'},
00346                                 remapping={'grasp_info':'grasp_info',
00347                                     'descriptor_idx':'descriptor_idx',
00348                                         'grasp_pose_stamped':'sm_grasp_pose'})
00349                 
00350                 
00351                 # IF UNKNOWN
00352                 # Learn grasping from user demo
00353                 smach.StateMachine.add('TransformPoseStamped1', 
00354                                         TransformPoseStamped('/wam_link0'),
00355                                 transitions={'succeeded':'MovePoseAway', 
00356                                                 'preempted':'failedMoveArm',
00357                                                 'aborted':'failedMoveArm'},
00358                                 remapping={'target_pose':'grasp_pose_link0'})
00359                 
00360                 # TODO alejar move
00361                 smach.StateMachine.add('MovePoseAway', 
00362                                         MovePoseAway(0.2),
00363                                 transitions={'succeeded':'MoveToSelectedGraspPoint', 
00364                                                 'aborted':'failedMoveArm'},
00365                                 remapping={'pose_st':'grasp_pose_link0'})
00366                 
00367                 smach.StateMachine.add('MoveToSelectedGraspPoint', sm_move,
00368                                 transitions={'success':'SetGravityCompensation', 
00369                                                 'aborted':'failedMoveArm',
00370                                                 'no_kinematic_solution':'failedMoveArm'},
00371                                 remapping={'pose_st':'grasp_pose_link0'})
00372                 
00373                 
00374                 smach.StateMachine.add('SetGravityCompensation',
00375                                                 ServiceState('/estirabot/wam_wrapper/wam_services',
00376                                                                                 wamdriver,
00377                                                                                 request = wamdriverRequest(1)),
00378                                                 transitions={'succeeded':'WaitUserInputState',
00379                                                                         'aborted':'failedMoveArm',
00380                                                                         'preempted':'failedMoveArm'})
00381                 
00382                 smach.StateMachine.add('WaitUserInputState', WaitUserInputState(),
00383                                 transitions={'succeeded':'RemoveGravityCompensation', 
00384                                                 'aborted':'failedLearn'})
00385                 
00386                 smach.StateMachine.add('RemoveGravityCompensation',
00387                                                 ServiceState('/estirabot/wam_wrapper/wam_services',
00388                                                                                 wamdriver,
00389                                                                                 request = wamdriverRequest(0)),
00390                                                 transitions={'succeeded':'GetGraspInfoFromDemoState',
00391                                                                         'aborted':'failedMoveArm',
00392                                                                         'preempted':'failedMoveArm'})
00393                 
00394                 smach.StateMachine.add('GetGraspInfoFromDemoState', GetGraspInfoFromDemoState(),
00395                                 transitions={'succeeded':'GraspingLearnerAddPointState', 
00396                                                 'aborted':'failedLearn'},
00397                                 remapping={'grasp_info':'grasp_info'})
00398                 
00399                 smach.StateMachine.add('GraspingLearnerAddPointState', GraspingLearnerAddPointState('/learn_new_grasping'),
00400                                 transitions={'succeeded':'GetPCL', 
00401                                                 'aborted':'failedLearn'})
00402                 
00403                 
00404                 # IF KNOWN
00405                 # Execute known grasping
00406                 smach.StateMachine.add('TransformPoseStamped2', 
00407                                         TransformPoseStamped('/wam_link0'),
00408                                 transitions={'succeeded':'SimpleBhandPickUpAction', 
00409                                                 'preempted':'failedVision',
00410                                                 'aborted':'failedVision'},
00411                                 remapping={'target_pose':'sm_transformed_pose_st'})
00412                 
00413                 # TODO REPLACE ORIENTATION AND SET OFFSET
00414                 
00415                 smach.StateMachine.add('SimpleBhandPickUpAction', 
00416                                 SimpleActionState('/estirabot/skills/grasp/pickup',
00417                                                   SimpleBhandPickUpAction,
00418                                                   goal_cb=grasp_cloth_goal_cb,
00419                                                   input_keys=['sm_transformed_pose_st']),
00420                                 transitions={'succeeded':'GoHome',
00421                                                 'preempted':'failedMoveArm',
00422                                                 'aborted':'failedMoveArm'})
00423                 
00424                 
00425                 
00426                 
00427                 #smach.StateMachine.add('GetGraspingPointAction', 
00428                                 #SimpleActionState('/estirabot/skills/bow_detector/bow_object_detector/get_grasping_point',
00429                                                   #GetGraspingPointAction,
00430                                                   ##goal_slots=['pcl_RGB'],
00431                                                   #goal_cb=grasping_point_goal_cb,
00432                                                   #input_keys=['pcl_RGB'],
00433                                                   #result_slots=['grasping_point']),
00434                                                   ##server_wait_timeout=rospy.Duration(10.0)),
00435                                 #transitions={'succeeded':'ConvertGraspPoint',
00436                                                 #'preempted':'failedVision',
00437                                                 #'aborted':'failedVision'},
00438                                 #remapping={'grasping_point':'sm_grasp_point'})
00439                 
00440                 
00441                 
00442                 # move to home
00443                 smach.StateMachine.add('GoHome', 
00444                                         sm_goHome,
00445                                 transitions={'success':'OpenGripper',
00446                                         'aborted':'failedMoveArm'})
00447                 
00448                 # lwpr
00449                 
00450                 # release
00451                 smach.StateMachine.add('OpenGripper',
00452                        smach_ros.SimpleActionState('/estirabot/gripper/open_action_',
00453                                                   openAction),
00454                        {'succeeded': 'CloseGripper',
00455                         'preempted': 'failedMoveArm',
00456                         'aborted'  : 'failedMoveArm'})
00457                 
00458                 smach.StateMachine.add('CloseGripper',
00459                        smach_ros.SimpleActionState('/estirabot/gripper/close_action_',
00460                                                   closeAction),
00461                        {'succeeded': 'finishOk',
00462                         'preempted': 'failedMoveArm',
00463                         'aborted'  : 'failedMoveArm'})
00464                 
00465                 # initial
00466                 
00467     
00468         #sis = smach_ros.IntrospectionServer('iri_grasping_learner', sm, '/SM_LEARNING2')
00469         #sis.start()
00470     
00471         # Execute SMACH plan
00472         outcome = sm.execute()
00473         
00474         #sis.stop()
00475 
00476 
00477 
00478 if __name__ == '__main__':
00479         main()


iri_grasping_learner
Author(s): Arnau Ramisa
autogenerated on Fri Dec 6 2013 21:42:27