客户端库
概述
客户端库是允许用户实现其 ROS 2 代码的 API。 使用客户端库,用户可以访问 ROS 2 概念,例如节点、主题、服务等。 客户端库有多种编程语言,因此用户可以使用最适合其应用程序的语言编写 ROS 2 代码。 例如,您可能更喜欢用 Python 编写可视化工具,因为它可以加快原型迭代速度,而对于系统中与效率相关的部分,节点可能最好用 C++ 实现。
使用不同客户端库编写的节点能够相互共享消息,因为所有客户端库都实现了代码生成器,为用户提供了使用相应语言与 ROS 2 接口文件交互的能力。
除了特定于语言的通信工具外,客户端库还向用户展示了使 ROS 成为“ROS”的核心功能。 例如,以下是通常可以通过客户端库访问的功能列表:
Names and namespaces
Time (real or simulated)
Parameters
Console logging
Threading model
Intra-process communication
支持的客户端库
C++ 客户端库(“rclcpp”)和 Python 客户端库(“rclpy”)都是利用“rcl”中通用功能的客户端库。
rclcpp
包
C++ 版 ROS 客户端库 (rclcpp
) 是面向用户的 C++ 惯用接口,提供所有 ROS 客户端功能,如创建节点、发布者和订阅。
rclcpp
建立在 rcl
和 rosidl
API 之上,旨在与 rosidl_generator_cpp
生成的 C++ 消息一起使用。
rclcpp
利用 C++ 和 C++17 的所有功能使接口尽可能易于使用,但由于它重用了 rcl
中的实现,因此它能够与使用 rcl
API 的其他客户端库保持一致的行为。
rclcpp
存储库位于 GitHub 上的 ros2/rclcpp ,包含 package rclcpp
。
生成的 API 文档在此处:
rclpy
包
适用于 Python 的 ROS 客户端库 (rclpy
) 是 C++ 客户端库的 Python 对应库。
与 C++ 客户端库一样,rclpy
也基于 rcl
C API 实现。
该接口提供惯用的 Python 体验,使用本机 Python 类型和模式,如列表和上下文对象。
通过在实现中使用 rcl
API,它在功能奇偶校验和行为方面与其他客户端库保持一致。
除了为每条消息提供围绕 rcl
API 和 Python 类的 Python 惯用绑定之外,Python 客户端库还负责执行模型,使用 threading.Thread
或类似程序来运行 rcl
API 中的函数。
与 C++ 类似,它会为用户与之交互的每条 ROS 消息生成自定义 Python 代码,但与 C++ 不同的是,它最终会将原生 Python 消息对象转换为 C 版本的消息。
所有操作都发生在 Python 版本的消息上,直到需要将它们传递到 rcl
层,此时它们被转换为纯 C 版本的消息,以便可以将其传递到 rcl
C API。
如果可能的话,在同一进程中发布者和订阅者之间进行通信时应避免这种情况,以减少 Python 的转换。
rclpy
存储库位于 GitHub 上的 ros2/rclpy 并包含 package rclpy
。
生成的 API 文档在此处:
社区维护
虽然 C++ 和 Python 客户端库由核心 ROS 2 团队维护,但 ROS 2 社区成员还维护其他客户端库:
Ada 这是一组软件包(绑定到
rcl
、消息生成器、绑定到tf2
、示例和教程),允许为 ROS 2 编写 Ada 应用程序。C
rclc
不会在 rcl 之上添加一层,而是对 rcl 进行补充,使 rcl+rclc 成为功能齐全的 C 语言客户端库。有关教程,请参阅 micro.ros.org。JVM 和 Android 用于 ROS 2 的 Java 和 Android 绑定。
.NET Core、UWP 和 C# 这是用于为 .NET Core 和 .NET Standard 编写 ROS 2 应用程序的项目集合(绑定、代码生成器、示例等)。
Node.js rclnodejs 是 ROS 2 的 Node.js 客户端。它为 ROS 2 编程提供了简单易用的 JavaScript API。
Rust 这是一组项目(rclrs 客户端库、代码生成器、示例等),使开发人员能够用 Rust 编写 ROS 2 应用程序。
Flutter 和 Dart ROS 2 的 Flutter 和 Dart 绑定。
较旧的、未维护的客户端库包括:
Common functionality: rcl
客户端库中的大多数功能并不特定于客户端库的编程语言。 例如,参数的行为和命名空间的逻辑在所有编程语言中都应该相同。 因此,客户端库不是从头开始实现通用功能,而是使用通用核心 ROS 客户端库 (RCL) 接口,该接口实现不特定于语言的 ROS 概念的逻辑和行为。 因此,客户端库只需使用外部函数接口将通用功能包装在 RCL 中。 这使客户端库更薄,更易于开发。 因此,通用 RCL 功能通过 C 接口公开,因为 C 语言通常是客户端库最容易包装的语言。 除了使客户端库轻量级之外,拥有通用核心的一个优点是语言之间的行为更加一致。 如果对核心 RCL 中功能的逻辑/行为(例如命名空间)进行了任何更改,则所有使用 RCL 的客户端库都将反映这些更改。 此外,拥有通用核心意味着在修复错误时,维护多个客户端库的工作量会减少。
rcl
的 API 文档可以在 此处 找到。
特定于语言的功能
需要特定于语言的功能/属性的客户端库概念未在 RCL 中实现,而是在每个客户端库中实现。
例如,“spin”函数使用的线程模型将具有特定于客户端库语言的实现。
演示
要了解使用 rclpy
的发布者和使用 rclcpp
的订阅者之间的消息交换,我们建议您从 17:25 开始观看 这个 ROSCon 演讲 <https://vimeo.com/187696091>`__(`在此处查看幻灯片)。
与 ROS 1 的比较
在 ROS 1 中,所有客户端库都是“从头开始”开发的。 例如,这允许 ROS 1 Python 客户端库纯粹用 Python 实现,从而带来无需编译代码等好处。 但是,客户端库之间的命名约定和行为并不总是一致的,必须在多个地方进行错误修复,并且有很多功能仅在一个客户端库中实现(例如 UDPROS)。
摘要
通过利用通用核心 ROS 客户端库,用各种编程语言编写的客户端库更容易编写,并且行为更一致。