EP_ROS框架---相机视频流交互二

EP:Engineer and Program

ROS2 跨 IP 传输相机图像核心结论

ROS2 图像优先用 Topic(发布订阅)。

Topic:持续流式推送图像(相机这种连续数据流,标准方案)

Service:一问一答,适合单次请求抓一张图片,不适合实时视频流

ROS2 底层是 DDS 中间件(FastDDS/CycloneDDS) ,DDS 自动完成跨 IP 网络发现、UDP 组播 / 单播传输,不需要你手动写 IP 套接字;只要两台机器网络互通、配置一致,发布节点推图像,任意 IP 上的订阅节点就能收到图像 topic。

一、ROS2 图像消息类型 & image_transport(图片传输协议层)

1)原生消息

  1. sensor_msgs/msg/Image:raw 原始图,BGR8/RGB8,不带压缩,体积巨大(1080p 一帧几 MB),局域网短距离可用,WiFi 跨 IP 很容易带宽爆满。
  2. sensor_msgs/msg/CompressedImage:JPEG/PNG 压缩图像,image_transport插件自动生成,推荐跨网络使用。

2)image_transport 插件系统

image_transport 是 ROS2 图像传输抽象层,插件化切换传输编码协议,不用改业务节点代码ROS

  • raw:默认,原始Image消息
  • compressed:JPEG/PNG(最常用,开箱即用)
  • ffmpeg_image_transport:H.264/H.265 硬件编码(NVIDIA GPU 硬编,高分辨率、高帧率首选)

原理:相机驱动发布基础 topic /camera/image;image_transport 自动派生:

/camera/image/compressed(jpeg)、/camera/image/ffmpeg(h264)

订阅端选择对应的 transport,自动解码。

安装:

复制代码
# 基础压缩插件
sudo apt install ros-humble-image-transport ros-humble-image-transport-plugins
# ffmpeg硬件编码插件(NVIDIA)
sudo apt install ros-humble-ffmpeg-image-transport

查看本机支持哪些图像传输协议:

复制代码
ros2 run image_transport list_transports

二、跨 IP 多机通信配置(场景:相机端 IP A,接收端 IP B)

前提:两边机器可以互相 ping 通

  1. 关闭本地回环限制(两边机器都执行)

    unset ROS_LOCALHOST_ONLY

  2. 统一 ROS_DOMAIN_ID(两边必须相同,0~101,推荐 42)

    export ROS_DOMAIN_ID=42

  3. RMW 中间件保持一致,默认 FastDDS

    export RMW_IMPLEMENTATION=rmw_fastrtps_cpp

  4. 复杂多网卡必配,指定 DDS 绑定网卡
    FastDDS 可以配置 xml,强制 DDS 使用enP1p1s0网卡,防止 DDS 在多个网卡之间乱发现,找不到远端 IP。

写到 ~/.bashrc 永久生效,source 后生效。

两边配置好后,重启 ros2 daemon:

复制代码
ros2 daemon stop && ros2 daemon start

测试连通性

  • 相机端(发布端):启动 usb_cam /realsense 等相机驱动,发布 /camera/image

  • 远端接收机:

    查看能否发现topic

    ros2 topic list

    订阅图像

    ros2 run rqt_image_view rqt_image_view

三、两种通信选型:Topic(推荐) vs Service(仅快照)

Topic 流式视频(正常摄像头实时传输)

相机节点持续 publish 图像消息到 topic;远端任意 IP 的节点订阅。

支持多接收端:1 个相机发布,多台 IP 机器同时订阅。

QoS 配置非常关键:图像大数据一般用 SENSOR_DATA QoS(best effort,丢帧优先保实时),不要用 RELIABLE,否则网络抖动直接卡顿、堆积。

Service:按需单次抓图(不做实时流)

定义服务,client(远端 IP)发一次请求,server(相机端)捕获一张图返回。适合 "远程点一下,拍一张照片",不适合连续视频 。

