【ROS2学习笔记】分布式通信
前言
本系列博文是本人的学习笔记,自用为主,不是教程,学习请移步其他大佬的相关教程。前几篇学习资源来自鱼香ROS大佬的详细教程,适合深入学习,但对本人这样的初学者不算友好,后续笔记将以@古月居的ROS2入门21讲为主,侵权即删。
一、学习目标
- 搞懂 “分布式系统” 的核心意义 —— 为什么机器人需要多台电脑分工干活
- 掌握 ROS 分布式的核心逻辑:不用改代码,多台电脑就能互通
- 学会树莓派的关键配置(装系统、ROS2、远程桌面),模拟机器人端计算平台
- 能独立完成 4 个分布式案例(话题、服务、小海龟、视觉),验证跨机通信
- 记住分布式通信的 “坑点”(网络、分组),避免调试时踩雷
二、为什么需要 ROS 分布式?
2.1 机器人的 “算力烦恼”(问题所在)
如果把机器人的所有功能(传感器驱动、电机控制、视觉识别、导航)都放在一台电脑上,会遇到两个大问题:
- 算力不够:视觉识别、导航规划这些功能很耗 CPU/GPU,比如树莓派(小体积、低功耗)跑不动复杂视觉算法;
- 卡顿延迟:一个电脑同时处理太多任务,会导致传感器数据延迟,甚至电机控制不及时,机器人 “反应变慢”。
2.2 分布式的解决方案:“分工合作”
分布式系统就是把机器人的任务拆给多台电脑,每台电脑负责一部分,像 “流水线” 一样配合:
-
例:机器人常用的 “两机分工”
电脑类型 放置位置 负责任务(轻量 / 底层) 优点 树莓派 / 嵌入式 机器人本体上 传感器驱动(相机、激光)、电机控制 体积小、功耗低,适合装在机器人上 笔记本 / 台式机 远程(比如桌面) 视觉识别、导航规划、人机交互(监控) 算力强,能跑复杂算法 -
关键优势:不用改代码!ROS 已经做好了跨机通信的底层,只要配置好环境,多台电脑就像 “一台电脑” 一样通信。
三、什么是 ROS 分布式?(核心概念)
3.1 一句话说清:多台电脑的 “ROS 局域网”
ROS 分布式是指:多台安装了 ROS 的电脑,在同一个局域网内,能互相发现对方的节点、话题、服务、动作,实现数据传输。比如:树莓派(机器人端)发布相机图像话题,笔记本(远程端)订阅这个话题做视觉识别 —— 就像两个节点在同一台电脑上一样。
3.2 机器人分布式的典型场景(有画面感)
用 “树莓派 + 笔记本” 模拟真实机器人系统:
- 树莓派(机器人上):接相机、电机,负责 “底层干活”—— 发布相机图像(
image_raw
话题)、接收速度指令(cmd_vel
话题)控制电机; - 笔记本(远程):负责 “上层思考”—— 订阅图像做红色目标识别、发布速度指令控制机器人运动;
- 通信效果:树莓派的图像能实时传到笔记本,笔记本的指令能实时发给树莓派,中间不用写任何 “跨机通信代码”。
四、实操 1:树莓派配置(机器人端计算平台)
树莓派是机器人分布式的 “常客”(小、轻、便宜),我们需要把它配置成 “机器人端的 ROS 节点”,步骤分 4 步:
4.1 第一步:给树莓派装系统(Ubuntu Mate)
树莓派不能直接装普通 Ubuntu,需要用 “适配 ARM 架构” 的系统,推荐Ubuntu Mate(对 ROS 支持好,操作简单)。
具体步骤(小白友好):
- 下载镜像:官网链接:https://ubuntu-mate.org/download/选择 “Raspberry Pi” 版本(比如 Ubuntu Mate 22.04,对应 ROS2 Humble)。
- 烧录镜像到 SD 卡:
- 工具:用
Raspberry Pi Imager
(官网下载:https://www.raspberrypi.com/software/ ),支持 Windows/Mac/Linux; - 操作:打开工具→选择 “自定义镜像”(刚才下载的 Ubuntu Mate)→选择 SD 卡→点击 “烧录”(等待 5-10 分钟)。
- 工具:用
- 启动树莓派:
- 把 SD 卡插入树莓派,接电源、显示器、键盘鼠标;
- 第一次启动会提示设置语言、用户名、密码(记好,后续远程要用)。
4.2 第二步:给树莓派装 ROS2(和 PC 端一样)
树莓派的 ROS2 安装流程和笔记本完全一致,以ROS2 Humble为例(对应 Ubuntu 22.04):
核心步骤(详细命令):
-
设置软件源(允许从国外源下载 ROS2):
# 设置编码 sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8# 添加ROS2软件源 sudo apt update && sudo apt install -y curl gnupg lsb-release sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
-
安装 ROS2 基础包:
sudo apt update && sudo apt upgrade -y # 安装基础版(足够做分布式测试) sudo apt install -y ros-humble-ros-base # 安装常用工具(话题查看、节点管理) sudo apt install -y ros-humble-rqt ros-humble-rqt-tf-tree
-
设置环境变量(每次启动终端自动加载 ROS2):
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc # 立即生效
-
验证安装:运行
ros2 --version
,如果输出 “ros2 humble”,说明安装成功。
4.3 第三步:树莓派编译 ROS 代码(和 PC 端同步)
为了测试分布式,需要把之前写的代码(比如learning_topic
、learning_service
)传到树莓派:
方法 1:用 U 盘拷贝
- 笔记本上把
dev_ws/src
(ROS 工作空间的源码目录)拷贝到 U 盘; - 树莓派插上 U 盘,把
src
目录复制到树莓派的dev_ws/src
(没有就新建:mkdir -p ~/dev_ws/src
)。
方法 2:用 Git(推荐,方便更新)
- 笔记本上把代码上传到 GitHub/GitLab;
- 树莓派上克隆代码:
mkdir -p ~/dev_ws/src cd ~/dev_ws/src git clone 你的代码仓库地址 # 比如 git clone https://github.com/xxx/ros2_code.git
编译代码:
cd ~/dev_ws # 进入工作空间
colcon build --symlink-install # 编译(symlink-install方便修改代码后不用重新编译)
source install/setup.bash # 加载环境变量
4.4 第四步:配置树莓派远程桌面(不用插显示器)
如果没有多余的显示器 / 键盘,远程桌面能让笔记本 “控制” 树莓派的桌面,方便操作:
步骤(以 VNC 为例):
- 树莓派端安装 VNC 服务:
sudo apt update && sudo apt install -y tightvncserver vncserver # 第一次运行会提示设置密码(记好,远程连接要用)
- 笔记本端安装 VNC 客户端:
- 工具:
RealVNC Viewer
(官网下载:https://www.realvnc.com/en/connect/download/viewer/ );
- 工具:
- 获取树莓派 IP 地址(树莓派终端执行):
ifconfig # 找“wlan0”下的“inet”,比如 192.168.1.105
- 远程连接:
- 打开 VNC Viewer→输入树莓派 IP(比如
192.168.1.105:1
,:1
是 VNC 端口)→输入密码→连接成功,就能看到树莓派桌面了。
- 打开 VNC Viewer→输入树莓派 IP(比如
4.5 参考链接(小白避坑)
如果步骤中遇到问题,可参考详细教程:https://blog.csdn.net/qq_52785580/article/details/122599728 (树莓派 Ubuntu Mate+ROS2 完整配置)
五、实操 2:ROS 分布式通信搭建(核心配置)
5.1 前提条件(必须满足,否则通信失败)
- 同一局域网:树莓派和笔记本必须连同一个 WiFi / 网线(比如家里的 WiFi,或笔记本开热点给树莓派);
- 关闭防火墙:两边都要关,避免防火墙挡住 ROS 数据(命令):
sudo ufw disable # 关闭Ubuntu防火墙(树莓派和笔记本都要执行)
- 虚拟机注意:如果笔记本用虚拟机装 Ubuntu,必须把虚拟机网络设为桥接模式(否则虚拟机和树莓派不在同一局域网)—— 虚拟机设置→网络适配器→桥接模式。
5.2 测试 1:自带节点跨机通信(talker/listener)
先用水印的demo_nodes
测试,验证最基础的话题通信:
步骤:
-
树莓派端(发布者):运行
talker
节点,发布chatter
话题(内容 “Hello World”):source /opt/ros/humble/setup.bash # 加载ROS2环境 ros2 run demo_nodes_cpp talker # 启动C++版本的发布者 # 预期输出:[INFO] [talker]:Publishing: 'Hello World: 1' 'Hello World: 2'...
-
笔记本端(订阅者):运行
listener
节点,订阅chatter
话题:source /opt/ros/humble/setup.bash # 加载ROS2环境 ros2 run demo_nodes_py listener # 启动Python版本的订阅者 # 预期输出:[INFO] [listener]:I heard: [Hello World: 1] [Hello World: 2]...
关键结论:不用改任何代码,树莓派的话题能被笔记本收到!
5.3 分布式分组:ROS_DOMAIN_ID(避免干扰)
如果同一局域网有很多 ROS 设备(比如多个机器人),会出现 “互相干扰”(比如 A 机器人的节点被 B 机器人的节点误连)。ROS2 用DOMAIN_ID(小组编号)解决:只有同一 DOMAIN_ID的设备才能通信。
配置方法(树莓派和笔记本都要设置):
- 打开终端,编辑
~/.bashrc
文件(每次启动终端自动加载):nano ~/.bashrc # 用nano编辑器打开
- 在文件末尾添加一行(比如设为
10
,可自定义 0-232 之间的数字):export ROS_DOMAIN_ID=10 # 同一小组的设备必须用相同的ID
- 保存并生效:
Ctrl+O # 保存 Ctrl+X # 退出nano source ~/.bashrc # 立即生效
验证分组:
- 把树莓派的 DOMAIN_ID 改成
11
,笔记本保持10
; - 再运行 talker/listener,会发现笔记本收不到树莓派的话题 —— 证明分组生效。
六、实操 3:4 个分布式案例测试(从简单到复杂)
案例 1:小海龟分布式控制(经典验证)
目标:笔记本启动小海龟仿真器,树莓派启动键盘控制,实现跨机控制。
步骤:
- 笔记本端(仿真器):启动小海龟窗口:
source /opt/ros/humble/setup.bash ros2 run turtlesim turtlesim_node # 小海龟仿真器
- 树莓派端(键盘控制):启动键盘控制节点:
source /opt/ros/humble/setup.bash ros2 run turtlesim turtle_teleop_key # 键盘控制
- 操作:在树莓派的终端按方向键,笔记本的小海龟会跟着动 —— 跨机控制成功!
案例 2:自定义话题分布式通信(Hello World)
目标:树莓派发布自定义/topic_helloworld
话题,笔记本订阅。
步骤:
- 树莓派端(发布者):运行之前写的
topic_helloworld_pub
节点:cd ~/dev_ws # 进入工作空间 source install/setup.bash # 加载自定义包环境 ros2 run learning_topic topic_helloworld_pub # 启动发布者 # 预期输出:[INFO] [topic_helloworld_pub]:Publishing: Hello World 1...
- 笔记本端(订阅者):运行
topic_helloworld_sub
节点:cd ~/dev_ws source install/setup.bash ros2 run learning_topic topic_helloworld_sub # 启动订阅者 # 预期输出:[INFO] [topic_helloworld_sub]:I heard: Hello World 1...
案例 3:自定义服务分布式通信(加法求和)
目标:笔记本启动加法服务端,树莓派启动客户端,跨机调用服务。
步骤:
- 笔记本端(服务端):运行
service_adder_server
:cd ~/dev_ws source install/setup.bash ros2 run learning_service service_adder_server # 启动服务端 # 预期输出:[INFO] [service_adder_server]:Waiting for request...
- 树莓派端(客户端):运行
service_adder_client
,传入参数2
和3
:cd ~/dev_ws source install/setup.bash ros2 run learning_service service_adder_client 2 3 # 启动客户端,求2+3 # 预期输出:[INFO] [service_adder_client]:Result of add: 5 # 笔记本端同步输出:[INFO] [service_adder_server]:Incoming request: a=2, b=3, sum=5
案例 4:机器视觉分布式通信(相机图像)
目标:树莓派接 USB 相机发布/image_raw
话题,笔记本订阅并显示图像。
步骤:
- 树莓派端(相机发布者):启动
usb_cam
节点(接好 USB 相机):source /opt/ros/humble/setup.bash ros2 run usb_cam usb_cam_node_exe # 启动相机驱动,发布/image_raw话题 # 预期输出:显示相机参数(分辨率、帧率),证明相机启动成功
- 笔记本端(图像订阅者):运行
topic_webcam_sub
节点,显示图像:cd ~/dev_ws source install/setup.bash ros2 run learning_topic topic_webcam_sub # 启动图像订阅者 # 预期输出:弹出OpenCV窗口,显示树莓派相机拍摄的实时图像
七、分布式通信注意事项(小白避坑指南)
- 环境变量必须加载:每次启动新终端,都要先
source /opt/ros/humble/setup.bash
(ROS2 基础环境)和source ~/dev_ws/install/setup.bash
(自定义包环境),否则找不到节点; - DOMAIN_ID 必须一致:跨机通信的设备,
ROS_DOMAIN_ID
必须相同,否则收不到数据; - 网络问题排查:如果通信失败,先执行
ping 树莓派IP
(笔记本端)或ping 笔记本IP
(树莓派端),能 ping 通说明网络没问题,ping 不通检查 WiFi / 网线; - 节点名 / 话题名一致:自定义节点的名称、话题名、服务名必须和 PC 端完全一致(比如树莓派发布
/image_raw
,笔记本必须订阅/image_raw
); - 树莓派性能有限:树莓派跑相机驱动没问题,但不要让它跑视觉识别(会卡顿),视觉任务交给笔记本。
八、复习要点总结(小白必背)
- 分布式核心:多台电脑分工,不用改代码,ROS 自动跨机通信;
- 树莓派配置四步走:装 Ubuntu Mate→装 ROS2→编译代码→远程桌面;
- 通信前提三要素:同一局域网、关闭防火墙、DOMAIN_ID 一致;
- 案例验证逻辑:从简单(talker/listener)到复杂(视觉),逐步验证;
- 避坑关键:环境变量要 source、网络要 ping 通、分组 ID 要相同。
ROS 分布式是机器人开发的 “必备技能”,掌握后就能灵活搭配不同算力的设备,让机器人跑得更流畅