# 使用Execute Callback (Python)编写一个简单的行为服务器

Description: 本教程涵盖了使用simple_action_server库来创建一个Fibonacci行为服务器，以Python的形式。这个行为服务器示例会生成一个Fibonacci序列、目标序列、完成反馈序列和最终结果序列。

Tutorial Level: BEGINNER

Next Tutorial: 编写一个行为客户端(Python)

Contents

## 编写行为服务器

### 代码

```   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():
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
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
```

```   7 import actionlib_tutorials.msg
```

```  17         self._as = actionlib.SimpleActionServer(self._action_name, actionlib_tutorials.msg.FibonacciAction, execute_cb=self.execute_cb, auto_start = False)
18         self._as.start()
```

```  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]))
```

```  33         # 开始运行行为
34         for i in range(1, goal.order):
35             # check that preempt has not been requested by the client
36             if self._as.is_preempt_requested():
38                 self._as.set_preempted()
39                 success = False
```

```  41             self._feedback.sequence.append(self._feedback.sequence[i] + self._feedback.sequence[i-1])
42             # 发布反馈(feedback)
43             self._as.publish_feedback(self._feedback)
```

```  47         if success:
48             self._result.sequence = self._feedback.sequence
50             self._as.set_succeeded(self._result)
```

```  52 if __name__ == '__main__':
53     rospy.init_node('fibonacci')
54     server = FibonacciAction(rospy.get_name())
55     rospy.spin()
```

## 编译

```cd %TOPDIR_YOUR_CATKIN_WORKSPACE%
catkin_make
source devel/setup.bash```

## 运行行为服务器

`roscore`

`rosrun actionlib_tutorials fibonacci_server.py`

Wiki: cn/actionlib_tutorials/Tutorials/Writing a Simple Action Server using the Execute Callback (Python) (last edited 2017-03-19 04:45:34 by Playfish)