< >
Home » ROS2入门教程 » ros2入门教程-比较ros1和ros2的异同

ros2入门教程-比较ros1和ros2的异同

ros2入门教程-比较ros1和ros2的异同

说明:

  • 介绍通过比较ros1和ros2的异同,了解如何从ros1迁移到ros2

为什么 ROS2 而不是保留 ROS1

  • ROS1 最初由 Willow Garage 于 2007 年创建,在开源机器人社区中已经变得非常庞大。

  • ROS1 背后的团队已经学会了——凭借这些年的经验,缺少哪些重要功能,以及可以改进的地方。 不幸的是,将所有这些修改添加到 ROS1 中需要许多重大更改,并使 ROS1 非常不稳定。 所以,ROS2是从零开始开发的,是一个全新的ROS。

  • 至于现在ROS在业界还不是很流行,缺乏一些最重要的要求,比如实时性、安全性、认证性。

  • ROS2 的目标之一是使其与工业应用兼容。

ROS1 和 ROS2 分布

  • 这是 ROS1 的情况:ROS Noetic(发布日期:2020)是最后一个 ROS1 版本。 这个最终的 ROS1 版本主要目标是为需要继续使用 ROS1 一段时间的开发人员/组织提供 Python3 支持。

  • ROS Noetic 的 EOL(End of Life)定于 2025 年。在那之后,不再有 ROS1! 所以,如果你今天在 ROS1 中有很大的代码库,那完全没问题,但不要等到 2024 年才开始进行更改。

  • 对于 ROS2,从 LTS(长期支持)版本 Foxy Fitzroy(发布日期:2020)开始,每年都会发布一个新的 ROS2 版本。 与之前对 ROS1 所做的相同。

  • 你已经可以开始使用现在相当稳定的 ROS2——至少核心功能,一些 3rd 方插件仍然缺失。

  • 现在让我们来探讨差异。 我将它们分成 3 个主要部分以形成某种结构,但可以随意跳到任何一点,它们都可以独立阅读。

ROS1 vs ROS2:编写节点

1.##ROS API – rclcpp, rclpy##

  • 在 ROS1 中,对于 Cpp,您使用 roscpp,对于 Python,使用 rospy。这两个库都是完全独立的,并且是从头开始构建的。这意味着 roscpp 和 rospy 之间的 API 不一定相同,并且某些功能是针对其中一个开发的,而不是针对另一个开发的。

  • ROS2 有更多的层。只有一个名为 rcl 的基础库,用 C 语言实现。这是包含所有 ROS2 核心特性的基础。

  • 您不会直接在程序中使用 rcl 库。您将使用构建在 rcl 之上的另一个客户端库。例如:rclcpp 用于 Cpp,rclpy 用于 Python。

  • 它有什么好处?那么任何新功能只需要使用 rcl 来实现。然后,在 rcl 之上的客户端库只需要提供绑定。

  • 对于作为开发人员的您来说,这意味着:

  • rclcpp 和 rclpy 之间的 API 将比 roscpp 和 rospy 之间的 API 更加相似。

  • 创建和使用其他语言的客户端库会更容易,例如rclnodejs、rcljava等。不需要重新发明轮子,你只需要用rcl做一个C绑定。 - 所有语言的所有客户端都将具有类似的 API。

  • 当一个新的核心功能发布时,它将更快地以不同的语言提供,因此您不必等待太多。

2.##Python 和 Cpp 版本##

  • 您可能知道,不再支持 Python2。 事实上,为了提供更顺畅的过渡,它仍然支持 Ubuntu 18 和 ROS1 Melodic,直到它们的 EOL(2023 年)。

  • Python3针对ROS1 Noetic以及所有 ROS2 版本。

  • 现在,对于 Cpp 来说,有一些很大的进展。 ROS1 的目标是 Cpp 98,您可以在以后的 ROS1 版本中使用 Cpp 11/14,前提是它不会破坏其他依赖项。

  • 在 ROS2 中,您现在可以默认使用 Cpp 11 和 14。 Cpp 17 也在路线图上。 这很棒,因为新版本的 Cpp 引入了许多有用的功能,使开发更容易、更快、更安全。 此外,它使 Cpp 更有趣,也许这将有助于使这种强大而伟大的语言民主化

