00001
00002
00003
00004 import roslib; roslib.load_manifest('iri_clean_board')
00005 import rospy
00006 import smach
00007 import smach_ros
00008
00009 from smach_ros import SimpleActionState
00010 from smach_ros import ServiceState
00011
00012 from actionlib import *
00013 from actionlib.msg import *
00014
00015 from iri_common_smach import st_sleep
00016
00017 from iri_clean_board.srv import *
00018 from estirabot_msgs.msg import *
00019 from estirabot_msgs.srv import *
00020 from iri_planning_msgs.srv import *
00021
00022 class NeedInfo(smach.State):
00023 def __init__(self):
00024 smach.State.__init__(self, outcomes=['next','failed'])
00025 self.counter = 0
00026
00027 def execute(self, userdata):
00028 rospy.logdebug('Executing state NeedInfo')
00029 return 'next'
00030
00031
00032 class GetInfoCamera(smach.State):
00033 def __init__(self):
00034 smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'],
00035 input_keys=[],
00036 output_keys=['segmented_image', 'pointcloud', 'plane_coefficients'])
00037 self.service_topic = '/iri_clean_perception/get_board_information/get_board_info_srv'
00038
00039 def execute(self, userdata):
00040 rospy.logdebug('Executing state GetInfoCamera')
00041 start_timer = time.time()
00042
00043 rospy.wait_for_service(self.service_topic)
00044 try:
00045 get_service = rospy.ServiceProxy(self.service_topic, BoardInfo)
00046 resp = get_service()
00047
00048 userdata.segmented_image = resp.segmented_image
00049 userdata.pointcloud = resp.pointcloud
00050 userdata.plane_coefficients = resp.plane_coefficients
00051
00052 stop_timer = time.time()
00053 global time_perception
00054 time_perception = time_perception + (stop_timer - start_timer)
00055 return 'succeeded'
00056
00057 except rospy.ServiceException, e:
00058 print "Service call failed: %s"%e
00059 return 'aborted'
00060
00061
00062 class PradaPlanning(smach.State):
00063 def __init__(self):
00064 smach.State.__init__(self, outcomes=['succeeded','preempted','aborted','no_plan'],
00065 input_keys=['rules_updated_sm'],
00066 output_keys=['target_ellipses','actions'])
00067 self.service_topic = '/iri_clean_plan/prada_planner/getBestAction'
00068
00069 def execute(self, userdata):
00070 rospy.logdebug('Executing state PradaPlanning')
00071
00072 start_timer = time.time()
00073 rospy.wait_for_service(self.service_topic)
00074 try:
00075 get_cleaning_plan = rospy.ServiceProxy(self.service_topic, PradaPlanSrv)
00076 resp = get_cleaning_plan(userdata.rules_updated_sm)
00077
00078 stop_timer = time.time()
00079 global time_planning
00080 time_planning = time_planning + (stop_timer - start_timer)
00081
00082 if resp.succeeded:
00083 userdata.target_ellipses = resp.target_ellipses
00084 userdata.actions = resp.actions
00085 return 'succeeded'
00086 else:
00087 return 'no_plan'
00088
00089 except rospy.ServiceException, e:
00090 print "Service call failed: %s"%e
00091 return 'aborted'
00092
00093
00094 class CalculateTrajectories(smach.State):
00095 def __init__(self):
00096 smach.State.__init__(self, outcomes=['succeeded','preempted','aborted','no_movements'],
00097 input_keys=['target_ellipses_sm','actions_sm','ellipses_sm','segmented_pointcloud_sm','plane_coefficients_sm'],
00098 output_keys=['poses','poses_2d_coordinates','secondary_arm'])
00099 self.service_topic = '/iri_clean_plan/cleaning_plan/get_trajectories_from_plan'
00100
00101 def execute(self, userdata):
00102 rospy.logdebug('Executing state CalculateTrajectories')
00103 start_timer = time.time()
00104 rospy.wait_for_service(self.service_topic)
00105 try:
00106 get_cleaning_plan = rospy.ServiceProxy(self.service_topic, PlanToTrajectories)
00107 resp = get_cleaning_plan(userdata.segmented_pointcloud_sm, userdata.plane_coefficients_sm, userdata.target_ellipses_sm, userdata.actions_sm)
00108
00109 stop_timer = time.time()
00110 global time_state
00111 time_state = time_state + (stop_timer - start_timer)
00112
00113 if resp.movement:
00114 userdata.poses = resp.poses
00115 userdata.poses_2d_coordinates = resp.poses_2d_coordinates
00116 userdata.secondary_arm = resp.secondary_arm
00117 return 'succeeded'
00118 else:
00119 return 'no_movements'
00120
00121 except rospy.ServiceException, e:
00122 print "Service call failed: %s"%e
00123 return 'aborted'
00124
00125
00126 class GetStateRepresentation(smach.State):
00127 def __init__(self):
00128 smach.State.__init__(self, outcomes=['succeeded','preempted','aborted','is_clean','get_full_info'],
00129 input_keys=['segmented_image_sm','segmented_pointcloud_sm','plane_coefficients_sm'],
00130 output_keys=['dirty_areas','distances','state_string','arm_position','segmented_pointcloud_sm','plane_coefficients_sm'])
00131 self.service_topic = '/iri_clean_plan/cleaning_plan/get_dirty_areas_state_representation'
00132 self.surface_clean_perceptions = 0
00133
00134 def execute(self, userdata):
00135 rospy.logdebug('Executing state GetStateRepresentation')
00136 start_timer = time.time()
00137 rospy.wait_for_service(self.service_topic)
00138 try:
00139 get_state = rospy.ServiceProxy(self.service_topic, StateRepresentation)
00140 resp = get_state(userdata.segmented_image_sm)
00141
00142 stop_timer = time.time()
00143 global time_state
00144 time_state = time_state + (stop_timer - start_timer)
00145
00146 if resp.is_clean:
00147 if self.surface_clean_perceptions < 2:
00148 self.surface_clean_perceptions += 1
00149 return 'get_full_info'
00150 else:
00151 return 'is_clean'
00152 else:
00153 self.surface_clean_perceptions = 0
00154 userdata.dirty_areas = resp.dirty_areas
00155 userdata.distances = resp.distances
00156 userdata.arm_position = resp.arm_position
00157 userdata.state_string = resp.state_string
00158 return 'succeeded'
00159 except rospy.ServiceException, e:
00160 print "Service call failed: %s"%e
00161 return 'aborted'
00162
00163
00164 class LearnerAddAction(smach.State):
00165 def __init__(self):
00166 smach.State.__init__(self, outcomes=['needs_learning','succeeded','preempted','aborted'],
00167 input_keys=['target_ellipses_sm','actions_sm','dirty_areas_sm','distances_sm','state_string_sm','movements_ok_sm'],
00168 output_keys=[])
00169 self.service_topic = '/iri_learning/rule_learner/add_action'
00170
00171 def execute(self, userdata):
00172 rospy.logdebug('Executing state LearnerAddAction')
00173 start_timer = time.time()
00174 rospy.wait_for_service(self.service_topic)
00175 try:
00176 get_cleaning_plan = rospy.ServiceProxy(self.service_topic, AddAction)
00177 resp = get_cleaning_plan(userdata.actions_sm[0], userdata.dirty_areas_sm, userdata.target_ellipses_sm[0], userdata.distances_sm, userdata.state_string_sm, userdata.movements_ok_sm)
00178
00179 stop_timer = time.time()
00180 global time_learning
00181 time_learning = time_learning + (stop_timer - start_timer)
00182
00183 if resp.needs_learning:
00184 return 'needs_learning'
00185 else:
00186 return 'succeeded'
00187
00188 except rospy.ServiceException, e:
00189 print "Service call failed: %s"%e
00190 return 'aborted'
00191
00192
00193 class LearnerAddState(smach.State):
00194 def __init__(self):
00195 smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'],
00196 input_keys=['segmented_image_sm'],
00197 output_keys=['rules_updated'])
00198 self.service_topic = '/iri_learning/rule_learner/add_state'
00199
00200 def execute(self, userdata):
00201 rospy.logdebug('Executing state LearnerAddState')
00202 start_timer = time.time()
00203 rospy.wait_for_service(self.service_topic)
00204 try:
00205 get_cleaning_plan = rospy.ServiceProxy(self.service_topic, AddState)
00206 resp = get_cleaning_plan(userdata.segmented_image_sm)
00207
00208 stop_timer = time.time()
00209 global time_learning
00210 time_learning = time_learning + (stop_timer - start_timer)
00211
00212 userdata.rules_updated = resp.rules_updated
00213 return 'succeeded'
00214
00215 except rospy.ServiceException, e:
00216 print "Service call failed: %s"%e
00217 return 'aborted'
00218
00219
00220 class MoveArm(smach.State):
00221 def __init__(self):
00222 smach.State.__init__(self, outcomes=['succeeded','failed'],
00223 input_keys=['poses','plane_coefficients_sm','poses_2d_coordinates','secondary_arm'],
00224 output_keys=['movements_ok'])
00225
00226 def execute(self, userdata):
00227 rospy.logdebug('Waiting for service')
00228 start_timer = time.time()
00229 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00230 try:
00231 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00232 resp = move_arm(userdata.poses, userdata.secondary_arm, userdata.plane_coefficients_sm, 1)
00233
00234 stop_timer = time.time()
00235 global time_moving
00236 time_moving = time_moving + (stop_timer - start_timer)
00237
00238 if resp.success:
00239 print 'Executing service success'
00240 userdata.movements_ok = True
00241 return 'succeeded'
00242 else:
00243
00244 pub = rospy.Publisher('/iri_clean_perception/get_board_information/unreachable_position', ImagePoint)
00245 for idx in resp.too_far_points_indexes:
00246 pub.publish(userdata.poses_2d_coordinates[idx])
00247 print 'Executing service failed. Maybe IK.'
00248 userdata.movements_ok = False
00249 return 'succeeded'
00250 except rospy.ServiceException, e:
00251 print "Service call failed: %s"%e
00252 return 'failed'
00253
00254
00255 class MoveArmBase(smach.State):
00256 def __init__(self):
00257 smach.State.__init__(self, outcomes=['next','failed'])
00258
00259 def execute(self, userdata):
00260 rospy.loginfo('Waiting for service')
00261 start_timer = time.time()
00262 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00263 try:
00264
00265 clean_mov = ArmMovementsPosesSrv()
00266 clean_mov.movement_type = 0
00267 clean_mov.poses = [];
00268 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00269 resp = move_arm(clean_mov.poses, [], [], 0)
00270
00271 stop_timer = time.time()
00272 global time_moving
00273 time_moving = time_moving + (stop_timer - start_timer)
00274
00275 if resp.success:
00276 print 'Executing service success'
00277 return 'next'
00278 else:
00279 print 'Executing service failed'
00280 return 'next'
00281 except rospy.ServiceException, e:
00282 print "Service call failed: %s"%e
00283 return 'failed'
00284
00285
00286 class MoveArmBaseWait(smach.State):
00287 def __init__(self):
00288 smach.State.__init__(self, outcomes=['next','failed'])
00289
00290 def execute(self, userdata):
00291 rospy.loginfo('Waiting for service')
00292 start_timer = time.time()
00293 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00294 try:
00295
00296 clean_mov = ArmMovementsPosesSrv()
00297 clean_mov.movement_type = 0
00298 clean_mov.poses = [];
00299 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00300 resp = move_arm(clean_mov.poses, [], [], 0)
00301
00302 stop_timer = time.time()
00303 global time_extra_learn
00304 time_extra_learn = time_extra_learn + (stop_timer - start_timer) + 1.0
00305
00306 if resp.success:
00307 print 'Executing service success'
00308 return 'next'
00309 else:
00310 print 'Executing service failed'
00311 return 'next'
00312 except rospy.ServiceException, e:
00313 print "Service call failed: %s"%e
00314 return 'failed'
00315
00316
00317 def calculate_trajectories_cb(userdata, request):
00318
00319 request.pointcloud_in = userdata.segmented_pointcloud_sm
00320 request.plane_coefficients = userdata.plane_coefficients_sm
00321 request.target_ellipses = userdata.target_ellipses_sm
00322 request.actions = userdata.actions_sm
00323 return request
00324
00325
00326 def main():
00327 rospy.init_node('smach_example_state_machine')
00328
00329
00330 sm = smach.StateMachine(outcomes=['finishOk','failedVision','failedPlanning','failedMoveArm'])
00331
00332
00333 with sm:
00334
00335 smach.StateMachine.add('NeedInfo', NeedInfo(),
00336 transitions={'next':'GetInfoCamera',
00337 'failed':'failedVision'},)
00338
00339 smach.StateMachine.add('GetInfoCamera', GetInfoCamera(),
00340
00341
00342
00343
00344
00345 transitions={'succeeded':'LearnerAddState',
00346 'preempted':'failedVision',
00347 'aborted':'failedVision'},
00348 remapping={'segmented_image':'segmented_image_sm',
00349 'pointcloud':'segmented_pointcloud_sm',
00350 'plane_coefficients':'plane_coefficients_sm'})
00351
00352 smach.StateMachine.add('LearnerAddState', LearnerAddState(),
00353 transitions={'succeeded':'GetStateRepresentation',
00354 'preempted':'failedPlanning',
00355 'aborted':'failedPlanning'},
00356 remapping={'rules_updated':'rules_updated_sm'})
00357
00358
00359 smach.StateMachine.add('GetStateRepresentation',
00360 GetStateRepresentation(),
00361 transitions={'is_clean':'finishOk',
00362 'get_full_info':'MoveArmBase',
00363 'succeeded':'PradaPlanning',
00364 'preempted':'failedVision',
00365 'aborted':'failedVision'},
00366 remapping={'dirty_areas':'dirty_areas_sm',
00367 'distances':'distances_sm',
00368 'state_string':'state_string_sm'})
00369
00370 smach.StateMachine.add('PradaPlanning',
00371
00372
00373
00374
00375
00376
00377 PradaPlanning(),
00378 transitions={'succeeded':'CalculateTrajectories',
00379 'preempted':'failedPlanning',
00380 'aborted':'failedPlanning',
00381 'no_plan':'NeedInfo'},
00382 remapping={'target_ellipses':'target_ellipses_sm',
00383 'actions':'actions_sm'})
00384
00385
00386
00387 smach.StateMachine.add('CalculateTrajectories',
00388 CalculateTrajectories(),
00389
00390
00391
00392
00393
00394
00395 transitions={'succeeded':'MoveArm',
00396 'preempted':'failedVision',
00397 'aborted':'failedVision',
00398 'no_movements':'NeedInfo'})
00399
00400
00401 smach.StateMachine.add('MoveArm', MoveArm(),
00402 transitions={'succeeded':'LearnerAddAction',
00403 'failed':'failedMoveArm'},
00404 remapping={'movements_ok':'movements_ok_sm'})
00405
00406 smach.StateMachine.add('LearnerAddAction',
00407 LearnerAddAction(),
00408 transitions={'needs_learning':'MoveArmBaseAndWait',
00409 'succeeded':'NeedInfo',
00410 'preempted':'failedPlanning',
00411 'aborted':'failedPlanning'})
00412
00413 smach.StateMachine.add('MoveArmBase', MoveArmBase(),
00414 transitions={'next':'NeedInfo',
00415 'failed':'failedMoveArm'})
00416
00417 smach.StateMachine.add('MoveArmBaseAndWait', MoveArmBaseWait(),
00418 transitions={'next':'WaitASecond',
00419 'failed':'failedMoveArm'})
00420
00421 smach.StateMachine.add('WaitASecond', st_sleep.WaitSeconds(1),
00422 transitions={'finish':'NeedInfo'})
00423
00424
00425 sis = smach_ros.IntrospectionServer('iri_board_cleaning', sm, '/SM_LEARNING')
00426 sis.start()
00427
00428
00429 try:
00430 outcome = sm.execute()
00431 finally:
00432 sis.stop()
00433
00434
00435
00436 if __name__ == '__main__':
00437 global time_perception
00438 global time_state
00439 global time_planning
00440 global time_learning
00441 global time_moving
00442 global time_extra_learn
00443
00444 time_perception = 0
00445 time_state = 0
00446 time_planning = 0
00447 time_learning = 0
00448 time_moving = 0
00449 time_extra_learn = 0
00450
00451 start=time.time()
00452 main()
00453 finish=time.time()
00454 total_time = finish-start
00455 rospy.loginfo('Time taken: ' + str(total_time))
00456 print "Total time " + str(total_time)
00457
00458
00459
00460 rospy.loginfo('Time taken perception: ' + str(time_perception))
00461 rospy.loginfo('Time taken state: ' + str(time_state))
00462 rospy.loginfo('Time taken planning: ' + str(time_planning))
00463 rospy.loginfo('Time taken learning: ' + str(time_learning))
00464 rospy.loginfo('Time taken moving: ' + str(time_moving))
00465 rospy.loginfo('Time taken extra_learn: ' + str(time_extra_learn))