servo_node.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 import time
00003 import roslib
00004 roslib.load_manifest('rospy')
00005 roslib.load_manifest('geometry_msgs')
00006 roslib.load_manifest('hrl_rfid')
00007 roslib.load_manifest('robotis')
00008 
00009 import time
00010 import rospy
00011 from geometry_msgs.msg import Twist
00012 import numpy as np, math
00013 import hrl_rfid.ros_M5e_client as rmc
00014 import robotis.ros_robotis as rr
00015 from threading import Thread
00016 
00017 class ServoNode( Thread ):
00018     def __init__( self ):
00019         Thread.__init__( self )
00020 
00021         self.should_run = True
00022 
00023         rospy.logout('servo_node: Initializing')
00024         rospy.init_node('servo_node')
00025 
00026         # Unfold "ears" to servo positions
00027         p_left = rr.ROS_Robotis_Client( 'left_pan' )
00028         t_left = rr.ROS_Robotis_Client( 'left_tilt' )
00029 
00030         p_left.move_angle( math.radians(-40), math.radians(10), blocking = False )
00031         t_left.move_angle( 0.0, math.radians(10), blocking = False )
00032 
00033         p_right = rr.ROS_Robotis_Client( 'right_pan' )
00034         t_right = rr.ROS_Robotis_Client( 'right_tilt' )
00035     
00036         p_right.move_angle( math.radians(40), math.radians(10), blocking = False )
00037         t_right.move_angle( 0.0, math.radians(10), blocking = False )
00038 
00039         self.reader = rmc.ROS_M5e_Client('ears')
00040         self.reader.track_mode('person      ')
00041 
00042         # Use assisted teleop as pseudo-callback to see if valid movement:
00043         self.check_pub = rospy.Publisher( 'rfid_cmd_vel_check', Twist )
00044         self.sub = rospy.Subscriber( "assisted_teleop_response", Twist, self.callback )
00045         self.command_pub = rospy.Publisher( "rfid_cmd_vel", Twist )
00046 
00047         self.moving = True
00048         time.sleep(3.0) # give antennas time to settle
00049 
00050         self.start()
00051 
00052     def callback( self, msg ):
00053         #print 'Hit callback: ', msg
00054         self.response_received = True
00055         self.response = msg
00056 
00057     def sloppy_check( self, desired_movement, timeout = 5.0 ):
00058         #print 'Checking: ', desired_movement
00059         # Simple statemachine with self.callback.  Checks to see if
00060         # assisted teleop returns an unaltered command
00061         self.response_received = False
00062         self.response = Twist()
00063 
00064         self.check_pub.publish( desired_movement )
00065         t0 = time.time()
00066 
00067         # wait for the callback to be received
00068         while not self.response_received and time.time() - t0 < timeout and self.should_run and not rospy.is_shutdown():
00069             time.sleep(0.01)
00070 
00071         # Apply some hysteresis to starting & stopping conditions
00072         if self.moving:
00073             if self.response.linear.x > 0.04:
00074                 self.moving = True  # As long as safe move is within 40%, keep moving
00075                 return self.response, True  
00076             else:
00077                 self.moving = False
00078                 return Twist(), False # Otherwise stop
00079         else:
00080             if self.response.linear.x > 0.075: 
00081                 self.moving = True  # Wait until it is within 75% to resume movement
00082                 return self.response, True  
00083             else:
00084                 self.moving = False
00085                 return Twist(), False # Otherwise remain stop
00086         
00087                 
00088             
00089 
00090     def run( self ):
00091         rospy.logout('servo_node: Running')
00092         filt_x = []
00093         filt_z = []
00094 
00095         while self.should_run and not rospy.is_shutdown():
00096             left = self.reader.read('EleLeftEar')[-1]
00097             if left == -1 or left < 75:
00098                 left = 75
00099             right = self.reader.read('EleRightEar')[-1]
00100             if right == -1 or right < 75:
00101                 right = 75
00102 
00103             check = Twist()
00104             check.linear.x = 0.1
00105             check.angular.z = 0.07 * (left - right)/5.0 
00106 
00107             safe_move, continue_moving = self.sloppy_check( check )
00108 
00109             if continue_moving:
00110                 filt_z.append( check.angular.z )
00111                 filt_x.append( check.linear.x )
00112             else:
00113                 filt_z.append( 0.0 )
00114                 filt_x.append( 0.0 )
00115                 
00116             if len( filt_z ) < 5 or len( filt_x ) < 5: # let the 5-point averager fill up.
00117                 continue
00118             filt_z = filt_z[1:]
00119             filt_x = filt_x[1:]
00120 
00121             filt_movement = Twist()
00122             filt_movement.linear.x = np.average( filt_x )
00123             filt_movement.angular.z = np.average( filt_z )
00124 
00125             self.command_pub.publish( filt_movement )
00126             time.sleep(0.01)
00127 
00128         # Stop the RFID reader (conserve power and hardware)
00129         try:
00130             r.stop()
00131         except: 
00132             # If servo_node is being run in the same launch file, stop is a
00133             #    race condition with service disappearing.  Just ignore.
00134             pass
00135         
00136         self.command_pub.publish( Twist() )  # Halt the base (just in case)
00137         rospy.logout('servo_node: Exiting')
00138 
00139 
00140     def stop( self ):
00141         self.should_run = False
00142         self.join(3)
00143         if (self.isAlive()):
00144             raise RuntimeError("servo_node: unable to stop thread")
00145 
00146 
00147 if __name__ == '__main__':
00148     sn = ServoNode()
00149     rospy.spin()
00150     sn.stop()
00151 


rfid_people_following
Author(s): Travis Deyle (Healthcare Robotics Lab, Georgia Tech)
autogenerated on Wed Nov 27 2013 11:38:30