rclpy 提供了用于与 ROS 2 交互的规范 Python API,本文记录相关内容。
简介
rclpy
是 ROS 2
(Robot Operating System 2)的 Python 接口,由 Dashing Diademata
发行版开始提供。rclpy
提供了一个易于使用的 Python 库,使得开发机器人软件变得更加直接和快速。它允许用户通过 Python 语言来编写 ROS 2 节点、服务、动作和话题,无需编写任何 C 代码。这对于希望利用 Python 生态系统(如科学计算、数据处理和机器学习库)的开发者来说是一个巨大的优势。
以下是 rclpy
的一些关键特点:
- 易于上手:Python 作为一种高级编程语言,拥有简洁的语法和丰富的库,使得快速开发成为可能。
- 类型安全:
rclpy
在设计上确保了类型安全,避免了 C 中常见的指针和内存管理问题。 - 全功能:
rclpy
提供了 ROS 2 所有核心功能的访问,包括节点管理、服务、动作和话题。 - 集成:
rclpy
可以与 Python 的科学计算和数据分析库无缝集成,为机器人应用程序提供强大的数据处理能力。 - 跨平台:支持多种操作系统和硬件平台,与 ROS 2 的其他组件一样。
使用 rclpy
可以让开发者在享受 Python 开发效率和生态系统的同时,开发出能在 ROS 2 生态中运行的机器人应用。这极大地降低了开发复杂性,并加速了创新机器人的研发过程。
Initialization, Shutdown, and Spinning
一个典型的ROS程序由以下操作组成:
- Initialization
- Create one or more ROS nodes
- Process node callbacks
- Shutdown
初始化是通过调用特定上下文的 init()
来完成的。这必须在创建任何 ROS 节点之前完成。
创建 ROS 节点是通过调用 create_node()
或实例化 Node 来完成的。
节点可用于创建常见的 ROS 实体,例如发布者、订阅、服务和操作。
创建节点后,可通过在节点上 spinning 来完成工作项(如订阅回调)。以下函数可用于处理等待执行的工作:spin()
、spin_once()
和 spin_until_future_complete()
。
当完成先前初始化的上下文后(即使用了与上下文相关的所有 ROS 节点),应调用 shutdown()
函数。这将使从上下文派生的所有实体失效。
相关方法:
方法 | 含义 | 备注 |
---|---|---|
rclpy.create_node | 创建 Node 的实例。 | 也可以用 from rclpy.node import Node 的类初始化完成实例创建 |
rclpy.init | 为给定上下文初始化 ROS 通信。 | |
rclpy.shutdown | 关闭先前初始化的上下文。 | |
rclpy.spin | 执行工作并阻塞,直到与执行器相关的上下文关闭。 | |
rclpy.spin_once | 执行一项工作或等待超时。只要回调在超时前准备就绪,提供的执行器就会执行一个回调。 | 如果没有提供执行器(即None),则使用全局执行器。如果全局执行器有一个部分完成的例行程序,那么所做的工作可能不是针对所提供的节点。 |
rclpy.spin_until_future_complete | 执行工作直到将来完成。 | 回调和其他工作将由提供的执行器执行,直到 future.done() 返回 True 或与执行器相关的上下文关闭。 |
Node
1 | class rclpy.node.Node(node_name, *, context=None, cli_args=None, namespace=None, use_global_arguments=True, enable_rosout=True, start_parameter_services=True, parameter_overrides=None, allow_undeclared_parameters=False, automatically_declare_parameters_from_overrides=False) |
---|
ROS2 的核心节点类,包含大量方法,官方文档。
Topics
官方文档
Publisher
1 | class rclpy.publisher.Publisher(publisher_handle, msg_type, topic, qos_profile, event_callbacks, callback_group) |
---|
为 ROS 发布者创建一个容器。
注意: 用户不应使用该构造函数创建发布者,而应调用 Node.create_publisher()
。
在 ROS 系统中,发布者通过在 ROS 主题上发布信息作为主要的通信手段。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
assert_liveliness | 手动断言该 "发布者 "还活着。 | |
destroy | 销毁发布者。 | |
get_subscription_count | 获取该出版商的订户数量。 | |
publish | 为出版商的主题发送信息。 | |
属性列表:
属性 | 含义 | 备注 |
---|---|---|
handle | 句柄 | |
topic_name | 话题名称 | |
Subscription
1 | class rclpy.subscription.Subscription(subscription_handle, msg_type, topic, callback, callback_group, qos_profile, raw, event_callbacks) |
---|
为 ROS 订阅创建一个容器。
注意: 用户不应使用此构造函数创建订阅,而应调用 Node.create_subscription()
。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
destroy | 销毁订阅者 | |
属性列表:
属性 | 含义 | 备注 |
---|---|---|
handle | 句柄 | |
topic_name | 话题名称 | |
Services
Client
1 | class rclpy.client.Client(context, client_handle, srv_type, srv_name, qos_profile, callback_group) |
---|
为 ROS 服务客户端创建一个容器。
注意: 用户不应使用该构造函数创建服务客户端,而应调用 Node.create_client()
。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
call | 提出服务请求并等待结果。 | |
call_async | 发出服务请求并异步获取结果。 | |
destroy | 销毁客户端 | |
remove_pending_request | 删除一个未来的列表中的未决请求。 | 这将阻止未来接收响应并执行其已完成的回调。 |
service_is_ready | 检查服务服务器是否就绪。 | |
wait_for_service | 等待服务服务器准备就绪。 | 服务器准备就绪或超时后立即返回。 |
属性列表:
属性 | 含义 | 备注 |
---|---|---|
handle | 句柄 | |
Service
1 | class rclpy.service.Service(service_handle, srv_type, srv_name, callback, callback_group, qos_profile) |
---|
为 ROS 服务服务器创建一个容器。
注意: 用户不应使用该构造函数创建服务服务器,而应调用 Node.create_service()
。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
destroy | 销毁服务 | |
send_response | 发送服务响应。 | |
属性列表:
属性 | 含义 | 备注 |
---|---|---|
handle | 句柄 | |
Actions
Action Client
1 | class rclpy.action.client.ActionClient(node, action_type, action_name, *, callback_group=None, goal_service_qos_profile=<rclpy.qos.QoSProfile object>, result_service_qos_profile=<rclpy.qos.QoSProfile object>, cancel_service_qos_profile=<rclpy.qos.QoSProfile object>, feedback_sub_qos_profile=<rclpy.qos.QoSProfile object>, status_sub_qos_profile=<rclpy.qos.QoSProfile object>) |
---|
ROS 行动客户端。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
add_to_wait_set | 将实体添加到等待集。 | |
destroy | 销毁底层动作客户端句柄。 | |
execute | 从就绪等待集获取数据后执行工作。 | 这将为未来对象设置接收到的任何服务响应的结果,并调用任何用户定义的回调(如反馈)。 |
get_num_entities | 返回等待集中使用的各类实体的数量。 | |
is_ready | 如果等待集中有一个或多个实体准备就绪,则返回 True。 | |
send_goal | 发送的目标,并等待结果。 | 请勿在回调中调用此方法,否则可能出现死锁。 |
send_goal_async | 发送目标并异步获取结果。 | 当行动服务器确认收到目标时,返回的 Future 结果将被设置为 ClientGoalHandle。 |
server_is_ready | 检查是否有行动服务器准备处理该客户端的请求。 | |
take_data | 从下层取走东西,以免等待组立即再次醒来。 | |
wait_for_server | 等待一个 action server 准备就绪。 | 当动作服务器为客户端准备就绪时立即返回。 :param timeout_sec: 等待动作服务器可用的秒数。 |
Action Server
1 | class rclpy.action.server.ActionServer(node, action_type, action_name, execute_callback, *, callback_group=None, goal_callback=<function default_goal_callback>, handle_accepted_callback=<function default_handle_accepted_callback>, cancel_callback=<function default_cancel_callback>, goal_service_qos_profile=<rclpy.qos.QoSProfile object>, result_service_qos_profile=<rclpy.qos.QoSProfile object>, cancel_service_qos_profile=<rclpy.qos.QoSProfile object>, feedback_pub_qos_profile=<rclpy.qos.QoSProfile object>, status_pub_qos_profile=<rclpy.qos.QoSProfile object>, result_timeout=900) |
---|
ROS 行动服务器。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
add_to_wait_set | 将实体添加到等待集。 | |
destroy | 销毁服务器。 | |
execute | 从就绪等待集获取数据后执行工作。 | |
get_num_entities | 返回等待集中使用的各类实体的数量。 | |
is_ready | 如果等待集中有一个或多个实体准备就绪,则返回 True。 | |
notify_execute | | |
notify_goal_done | | |
register_cancel_callback | 注册用于处理取消请求的回调。 | 取消回调的目的是决定是否接受或拒绝取消进行中(或排队中)目标的请求。回调应接受一个包含取消请求的参数,并必须返回一个 CancelResponse 值。 |
register_execute_callback | 注册用于执行行动目标的回调。 | 执行回调的目的是执行操作目标,并在完成后返回结果。回调应接受一个包含目标请求的参数,并且必须返回一个结果实例。 |
register_goal_callback | 注册用于处理新目标请求的回调。 | 目标回调的目的是决定是否接受或拒绝一个新目标。回调应将目标请求消息作为参数,并必须返回一个 GoalResponse 值。 |
register_handle_accepted_callback | 注册一个回调,用于处理新接受的目标。 | |
take_data | 从下层取走东西,以免等待组立即再次醒来。 | |
属性列表:
属性 | 含义 | 备注 |
---|---|---|
action_type | 行动类型 | |
Timer
Rate
1 | class rclpy.timer.Rate(timer, *, context) |
---|
用于 sleep
的实用工具。
方法列表:
方法 | 含义 | 备注 |
---|---|---|
destroy | 销毁实例 | |
sleep | 阻止直到计时器触发。 | 在回调中调用此功能时应小心谨慎。如果在单线程执行器(SingleThreadedExecutor)的回调中调用,可能会永远阻塞。 |
Timer
1 | class rclpy.timer.Timer(callback, callback_group, timer_period_ns, clock, *, context=None) |
---|
Parameters
Parameter
1 | class rclpy.parameter.Parameter(name, type_=None, value=None) |
---|
Parameter Service
1 | class rclpy.parameter_service.ParameterService(node) |
---|
Logging
1 | class rclpy.logging.LoggingSeverity |
---|
日志严重性级别枚举。
DEBUG
= 10ERROR
= 40FATAL
= 50INFO
= 20UNSET
= 0WARN
= 30
Context
1 | class rclpy.context.Context |
---|
封装了启动和关闭的生命周期。
上下文对象不应重复使用,并在其析构函数中最终确定。
Execution and Callbacks
控制回调执行的组件有两个:执行器和回调组。
- Executors: 执行器负责回调的实际执行,应扩展 Executor 类。
- Callback: 回调组用于执行回调的并发规则,并应扩展 CallbackGroup 类。
Executors
1 | class rclpy.executors.Executor(*, context=None) |
---|
执行器的基类。
执行器控制用于处理回调的线程模型。回调是工作单位,如订阅回调、定时器回调、服务调用和接收到的客户端响应。执行器控制回调在哪些线程中执行。
自定义执行器必须定义 spin_once()
。如果执行器有任何清理工作,则还应定义 shutdown()
。
Callback Groups
1 | class rclpy.callback_groups.CallbackGroup |
---|
回调组的基类。
回调组控制何时允许执行回调。
该类不应被实例化。相反,类应扩展该类并实现 can_execute()
、beginning_execution()
和 ending_execution()
。
参考资料
- https://docs.ros2.org/latest/api/rclpy/
文章链接: https://cloud.tencent.com/developer/article/2436107