00001
00002 import roslib
00003 roslib.load_manifest('rfid_servoing')
00004 import rospy
00005
00006 import hrl_rfid.ros_M5e_client as rmc
00007 from hrl_rfid.msg import RFIDread
00008 import robotis.ros_robotis as rr
00009 import costmap_services.python_client as costmap
00010 from geometry_msgs.msg import Twist
00011 import actionlib
00012
00013 from rfid_servoing.srv import ServoSrv
00014 from rfid_servoing.msg import ServoAction, ServoResult, ServoGoal
00015
00016
00017 import numpy as np, math
00018 from collections import deque
00019 import os
00020 from threading import Lock
00021
00022 def ctime():
00023 return rospy.Time.now().to_time()
00024
00025 def retfalse():
00026 return False
00027
00028 class ServoNode( ):
00029 def __init__( self ):
00030 rospy.logout('servo_node: Initializing')
00031 try:
00032 rospy.init_node('servo_node')
00033 except:
00034 pass
00035
00036
00037 self.p_left = rr.ROS_Robotis_Client( 'left_pan' )
00038 self.t_left = rr.ROS_Robotis_Client( 'left_tilt' )
00039 self.p_right = rr.ROS_Robotis_Client( 'right_pan' )
00040 self.t_right = rr.ROS_Robotis_Client( 'right_tilt' )
00041
00042
00043 self.cs = costmap.CostmapServices( accum = 3 )
00044
00045
00046
00047 self._pub = rospy.Publisher( 'rfid_cmd_vel', Twist )
00048
00049
00050 self._service_servo = rospy.Service( '/rfid_servo/servo', ServoSrv, self.service_request )
00051 self._as = actionlib.SimpleActionServer( '/rfid_servo/servo_act',
00052 ServoAction, execute_cb = self.action_request )
00053 self._as.start()
00054
00055 rospy.logout( 'servo_node: Service ready and waiting' )
00056
00057
00058 def service_request( self, req ):
00059 return self.run( req.tagid )
00060
00061 def action_request( self, goal ):
00062 rospy.logout( 'servo_node: action_request received for tagid: \'%s\'' % goal.tagid )
00063
00064 def preempt_func():
00065
00066 check = self._as.is_preempt_requested()
00067 if check:
00068 rospy.logout( 'servo_node: action_request preempted!' )
00069 return check
00070
00071 rv = self.run( goal.tagid, preempt_func = preempt_func )
00072 rospy.logout( 'servo_node: action_request received result %d' % int(rv) )
00073
00074 if preempt_func():
00075 rospy.logout('servo_node: returning actionlib state preempted.')
00076 self._as.set_preempted()
00077 elif rv == True:
00078 self._as.set_succeeded( ServoResult( int(rv) ))
00079
00080
00081 def run( self, tag_id, preempt_func = retfalse ):
00082
00083
00084 rospy.logout( 'servo_node: Run called for tagid: \'%s\'' % tag_id )
00085
00086
00087 self.robotis_init()
00088
00089
00090 zc = ZedCalc( filt_len = 5, tag_id = tag_id )
00091
00092 rospy.logout('servo_node: Running')
00093
00094 zed_next = zc.next_pub()
00095 r = rospy.Rate( 10 )
00096 while not rospy.is_shutdown() and self.cs.scoreTraj_PosHyst( 0.1, 0.0, zed_next ) != -1.0 and not preempt_func():
00097 move_command = Twist()
00098 move_command.linear.x = 0.1
00099 move_command.angular.z = zed_next
00100
00101 self._pub.publish( move_command )
00102 zc.update_last_pub( zed_next )
00103 zed_next = zc.next_pub()
00104
00105
00106 try:
00107 r.sleep()
00108 except rospy.ROSInterruptException:
00109 pass
00110
00111 self._pub.publish( Twist() )
00112
00113
00114
00115
00116 zc.stop()
00117
00118 if preempt_func():
00119 rospy.logout( 'servo_node: Preempt was requested. May not have finished.' )
00120 rospy.logout( 'servo_node: Exiting' )
00121 return False
00122 else:
00123 rospy.logout( 'servo_node: Exiting' )
00124 return True
00125
00126
00127 def robotis_init( self ):
00128
00129 self.t_left.move_angle( 0.0, math.radians(30), blocking = False )
00130 self.t_right.move_angle( 0.0, math.radians(30), blocking = False )
00131 self.p_left.move_angle( math.radians(40), math.radians(30), blocking = False )
00132 self.p_right.move_angle( math.radians(-40), math.radians(30), blocking = True )
00133
00134 while self.p_left.is_moving() or self.p_right.is_moving():
00135 rospy.sleep( 0.05 )
00136
00137 def robotis_end( self ):
00138
00139 self.t_left.move_angle( 0.0, math.radians(10), blocking = False )
00140 self.t_right.move_angle( 0.0, math.radians(10), blocking = False )
00141 self.p_left.move_angle( 1.350, math.radians(10), blocking = False )
00142 if not (os.environ.has_key('ROBOT') and os.environ['ROBOT'] == 'sim'):
00143 self.p_right.move_angle( -1.350, math.radians(10), blocking = False )
00144 else:
00145 self.p_right.move_angle( -1.350, math.radians(10), blocking = True )
00146
00147
00148
00149 class ZedCalc( ):
00150
00151 def __init__( self, tag_id, sub_name = '/rfid/ears_reader', filt_len = 5 ):
00152 rospy.logout( 'ZedCalc: Initializing' )
00153
00154 self.values = { 'EleLeftEar': 75.0,
00155 'EleRightEar': 75.0 }
00156
00157 self.lock = Lock()
00158 self.buff_len = filt_len * 2
00159 self.zed_buff = deque( np.zeros( self.buff_len ))
00160
00161 self.last_zed = 0.0
00162 self.new_zed = 0.0
00163
00164 self._sub = rospy.Subscriber( sub_name, RFIDread, self.callback)
00165 self.reader = rmc.ROS_M5e_Client('ears')
00166 self.reader.track_mode( tag_id )
00167
00168 rospy.logout( 'ZedCalc: Ready.' )
00169
00170 def stop( self ):
00171 rospy.logout( 'ZedCalc: Stopping RFID reader' )
00172 self.reader.stop()
00173
00174
00175 def callback( self, msg ):
00176 self.values[ msg.antenna_name ] = np.clip( msg.rssi, 75.0, 110.0 )
00177 left = self.values[ 'EleLeftEar' ]
00178 right = self.values[ 'EleRightEar' ]
00179
00180 self.lock.acquire()
00181 self.zed_buff.append( 0.10 * (left - right)/5.0 )
00182 if len( self.zed_buff ) > self.buff_len:
00183 self.zed_buff.popleft()
00184 self.lock.release()
00185
00186 def next_pub( self, angle_slew = math.radians( 10 )):
00187 self.lock.acquire()
00188 target = np.mean( self.zed_buff )
00189 self.lock.release()
00190
00191 lz = self.last_zed
00192 return lz + np.clip( target - lz, -1.0 * angle_slew, angle_slew )
00193
00194 def update_last_pub( self, pub_val ):
00195 self.last_zed = pub_val
00196
00197
00198
00199 if __name__ == '__main__':
00200
00201 sn = ServoNode()
00202 rospy.spin()
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228