ROS 2 Humble image publishers for a Jetson CSI camera or a V4L2 USB camera.
源码目录:
/home/ubuntu/ros2_ws/src/Camera_USB_and_CSI
ROS 2 包名遵循命名规范,使用小写:
camera_usb_and_csi
功能包括:
- Jetson CSI 相机节点,通过
nvarguscamerasrc获取图像。 - V4L2 USB 相机节点,默认通过
/dev/usb_cam获取图像。 - 一个 launch 文件,通过
camera_type:=CSI或camera_type:=USB选择节点。 - CSI 和 USB 节点都默认发布
/image_raw,可直接连接collect_picture。 - USB 设备序列号绑定脚本及 udev 规则。
Warning
不要同时启动 CSI 和 USB 节点向同一个 /image_raw 发布,否则订阅端会收到两个发布者的图像。
source 只对当前终端有效。每次新开终端、标签页或 SSH 会话,都要重新执行:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash如果目标机器还没有可用的 ROS 2 工作空间,先按本节从零创建,再继续后面的设备绑定与启动步骤。
mkdir -p /home/ubuntu/ros2_ws/src
cd /home/ubuntu/ros2_ws将 Camera_USB_and_CSI 整个目录复制到工作空间 src 下(按你的实际源码位置调整左侧路径):
cp -a /home/ubuntu/ros2_ws/src/Camera_USB_and_CSI /home/ubuntu/ros2_ws/src/如果源码当前就在该位置,也可以跳过复制,直接检查目录是否存在:
ls -la /home/ubuntu/ros2_ws/src/Camera_USB_and_CSIcd /home/ubuntu/ros2_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install --packages-select camera_usb_and_csi
source /home/ubuntu/ros2_ws/install/setup.bashsource /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 pkg prefix camera_usb_and_csi
ros2 pkg executables camera_usb_and_csi若能输出包路径和可执行节点列表,说明工作空间与功能包已就绪。
source 只对当前终端有效。每次新开终端、标签页或 SSH 会话,都要重新执行:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bashecho "source /opt/ros/humble/setup.bash" >> ~/.bashrc
echo "source /home/ubuntu/ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrcNote
如果你同时维护多个 ROS 2 工作空间,建议不要都写入 ~/.bashrc,避免环境相互覆盖。可按项目在终端手动 source 对应工作空间。
部署前必须按第 4 节列出并人工确认 CSI、USB 设备。下表是本功能包验证所使用的设备
映射;实际 /dev/videoN 编号应以目标主机的检查结果为准。
| 设备 | 识别结果 |
|---|---|
/dev/video0 |
IMX219 CSI 相机,由 Jetson Argus 使用。 |
/dev/video1 |
icSpring USB 摄像头的视频采集接口。 |
/dev/video2 |
同一 USB 摄像头的非采集接口,不应绑定。 |
USB 摄像头的稳定属性:
VID=32e6
PID=9251
SERIAL=202404150001
V4L2 index=0
测试脚本使用 Ubuntu 提供且支持 GStreamer 的 OpenCV,确保能够打开 Jetson CSI 管线。
无界面读取 30 帧:
python3 /home/ubuntu/Desktop/csi_camera_test.py --no-display --frames 30打开测试窗口,按 q 或 Esc 退出:
python3 /home/ubuntu/Desktop/csi_camera_test.pyCSI 默认使用 1280x720 的传感器采集模式,并将 ROS 话题输出缩放为 640x480:
sensor-id=0
capture: 1280x720
output: 640x480
60 FPS
不要根据设备编号直接猜测 USB 摄像头。/dev/videoN 编号可能因插拔顺序或重启发生变化,绑定前必须先手动列出设备并确认画面来源。
先查看所有视频设备:
ls -l /dev/video*再使用绑定脚本的只读列表功能:
bash /home/ubuntu/ros2_ws/src/Camera_USB_and_CSI/scripts/install_usb_camera_rule.sh --list列表中应选择同时满足以下条件的设备:
BUS是usb。CAPTURE是yes。PRODUCT、SERIAL与准备绑定的 USB 摄像头一致。- 同一个 USB 摄像头有多个
/dev/videoN时,选择实际能输出画面的 capture 接口。
参考识别结果:
/dev/video0 platform CSI IMX219
/dev/video1 usb CAPTURE=yes 应绑定
/dev/video2 usb CAPTURE=no 不应绑定
还应实际打开候选设备确认画面。例如测试 /dev/video1:
gst-launch-1.0 v4l2src device=/dev/video1 \
! videoconvert \
! autovideosink确认画面来自目标 USB 摄像头后按 Ctrl+C 退出。也可以在 /home/ubuntu/Desktop/usb_camera_test.py 中把 cv2.VideoCapture(...) 的编号改成候选设备编号后运行测试。
把下面命令中的 /dev/video1 改成上一步人工确认的实际设备号。先使用 --dry-run 预览规则,此时不会修改系统:
bash /home/ubuntu/ros2_ws/src/Camera_USB_and_CSI/scripts/install_usb_camera_rule.sh \
--device /dev/video1 \
--dry-run如果不传 --device,脚本只会显示设备列表并停止,不会自动选择或安装规则。
再次确认脚本输出的设备、VID、PID、序列号和接口 index 正确,然后使用同一个设备参数执行绑定:
bash /home/ubuntu/ros2_ws/src/Camera_USB_and_CSI/scripts/install_usb_camera_rule.sh \
--device /dev/video1该命令会在写入 /etc/udev/rules.d 时请求一次当前用户的 sudo 密码。
脚本会安装:
/etc/udev/rules.d/99-usb-camera.rules
并生成:
/dev/usb_cam -> /dev/video1
检查结果:
ls -l /dev/usb_cam
udevadm info --query=property --name=/dev/usb_cam如果规则安装后别名没有立即出现,拔插一次 USB 摄像头再检查。规则绑定的是序列号和视频接口,不依赖易变化的 /dev/videoN 编号。
功能包中提供了已验证设备的规则文件:
/home/ubuntu/ros2_ws/src/Camera_USB_and_CSI/udev/99-usb-camera.rules
将整个 Camera_USB_and_CSI 目录复制到目标工作空间的 src 下。例如:
cp -a Camera_USB_and_CSI /home/ubuntu/ros2_ws/src/每台目标主机都应重新运行绑定脚本,让脚本读取 USB 摄像头的 VID、PID、序列号和 V4L2 接口索引,不要直接复用其他设备的静态规则。
cd /home/ubuntu/ros2_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install --packages-select camera_usb_and_csi
source /home/ubuntu/ros2_ws/install/setup.bash确认 ROS 2 已发现包和可执行节点:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 pkg prefix camera_usb_and_csi
ros2 pkg executables camera_usb_and_csisource /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 launch camera_usb_and_csi camera.launch.py camera_type:=CSI常用 CSI 参数:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 launch camera_usb_and_csi camera.launch.py \
camera_type:=CSI \
csi_sensor_id:=0 \
csi_capture_width:=1280 \
csi_capture_height:=720 \
csi_output_width:=640 \
csi_output_height:=480 \
csi_framerate:=60 \
csi_flip_method:=0 \
image_topic:=/image_rawcsi_flip_method 可取 0 到 7,用于旋转或翻转画面。
推荐使用固定别名:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 launch camera_usb_and_csi camera.launch.py \
camera_type:=USB \
usb_device:=/dev/usb_camUSB 默认参数为 640x480 @ 30 FPS、MJPEG,适合在 rqt 中实时查看。需要更高分辨率时可通过下面的参数修改。
修改 USB 端口、分辨率和格式:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 launch camera_usb_and_csi camera.launch.py \
camera_type:=USB \
usb_device:=/dev/video1 \
usb_width:=640 \
usb_height:=480 \
usb_framerate:=30 \
usb_pixel_format:=MJPEG \
image_topic:=/image_raw对于同时支持 MJPEG 和 YUY2 的 USB 摄像头,推荐使用 MJPEG,其 USB 带宽占用更低。
启动任一相机节点后,在新终端执行:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 topic info /image_raw --verbose
ros2 topic hz /image_raw消息类型应为:
sensor_msgs/msg/Image
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 run rqt_image_view rqt_image_view在左上角话题下拉框中选择:
/image_raw
发布端使用传感器数据 QoS(Best Effort),适合实时图像,掉帧时不会积压旧画面。
CSI:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 run camera_usb_and_csi csi_camera_node --ros-args \
-p sensor_id:=0 \
-p image_topic:=/image_rawUSB:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 run camera_usb_and_csi usb_camera_node --ros-args \
-p device:=/dev/usb_cam \
-p image_topic:=/image_rawcollect_picture 和本相机包都默认使用 /image_raw,无需额外指定环境变量。先启动 CSI 或 USB 相机:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 launch camera_usb_and_csi camera.launch.py camera_type:=CSI然后在另一个终端启动采集软件:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
/home/ubuntu/Software/collect_picture/run_collect_picture.sh软件会直接订阅 /image_raw。只启动一个相机发布节点,避免 CSI 和 USB 同时向该话题发布图像。
检查 OpenCV:
python3 -c 'import cv2; print(cv2.__version__, cv2.__file__)'用户目录的 OpenCV 4.11 没有 GStreamer 支持。本包会主动移除用户 site-packages,使用 /usr/lib/python3/dist-packages 中的系统 OpenCV。
如果出现 cannot allocate memory in static TLS block,可临时执行:
export LD_PRELOAD=/lib/aarch64-linux-gnu/libGLdispatch.so.0重新运行绑定脚本,或拔插 USB 摄像头:
bash /home/ubuntu/ros2_ws/src/Camera_USB_and_CSI/scripts/install_usb_camera_rule.sh \
--device /dev/video1确认没有其他程序占用摄像头:
fuser /dev/usb_cam也可以绕过别名测试原始端口:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 launch camera_usb_and_csi camera.launch.py \
camera_type:=USB usb_device:=/dev/video1确认相机节点终端没有报错,然后检查:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 node list
ros2 topic list
ros2 topic info /image_raw --verbose确保启动节点和 rqt 的终端都加载了同一个 ROS 2 环境,并且 ROS_DOMAIN_ID 一致。
如果节点正在运行,但普通 ros2 topic list 显示缓存结果,重启 ROS 2 CLI daemon,或使用不经过 daemon 的查询:
source /opt/ros/humble/setup.bash
source /home/ubuntu/ros2_ws/install/setup.bash
ros2 daemon stop
ros2 daemon start
ros2 topic list --no-daemon
ros2 topic info /image_raw --verbose --no-daemon