00001
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
00034 pub = rospy.Publisher('/debug/pcl_table_scene', PointCloud2, None, False, True)
00035 pub.publish(userdata.pcl_RGB)
00036
00037
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
00043
00044 pub = rospy.Publisher('/log/descriptor_used', Int8, None, False, True)
00045 pub.publish(userdata.descriptors[userdata.descriptors_index])
00046
00047
00048
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
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
00105 grasp_pose_st = userdata.best_grasp_pose
00106
00107
00108
00109 grasp_pose_st_wam = self.tf_manager.transform_pose('wam_link0', grasp_pose_st)
00110
00111
00112 if (grasp_pose_st_wam.pose.position.z < -0.282):
00113 grasp_pose_st_wam.pose.position.z = -0.282
00114
00115
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
00123
00124 pub = rospy.Publisher('/debug/grasp/original', PoseStamped, None, False, True)
00125 pub.publish(grasp_pose_st_wam)
00126
00127
00128 try:
00129 joints_grasp = get_inverse_kinematics_from_pose(grasp_pose_st_wam.pose)
00130
00131
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
00182 def construct_round_iterator_sm():
00183
00184
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
00194
00195 smach.StateMachine.add('WAIT_TO_STABLE_SCENARIO', WaitSeconds(2),
00196 transitions={'finish': 'success'})
00197
00198
00199
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
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
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
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
00255 sm_drop = smach.StateMachine(outcomes=['success','aborted'])
00256
00257 with sm_drop:
00258
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
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
00292 smach.StateMachine.add('START_ROUND', sm_start_round,
00293 transitions={'success': 'CALCULATE_GRASP_POINT',
00294 'aborted': 'aborted'})
00295
00296
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
00303 smach.StateMachine.add('PICK_AND_LIFT', sm_pick_and_lift,
00304 transitions={'success': 'CHECK_RESULT',
00305 'aborted': 'aborted' })
00306
00307 smach.StateMachine.add('CHECK_RESULT', sm_check_result,
00308 transitions = {'success': 'DROP'})
00309
00310
00311 smach.StateMachine.add('DROP', sm_drop,
00312 transitions = {'success': 'continue',
00313 'aborted': 'aborted'})
00314
00315
00316 Iterator.set_contained_state('CONTAINER_STATE',
00317 container_sm,
00318 loop_outcomes=['continue'])
00319
00320 StateMachine.add('ROUND_ITERATOR',round_iterator,
00321 {'succeeded':'continue',
00322 'aborted':'aborted'})
00323 return sm
00324
00325
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
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
00358 def construct_descriptors_iterator_sm():
00359 sm = StateMachine(outcomes = ['succeeded','aborted'],
00360 output_keys = ['descriptors','descriptors_index'])
00361
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
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()