客户端库

概述

客户端库是允许用户实现其 ROS 2 代码的 API。使用客户端库,用户可以访问 ROS 2 概念,如节点、主题、服务等。客户端库以多种编程语言提供,因此用户可以使用最适合其应用程序的语言编写 ROS 2 代码。例如,您可能更喜欢使用 Python 编写可视化工具,因为它可以加快原型设计的迭代速度,而对于与效率有关的系统的某些部分,最好使用 C++ 实现节点。

使用不同客户端库编写的节点能够相互共享消息,因为所有客户端库都实现了代码生成器,为用户提供了与相应语言中的 ROS 2 接口文件交互的功能。

除了特定语言的通信工具外,客户端库还向用户公开了使 ROS 成为“ROS”的核心功能。例如,以下是通常可以通过客户端库访问的功能列表:

  • 名称和命名空间

  • 时间(真实或模拟)

  • 参数

  • 控制台日志记录

  • 线程模型

  • 进程内通信

支持的客户端库

C++客户端库(rclcpp)和Python客户端库(rclpy)都是使用``rcl``中通用功能的客户端库。

``rclcpp``包

ROS C++客户端库(rclcpp)是用户界面,使用C++的接口,提供了所有ROS客户端功能,如创建节点、发布者和订阅者。rclcpp``基于``rcl``和``rosidl API,并且设计用于与``rosidl_generator_cpp``生成的C++消息一起使用。

rclcpp``利用C++和C++17的所有特性,使接口尽可能易于使用,但由于它重用了``rcl``中的实现,因此能够与使用``rcl |API|的其他客户端库保持一致的行为。

rclcpp``仓库位于GitHub上的`ros2/rclcpp <https://github.com/ros2/rclcpp>`_,包含|package| ``rclcpp。生成的|API|文档在此处:

api/rclcpp/index.html

``rclpy``包

ROS 的 Python 客户端库(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 文档在此处:

api/rclpy/index.html

社区维护

尽管C++和Python客户端库由ROS 2核心团队维护,但ROS 2社区成员还维护了其他客户端库:

  • C ``rclc``不在rcl之上添加一个层,而是在C中补充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 是 ROS 2 的 Node.js 客户端。它为 ROS 2 编程提供了一个简单且易于使用的 JavaScript API。

  • Rust 是一组项目(包括 rclrs 客户端库、代码生成器、示例等),使开发人员能够使用 Rust 编写 ROS 2 应用程序。

较旧且不再维护的客户端库有:

通用功能:rcl

客户端库中的大部分功能与客户端库的编程语言无关。例如,参数的行为和命名空间的逻辑在所有编程语言中应该是相同的。因此,客户端库不需要从头开始实现通用功能,而是利用一个通用的ROS客户端库(RCL)接口,该接口实现了与ROS概念无关的逻辑和行为。因此,客户端库只需要使用外部函数接口将通用功能封装在RCL中。这使得客户端库更加轻巧且易于开发。因此,通用的RCL功能通过C接口公开,因为C语言通常是客户端库最容易封装的语言。

除了使客户端库变得轻量级之外,拥有通用核心的优势是不同语言之间的行为更加一致。如果对核心RCL中的逻辑/行为进行任何更改,例如命名空间,使用RCL的所有客户端库都将反映这些更改。此外,拥有通用核心意味着在修复错误时维护多个客户端库的工作量减少。

``rcl``的API文档可以在此处找到:<https://docs.ros.org/en/humble/p/rcl/>。

特定于语言的功能

需要语言特定功能/属性的客户端库概念不在RCL中实现,而是在每个客户端库中实现。例如,“spin”函数使用的线程模型将具有特定于客户端库语言的实现。

演示

如果你想了解使用 rclpy 发布者和使用 rclcpp 订阅者之间的消息交换过程,我们建议你观看这个 ROSCon 演讲(<https://vimeo.com/187696091>`__),从 17:25 开始(在这里查看幻灯片)。

与ROS 1的比较

在 ROS 1 中,所有客户端库都是从头开始开发的。这使得 ROS 1 Python 客户端库可以完全用 Python 实现,例如,这带来了无需编译代码的好处。然而,命名约定和行为在客户端库之间并不总是一致的,bug 修复必须在多个位置进行,而且有许多功能只在一个客户端库中实现(例如,UDPROS)。

总结

通过使用通用的核心 ROS 客户端库,以多种编程语言编写的客户端库更容易编写,并且具有更一致的行为。