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 from iri_clean_board.msg import *
00015 from iri_clean_board.srv import *
00016 from estirabot_msgs.msg import *
00017 from estirabot_msgs.srv import *
00018
00019
00020
00021
00022
00023 import time
00024
00025
00026 class NeedInfo(smach.State):
00027 def __init__(self):
00028 smach.State.__init__(self, outcomes=['next','failed'])
00029 self.counter = 0
00030
00031 def execute(self, userdata):
00032 rospy.loginfo('Executing state NeedInfo')
00033 return 'next'
00034
00035
00036
00037 class Planning(smach.State):
00038 def __init__(self):
00039 smach.State.__init__(self, outcomes=['next','finish','get_info','get_full_info','failed'],
00040 input_keys=['image_segm','pointcloud_segm','plane_coefficients'],
00041 output_keys=['poses','plane_coefficients','poses_2d_coordinates','secondary_arm'])
00042 self.surface_clean_perceptions = 0
00043
00044
00045 def execute(self, userdata):
00046 if userdata.pointcloud_segm.height == 0:
00047 rospy.loginfo('Pointcloud isn\'t available yet')
00048 return 'get_info'
00049
00050 rospy.loginfo('Executing state Planning')
00051 rospy.wait_for_service('/iri_clean_plan/cleaning_plan/get_cleaning_plan')
00052 try:
00053 get_cleaning_plan = rospy.ServiceProxy('/iri_clean_plan/cleaning_plan/get_cleaning_plan', PlanSrv)
00054 resp = get_cleaning_plan(userdata.pointcloud_segm, userdata.image_segm, userdata.plane_coefficients)
00055 if resp.is_clean:
00056 if self.surface_clean_perceptions < 2:
00057 self.surface_clean_perceptions += 1
00058 return 'get_full_info'
00059 else:
00060 return 'finish'
00061 elif not resp.movement:
00062 self.surface_clean_perceptions = 0
00063 return 'get_info'
00064 else:
00065 self.surface_clean_perceptions = 0
00066 userdata.poses = resp.poses
00067 userdata.plane_coefficients = resp.plane_coefficients
00068 userdata.poses_2d_coordinates = resp.poses_2d_coordinates
00069 userdata.secondary_arm = resp.secondary_arm
00070 return 'next'
00071 except rospy.ServiceException, e:
00072 print "Service call failed: %s"%e
00073 return 'failed'
00074
00075
00076
00077 class MoveArm(smach.State):
00078 def __init__(self):
00079 smach.State.__init__(self, outcomes=['next','failed'],
00080 input_keys=['poses','plane_coefficients','poses_2d_coordinates','secondary_arm'])
00081
00082 def execute(self, userdata):
00083 rospy.loginfo('Waiting for service')
00084 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00085 try:
00086 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00087 resp = move_arm(userdata.poses, userdata.secondary_arm, userdata.plane_coefficients, 1)
00088 if resp.success:
00089 print 'Executing service success'
00090 return 'next'
00091 else:
00092
00093 pub = rospy.Publisher('/iri_clean_perception/get_board_information/unreachable_position', ImagePoint)
00094 for idx in resp.too_far_points_indexes:
00095 pub.publish(userdata.poses_2d_coordinates[idx])
00096 print 'Executing service failed. Maybe IK.'
00097 return 'next'
00098 except rospy.ServiceException, e:
00099 print "Service call failed: %s"%e
00100 return 'failed'
00101
00102
00103 class MoveArmBase(smach.State):
00104 def __init__(self):
00105 smach.State.__init__(self, outcomes=['next','failed'])
00106
00107 def execute(self, userdata):
00108 rospy.loginfo('Waiting for service')
00109 rospy.wait_for_service('/iri_clean_plan/arm_movements_by_pose/clean_movement')
00110 try:
00111
00112 clean_mov = ArmMovementsPosesSrv()
00113 clean_mov.movement_type = 0
00114 clean_mov.poses = [];
00115 move_arm = rospy.ServiceProxy('/iri_clean_plan/arm_movements_by_pose/clean_movement', ArmMovementsPosesSrv)
00116 resp = move_arm(clean_mov.poses, [], [], 0)
00117 if resp.success:
00118 print 'Executing service success'
00119 return 'next'
00120 else:
00121 print 'Executing service failed'
00122 return 'next'
00123 except rospy.ServiceException, e:
00124 print "Service call failed: %s"%e
00125 return 'failed'
00126
00127
00128
00129 def main():
00130 rospy.init_node('smach_example_state_machine')
00131
00132
00133 sm = smach.StateMachine(outcomes=['finishOk','failedVision','failedPlanning','failedMoveArm'])
00134
00135
00136 with sm:
00137
00138 smach.StateMachine.add('NeedInfo', NeedInfo(),
00139 transitions={'next':'GetInfoAction',
00140 'failed':'failedVision'},)
00141
00142 smach.StateMachine.add('GetInfoAction',
00143
00144
00145
00146
00147
00148
00149 ServiceState('/iri_clean_perception/get_board_information/get_board_info_srv',
00150 BoardInfo,
00151 response_slots=['segmented_image',
00152 'pointcloud',
00153 'plane_coefficients']),
00154 transitions={'succeeded':'Planning',
00155 'preempted':'failedVision',
00156 'aborted':'failedVision'},
00157 remapping={'segmented_image':'image_segm',
00158 'pointcloud':'pointcloud_segm',
00159 'plane_coefficients':'plane_coefficients'})
00160
00161 smach.StateMachine.add('Planning', Planning(),
00162 transitions={'next':'MoveArm',
00163 'finish':'finishOk',
00164 'get_full_info':'MoveArmBase',
00165 'get_info':'NeedInfo',
00166 'failed':'failedPlanning'})
00167 smach.StateMachine.add('MoveArm', MoveArm(),
00168 transitions={'next':'NeedInfo',
00169 'failed':'failedMoveArm'})
00170 smach.StateMachine.add('MoveArmBase', MoveArmBase(),
00171 transitions={'next':'NeedInfo',
00172 'failed':'failedMoveArm'})
00173
00174
00175 outcome = sm.execute()
00176
00177
00178
00179 if __name__ == '__main__':
00180 start=time.time()
00181 main()
00182 finish=time.time()
00183 total_time = finish-start
00184 rospy.loginfo('Time taken: ' + str(total_time))
00185 print total_time