replicable_create_model.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 dynamic_reconfigure.client
00008 import tf
00009 
00010 from estirabot_common import *
00011 
00012 from smach import StateMachine, CBState, Iterator
00013 from smach_ros import ServiceState
00014 from actionlib import *
00015 from actionlib.msg import *
00016 from std_msgs.msg import String
00017 from object_manipulation_msgs.msg import PickupAction,PickupGoal,PlaceAction,PlaceGoal
00018 from sensor_msgs.msg import PointCloud2, JointState
00019 from iri_deformable_analysis.srv import DoDeformableAnalysis, DoDeformableAnalysisRequest
00020 from iri_dynamixel_gripper.msg import closeAction, openAction
00021 from estirabot_msgs.msg import PomdpGraspConfig
00022 from geometry_msgs.msg import Transform, PoseStamped, Pose, Quaternion
00023 from pprint import pprint
00024 from std_msgs.msg import Int8
00025 
00026 class PerformAnalysis(smach.State):
00027     def __init__(self):
00028         smach.State.__init__(self, outcomes=['success','fail','timeout'],
00029                                    input_keys=['pcl_RGB','descriptors','descriptors_index'],
00030                                    output_keys=['best_grasp_pose'])
00031 
00032     def execute(self, userdata):
00033         # Log the PCL
00034         pub = rospy.Publisher('/debug/pcl_table_scene', PointCloud2,  None, False, True)
00035         pub.publish(userdata.pcl_RGB)
00036 
00037         # Set up the desired descriptor (via param server)
00038         print "Descriptor:"
00039         pprint(userdata.descriptors[userdata.descriptors_index])
00040         client = dynamic_reconfigure.client.Client("/estirabot/skills/deformable_analysis/iri_feature_map")
00041         config = client.update_configuration({ 'selected_centroid' : userdata.descriptors[userdata.descriptors_index]})
00042         #rospy.set_param('/estirabot/skills/deformable_analysis/iri_feature_map/selected_centroid', userdata.descriptors[userdata.descriptors_index])
00043 
00044         pub = rospy.Publisher('/log/descriptor_used', Int8, None, False, True)
00045         pub.publish(userdata.descriptors[userdata.descriptors_index])
00046 
00047 
00048         # Config and launch the deformable analysis
00049         handler = rospy.ServiceProxy('/estirabot/skills/deformable_analysis/do_deformable_analysis',
00050                                      DoDeformableAnalysis)
00051 
00052         analysis_request = DoDeformableAnalysisRequest()
00053         analysis_request.pcl_to_analyze = userdata.pcl_RGB
00054         # TODO: need to fix a fusion criteria (always use 1 = FEATURE MAP)
00055         analysis_request.fusion_criteria_id = 1
00056 
00057         try:
00058             response = handler(analysis_request)
00059 
00060             if (not response):
00061                 return 'fail'
00062 
00063         except rospy.ServiceException, e:
00064             return 'timeout'
00065 
00066         pose_st = response.deformable_analysis.graspability.best_grasp_pose
00067         userdata.best_grasp_pose = pose_st
00068         print("end analysis")
00069 
00070         return 'success'
00071 
00072 class CalculateGrasp(smach.State):
00073     def __init__(self):
00074         smach.State.__init__(self, outcomes=['success','fail','all_ik_fail'],
00075                                    input_keys=['best_grasp_pose','gripper_options','gripper_index'],
00076                                    output_keys=['grasp_goal'])
00077         self.tf_manager = TransformManager()
00078 
00079     def calculate_gripper_orientation(self, userdata):
00080         orientation = Quaternion()
00081 
00082         print "Gripper orientation:"
00083         pprint(userdata.gripper_options[userdata.gripper_index])
00084         pub = rospy.Publisher('/log/gripper_orientation_used', Int8, None, False, True)
00085         pub.publish(userdata.gripper_options[userdata.gripper_index])
00086 
00087         if (userdata.gripper_options[userdata.gripper_index] == 1):
00088             orientation.x = 1.0
00089             orientation.y = 0
00090             orientation.z = 0
00091             orientation.w = 0
00092         elif (userdata.gripper_options[userdata.gripper_index] == 0):
00093             orientation.x = 0.7071
00094             orientation.y = 0.7071
00095             orientation.z = 0
00096             orientation.w = 0
00097         else:
00098             raise ValueError("Gripper option not valid %i", userdata.gripper_options[gripper_index])
00099 
00100         return orientation
00101 
00102 
00103     def execute(self, userdata):
00104         # shorcuts
00105         grasp_pose_st = userdata.best_grasp_pose
00106 
00107         # grasp_pose_st comes referecence to camera frame_id
00108         # we need to transform the message to wam base frame wam_link0 
00109         grasp_pose_st_wam = self.tf_manager.transform_pose('wam_link0', grasp_pose_st)
00110 
00111         #security check
00112         if (grasp_pose_st_wam.pose.position.z < -0.282):
00113             grasp_pose_st_wam.pose.position.z = -0.282
00114 
00115         # Orientation is handling depending of the config
00116         try:
00117             grasp_pose_st_wam.pose.orientation = self.calculate_gripper_orientation(userdata)
00118         except ValueError as e:
00119             rospy.logerr('%s', e.value)
00120             return 'fail'
00121 
00122         #pprint("Grasp original")
00123         #pprint(grasp_pose_st_wam)
00124         pub = rospy.Publisher('/debug/grasp/original', PoseStamped, None, False, True)
00125         pub.publish(grasp_pose_st_wam)
00126 
00127         # For grasp we need the inverse kinematics and get joinst positions
00128         try:
00129             joints_grasp = get_inverse_kinematics_from_pose(grasp_pose_st_wam.pose)
00130 
00131         #except NoKinematicSolutionException, e:
00132         except rospy.ServiceException, e:
00133             pub = rospy.Publisher('/log/number_of_clothes', Int8, None, False, True)
00134             pub.publish(99)
00135             print "Inverse Kinematic failed. Please change the scene and press a key"
00136             raw_input()
00137             return 'all_ik_fail'
00138 
00139         userdata.grasp_goal = grasp_pose_st_wam.pose
00140         return 'success'
00141 
00142 def get_sm_place_goal_callback(userdata, default_goal):
00143     pose_stamped                 = PoseStamped()
00144     pose_stamped.header.frame_id = 'wam_link0'
00145     pose_stamped.header.stamp    = rospy.Time.now()
00146     pose_stamped.pose            = userdata.sm_pomdp_config.place_point
00147 
00148     goal = PlaceGoal()
00149     goal.place_locations.append(pose_stamped)
00150 
00151     return goal
00152 
00153 class LiftAction(smach.State):
00154     def __init__(self):
00155         smach.State.__init__(self, outcomes=['success','aborted'])
00156 
00157     def execute(self, userdata):
00158         return 'success'
00159 
00160 class InputResult(smach.State):
00161     def __init__(self):
00162         smach.State.__init__(self, outcomes=['ok'])
00163 
00164     def execute(self, userdata):
00165         keyserver = GetKeyStroke()
00166         c = -1
00167         print "Press [0-5] for clothes grabbed:"
00168         while ((c < 0) or (c > 5)):
00169             c = keyserver()
00170             try:
00171                 c = int(c)
00172             except ValueError:
00173                 continue
00174 
00175         print "Your value was: " + str(c)
00176         pub = rospy.Publisher('/log/number_of_clothes', Int8, None, False, True)
00177         pub.publish(c)
00178 
00179         return 'ok'
00180 
00181 # Iterator over rounds given a fixed config
00182 def construct_round_iterator_sm():
00183 
00184     # 1. START_ROUND state machine
00185     sm_start_round = smach.StateMachine(outcomes=['success','aborted'])
00186 
00187 
00188     with sm_start_round:
00189         smach.StateMachine.add('MOVE_TO_HOME_POSITION', EstirabotGoHome(),
00190                           transitions={'success': 'WAIT_TO_STABLE_SCENARIO',
00191                                        'fail'   : 'aborted'})
00192 
00193         # Need to wait some seconds to be sure clothes are not in the air after
00194         # a lift action. Otherwise PCL can see them as part os scenario.
00195         smach.StateMachine.add('WAIT_TO_STABLE_SCENARIO', WaitSeconds(2),
00196                           transitions={'finish': 'success'})
00197 
00198 
00199     # 2. CALCULATE_GRASP_POINT state machine
00200     sm_calculate_grasp_point = smach.StateMachine(outcomes = ['success','aborted','all_ik_fail' ],
00201                          input_keys  = ['descriptors', 'descriptors_index', 'gripper_options', 'gripper_index'],
00202                          output_keys = ['sm_grasp_goal'])
00203 
00204     with sm_calculate_grasp_point:
00205         # Get kinect image and process and make analisys
00206         smach.StateMachine.add('GET_KINECT_IMAGE', EstirabotGetPCL("/estirabot/skills/pcl_distance_filtered"),
00207                 transitions = {'success' : 'PERFORM_ANALISYS',
00208                                'fail'    : 'aborted'},
00209                 remapping   = {'pcl_RGB'         : 'sm_pcl_output'})
00210         smach.StateMachine.add('PERFORM_ANALISYS', PerformAnalysis(),
00211                 transitions = {'success'        : 'CALCULATE_GRASP',
00212                                'fail'           : 'aborted',
00213                                'timeout'        : 'aborted'},
00214                 remapping   = {'pcl_RGB'         : 'sm_pcl_output',
00215                                'best_grasp_pose' : 'sm_best_grasp_pose'})
00216         smach.StateMachine.add('CALCULATE_GRASP', CalculateGrasp(),
00217                 transitions = {'success'        : 'success',
00218                                'fail'           : 'aborted',
00219                                'all_ik_fail'    : 'all_ik_fail'},
00220                 remapping   = {'pcl_RGB'         : 'sm_pcl_output',
00221                                'best_grasp_pose' : 'sm_best_grasp_pose',
00222                                'grasp_goal'      : 'sm_grasp_goal'})
00223 
00224     # 3. PICK & LIFT
00225     sm_pick_and_lift = smach.StateMachine(outcomes=['success','aborted'],
00226                                           input_keys=['sm_grasp_goal'])
00227 
00228     with sm_pick_and_lift:
00229         smach.StateMachine.add('DO_MOVE_TO_GRASP', EstirabotCartesianMove(),
00230                  transitions = {'success'        : 'DO_CLOSE_GRIPPER',
00231                                 'fail'           : 'aborted'},
00232                  remapping   = {'goal'           : 'sm_grasp_goal'})
00233 
00234         smach.StateMachine.add('DO_CLOSE_GRIPPER',
00235                            smach_ros.SimpleActionState('/estirabot/gripper/close_action_',
00236                                closeAction),
00237                            {'succeeded' : 'DO_LIFT',
00238                             'preempted' : 'aborted',
00239                             'aborted'   : 'WAIT_TO_GRIPPER_FOR_CLOSE'})
00240 
00241         smach.StateMachine.add('WAIT_TO_GRIPPER_FOR_CLOSE', WaitSeconds(20),
00242                           transitions={'finish': 'DO_CLOSE_GRIPPER'})
00243 
00244         smach.StateMachine.add('DO_LIFT', EstirabotGoHome(),
00245                         transitions={'success' : 'success',
00246                                      'fail'    : 'aborted'})
00247     # 4. CHECK
00248     sm_check_result = smach.StateMachine(outcomes=['success'])
00249 
00250     with sm_check_result:
00251         smach.StateMachine.add('INPUT_RESULT', InputResult(),
00252                 transitions = { 'ok' : 'success'})
00253 
00254     # 5. DROP
00255     sm_drop = smach.StateMachine(outcomes=['success','aborted'])
00256 
00257     with sm_drop:
00258         # TODO: move to place position need new state <------ 
00259 
00260         smach.StateMachine.add('DO_PLACE',
00261                        smach_ros.SimpleActionState('/estirabot/gripper/open_action_',
00262                                                   openAction),
00263                        {'succeeded': 'success',
00264                         'preempted': 'aborted',
00265                         'aborted'  : 'WAIT_TO_GRIPPER_FOR_OPEN'})
00266 
00267         smach.StateMachine.add('WAIT_TO_GRIPPER_FOR_OPEN', WaitSeconds(8),
00268                 transitions={'finish': 'DO_PLACE'})
00269 
00270     # MAIN STATE MACHINE
00271     sm = StateMachine(outcomes = ['continue','aborted'],
00272                       input_keys  = ['descriptors','descriptors_index','gripper_options','gripper_index'],
00273                       output_keys = ['descriptors','descriptors_index','gripper_options','gripper_index'])
00274     sm.userdata.rounds = 10
00275 
00276     with sm:
00277 
00278         round_iterator = Iterator(outcomes = ['succeeded','aborted'],
00279                             input_keys  = ['descriptors','descriptors_index','gripper_options','gripper_index'],
00280                             it = range(0, sm.userdata.rounds),
00281                             output_keys = ['descriptors','descriptors_index','gripper_options','gripper_index'],
00282                             it_label = 'round_index',
00283                             exhausted_outcome = 'succeeded')
00284 
00285         with round_iterator:
00286             container_sm = StateMachine(outcomes = ['succeeded','aborted','continue'],
00287                 input_keys = ['round_index','descriptors','descriptors_index','gripper_options','gripper_index'],
00288                 output_keys = ['round_index','descriptors','descriptors_index','gripper_options','gripper_index'])
00289 
00290             with container_sm:
00291                 # 1 START ROUND
00292                 smach.StateMachine.add('START_ROUND', sm_start_round,
00293                         transitions={'success': 'CALCULATE_GRASP_POINT',
00294                                      'aborted': 'aborted'})
00295 
00296                 # 2 CALCULATE GRASP POINT
00297                 smach.StateMachine.add('CALCULATE_GRASP_POINT', sm_calculate_grasp_point,
00298                         transitions={'success'     : 'PICK_AND_LIFT',
00299                                      'aborted'     : 'aborted',
00300                                      'all_ik_fail' : 'continue'})
00301 
00302                 # 3 PICK AND LIFT
00303                 smach.StateMachine.add('PICK_AND_LIFT', sm_pick_and_lift,
00304                         transitions={'success': 'CHECK_RESULT',
00305                                      'aborted': 'aborted' })
00306                 # 4. CHECK
00307                 smach.StateMachine.add('CHECK_RESULT', sm_check_result,
00308                         transitions = {'success': 'DROP'})
00309 
00310                 # 5. DROP
00311                 smach.StateMachine.add('DROP', sm_drop,
00312                         transitions = {'success': 'continue',
00313                                        'aborted': 'aborted'})
00314 
00315             #close container_sm
00316             Iterator.set_contained_state('CONTAINER_STATE', 
00317                                          container_sm, 
00318                                          loop_outcomes=['continue'])
00319         #close the round_iterator
00320         StateMachine.add('ROUND_ITERATOR',round_iterator,
00321                      {'succeeded':'continue',
00322                       'aborted':'aborted'})
00323     return sm
00324 
00325 # Iterator to choose between gripper configuration
00326 def construct_gripper_orientation_iterator_sm():
00327     sm = StateMachine(outcomes    = ['continue','aborted'], 
00328                       input_keys  = ['descriptors','descriptors_index'],
00329                       output_keys = ['gripper_options','gripper_index','descriptors','descriptors_index'])
00330 
00331     #sm.userdata.gripper_options = [ 0, 1 ]
00332     sm.userdata.gripper_options = [ 0 ]
00333 
00334     sm.userdata.total_options = len(sm.userdata.gripper_options)
00335 
00336     sm_container = construct_round_iterator_sm()
00337 
00338     with sm:
00339         gripper_iterator = Iterator(outcomes = ['succeeded','aborted'],
00340                                input_keys = ['gripper_options','descriptors','descriptors_index'],
00341                                it = range(0, sm.userdata.total_options),
00342                                output_keys = ['gripper_options', 'gripper_index', 'descriptors','descriptors_index'],
00343                                it_label = 'gripper_index',
00344                                exhausted_outcome = 'succeeded')
00345 
00346         with gripper_iterator:
00347             Iterator.set_contained_state('GRIPPER_CONTAINER_STATE',
00348                                     sm_container,
00349                                     loop_outcomes=['continue'])
00350 
00351         smach.StateMachine.add('GRIPPER_ITERATOR', gripper_iterator,
00352                  {'succeeded':'continue',
00353                   'aborted':'aborted'})
00354 
00355     return sm
00356 
00357 # Iterator to round over descriptor iterators
00358 def construct_descriptors_iterator_sm():
00359     sm = StateMachine(outcomes  = ['succeeded','aborted'],
00360                                    output_keys = ['descriptors','descriptors_index'])
00361     # sm.userdata.descriptors = [ 11, 14, 15, 16, 22 ]
00362     sm.userdata.descriptors = [ 11 ]
00363     sm.userdata.total_descriptors = len(sm.userdata.descriptors)
00364 
00365     sm_container = construct_gripper_orientation_iterator_sm()
00366 
00367     with sm:
00368         descriptor_iterator = Iterator(outcomes = ['succeeded','aborted'],
00369                                input_keys = ['descriptors'],
00370                                it = range(0, sm.userdata.total_descriptors),
00371                                output_keys = ['descriptors','descriptors_index'],
00372                                it_label = 'descriptors_index',
00373                                exhausted_outcome = 'succeeded')
00374 
00375         with descriptor_iterator:
00376             Iterator.set_contained_state('DESCRIPTOR_CONTAINER_STATE',
00377                                     sm_container,
00378                                     loop_outcomes=['continue'])
00379 
00380         smach.StateMachine.add('DESCRIPTOR_ITERATOR', descriptor_iterator,
00381                  {'succeeded':'succeeded',
00382                   'aborted':'aborted'})
00383 
00384     return sm
00385 
00386 
00387 def main():
00388     rospy.init_node("pomdp_sm")
00389     sm_iterator = construct_descriptors_iterator_sm()
00390 
00391     # Run state machine introspection server for smach viewer
00392     sis = smach_ros.IntrospectionServer('estirabot_smach_replicable', sm_iterator,
00393                                         '/estirabot_smach_replicable')
00394 
00395     sis.start()
00396 
00397 
00398     outcome = sm_iterator.execute()
00399 
00400     rospy.spin()
00401     sis.stop()
00402 
00403 if __name__ == "__main__":
00404     main()


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