00001
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
00041
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
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
00072 pub = rospy.Publisher('/log/pcl_table_scene', PointCloud2, None, False, True)
00073
00074
00075
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
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
00113
00114 grasp_pose_st_wam = self.tf_manager.transform_pose('wam_link0', grasp_pose_st)
00115
00116
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
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
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
00151 pub_config = rospy.Publisher('/log/pomdp_config', PomdpGraspConfig, None, False, True)
00152 pub_config.publish(pomdp_config)
00153
00154
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
00160 except rospy.ServiceException, e:
00161
00162 if (current_modifier < len(pomdp_config.approach_config.grasp_modifiers)-1):
00163
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
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
00175
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
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
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
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
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',
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
00272 sm_pick_and_lift = smach.StateMachine(outcomes=['success','aborted'],
00273 input_keys=['sm_grasp_goal'])
00274
00275 with sm_pick_and_lift:
00276
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
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
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
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
00332 smach.StateMachine.add('START_ROUND', sm_start_round,
00333 transitions={'success': 'CALCULATE_GRASP_POINT',
00334 'aborted': 'aborted'})
00335
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
00342 smach.StateMachine.add('PICK_AND_LIFT', sm_pick_and_lift,
00343 transitions={'success': 'CHECK_RESULT',
00344 'aborted': 'aborted' })
00345
00346 smach.StateMachine.add('CHECK_RESULT', sm_check_result,
00347 transitions = {'success': 'DROP'})
00348
00349
00350 smach.StateMachine.add('DROP', sm_drop,
00351 transitions = {'success': 'continue',
00352 'aborted': 'aborted'})
00353
00354
00355 Iterator.set_contained_state('CONTAINER_STATE',
00356 container_sm,
00357 loop_outcomes=['continue'])
00358
00359 StateMachine.add('ROUND_ITERATOR',round_iterator,
00360 {'succeeded':'continue',
00361 'aborted':'aborted'})
00362 return sm
00363
00364
00365
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
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()