这是我对ROS官方ROS2教程的翻译,纯个人理解,对于文中的关键词汇或不确定的语句标注了原文,如有错误或翻译问题还请指出。
文章翻译并未按照逐句逐词的方式进行,而是加入了我的一些主观思考,不过原则上还是会以原文思路为主。
原文:https://index.ros.org/doc/ros2/Concepts/ROS-2-Client-Libraries/
有关于ROS2的客户端程序库
概览
ROS2的客户端程序库(Client Library)是用户实现ROS代码时可以使用的API集合。这些API可以允许用户来访问前边提到的那些ROS概念,比如节点(nodes)、主题(topics)、服务(services)等。客户端程序库已经正在被各种编程语言实现,从而用户可以选择最适合他们应用程序的编程语言来编写ROS代码。比如说,你可能需要使用Python来编写可视化工具,因为Python语言可以让原型迭代更快,然而你的系统中的另一些代码块可能需要考虑性能问题,这些节点使用C++语言来实现可能会更好。
使用不同编程语言的客户端程序库编写的节点同样能够共享消息,这是因为所有的客户端程序库中都实现了代码生成器,从而允许用户可以使用期望的语言来与ROS的接口文件进行交互。
另外对于一些特定编程语言特殊的通信工具,客户端程序库将核心功能暴露给用户,这更像的ROS的风格。比如,下边是一个通过客户端程序库可以访问的功能列表:
- 名字和命名空间
- 时间(真实时间与仿真时间)
- 参数
- 终端日志
- 线程模型
- 进程间通信
支持的客户端程序库
C++客户端程序库(rclcpp)和Python客户端程序库(rclpy)都是利用RCL(ROS Client Library)中常用功能实现的客户端程序库。
这两个库现在已经由ROS2团队维护,并且ROS2社区的成员已经正在创建其他的一些客户端程序库,比如:
- JVM 和 Android
- Objective C 和 iOS
- C#
- Swift
- Node.js
- Ada
- _.NET Core, UWP 和 C#
通用性功能:RCL
很多在客户端程序库中的功能并不是某个客户端程序库编程语言所特有的功能。比如,参数的行为以及命名空间的逻辑,这些概念应该在所有编程语言中都是一致的。所以,客户端程序库可以使用一个通用的RCL内核接口来实现这些逻辑和行为,而不需要从原型中使用特殊编程语言来实现这些通用功能。进而,客户端程序库只需要使用外部函数接口来包装这些RCL中的通用功能,这使得实际开发的客户端程序库更轻量级并且更易于扩展。因为这个原因,通用的RCL功能使用C语言暴露出来,因为C语言是最容易包装的一种语言。
除了能够让客户端程序库更加轻量级,包装RCL通用内核的另外一个优势是编程语言之间的行为逻辑将更为固定。如果在RCL内核上有任何关于功能性逻辑和行为的改变,比如命名空间,所有包装RCL通用内核的客户端程序库均会被更新。而且,包装通用内核将有利于在修改bug时能够以最小的工作量维护多个客户端程序库。
RCL中的API文档在这里:http://docs.ros2.org/latest/api/rcl/
编程语言特殊的功能
客户端程序库中与特定编程语言相关的特性或属性在RCL内核中没有实现,而是在每一个客户端程序库中单独实现。比如,使用spin函数的线程模型将会在特殊编程语言的客户端程序库中实现。
实例
有个公开的视频集,推荐看一下,其中从17:25开始的一段内容,演示了使用rclpy实现的发布者节点与使用rclcpp实现的订阅者节点之间的信息交换。
与ROS1的比较
在ROS1中,所有的客户端程序库功能都是需要从头开发的。比如说,ROS1中的Python客户端程序库完全的用Python语言实现,这样做的好处是不需要编译代码,然而,命名约定和行为在客户端程序库之间经常不是固定的,这就需要在多个不同的地方修复bug,并且有很多功能仅仅在一个客户端程序库中实现,比如UDPROS。
总结
通过使用通用内核的RCL,客户端程序库可以使用不同的编程语言来方便的编写,并且还能保证行为一致性。