upclose_detector.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 
00003 # Without the in-hand RFID reader, use ARToolKit instead for upclose
00004 # (nearfield) validation
00005 
00006 import roslib
00007 roslib.load_manifest('rfid_artoolkit')
00008 import rospy
00009 
00010 import rfid_servoing.servo as servo
00011 import costmap_services.python_client as costmap
00012 import artoolkit_detector as artag
00013 import actionlib
00014 
00015 from rfid_artoolkit.srv import ARServoSrv, ARServoSrvResponse
00016 from rfid_artoolkit.msg import UpCloseAction, UpCloseResult, UpCloseGoal
00017 
00018 class ARservoScan():
00019     # Uses ARtagScan along with costmap functionality (ie. in rfid_servoing) to
00020     # determine when to preempt the ARtagScan and continue servoing.
00021 
00022     # This class is used to keep the artoolkit_detector somewhat decoupled from all this other jazz.
00023     def __init__( self ):
00024         try:
00025             rospy.init_node('artag_superclass')
00026         except: # Parent already initialized
00027             pass
00028 
00029         rospy.logout( 'ARservoScan: Initializing' )
00030 
00031         self.scanner = artag.ARtagScan()
00032 
00033         # Create Costmap Services obj
00034         self.cs = costmap.CostmapServices( accum = 15 )
00035         self._service = rospy.Service( '/rfid_artoolkit/upclose', ARServoSrv, self.service_request )
00036         self._as = actionlib.SimpleActionServer( '/rfid_artoolkit/upclose_act',
00037                                                  UpCloseAction, execute_cb = self.action_request )
00038         self._as.start()
00039 
00040         # Note: After moving, this will require accum * -1's before stopping.
00041 
00042         rospy.logout( 'ARservoScan: Ready and Running.' )
00043 
00044 
00045     def service_request( self, req ):
00046         success, found_tag, pos, frame = self.scan( req.tagid )
00047         
00048         rv = ARServoSrvResponse()
00049         rv.success = success and found_tag # not preempted & found tag
00050         if success and found_tag:
00051             rv.ps.header.frame_id = frame
00052             rv.ps.header.stamp = rospy.Time.now()
00053             rv.ps.point.x = pos[0]
00054             rv.ps.point.y = pos[1]
00055             rv.ps.point.z = pos[2]
00056 
00057         return rv
00058 
00059     
00060     def action_request( self, goal ):
00061         rospy.logout( 'ARservoScan: action_request received for tagid: \'%s\'' % goal.tagid )
00062 
00063         zc = servo.ZedCalc( filt_len = 5, tag_id = goal.tagid )
00064 
00065         def free_to_move_preempt():
00066             # Note: I believe the variables are scoped at time of func def
00067             zed_next = zc.next_pub() # Where does RFID want to go?
00068             costmap_rv = self.cs.scoreTraj_NegHyst( 0.1, 0.0, zed_next )
00069             #print zed_next
00070             #print costmap_rv
00071             if costmap_rv == -1.0:
00072                 #rospy.logout( 'Obstacle still present.' )
00073                 return False # Still keep scaning
00074             else:
00075                 rospy.logout( 'ARservoScan: Obstacle Gone... PREEMPT!' )
00076                 return True # Whatever was in way is gone. Should go back to servoing.
00077 
00078         def actionlib_preempt():
00079             check = self._as.is_preempt_requested()
00080             if check:
00081                 rospy.logout( 'ARservoScan: actionlib Preempt requested.  PREEMPT!' )
00082             return check
00083 
00084         def preempt_func():
00085             return free_to_move_preempt() or actionlib_preempt()
00086         
00087         success, found_tag, pos, frame = self.scanner.scan( preempt_func = preempt_func )
00088         # Success will be false if it was preempted (eg. preempt_func returns True)
00089 
00090         zc.stop() # Stop the RFID reader...
00091 
00092         if success and found_tag:
00093             found_tag, pos, frame = self.scanner.settle( pos, frame )
00094 
00095         if success:  # Weren't preempted
00096             if found_tag:
00097                 status = 'SUCCEEDED'
00098             else:
00099                 status = 'FAILED'
00100         else:
00101             if actionlib_preempt(): # preempt caused by actionlib
00102                 status = 'PREEMPTED'
00103             else: # obstacle is clear
00104                 status = 'RESERVO'
00105                 
00106         rospy.logout( 'ARservoScan: Scan completed.' )
00107 
00108         rv = UpCloseResult()
00109         rv.success = success and found_tag # not preempted & found tag
00110         rv.status = status
00111         if success and found_tag:
00112             rv.ps.header.frame_id = frame
00113             rv.ps.header.stamp = rospy.Time.now()
00114             rv.ps.point.x = pos[0]
00115             rv.ps.point.y = pos[1]
00116             rv.ps.point.z = pos[2]
00117         
00118         self._as.set_succeeded( rv )
00119 
00120 
00121     def scan( self, tag_id ):
00122         # Note: action_request does pretty much the same thing, but with preemption.
00123 
00124         rospy.logout( 'ARservoScan: Scan requested for tagid \'%s\'' % tag_id )
00125         # Subscribe to RFID reader to figure out where it wants to go.
00126         zc = servo.ZedCalc( filt_len = 5, tag_id = tag_id )
00127 
00128         def preempt_func():
00129             # Note: I believe the variables are scoped at time of func def
00130             zed_next = zc.next_pub() # Where does RFID want to go?
00131             costmap_rv = self.cs.scoreTraj_NegHyst( 0.1, 0.0, zed_next )
00132             #print zed_next
00133             #print costmap_rv
00134             if costmap_rv == -1.0:
00135                 #rospy.logout( 'Obstacle still present.' )
00136                 return False # Still keep scaning
00137             else:
00138                 rospy.logout( 'ARservoScan: Obstacle Gone... PREEMPT!' )
00139                 return True # Whatever was in way is gone. Should go back to servoing.
00140         
00141         success, found_tag, pos, frame = self.scanner.scan( preempt_func = preempt_func )
00142         # Success will be false if it was preempted (eg. preempt_func returns True)
00143 
00144         zc.stop() # Stop the RFID reader...
00145 
00146         if success and found_tag:
00147             found_tag, pos, frame = self.scanner.settle( pos, frame )
00148 
00149         rospy.logout( 'ARservoScan: Scan completed.' )
00150         #print 'scan result: ', success, found_tag, pos, frame
00151         return ( success, found_tag, pos, frame )
00152 
00153 
00154 def testScan():
00155     rospy.init_node( 'testScan' )
00156 
00157     servoScan = ARservoScan()
00158     success, found_tag, pos, frame = servoScan.scan( 'person      ' )
00159     print 'results: ', success, found_tag, pos, frame
00160 
00161 if __name__ == '__main__':
00162 
00163     ss = ARservoScan()
00164     rospy.spin()
00165 
00166 
00167     # There are (at least) three ways to call this code.
00168     # 1) Python:
00169     
00170     # testScan()
00171 
00172     # 2) ROS service:
00173 
00174     # rosservice call /rfid_artoolkit/upclose "'person      '"
00175 
00176     # 3) ROS actionlib:
00177 
00178     # try:
00179     #     client = actionlib.SimpleActionClient( '/rfid_artoolkit/upclose_act', UpCloseAction )
00180     #     client.wait_for_server()
00181     #     client.send_goal( UpCloseGoal( 'person      ' ))
00182     #     # Test Preempt
00183     #     # rospy.sleep( 10 )
00184     #     # client.cancel_all_goals()
00185     #     client.wait_for_result()
00186     #     print client.get_result()
00187 
00188     # except rospy.ROSInterruptException:
00189     #     print 'Program interrupted before completion'
00190 
00191     # rospy.spin()
00192 
00193     


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