rfid_search.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 
00003 import roslib; 
00004 roslib.load_manifest('rfid_people_following')
00005 roslib.load_manifest('std_srvs')
00006 roslib.load_manifest('explore_hrl')
00007 roslib.load_manifest('move_base_msgs')
00008 roslib.load_manifest('actionlib')
00009 roslib.load_manifest('geometry_msgs')
00010 roslib.load_manifest('tf')
00011 roslib.load_manifest('hrl_rfid')
00012 import rospy
00013 
00014 import tf
00015 import tf.transformations as tft
00016 import actionlib
00017 from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
00018 import hrl_rfid.ros_M5e_client as rmc
00019 
00020 from rfid_people_following.srv import StringInt32_Int32
00021 from rfid_people_following.srv import String_Int32
00022 from rfid_people_following.srv import Int32_Int32
00023 from rfid_people_following.srv import String_StringArr
00024 from std_srvs.srv import Empty
00025 from geometry_msgs.msg import PointStamped
00026 import actionlib
00027 import explore_hrl.msg
00028 
00029 from geometry_msgs.msg import PoseStamped
00030 from geometry_msgs.msg import Quaternion
00031 
00032 import numpy as np, math
00033 import time
00034 from threading import Thread
00035 import os
00036 
00037 
00038 # A more general form of this should be folded back into ros_M5e_client!
00039 # It also appears in new_servo_node (rfid_people_following)
00040 class rfid_poller( Thread ):
00041     def __init__( self, tagid ):
00042         Thread.__init__( self )
00043         self.reader = rmc.ROS_M5e_Client('ears')
00044         self.listener = tf.TransformListener()
00045         self.listener.waitForTransform('/ear_antenna_left', '/map',
00046                                        rospy.Time(0), timeout = rospy.Duration(100) )
00047         self.listener.waitForTransform('/ear_antenna_right', '/map',
00048                                        rospy.Time(0), timeout = rospy.Duration(100) )
00049 
00050         self.should_run = True
00051         self.should_poll = False
00052         self.data = []
00053         self.tagid = tagid
00054         self.start()
00055 
00056     def transform( self, antname ):
00057         ps = PointStamped()
00058         ps2 = PointStamped()
00059         ps2.point.x = 0.1
00060 
00061         if antname == 'EleLeftEar':
00062             ps.header.frame_id = '/ear_antenna_left'
00063             ps.header.stamp = rospy.Time( 0 )
00064 
00065             ps2.header.frame_id = '/ear_antenna_left'
00066             ps2.header.stamp = rospy.Time( 0 )
00067         elif antname == 'EleRightEar':
00068             ps.header.frame_id = '/ear_antenna_right'
00069             ps.header.stamp = rospy.Time( 0 )
00070 
00071             ps2.header.frame_id = '/ear_antenna_right'
00072             ps2.header.stamp = rospy.Time( 0 )
00073         else:
00074             rospy.logout( 'Bad ear' )
00075             return False, 0.0, 0.0, 0.0
00076 
00077         try:
00078             ps_map = self.listener.transformPoint( '/map', ps )
00079             x = ps_map.point.x
00080             y = ps_map.point.y
00081             #rospy.logout( 'Done 1' )
00082 
00083             ps2_map = self.listener.transformPoint( '/map', ps2 )
00084             x2 = ps2_map.point.x
00085             y2 = ps2_map.point.y
00086             #rospy.logout( 'Done 1' )
00087 
00088             # We'll pass back the position of the base (which will be a "safe" place to traverse, whereas the antenna pos not necessarily in the clear)
00089             ps_base = PointStamped()
00090             ps_base.header.frame_id = '/base_link'
00091             ps_base.header.stamp = rospy.Time( 0 )
00092             ps_base_map = self.listener.transformPoint( '/map', ps_base )
00093             x_base = ps_base_map.point.x
00094             y_base = ps_base_map.point.y
00095             
00096             #rospy.logout( 'Transform Success ' + ps.header.frame_id )
00097             return True, x_base, y_base, np.arctan2( y2 - y, x2 - x )
00098         except:
00099             rospy.logout( 'Transform failed! ' + ps.header.frame_id )
00100             return False, 0.0, 0.0, 0.0
00101             
00102 
00103     def start_poller( self ):
00104         # Start appending into self.data
00105         #self.reader.track_mode( self.tagid )
00106         self.should_poll = True
00107 
00108     def stop_poller( self ):
00109         # Stop appending into self.data
00110         #self.reader.stop()
00111         self.should_poll = False
00112 
00113     def run( self ):
00114         rospy.logout( 'rfid_poller: Starting' )
00115         while self.should_run and not rospy.is_shutdown():
00116             if self.should_poll:
00117                 left = self.reader.read('EleLeftEar')[-1]
00118                 success, x, y, ang = self.transform( 'EleLeftEar' )
00119                 if success:
00120                     self.data.append( [left, [x,y,ang]] )
00121 
00122                 right = self.reader.read('EleRightEar')[-1]
00123                 success, x, y, ang = self.transform( 'EleRightEar' )
00124                 if success:
00125                     self.data.append( [right, [x,y,ang]] )
00126             else:
00127                 rospy.sleep( 0.050 )
00128             
00129         try:  # Shut it down to conserve power.  Something of a race condition (exception)
00130             self.reader.stop()
00131         except:
00132             pass
00133         rospy.logout( 'rfid_poller: Exiting' )
00134         
00135     def stop( self ):
00136         # Kill off the poller thread.
00137         self.should_run = False
00138         self.join(5)
00139         # if (self.isAlive()):
00140         #     raise RuntimeError("rfid_poller: Unable to stop thread")
00141 
00142 
00143 # A more general form of this should be folded back into orient_node (rfid_people_following)!
00144 class Flapper( Thread ):
00145     def __init__( self, tagid = 'person      '):
00146         Thread.__init__( self )
00147         rospy.logout('Flapper: Initializing' )
00148         rospy.wait_for_service( '/rfid_orient/flap' )
00149         rospy.logout('Flapper: flap service ready.' )
00150 
00151         self._flap = rospy.ServiceProxy( '/rfid_orient/flap', String_StringArr )
00152         self.flap = lambda : self._flap( tagid )
00153 
00154         self.should_run = True
00155         self.should_flap = False
00156         self.start()
00157 
00158     def start_flapper( self ):
00159         # Start appending into self.data
00160         #self.reader.track_mode( self.tagid )
00161         self.should_flap = True
00162 
00163     def stop_flapper( self ):
00164         # Stop appending into self.data
00165         #self.reader.stop()
00166         self.should_flap = False
00167 
00168     def run( self ):
00169         rospy.logout( 'Flapper: Starting' )
00170         r = rospy.Rate( 10 )
00171         while self.should_run and not rospy.is_shutdown():
00172             if self.should_flap:
00173                 self.flap()
00174             else:
00175                 r.sleep()
00176             
00177         rospy.logout( 'Flapper: Exiting' )
00178         
00179     def stop( self ):
00180         # Kill off the poller thread.
00181         self.should_run = False
00182         self.join(15)
00183         if (self.isAlive()):
00184             raise RuntimeError("Flapper: Unable to stop thread")
00185 
00186 
00187 def navstack( x, y, ang ):
00188     try:
00189         rospy.logout( 'Requesting navstack move to <x,y,ang-deg> %3.3f %3.3f %3.3f.' % (x, y, math.degrees(ang)) )
00190 
00191         client = actionlib.SimpleActionClient( 'move_base', MoveBaseAction )
00192         client.wait_for_server()
00193 
00194         ps = PoseStamped()
00195         ps.header.frame_id = '/map'
00196         ps.header.stamp = rospy.Time(0)
00197         ps.pose.position.x = x
00198         ps.pose.position.y = y
00199         ps.pose.orientation = Quaternion( *tft.quaternion_from_euler( 0.0, 0.0, ang ))
00200 
00201         goal = MoveBaseGoal( ps )
00202         client.send_goal( goal )
00203         rospy.logout( 'Waiting for base to stop moving.' )
00204         client.wait_for_result()
00205         rospy.logout( 'Successfully navigated to desired position.' )
00206         return True
00207     except:
00208         rospy.logout( 'Navstack did not achieve desired position.' )
00209         return False
00210 
00211 
00212 class RFIDSearch():
00213     def __init__( self ):
00214         try:
00215             rospy.init_node( 'rfid_search' )
00216         except:
00217             pass
00218         
00219         rospy.logout( 'rfid_search: Initializing.' )
00220         #rospy.wait_for_service( '/rfid_servo/servo' )
00221         rospy.wait_for_service( '/rfid_orient/orient' )
00222         rospy.wait_for_service( '/rfid_orient/flap' )
00223         #rospy.wait_for_service( '/rfid_demo/demo' )
00224         #rospy.wait_for_service( '/rfid_gui/select' )
00225         self.explore_act = actionlib.SimpleActionClient('explore', explore_hrl.msg.ExploreAction)
00226         rospy.logout( 'rfid_search: Waiting for explore.' )
00227         self.explore_act.wait_for_server()
00228         rospy.logout( 'rfid_search: Done Initializing.' )
00229 
00230         #self._servo = rospy.ServiceProxy( '/rfid_servo/servo', StringInt32_Int32 )
00231         #self.follow1 = lambda : self._servo( 'person      ', 1 ) # Stops at first obs
00232         #self.follow = lambda : self._servo( 'person      ', 0 ) # Runs forever
00233 
00234         #self._demo = rospy.ServiceProxy( '/rfid_demo/demo', Empty )
00235         #self.demo = lambda : self._demo() 
00236 
00237         #self._servo_stop = rospy.ServiceProxy( '/rfid_servo/stop_next_obs', Int32_Int32 )
00238         #self.servo_toggle = lambda : self._servo_stop( 1 ) 
00239 
00240         self._orient = rospy.ServiceProxy( '/rfid_orient/orient', String_Int32 )
00241         self.orient = lambda tagid: self._orient( tagid )
00242 
00243         self.rp = rfid_poller('person      ')
00244         self.flapper = Flapper()
00245 
00246         rospy.logout( 'rfid_search: ready to go!' )
00247 
00248     def wait_for_finish( self, radius = 2.0 ):
00249         print 'Starting RFID tag scanning'
00250         self.rp.start_poller()
00251         self.flapper.start_flapper()
00252         rospy.sleep( 0.3 )
00253 
00254         print 'Starting Search'
00255         goal = explore_hrl.msg.ExploreGoal( radius = radius )
00256         self.explore_act.send_goal(goal)
00257         rospy.sleep( 0.5 )
00258         self.explore_act.wait_for_result()
00259         res = self.explore_act.get_result()
00260         print 'Search Complete: ', res
00261         status = self.explore_act.get_state()
00262 
00263         print 'Disabling RFID scanning'
00264         self.flapper.stop_flapper()
00265         self.rp.stop_poller()
00266 
00267         print 'Computing Best Position'
00268         readings =  self.rp.data
00269         print readings
00270         rr = list( self.rp.data ) # rfid_reads: [ [rssi,[x,y,ang]], ...]
00271         rssi = [ r for r,vec in rr ]
00272         max_rssi, max_pose = rr[ np.argmax( rssi ) ]
00273 
00274         print 'Moving to best Position: ', max_pose, ' RSSI: ', max_rssi
00275         navstack( *max_pose )
00276 
00277         print 'Executing Remainder of Demo'
00278         # if (os.environ.has_key('ROBOT') and os.environ['ROBOT'] == 'sim'):
00279         #     self.follow1() # Only do servoing in simulation
00280         # else:
00281         #     try:
00282         #         self.demo() # Run the full demo IRL
00283         #     except: # for some reason, NoneType throws exception...
00284         #         pass
00285 
00286         print 'Shutting down threads'
00287         self.rp.stop()
00288         self.flapper.stop()
00289 
00290         if status == actionlib.GoalStatus.SUCCEEDED:
00291             return 'succeeded'
00292         else:
00293             return 'aborted'
00294 
00295 if __name__ == '__main__':
00296     rs = RFIDSearch()
00297     time.sleep( 3 )
00298     rs.wait_for_finish( radius = 1.7 )
00299     #print rs.flap()
00300 
00301 #     while True:
00302 #         print 'DoneSearching: ', rs.doneSearching()


rfid_demos
Author(s): Travis Deyle
autogenerated on Wed Nov 27 2013 11:50:51