目标:用 Python 实现一个动作服务器和客户端。
教程级别:中级
时间:15 分钟
目录
背景
先决条件
任务
1. 编写动作服务器
2. 编写动作客户端
摘要
相关内容
背景
动作是 ROS 2 中异步通信的一种形式。动作客户端向动作服务器发送目标请求。动作服务器向动作客户端发送目标反馈和结果。
先决条件
您将需要 custom_action_interfaces
包和在上一教程中定义的 Fibonacci.action
接口,创建一个操作。
任务
1. 编写动作服务器
让我们专注于编写一个动作服务器,使用我们在创建动作教程中创建的动作来计算斐波那契序列。
直到现在,您已经创建了包并使用 ros2 run
来运行您的节点。然而,为了在本教程中保持简单,我们将把动作服务器限定在一个文件中。如果您想看看完整的动作教程包是什么样子,请查看 action_tutorials https://github.com/ros2/demos/tree/jazzy/action_tutorials 。
在您的home目录中打开一个新文件,我们称它为 fibonacci_action_server.py
,并添加以下代码:
import rclpy # 导入ROS2的Python库
from rclpy.action import ActionServer # 从rclpy.action模块导入ActionServer类
from rclpy.node import Node # 从rclpy.node模块导入Node类
from custom_action_interfaces.action import Fibonacci # 导入自定义的Fibonacci动作接口
class FibonacciActionServer(Node): # 定义一个名为FibonacciActionServer的类,该类继承自Node类
def __init__(self): # 类的初始化函数
super().__init__('fibonacci_action_server') # 调用父类的初始化函数,创建一个名为'fibonacci_action_server'的节点
self._action_server = ActionServer( # 创建一个动作服务器
self, # 传入当前节点实例
Fibonacci, # 指定动作接口为Fibonacci
'fibonacci', # 动作的名字为'fibonacci'
self.execute_callback) # 当收到动作目标时,调用的回调函数为execute_callback
def execute_callback(self, goal_handle): # 定义动作执行的回调函数
self.get_logger().info('Executing goal...') # 打印日志信息
result = Fibonacci.Result() # 创建一个Fibonacci动作的结果实例
return result # 返回结果实例
def main(args=None): # 定义主函数
rclpy.init(args=args) # 初始化ROS2的Python库
fibonacci_action_server = FibonacciActionServer() # 创建一个FibonacciActionServer的实例
rclpy.spin(fibonacci_action_server) # 使fibonacci_action_server节点保持活动状态,直到节点被显式关闭或按下Ctrl+C
if __name__ == '__main__': # 如果当前脚本被直接运行,而不是被导入为模块运行
main() # 调用主函数
第 8 行定义了一个类 FibonacciActionServer
,它是 Node
的子类。该类通过调用 Node
构造函数来初始化,将我们的节点命名为 fibonacci_action_server
:
super().__init__('fibonacci_action_server')
在构造函数中,我们还实例化了一个新的动作服务器:
self._action_server = ActionServer(
self,
Fibonacci,
'fibonacci',
self.execute_callback)
一个动作服务器需要四个参数:
一个 ROS 2 节点用于添加动作客户端到:
self
。动作类型:
Fibonacci
(在第 5 行导入)。动作名称:
'fibonacci'
。用于执行已接受目标的回调函数:
self.execute_callback
。此回调函数必须为动作类型返回一个结果消息。
我们还在我们的类中定义了一个 execute_callback
方法:
def execute_callback(self, goal_handle):
self.get_logger().info('Executing goal...')
result = Fibonacci.Result()
return result
这是一旦目标被接受后将被调用来执行的方法。
让我们尝试运行我们的动作服务器:
python3 fibonacci_action_server.py
在另一个终端,我们可以使用命令行界面来发送一个目标:
ros2 action send_goal fibonacci custom_action_interfaces/action/Fibonac