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 random
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, Int8, Int32
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 estirabot_msgs.srv import obs2action, obs2actionRequest
00020 from geometry_msgs.msg import Transform, PoseStamped, Pose
00021 from pprint import pprint
00022
00023 from iri_common_smach.st_get_pcl import GetPCL
00024 from iri_common_smach.utils_msg import build_pose_stamped_msg
00025 from iri_common_smach.get_keystroke import GetKeyStroke
00026 from iri_common_smach.homogeneous_product import homogeneous_product_pose_transform
00027 from iri_common_smach.st_topic_publisher import TopicPublisher
00028 from iri_wam_smach.sm_wam_move_from_pose import SM_WAM_MoveFromPose
00029
00030 from estirabot_apps_base.utils_pomdp import PomdpConfigFactory, TranslatePomdp
00031 from estirabot_apps_base.sm_move import SM_ESTIRABOT_GoHome
00032 from estirabot_apps_base.sm_deformable_analysis import SM_ESTIRABOT_DeformableAnalysis
00033 from estirabot_apps_base.sm_generate_grasp import SM_ESTIRABOT_GenerateGraspMsg
00034 from TranslatePomdp2piles import TranslatePomdp
00035
00036 class ExperimentData():
00037 def __init__(self):
00038
00039
00040 self.iteration_number = 0
00041
00042 self.algorithms = [ 1, 1, 1, 1, 1, 1,
00043 1, 1, 1, 1, 1, 1,
00044 1, 1, 1, 1, 1, 1,
00045 1, 1, 1]
00046
00047
00048
00049
00050
00051 self.algorithms_index_list = []
00052 self.total_algs = len(self.algorithms)
00053
00054
00055 self.numrounds = 10
00056 for i in range(self.numrounds):
00057 self.algorithms_index_list.extend(range(self.total_algs))
00058 random.shuffle(self.algorithms_index_list)
00059
00060
00061 print(self.algorithms_index_list)
00062 self.numexperiments = len(self.algorithms_index_list)
00063
00064
00065 class InputResult(smach.State):
00066 def __init__(self):
00067 smach.State.__init__(self, outcomes=['success'])
00068
00069 def execute(self, userdata):
00070 keyserver = GetKeyStroke()
00071 c = -1
00072 print "Press [0-5] for clothes grabbed, 9 for error:"
00073 while (c < 0):
00074 c = keyserver()
00075 try:
00076 c = int(c)
00077 except ValueError:
00078 print "Error. Press [0-5] for clothes grabbed:"
00079 continue
00080
00081 print "Your value was: " + str(c)
00082 pub = rospy.Publisher('/log/number_of_clothes', Int8, None, False, True)
00083 pub.publish(c)
00084
00085 return 'success'
00086
00087 class PlaceHandler():
00088 def __init__(self):
00089 self.next_left_zone = 1
00090 self.next_right_zone = 1
00091
00092 def calculate_place_pose(self, pomdp_config):
00093
00094 if (pomdp_config.place_point == None):
00095 return self.get_basket_pose_st()
00096
00097
00098 if (pomdp_config.grabbing_zone == pomdp_config.LEFT_ZONE):
00099 return self.get_left_place_pose()
00100 elif (pomdp_config.grabbing_zone == pomdp_config.RIGHT_ZONE):
00101 return self.get_right_place_pose()
00102 else:
00103 rospy.logerr("Value for graspping zone is not LEFT or RIGHT")
00104 return build_home_pose()
00105
00106 def get_basket_pose_st(self):
00107 return build_pose_stamped_msg('/wam_link0', -0.165, 0.514, -0.188, 1, 0, 0, 0)
00108
00109 def get_right_place_pose(self):
00110 if (self.next_right_zone == 1):
00111 pose = build_pose_stamped_msg('/wam_link0', 0.422, -0.390, -0.234, 1, 0, 0, 0)
00112 elif (self.next_right_zone == 2):
00113 pose = build_pose_stamped_msg('/wam_link0',0.584, -0.390, -0.234, 1, 0, 0, 0)
00114 elif (self.next_right_zone == 3):
00115 pose = build_pose_stamped_msg('/wam_link0',0.633, -0.160, -0.234, 1, 0, 0, 0)
00116 elif (self.next_right_zone == 4):
00117 pose = build_pose_stamped_msg('/wam_link0',0.476, -0.160, -0.234, 1, 0, 0, 0)
00118 else:
00119 rospy.logerr("Righ pose next zone is out of range: " + str(self.next_right_zone))
00120
00121 self.next_right_zone = self.next_right_zone + 1
00122
00123
00124 if (self.next_right_zone > 4):
00125 self.next_right_zone = 1
00126
00127 return pose
00128
00129 def get_left_place_pose(self):
00130 if (self.next_left_zone == 1):
00131 pose = build_pose_stamped_msg('/wam_link0',0.422, 0.390, -0.234, 1, 0, 0, 0)
00132 elif (self.next_left_zone == 2):
00133 pose = build_pose_stamped_msg('/wam_link0',0.584, 0.390, -0.234, 1, 0, 0, 0)
00134 elif (self.next_left_zone == 3):
00135 pose = build_pose_stamped_msg('/wam_link0',0.633, 0.160, -0.234, 1, 0, 0, 0)
00136 elif (self.next_left_zone == 4):
00137 pose = build_pose_stamped_msg('/wam_link0',0.476, 0.160, -0.234, 1, 0, 0, 0)
00138 else:
00139 rospy.logerr("Left pose next zone is out of range: " + str(self.next_left_zone))
00140
00141 self.next_left_zone = self.next_left_zone + 1
00142
00143
00144 if (self.next_left_zone > 4):
00145 self.next_left_zone = 1
00146
00147 return pose
00148
00149 class FirstAction(smach.State):
00150 def __init__(self):
00151 smach.State.__init__(self, outcomes = ['ok','fail'],
00152 output_keys = ['pomdp_action','place_handler'])
00153
00154 def execute(self, userdata):
00155
00156
00157 randaction = random.randint(0,userdata.total_algs)
00158 print("initial random action: " % randaction)
00159 userdata.pomdp_action = randaction
00160 pub = rospy.Publisher('/log/pomdp/action', Int8, None, False, True)
00161 pub.publish(response.action)
00162
00163 if (not response):
00164 return 'fail'
00165
00166
00167 userdata.place_handler = PlaceHandler()
00168
00169 return 'ok'
00170
00171 class CountObjects(smach.State):
00172 def __init__(self):
00173 smach.State.__init__(self, outcomes = ['fail','success'],
00174 input_keys = ['sm_pcl_table_left','sm_pcl_table_right'],
00175 output_keys = ['left_objects','right_objects'])
00176 self.number = -1
00177
00178 sub = rospy.Subscriber("/estirabot/skills/iri_textile_count/num_objects_found",
00179 Int32, self.recieve_number)
00180
00181 def execute(self, userdata):
00182
00183 self.calculate_objects(userdata.sm_pcl_table_left)
00184 userdata.left_objects = self.number
00185 pprint ("Left objects: " + str(self.number))
00186 pub = rospy.Publisher('/debug/observation/left_objects', Int8, None, False, True)
00187 pub.publish(self.number)
00188
00189
00190 rospy.sleep(2)
00191
00192
00193 self.calculate_objects(userdata.sm_pcl_table_right)
00194 userdata.right_objects = self.number
00195 pprint ("Right objects: " + str(self.number))
00196 pub = rospy.Publisher('/debug/observation/right_objects', Int8, None, False, True)
00197 pub.publish(self.number)
00198
00199 return 'success'
00200
00201 def recieve_number(self, data):
00202 self.number = data.data
00203
00204 def calculate_objects(self, pcl):
00205 self.number = -1
00206
00207 pub = rospy.Publisher('/estirabot/skills/table/pcl', PointCloud2, None, False, True)
00208 pub.publish(pcl)
00209
00210 while (self.number == -1 and (not rospy.is_shutdown())):
00211 pprint("waiting")
00212 time.sleep(.1)
00213
00214 class PrePlaceCalculation(smach.State):
00215 def __init__(self):
00216 smach.State.__init__(self, outcomes = ['finish'],
00217 input_keys = ['sm_pomdp_config'],
00218 output_keys = ['pre_pose_st'])
00219
00220 def execute(self, userdata):
00221 tf = Transform()
00222 tf.translation.z = -0.4
00223
00224 pre_pose_st = PoseStamped()
00225 pre_pose_st.header.frame_id = '/wam_link0'
00226 pre_pose_st.header.stamp = rospy.Time.now()
00227 pre_pose_st.pose = homogeneous_product_pose_transform(
00228 userdata.sm_pomdp_config.place_point.pose, tf)
00229
00230 userdata.pre_pose_st = pre_pose_st
00231 return 'finish'
00232
00233 class GetNextAction(smach.State):
00234 def __init__(self):
00235 smach.State.__init__(self, outcomes = ['fail','finish','continue'],
00236 input_keys = ['experiment_data'],
00237 output_keys = ['pomdp_action', 'experiment_data'])
00238
00239
00240 def execute(self, userdata):
00241
00242
00243 pprint("iteration number = %d" % userdata.experiment_data.iteration_number)
00244 userdata.experiment_data.iteration_number += 1
00245 if (userdata.experiment_data.iteration_number == userdata.experiment_data.numexperiments):
00246 return 'finish'
00247 action = userdata.experiment_data.algorithms_index_list[userdata.experiment_data.iteration_number]
00248
00249
00250 pub = rospy.Publisher('/log/pomdp/action', Int8, None, False, True)
00251 pub.publish(action)
00252 userdata.pomdp_action = action
00253 return 'continue'
00254
00255 def get_sm_grasp_goal_callback(userdata, default_goal):
00256 return userdata.sm_grasp_goal
00257
00258 def get_sm_place_goal_callback(userdata, default_goal):
00259 goal = PlaceGoal()
00260 goal.place_locations.append(userdata.sm_pomdp_config.place_point)
00261
00262 return goal
00263
00264 def construct_main_sm():
00265 sm = StateMachine(outcomes = ['succeeded','aborted'])
00266
00267 factory_home = SM_ESTIRABOT_GoHome()
00268 sm_home = factory_home.build_sm()
00269
00270 factory_analysis = SM_ESTIRABOT_DeformableAnalysis()
00271 sm_analysis = factory_analysis.build_sm()
00272
00273 factory_grasp = SM_ESTIRABOT_GenerateGraspMsg()
00274 sm_grasp_generation = factory_grasp.build_sm()
00275
00276 factory_move = SM_WAM_MoveFromPose('/estirabot/wam_wrapper/joints_move',
00277 '/estirabot/iri_wam_tcp_ik/get_wam_ik')
00278 sm_move = factory_move.build_sm()
00279
00280
00281 sm.userdata.experiment_data = ExperimentData()
00282
00283 sm.userdata.place_handler = PlaceHandler()
00284
00285 with sm:
00286 smach.StateMachine.add('START_ROUND', sm_home,
00287 transitions={'success' : 'LOG_PCL',
00288 'aborted' : 'aborted'})
00289 smach.StateMachine.add('LOG_PCL',
00290 GetPCL("/estirabot/ceiling_kinect/camera/rgb/points"),
00291 transitions = {'success' : 'LOG_IMAGE',
00292 'fail' : 'aborted'},
00293 remapping = {'pcl_RGB' : 'sm_pcl_to_log'})
00294 smach.StateMachine.add('LOG_IMAGE',
00295 TopicPublisher('/log/pcl_table', PointCloud2),
00296 transitions={'finish': 'GET_NEXT_ACTION'},
00297 remapping = {'msg' : 'sm_pcl_to_log'})
00298
00299
00300 smach.StateMachine.add('GET_NEXT_ACTION', GetNextAction(),
00301 transitions={'continue' : 'TRANSLATE_POMDP_ACTION',
00302 'finish' : 'succeeded',
00303 'fail' : 'aborted'})
00304
00305
00306 smach.StateMachine.add('TRANSLATE_POMDP_ACTION', TranslatePomdp(),
00307 transitions = { 'image_from_left' : 'GET_KINECT_IMAGE_FROM_LEFT',
00308 'image_from_right' : 'GET_KINECT_IMAGE_FROM_RIGHT',
00309 'fail':'aborted'},
00310 remapping = { 'sm_pomdp_config' : 'sm_pomdp_config'})
00311
00312
00313
00314 smach.StateMachine.add('GET_KINECT_IMAGE_FROM_LEFT',
00315 GetPCL("/estirabot/skills/table/left/pcl"),
00316 transitions = {'success' : 'PERFORM_ANALISYS',
00317 'fail' : 'aborted'},
00318 remapping = {'pcl_RGB' : 'sm_pcl_output'})
00319
00320
00321 smach.StateMachine.add('GET_KINECT_IMAGE_FROM_RIGHT',
00322 GetPCL("/estirabot/skills/table/right/pcl"),
00323 transitions = {'success' : 'PERFORM_ANALISYS',
00324 'fail' : 'aborted'},
00325 remapping = {'pcl_RGB' : 'sm_pcl_output'})
00326
00327
00328 smach.StateMachine.add('PERFORM_ANALISYS', sm_analysis,
00329 transitions = {'success' : 'CALCULATE_GRASP',
00330 'timeout' : 'PERFORM_ANALISYS',
00331 'fail' : 'aborted'},
00332 remapping = {'deformable_config' : 'sm_pomdp_config',
00333 'pcl_RGB' : 'sm_pcl_output',
00334 'best_grasp_pose' : 'sm_best_grasp_pose'})
00335
00336 smach.StateMachine.add('CALCULATE_GRASP', sm_grasp_generation,
00337 transitions = {'success' : 'DO_GRASP',
00338 'no_ik_solution' : 'CALCULATE_GRASP',
00339 'fail' : 'aborted',
00340 'all_ik_fail' : 'GET_TABLE_IMAGE_FROM_LEFT'},
00341 remapping = {'pomdp_grasp_config' : 'sm_pomdp_config',
00342 'grasp_pose' : 'sm_best_grasp_pose',
00343 'grasp_goal' : 'sm_grasp_goal'})
00344
00345 smach.StateMachine.add('DO_GRASP',
00346 smach_ros.SimpleActionState('/estirabot/skills/grasp/pickup',
00347 PickupAction,
00348 goal_cb = get_sm_grasp_goal_callback,
00349 input_keys=['sm_grasp_goal']),
00350 {'succeeded': 'DO_LIFT',
00351 'preempted': 'aborted',
00352 'aborted' : 'aborted'})
00353
00354 smach.StateMachine.add('DO_LIFT', sm_home,
00355 transitions={'success' : 'CHECK_GRASP',
00356 'aborted' : 'aborted'})
00357
00358 smach.StateMachine.add('CHECK_GRASP', InputResult(),
00359 transitions={'success' : 'CALCULATE_PRE_PLACE'})
00360
00361
00362 smach.StateMachine.add('CALCULATE_PRE_PLACE', PrePlaceCalculation(),
00363 transitions={'finish' : 'MOVE_TO_PRE_PLACE'},
00364 remapping={'pre_pose_st':'sm_pre_pose_st'})
00365
00366 smach.StateMachine.add('MOVE_TO_PRE_PLACE', sm_move,
00367 transitions={'success' : 'DO_PLACE',
00368 'aborted' : 'aborted',
00369 'no_kinematic_solution' : 'DO_PLACE'},
00370 remapping={'pose_st':'sm_pre_pose_st'})
00371
00372
00373 smach.StateMachine.add('DO_PLACE',
00374 smach_ros.SimpleActionState('/estirabot/skills/iri_place/place',
00375 PlaceAction,
00376 goal_cb = get_sm_place_goal_callback,
00377 input_keys=['sm_pomdp_config']),
00378 {'succeeded': 'BACK_TO_HOME',
00379 'preempted': 'aborted',
00380 'aborted' : 'aborted'})
00381
00382 smach.StateMachine.add('BACK_TO_HOME', sm_home,
00383 transitions={'success' : 'GET_TABLE_IMAGE_FROM_LEFT',
00384 'aborted' : 'aborted'})
00385
00386
00387
00388 smach.StateMachine.add('GET_TABLE_IMAGE_FROM_LEFT',
00389 GetPCL("/estirabot/skills/table/left/pcl"),
00390 transitions = {'success' : 'GET_TABLE_IMAGE_FROM_RIGHT',
00391 'fail' : 'aborted'},
00392 remapping = {'pcl_RGB' : 'sm_pcl_table_left'})
00393
00394 smach.StateMachine.add('GET_TABLE_IMAGE_FROM_RIGHT',
00395 GetPCL("/estirabot/skills/table/right/pcl"),
00396 transitions = {'success' : 'COUNT_OBJECTS',
00397 'fail' : 'aborted'},
00398 remapping = {'pcl_RGB' : 'sm_pcl_table_right'})
00399
00400 smach.StateMachine.add('COUNT_OBJECTS', CountObjects(),
00401 transitions={'success' : 'START_ROUND',
00402 'fail' : 'aborted'})
00403
00404 return sm
00405
00406 def main():
00407 rospy.init_node("pomdp_sm")
00408 sm_main = construct_main_sm()
00409
00410
00411 sis = smach_ros.IntrospectionServer('estirabot_smach_replicable', sm_main,
00412 '/estirabot_smach_replicable')
00413
00414 sis.start()
00415
00416 outcome = sm_main.execute()
00417
00418 rospy.spin()
00419 sis.stop()
00420
00421 if __name__ == "__main__":
00422 main()