计算机视觉/视频分析

使用适用于 ROS 的 NVIDIA Isaac Transport 提升自定义 ROS 图形

 

适用于 ROS 的 NVIDIA Isaac Transport(NITROS)是在 ROS 2 Humble 中引入的两种硬件加速功能——类型适应和类型协商的实现。

类型适应 使 ROS 节点能够以针对特定硬件加速器优化的数据格式工作。经过调整的类型用于处理图形,以减少 CPU 和内存加速器之间的内存复制。

通过类型协商,不同的 ROS 节点可以在图形中公布它们支持的类型,使得 ROS 框架能够选择合适的数据格式,从而实现最佳性能。

GIF showing a comparison between inefficient hardware acceleration and NITROS-enabled efficient hardware acceleration. In the first case, image data is copied multiple times between CPU and GPU resulting in slow data transfer. In the second case, image data is transferred once from CPU to GPU, and is then accessible directly from GPU memory to NITROS-compatible nodes.
图 1.NITROS 通过减少 CPU 和 GPU 之间的内存复制来实现高效加速

当两个支持 NITROS 的 ROS 节点在一个图形中相邻时,它们可以通过类型协商发现彼此,然后使用类型适应来共享数据。类型适应和类型协商相结合,通过删除不必要的内存拷贝,显著提高了基于 ROS 的应用程序中 AI 和计算机视觉任务的性能。

这降低了 CPU 开销,并优化了底层硬件的性能。图 1 显示了使用 NITROS 实现的高效硬件加速。数据可从 GPU 显存访问,而无需频繁进行 CPU 复制。

您可以在处理图形中将基于 NITROS 的 Isaac ROS 节点与其他 ROS 节点结合使用,因为 ROS 框架能够与不支持协商的传统节点保持兼容。在与非 NITROS 节点通信时,支持 NITROS 的节点的功能与典型的 ROS 2 节点相似。大多数 Isaac ROS GEM 都是 NITROS 加速的。

详细了解 NITROS 和系统假设:NVIDIA NITROS 文档

采用 NITROS 的 NVIDIA CUDA

NVIDIA CUDA 是一种并行计算编程模型,能够利用 GPU 大幅加速机器人系统中的功能。您可以通过托管 NITROS 发布者和托管 NITROS 订阅者,将 CUDA 与 NITROS 结合使用,以优化您的自定义 ROS 2 节点。

Block diagram showing CUDA with NITROS. Your ROS 2 node can use a Managed NITROS Subscriber ‌or Publisher to communicate with other NITROS-capable nodes.
图 2.使用 NITROS 的 CUDA 概述

ROS 节点中的 CUDA 代码可以使用 GPU 显存与支持 NITROS 的 Isaac ROS 节点共享其输出缓冲区,托管 NITROS 发行商。这将消除昂贵的 CPU 内存复制,从而提高性能。NITROS 还通过发布与普通 ROS 2 消息相同的数据来保持与非 NITROS 节点的兼容性。

Block diagram showing the use of Managed NITROS Publisher in your ROS 2 node. Your node can then communicate with both NITROS-capable and non-NITROS nodes (like RViz) through type adaptation.
图 3.ROS 2 节点中的 NITROS Publisher

在订阅者端,ROS 节点中的 CUDA 代码可以使用托管 NITROS 用户。输入可以来自支持 NITROS 的 Isaac ROS 节点,也可以来自使用 NITROS Publisher 的另一个支持 CUDA 的 ROS 节点。与带管理的 NITROS Publisher 一样,这通过增加 GPU 和 CPU 之间的并行计算来提供更好的性能。

lock diagram showing the use of Managed NITROS Subscriber in your ROS 2 node. Your node can then subscribe to NITROS-typed messages from a NITROS-capable node through type adaptation.
图 4.ROS 2 节点中的 NITROS 订阅者

为了更好地理解这一点,我们来考虑一个执行基于 DNN 的点云分割的示例图。总的来说,以下是使用 CUDA 和 NITROS 的三个主要组件:

  1. 使用带管理的 NITROS Publisher 的编码器节点sensor_msgs/PointCloud2将消息转换成NitrosTensorList
  2. Isaac ROS TensorRT 节点用于执行 DNN 推理,NitrosTensorList并生成输出NitrosTensorList
  3. 带托管 NITROS 订阅者的解码器节点,用于转换输出NitrosTensorList分割成一个sensor_msgs/PointCloud2市场宣传文本

