$search
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, 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 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 = "" 00067 00068 #Proxy for listingBehaviors and stopping them 00069 self.behaviorProxy = self.getProxy( "ALBehaviorManager" ) 00070 00071 # Register ROS services 00072 self.getInstalledBehaviorsService = rospy.Service( 00073 self.NODE_NAME + "/get_installed_behaviors", 00074 GetInstalledBehaviors, 00075 self.getInstalledBehaviors 00076 ) 00077 00078 #Prepare and start actionlib server 00079 self.actionlibServer = actionlib.SimpleActionServer( 00080 self.NODE_NAME + "/run_behavior", 00081 RunBehaviorAction, 00082 self.runBehavior, 00083 False 00084 ) 00085 00086 self.actionlibServer.register_preempt_callback( self.stopBehavior ) 00087 00088 self.actionlibServer.start() 00089 00090 def getInstalledBehaviors( self, request ): 00091 result = self.behaviorProxy.getInstalledBehaviors() 00092 return GetInstalledBehaviorsResponse( result ) 00093 00094 00095 def runBehavior( self, request ): 00096 #Note that this function is executed on a different thread 00097 00098 #Save name of behavior to be run 00099 self.behavior = request.behavior 00100 result = RunBehaviorResult() 00101 result.noErrors = True 00102 00103 if not self.behaviorProxy.isBehaviorInstalled( self.behavior ) : 00104 result.noErrors = False 00105 self.actionlibServer.set_aborted( 00106 result, 00107 "Unknown behavior: " + str(self.behavior) 00108 ) 00109 self.behavior = "" 00110 return 00111 00112 #Execute behavior (risky if ALBehavior is not thread-safe!) 00113 self.behaviorProxy.runBehavior( self.behavior ) 00114 00115 # If we exited prematurely due to a call to stop behavior (which was 00116 # activated by a actionlib preemption signal) then set as preempted 00117 if self.actionlibServer.is_preempt_requested() : 00118 self.currentBehavior = "" 00119 self.actionlibServer.set_preempted() 00120 return 00121 00122 #Everything went fine, finished normally 00123 self.behavior = "" 00124 self.actionlibServer.set_succeeded( result ) 00125 return 00126 00127 def stopBehavior( self ): 00128 if self.behavior != "" and self.actionlibServer.is_active() : 00129 self.behaviorProxy.stopBehavior( self.behavior ) 00130 00131 00132 if __name__ == '__main__': 00133 node = NaoBehaviors() 00134 rospy.loginfo( node.NODE_NAME + " running..." ) 00135 rospy.spin() 00136 rospy.loginfo( node.NODE_NAME + " stopped." ) 00137 exit(0)