artoolkit_detector.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 # Taken from Tiffany & Kelsey and readapted to my needs.
00003 
00004 import roslib
00005 roslib.load_manifest('hrl_pr2_lib')
00006 roslib.load_manifest('ar_pose')
00007 roslib.load_manifest('rfid_people_following')
00008 import rospy
00009 import tf
00010 import actionlib
00011 from actionlib_msgs.msg import GoalStatus
00012 from pr2_controllers_msgs.msg import PointHeadAction, PointHeadGoal
00013 from geometry_msgs.msg import PointStamped
00014 from rfid_people_following.srv import FloatFloatFloatFloat_Int32 as arm_srv
00015 from ar_pose.msg import ARMarkers
00016 
00017 import time
00018 from threading import Thread
00019 import numpy as np, math
00020 
00021 def ctime():
00022     return rospy.Time.now().to_time()
00023 
00024 def goal( frame, pos, d ):
00025     g = PointHeadGoal()
00026     g.target.header.frame_id = frame
00027     g.target.point.x = pos[0]
00028     g.target.point.y = pos[1]
00029     g.target.point.z = pos[2]
00030     g.min_duration = rospy.Duration( d )
00031     # Note, looking @ head action source, it seems pointing_frame unimplemented...
00032     #   Just account with a static offset (for now) where desired.
00033     return g
00034 
00035 class ARtagDetect():
00036     def __init__( self ):
00037         try:
00038             rospy.init_node('ar_detect_tracker')
00039         except: # Parent already initialized
00040             pass
00041 
00042         self.found_tag = False
00043         self.settling = False
00044         self.last_pos = [ 0.54, 0.0, 0.35 ]
00045         self.last_logout = ctime()
00046 
00047         self.hc = actionlib.SimpleActionClient('/head_traj_controller/point_head_action', PointHeadAction) # headclient
00048         self.hc.wait_for_server()
00049         
00050         self.listener = tf.TransformListener()
00051         self.listener.waitForTransform('/torso_lift_link', '/openni_rgb_optical_frame',
00052                                        rospy.Time(0), timeout = rospy.Duration(100) )
00053 
00054         self.artag_sub = rospy.Subscriber( '/artag_marker_handoff',
00055                                            ARMarkers,
00056                                            self.processARtag )
00057         self.abort = False
00058         rospy.logout('ARtagDetect: Ready and Running.')
00059 
00060     def processARtag( self, msg ):
00061         if msg.markers != []:
00062             frame = msg.markers[0].header.frame_id
00063             p = msg.markers[0].pose.pose.position
00064 
00065             pt = PointStamped()
00066             pt.header.frame_id = frame
00067             pt.point.x = p.x
00068             pt.point.y = p.y 
00069             pt.point.z = p.z
00070             pt.header.stamp = rospy.Time(0)
00071 
00072             try:
00073                 pt_bl = self.listener.transformPoint( '/torso_lift_link', pt )
00074                 pbl = pt_bl.point
00075                 # pointing_frame manual offset (should actually be on p.y,
00076                 #   but this is a good approximation with less noise in robot frame).
00077                 pbl.z = pbl.z - 0.2 
00078                 self.last_pos = [ pbl.x, pbl.y, pbl.z ]
00079                 if not self.found_tag:
00080                     self.hc.cancel_all_goals() # stop searching
00081                 self.found_tag = True
00082             except:
00083                 print pt
00084                 rospy.logout( 'ARtagDetect: Transform failed' )
00085                 return False
00086             
00087         else:
00088             if not self.found_tag and ctime() - self.last_logout > 3.0:
00089                 rospy.logout( 'ARtag still undetected...' )
00090                 self.last_logout = ctime()
00091 
00092     def scan( self ):
00093         rate = rospy.Rate(10)
00094         
00095         self.hc.send_goal( goal( 'torso_lift_link', [0.54, 0.2, 0.25], 2.0 ))
00096         self.hc.wait_for_result()
00097         rospy.logout('ARtagDetect: starting sweep')
00098         
00099         cmds = [ [0.54, -0.2, 0.25],
00100                  [0.54, 0.2, -0.10],
00101                  [0.54, -0.2, 0.0],
00102                  [0.54, 0.2, 0.20],
00103                  [0.54, -0.2, 0.30],
00104                  [0.54, 0.0, 0.35] ]
00105 
00106         q_rate = rospy.Rate(30)
00107         for cmd in cmds:
00108             self.hc.send_goal( goal( 'torso_lift_link', cmd, 6.0 ))
00109             self.hc.wait_for_result( rospy.Duration( 6.0 ))
00110             if self.found_tag or self.abort:
00111                 break
00112 
00113         if not self.found_tag or self.abort:
00114             self.hc.cancel_all_goals() # just in case
00115             self.hc.send_goal( goal( 'torso_lift_link', [0.54, 0.0, 0.35], 2.0 ))
00116             self.hc.wait_for_result()
00117             return (False, 'torso_lift_link', self.last_pos)
00118 
00119         self.hc.cancel_all_goals() # just in case
00120         rate.sleep()
00121 
00122         rospy.logout('ARtagDetect: Tag detected!')
00123         self.settling = True
00124 
00125         settle = ctime()
00126         pos = list( self.last_pos )
00127         
00128         #while not rospy.is_shutdown():
00129         while ctime() - settle < 1.5 and not self.abort:
00130             self.hc.send_goal( goal( 'torso_lift_link', self.last_pos, 1.0 ))
00131             self.hc.stop_tracking_goal()
00132             if not np.allclose( pos, self.last_pos, rtol=0.15 ): # not settled within 5cm per axis?
00133                 print 'Pos: ', pos, ' LastPos: ', self.last_pos
00134                 settle = ctime()    # reset counter
00135                 pos = list( self.last_pos ) # reset basis pose
00136             rate.sleep()
00137 
00138         self.hc.cancel_all_goals() # just in case
00139         rate.sleep()
00140         # return (success, link, pose)
00141         rospy.logout( 'Tag found!' )
00142         self.settling = False
00143         return (True, 'torso_lift_link', pos)
00144 
00145 
00146 class ARthread( Thread ):
00147     def __init__( self ):
00148         Thread.__init__( self )
00149         self.should_run = True
00150 
00151         self.d = ARtagDetect()
00152         self.should_scan = False
00153         self.res = False, 'linkname', [1.0, 1.0, 1.0]
00154         self.success = False
00155         self.logtime = ctime()
00156         self.logtime1 = ctime()
00157 
00158         self.start()
00159 
00160     def run( self ):
00161         r = rospy.Rate( 10 )
00162         while self.should_run and not rospy.is_shutdown():
00163             if self.should_scan and not self.success:
00164                 self.d.abort = False
00165                 self.d.found_tag = False
00166                 self.d.settling = False
00167                 self.res = self.d.scan()
00168                 self.success, link, pos = self.res
00169             r.sleep()
00170 
00171     def scan( self ):
00172         if ctime() - self.logtime > 3.0:
00173             self.logtime = ctime()
00174             rospy.logout('ARthread: started scanning')
00175         #self.res = False, 'linkname', [1.0, 1.0, 1.0]
00176         self.should_scan = True
00177 
00178     def found_tag( self ):
00179         return self.d.found_tag
00180 
00181     def settling( self ):
00182         return self.d.settling
00183 
00184     def abort( self ):
00185         if ctime() - self.logtime1 > 3.0:
00186             self.logtime1 = ctime()
00187             rospy.logout('ARthread: scanning aborted.')
00188         self.should_scan = False
00189         self.d.abort = True
00190             
00191     def stop( self ):
00192         self.should_run = False
00193         self.join(10)
00194         if (self.isAlive()):
00195             raise RuntimeError("ARNode: unable to stop thread")            
00196 
00197 if __name__ == '__main__':
00198     ar = ARthread()
00199     print 'Starting scann'
00200     ar.scan()
00201     print 'Sleeping 10 sec.'
00202     time.sleep( 10.0 )
00203     ar.abort()
00204     print 'Aborted...'
00205     print 'Result: ', ar.res
00206     ar.stop()
00207 
00208 
00209 # if __name__ == '__main__':
00210 #     detector = ARtagDetect( )
00211 #     print 'done'
00212 #     rospy.wait_for_service( '/rfid_handoff/handoff_pos' )
00213 #     print 'done1'
00214 #     _hopos = rospy.ServiceProxy( '/rfid_handoff/handoff_pos', arm_srv )
00215 #     hopos = lambda x,y,z,a: _hopos( x,y,z,a )
00216 
00217 #     success, link, pos = detector.scan()
00218 #     print 'Pos: ', pos
00219 #     x,y,z = pos
00220 #     ang = 0.0
00221 #     if success == True:
00222 #         # hacky! Pull the handoff point (wrist) 36cm closer to robot in xy-plane
00223 #         r = np.sqrt( x ** 2.0 + y ** 2.0 )
00224 #         theta = np.arctan2( y, x )
00225 #         r = r - 0.36 
00226 #         x_new = r * np.cos( theta )
00227 #         print 'x_new: ', x_new
00228 #         y_new = r * np.sin( theta )
00229 #         hopos( x_new, y_new, z + 0.20, ang )


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