3.##编写节点(使用 OOP)##

  • 在 ROS1 中,没有特定的结构告诉您应该如何编写节点功能。 您可以决定在程序的任何地方添加回调函数,或者如果您愿意,也可以使用 OOP,但每个实现都可能是独一无二的。

  • 在 ROS2 中,情况有所不同。 关于如何编写节点有一个约定。 您必须创建一个继承自 Node 对象的类(例如:Cpp 中的 rclcpp::Node,Python 中的 rclpy.node.Node)。

  • 这很棒,因为它将为每个人节省大量时间。 你已经有了一个很好的模块化结构来编写你的节点。 它将使您的程序更清洁,并且不同项目的开发人员之间的合作将更加容易。

  • 在 ROS2 中为您的节点使用 OOP 还允许您将它们转换为组件,这是 ROS2 中的一项新功能。

4.##同一可执行文件中的多个节点 – ROS2 组件##

  • 在 ROS1 中,节点与可执行文件紧密相关。 在 ROS1 中添加了一个名为 Nodelets 的新功能,以便能够在同一个可执行文件中编写多个节点,并进行进程内通信。 当您的硬件资源有限和/或您需要在节点之间发送大量消息时,这真的很棒。

  • 在 ROS2 中,Nodelets 不再被称为 Nodelets。 该功能已直接包含在 ROS2 核心中,现在称为“组件”。

  • 因此,使用 ROS2,您可以使用组件处理来自同一个可执行文件的多个节点。 组件只是一个稍微修改过的节点类(我们仍然在那里使用 OOP)。

  • 然后,您可以从启动文件、终端或可执行文件启动组件。 您可以激活进程内通信以消除任何 ROS2 通信开销。

  • 构建组件是创建高效 ROS2 应用程序的好习惯。

5.##生命周期节点##

  • ROS2 引入了生命周期节点的概念。 生命周期节点具有不同的状态:未配置、非活动、活动、已完成。 当您在实际运行节点的主要功能之前需要一个设置阶段时,这非常有用。

  • 当您启动这样一个节点时,它最初是未配置的。 通过提供的接口(ROS2 服务),您可以请求转换到另一个状态。 当您这样做时,将在节点内触发预定义的回调。

  • 假设您有一个传感器节点。 您首先需要确保检测到传感器,并且通信已成功启动。 然后您可以开始阅读循环并发布数据。

  • 使用生命周期节点,您可以清楚地将其分开:首先,您为发布者、订阅者和其他实例化对象分配内存。 然后,您启动与传感器的通信。 最后你运行你的阅读循环来发布数据。

6.编写启动文件

  • 启动文件允许您从一个文件启动所有节点。您可以启动标准节点、组件、生命周期节点。您可以添加自变量、参数和许多其他选项。

  • ROS1 中,您已经习惯使用 XML 编写启动文件。

  • 在 ROS2 中,您现在将使用 Python 编写启动文件。有一个 API 允许您启动节点、检索配置文件、添加参数等。它将允许您比以前更多地自定义启动文件。

  • 但是,用 Python 编写启动文件真的很新鲜吗?好吧事实上没有。在 ROS1 中还有一个 Python API。问题是:没有人知道它,关于它的文档几乎为零。所以,没有人使用它。用 XML 编写启动文件已成为一种常态,这很棒,但肯定不像 Python API 那样模块化。

  • 而且……如果你愿意,你也可以用 XML 编写你的 ROS2 启动文件。但更喜欢使用 Python,因为它带来了更多的模块化、更多的文档,并且已经成为启动文件的 ROS2 约定。

ROS1 与 ROS2:通信

