nao_behaviors.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 #
00004 # ROS node to control NAO's built-in and user-installed behaviors using NaoQI
00005 # Tested with NaoQI: 1.12
00006 #
00007 # Copyright (c) 2012, 2013 Miguel Sarabia
00008 # Imperial College London
00009 #
00010 # Redistribution and use in source and binary forms, with or without
00011 # modification, are permitted provided that the following conditions are met:
00012 #
00013 #    # Redistributions of source code must retain the above copyright
00014 #       notice, this list of conditions and the following disclaimer.
00015 #    # Redistributions in binary form must reproduce the above copyright
00016 #       notice, this list of conditions and the following disclaimer in the
00017 #       documentation and/or other materials provided with the distribution.
00018 #    # Neither the name of the Imperial College London nor the names of its
00019 #       contributors may be used to endorse or promote products derived from
00020 #       this software without specific prior written permission.
00021 #
00022 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00023 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00026 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00027 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00028 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00029 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00030 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 # POSSIBILITY OF SUCH DAMAGE.
00033 #
00034 
00035 import threading
00036 import roslib
00037 
00038 roslib.load_manifest('nao_driver')
00039 
00040 import rospy
00041 import actionlib
00042 
00043 from nao_driver import *
00044 
00045 from nao_msgs.msg import(
00046     RunBehaviorAction,
00047     RunBehaviorResult
00048     )
00049 
00050 from nao_msgs.srv import (
00051     GetInstalledBehaviors, 
00052     GetInstalledBehaviorsResponse,
00053     )
00054 
00055 class NaoBehaviors(NaoNode):
00056     #This should be treated as a constant
00057     NODE_NAME = "nao_behaviors"
00058     
00059     def __init__( self ):
00060         
00061         #Initialisation
00062         NaoNode.__init__( self )
00063         rospy.init_node( self.NODE_NAME )
00064         
00065         #We need this variable to be able to call stop behavior when preempted
00066         self.behavior = None
00067         self.lock = threading.RLock()
00068         
00069         #Proxy for listingBehaviors and stopping them
00070         self.behaviorProxy = self.getProxy( "ALBehaviorManager" )
00071         
00072         # Register ROS services
00073         self.getInstalledBehaviorsService = rospy.Service(
00074             "get_installed_behaviors",
00075             GetInstalledBehaviors,
00076             self.getInstalledBehaviors
00077             )
00078         
00079         #Prepare and start actionlib server
00080         self.actionlibServer = actionlib.SimpleActionServer(
00081             "run_behavior",
00082             RunBehaviorAction,
00083             self.runBehavior,
00084             False
00085             )
00086         
00087         self.actionlibServer.register_preempt_callback( self.stopBehavior )
00088         
00089         self.actionlibServer.start()
00090     
00091     def getInstalledBehaviors( self, request ):
00092         result = self.behaviorProxy.getInstalledBehaviors()
00093         return GetInstalledBehaviorsResponse( result )
00094     
00095     
00096     def runBehavior( self, request ):
00097         #Note this function is executed from a different thread
00098         rospy.logdebug(
00099             "Execution of behavior: '{}' requested".format(request.behavior))
00100         
00101         #Check requested behavior is installed
00102         if not request.behavior in self.behaviorProxy.getInstalledBehaviors():
00103             error_msg = "Behavior '{}' not installed".format(request.behavior)
00104             self.actionlibServer.set_aborted(text = error_msg)
00105             rospy.logdebug(error_msg)
00106             return
00107         
00108         with self.lock:
00109             # Check first if we're already preempted, and return if so
00110             if self.actionlibServer.is_preempt_requested():
00111                 self.actionlibServer.set_preempted()
00112                 rospy.logdebug("Behavior execution preempted before it started")
00113                 return
00114 
00115             #Save name of behavior to be run
00116             self.behavior = request.behavior
00117             #Execute behavior (on another thread so we can release lock)
00118             taskID = self.behaviorProxy.post.runBehavior( self.behavior )
00119 
00120         # Wait for task to complete (or be preempted)    
00121         rospy.logdebug("Waiting for behavior execution to complete")
00122         self.behaviorProxy.wait( taskID, 0 )
00123         
00124         #Evaluate results
00125         with self.lock:
00126             self.behavior = None
00127             # If preempted, report so
00128             if self.actionlibServer.is_preempt_requested() :
00129                 self.actionlibServer.set_preempted()
00130                 rospy.logdebug("Behavior execution preempted")
00131             # Otherwise, set as succeeded
00132             else:
00133                 self.actionlibServer.set_succeeded()
00134                 rospy.logdebug("Behavior execution succeeded")
00135 
00136     def stopBehavior( self ):
00137         with self.lock:
00138             if self.behavior and self.actionlibServer.is_active() :
00139                 self.behaviorProxy.stopBehavior( self.behavior )
00140 
00141 
00142 if __name__ == '__main__':
00143     node = NaoBehaviors()
00144     rospy.loginfo( node.NODE_NAME + " running..." )
00145     rospy.spin()
00146     rospy.loginfo( node.NODE_NAME + " stopped." )
00147     exit(0)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


nao_driver
Author(s): Armin Hornung, Stefan Osswald, Daniel Maier
autogenerated on Tue Oct 15 2013 10:06:23