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 from iri_common_smach import timed_state
00017 from iri_common_smach import timed_service_state
00018
00019 from iri_clean_board.srv import *
00020 from estirabot_msgs.msg import *
00021 from estirabot_msgs.srv import *
00022 from iri_planning_msgs.srv import *
00023
00024 class NeedInfo(smach.State):
00025 def __init__(self):
00026 smach.State.__init__(self, outcomes=['next','failed'])
00027 self.counter = 0
00028
00029 def execute(self, userdata):
00030 rospy.logdebug('Executing state NeedInfo')
00031 return 'next'
00032
00033
00034 class PradaPlanning(timed_state.TimedState):
00035 def __init__(self):
00036 timed_state.TimedState.__init__(self, outcomes=['succeeded','preempted','aborted','no_plan'],
00037 input_keys=['rules_updated_sm'],
00038 output_keys=['target_ellipses','actions'])
00039 self.service_topic = '/iri_clean_plan/prada_planner/getBestAction'
00040
00041 def timed_execute(self, userdata):
00042 rospy.logdebug('Executing state PradaPlanning')
00043 rospy.wait_for_service(self.service_topic)
00044 try:
00045 get_cleaning_plan = rospy.ServiceProxy(self.service_topic, PradaPlanSrv)
00046 resp = get_cleaning_plan(False)
00047
00048 if resp.succeeded:
00049 userdata.target_ellipses = resp.target_ellipses
00050 userdata.actions = resp.actions
00051 return 'succeeded'
00052 else:
00053 return 'no_plan'
00054
00055 except rospy.ServiceException, e:
00056 print "Service call failed: %s"%e
00057 return 'aborted'
00058
00059
00060 class CalculateTrajectories(timed_state.TimedState):
00061 def __init__(self):
00062 timed_state.TimedState.__init__(self, outcomes=['succeeded','preempted','aborted','no_movements'],
00063 input_keys=['target_ellipses_sm','actions_sm','ellipses_sm','segmented_pointcloud_sm','plane_coefficients_sm'],
00064 output_keys=['poses','poses_2d_coordinates','secondary_arm'])
00065 self.service_topic = '/iri_clean_plan/cleaning_plan/get_trajectories_from_plan'
00066 self.sequence_actions = ""
00067
00068 def timed_execute(self, userdata):
00069 self.sequence_actions = self.sequence_actions + " - " + userdata.actions_sm[0]
00070 rospy.logdebug('Executing state CalculateTrajectories')
00071 rospy.loginfo('Will execute action: ' + userdata.actions_sm[0])
00072 rospy.wait_for_service(self.service_topic)
00073 try:
00074 get_trajectories_from_plan = rospy.ServiceProxy(self.service_topic, PlanToTrajectories)
00075 resp = get_trajectories_from_plan(userdata.segmented_pointcloud_sm, userdata.plane_coefficients_sm, userdata.target_ellipses_sm, userdata.actions_sm)
00076
00077 if resp.movement:
00078 userdata.poses = resp.poses
00079 userdata.poses_2d_coordinates = resp.poses_2d_coordinates
00080 userdata.secondary_arm = resp.secondary_arm
00081 return 'succeeded'
00082 else:
00083 return 'no_movements'
00084
00085 except rospy.ServiceException, e:
00086 print "Service call failed: %s"%e
00087 return 'aborted'
00088
00089
00090 class GetStateRepresentation(timed_state.TimedState):
00091 def __init__(self):
00092 timed_state.TimedState.__init__(self, outcomes=['succeeded','preempted','aborted','is_clean','get_full_info'],
00093 input_keys=['segmented_image_sm','segmented_pointcloud_sm','plane_coefficients_sm'],
00094 output_keys=['dirty_areas','distances','state_string','arm_position','segmented_pointcloud_sm','plane_coefficients_sm'])
00095 self.service_topic = '/iri_clean_plan/cleaning_plan/get_dirty_areas_state_representation'
00096 self.surface_clean_perceptions = 0
00097
00098 def timed_execute(self, userdata):
00099 rospy.logdebug('Executing state GetStateRepresentation')
00100 rospy.wait_for_service(self.service_topic)
00101 try:
00102 get_state = rospy.ServiceProxy(self.service_topic, StateRepresentation)
00103 resp = get_state(userdata.segmented_image_sm)
00104
00105 if resp.is_clean:
00106 if self.surface_clean_perceptions < 2:
00107 self.surface_clean_perceptions += 1
00108 return 'get_full_info'
00109 else:
00110 return 'is_clean'
00111 else:
00112 self.surface_clean_perceptions = 0
00113 userdata.dirty_areas = resp.dirty_areas
00114 userdata.distances = resp.distances
00115 userdata.arm_position = resp.arm_position
00116 userdata.state_string = resp.state_string
00117 return 'succeeded'
00118 except rospy.ServiceException, e:
00119 print "Service call failed: %s"%e
00120 return 'aborted'
00121
00122
00123 class MoveArm(timed_state.TimedState):
00124 def __init__(self):
00125 timed_state.TimedState.__init__(self, outcomes=['succeeded','failed'],
00126 input_keys=['poses','plane_coefficients_sm','poses_2d_coordinates','secondary_arm'],
00127 output_keys=['movements_ok'])
00128
00129 def timed_execute(self, userdata):
00130 rospy.logdebug('Waiting for service')
00131 rospy.loginfo('Executing action number ' + str(self.num_executions))
00132 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00133 try:
00134 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00135 resp = move_arm(userdata.poses, userdata.secondary_arm, userdata.plane_coefficients_sm, 1)
00136
00137 if resp.success:
00138 print 'Executing service success'
00139 userdata.movements_ok = True
00140 return 'succeeded'
00141 else:
00142
00143 pub = rospy.Publisher('/iri_clean_perception/get_board_information/unreachable_position', ImagePoint)
00144 for idx in resp.too_far_points_indexes:
00145 pub.publish(userdata.poses_2d_coordinates[idx])
00146 print 'Executing service failed. Maybe IK.'
00147 userdata.movements_ok = False
00148 return 'succeeded'
00149 except rospy.ServiceException, e:
00150 print "Service call failed: %s"%e
00151 return 'failed'
00152
00153
00154 class MoveArmBase(timed_state.TimedState):
00155 def __init__(self):
00156 timed_state.TimedState.__init__(self, outcomes=['next','failed'])
00157
00158 def timed_execute(self, userdata):
00159 rospy.loginfo('Waiting for service')
00160 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00161 try:
00162
00163 clean_mov = ArmMovementsPosesSrv()
00164 clean_mov.movement_type = 0
00165 clean_mov.poses = [];
00166 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00167 resp = move_arm(clean_mov.poses, [], [], 0)
00168
00169 if resp.success:
00170 print 'Executing service success'
00171 return 'next'
00172 else:
00173 print 'Executing service failed'
00174 return 'next'
00175 except rospy.ServiceException, e:
00176 print "Service call failed: %s"%e
00177 return 'failed'
00178
00179
00180 def main():
00181 rospy.init_node('iri_cleaning_state_machine')
00182
00183
00184 sm = smach.StateMachine(outcomes=['finishOk','failedVision','failedPlanning','failedMoveArm'])
00185
00186 st_get_info_camera = timed_service_state.TimedServiceState('/iri_clean_perception/get_board_information/get_board_info_srv',
00187 BoardInfo,
00188 response_slots=['segmented_image',
00189 'pointcloud',
00190 'plane_coefficients'])
00191 st_get_state_representation = GetStateRepresentation()
00192 st_prada_planning = PradaPlanning()
00193 st_calculate_trajectories = CalculateTrajectories()
00194 st_move_arm = MoveArm()
00195 st_move_arm_base = MoveArmBase()
00196
00197 sleep_time = 1
00198 st_wait_seconds = st_sleep.WaitSeconds(sleep_time)
00199
00200
00201 with sm:
00202
00203 smach.StateMachine.add('NeedInfo', NeedInfo(),
00204 transitions={'next':'GetInfoCamera',
00205 'failed':'failedVision'},)
00206
00207 smach.StateMachine.add('GetInfoCamera', st_get_info_camera,
00208 transitions={'succeeded':'GetStateRepresentation',
00209 'preempted':'failedVision',
00210 'aborted':'failedVision'},
00211 remapping={'segmented_image':'segmented_image_sm',
00212 'pointcloud':'segmented_pointcloud_sm',
00213 'plane_coefficients':'plane_coefficients_sm'})
00214
00215 smach.StateMachine.add('GetStateRepresentation',
00216 st_get_state_representation,
00217 transitions={'is_clean':'finishOk',
00218 'get_full_info':'MoveArmBase',
00219 'succeeded':'PradaPlanning',
00220 'preempted':'failedVision',
00221 'aborted':'failedVision'},
00222 remapping={'dirty_areas':'dirty_areas_sm',
00223 'distances':'distances_sm',
00224 'state_string':'state_string_sm'})
00225
00226 smach.StateMachine.add('PradaPlanning',
00227 st_prada_planning,
00228 transitions={'succeeded':'CalculateTrajectories',
00229 'preempted':'failedPlanning',
00230 'aborted':'failedPlanning',
00231 'no_plan':'NeedInfo'},
00232 remapping={'target_ellipses':'target_ellipses_sm',
00233 'actions':'actions_sm'})
00234
00235 smach.StateMachine.add('CalculateTrajectories',
00236 st_calculate_trajectories,
00237 transitions={'succeeded':'MoveArm',
00238 'preempted':'failedVision',
00239 'aborted':'failedVision',
00240 'no_movements':'NeedInfo'})
00241
00242
00243 smach.StateMachine.add('MoveArm', st_move_arm,
00244 transitions={'succeeded':'NeedInfo',
00245 'failed':'failedMoveArm'},
00246 remapping={'movements_ok':'movements_ok_sm'})
00247
00248 smach.StateMachine.add('MoveArmBase', st_move_arm_base,
00249 transitions={'next':'WaitASecond',
00250 'failed':'failedMoveArm'})
00251
00252 smach.StateMachine.add('WaitASecond', st_wait_seconds,
00253 transitions={'finish':'NeedInfo'})
00254
00255
00256 sis = smach_ros.IntrospectionServer('iri_cleaning', sm, '/SM_LEARNING')
00257 sis.start()
00258
00259 start_time = time.time()
00260
00261
00262 try:
00263 outcome = sm.execute()
00264 finally:
00265 sis.stop()
00266 total_time = time.time() - start_time
00267
00268
00269 time_perception = st_get_info_camera.get_execution_time()
00270 time_planning = st_prada_planning.get_execution_time()
00271 time_state = st_get_state_representation.get_execution_time()
00272 time_state_traj = st_calculate_trajectories.get_execution_time()
00273 time_moving = st_move_arm.get_execution_time()
00274 time_moving_home = st_move_arm_base.get_execution_time()
00275
00276
00277 num_actions = st_move_arm.get_number_executions()
00278 sequence_actions = st_calculate_trajectories.sequence_actions
00279
00280
00281 time_state = time_state + time_state_traj
00282
00283 rospy.loginfo('Time taken: ' + str(total_time))
00284 rospy.loginfo('Time taken perception: ' + str(time_perception))
00285 rospy.loginfo('Time taken state: ' + str(time_state))
00286 rospy.loginfo('Time taken planning: ' + str(time_planning))
00287 rospy.loginfo('Time taken moving: ' + str(time_moving))
00288 rospy.loginfo('Time taken moving home: ' + str(time_moving_home))
00289 rospy.loginfo('Number of actions: ' + str(num_actions))
00290 rospy.loginfo('Sequence of actions: ' + sequence_actions)
00291
00292 if len(sys.argv) > 1:
00293 file_name = sys.argv[2]
00294 f = open(file_name, 'a')
00295 f.write('\n')
00296 f.write('Time taken: ' + str(total_time) + '\n')
00297 f.write('Time taken perception: ' + str(time_perception) + '\n')
00298 f.write('Time taken state: ' + str(time_state) + '\n')
00299 f.write('Time taken planning: ' + str(time_planning) + '\n')
00300 f.write('Time taken moving: ' + str(time_moving) + '\n')
00301 f.write('Time taken moving home: ' + str(time_moving_home) + '\n')
00302 f.write('Number of actions: ' + str(num_actions) + '\n')
00303 f.write('Sequence of actions: ' + sequence_actions + '\n')
00304
00305
00306
00307 if __name__ == '__main__':
00308 main()
00309