1.不再有 ROS master

  • 您从 ROS1 中学到的一件事是:始终在运行节点之前启动 ROS 主节点。 ROS1 master 将充当您节点的 DNS 服务器,因此它们可以相互检索。

  • 在 ROS2 中,没有更多的 ROS master 了! 这不再是一个集中式系统。 每个节点都有发现其他节点的能力。 您可以简单地启动一个节点,而不必担心是否有一个主节点正在运行。

  • 这种变化很棒,因为它允许您创建一个完全分布式的系统。 每个节点都是独立的,不必关心全局主节点。

  • 在创建多机 ROS2 应用程序时,您不必将一台机器定义为“主机”。 每台机器都将是独立的,并且能够自行启动、相互连接和断开连接,并且比 ROS1 中的设置更少。

2.参数

  • 因此,在 ROS1 中,参数由参数服务器处理,而参数服务器本身由……ROS master 处理。

  • 在 ROS2 中,没有更多的 ROS 主服务器 = 没有更多的(全局)参数服务器。

  • 参数的概念已经完全改变。不再有全局参数。每个参数都特定于一个节点。

  • 一个节点声明和管理自己的参数,这些参数在节点被杀死时被销毁。

  • 就像每个节点都有自己的参数服务器一样。当您启动一个节点时,会创建一些 ROS2 服务。这些允许您从终端或其他节点与其参数进行交互。

  • 此外,您可以在创建节点后使用参数回调轻松修改节点的参数。

  • 如果您在 ROS1 中使用 dynamic_reconfigure 工具,那么,好消息,现在这是核心功能的一部分。无需额外配置,您只需将参数回调绑定到您的节点。

  • 查看如何处理代码中的参数:rclcpp 参数和 rclpy 参数。

  • 以及如何创建参数回调:rclpp 参数回调和 rclpy 参数回调。

3.服务

  • 在 ROS1 中,服务是同步的。 当您的服务客户端向服务器请求请求时,它会一直卡住,直到服务器响应(或失败)。

  • 在 ROS2 中,服务是异步的。

  • 当您调用服务时,您可以添加一个回调函数,该回调函数将在服务器响应时触发。 与此同时,你的主线程没有卡住。

  • 当然,如果你愿意,你也可以同步使用服务。

4. 动作

  • 在 ROS1 中,动作从未出现在核心功能中。 这是几年后的一个补充,解决了服务不异步,没有反馈或取消机制的问题。

  • 因此,ROS1 中的操作完全建立在 ROS1 话题之上。

  • 在 ROS2 中,动作现在是 ROS2 核心的一部分。 Cpp 和 Python 的 API 与 ROS1 非常相似,因此代码没有问题。

  • 在下面,动作仍然使用话题来提供反馈和目标状态,但也使用(异步)服务来设置目标、取消目标和请求结果。

  • 现在,动作也有了自己的命令行工具! 正如您对服务所做的那样,您现在可以直接从终端将操作目标发送到服务器。

5. 消息、服务和动作定义

  • 为消息、服务和动作创建定义的方式在 ROS1 和 ROS2 中非常相似。 您仍然将它们放入 msg/、srv/ 和 action/ 文件夹中。

  • 但是在编译它们之后,会添加一个命名空间:

Message: msg/…
Services: srv/…
Actions: action/…
  • 例如,假设您有一个名为 my_robot_msgs 的包,并且在此包中创建了一个名为 Temperature 的消息,以及一个名为 ActivateButton 的服务。 在您的节点代码中,您必须使用以下命令导入它们:
my_robot_msgs/msg/Temperature.
my_robot_msgs/srv/ActivateButton.
  • 这很棒,因为它减少了混淆,并使所有 3 种通信类型之间的分离更加清晰。

