00001 import roslib
00002 roslib.load_manifest( 'rfid_people_following' )
00003 roslib.load_manifest( 'tf' )
00004 roslib.load_manifest( 'geometry_msgs' )
00005 roslib.load_manifest('hrl_rfid')
00006 import rospy
00007
00008 from hrl_rfid.msg import RFIDread
00009 from hrl_rfid.msg import RFIDreadArr
00010 from hrl_rfid.srv import RfidSrv
00011 import tf
00012 from geometry_msgs.msg import PointStamped
00013
00014 import sys, serial, time, string
00015 from threading import Thread
00016 import friis
00017 import pickle as pkl
00018 import numpy as np, math
00019
00020
00021 def prin(x): print x
00022
00023 f = open( '/home/travis/svn/data_robot1/rfid_data/pan_captures/model_fit.pkl', 'r' )
00024 d = pkl.load( f )
00025 f.close()
00026
00027 def calculate_angle( pt1 ):
00028 return np.arctan2( pt1.point.y, pt1.point.x )
00029
00030 class M5e:
00031 "Interface to Mercury M5e and M5e-Compact"
00032 def __init__(self, portSTR='/dev/robot/RFIDreader', baudrate=9600,
00033 TXport=1, RXport=1, readPwr=2300, protocol='GEN2', compact=True, verbosity_func=prin):
00034
00035
00036
00037
00038 self.TXport = TXport
00039 self.RXport = RXport
00040 self.readPwr = readPwr
00041 self.protocol = protocol
00042 self.compact = compact
00043 self.prin = verbosity_func
00044 self.ser = None
00045
00046 try:
00047 rospy.init_node( 'RFID_Simulator_Friis' )
00048 except rospy.ROSException:
00049 pass
00050
00051 self.prin( 'Initializing M5e (or M5e-Compact)' )
00052 self.listener = tf.TransformListener()
00053
00054 rospy.logout('Simulated M5e: Waiting for odom_combined-antenna tf')
00055 self.listener.waitForTransform('/ear_antenna_left', '/odom_combined',
00056 rospy.Time(0), timeout = rospy.Duration(100) )
00057 self.listener.waitForTransform('/ear_antenna_right', '/odom_combined',
00058 rospy.Time(0), timeout = rospy.Duration(100) )
00059 self.listener.waitForTransform('/left_rotation_center', '/odom_combined',
00060 rospy.Time(0), timeout = rospy.Duration(100) )
00061 self.listener.waitForTransform('/right_rotation_center', '/odom_combined',
00062 rospy.Time(0), timeout = rospy.Duration(100) )
00063 self.listener.waitForTransform('/base_link', '/odom_combined',
00064 rospy.Time(0), timeout = rospy.Duration(100) )
00065 self.listener.waitForTransform('/tag_gt', '/odom_combined',
00066 rospy.Time(0), timeout = rospy.Duration(100) )
00067 rospy.logout('Simulated M5e: Transforms ready')
00068 self.prin( 'M5e Initialized' )
00069
00070
00071 def ChangeAntennaPorts(self, TXport, RXport):
00072 "Changes TX and RX ports"
00073 self.TXport = TXport
00074 self.RXport = RXport
00075
00076
00077 def QueryEnvironment(self, timeout=50):
00078 rospy.sleep( timeout * 0.001 )
00079 return []
00080
00081
00082
00083 def TrackSingleTag(self, tagID, timeout=50):
00084 rospy.sleep( timeout * 0.001 )
00085
00086
00087 ant_zp = PointStamped()
00088 ant_zp.header.stamp = rospy.Time(0)
00089
00090 tag_zp = PointStamped()
00091 tag_zp.header.stamp = rospy.Time(0)
00092 tag_zp.header.frame_id = '/tag_gt'
00093
00094 if self.TXport == 1 and self.RXport == 1:
00095 ear_frame = '/ear_antenna_left'
00096 else:
00097 ear_frame = '/ear_antenna_right'
00098
00099 ant_zp.header.frame_id = ear_frame
00100
00101
00102 tag_in_ant = self.listener.transformPoint( ear_frame, tag_zp )
00103 ant_in_tag = self.listener.transformPoint( '/tag_gt', ant_zp )
00104
00105
00106 tag_in_ant_sphere = np.array( friis.CartToSphere2( tag_in_ant.point.x,
00107 tag_in_ant.point.y,
00108 tag_in_ant.point.z ))
00109 ant_in_tag_sphere = np.array( friis.CartToSphere2( ant_in_tag.point.x,
00110 ant_in_tag.point.y,
00111 ant_in_tag.point.z ))
00112
00113
00114
00115 Ptag = friis.pwr_inc_tag( tag_in_ant_sphere[0],
00116 friis.patch.G, tag_in_ant_sphere[1], tag_in_ant_sphere[2],
00117 friis.dipole.G, ant_in_tag_sphere[1], ant_in_tag_sphere[2] )
00118 Prdr = friis.pwr_inc_rdr( tag_in_ant_sphere[0],
00119 friis.patch.G, tag_in_ant_sphere[1], tag_in_ant_sphere[2],
00120 friis.dipole.G, ant_in_tag_sphere[1], ant_in_tag_sphere[2] )
00121 Prdr_dBm = friis.WattsToDBm( Prdr )
00122
00123
00124 sim_read = Ptag > friis.DBmToWatts( -18.0 )
00125 sim_rssi_ind = np.sum( Prdr_dBm > d['bins'][:-1] ) - 1
00126 sim_rssi_ind = np.clip( sim_rssi_ind, 0, sim_rssi_ind )
00127 sim_rssi = d['mean_rssi'][sim_rssi_ind]
00128
00129 if sim_read:
00130 return int(sim_rssi)
00131 else:
00132 return -1
00133
00134
00135
00136
00137
00138 class ROS_M5e( Thread ):
00139 QUERY_MODE = 'query'
00140 TRACK_MODE = 'track'
00141
00142 def __init__(self, name = 'reader1', readPwr = 2300,
00143 portStr = '/dev/robot/RFIDreader',
00144 antFuncs = [], callbacks = []):
00145
00146 Thread.__init__(self)
00147 self.should_run = True
00148
00149 try:
00150 rospy.init_node( 'rfid_m5e_' + name )
00151 except rospy.ROSException:
00152 pass
00153
00154 self.mode = ''
00155 self.name = name + '_reader'
00156
00157 rospy.logout( 'ROS_M5e: Launching RFID Reader' )
00158 rospy.logout( 'ROS_M5e: Please check out our related work @ http://www.hsi.gatech.edu/hrl/project_rfid.shtml' )
00159 rospy.logout( 'ROS_M5e: '+self.name+' Building & Connecting to reader' )
00160
00161 def prin( x ): rospy.logout( 'ROS_M5e: lib_M5e: ' + x )
00162
00163 self.reader = M5e(readPwr=readPwr, portSTR = portStr, verbosity_func = prin)
00164 self.antFuncs = antFuncs
00165 self.callbacks = callbacks + [self.broadcast]
00166
00167 rospy.logout( 'ROS_M5e: publishing RFID reader with type RFIDread to channel /rfid/'+name+'_reader' )
00168 self.channel = rospy.Publisher('/rfid/'+name+'_reader', RFIDread)
00169 self.pub_arr = rospy.Publisher('/rfid/'+name+'_reader_arr', RFIDreadArr)
00170 self._mode_service_obj = rospy.Service('/rfid/'+name+'_mode',
00171 RfidSrv, self._mode_service)
00172
00173 rospy.logout( 'ROS_M5e: '+self.name+' Inialized and awaiting instructions' )
00174
00175 self.start()
00176
00177 def run( self ):
00178 while self.should_run:
00179 if self.mode == self.QUERY_MODE:
00180 for aF in self.antFuncs:
00181 antennaName = aF(self.reader)
00182 results = self.reader.QueryEnvironment()
00183 if len(results) == 0:
00184 results = [[ '', -1 ]]
00185
00186
00187 arr = []
00188 t_now = rospy.Time.now()
00189 for tagid, rssi in results:
00190 rv = RFIDread( None, antennaName, tagid, rssi )
00191 rv.header.stamp = t_now
00192 arr.append( rv )
00193 datum = [antennaName, tagid, rssi]
00194 [cF(datum) for cF in self.callbacks]
00195 rfid_arr = RFIDreadArr()
00196 rfid_arr.header.stamp = t_now
00197 rfid_arr.arr = arr
00198 self.pub_arr.publish( rfid_arr )
00199 elif self.mode == self.TRACK_MODE:
00200 for aF in self.antFuncs:
00201 antennaName = aF(self.reader)
00202 tagid = self.tag_to_track
00203 rssi = self.reader.TrackSingleTag(tagid, timeout=100)
00204 t_now = rospy.Time.now()
00205 rv = RFIDread( None, antennaName, tagid, rssi )
00206 rv.header.stamp = t_now
00207 rfid_arr = RFIDreadArr()
00208 rfid_arr.header.stamp = t_now
00209 rfid_arr.arr = [rv]
00210 self.pub_arr.publish( rfid_arr )
00211
00212 datum = [antennaName, tagid, rssi]
00213 [cF(datum) for cF in self.callbacks]
00214 else:
00215 time.sleep(0.005)
00216
00217 rospy.logout( 'ROS_M5e: '+self.name+' Shutting down reader' )
00218
00219 def stop( self ):
00220 self.should_run = False
00221 self.join(3)
00222 if (self.isAlive()):
00223 raise RuntimeError("ROS_M5e: unable to stop thread")
00224
00225 def broadcast(self, data):
00226 antName, tagid, rssi = data
00227 rv = RFIDread( None, antName, tagid, rssi )
00228 rv.header.stamp = rospy.Time.now()
00229 self.channel.publish( rv )
00230
00231
00232 def _mode_service(self, data):
00233 val = data.data
00234 if len(val) == 0:
00235 rospy.logout( 'ROS_M5e: Mode Service called with invalid argument: ' + str(val) )
00236 elif len(val) == 1:
00237 if val[0] == self.QUERY_MODE:
00238 rospy.logout( 'ROS_M5e: '+self.name+' Entering Query Mode' )
00239 self.mode = self.QUERY_MODE
00240 else:
00241 rospy.logout( 'ROS_M5e: '+self.name+' Stopping Reader' )
00242 self.mode = ''
00243 elif len(val) == 2:
00244 if val[0] == self.TRACK_MODE and len(val[1]) == 12:
00245 rospy.logout( 'ROS_M5e: '+self.name+' Entering Track Mode: ' + str(val[1]) )
00246 self.mode = self.TRACK_MODE
00247 self.tag_to_track = val[1]
00248 else:
00249 rospy.logout( 'ROS_M5e: Mode Service called with invalid argument: ' + str(val) )
00250 else:
00251 rospy.logout( 'ROS_M5e: Mode Service called with invalid argument: ' + str(val) )
00252 return True
00253
00254
00255
00256
00257
00258
00259
00260 def EleLeftEar(M5e):
00261 M5e.ChangeAntennaPorts(1,1)
00262 rospy.sleep(0.010)
00263 return 'EleLeftEar'
00264
00265 def EleRightEar(M5e):
00266 M5e.ChangeAntennaPorts(2,2)
00267 rospy.sleep(0.010)
00268 return 'EleRightEar'
00269
00270 def Hand_Right_1(M5e):
00271
00272 M5e.TransmitCommand('\x02\x96\x01\x01')
00273 M5e.ReceiveResponse()
00274 M5e.TransmitCommand('\x02\x96\x02\x00')
00275 M5e.ReceiveResponse()
00276 return 'Hand_Right_1'
00277
00278 def Hand_Right_2(M5e):
00279
00280 M5e.TransmitCommand('\x02\x96\x01\x01')
00281 M5e.ReceiveResponse()
00282 M5e.TransmitCommand('\x02\x96\x02\x01')
00283 M5e.ReceiveResponse()
00284 return 'Hand_Right_2'
00285
00286 def Hand_Left_1(M5e):
00287
00288 M5e.TransmitCommand('\x02\x96\x01\x00')
00289 M5e.ReceiveResponse()
00290 M5e.TransmitCommand('\x02\x96\x02\x00')
00291 M5e.ReceiveResponse()
00292 return 'Hand_Left_1'
00293
00294 def Hand_Left_2(M5e):
00295
00296 M5e.TransmitCommand('\x02\x96\x01\x00')
00297 M5e.ReceiveResponse()
00298 M5e.TransmitCommand('\x02\x96\x02\x01')
00299 M5e.ReceiveResponse()
00300 return 'Hand_Left_2'
00301
00302 def PrintDatum(data):
00303 ant, ids, rssi = data
00304 print data
00305