artoolkit_detector.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 
00003 import roslib
00004 roslib.load_manifest('rfid_artoolkit')
00005 import rospy
00006 
00007 import tf
00008 import actionlib
00009 from actionlib_msgs.msg import GoalStatus
00010 from pr2_controllers_msgs.msg import PointHeadAction, PointHeadGoal
00011 from geometry_msgs.msg import PointStamped
00012 from ar_pose.msg import ARMarkers
00013 
00014 import time
00015 from threading import Thread, Lock
00016 import numpy as np, math
00017 from collections import deque
00018 
00019 def ctime():
00020     return rospy.Time.now().to_time()
00021 
00022 def retfalse():
00023     return False
00024 
00025 def goal( frame, pos, d ):
00026     g = PointHeadGoal()
00027     g.target.header.frame_id = frame
00028     g.target.point.x = pos[0]
00029     g.target.point.y = pos[1]
00030     g.target.point.z = pos[2]
00031     g.min_duration = rospy.Duration( d )
00032     # Note, looking @ head action source, it seems pointing_frame unimplemented...
00033     #   Just account with a static offset (for now) where desired.
00034     return g
00035 
00036 class ARtagDetect():
00037     def __init__( self ):
00038         try:
00039             rospy.init_node('ar_detect_tracker')
00040         except: # Parent already initialized
00041             pass
00042 
00043         rospy.logout('ARtagDetect: Initializing.')
00044 
00045         self.lock = Lock() # for last_pos & found_tag
00046         self.found_tag = False
00047         self.init_pos = [ 0.54, 0.0, 0.35 ]
00048         self.last_pos = [ 0.54, 0.0, 0.35 ]
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         rospy.logout('ARtagDetect: Ready and Running.')
00058 
00059     def processARtag( self, msg ):
00060         if msg.markers != []:
00061             frame = msg.markers[0].header.frame_id
00062             p = msg.markers[0].pose.pose.position
00063 
00064             pt = PointStamped()
00065             pt.header.frame_id = frame
00066             pt.point.x = p.x
00067             pt.point.y = p.y 
00068             pt.point.z = p.z
00069             pt.header.stamp = rospy.Time(0)
00070 
00071             try:
00072                 pt_bl = self.listener.transformPoint( '/torso_lift_link', pt )
00073                 pbl = pt_bl.point
00074                 # pointing_frame manual offset (should actually be on p.y,
00075                 #   but this is a good approximation with less noise in robot frame).
00076                 pbl.z = pbl.z - 0.2
00077 
00078                 self.lock.acquire()
00079                 self.last_pos = [ pbl.x, pbl.y, pbl.z ]
00080                 self.found_tag = True
00081                 self.lock.release()
00082             except:
00083                 rospy.logout( 'ARtagDetect: Transform failed' )
00084 
00085     def init_new_detection( self ):
00086         self.lock.acquire()
00087         self.last_pos = self.init_pos
00088         self.found_tag = False
00089         self.lock.release()
00090 
00091     def found_new_tag( self ):
00092         self.lock.acquire()
00093         rv = ( self.found_tag, self.last_pos, '/torso_lift_link' )
00094         self.lock.release()
00095         return rv
00096 
00097 
00098 class ARtagScan():
00099     def __init__( self ):
00100         try:
00101             rospy.init_node('artag_scanner')
00102         except: # Parent already initialized
00103             pass
00104 
00105         rospy.logout( 'ARtagScan: Initializing' )
00106 
00107         self.detector = ARtagDetect()
00108         
00109         self.hc = actionlib.SimpleActionClient('/head_traj_controller/point_head_action', PointHeadAction) # headclient
00110         self.hc.wait_for_server()
00111         
00112         rospy.logout( 'ARtagScan: Ready and Running.' )
00113 
00114     def scan( self, preempt_func = retfalse ):
00115         # self.hc.send_goal( goal( 'torso_lift_link', [0.54, 0.2, 0.25], 2.0 ))
00116         # self.hc.wait_for_result( rospy.Duration( 2.0 ))
00117 
00118         rospy.logout('ARtagScan: starting sweep')
00119         
00120         cmds = [ [0.54, -0.2, 0.25],
00121                  [0.54, 0.2, -0.10],
00122                  [0.54, -0.2, 0.0],
00123                  [0.54, 0.2, 0.20],
00124                  [0.54, -0.2, 0.30],
00125                  [0.54, 0.0, 0.35] ]
00126 
00127         self.detector.init_new_detection()
00128 
00129         found_tag, pos, frame = self.detector.found_new_tag()
00130         for cmd in cmds:
00131             if not rospy.is_shutdown() and not found_tag and not preempt_func():
00132                 self.hc.send_goal( goal( 'torso_lift_link', cmd, 6.0 ))
00133                 found_tag, pos, frame = self.detector.found_new_tag()
00134 
00135                 goal_done = False
00136                 while not rospy.is_shutdown() and not goal_done and not found_tag and not preempt_func():
00137                     found_tag, pos, frame = self.detector.found_new_tag()
00138                     goal_done = self.hc.wait_for_result( rospy.Duration( 0.05 )) # ~20Hz
00139 
00140                 self.hc.cancel_all_goals() # just in case
00141 
00142         if preempt_func():
00143             rospy.logout( 'ARtagScan: Preempt was requested. May not have finished.' )
00144             rospy.logout( 'ARtagScan: Exiting' )
00145             return ( False, found_tag, pos, frame )
00146         else:
00147             rospy.logout( 'ARtagScan: Exiting' )
00148             return ( True, found_tag, pos, frame )
00149 
00150 
00151     def settle( self, init_pos, init_frame, preempt_func = retfalse ):
00152         rospy.logout('ARtagScan: Starting settle. Looking at detection')
00153 
00154         # Look in direction of initial read
00155         self.hc.send_goal( goal( init_frame, init_pos, 2.0 ))
00156         self.hc.wait_for_result( rospy.Duration( 2.0 ))
00157         
00158         buff = deque()
00159         buff.append( init_pos )
00160 
00161         rospy.sleep( 0.3 )
00162         settle = 5.0
00163         stime = ctime()
00164 
00165         rospy.logout('ARtagScan: Averaging scans')
00166 
00167         # Refine the estimate
00168         found_tag = False
00169         self.detector.init_new_detection()
00170         self.hc.send_goal( goal( init_frame, init_pos, 0.5 ))
00171         goal_reached = False
00172         r = rospy.Rate( 20 )
00173         while not rospy.is_shutdown() and ctime() - stime < settle:
00174             #print 'Times: ', ctime(), stime
00175             found_tag, pos, frame = self.detector.found_new_tag()
00176             if found_tag:
00177                 buff.append( pos )
00178                 found_tag = False
00179                 self.detector.init_new_detection()
00180 
00181             goal_reached = self.hc.wait_for_result( rospy.Duration( 0.02 ))
00182             if goal_reached:
00183                 mean_pos = np.mean( buff, axis = 0 )
00184                 self.hc.send_goal( goal( init_frame, mean_pos, 0.5 ))
00185 
00186             r.sleep()
00187 
00188         self.hc.wait_for_result( rospy.Duration( 2.0 ))
00189         mean_pos = np.mean( buff, axis = 0 )
00190         return ( True, mean_pos, init_frame )
00191 
00192 
00193 def testDetect():
00194     rospy.init_node( 'testDetect' )
00195     rate = rospy.Rate( 1.0 )
00196     detector = ARtagDetect()
00197     detector.init_new_detection()
00198 
00199     found_tag, pos, frame = detector.found_new_tag()
00200 
00201     while not rospy.is_shutdown():
00202         found_tag, pos, frame = detector.found_new_tag()
00203         print found_tag, pos, frame
00204         rate.sleep()
00205 
00206 def testScan():
00207     rospy.init_node( 'testScan' )
00208     rate = rospy.Rate( 1.0 )
00209     scanner = ARtagScan()
00210 
00211     rv = scanner.scan()
00212     print 'scanner res: ', rv
00213     success, found_tag, pos, frame = rv
00214 
00215     rv = scanner.settle( pos, frame )
00216     print 'settle res: ', rv
00217 
00218 
00219 if __name__ == '__main__':
00220     #testDetect()
00221     testScan()


rfid_artoolkit
Author(s): Travis Deyle
autogenerated on Wed Nov 27 2013 11:49:51