6. 服务质量

  • ROS2 引入了 QoS,即服务质量。

  • 使用该功能,您可以选择节点如何处理通信:您想确保收到所有消息吗?或者,只要数据经常更新,丢失几条消息就可以了?您是要保留消息队列以防节点没有时间处理所有消息,还是要在前一条消息的回调仍在运行时丢弃任何新消息?

  • 好吧,如果您必须为您的应用程序提出此类问题,那么您将需要为您的节点调整 QoS。

  • 默认情况下,已选择 ROS2 通信(主题、服务等)的 QoS,因此您可以期待与 ROS1 中相同的行为:

  • 任何订阅主题的节点都不会收到之前的消息,只会收到订阅后发布的消息。

  • 与 TCP 一样,消息保证被传递。

  • 您可以为等待处理的已传递消息设置队列大小。

  • 如果您必须处理有损耗的无线网络和/或较大的消息带宽,那么 QoS 是一个值得关注的设置。

  • 但是,如果您刚刚开始使用 ROS,或者有一个非常简单的应用程序,请不要担心 QoS。有更重要的东西要先学习,当你需要的时候你会回到QoS。

ROS1 vs ROS2:包、工作区和环境

1. 构建你的节点

  • ROS1中的构建系统是catkin。 你使用“catkin_make”或“catkin build”来构建和安装你的包。

  • 在 ROS2 中,没有更多的柳絮。 Ament 是新的构建系统,除此之外,您还可以获得 colcon 命令行工具。

  • 要编译,您将在 ROS2 工作区中使用命令“colcon build”。

  • 关于 ament 和 colcon 还有很多话要说,但只要有了这些信息,您就可以毫无问题地构建您的第一个节点。

2. 命令行工具

  • 大多数命令行工具在 ROS1 和 ROS2 之间是相似的。 工具的名称和一些选项不同,但在使用时没有太大区别。

  • 例如,要列出所有主题,在 ROS1 中您将执行“rostopic list”,在 ROS2 中您将执行“ros2 topic list”。 “rosservice” 变成 ros2 服务,“rosrun” 变成 ros2 run,“rosbag” 变成 ros2 bag,等等。

  • 你只需要写“ros2”,然后是你想使用的工具的名称。

3. Cpp 和 Python 包

  • 使用 ROS1,您可以创建一个包,然后添加您想要的任何 Cpp/Python 文件。

  • ROS2 区分了 Cpp 和 Python 包。从命令行创建包时,您必须指定一种构建类型:ament_cmake 或 ament_python。

  • 根据该论点,包架构将不一样。

  • 对于 Cpp 包,情况与 ROS1 非常相似。你还有一个 CMakeLists.txt。您只需要调整您的 cmake 指令以使用 ament 而不是 catkin。

  • 对于 Python 包,情况有所不同:您有一些新文件,例如 setup.py 和 setup.cfg。 setup.py 替换了 CMakeLists.txt。您当然可以直接运行您的 Python 脚本,但如果您想从 ROS2 命令行工具或启动文件启动它们,您必须先安装它们(使用“colcon build”)。

  • 如果你愿意,你也可以为 Python 和 Cpp 创建一个 ROS2 包,但这需要更多的设置。

  • 总的来说,在 ROS2 中设置包比在 ROS1 中复杂一点,但它也更完整,更有条理。

4. 引入工作区和覆盖

  • 在 ROS1 和 ROS2 之间引入 ROS 环境并没有太大的不同。 您首先获取您的全局 ROS 安装,然后是您的工作区,然后您可以使用您的自定义代码。

  • ROS2 带来了叠加层的概念。 您可以在彼此之上拥有多个工作区。

  • 首先你获取你的全局 ROS 安装,然后是你的第一个工作空间(覆盖),你的第二个覆盖等等。如果一个包在较低级别的覆盖和较高级别的覆盖中具有相同的名称,那么只会使用较高级别的。

  • 当您开发应用程序并且已经拥有一定数量的包时,您可以只为一个包创建覆盖。 这将允许您快速迭代它,同时为其他项目保持代码库不变。

  • 使用这种技术,您还可以覆盖已经从二进制文件安装的包。 这是非常实用的,因此您可以保持安装包,同时为特定应用程序拥有自己的版本。

