nao_walker.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #
4 # ROS node to control Nao's walking engine (omniwalk and footsteps)
5 # This code is currently compatible to NaoQI version 1.6 or newer (latest
6 # tested: 1.12)
7 #
8 # Copyright 2009-2011 Armin Hornung & Stefan Osswald, University of Freiburg
9 # http://www.ros.org/wiki/nao
10 #
11 # Redistribution and use in source and binary forms, with or without
12 # modification, are permitted provided that the following conditions are met:
13 #
14 # # Redistributions of source code must retain the above copyright
15 # notice, this list of conditions and the following disclaimer.
16 # # Redistributions in binary form must reproduce the above copyright
17 # notice, this list of conditions and the following disclaimer in the
18 # documentation and/or other materials provided with the distribution.
19 # # Neither the name of the University of Freiburg nor the names of its
20 # contributors may be used to endorse or promote products derived from
21 # this software without specific prior written permission.
22 #
23 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 # POSSIBILITY OF SUCH DAMAGE.
34 #
35 
36 import rospy
37 
38 from naoqi_driver.naoqi_node import NaoqiNode
39 
40 from std_msgs.msg import String
41 from geometry_msgs.msg import Twist
42 from geometry_msgs.msg import Pose2D
43 
44 from std_srvs.srv import Empty, EmptyResponse
45 from naoqi_bridge_msgs.srv import CmdPoseService, CmdVelService, CmdPoseServiceResponse, CmdVelServiceResponse, SetArmsEnabled, SetArmsEnabledResponse
46 from humanoid_nav_msgs.msg import StepTarget
47 from humanoid_nav_msgs.srv import StepTargetService, StepTargetServiceResponse
48 
49 from nao_apps import startWalkPose
50 
52  def __init__(self):
53  NaoqiNode.__init__(self, 'nao_walker')
54 
55  self.connectNaoQi()
56 
57  # walking pattern params:
58  self.stepFrequency = rospy.get_param('~step_frequency', 0.5)
59 
60  self.useStartWalkPose = rospy.get_param('~use_walk_pose', False)
61  self.needsStartWalkPose = True
62 
63  # other params
64  self.maxHeadSpeed = rospy.get_param('~max_head_speed', 0.2)
65  # initial stiffness (defaults to 0 so it doesn't strain the robot when no teleoperation is running)
66  # set to 1.0 if you want to control the robot immediately
67  initStiffness = rospy.get_param('~init_stiffness', 0.0)
68 
69  self.useFootGaitConfig = rospy.get_param('~use_foot_gait_config', False)
70  rospy.loginfo("useFootGaitConfig = %d" % self.useFootGaitConfig)
71  if self.useFootGaitConfig:
72  self.footGaitConfig = rospy.get_param('~foot_gait_config', self.motionProxy.getFootGaitConfig("Default"))
73  else:
74  self.footGaitConfig = self.motionProxy.getFootGaitConfig("Default")
75 
76  # TODO: parameterize
77  if initStiffness > 0.0 and initStiffness <= 1.0:
78  self.motionProxy.stiffnessInterpolation('Body', initStiffness, 0.5)
79 
80  try:
81  enableFootContactProtection = rospy.get_param('~enable_foot_contact_protection')
82  self.motionProxy.setMotionConfig([["ENABLE_FOOT_CONTACT_PROTECTION", enableFootContactProtection]])
83  if enableFootContactProtection:
84  rospy.loginfo("Enabled foot contact protection")
85  else:
86  rospy.loginfo("Disabled foot contact protection")
87  except KeyError:
88  # do not change foot contact protection
89  pass
90 
91  # last: ROS subscriptions (after all vars are initialized)
92  rospy.Subscriber("cmd_vel", Twist, self.handleCmdVel, queue_size=1)
93  rospy.Subscriber("cmd_pose", Pose2D, self.handleTargetPose, queue_size=1)
94  rospy.Subscriber("cmd_step", StepTarget, self.handleStep, queue_size=50)
95 
96  # Create ROS publisher for speech
97  self.pub = rospy.Publisher("speech", String, latch = True)
98 
99  # ROS services (blocking functions)
100  self.cmdPoseSrv = rospy.Service("cmd_pose_srv", CmdPoseService, self.handleTargetPoseService)
101  self.cmdVelSrv = rospy.Service("cmd_vel_srv", CmdVelService, self.handleCmdVelService)
102  self.stepToSrv = rospy.Service("cmd_step_srv", StepTargetService, self.handleStepSrv)
103  self.stopWalkSrv = rospy.Service("stop_walk_srv", Empty, self.handleStopWalkSrv)
104  self.needsStartWalkPoseSrv = rospy.Service("needs_start_walk_pose_srv", Empty, self.handleNeedsStartWalkPoseSrv)
105  self.readFootGaitConfigSrv = rospy.Service("read_foot_gait_config_srv", Empty, self.handleReadFootGaitConfigSrv)
106  self.setArmsEnabledSrv = rospy.Service("enable_arms_walking_srv", SetArmsEnabled, self.handleSetArmsEnabledSrv)
107 
108  self.say("Walker online")
109 
110  rospy.loginfo("nao_walker initialized")
111 
112  def connectNaoQi(self):
113  '''(re-) connect to NaoQI'''
114  rospy.loginfo("Connecting to NaoQi at %s:%d", self.pip, self.pport)
115 
116  self.motionProxy = self.get_proxy("ALMotion")
117  if self.motionProxy is None:
118  exit(1)
119 
120  def stopWalk(self):
121  """ Stops the current walking bahavior and blocks until the clearing is complete. """
122  try:
123  self.motionProxy.setWalkTargetVelocity(0.0, 0.0, 0.0, self.stepFrequency)
124  self.motionProxy.waitUntilWalkIsFinished()
125 
126 
127  except RuntimeError,e:
128  print "An error has been caught"
129  print e
130  return False
131 
132  return True
133 
134 
135  def say(self, text):
136  self.pub.publish(text)
137 
138  def handleCmdVel(self, data):
139  rospy.logdebug("Walk cmd_vel: %f %f %f, frequency %f", data.linear.x, data.linear.y, data.angular.z, self.stepFrequency)
140  if data.linear.x != 0 or data.linear.y != 0 or data.angular.z != 0:
141  self.gotoStartWalkPose()
142  try:
143  eps = 1e-3 # maybe 0,0,0 is a special command in motionProxy...
144  if abs(data.linear.x)<eps and abs(data.linear.y)<eps and abs(data.angular.z)<eps:
145  self.motionProxy.setWalkTargetVelocity(0,0,0,0.5)
146  else:
147  self.motionProxy.setWalkTargetVelocity(data.linear.x, data.linear.y, data.angular.z, self.stepFrequency, self.footGaitConfig)
148  except RuntimeError,e:
149  # We have to assume there's no NaoQI running anymore => exit!
150  rospy.logerr("Exception caught in handleCmdVel:\n%s", e)
151  rospy.signal_shutdown("No NaoQI available anymore")
152 
153 
154 
155  def handleCmdVelService(self, req):
156  self.handleCmdVel(req.twist)
157  return CmdVelServiceResponse()
158 
159  def handleTargetPose(self, data, post=True):
160  """handles cmd_pose requests, walks to (x,y,theta) in robot coordinate system"""
161 
162  rospy.logdebug("Walk target_pose: %f %f %f", data.x,
163  data.y, data.theta)
164 
165  self.gotoStartWalkPose()
166 
167  try:
168  if post:
169  self.motionProxy.post.walkTo(data.x, data.y, data.theta, self.footGaitConfig)
170  else:
171  self.motionProxy.walkTo(data.x, data.y, data.theta, self.footGaitConfig)
172  return True
173  except RuntimeError,e:
174  rospy.logerr("Exception caught in handleTargetPose:\n%s", e)
175  return False
176 
177 
178  def handleStep(self, data):
179  rospy.logdebug("Step leg: %d; target: %f %f %f", data.leg, data.pose.x,
180  data.pose.y, data.pose.theta)
181  try:
182  if data.leg == StepTarget.right:
183  leg = "RLeg"
184  elif data.leg == StepTarget.left:
185  leg = "LLeg"
186  else:
187  rospy.logerr("Received a wrong leg constant: %d, ignoring step command", data.leg)
188  return
189  self.motionProxy.stepTo(leg, data.pose.x, data.pose.y, data.pose.theta)
190  return True
191  except RuntimeError, e:
192  rospy.logerr("Exception caught in handleStep:\n%s", e)
193  return False
194 
195  def handleStepSrv(self, req):
196  if self.handleStep(req.step):
197  return StepTargetServiceResponse()
198  else:
199  return None
200 
201  def handleTargetPoseService(self, req):
202  """ do NOT use post"""
203  if self.handleTargetPose(req.pose, False):
204  return CmdPoseServiceResponse()
205  else:
206  return None
207 
208  def handleStopWalkSrv(self, req):
209  if self.stopWalk():
210  return EmptyResponse()
211  else:
212  return None
213 
214  def gotoStartWalkPose(self):
215  if self.useStartWalkPose and self.needsStartWalkPose:
217  self.needsStartWalkPose = False
218 
220  self.needsStartWalkPose = True
221  return EmptyResponse()
222 
224  self.useFootGaitConfig = rospy.get_param('~use_foot_gait_config', False)
225  rospy.loginfo("useFootGaitConfig = %d" % self.useFootGaitConfig)
226  if self.useFootGaitConfig:
227  self.footGaitConfig = rospy.get_param('~foot_gait_config', self.motionProxy.getFootGaitConfig("Default"))
228  else:
229  self.footGaitConfig = self.motionProxy.getFootGaitConfig("Default")
230  return EmptyResponse()
231 
232  def handleSetArmsEnabledSrv(self, req):
233  self.motionProxy.setWalkArmsEnable(req.left_arm, req.right_arm)
234  rospy.loginfo("Arms enabled during walk: left(%s) right(%s)" % (req.left_arm, req.right_arm))
235  return SetArmsEnabledResponse()
236 
237 
238 if __name__ == '__main__':
239  walker = NaoWalker()
240  rospy.loginfo("nao_walker running...")
241  rospy.spin()
242  rospy.loginfo("nao_walker stopping...")
243  walker.stopWalk()
244 
245  rospy.loginfo("nao_walker stopped.")
246  exit(0)
def handleSetArmsEnabledSrv(self, req)
Definition: nao_walker.py:232
def startWalkPose(motionProxy)
def connectNaoQi(self)
Definition: nao_walker.py:112
def handleTargetPoseService(self, req)
Definition: nao_walker.py:201
def handleStopWalkSrv(self, req)
Definition: nao_walker.py:208
def handleCmdVel(self, data)
Definition: nao_walker.py:138
def gotoStartWalkPose(self)
Definition: nao_walker.py:214
def handleNeedsStartWalkPoseSrv(self, data)
Definition: nao_walker.py:219
def say(self, text)
Definition: nao_walker.py:135
def handleStepSrv(self, req)
Definition: nao_walker.py:195
def handleTargetPose(self, data, post=True)
Definition: nao_walker.py:159
def handleCmdVelService(self, req)
Definition: nao_walker.py:155
def __init__(self)
Definition: nao_walker.py:52
def handleStep(self, data)
Definition: nao_walker.py:178
def get_proxy(self, name, warn=True)
def handleReadFootGaitConfigSrv(self, data)
Definition: nao_walker.py:223


nao_apps
Author(s):
autogenerated on Mon Jun 10 2019 14:04:55