教程:VENTUNO Q/ROS 2 RGB 相机:修订间差异

来自WindwizPi wiki
此页面具有访问限制。如果您看见此消息,则说明您没有权限访问此页面。
Windwiz​(留言 | 贡献)
导入 VENTUNO Q 中文教程
 
Windwiz​(留言 | 贡献)
导入 VENTUNO Q 中文教程
 
第27行: 第27行:
=== 硬件连接 ===
=== 硬件连接 ===


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/ventuno-sbc-mode-camera.png" alt="VENTUNO Q 单板计算机模式" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/ventuno-sbc-mode-camera.png
 


上图显示了本教程中使用的基本 VENTUNO Q 设置、电路板、电源、HDMI 显示器、USB 键盘和鼠标,在 SBC 模式下运行 Ubuntu。这是连接任何传感器之前的起点。除了此基本设置之外,USB 网络摄像头还连接到主板的 USB-A 端口之一,而 CSI 摄像头则通过主板的板载 MIPI-CSI-2 连接器进行连接。
上图显示了本教程中使用的基本 VENTUNO Q 设置、电路板、电源、HDMI 显示器、USB 键盘和鼠标,在 SBC 模式下运行 Ubuntu。这是连接任何传感器之前的起点。除了此基本设置之外,USB 网络摄像头还连接到主板的 USB-A 端口之一,而 CSI 摄像头则通过主板的板载 MIPI-CSI-2 连接器进行连接。
第155行: 第157行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_webcam_1.png" alt="UVC 兼容 USB 相机 - ROS" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_webcam_1.png
 


