nao_ni_walker.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 #
00003 # This code is a modified version of Armin Hornung, University of Freiburg 
00004 # ROS node to send out movement commands to the Nao Aldebaran API (teleoperated)
00005 #
00006 # Copyright 2010 Halit Bener SUAY, Worcester Polytechnic Institute
00007 # benersuay@wpi.edu
00008 #
00009 # https://github.com/wpi-ros-pkg-git/nao_openni
00010 #
00011 # Redistribution and use in source and binary forms, with or without
00012 # modification, are permitted provided that the following conditions are met:
00013 #
00014 #    # Redistributions of source code must retain the above copyright
00015 #       notice, this list of conditions and the following disclaimer.
00016 #    # Redistributions in binary form must reproduce the above copyright
00017 #       notice, this list of conditions and the following disclaimer in the
00018 #       documentation and/or other materials provided with the distribution.
00019 #    # Neither the name of the <ORGANIZATION> nor the names of its
00020 #       contributors may be used to endorse or promote products derived from
00021 #       this software without specific prior written permission.
00022 #
00023 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00027 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 # POSSIBILITY OF SUCH DAMAGE.
00034 #
00035 
00036 # This code has arm angle control in addition to its original
00037 
00038 import roslib
00039 roslib.load_manifest('nao_ctrl')
00040 import rospy
00041 
00042 import math
00043 from math import fabs
00044 
00045 from std_msgs.msg import String
00046 from geometry_msgs.msg import Twist
00047 from sensor_msgs.msg import JointState
00048 
00049 from nao_ctrl.msg import MotionCommandBtn
00050 from nao_ctrl.msg import HeadAngles
00051 
00052 try:
00053         import naoqi
00054         import motion
00055         from naoqi import ALProxy
00056 except ImportError:
00057         rospy.logerr("Error importing NaoQI. Please make sure that Aldebaran's NaoQI API is in your PYTHONPATH.")
00058         exit(1)
00059 
00060 from crouch import crouch
00061 from init_pose import initPose
00062 
00063 class NaoWalker():
00064         def __init__(self, ip, port):
00065                 
00066                 # ROS initialization:
00067                 rospy.init_node('nao_walker')
00068                   
00069                 self.connectNaoQi(ip, port)
00070 
00071                 # walking pattern params:
00072                 self.stepFrequency = rospy.get_param('~step_frequency', 0.5)  
00073         
00074         # other params
00075                 self.maxHeadSpeed = rospy.get_param('~max_head_speed', 0.2)
00076                 self.headYawChange = rospy.get_param('~head_yaw_change',0.5)
00077                 self.HeadPitchChange = rospy.get_param('~head_pitch_change', 0.5)
00078                 
00079                 self.motionProxy.stiffnessInterpolation('Body', 1.0, 0.5)
00080                 
00081                 # last: ROS subscriptions (after all vars are initialized)
00082                 rospy.Subscriber("head_angles", HeadAngles, self.handleHead, queue_size=1)
00083                 rospy.Subscriber("cmd_vel", Twist, self.handleCmdVel, queue_size=1)
00084                 rospy.Subscriber("motion_command_btn", MotionCommandBtn, self.handleMotionBtn, queue_size=1)
00085                 rospy.Subscriber("speech", String, self.handleSpeech)
00086 
00087                 rospy.Subscriber("lshoulder_angles", HeadAngles, self.handleLArm, queue_size=1)
00088                 rospy.Subscriber("lelbow_angles", HeadAngles, self.handleLElbow, queue_size=1)
00089                 rospy.Subscriber("rshoulder_angles", HeadAngles, self.handleRArm, queue_size=1)
00090                 rospy.Subscriber("relbow_angles", HeadAngles, self.handleRElbow, queue_size=1)
00091                 
00092                 rospy.loginfo("nao_walker initialized")
00093 
00094         # (re-) connect to NaoQI:
00095         def connectNaoQi(self, ip, port):
00096                 rospy.loginfo("Connecting to NaoQi at %s:%d", ip, port)
00097                 
00098                 self.ttsProxy = None
00099                 self.motionProxy = None
00100                 
00101                 try:
00102                         self.ttsProxy = ALProxy("ALTextToSpeech",ip,port)
00103                 except RuntimeError,e:
00104                         rospy.logwarn("No Proxy to TTS available, disabling speech output.")
00105 
00106                 try:
00107                         self.motionProxy = ALProxy("ALMotion",ip,port)
00108                         self.motionProxy.setWalkArmsEnable(False,False)
00109                 except RuntimeError,e:
00110                         rospy.logerr("Error creating Proxy to motion, exiting...")
00111                         print e
00112                         exit(1)
00113 
00114         def stopWalk(self):
00115                 """ Stops the current walking bahavior and blocks until the clearing is complete. """
00116                 try:
00117                         self.motionProxy.setWalkTargetVelocity(0.0, 0.0, 0.0, self.stepFrequency)
00118                         self.motionProxy.waitUntilWalkIsFinished()
00119 
00120                                                 
00121                 except RuntimeError,e:
00122                         print "An error has been caught"
00123                         print e
00124                         
00125         
00126         def handleSpeech(self,data):
00127                 if (not self.ttsProxy is None):
00128                         try:
00129                                 self.ttsProxy.say(data.data)
00130                         except RuntimeError,e:
00131                                 rospy.logerr("Exception caught:\n%s", e)
00132         
00133         
00134         # Head needs to be rewritten:
00135         def handleHead(self,data):
00136                 """handles head movement callback """
00137                 
00138                 #headChange = [0.5*data.yaw,0.5*data.pitch]  
00139                 
00140                 try:
00141                         #self.motionProxy.changeAngles(["HeadYaw", "HeadPitch"], headChange, self.maxHeadSpeed)
00142                         self.motionProxy.setAngles(["HeadYaw", "HeadPitch"], [data.yaw, data.pitch], self.maxHeadSpeed)
00143                 except RuntimeError,e:
00144                         rospy.logerr("Exception caught:\n%s", e)
00145         
00146         def handleCmdVel(self, data):
00147                 rospy.logdebug("Walk cmd_vel: %d %d %d, frequency %d", data.linear.x, data.linear.y, data.angular.z, self.stepFrequency)
00148                 try:
00149                         self.motionProxy.setWalkTargetVelocity(data.linear.x, data.linear.y, data.angular.z, self.stepFrequency)
00150                 except RuntimeError,e:
00151                         rospy.logerr("Exception caught:\n%s", e)
00152                 
00153         
00154         def handleMotionBtn(self,data):
00155 #               global walkLock
00156 #               walkLock.acquire()
00157                         
00158                 if (data.button == MotionCommandBtn.crouchNoStiff):
00159                         self.stopWalk()
00160                         crouch(self.motionProxy)
00161                         self.motionProxy.stiffnessInterpolation('Body',0.0, 0.5)
00162                         if (not self.ttsProxy is None):
00163                                 self.ttsProxy.say("Stiffness removed")
00164                 elif (data.button == MotionCommandBtn.initPose):
00165                         initPose(self.motionProxy)
00166                 elif (data.button == MotionCommandBtn.stiffnessOn):
00167                         self.motionProxy.stiffnessInterpolation('Body',1.0, 0.5)
00168                 elif (data.button == MotionCommandBtn.stiffnessOff):
00169                         self.motionProxy.stiffnessInterpolation('Body',0.0, 0.5)
00170 
00171         def handleLArm(self,data):
00172                 try:
00173                         self.motionProxy.setAngles(["LShoulderPitch", "LShoulderRoll"], [data.pitch, data.yaw], self.maxHeadSpeed)
00174                 except RuntimeError,e:
00175                         rospy.logerr("Exception caught:\n%s", e)
00176 
00177         def handleRArm(self,data):
00178                 try:
00179                         self.motionProxy.setAngles(["RShoulderPitch", "RShoulderRoll"], [data.pitch, data.yaw], self.maxHeadSpeed)
00180                 except RuntimeError,e:
00181                         rospy.logerr("Exception caught:\n%s", e)
00182         
00183         def handleLElbow(self,data):
00184                 try:
00185                         self.motionProxy.setAngles(["LElbowRoll","LElbowYaw" ], [data.pitch, data.yaw], self.maxHeadSpeed)
00186                 except RuntimeError,e:
00187                         rospy.logerr("Exception caught:\n%s", e)
00188 
00189         def handleRElbow(self,data):
00190                 try:
00191                         self.motionProxy.setAngles(["RElbowRoll","RElbowYaw"], [data.pitch, data.yaw], self.maxHeadSpeed)
00192                 except RuntimeError,e:
00193                         rospy.logerr("Exception caught:\n%s", e)                
00194 
00195 
00196 if __name__ == '__main__':
00197         
00198         # get connection from command line:
00199         from optparse import OptionParser
00200 
00201         parser = OptionParser()
00202         parser.add_option("--pip", dest="pip", default="127.0.0.1",
00203                           help="IP/hostname of parent broker. Default is 127.0.0.1.", metavar="IP")
00204         parser.add_option("--pport", dest="pport", default=9559,
00205                           help="port of parent broker. Default is 9559.", metavar="PORT")
00206                 
00207         (options, args) = parser.parse_args()
00208 
00209         walker = NaoWalker(options.pip, int(options.pport))
00210         rospy.spin()
00211         rospy.loginfo("nao_walker NaoWalker...")
00212         walker.stopWalk()
00213         
00214         rospy.loginfo("nao_walker stopped.")
00215         exit(0)


nao_openni
Author(s): Bener SUAY
autogenerated on Mon Jan 6 2014 11:27:51