00001 #! /usr/bin/python 00002 import roslib 00003 roslib.load_manifest('rfid_demos') 00004 roslib.load_manifest('rfid_explore_room') 00005 import rospy 00006 00007 import smach 00008 import tf 00009 from smach_ros import SimpleActionState, ServiceState, IntrospectionServer 00010 import actionlib 00011 00012 from rfid_behaviors.srv import FlapperSrv, FlapperSrvRequest 00013 from rfid_behaviors.srv import RecorderSrv, RecorderSrvRequest, NextBestVantage 00014 from rfid_behaviors.msg import RecorderReads 00015 from rfid_explore_room.srv import ExploreRoomSrv, ExploreRoomSrvResponse 00016 from explore_hrl.msg import ExploreAction, ExploreGoal 00017 from geometry_msgs.msg import PoseStamped 00018 00019 00020 class Sleeper( smach.State ): 00021 def __init__( self, time ): 00022 smach.State.__init__( self, outcomes = ['succeeded'] ) 00023 self.time = time 00024 00025 def execute( self, userdata ): 00026 rospy.sleep( self.time ) 00027 return 'succeeded' 00028 00029 def sm_search(): 00030 # Create a SMACH state machine 00031 sm_search = smach.StateMachine( outcomes=['succeeded', 'aborted', 'preempted'], 00032 input_keys = ['tagid', 'explore_radius']) 00033 00034 # Open the container 00035 with sm_search: 00036 00037 # Start the RFID recorder 00038 smach.StateMachine.add( 00039 'RECORDER_START', 00040 ServiceState( '/rfid_recorder/record', 00041 RecorderSrv), 00042 transitions = {'succeeded':'FLAPPER_START'}) 00043 00044 00045 # Start the ears flapping. 00046 smach.StateMachine.add( 00047 'FLAPPER_START', 00048 ServiceState( '/flapper/flap', 00049 FlapperSrv, 00050 request_slots = ['tagid']), 00051 transitions = {'succeeded':'EXPLORE_ROOM'}, 00052 # transitions = {'succeeded':'SLEEPER'}, 00053 remapping = {'tagid':'tagid'}) 00054 00055 # smach.StateMachine.add('SLEEPER', Sleeper( 5.0 ), transitions = {'succeeded':'FLAPPER_STOP'}) 00056 00057 00058 # EXPLORE 00059 def explore_response_cb( userdata, response ): 00060 # result is of ExploreRoomSrvResponse 00061 return response.result 00062 00063 smach.StateMachine.add( 00064 'EXPLORE_ROOM', 00065 ServiceState( '/explore/explore', # Default outcomes 00066 ExploreRoomSrv, 00067 request_slots = [ 'radius' ], 00068 response_cb = explore_response_cb), 00069 remapping = { 'radius':'explore_radius' }, 00070 transitions = {'succeeded':'FLAPPER_STOP'}) # input 00071 00072 00073 # Stop the ears flapping. 00074 smach.StateMachine.add( 00075 'FLAPPER_STOP', 00076 ServiceState( '/flapper/flap', 00077 FlapperSrv, 00078 request_slots = ['tagid']), 00079 transitions = {'succeeded':'RECORDER_STOP'}, 00080 remapping = {'tagid':'tagid'}) 00081 00082 # Start the RFID recorder 00083 smach.StateMachine.add( 00084 'RECORDER_STOP', 00085 ServiceState( '/rfid_recorder/record', 00086 RecorderSrv), 00087 transitions = {'succeeded':'succeeded'}) 00088 00089 00090 return sm_search 00091 00092 00093 00094 00095 if __name__ == '__main__': 00096 rospy.init_node('smach_rfid_explore') 00097 00098 sm = sm_search() 00099 00100 sis = IntrospectionServer('sm_rfid_explore', sm, '/SM_ROOT_RFID_EXPLORE') 00101 sis.start() 00102 rospy.sleep(3.0) 00103 00104 sm.userdata.tagid = '' 00105 #sm.userdata.tagid = 'person ' 00106 sm.userdata.explore_radius = 2.7 00107 outcome = sm.execute() 00108 00109 sis.stop() 00110 00111 00112 00113 00114 00115 # This old concurrency one didn't work. 00116 00117 # def sm_search(): 00118 # # Create a SMACH state machine 00119 # sm_search = smach.Concurrence( outcomes=['succeeded', 'aborted', 'preempted'], 00120 # default_outcome = 'aborted', 00121 # outcome_map = {'succeeded': {'EXPLORE_ROOM':'succeeded'}, 00122 # 'aborted': {'EXPLORE_ROOM':'aborted'}, 00123 # 'preempted': {'EXPLORE_ROOM':'preempted'}}, 00124 # output_keys = ['explore_rfid_reads'], 00125 # input_keys = ['tagid', 'explore_radius'], 00126 # child_termination_cb = lambda arg: True ) 00127 # # Note: child_termination_cb: Terminate all other states' execution upon first child complete (Always EXPLORE_ROOM). 00128 00129 # # Open the container 00130 # with sm_search: 00131 # smach.Concurrence.add( 00132 # 'EXPLORE_ROOM', 00133 # SimpleActionState( '/explore', # Default outcomes 00134 # ExploreAction, 00135 # goal_slots = [ 'radius' ]), 00136 # remapping = { 'radius':'explore_radius' }) # input 00137 00138 # smach.Concurrence.add( 00139 # 'RFID_FLAPPER', 00140 # Flapper(), # outcomes: preempted 00141 # remapping = { 'tagid' : 'tagid' }) # input 00142 00143 # smach.Concurrence.add( 00144 # 'RFID_RECORDER', 00145 # Recorder(), # outcomes: preempted 00146 # remapping = { 'rfid_reads' : 'explore_rfid_reads' }) # output 00147 00148 00149 # return sm_search 00150 00151 00152 00153 00154 # import hrl_rfid.ros_M5e_client as rmc 00155 # class Recorder(smach.State): 00156 # def __init__(self): 00157 # smach.State.__init__(self, 00158 # outcomes = ['preempted'], 00159 # output_keys = ['rfid_reads']) # [(RFIDread, ps_ant_map, ps_base_map ), ...] 00160 # self.data = [] 00161 00162 # def execute(self, userdata): 00163 # rospy.logout( 'RFID Recorder: Initiated.' ) 00164 # self.data = [] 00165 00166 # listener = tf.TransformListener() 00167 # rospy.logout( 'RFID Recorder: Waiting on transforms' ) 00168 # listener.waitForTransform('/ear_antenna_left', '/map', 00169 # rospy.Time(0), timeout = rospy.Duration(100) ) 00170 # listener.waitForTransform('/ear_antenna_right', '/map', 00171 # rospy.Time(0), timeout = rospy.Duration(100) ) 00172 # rospy.logout( 'RFID Recorder: Ready' ) 00173 00174 # def process_datum( datum ): 00175 # # Hooray for lexical scope (listener)! 00176 # ant_lookup = { 'EleLeftEar': '/ear_antenna_left', 00177 # 'EleRightEar': '/ear_antenna_right' } 00178 00179 # ps_ant = PoseStamped() 00180 # ps_ant.header.stamp = rospy.Time( 0 ) 00181 # ps_ant.header.frame_id = ant_lookup[ datum.antenna_name ] 00182 00183 # ps_base = PoseStamped() 00184 # ps_base.header.stamp = rospy.Time( 0 ) 00185 # ps_base.header.frame_id = '/base_link' 00186 00187 # try: 00188 # ps_ant_map = listener.transformPose( '/map', ps_ant ) 00189 # ps_base_map = listener.transformPose( '/map', ps_base ) 00190 # rv = ( datum, ps_ant_map, ps_base_map ) 00191 # except: 00192 # rospy.logout( 'RFID Recorder: TF failed. Ignoring read.' ) 00193 # rv = None 00194 # return rv 00195 00196 # def add_datum( datum ): 00197 # # Hooray for lexical scope (data)! 00198 # self.data.append( process_datum( datum )) 00199 00200 # # Notes: In this case, the flapper will initiate RFID reads 00201 # # for the proper tagid. Not ideal, but how it is for now. 00202 # rec = rmc.ROS_M5e_Client('ears', callbacks = [add_datum]) 00203 00204 # rospy.logout( 'RFID Recorder: Logging Reads.' ) 00205 # while not smach.State.preempt_requested( self ): 00206 # rospy.sleep( 0.1 ) 00207 00208 # rospy.logout( 'RFID Recorder: Preempt requested. Saving reads.' ) 00209 # rec.unregister() # Stop processing new reads 00210 # rospy.sleep( 0.5 ) # Give it some time to settle 00211 # userdata.rfid_reads = list(self.data) # Save the data. 00212 # self.data = [] 00213 # return 'preempted' 00214