demo-heigh-analisys.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import roslib; roslib.load_manifest('estirabot_apps')
00004 import rospy
00005 import smach
00006 import smach_ros
00007 import tf
00008 import time
00009 
00010 from smach import StateMachine, CBState, Iterator
00011 from smach_ros import ServiceState
00012 from actionlib import *
00013 from actionlib.msg import *
00014 from std_msgs.msg import String
00015 from object_manipulation_msgs.msg import PickupAction,PickupGoal,PlaceAction,PlaceGoal
00016 from sensor_msgs.msg import PointCloud2, JointState
00017 from iri_deformable_analysis.srv import DoDeformableAnalysis, DoDeformableAnalysisRequest
00018 from estirabot_msgs.msg import PomdpGraspConfig
00019 from geometry_msgs.msg import Transform, PoseStamped, Pose
00020 from pprint import pprint
00021 from std_msgs.msg import Int8
00022 
00023 from iri_common_smach.st_get_pcl          import GetPCL
00024 from iri_common_smach.utils_msg           import build_pose_stamped_msg, build_transform_msg
00025 from iri_common_smach.get_keystroke       import GetKeyStroke
00026 
00027 from estirabot_apps_base.utils_pomdp            import PomdpConfigFactory
00028 from estirabot_apps_base.sm_move                import SM_ESTIRABOT_GoHome
00029 from estirabot_apps_base.sm_deformable_analysis import SM_ESTIRABOT_DeformableAnalysis
00030 from estirabot_apps_base.sm_generate_grasp      import SM_ESTIRABOT_GenerateGraspMsg
00031 
00032 class PublishGraspID(smach.State):
00033     def __init__(self):
00034         smach.State.__init__(self, outcomes=['success','fail'],
00035                              input_keys=['sm_pomdp_config'])
00036 
00037     def execute(self, userdata):
00038         print "Publish grasp id"
00039         time.sleep(1)
00040         #  pprint(userdata.sm_pomdp_config)
00041 #raw_input()
00042         return 'success'
00043 
00044 class HandlePomdpConfig(smach.State):
00045     def __init__(self):
00046         smach.State.__init__(self, outcomes=['ok'], input_keys=['algorithms','algorithms_index'],
00047                                                     output_keys=['sm_pomdp_config','algorithms_index'])
00048 
00049     def execute(self, userdata):
00050         magic_number = userdata.algorithms[userdata.algorithms_index]
00051 
00052         factory = PomdpConfigFactory()
00053         userdata.sm_pomdp_config = factory.get_instance(magic_number)
00054         # Publish the magic number
00055         pub = rospy.Publisher('/log/config_magic_number', Int8, None, False, True)
00056         pub.publish(magic_number)
00057         pprint("MAGIC NUMBER: " + str(magic_number))
00058 
00059         userdata.algorithms_index = userdata.algorithms_index + 1
00060         pprint("INDEX: " + str(userdata.algorithms_index))
00061 
00062         return 'ok'
00063 
00064 class PerformAnalysis(smach.State):
00065     def __init__(self):
00066         smach.State.__init__(self, outcomes=['success','fail','timeout'],
00067                                    input_keys=['pcl_RGB','sm_pomdp_config'],
00068                                    output_keys=['best_grasp_pose'])
00069 
00070     def execute(self, userdata):
00071         # Log the PCL
00072         pub = rospy.Publisher('/log/pcl_table_scene', PointCloud2,  None, False, True)
00073         #pub.publish(userdata.pcl_RGB)
00074 
00075         # Config and launch the deformable analysis
00076         handler = rospy.ServiceProxy('/estirabot/skills/deformable_analysis/do_deformable_analysis',
00077                                      DoDeformableAnalysis)
00078 
00079         analysis_request = DoDeformableAnalysisRequest()
00080         analysis_request.pcl_to_analyze = userdata.pcl_RGB
00081         analysis_request.fusion_criteria_id = userdata.sm_pomdp_config.best_pose_algorithm_id
00082 
00083         try:
00084             response = handler(analysis_request)
00085 
00086             if (not response):
00087                 return 'fail'
00088 
00089         except rospy.ServiceException, e:
00090             return 'timeout'
00091 
00092         pose_st = response.deformable_analysis.graspability.best_grasp_pose
00093         userdata.best_grasp_pose = pose_st
00094         print("end analysis")
00095 
00096         return 'success'
00097 
00098 class CalculateGrasp(smach.State):
00099     def __init__(self):
00100         smach.State.__init__(self, outcomes=['success','fail','no_ik_solution','all_ik_fail'],
00101                                    input_keys=['best_grasp_pose','sm_pomdp_config'],
00102                                    output_keys=['sm_pomdp_config','grasp_goal'])
00103         self.tf_manager = TransformManager()
00104 
00105     def execute(self, userdata):
00106         # shorcuts
00107         pomdp_config  = userdata.sm_pomdp_config
00108         grasp_pose_st = userdata.best_grasp_pose
00109 
00110         rospy.set_param('/estirabot/skills/grasp/fingers_configuration', pomdp_config.fingers_grasp_configs)
00111 
00112         # grasp_pose_st comes referecence to camera frame_id
00113         # we need to transform the message to wam base frame wam_link0 
00114         grasp_pose_st_wam = self.tf_manager.transform_pose('wam_link0', grasp_pose_st)
00115 
00116         # Orientation is fixed so ignoring previous
00117         grasp_pose_st_wam.pose.orientation.x = 0
00118         grasp_pose_st_wam.pose.orientation.y = 0
00119         grasp_pose_st_wam.pose.orientation.z = 0
00120         grasp_pose_st_wam.pose.orientation.w = 1.0
00121 
00122         pprint("Grasp original")
00123         pub = rospy.Publisher('/debug/grasp/original', PoseStamped, None, False, True)
00124         pub.publish(grasp_pose_st_wam)
00125 
00126         # real grasp is build applying grasp modifier to grasp_pose
00127         current_modifier     = pomdp_config.approach_config.grasp_modifier_used
00128         pprint("Using grasp modifier number: " + str(current_modifier))
00129         real_grasp_st        = PoseStamped()
00130         real_grasp_st.header = grasp_pose_st_wam.header
00131         real_grasp_st.pose   = homogeneous_product_pose_transform(grasp_pose_st_wam.pose,
00132                                                           pomdp_config.approach_config.grasp_modifiers[current_modifier])
00133         if (real_grasp_st.pose.position.z < -0.282):
00134             real_grasp_st.pose.position.z = -0.282
00135 
00136         pprint("Grasp modifier applied")
00137         pub = rospy.Publisher('/debug/grasp/real', PoseStamped, None, False, True)
00138         pub.publish(real_grasp_st)
00139 
00140         # pre-grasp posture is relative to real_grasp pose
00141         pre_grasp_pose_st        = PoseStamped()
00142         pre_grasp_pose_st.header = grasp_pose_st_wam.header
00143 
00144         pre_grasp_pose_st.pose = homogeneous_product_pose_transform(real_grasp_st.pose,
00145                                                           pomdp_config.approach_config.pre_grasp_modifier)
00146         pprint("PRE-Grasp modifier applied")
00147         pub = rospy.Publisher('/debug/grasp/pre_grasp', PoseStamped, None, False, True)
00148         pub.publish(pre_grasp_pose_st)
00149 
00150         # GRASP is Kinematic compliant so save and log the final configuration
00151         pub_config = rospy.Publisher('/log/pomdp_config', PomdpGraspConfig, None, False, True)
00152         pub_config.publish(pomdp_config)
00153 
00154         # For both grasp and pre-grasp we need the inverse kinematics and get joinst positions
00155         try:
00156             joints_grasp     = get_inverse_kinematics_from_pose(real_grasp_st.pose)
00157             joints_pre_grasp = get_inverse_kinematics_from_pose(pre_grasp_pose_st.pose)
00158 
00159         #except NoKinematicSolutionException, e:
00160         except rospy.ServiceException, e:
00161             # Let's go to next grasp_modifier (if any)
00162             if (current_modifier < len(pomdp_config.approach_config.grasp_modifiers)-1):
00163                 # Mark next configuration to use 
00164                 pomdp_config.approach_config.grasp_modifier_used = pomdp_config.approach_config.grasp_modifier_used + 1
00165                 pomdp_config.approach_config.pre_grasp_modifier
00166                 return 'no_ik_solution'
00167             else:
00168                 # all modifiers were tested and are not valid. Return error
00169                 pub = rospy.Publisher('/log/number_of_clothes', Int8, None, False, True)
00170                 pub.publish(0)
00171                 rospy.logerr("Inverse Kinematics has no solution")
00172                 return 'all_ik_fail'
00173 
00174         #     rospy.logerr("WamIK service failed")
00175         #           return 'fail'
00176 
00177         userdata.grasp_goal =  build_simple_pickup_goal(joints_grasp,
00178                                                         joints_pre_grasp,
00179                                                         pomdp_config.fingers_grasp_configs)
00180         return 'success'
00181 
00182 def get_sm_grasp_goal_callback(userdata, default_goal):
00183     return userdata.sm_grasp_goal
00184 
00185 def get_sm_place_goal_callback(userdata, default_goal):
00186     pose_stamped                 = PoseStamped()
00187     pose_stamped.header.frame_id = '/wam_link0'
00188     pose_stamped.header.stamp    = rospy.Time.now()
00189     pose_stamped.pose            = userdata.sm_pomdp_config.place_point
00190 
00191     goal = PlaceGoal()
00192     goal.place_locations.append(userdata.sm_pomdp_config.place_point)
00193 
00194     return goal
00195 
00196 class InputResult(smach.State):
00197     def __init__(self):
00198         smach.State.__init__(self, outcomes=['ok'])
00199 
00200     def execute(self, userdata):
00201         keyserver = GetKeyStroke()
00202         c = -1
00203         print "Press [0-5] for clothes grabbed:"
00204         while ((c < 0) or (c > 5)):
00205             c = keyserver()
00206             try:
00207                 c = int(c)
00208             except ValueError:
00209                 continue
00210 
00211         print "Your value was: " + str(c)
00212         pub = rospy.Publisher('/log/number_of_clothes', Int8, None, False, True)
00213         pub.publish(c)
00214 
00215         return 'ok'
00216 
00217 # Iterator over rounds given a fixed config
00218 def construct_round_iterator_sm():
00219 
00220     factory_home = SM_ESTIRABOT_GoHome()
00221     sm_home = factory_home.build_sm()
00222 
00223     factory_analysis = SM_ESTIRABOT_DeformableAnalysis()
00224     sm_analysis = factory_analysis.build_sm()
00225 
00226     factor_grasp = SM_ESTIRABOT_GenerateGraspMsg()
00227     sm_grasp_generation = factor_grasp.build_sm()
00228 
00229     # 1. START_ROUND state machine
00230     sm_start_round = smach.StateMachine(outcomes=['success','aborted'],
00231                                         input_keys=['sm_pomdp_config'])
00232 
00233     with sm_start_round:
00234         smach.StateMachine.add('PUBLISH_GRASP_ID', PublishGraspID(),
00235                           transitions={'success'   : 'MOVE_TO_HOME_POSITION',
00236                                        'fail'      : 'aborted'})
00237 
00238 
00239         smach.StateMachine.add('MOVE_TO_HOME_POSITION', sm_home,
00240                           transitions={'success'   : 'success',
00241                                        'aborted'   : 'aborted'})
00242 
00243     # 2. CALCULATE_GRASP_POINT state machine
00244     sm_calculate_grasp_point = smach.StateMachine(outcomes=['success','aborted','all_ik_fail'],
00245                                                   input_keys=['sm_pomdp_config'],
00246                                                   output_keys=['sm_grasp_goal'])
00247 
00248     with sm_calculate_grasp_point:
00249         # Get kinect image and process and make analisys
00250         smach.StateMachine.add('GET_KINECT_IMAGE', 
00251                                GetPCL("/estirabot/skills/pcl_distance_filtered"),
00252                 transitions = {'success' : 'PERFORM_ANALISYS',
00253                                'fail'    : 'aborted'},
00254                 remapping   = {'pcl_RGB'         : 'sm_pcl_output'})
00255         smach.StateMachine.add('PERFORM_ANALISYS', sm_analysis,
00256                 transitions = {'success'        : 'CALCULATE_GRASP',
00257                                'fail'           : 'aborted',
00258                                'timeout'        : 'aborted'},
00259                 remapping   = {'deformable_config' : 'sm_pomdp_config', # compatibles
00260                                'pcl_RGB'           : 'sm_pcl_output',
00261                                'best_grasp_pose'   : 'sm_best_grasp_pose'})
00262         smach.StateMachine.add('CALCULATE_GRASP', sm_grasp_generation,
00263                 transitions = {'success'        : 'success',
00264                                'fail'           : 'aborted',
00265                                'no_ik_solution' : 'CALCULATE_GRASP',
00266                                'all_ik_fail'    : 'all_ik_fail'},
00267                 remapping   = {'grasp_pose'         : 'sm_best_grasp_pose',
00268                                'pomdp_grasp_config' : 'sm_pomdp_config',
00269                                'grasp_goal'         : 'sm_grasp_goal'})
00270 
00271     # 3. PICK & LIFT
00272     sm_pick_and_lift = smach.StateMachine(outcomes=['success','aborted'],
00273                                           input_keys=['sm_grasp_goal'])
00274 
00275     with sm_pick_and_lift:
00276         # TODO: endless loop if fail
00277         smach.StateMachine.add('DO_GRASP',
00278                                smach_ros.SimpleActionState('/estirabot/skills/grasp/pickup',
00279                                                           PickupAction,
00280                                                           goal_cb = get_sm_grasp_goal_callback,
00281                                                           input_keys=['sm_grasp_goal']),
00282                                {'succeeded': 'DO_LIFT',
00283                                 'preempted': 'aborted',
00284                                 'aborted'  : 'aborted'})
00285 
00286         smach.StateMachine.add('DO_LIFT', sm_home,
00287                         transitions={'success' : 'success',
00288                                      'aborted' : 'aborted'})
00289     # 4. CHECK
00290     sm_check_result = smach.StateMachine(outcomes=['success'])
00291 
00292     with sm_check_result:
00293         smach.StateMachine.add('INPUT_RESULT', InputResult(),
00294                 transitions = { 'ok' : 'success'})
00295 
00296     # 5. DROP
00297     sm_drop = smach.StateMachine(outcomes=['success','aborted'],
00298                                    input_keys=['sm_pomdp_config'])
00299 
00300     with sm_drop:
00301         smach.StateMachine.add('DO_PLACE',
00302                        smach_ros.SimpleActionState('/estirabot/skills/iri_place/place',
00303                                                   PlaceAction,
00304                                                   goal_cb = get_sm_place_goal_callback,
00305                                                   input_keys=['sm_pomdp_config']),
00306                        {'succeeded': 'success',
00307                         'preempted': 'aborted',
00308                         'aborted'  : 'aborted'})
00309 
00310     # MAIN STATE MACHINE
00311     sm = StateMachine(outcomes = ['continue','aborted'],
00312                       input_keys = ['algorithms','algorithms_index'],
00313                       output_keys = ['algorithms','algorithms_index'])
00314     sm.userdata.rounds = 10
00315 
00316     with sm:
00317         smach.StateMachine.add('CHOOSE_POMDP_CONFIG', HandlePomdpConfig(),
00318             transitions = {'ok':'ROUND_ITERATOR'})
00319 
00320         round_iterator = Iterator(outcomes = ['succeeded','aborted'],
00321                                input_keys = ['sm_pomdp_config'],
00322                                it = range(0, sm.userdata.rounds),
00323                                output_keys = ['sm_pomdp_config'],
00324                                it_label = 'index',
00325                                exhausted_outcome = 'succeeded')
00326         with round_iterator:
00327             container_sm = StateMachine(outcomes = ['succeeded','aborted','continue'],
00328                                         input_keys = ['sm_pomdp_config'],
00329                                         output_keys = ['sm_pomdp_config'])
00330             with container_sm:
00331                 # 1 START ROUND
00332                 smach.StateMachine.add('START_ROUND', sm_start_round,
00333                         transitions={'success': 'CALCULATE_GRASP_POINT',
00334                                      'aborted': 'aborted'})
00335                 # 2 CALCULATE GRASP POINT
00336                 smach.StateMachine.add('CALCULATE_GRASP_POINT', sm_calculate_grasp_point,
00337                         transitions={'success'     : 'PICK_AND_LIFT',
00338                                      'aborted'     : 'aborted',
00339                                      'all_ik_fail' : 'continue'})
00340 
00341                 # 3 PICK AND LIFT
00342                 smach.StateMachine.add('PICK_AND_LIFT', sm_pick_and_lift,
00343                         transitions={'success': 'CHECK_RESULT',
00344                                      'aborted': 'aborted' })
00345                 # 4. CHECK
00346                 smach.StateMachine.add('CHECK_RESULT', sm_check_result,
00347                         transitions = {'success': 'DROP'})
00348 
00349                 # 5. DROP
00350                 smach.StateMachine.add('DROP', sm_drop,
00351                         transitions = {'success': 'continue',
00352                                        'aborted': 'aborted'})
00353 
00354             #close container_sm
00355             Iterator.set_contained_state('CONTAINER_STATE', 
00356                                          container_sm, 
00357                                          loop_outcomes=['continue'])
00358         #close the round_iterator
00359         StateMachine.add('ROUND_ITERATOR',round_iterator,
00360                      {'succeeded':'continue',
00361                       'aborted':'aborted'})
00362     return sm
00363 
00364 # Main iterator to choose algorithms and run each of them
00365 # several times
00366 def construct_alg_iterator_sm():
00367     sm = StateMachine(outcomes = ['succeeded','aborted'], output_keys = ['algorithms_index','algorithms'])
00368     sm.userdata.algorithms_index = 0
00369     sm.userdata.algorithms = [ 1 ]
00370 
00371     sm.userdata.total_algs = len(sm.userdata.algorithms)
00372 
00373     sm_container = construct_round_iterator_sm()
00374 
00375     with sm:
00376         alg_iterator = Iterator(outcomes = ['succeeded','aborted'],
00377                                input_keys = ['algorithms','algorithms_index'],
00378                                it = range(0, sm.userdata.total_algs),
00379                                output_keys = ['algorithms','algorithms_index'],
00380                                it_label = 'index',
00381                                exhausted_outcome = 'succeeded')
00382 
00383         with alg_iterator:
00384             Iterator.set_contained_state('ALG_CONTAINER_STATE',
00385                                     sm_container,
00386                                     loop_outcomes=['continue'])
00387 
00388         smach.StateMachine.add('ALGORITHM_ITERATOR', alg_iterator,
00389                  {'succeeded':'succeeded',
00390                   'aborted':'aborted'})
00391 
00392     return sm
00393 
00394 def main():
00395     rospy.init_node("pomdp_sm")
00396     sm_iterator = construct_alg_iterator_sm()
00397 
00398     # Run state machine introspection server for smach viewer
00399     sis = smach_ros.IntrospectionServer('estirabot_smach_replicable', sm_iterator,
00400                                         '/estirabot_smach_replicable')
00401 
00402     sis.start()
00403 
00404 
00405     outcome = sm_iterator.execute()
00406 
00407     rospy.spin()
00408     sis.stop()
00409 
00410 if __name__ == "__main__":
00411     main()


estirabot_apps
Author(s): Jose Luis Rivero
autogenerated on Fri Dec 6 2013 23:20:59