托管式 NITROS 发布者和订阅者提供熟悉的界面,与标准 rclcpp::Publisher rclcpp::Subscriber API,可直观地与现有的 ROS 2 节点集成。CUDA 与 NITROS 还实现了更模块化的软件设计。借助托管 NITROS 发行商和订阅者,CUDA 节点可以在图形中的任何位置与 Isaac ROS 节点和其他 CUDA 节点一起使用,从而在每个节点中获得加速计算的优势。

再深入探究一下,NITROS 基于 NVIDIA 图形执行框架(GXF),这是一个用于构建高性能计算图的可扩展框架。NITROS 利用 GXF 实现高效的 ROS 应用图。借助 NITROS 的 CUDA,开发者可以在不需要深入了解 GXF 底层工作原理的情况下,支持 NITROS 节点。GXF 层被抽象化,使用户能够像平常一样轻松快速地编写 ROS 2 节点,并通过直接调整以启用 NITROS。

详细了解 核心概念:CUDA 与 NITROS 的结合。

目前,托管式 NITROS 发行商和订阅者仅与 Isaac ROS 兼容 NitrosTensorList 消息类型。请访问 isaac_ros_nitros_type 以获取 NITROS 数据类型的完整列表。

使用 CUDA 与 NITROS 和 YOLOv8 进行物体检测

Isaac ROS 提供了 YOLOv8 样本,展示了如何结合使用托管式 NITROS 实用程序与自定义 ROS 解码器,以充分利用 NITROS。此示例利用 Isaac ROS DNN 推理 中的 YOLOv8,执行 TensorRT 加速的物体检测。托管式 NITROS 发布者和订阅者使用 NITROS 类型的消息,目前仅与 Isaac ROS NitrosTensorList 消息类型兼容。此消息类型用于在节点与 Isaac ROS DNN 推理节点之间共享张量。

An image of a group of people on bicycles with bounding boxes drawn around detected objects in the image. These are the results of object detection using YOLOv8 and Isaac ROS DNN Inference.
图 5.使用 Isaac ROS DNN 推理检测 YOLOv8 物体

假设您想使用具有 Isaac ROS DNN 推理和 CUDA NITROS 加速的自定义物体检测模型。检测流程涉及三个主要步骤:输入图像编码、DNN 推理和输出解码。Isaac ROS DNN 推理可实现前两个步骤。

在解码步骤中,必须从推理结果(即张量)中提取相关信息。对于 2D 物体检测等任务,相关信息包括图像中检测到的每个输出的边界框和类分数。

我们来详细了解每个步骤。

第 1 步:编码

在输入端,Isaac ROS 提供了 NITROS 加速的DNN 图像编码器。它会预处理输入图像,并将其转换为张量,然后通过 isaac_ros_tensor_list 输入到 TensorRT 或 Triton 节点进行推理。

您可以为调整大小等各种预处理函数指定图像大小和网络预期的输入大小等参数。请注意,根据任务,您将需要不同的编码器。例如,您无法将此图像编码器与语言模型一起使用,因为网络需要不同的输入编码。

Diagram showing an overview of the Isaac ROS DNN Image Encoder node. The node takes in a ROS 2 image message as input, encodes it into a list of tensors and outputs an Isaac ROS TensorList message. This message is passed onto the Isaac ROS inference node.
图 6.Isaac ROS DNN 图像编码器节点概述

第 2 步:推理

Isaac ROS 为 DNN 推理提供了两个 ROS 节点,分别是 TensorRT 节点Triton 节点。目前,YOLOv8 示例使用的是 TensorRT 节点。您只需将训练好的模型提供给 TensorRT 节点,该节点便会执行推理并输出包含检测结果的张量。

此输出张量列表将传递给解码器节点。您可以指定网络预期的维度和张量名称等参数,这些信息可以通过使用 Netron 等工具轻松找到。

Block diagram showing an overview of the Isaac ROS TensorRT inference node. It takes a trained model and an input tensor list from the image encoder node as input, performs inference, and outputs a tensor list containing inference results to the decoder node.
图 7.Isaac ROS TensorRT 推理节点概述

第 3 步:解码

必须将来自 TensorRT 或 Triton 节点的推理输出张量解析为所需边界框和类信息。假设您已将模型的解码器编写为 ROS 2 节点(尚未支持 NITROS)。解码器节点不支持 NITROS 类型的消息,并且需要来自推理节点的典型 ROS 2 消息。这仍然有效,因为 NITROS 与非 NITROS 节点保持兼容性。

但是,在这种情况下,来自推理节点(GPU 显存中)的输出 NITROS 类型消息将转换为 ROS 2 消息,并带到 CPU 显存以供解码器使用。由于数据现在位于 CPU 显存中,因此这会增加一些开销,导致在与下游 ROS 节点一起工作时出现 CPU 显存复制。

