Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
使用Execute Callback (Python)编写一个简单的行为服务器
Description: 本教程涵盖了使用simple_action_server库来创建一个Fibonacci行为服务器,以Python的形式。这个行为服务器示例会生成一个Fibonacci序列、目标序列、完成反馈序列和最终结果序列。Tutorial Level: BEGINNER
Next Tutorial: 编写一个行为客户端(Python)
创建行为消息
查看C++ 版本教程 然后当你已经完成创建消息后返回。
编写行为服务器
在本教程中使用到的代码和示例可以在actionlib_tutorials包中找到。你也许应该在开始本教程之前阅读actionlib包。
代码
以下的代码可以在actionlib_tutorials/simple_action_servers/fibonacci_server.py中找到,并且实现了一个python形式的行为服务器用于 fibonacci行为.
1 #! /usr/bin/env python
2
3 import rospy
4
5 import actionlib
6
7 import actionlib_tutorials.msg
8
9 class FibonacciAction(object):
10 #创建用于发布反馈(feedback)/结果(result)的消息
11 _feedback = actionlib_tutorials.msg.FibonacciFeedback()
12 _result = actionlib_tutorials.msg.FibonacciResult()
13
14 def __init__(self, name):
15 self._action_name = name
16 self._as = actionlib.SimpleActionServer(self._action_name, actionlib_tutorials.msg.FibonacciAction, execute_cb=self.execute_cb, auto_start = False)
17 self._as.start()
18
19 def execute_cb(self, goal):
20 # helper variables
21 r = rospy.Rate(1)
22 success = True
23
24 # 附加种子用于fibonacci序列
25 self._feedback.sequence = []
26 self._feedback.sequence.append(0)
27 self._feedback.sequence.append(1)
28
29 # 发布信息到控制台,用于用户查看
30 rospy.loginfo('%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i' % (self._action_name, goal.order, self._feedback.sequence[0], self._feedback.sequence[1]))
31
32 # 开始运行行为
33 for i in range(1, goal.order):
34 # check that preempt has not been requested by the client
35 if self._as.is_preempt_requested():
36 rospy.loginfo('%s: Preempted' % self._action_name)
37 self._as.set_preempted()
38 success = False
39 break
40 self._feedback.sequence.append(self._feedback.sequence[i] + self._feedback.sequence[i-1])
41 # 发布反馈(feedback)
42 self._as.publish_feedback(self._feedback)
43 # 这个步骤不是必要的,用于演示效果所以序列会以1Hz完成。
44 r.sleep()
45
46 if success:
47 self._result.sequence = self._feedback.sequence
48 rospy.loginfo('%s: Succeeded' % self._action_name)
49 self._as.set_succeeded(self._result)
50
51 if __name__ == '__main__':
52 rospy.init_node('fibonacci')
53 server = FibonacciAction(rospy.get_name())
54 rospy.spin()
代码解释
6 import actionlib
这一行会加载actionlib库用于实现简单行为。
7 import actionlib_tutorials.msg
指定的行为生成几个消息用于目标、接收反馈等等。这一行加载生成的消息
在这里,创建SimpleActionServer,我们传递一个名字(用于作为一个命名空间namespace)、一个行为类型和可选项运行回调。由于我们在这个示例中指定一个运行回调,因此会为我们循环一个线程,该线程允许我们当一个新目标进来时,会以一个回调(callback)形式接收来运行行为。
注意你应当总是显示的设置auto_start为False,除非你知道你在做什么(参考)。
20 def execute_cb(self, goal):
这是一个运行回调函数,不管什么时候,只有一个新目标接收到的时候会运行。
22 r = rospy.Rate(1)
23 success = True
24
25 # 附加种子用于fibonacci序列
26 self._feedback.sequence = []
27 self._feedback.sequence.append(0)
28 self._feedback.sequence.append(1)
29
30 # 发布信息到控制台,用于用户查看
31 rospy.loginfo('%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i' % (self._action_name, goal.order, self._feedback.sequence[0], self._feedback.sequence[1]))
在这里,创建内置行为。在本示例中发布的rospy.loginfo来让用户知道行为处于运行状态。
一个行为服务器的重要组件是有能力允许一个行为客户端的请求,该请求是目标可以被取消。当一个客户端请求当前目标被抢占时,行为服务器应该取消目标,运行任何必要的清理工作,随后调用set_preempted函数,该函数触发一个行为被用户请求抢占的信号。在这里,我们将每一秒进行检查是否被抢占。另外,当接收到一个抢占请求时,我们应该接收一个回调。
在这里,Fibonacci序列指定反馈变量,随后在提供的反馈通道中通过行为服务器发布。之后,行为继续循环和发布反馈。
一旦行为结束Fibonacci序列处理,行为服务器通过调用set_succeeded来通知行为客户端行为目标完成。
最后,main函数,创建行为服务器并且循环节点。
编译
只有初始化的时候,即你创建教程包的时候,你需要编译生成shell配置文件。
cd %TOPDIR_YOUR_CATKIN_WORKSPACE% catkin_make source devel/setup.bash
运行行为服务器
运行:
roscore
然后在一个新终端上,用以下命令来运行行为服务器。
rosrun actionlib_tutorials fibonacci_server.py