“起始”行显示节点正在使用的设备、分辨率、捕获方法和请求的帧速率,检查此处的设备路径与您在上面标识的路径是否匹配。如果没有出现这一行,则该节点无法打开摄像头,我们需要检查下面的[[#troubleshooting|故障排除部分]]。
“起始”行显示节点正在使用的设备、分辨率、捕获方法和请求的帧速率,检查此处的设备路径与您在上面标识的路径是否匹配。如果没有出现这一行,则该节点无法打开摄像头,我们需要检查下面的[[#troubleshooting|故障排除部分]]。
第302行: 第306行:
从窗口顶部的主题下拉列表中选择“/image_raw”。
从窗口顶部的主题下拉列表中选择“/image_raw”。


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/usb-webcam-rqt-image-view.gif" alt="rqt_image_view 中的 USB 网络摄像头输入" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/usb-webcam-rqt-image-view.gif
 


<span id="using-multiple-cameras"></span>
<span id="using-multiple-cameras"></span>
第326行: 第332行:
VENTUNO Q 具有 MIPI-CSI-2 接口,支持包括 IMX577 在内的摄像头模块。要使 CSI 相机正常工作,需要首先安装高通的相机驱动程序堆栈,因为传感器直接连接到 SoC 的图像信号处理器,而不是显示为标准 USB 设备。
VENTUNO Q 具有 MIPI-CSI-2 接口,支持包括 IMX577 在内的摄像头模块。要使 CSI 相机正常工作,需要首先安装高通的相机驱动程序堆栈,因为传感器直接连接到 SoC 的图像信号处理器,而不是显示为标准 USB 设备。


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/csi_setup.png" alt="CSI 摄像机设置" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/csi_setup.png
 


[https://www.arducam.com/arducam-imx577-mini-camera-module-for-qualcomm-rb3g2.html 适用于 Qualcomm RB3G2 的 Arducam IMX577 迷你摄像头模块] (SKU B0488) 可与 VENTUNO Q 配合使用,无需任何硬件修改。
[https://www.arducam.com/arducam-imx577-mini-camera-module-for-qualcomm-rb3g2.html 适用于 Qualcomm RB3G2 的 Arducam IMX577 迷你摄像头模块] (SKU B0488) 可与 VENTUNO Q 配合使用,无需任何硬件修改。
第413行: 第421行:
启动文件将相机节点组成容器并开始流式传输。最后一行在相机运行时定期重复,报告流名称、像素格式、分辨率和测量的帧速率:
启动文件将相机节点组成容器并开始流式传输。最后一行在相机运行时定期重复,报告流名称、像素格式、分辨率和测量的帧速率:


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_1.png" alt="QRB ROS 相机 (1)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_1.png
 


只要您需要相机,就让它在终端中运行,关闭它会停止每个下游节点的流。
只要您需要相机,就让它在终端中运行,关闭它会停止每个下游节点的流。
第451行: 第461行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_2.png" alt="QRB ROS 相机 (2)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_2.png
 


检查发布率:
检查发布率:
第528行: 第540行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_1.png" alt="CSI 相机 - ROS (1)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_1.png
 


只要您想要使用相机,就让该节点在自己的终端中运行,关闭它会完全停止图像流,包括使用它的任何下游节点,例如本节后面介绍的 [[#using-csi-camera-with-edge-impulse|Edge Impulse 集成]]。
只要您想要使用相机,就让该节点在自己的终端中运行,关闭它会完全停止图像流,包括使用它的任何下游节点,例如本节后面介绍的 [[#using-csi-camera-with-edge-impulse|Edge Impulse 集成]]。
第542行: 第556行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_2.png" alt="CSI 相机 - ROS (2)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_2.png
 


该管道捕获相机的本机 NV12 输出。它在发布之前在软件中将其转换为 '''RGB8''',类似于 USB 网络摄像头部分中介绍的转换。
该管道捕获相机的本机 NV12 输出。它在发布之前在软件中将其转换为 '''RGB8''',类似于 USB 网络摄像头部分中介绍的转换。
第563行: 第579行:
从窗口顶部的主题下拉列表中选择“/camera/image_raw”。
从窗口顶部的主题下拉列表中选择“/camera/image_raw”。


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_3.png" alt="CSI 相机 - ROS (3)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_3.png
 


<span id="using-multiple-cameras"></span>
<span id="using-multiple-cameras"></span>
第582行: 第600行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_4.png" alt="CSI 相机 - ROS (4)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_4.png
 


在两个节点都运行的情况下,名称空间重新映射将第二个相机的主题放置在“/camera1/camera/image_raw”,而不是“/camera1/image_raw”,因为单独的重新映射可能会建议:
在两个节点都运行的情况下,名称空间重新映射将第二个相机的主题放置在“/camera1/camera/image_raw”,而不是“/camera1/image_raw”,因为单独的重新映射可能会建议:
第590行: 第610行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_5.png" alt="CSI 相机 - ROS (5)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_5.png
 


使用“gscam”同时运行两个摄像头是可能的,尽管与单独运行单个摄像头相比,每个流的持续速率会下降,通常每个流都会下降到 5 到 7 Hz 范围,因为两个流共享相同的 CPU 端转换工作和摄像头 ISP。
使用“gscam”同时运行两个摄像头是可能的,尽管与单独运行单个摄像头相比,每个流的持续速率会下降,通常每个流都会下降到 5 到 7 Hz 范围,因为两个流共享相同的 CPU 端转换工作和摄像头 ISP。
第671行: 第693行:
本部分使用 '''QNN 加速的 YOLO11 模型''',[assets/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim <code>yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px</code>],从 Edge Impulse Studio 导出并与本文档一起提供。
本部分使用 '''QNN 加速的 YOLO11 模型''',[assets/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim <code>yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px</code>],从 Edge Impulse Studio 导出并与本文档一起提供。


[assets/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim <img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/downloads-banner.png" alt="QNN 加速的 YOLO11 模型示例" />]
[assets/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim  
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/downloads-banner.png
]


QNN 加速模型在 Qualcomm Hexagon NPU 而不是 CPU 上运行,因此该模型预计比基于标准 CPU 的“.eim”模型运行速度要快得多。与任何“.eim”文件一样,在运行之前确保它是可执行的:
QNN 加速模型在 Qualcomm Hexagon NPU 而不是 CPU 上运行,因此该模型预计比基于标准 CPU 的“.eim”模型运行速度要快得多。与任何“.eim”文件一样,在运行之前确保它是可执行的:
第693行: 第717行:
成功加载后,节点会报告模型详细信息、确认订阅并开始推理:
成功加载后,节点会报告模型详细信息、确认订阅并开始推理:


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_3.png" alt="QRB ROS 相机 (3)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_3.png
 


这是使 NV12 流直接可用的配对,“edgeimpulse_ros”对其进行本地解码,因此相机和模型之间不需要颜色转换节点。
这是使 NV12 流直接可用的配对,“edgeimpulse_ros”对其进行本地解码,因此相机和模型之间不需要颜色转换节点。
第717行: 第743行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_6.png" alt="CSI 相机 - ROS (6)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_6.png
 


<span id="verifying-detections"></span>
<span id="verifying-detections"></span>
第752行: 第780行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_7.png" alt="CSI 相机 - ROS (7)" />
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_7.png
 


要查看带注释的提要,请使用“publish_debug_image:=true”启动并在“rqt_image_view”中打开它:
要查看带注释的提要,请使用“publish_debug_image:=true”启动并在“rqt_image_view”中打开它:
第760行: 第790行:
</syntaxhighlight>
</syntaxhighlight>


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_4.png" alt="CSI相机-QRB ROS相机" />


<img src="https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_8.png" alt="CSI 相机 - gscam" />
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_qrb_csi_4.png
 
 
 
https://cdn.jsdelivr.net/gh/arduino/docs-content@main/content/hardware/ventuno/boards/ventuno-q/tutorials/robotics/ros2-perception-rgb-cam/assets/perception_csi_8.png
 


<span id="edge-impulse-troubleshooting"></span>
<span id="edge-impulse-troubleshooting"></span>

2026年9月28日 (一) 06:01的最新版本

概述

相机使机器人能够观察、检测物体和估计距离。在 ROS 2 中,相机数据作为标准消息类型通过主题发布,因此系统中的任何节点都可以订阅和处理它,无论哪个特定相机生成它。

在本教程中,您将连接并配置 Arduino® VENTUNO™ Q 上提供的两个 RGB 摄像头选项、使用 usb_cam 驱动程序的标准 USB 网络摄像头,以及使用 Qualcomm qrb_ros_camera 软件包的 CSI 摄像头。

目标

  • 连接 USB 网络摄像头并将其图像流发布为 ROS 2 主题。
  • 安装 Qualcomm 相机驱动程序堆栈并通过“qrb_ros_camera”流式传输 CSI 相机。
  • 从终端验证每个摄像头的数据速率并使用“rqt_image_view”查看它。
  • 使用 Edge Impulse 对摄像机流运行对象检测。

硬件与软件要求

硬件要求

硬件连接

ventuno-sbc-mode-camera.png


上图显示了本教程中使用的基本 VENTUNO Q 设置、电路板、电源、HDMI 显示器、USB 键盘和鼠标,在 SBC 模式下运行 Ubuntu。这是连接任何传感器之前的起点。除了此基本设置之外,USB 网络摄像头还连接到主板的 USB-A 端口之一,而 CSI 摄像头则通过主板的板载 MIPI-CSI-2 连接器进行连接。

VENTUNO Q 有两个 USB-A 端口,在此基本设置中键盘和鼠标已占用这些端口。由于 USB 网络摄像头还需要 USB 端口,因此建议将 USB-C 集线器连接到开发板的 USB-C 端口,以提供额外的 USB-A 端口,这样您就无需在每次连接网络摄像头时断开键盘或鼠标的连接。

说明:

在本教程中,显示​​器通过主板的本机 HDMI 端口进行连接,从而为集线器保留 USB-C 端口。

软件要求

警告:

在继续本教程之前,请确保您的 VENTUNO Q 安装了最新的系统映像并且 ROS 2 Jazzy 正常工作。

USB网络摄像头

USB 网络摄像头是将图像数据输入 ROS 2 系统的最简单方法。 VENTUNO Q 具有两个 USB-A 端口,与任何遵循 UVC(USB 视频类) 标准的相机兼容,该标准涵盖了当今大多数消费类网络摄像头。

usb_cam 包是一个基于 V4L(Linux 视频) 的驱动程序,它是比 UVC 更广泛的标准,涵盖了 Linux 上的大多数 USB 摄像头。它从相机设备读取帧并将其作为 ROS 2 主题上的“sensor_msgs/Image”消息发布。

连接相机

将网络摄像头插入 VENTUNO Q 的 USB-A 端口之一。要验证它是否显示为视频设备,请打开终端并运行:

ls /dev/video*

您至少应该看到“/dev/video0”。如果您连接了多个 USB 摄像头,每个摄像头将显示为单独编号的设备。

安装USB CAM

直接从 ROS 2 软件包存储库安装二进制版本:

sudo apt-get install ros-jazzy-usb-cam

如果由于某种原因二进制文件不可用,请从源代码构建包。将其克隆到您的工作区中,使用 rosdep 安装依赖项,并使用 colcon 进行构建:

cd ~/ros2_ws/src
git clone https://github.com/ros-drivers/usb_cam.git
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -y
colcon build
source ~/ros2_ws/install/setup.bash

有关完整的软件包文档和源代码,请参阅 usb_cam GitHub 存储库。

运行相机节点

由于本教程还涵盖 CSI 摄像头,因此安装其驱动程序堆栈可以改变 USB 网络摄像头的设备索引,安装 CSI 驱动程序后,/dev/video0 可能不再是网络摄像头。在运行节点之前确认正确的设备:

ls /dev/video*

如果列出了多个视频设备,并且您不确定哪个是网络摄像头,请在不指定设备的情况下运行一次节点,控制台输出会在末尾按名称列出每个检测到的设备:

ros2 run usb_cam usb_cam_node_exe

您还可能会看到“/dev/v4l-subdev*”路径的一系列“无法检索设备功能”或“无法打开设备”行。这些是在枚举期间扫描的 CSI 摄像头的内部 ISP 子设备,而不是网络摄像头,因此可以安全地忽略。

一旦您知道正确的设备,有两种方法可以启动节点。

最简单的是直接传递设备:

ros2 run usb_cam usb_cam_node_exe --ros-args -p video_device:=/dev/video2

您还可以从 YAML 文件加载参数,这是一起配置相机设备、分辨率和像素格式的方法。包附带两个示例参数文件“params_1.yaml”和“params_2.yaml”,安装在包的共享目录下。由于该目录是只读的,因此首先将文件复制到您的主目录:

cp /opt/ros/jazzy/share/usb_cam/config/params_1.yaml ~/usb_cam_params.yaml

编辑副本中的“video_device”字段以匹配正确的设备:

sed -i 's|video_device: "/dev/video0"|video_device: "/dev/video2"|' ~/usb_cam_params.yaml

然后使用编辑后的副本运行节点:

ros2 run usb_cam usb_cam_node_exe --ros-args --params-file ~/usb_cam_params.yaml

您只需要运行这两者之一,而不是同时运行两者。成功启动应类似于以下日志:

[INFO] [usb_cam]: camera_name value: test_camera
[WARN] [usb_cam]: framerate: 30.000000
[INFO] [usb_cam]: Starting 'test_camera' (/dev/video2) at 640x480 via mmap (mjpeg2rgb) at 30 FPS


perception_webcam_1.png


“起始”行显示节点正在使用的设备、分辨率、捕获方法和请求的帧速率,检查此处的设备路径与您在上面标识的路径是否匹配。如果没有出现这一行,则该节点无法打开摄像头,我们需要检查下面的故障排除部分。

首次运行时的预期警告

第一次运行节点时,您可能会看到如下校准警告:

[ERROR] [camera_calibration_parsers]: Unable to open camera calibration file [...]
[WARN] [usb_cam]: Camera calibration file ... not found

这是预期的且无害的。该节点还没有校准文件,因为尚未为该相机生成校准文件,并且如果没有校准文件,它将继续正常运行。

需要进行校准才能使用相机执行需要精确距离或几何测量的任务。

一旦节点开始捕获帧,您可能还会看到类似以下的警告:

unknown control 'white_balance_temperature_auto'
unknown control 'exposure_auto'
unknown control 'focus_auto'

这意味着您的特定相机型号不会公开特定的 V4L2 控件。它因相机而异,不会影响图像流。

检查支持的格式

每个相机都会报告一组不同的支持分辨率和格式。要查看您的特定相机支持什么,请运行该节点并观察其启动时的控制台输出。它显示与此类似的列表:

This device supports the following formats:
    YUYV 4:2:2 640 x 480 (30 Hz)
    YUYV 4:2:2 640 x 480 (25 Hz)
    YUYV 4:2:2 320 x 240 (30 Hz)
    YUYV 4:2:2 800 x 600 (20 Hz)
    YUYV 4:2:2 960 x 720 (10 Hz)
    YUYV 4:2:2 1280 x 720 (7 Hz)
    YUYV 4:2:2 1280 x 960 (7 Hz)
    Motion-JPEG 640 x 480 (30 Hz)
    Motion-JPEG 320 x 240 (30 Hz)
    Motion-JPEG 800 x 600 (30 Hz)
    Motion-JPEG 960 x 720 (30 Hz)
    Motion-JPEG 1280 x 720 (30 Hz)
    Motion-JPEG 1280 x 960 (30 Hz)
    ... (full list includes every framerate down to 5 Hz for each resolution)

请注意,YUYV 在更高分辨率(如 1280x720)下下降至 7 Hz,而 Motion-JPEG 在所有列出的分辨率(高达 1280x960)中保持完整的 30 Hz。

这是前面提到的两种格式之间带宽差异的直接摄像机报告示例。 YUYV 未压缩,每帧需要比 Motion-JPEG 更多的 USB 带宽,这就是为什么压缩格式仍可提供更高的分辨率和帧速率。

一旦您知道您的相机支持什么,请在“~/usb_cam_params.yaml”副本中设置“pixel_format”字段以匹配列出的格式之一。如果您不确定格式字符串是否有效,可以直接测试它,并以与以前相同的方式显式指定设备:

ros2 run usb_cam usb_cam_node_exe --ros-args -p video_device:=/dev/video2 -p pixel_format:="test"

这个故意无效的值会产生一个明显的错误,列出驱动程序实际接受的每个格式名称:

[INFO] [1786583769.755635724] [usb_cam]: Starting 'default_cam' (/dev/video2) at 640x480 via mmap (test) at 30 FPS
...
This driver supports the following formats:
    rgb8
    yuyv
    yuyv2rgb
    uyvy
    uyvy2rgb
    mono8
    mono16
    y102mono8
    raw_mjpeg
    mjpeg2rgb
    m4202rgb
terminate called after throwing an instance of 'std::invalid_argument'
  what():  Specified format `test` is unsupported by this ROS driver

此列表是 ROS 驱动程序本身理解的“pixel_format”值集,与上面特定相机报告的分辨率和帧速率列表分开。设置“pixel_format”时使用这些确切名称之一。将“test”替换为任何格式名称将告诉您驱动程序是否将其识别为受支持。

验证图像流

在节点运行的情况下,打开第二个终端并检查图像主题是否正在发布:

ros2 topic list | grep image

查看实际发布率:

ros2 topic hz /image_raw

让其运行至少 60 秒,而不是读取前几个样本。在 VENTUNO Q 上,速率开始时接近相机为“mjpeg”和“yuyv”配置的帧速率,然后在第一分钟内逐渐降低,然后稳定在较低的持续速率,通常在 640x480 时介于 10 到 15 Hz 之间,即使使用“mjpeg”时也是如此。

这种减少与基于软件的色彩空间转换一致,在节点的启动输出中显示为“swscaler”警告。如果您需要更高的持续帧速率,请考虑较低的分辨率,因为每帧数据较少会降低软件转换成本。

以下是在 VENTUNO Q 上使用“mjpeg2rgb”进行的 60 多秒会话的简短示例,显示了上述模式:

average rate: 29.992
        min: 0.030s max: 0.037s std dev: 0.00225s window: 31
average rate: 26.360
        min: 0.026s max: 0.167s std dev: 0.01857s window: 107
average rate: 18.021
        min: 0.026s max: 1.853s std dev: 0.13195s window: 311
average rate: 13.034
        min: 0.026s max: 3.232s std dev: 0.24949s window: 500
average rate: 10.397
        min: 0.024s max: 3.523s std dev: 0.30513s window: 1960

请注意,“max”列随着下降的速率而增长,这是各个帧之间不断扩大的差距,而不仅仅是较慢的平均值。汇率稳定在这个较低范围内,并且在本交易日的剩余时间内不会恢复。

压缩

只要您的系统上安装了“image_transport_plugins”包,“usb_cam”节点就会通过“image_transport”自动发布压缩图像主题。

这为您提供了一个“压缩”主题以及原始主题,无需任何额外配置。但是,像 RViz2 这样的工具无法直接可视化压缩图像,因此如果您想在 RViz2 中查看压缩流,请先将其重新发布为原始图像:

ros2 run image_transport republish compressed raw \
  --ros-args --remap in/compressed:=image_raw/compressed --remap out:=image_raw/uncompressed

可视化流

如果您有连接到 VENTUNO Q 的显示器,“rqt_image_view”将为您提供相机正在工作的即时视觉反馈,而无需从终端解释主题速率:

sudo apt install ros-jazzy-rqt-image-view
ros2 run rqt_image_view rqt_image_view

从窗口顶部的主题下拉列表中选择“/image_raw”。


usb-webcam-rqt-image-view.gif


使用多个相机

如果您将多个 USB 网络摄像头连接到 VENTUNO Q 的两个 USB-A 端口,则每个节点都需要一个唯一的命名空间,否则两个节点都会尝试发布到相同的“/image_raw”主题并发生冲突。

首先使用“ls /dev/video*”确认两个设备路径,然后重新映射每个设备的命名空间,用您的实际设备路径替换下面的“/dev/video0”和“/dev/video2”:

ros2 run usb_cam usb_cam_node_exe --ros-args --remap __ns:=/usb_cam_0 -p video_device:=/dev/video0
ros2 run usb_cam usb_cam_node_exe --ros-args --remap __ns:=/usb_cam_1 -p video_device:=/dev/video2

这将分别在“/usb_cam_0/image_raw”和“/usb_cam_1/image_raw”上发布两个流。

CSI摄像机

VENTUNO Q 具有 MIPI-CSI-2 接口,支持包括 IMX577 在内的摄像头模块。要使 CSI 相机正常工作,需要首先安装高通的相机驱动程序堆栈,因为传感器直接连接到 SoC 的图像信号处理器,而不是显示为标准 USB 设备。


csi_setup.png


适用于 Qualcomm RB3G2 的 Arducam IMX577 迷你摄像头模块 (SKU B0488) 可与 VENTUNO Q 配合使用,无需任何硬件修改。

有两种方法可以将 CSI 相机引入该平台上的 ROS 2。 qrb_ros_camera 是 Qualcomm 的 ROS 2 相机包,也是 VENTUNO Q 上的推荐路径,因为它直接与相机 ISP 通信,并通过零拷贝传输以传感器的本机 NV12 格式发布帧。 gscam 包装了 GStreamer 管道并转换为 RGB8,这适合需要标准颜色编码的工具。下面介绍了两者,从“qrb_ros_camera”开始。

安装摄像头驱动

安装 Qualcomm 风格的 GStreamer 插件、CamX 和相关内核驱动程序:

sudo apt update && sudo apt upgrade -y && sudo apt install gstreamer1.0-plugins-qcom -y

连接相机后,重新启动开发板,以便驱动程序可以正确初始化传感器:

sudo reboot

连接相机的扁平电缆时,电缆的蓝色一侧必须朝上,朝向连接器的前面。

验证摄像头检测

重启后,检查板是否识别出连接的摄像头:

sudo dmesg | grep Probe
CAM_INFO: CAM-SENSOR: cam_sensor_driver_cmd: 1250: Probe failed for cmk_imx577 slot:23, slave_addr:0x34, sensor_id:0x577
CAM_INFO: CAM-SENSOR: cam_sensor_driver_cmd: 1290: Probe success for cmk_imx577 slot:24,slave_addr:0x34,sensor_id:0x577
CAM_INFO: CAM-SENSOR: cam_sensor_driver_cmd: 1250: Probe failed for cmk_imx577 slot:25, slave_addr:0x34, sensor_id:0x577

驱动程序扫描多个可能的 I2C 插槽地址,因此看到多个“探测失败”行不是问题。重要的是“探测成功”行的数量,它应该与您物理连接的摄像机数量相匹配。

QRB ROS相机

qrb_ros_camera 是 Qualcomm 的 ROS 2 相机包,适用于 Qualcomm 平台上的 CSI 和 GMSL 相机。它通过传感器已使用的相机服务和 CamX 层读取帧,然后通过 Linux DMA 缓冲区支持的零复制传输来发布它们,因此图像数据不会在同一进程中复制到订阅者。

安装QRB ROS相机

该软件包通过两个 Qualcomm IoT 软件包档案“qcom-ppa”和“qirp”进行分发。第一个文件已在本教程前面安装相机驱动程序时添加,因此在添加任何内容之前请检查存在哪些存档:

grep -rn "ubuntu-qcom-iot" /etc/apt/sources.list.d/ /etc/apt/sources.list 2>/dev/null

如果未列出,请添加“qirp”存档,然后刷新包列表以便新包可用:

sudo add-apt-repository ppa:ubuntu-qcom-iot/qirp
sudo apt update

现在安装包:

sudo apt install ros-jazzy-qrb-ros-camera

这还会拉取“ros-jazzy-qrb-camera”、“ros-jazzy-qrb-ros-transport-image-type”和“ros-jazzy-lib-mem-dmabuf”。这些是相机堆栈及其零拷贝传输的支持库。

运行相机节点

该软件包附带了一个启动文件,该文件以工作默认配置启动相机,因此您无需在首次运行时传递任何参数。获取 ROS 2 环境,然后启动节点:

source /opt/ros/jazzy/setup.bash
ros2 launch qrb_ros_camera qrb_ros_camera_launch.py

启动文件将相机节点组成容器并开始流式传输。最后一行在相机运行时定期重复,报告流名称、像素格式、分辨率和测量的帧速率:


perception_qrb_csi_1.png


只要您需要相机,就让它在终端中运行,关闭它会停止每个下游节点的流。

说明:

启动文件配置为 1280x720、30 FPS。 QRB ROS 相机存储库将 1920x1080 记录为默认参数,但启动文件设置了自己的值,该值优先。

当相机运行时,打开第二个终端来检查它正在发布的内容。该节点为每个流创建一个主题,以相机 ID 和流名称命名,因此默认的单流配置为图像提供“/cam0_stream1”,为校准数据提供“/cam0_stream1_camera_info”:

ros2 topic list
/cam0_stream1
/cam0_stream1_camera_info
/parameter_events
/rosout

尽管发布者在内部使用类型适应、DMA 缓冲区支持的图像,但普通订阅者看到的是标准的“sensor_msgs/msg/Image”:

ros2 topic info -v /cam0_stream1
Type: sensor_msgs/msg/Image
Publisher count: 1
Node name: camera_node
QoS profile:
  Reliability: RELIABLE
  Durability: VOLATILE


perception_qrb_csi_2.png


检查发布率:

ros2 topic hz /cam0_stream1
average rate: 21.370
 min: 0.017s max: 0.301s std dev: 0.03076s window: 332
average rate: 21.222
 min: 0.017s max: 0.301s std dev: 0.03122s window: 351
average rate: 21.168
 min: 0.017s max: 0.301s std dev: 0.03137s window: 394

该汇率在持续的交易时段内保持稳定,而不是随着时间的推移而下降。外部订阅者测量的速率低于节点内部报告的速率,因为零复制路径有利于组成同一容器的节点。

读回已发布的框架的格式:

ros2 topic echo /cam0_stream1 --no-arr
height: 720
width: 1280
encoding: nv12
is_bigendian: 0
step: 1280
data: '<sequence type: uint8, length: 1382400>'

警告:

rqt_image_view 无法直接显示该主题。它依赖于“cv_bridge”,它无法将“nv12”识别为图像编码并报告“无法识别的图像编码[nv12]”。订阅本身有效,只是显示转换失败。要查看相机输出,请使用解码 NV12 的节点,例如下面介绍的 Edge Impulse 集成,或使用发布 RGB8 的“gscam”。

斯卡姆

说明:

CSI 相机管道改进目前正在进行中,一旦可用,将包含在本节中。

gscam 是替代路径。它使用 Qualcomm 的“qtiqmmfsrc”源包装 GStreamer 管道,并在发布之前转换为 RGB8,这在下游工具需要标准颜色编码而不是 NV12 时非常有用。

使用以下命令安装软件包:

sudo apt install ros-jazzy-gscam

运行节点,将其指向相机管道:

ros2 run gscam gscam_node \
  --ros-args \
  -p gscam_config:="qtiqmmfsrc camera=0 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! queue ! videoconvert" \
  -p image_encoding:="rgb8" \
  -p sync_sink:=false \
  -p use_gst_timestamps:=true \
  -p frame_id:="camera_link"

成功启动后,节点会报告正在使用的管道,然后确认流正在运行:

[INFO] [gscam_publisher]: Using gstreamer config from rosparam: "qtiqmmfsrc camera=0 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! queue ! videoconvert"
[INFO] [gscam_publisher]: Publishing stream...
[INFO] [gscam_publisher]: Started stream.


perception_csi_1.png


只要您想要使用相机,就让该节点在自己的终端中运行,关闭它会完全停止图像流,包括使用它的任何下游节点,例如本节后面介绍的 Edge Impulse 集成。

该节点在“/camera”命名空间下而不是在根目录下发布,因此实际的图像主题是“/camera/image_raw”,而不是“/image_raw”:

ros2 topic list | grep image
ros2 topic hz /camera/image_raw


perception_csi_2.png


该管道捕获相机的本机 NV12 输出。它在发布之前在软件中将其转换为 RGB8,类似于 USB 网络摄像头部分中介绍的转换。

在 1920x1080 的单个相机上,持续速率稳定在 8 到 9 Hz 范围内,远低于所要求的 30 FPS,因为转换发生在 CPU 上而不是在硬件中。

可视化流

如果您有连接到 VENTUNO Q 的显示器,则可以使用“rqt_image_view”查看实时摄像头源:

sudo apt install ros-jazzy-rqt-image-view
ros2 run rqt_image_view rqt_image_view

从窗口顶部的主题下拉列表中选择“/camera/image_raw”。


perception_csi_3.png


使用多个相机

如果连接了多个 CSI 摄像机,则检测步骤中的每条“Probe success”行对应一个可用摄像机索引,从“0”开始。为下一个摄像头运行第二个“gscam”实例,重新映射其节点名称和命名空间,以便它不会与第一个实例发生冲突:

ros2 run gscam gscam_node \
  --ros-args \
  -r __node:=gscam_publisher_1 \
  -r __ns:=/camera1 \
  -p gscam_config:="qtiqmmfsrc camera=1 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! queue ! videoconvert" \
  -p image_encoding:="rgb8" \
  -p sync_sink:=false \
  -p use_gst_timestamps:=true \
  -p frame_id:="camera_link_1"


perception_csi_4.png


在两个节点都运行的情况下,名称空间重新映射将第二个相机的主题放置在“/camera1/camera/image_raw”,而不是“/camera1/image_raw”,因为单独的重新映射可能会建议:

ros2 topic list | grep image


perception_csi_5.png


使用“gscam”同时运行两个摄像头是可能的,尽管与单独运行单个摄像头相比,每个流的持续速率会下降,通常每个流都会下降到 5 到 7 Hz 范围,因为两个流共享相同的 CPU 端转换工作和摄像头 ISP。

使用具有 Edge Impulse 的 CSI 相机

edgeimpulse_ros 是 Edge Impulse 的官方 ROS 2 软件包。它将经过训练的“.eim”模型包装为与相机无关的节点“edgeimpulse_detector”,该节点订阅任何“sensor_msgs/Image”主题并将结果发布为标准“vision_msgs”,无需学习自定义消息类型。

该节点本地解码多种编码,包括“bgr8”、“rgb8”、“yuyv”和 NV12。这对于 VENTUNO Q 来说直接重要,因为这意味着节点可以直接订阅“qrb_ros_camera”的 NV12 输出,无需单独的颜色转换步骤,从而避免了本节前面介绍的“gscam”CPU 转换开销。

安装Edgeimpulse_ROS

安装 ROS 消息依赖项和 Python 绑定:

sudo apt update
sudo apt install ros-jazzy-vision-msgs ros-jazzy-diagnostic-msgs \
  python3-opencv python3-numpy portaudio19-dev

安装 Edge Impulse Linux SDK。即使对于视觉模型,SDK 也会在加载时导入“pyaudio”,因此无论模型类型如何,它都需要存在:

pip install --user --break-system-packages edge_impulse_linux pyaudio

警告:

不要将 Edge Impulse Linux SDK (linux-sdk-python) 克隆到工作区的 src/ 目录中,colcon 会尝试将其构建为 ROS 包。如上所示,使用“pip”安装它。

rm -rf ~/ros2_ws/src/edgeimpulse_ros
rm -rf ~/ros2_ws/build/edgeimpulse_ros ~/ros2_ws/install/edgeimpulse_ros

警告:

如果您之前在本系列前面测试过社区 edgeimpulse_ros 包,请先将其删除,这两个包声明相同的内部 ROS 包名称,并且不能共存于同一工作区中:


如果您在删除之前已尝试构建,还请清除过时的构建工件以避免入口点注册损坏:

克隆并构建包:

cd ~/ros2_ws/src
git clone https://github.com/edgeimpulse/edgeimpulse-ros.git
cd ~/ros2_ws
colcon build --packages-select edgeimpulse_ros
source install/setup.bash

模型

本部分使用 QNN 加速的 YOLO11 模型,[assets/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px],从 Edge Impulse Studio 导出并与本文档一起提供。

[assets/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim downloads-banner.png ]

QNN 加速模型在 Qualcomm Hexagon NPU 而不是 CPU 上运行,因此该模型预计比基于标准 CPU 的“.eim”模型运行速度要快得多。与任何“.eim”文件一样,在运行之前确保它是可执行的:

chmod +x yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim

使用 Qrb_ros_camera 运行

qrb_ros_camera 必须已在其自己的终端中运行,如本节前面所述。将检测节点指向其图像主题,内置解码器在内部处理 NV12 转换:

ros2 launch edgeimpulse_ros edgeimpulse_detector.launch.py \
  model_path:="/path/to/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim" \
  image_topic:=/cam0_stream1 \
  image_qos:=sensor_data

成功加载后,节点会报告模型详细信息、确认订阅并开始推理:


perception_qrb_csi_3.png


这是使 NV12 流直接可用的配对,“edgeimpulse_ros”对其进行本地解码,因此相机和模型之间不需要颜色转换节点。

与 Gscam 一起运行

在启动检测节点之前,“gscam”必须已在其自己的终端中运行,如本节前面所述。将节点指向 gscam 主题:

ros2 launch edgeimpulse_ros edgeimpulse_detector.launch.py \
  model_path:="/path/to/yolo11-small-linux-aarch64-qnn-v1-impulse-2-480px.eim" \
  image_topic:=/camera/image_raw \
  image_qos:=sensor_data

成功加载后,节点会报告模型详细信息并开始推理:

[INFO] [edgeimpulse_detector]: Loaded model "Marco Colombo/Yolo11 Small" type=object_detection input=480x480 rgb resize=fit-shortest has_anomaly=0 kinds=['detection'] labels=['person', 'bicycle', 'car', ...]
[INFO] [edgeimpulse_detector]: Subscribed to "/camera/image_raw" (raw, qos=sensor_data)
[INFO] [edgeimpulse_detector]: First inference result keys: ['bounding_boxes']


perception_csi_6.png


验证检测结果

ros2 topic echo /edgeimpulse_detector/detections

成功检测后,主题会报告原始图像像素坐标中的类标签、置信度得分和边界框:

detections:
- header:
    stamp:
      sec: 1787090150
      nanosec: 737264321
    frame_id: cam0_stream1
  results:
  - hypothesis:
      class_id: chair
      score: 0.5727539658546448
    pose:
      pose:
        position: {x: 0.0, y: 0.0, z: 0.0}
        orientation: {x: 0.0, y: 0.0, z: 0.0, w: 1.0}
  bbox:
    center:
      position: {x: 389.25, y: 332.25}
      theta: 0.0
    size_x: 217.5
    size_y: 346.5
  id: ''


perception_csi_7.png


要查看带注释的提要,请使用“publish_debug_image:=true”启动并在“rqt_image_view”中打开它:

ros2 run rqt_image_view rqt_image_view /edgeimpulse_detector/debug_image


perception_qrb_csi_4.png


perception_csi_8.png


边缘脉冲故障排除

如果节点因“依赖项“pyaudio”丢失”而无法启动,则无论模型类型如何,Edge Impulse SDK都会在加载时导入“pyaudio”。安装系统库和 Python 轮:

sudo apt install portaudio19-dev
pip install --user --break-system-packages pyaudio

如果节点因“模型文件...不可执行”而失败,则“.eim”文件需要使用“chmod +x”设置其执行位。

如果~/detections上没有出现消息,请确认相机主题实际上是使用ros2 topic hz <image_topic>发布的,并确认image_qos与发布者兼容,reliable订阅者无法从best_effort发布者接收,sensor_data是上面使用的安全默认值。

故障排除

如果连接网络摄像头后未找到“/dev/video0”,请尝试不同的 USB 端口并使用以下命令检查内核日志中的设备错误:

dmesg | tail -30

如果“usb_cam”节点启动,但您不确定要使用哪种像素格式,请运行该节点一次并读取打印到控制台的支持格式,然后在“config/params.yaml”中设置“pixel_format”以完全匹配。

如果 ros2 topic hz /image_raw 报告的帧率在启动节点后缓慢攀升,而不是立即读取接近目标帧率,这是正常的,速率估计需要大量样本才能稳定。让它运行至少30秒,然后再判断实际保持的速率。

如果“ros2节点列表”或“ros2主题列表”返回空,即使节点明显在另一个终端中运行,ROS 2发现守护进程可能处于过时状态,这可能在测试期间重复启动和停止节点后发生。直接重启:

ros2 daemon stop
ros2 daemon start

如果网络摄像头在会话中途停止出现在“/dev/video*”下,即使它之前工作过,请检查内核日志中是否有断开连接事件:

dmesg | tail -30

查找提及相机已断开连接或重置的行。如果在持续使用过程中反复出现这种情况,则可能表明存在 USB 供电问题而不是软件问题,请尝试不同的 USB 端口,并避免使用会增加电源路径电阻的 USB 集线器或延长线。

如果节点报告“未知控制‘focus_auto’”,并且无论设置什么参数,图像都永远不会聚焦,则您的相机可能根本没有自动对焦电机。例如,罗技 C270 是一款定焦摄像头,出厂设置范围为大致无限远,低至约 40 厘米,并且没有 ROS 参数可以添加硬件中实际不存在的自动对焦功能。将相机重新定位在其原始对焦范围内,而不是尝试在软件中调整对焦。

如果CSI摄像机图像出现失焦,可以手动调整镜头。镜头通过小螺丝固定在安装座中,稍微松开它们,旋转镜头直至图像清晰,然后重新拧紧。在调整时使用 Edge Impulse 调试图像或“rqt_image_view”中的“gscam”流实时检查结果。

如果在查看“qrb_ros_camera”主题时“rqt_image_view”报告“无法识别的图像编码[nv12]”,这是预期的。 rqt_image_view 用于转换图像以供显示的 cv_bridge 不支持 NV12。订阅本身正常工作,只是显示转换失败。通过解码 NV12 的节点查看流,例如 Edge Impulse 调试图像,或使用发布 RGB8 的“gscam”。

如果 CSI 摄像头未出现在dmesg | grep Probe 输出,确认扁平电缆正确就位,蓝色面朝上并朝向连接器的前面,并且在连接相机后重新启动了板。如果“gscam”启动但从未发布任何图像数据,请确认已安装“gstreamer1.0-plugins-qcom”,这是提供管道依赖的“qtiqmmfsrc”元素的包。

总结

在本教程中,您已将 USB 网络摄像头和 CSI 摄像头连接到 VENTUNO Q 并将其数据发布为 ROS 2 主题。这些主题是标准 ROS 2 消息类型,可以直接由本系列其余部分中的 SLAM、导航和 AI 节点使用。

后续步骤

随着 RGB 图像数据流经 ROS 2 主题,您可以继续进行深度传感或 2D 映射:

致谢

ROS 是 Open Source Robotics Foundation 的商标。本教程仅用于教育目的,帮助用户在 Arduino 硬件上学习 ROS 2。本内容并不意味着 Arduino 与 Open Source Robotics Foundation 之间存在背书、合作或隶属关系。

支持

在使用 VENTUNO Q 过程中如遇问题或有疑问,我们提供多种支持资源帮助你找到答案与解决方案。

帮助中心

浏览我们的帮助中心,其中提供大量面向 VENTUNO Q 的文章与指南。Arduino 帮助中心旨在提供深入的技术支持,帮助你充分发挥设备潜力。

论坛

加入我们的社区论坛,与其他用户交流、分享经验并提问。

联系我们

若需要个性化协助,或有上述帮助与支持资源未涵盖的问题,请联系我们的支持团队。


原文:https://docs.arduino.cc/tutorials/ventuno-q/ros2-perception-rgb-cam/ 本页为 Arduino 官方教程的中文翻译,供内部查阅。命令与代码保持原文。