00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 import roslib
00037 roslib.load_manifest('nao_driver')
00038 import rospy
00039
00040 import logging
00041 logging.basicConfig()
00042
00043 from nao_driver import *
00044
00045 import math
00046 from math import fabs
00047
00048 from std_msgs.msg import String
00049 from geometry_msgs.msg import Twist
00050 from geometry_msgs.msg import Pose2D
00051 from sensor_msgs.msg import JointState
00052 from std_msgs.msg import Bool
00053 import std_msgs.msg
00054
00055 from std_srvs.srv import Empty, EmptyResponse
00056 from nao_msgs.srv import CmdPoseService, CmdVelService, CmdPoseServiceResponse, CmdVelServiceResponse
00057 from humanoid_nav_msgs.msg import StepTarget
00058 from humanoid_nav_msgs.srv import StepTargetService, StepTargetServiceResponse
00059
00060 import nao_msgs.srv
00061
00062 from start_walk_pose import startWalkPose
00063
00064 class NaoWalker(NaoNode):
00065 def __init__(self):
00066 NaoNode.__init__(self)
00067
00068
00069 rospy.init_node('nao_walker')
00070
00071 self.connectNaoQi()
00072
00073
00074 self.scan_active = False
00075
00076 self.stepFrequency = rospy.get_param('~step_frequency', 0.5)
00077
00078 self.useStartWalkPose = rospy.get_param('~use_walk_pose', False)
00079 self.needsStartWalkPose = True
00080
00081
00082 self.maxHeadSpeed = rospy.get_param('~max_head_speed', 0.2)
00083
00084
00085 initStiffness = rospy.get_param('~init_stiffness', 0.0)
00086
00087 self.for_iros2011 = rospy.get_param('~for_iros2011', False)
00088 rospy.loginfo("for_iros2011 = %d" % self.for_iros2011)
00089 if self.for_iros2011:
00090 self.doubleScan = rospy.get_param('~double_scan', False)
00091 self.doubleScanFrom = rospy.get_param('~double_scan_from', 0.0)
00092 self.doubleScanTo = rospy.get_param('~double_scan_to', -30.0)
00093 self.scanInfoPub = rospy.Publisher("scan_info", Bool, latch=True)
00094 scanInfo = Bool(False)
00095 self.scanInfoPub.publish(scanInfo)
00096
00097 self.useFootGaitConfig = rospy.get_param('~use_foot_gait_config', False)
00098 rospy.loginfo("useFootGaitConfig = %d" % self.useFootGaitConfig)
00099 if self.useFootGaitConfig:
00100 self.footGaitConfig = rospy.get_param('~foot_gait_config', self.motionProxy.getFootGaitConfig("Default"))
00101 else:
00102 self.footGaitConfig = self.motionProxy.getFootGaitConfig("Default")
00103
00104
00105 if initStiffness > 0.0 and initStiffness <= 1.0:
00106 self.motionProxy.stiffnessInterpolation('Body', initStiffness, 0.5)
00107
00108 try:
00109 enableFootContactProtection = rospy.get_param('~enable_foot_contact_protection')
00110 self.motionProxy.setMotionConfig([["ENABLE_FOOT_CONTACT_PROTECTION", enableFootContactProtection]])
00111 if enableFootContactProtection:
00112 rospy.loginfo("Enabled foot contact protection")
00113 else:
00114 rospy.loginfo("Disabled foot contact protection")
00115 except KeyError:
00116
00117 pass
00118
00119
00120 rospy.Subscriber("cmd_vel", Twist, self.handleCmdVel, queue_size=1)
00121 rospy.Subscriber("cmd_pose", Pose2D, self.handleTargetPose, queue_size=1)
00122 rospy.Subscriber("cmd_step", StepTarget, self.handleStep, queue_size=50)
00123 rospy.Subscriber("speech", String, self.handleSpeech)
00124 rospy.Subscriber("start_scan", std_msgs.msg.Empty, self.handleStartScan, queue_size=1)
00125
00126
00127 self.cmdPoseSrv = rospy.Service("cmd_pose_srv", CmdPoseService, self.handleTargetPoseService)
00128 self.cmdVelSrv = rospy.Service("cmd_vel_srv", CmdVelService, self.handleCmdVelService)
00129 self.stepToSrv = rospy.Service("cmd_step_srv", StepTargetService, self.handleStepSrv)
00130 self.headScanSrv = rospy.Service("head_scan_srv", Empty, self.handleHeadScanSrv)
00131 self.stopWalkSrv = rospy.Service("stop_walk_srv", Empty, self.handleStopWalkSrv)
00132 self.needsStartWalkPoseSrv = rospy.Service("needs_start_walk_pose_srv", Empty, self.handleNeedsStartWalkPoseSrv)
00133 self.readFootGaitConfigSrv = rospy.Service("read_foot_gait_config_srv", Empty, self.handleReadFootGaitConfigSrv)
00134
00135 self.say("Walker online")
00136
00137 rospy.loginfo("nao_walker initialized")
00138
00139 def connectNaoQi(self):
00140 '''(re-) connect to NaoQI'''
00141 rospy.loginfo("Connecting to NaoQi at %s:%d", self.pip, self.pport)
00142
00143 self.motionProxy = self.getProxy("ALMotion")
00144 if self.motionProxy is None:
00145 exit(1)
00146
00147 self.ttsProxy = self.getProxy("ALTextToSpeech", warn=False)
00148 if self.ttsProxy is None:
00149 rospy.logwarn("No Proxy to TTS available, disabling speech output.")
00150
00151
00152 def stopWalk(self):
00153 """ Stops the current walking bahavior and blocks until the clearing is complete. """
00154 try:
00155 self.motionProxy.setWalkTargetVelocity(0.0, 0.0, 0.0, self.stepFrequency)
00156 self.motionProxy.waitUntilWalkIsFinished()
00157
00158
00159 except RuntimeError,e:
00160 print "An error has been caught"
00161 print e
00162 return False
00163
00164 return True
00165
00166
00167 def handleSpeech(self,data):
00168 self.say(data.data)
00169
00170 def say(self, text):
00171 if (not self.ttsProxy is None):
00172 try:
00173
00174
00175 print("say %s ..." % str(text))
00176 ttsid = self.ttsProxy.post.say(str(text))
00177
00178 print("...done")
00179 except RuntimeError,e:
00180 rospy.logerr("Exception caught:\n%s", e)
00181
00182 def handleCmdVel(self, data):
00183 rospy.logdebug("Walk cmd_vel: %f %f %f, frequency %f", data.linear.x, data.linear.y, data.angular.z, self.stepFrequency)
00184 if data.linear.x != 0 or data.linear.y != 0 or data.angular.z != 0:
00185 self.gotoStartWalkPose()
00186 try:
00187 eps = 1e-3
00188 if abs(data.linear.x)<eps and abs(data.linear.y)<eps and abs(data.angular.z)<eps:
00189 self.motionProxy.setWalkTargetVelocity(0,0,0,0.5)
00190 else:
00191 self.motionProxy.setWalkTargetVelocity(data.linear.x, data.linear.y, data.angular.z, self.stepFrequency, self.footGaitConfig)
00192 except RuntimeError,e:
00193
00194 rospy.logerr("Exception caught in handleCmdVel:\n%s", e)
00195 rospy.signal_shutdown("No NaoQI available anymore")
00196
00197
00198
00199 def handleCmdVelService(self, req):
00200 self.handleCmdVel(req.twist)
00201 return CmdVelServiceResponse()
00202
00203 def handleTargetPose(self, data, post=True):
00204 """handles cmd_pose requests, walks to (x,y,theta) in robot coordinate system"""
00205 if self.scan_active:
00206 return False
00207
00208 rospy.logdebug("Walk target_pose: %f %f %f", data.x,
00209 data.y, data.theta)
00210
00211 self.gotoStartWalkPose()
00212
00213 try:
00214 if post:
00215 self.motionProxy.post.walkTo(data.x, data.y, data.theta, self.footGaitConfig)
00216 else:
00217 self.motionProxy.walkTo(data.x, data.y, data.theta, self.footGaitConfig)
00218 return True
00219 except RuntimeError,e:
00220 rospy.logerr("Exception caught in handleTargetPose:\n%s", e)
00221 return False
00222
00223
00224 def handleStep(self, data):
00225 rospy.logdebug("Step leg: %d; target: %f %f %f", data.leg, data.pose.x,
00226 data.pose.y, data.pose.theta)
00227 try:
00228 if data.leg == StepTarget.right:
00229 leg = "RLeg"
00230 elif data.leg == StepTarget.left:
00231 leg = "LLeg"
00232 else:
00233 rospy.logerr("Received a wrong leg constant: %d, ignoring step command", data.leg)
00234 return
00235 self.motionProxy.stepTo(leg, data.pose.x, data.pose.y, data.pose.theta)
00236 return True
00237 except RuntimeError, e:
00238 rospy.logerr("Exception caught in handleStep:\n%s", e)
00239 return False
00240
00241 def handleStepSrv(self, req):
00242 if self.handleStep(req.step):
00243 return StepTargetServiceResponse()
00244 else:
00245 return None
00246
00247 def handleTargetPoseService(self, req):
00248 """ do NOT use post"""
00249 if self.handleTargetPose(req.pose, False):
00250 return CmdPoseServiceResponse()
00251 else:
00252 return None
00253
00254 def handleHeadScanSrv(self, req):
00255 if self.perform_laser_scan():
00256 return EmptyResponse()
00257 else:
00258 return None
00259
00260 def handleStartScan(self, msg):
00261 self.perform_laser_scan()
00262
00263 def handleStopWalkSrv(self, req):
00264 if self.stopWalk():
00265 return EmptyResponse()
00266 else:
00267 return None
00268
00269 def gotoStartWalkPose(self):
00270 if self.useStartWalkPose and self.needsStartWalkPose:
00271 startWalkPose(self.motionProxy)
00272 self.needsStartWalkPose = False
00273
00274 def handleNeedsStartWalkPoseSrv(self, data):
00275 self.needsStartWalkPose = True
00276 return EmptyResponse()
00277
00278 def handleReadFootGaitConfigSrv(self, data):
00279 self.useFootGaitConfig = rospy.get_param('~use_foot_gait_config', False)
00280 rospy.loginfo("useFootGaitConfig = %d" % self.useFootGaitConfig)
00281 if self.useFootGaitConfig:
00282 self.footGaitConfig = rospy.get_param('~foot_gait_config', self.motionProxy.getFootGaitConfig("Default"))
00283 else:
00284 self.footGaitConfig = self.motionProxy.getFootGaitConfig("Default")
00285 return EmptyResponse()
00286
00287 def perform_laser_scan(self):
00288 if self.scan_active:
00289 print "ignoring button press because I'm already scanning"
00290 return False
00291 self.scan_active = True
00292 self.stopWalk()
00293 if self.for_iros2011:
00294 from iros2011_scan import head_scan
00295 head_scan(self.motionProxy,self.ttsProxy, 28.0, -36.0, 1.0, 10.0, True)
00296 if self.doubleScan:
00297 head_scan(self.motionProxy, self.ttsProxy, self.doubleScanFrom, self.doubleScanTo, 1.0, 10.0, False)
00298 self.motionProxy.angleInterpolation('HeadPitch', 0.0, 2.5, True)
00299 else:
00300
00301
00302 from headscanTop import head_scan
00303 if (not self.ttsProxy is None):
00304 self.say("Starting scan")
00305 else:
00306 rospy.loginfo("Starting scan")
00307
00308 rospy.sleep(2)
00309
00310 head_scan(self.motionProxy,28.0, -35.0, 1.0, 10.0, True)
00311 if (not self.ttsProxy is None):
00312 self.say("Scan complete")
00313 else:
00314 rospy.loginfo("Scan complete")
00315 self.scan_active = False
00316 self.needsStartWalkPose = True
00317 return True
00318
00319
00320 if __name__ == '__main__':
00321 walker = NaoWalker()
00322 rospy.loginfo("nao_walker running...")
00323 rospy.spin()
00324 rospy.loginfo("nao_walker stopping...")
00325 walker.stopWalk()
00326
00327 rospy.loginfo("nao_walker stopped.")
00328 exit(0)