现在,假设您想升级解码器,以通过 NITROS 与推理节点(和其他 NITROS 加速节点)通信,而不是产生 CPU 显存复制成本。在这种情况下,所有数据都保留在 GPU 显存中。

通过在解码器节点中使用托管 NITROS 订阅者,可以轻松实现这一点。它订阅来自推理节点的 NITROS 类型的输出消息,并使用 NITROS 视图 获取包含检测输出的 CUDA 缓冲区。然后,您可以对这些数据实施解码逻辑,并通过适当的 ROS 消息类型发布结果。

YOLOv8 解码器可配置 NMS 值和置信值等参数,以筛选候选检测结果。可使用简单的可视化节点订阅生成的 ROS 消息,并在输入图像上绘制边界框。请注意,带管理的 NITROS 只能与 CPP ROS 2 节点集成。

Diagram showing an overview of the YOLOv8 Decoder node. This node takes in an encoded tensor list from the inference node, extracts required information from the detection results and output results as a Detection2DArray ROS 2 message.
图 8.YOLOv8 解码器节点概述

Isaac ROS NITROS 桥接器

如果您的机器人应用目前基于 ROS 1,您仍然可以利用新发布的 Isaac ROS NITROS 桥接器。对于那些使用早于 Humble 版本的 ROS 2,无法进行类型适应和协商的开发者来说,这个桥接器也非常有用。

为了突出显示可以实现的加速效果,NITROS 桥接器在 ROS 1 Noetic 和 NITROS 软件包之间传输 1080p 图像时,速度提高了 2.5 倍,相比于 ROS 1 桥接器

ROS 桥接器包含基于 CPU 的内存复制成本,而 Isaac ROS NITROS 桥接器通过将数据从 CPU 移动到 GPU 来消除这种成本。这些数据可以在 GPU 显存中就地使用。

NITROS 桥接器由两个转换器节点组成。一个用于 ROS 侧(例如 Noetic),另一个用于 ROS 2 侧(例如 Humble)。在没有 NITROS 转换器的情况下使用 ROS 桥接器会导致图像从 Noetic 发送到 Humble,并通过 CPU 内存中 ROS 进程的副本返回,从而增加延迟。这个问题在发送大量数据(例如分段点云)的节点之间尤为明显。

Block diagram of ROS bridge without NITROS converters.
图 9.不带 NITROS 转换器的 ROS 桥接器

NITROS 桥接器旨在降低 ROS 版本之间的端到端延迟。考虑使用相同的示例,这次使用 NITROS 转换器。Noetic 侧的转换器(图 10)将图像移动到 GPU 显存,避免通过桥接器复制 CPU 内存。Humble 侧的转换器(图 10)将 GPU 显存中的图像转换为与其他 NITROS 加速节点兼容的 NITROS 图像类型。

工作原理与之类似,即图像数据作为 NITROS 图像从 Humble 通过两侧的转换器发送到 Noetic 中 CPU 可访问内存中的图像。

想要了解更多关于性能提升的信息,请访问 Isaac ROS 基准测试,了解 NITROS 桥接器ros1_bridge 的详细信息。请注意,Isaac ROS NITROS 桥接器目前尚不支持 NVIDIA Jetson 平台。

Block diagram showing an overview of NITROSb. On the ROS 1 side, an image in CPU memory is copied over to the GPU through the NITROS Converter ROS node. This image can be used on the ROS 2 side through the NITROS Converter ROS 2 node without any CPU copies since it is available in GPU memory. In this way, the image is also accessible to other NITROS nodes.
图 10.NITROS 桥接器概述

将 ROS 2 节点与 NITROS 集成的优势

以下总结了将 ROS 2 节点与 NITROS 集成的诸多优势:

  • 通过减少 CPU 内存复制来提高性能。
  • 兼容其他非 NITROS ROS 节点,例如 RViz.
  • 通过托管 NITROS 发行商和订阅者,轻松将自定义 ROS 2 节点与硬件加速的 Isaac ROS 节点集成。
  • 使用 CUDA 和 NITROS 进行模块化软件设计。
  • 使用 NITROS 桥接器提高基于早期 ROS 版本的应用程序的性能。

尝试使用 Isaac ROS NITROS 和我们的 YOLOv8 物体检测 示例!
欲了解更多关于我们的硬件加速软件包的信息,请访问 NVIDIA Isaac ROS 文档。如需获取 Isaac ROS 的最新信息,请访问 开发者论坛

 

Tags