【ROS2学习笔记】分布式通信

前言

本系列博文是本人的学习笔记,自用为主,不是教程,学习请移步其他大佬的相关教程。前几篇学习资源来自鱼香ROS大佬的详细教程,适合深入学习,但对本人这样的初学者不算友好,后续笔记将以@古月居的ROS2入门21讲为主,侵权即删。

一、学习目标

  1. 搞懂 "分布式系统" 的核心意义 ------ 为什么机器人需要多台电脑分工干活
  2. 掌握 ROS 分布式的核心逻辑:不用改代码,多台电脑就能互通
  3. 学会树莓派的关键配置(装系统、ROS2、远程桌面),模拟机器人端计算平台
  4. 能独立完成 4 个分布式案例(话题、服务、小海龟、视觉),验证跨机通信
  5. 记住分布式通信的 "坑点"(网络、分组),避免调试时踩雷

二、为什么需要 ROS 分布式?

2.1 机器人的 "算力烦恼"(问题所在)

如果把机器人的所有功能(传感器驱动、电机控制、视觉识别、导航)都放在一台电脑上,会遇到两个大问题:

  • 算力不够:视觉识别、导航规划这些功能很耗 CPU/GPU,比如树莓派(小体积、低功耗)跑不动复杂视觉算法;
  • 卡顿延迟:一个电脑同时处理太多任务,会导致传感器数据延迟,甚至电机控制不及时,机器人 "反应变慢"。

2.2 分布式的解决方案:"分工合作"

分布式系统就是把机器人的任务拆给多台电脑,每台电脑负责一部分,像 "流水线" 一样配合:

  • 例:机器人常用的 "两机分工"

    电脑类型 放置位置 负责任务(轻量 / 底层) 优点
    树莓派 / 嵌入式 机器人本体上 传感器驱动(相机、激光)、电机控制 体积小、功耗低,适合装在机器人上
    笔记本 / 台式机 远程(比如桌面) 视觉识别、导航规划、人机交互(监控) 算力强,能跑复杂算法
  • 关键优势:不用改代码!ROS 已经做好了跨机通信的底层,只要配置好环境,多台电脑就像 "一台电脑" 一样通信。

三、什么是 ROS 分布式?(核心概念)

3.1 一句话说清:多台电脑的 "ROS 局域网"

ROS 分布式是指:多台安装了 ROS 的电脑,在同一个局域网内,能互相发现对方的节点、话题、服务、动作,实现数据传输。比如:树莓派(机器人端)发布相机图像话题,笔记本(远程端)订阅这个话题做视觉识别 ------ 就像两个节点在同一台电脑上一样。

3.2 机器人分布式的典型场景(有画面感)

用 "树莓派 + 笔记本" 模拟真实机器人系统:

  1. 树莓派(机器人上):接相机、电机,负责 "底层干活"------ 发布相机图像(image_raw话题)、接收速度指令(cmd_vel话题)控制电机;
  2. 笔记本(远程):负责 "上层思考"------ 订阅图像做红色目标识别、发布速度指令控制机器人运动;
  3. 通信效果:树莓派的图像能实时传到笔记本,笔记本的指令能实时发给树莓派,中间不用写任何 "跨机通信代码"。

四、实操 1:树莓派配置(机器人端计算平台)

树莓派是机器人分布式的 "常客"(小、轻、便宜),我们需要把它配置成 "机器人端的 ROS 节点",步骤分 4 步:

4.1 第一步:给树莓派装系统(Ubuntu Mate)

树莓派不能直接装普通 Ubuntu,需要用 "适配 ARM 架构" 的系统,推荐Ubuntu Mate(对 ROS 支持好,操作简单)。