5. 操作系统支持

  • ROS1 的主要目标是 Ubuntu。

  • ROS2 的好消息:由于其新架构,您可以在 Ubuntu、MacOS 和 Windows 10(+其他操作系统,但这是 3 个主要操作系统)上安装和使用它。

  • 这将使 ROS2 在许多应用程序中更易于访问和嵌入。

  • 例如,您可以拥有一个带有 Raspberry Pi 和 Ubuntu 的移动机器人,以及另一台使用 Windows 的计算机作为 3D 模拟工具和一个驱动程序节点,用于扫描场景的相机。 所有这一切都顺利进行。

6. 何时从 ROS1 切换到 ROS2?

  • 没那么简单,很多人会告诉你不同的答案。 ROS1 仍然很强大,有很多稳定的插件、更多的文档和 3rd 方插件。最终它会结束,但你还有几年的时间。

  • 如果您是 ROS 新手(无论是 ROS1 还是 ROS2),那么您可能应该学习 ROS2 基础知识。但是,尝尝 ROS1 也很有趣。为什么?因为如果你也看到它在 ROS1 中是如何完成的,你可能会更好地理解 ROS2 中的一些东西。此外,您想要使用的某些工具/包可能尚未移植到 ROS2,因此您别无选择,只能使用 ROS1 版本的包。在这种情况下,ros1_bridge 包将很有用(见下一节)。

  • 如果你已经了解 ROS 并且想要开始一个全新的项目,那么走 ROS2 的方式可能是你应该做的,所以这意味着未来的过渡工作更少。 ROS1 和 ROS2 的核心概念是相似的,所以你对 ROS1 的经验越多,你学习 ROS2 的时间就越少。您还可以使用 ROS1 和 ROS2,与 ros1_bridge 一起使用,以便使用缺少的工具和插件。

  • 如果您的一个或多个机器人已经在 ROS1 中拥有代码库,或者对于拥有数十名开发人员的完整组织,切换到 ROS2 可能需要大量工作。代码库越大,ROS 对你的项目的影响越大,花费的时间就越长,也就越复杂。您可以选择继续使用 ROS1 处理遗留项目,并开始使用 ROS2 处理新项目。或者,您现在可以开始将所有代码移植到 ROS2,因为这涉及到很多工作(取决于您的代码编写得如何)。首先,在您决定进行完全切换之前,请确保您需要的大部分 ROS 功能都已移植到 ROS2。同样,ros1_bridge 可以在过渡期间为您提供帮助。

7. 将 ROS1 和 ROS2 与 ros1_bridge 包一起使用

  • 如果您需要使用现有的 ROS1 代码库,但想使用 ROS2 开发新功能,那么您不一定会卡住。

  • 您可以使用名为 ros1_bridge 的 ROS2 包,顾名思义,它将成为 ROS1 和 ROS2 通信之间的桥梁。

  • 即使 ROS1 和 ROS2 的概念是一样的,但是底层的通信并不能直接兼容,需要一些适配。 ros1_bridge 包提供了这一点。

  • 在过渡到 ROS2 时,您可以开始在 ROS2 中移植一些包,并使这些包与您的 ROS1 应用程序的其余部分进行通信。 然后,你移植越来越多的包,直到用 ROS1 写的东西都没有了。 在所有移植期间,您的应用程序仍然可以按预期工作。

ROS1 vs ROS2:结论

  • 在本文中,您已经看到了 ROS1 和 ROS2 之间的一些主要区别。 我试图使该方法侧重于实用方面,因此当您使用 ROS 开发机器人应用程序时,您可以大致了解发生了什么变化。

  • 要了解最新信息,您可以查看 ROS Discourse 论坛,在那里您会看到有关新概念、辩论和公告的有趣讨论。

  • 现在,这里提供的列表肯定不是详尽无遗的,有些信息可能会发生变化,因为 ROS2 仍在不断发展。 但是,当您决定学习 ROS2 时,了解您需要关注什么是一个很好的起点。

参考:

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros2入门教程