自定义 srv 消息,把CompressedImage作为返回字段。

四、如何自定义 / 修改图片传输协议(image_transport 插件开发)

如果自己定义图像编码协议 (自定义压缩 / 自定义二进制打包),需要开发image_transport插件:

  1. 新建 ROS2 功能包,继承 image_transport::PublisherPlugin / SubscriberPlugin
  2. 实现:编码函数(cv::Mat → 自定义二进制包)、解码函数(自定义包 → cv::Mat)
  3. 注册插件,编译,两边机器安装插件
  4. 启动节点时,指定 image_transport:=你的插件名

绝大多数工程不需要从零开发协议 ,直接用 compressed(jpeg) 或者 ffmpeg(h264/h265) 足够;ffmpeg 插件支持 NVIDIA 硬件编解码,大幅降低 CPU 负载。

五、关键踩坑(适配你当前 NVIDIA 机器 + 双网卡环境)

  1. 双网卡 DDS 发现混乱 :FastDDS 默认会在所有网卡广播,多网卡环境容易发现失败,必须用 FastDDS XML 配置锁定网卡enP1p1s0。

  2. 原始图像太大:720p/1080p 不要直接 raw 跨 IP,带宽爆炸,一定要开 compressed 或者 h264。

  3. QoS 不匹配 :发布 / 订阅 QoS 不一致,topic 看得见但收不到图像,图像传输推荐 QoS SENSOR_DATA。

  4. 防火墙:两台 ubuntu 关闭 ufw,或者放行 UDP 端口(DDS 使用 UDP)

    sudo ufw disable

  5. 可以把相机发布节点封装成 systemctl service,上电自动启动摄像头 topic 发布。

六、最小示例:USB 相机发布压缩图像

复制代码
# 安装usb_cam
sudo apt install ros-humble-usb-cam
# 启动相机,自动发布 /camera/image 和 /camera/image/compressed
ros2 run usb_cam usb_cam_node_exe

远端机器查看压缩流:

复制代码
ros2 topic echo /camera/image/compressed

七、补充:如果需要公网跨 IP(不在同一个局域网)

DDS 默认组播无法跨公网,两种方案:

  1. 部署 DDS Router,转发 DDS 流量;
  2. 写 bridge 节点:本机订阅 ROS2 图像 topic,转成 RTSP/WebSocket,远端拉流(脱离原生 DDS)。
相关推荐
Dfreedom.1 小时前
光谱定性分析中PCA、SVM与LDA方法的对比研究
机器学习·支持向量机·lda·pca·svm·化学计量学·光谱数据处理
AI行业应用研究1 小时前
会务信息载体的演进:纸质、PDF 与结构化数据源的分发成本与版本一致性
大数据·人工智能·安全·小程序·架构·pdf
罗西的思考1 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 — (6)— 奖励机制
人工智能·笔记·学习
Ai小禾2 小时前
【Obsidian对话数据怎么导入到另外一个Obsidian账号里去? 】用“AI导出鸭”把AI对话变成可迁移的知识资产
人工智能
4SAPI2 小时前
AI API Gateway平台哪个好?从架构视角看企业多模型网关选型与实践
java·大数据·人工智能·gateway·php
EatFan2 小时前
2026 后端 AI 工程化:Spring AI 2.0、MCP 协议与 Agent 内嵌如何收进 Java 生产系统
java·人工智能·spring·agent·spring ai·spring boot 3·mcp
会议咨询2 小时前
2026年交互设计、计算机视觉与数字化技术国际会议(ICDT 2026)
人工智能·计算机视觉·交互
JPower_mr.g2 小时前
SmartCall 音色管理技术解析:基于 SPI 的可扩展音色注册架构
java·开发语言·人工智能·ai·架构·开源
高洁012 小时前
智能博弈背景下中国AI国防建设的战略价值
人工智能·python·深度学习·django·tornado