具体步骤(小白友好):
  1. 下载镜像 :官网链接:https://ubuntu-mate.org/download/选择 "Raspberry Pi" 版本(比如 Ubuntu Mate 22.04,对应 ROS2 Humble)。
  2. 烧录镜像到 SD 卡
    • 工具:用Raspberry Pi Imager(官网下载:https://www.raspberrypi.com/software/ ),支持 Windows/Mac/Linux;
    • 操作:打开工具→选择 "自定义镜像"(刚才下载的 Ubuntu Mate)→选择 SD 卡→点击 "烧录"(等待 5-10 分钟)。
  3. 启动树莓派
    • 把 SD 卡插入树莓派,接电源、显示器、键盘鼠标;
    • 第一次启动会提示设置语言、用户名、密码(记好,后续远程要用)。

4.2 第二步:给树莓派装 ROS2(和 PC 端一样)

树莓派的 ROS2 安装流程和笔记本完全一致,以ROS2 Humble为例(对应 Ubuntu 22.04):

核心步骤(详细命令):
  1. 设置软件源(允许从国外源下载 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
  2. 安装 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
  3. 设置环境变量(每次启动终端自动加载 ROS2):

    复制代码
    echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
    source ~/.bashrc  # 立即生效
  4. 验证安装 :运行ros2 --version,如果输出 "ros2 humble",说明安装成功。

4.3 第三步:树莓派编译 ROS 代码(和 PC 端同步)

为了测试分布式,需要把之前写的代码(比如learning_topiclearning_service)传到树莓派:

方法 1:用 U 盘拷贝
  1. 笔记本上把dev_ws/src(ROS 工作空间的源码目录)拷贝到 U 盘;
  2. 树莓派插上 U 盘,把src目录复制到树莓派的dev_ws/src(没有就新建:mkdir -p ~/dev_ws/src)。
方法 2:用 Git(推荐,方便更新)
  1. 笔记本上把代码上传到 GitHub/GitLab;

  2. 树莓派上克隆代码:

    复制代码
    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 为例):
  1. 树莓派端安装 VNC 服务

    复制代码
    sudo apt update && sudo apt install -y tightvncserver
    vncserver  # 第一次运行会提示设置密码(记好,远程连接要用)
  2. 笔记本端安装 VNC 客户端

  3. 获取树莓派 IP 地址 (树莓派终端执行):

    复制代码
    ifconfig  # 找"wlan0"下的"inet",比如 192.168.1.105
  4. 远程连接

    • 打开 VNC Viewer→输入树莓派 IP(比如192.168.1.105:1:1是 VNC 端口)→输入密码→连接成功,就能看到树莓派桌面了。

4.5 参考链接(小白避坑)

如果步骤中遇到问题,可参考详细教程:https://blog.csdn.net/qq_52785580/article/details/122599728 (树莓派 Ubuntu Mate+ROS2 完整配置)

五、实操 2:ROS 分布式通信搭建(核心配置)

5.1 前提条件(必须满足,否则通信失败)

  1. 同一局域网:树莓派和笔记本必须连同一个 WiFi / 网线(比如家里的 WiFi,或笔记本开热点给树莓派);

  2. 关闭防火墙 :两边都要关,避免防火墙挡住 ROS 数据(命令):

    复制代码
    sudo ufw disable  # 关闭Ubuntu防火墙(树莓派和笔记本都要执行)
  3. 虚拟机注意 :如果笔记本用虚拟机装 Ubuntu,必须把虚拟机网络设为桥接模式(否则虚拟机和树莓派不在同一局域网)------ 虚拟机设置→网络适配器→桥接模式。

5.2 测试 1:自带节点跨机通信(talker/listener)

先用水印的demo_nodes测试,验证最基础的话题通信:

步骤:
  1. 树莓派端(发布者) :运行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'...
  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的设备才能通信。

配置方法(树莓派和笔记本都要设置):
  1. 打开终端,编辑~/.bashrc文件(每次启动终端自动加载):

    复制代码
    nano ~/.bashrc  # 用nano编辑器打开
  2. 在文件末尾添加一行(比如设为10,可自定义 0-232 之间的数字):

    复制代码
    export ROS_DOMAIN_ID=10  # 同一小组的设备必须用相同的ID
  3. 保存并生效:

    复制代码
    Ctrl+O  # 保存
    Ctrl+X  # 退出nano
    source ~/.bashrc  # 立即生效
验证分组:
  • 把树莓派的 DOMAIN_ID 改成11,笔记本保持10
  • 再运行 talker/listener,会发现笔记本收不到树莓派的话题 ------ 证明分组生效。

六、实操 3:4 个分布式案例测试(从简单到复杂)

案例 1:小海龟分布式控制(经典验证)

目标:笔记本启动小海龟仿真器,树莓派启动键盘控制,实现跨机控制。

步骤:
  1. 笔记本端(仿真器) :启动小海龟窗口:

    复制代码
    source /opt/ros/humble/setup.bash
    ros2 run turtlesim turtlesim_node  # 小海龟仿真器
  2. 树莓派端(键盘控制) :启动键盘控制节点:

    复制代码
    source /opt/ros/humble/setup.bash
    ros2 run turtlesim turtle_teleop_key  # 键盘控制
  3. 操作:在树莓派的终端按方向键,笔记本的小海龟会跟着动 ------ 跨机控制成功!

案例 2:自定义话题分布式通信(Hello World)

目标:树莓派发布自定义/topic_helloworld话题,笔记本订阅。

步骤:
  1. 树莓派端(发布者) :运行之前写的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...
  2. 笔记本端(订阅者) :运行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:自定义服务分布式通信(加法求和)

目标:笔记本启动加法服务端,树莓派启动客户端,跨机调用服务。

步骤:
  1. 笔记本端(服务端) :运行service_adder_server

    复制代码
    cd ~/dev_ws
    source install/setup.bash
    ros2 run learning_service service_adder_server  # 启动服务端
    # 预期输出:[INFO] [service_adder_server]:Waiting for request...
  2. 树莓派端(客户端) :运行service_adder_client,传入参数23

    复制代码
    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话题,笔记本订阅并显示图像。

步骤:
  1. 树莓派端(相机发布者) :启动usb_cam节点(接好 USB 相机):

    复制代码
    source /opt/ros/humble/setup.bash
    ros2 run usb_cam usb_cam_node_exe  # 启动相机驱动,发布/image_raw话题
    # 预期输出:显示相机参数(分辨率、帧率),证明相机启动成功
  2. 笔记本端(图像订阅者) :运行topic_webcam_sub节点,显示图像:

    复制代码
    cd ~/dev_ws
    source install/setup.bash
    ros2 run learning_topic topic_webcam_sub  # 启动图像订阅者
    # 预期输出:弹出OpenCV窗口,显示树莓派相机拍摄的实时图像

七、分布式通信注意事项(小白避坑指南)

  1. 环境变量必须加载 :每次启动新终端,都要先source /opt/ros/humble/setup.bash(ROS2 基础环境)和source ~/dev_ws/install/setup.bash(自定义包环境),否则找不到节点;
  2. DOMAIN_ID 必须一致 :跨机通信的设备,ROS_DOMAIN_ID必须相同,否则收不到数据;
  3. 网络问题排查 :如果通信失败,先执行ping 树莓派IP(笔记本端)或ping 笔记本IP(树莓派端),能 ping 通说明网络没问题,ping 不通检查 WiFi / 网线;
  4. 节点名 / 话题名一致 :自定义节点的名称、话题名、服务名必须和 PC 端完全一致(比如树莓派发布/image_raw,笔记本必须订阅/image_raw);
  5. 树莓派性能有限:树莓派跑相机驱动没问题,但不要让它跑视觉识别(会卡顿),视觉任务交给笔记本。

八、复习要点总结(小白必背)

  1. 分布式核心:多台电脑分工,不用改代码,ROS 自动跨机通信;
  2. 树莓派配置四步走:装 Ubuntu Mate→装 ROS2→编译代码→远程桌面;
  3. 通信前提三要素:同一局域网、关闭防火墙、DOMAIN_ID 一致;
  4. 案例验证逻辑:从简单(talker/listener)到复杂(视觉),逐步验证;
  5. 避坑关键:环境变量要 source、网络要 ping 通、分组 ID 要相同。

ROS 分布式是机器人开发的 "必备技能",掌握后就能灵活搭配不同算力的设备,让机器人跑得更流畅

相关推荐
CosimaLi5 分钟前
CMake学习笔记
笔记·学习
正经教主31 分钟前
【Trae+AI】和Trae学习搭建App_02:后端API开发
学习·app·1024程序员节
岑梓铭38 分钟前
《考研408数据结构》第六章(5.1+5.2+5.3树、二叉树、线索二叉树)复习笔记
数据结构·笔记·考研·408·1024程序员节
源代码•宸39 分钟前
Qt6 学习——一个Qt桌面应用程序
开发语言·c++·经验分享·qt·学习·软件构建·windeployqt
摇滚侠1 小时前
全面掌握 PostgreSQL 关系型数据库,PostgreSQL 介绍,笔记02
数据库·笔记·postgresql
摇滚侠1 小时前
Spring Boot3零基础教程,生命周期监听,自定义监听器,笔记59
java·开发语言·spring boot·笔记
讽刺人生Yan2 小时前
RFSOC学习记录(一)RF data converter总览
学习·fpga开发·rfsoc
张人玉2 小时前
WPF 控件速查 PDF 笔记(可直接落地版)
笔记·microsoft·wpf
Pluchon2 小时前
硅基计划2.0 学习总结 玖 图书管理系统 2.0复盘版(文字末尾源码可复制)
java·学习·项目·源码可复制
摇滚侠2 小时前
Spring Boot3零基础教程,事件驱动开发,设计登录成功后增加积分记录信息功能,笔记61
java·spring boot·笔记·后端