ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

树莓派4B跑ROS2 Humble全指南:从系统选型到DDS切换避坑

树莓派4B跑ROS2 Humble全指南:从系统选型到DDS切换避坑 我一直觉得树莓派4B跑ROS2这件事被不少人高估了难度也被不少人低估了细节。说难度不高是因为ROS2 Humble在Ubuntu软件源里已经有现成编译好的二进制包不用像ROS1时代那样从源码折腾几个小时说细节多是因为从选Ubuntu版本、烧录镜像、扩充Swap到DDS中间件的选型每一步都有几个隐藏的坑而这些坑大多数教程不会写。这篇文章我把整套流程重新走了一遍从树莓派4B上装哪个系统、用什么镜像到ROS2 Humble安装、环境变量配置、DDS切换再到用真实节点验证改造全部记录下来。适合两类人看一类是打算在树莓派上入门ROS2的初学者另一类是在x86电脑上装过ROS2、想在ARM板子上做部署的开发者。无论你是2GB内存的低配版还是8GB高配版文章里的避坑点基本都覆盖到了。1. 版本选择的底层逻辑为什么是Humble为什么是Ubuntu 22.04很多朋友拿到树莓派4B第一件事就是按直觉装系统结果装到一半发现版本对不上。这里面的逻辑其实很简单ROS2的发行版和Ubuntu版本是强绑定的选错一个后面全白搭。1.1 Humble与Foxy的差别别装完才后悔ROS2的发行版比ROS1更依赖操作系统。Humble Hawksbill这个版本官方对应的是Ubuntu 22.04 Jammy它从2022年5月发布支持到2027年5月是一个妥妥的LTS版本。而Foxy Fitzroy对应的是Ubuntu 20.04 Focal发布更早维护期只到2023年5月现在已经不再接收常规更新了。我在实际项目里的感受是Foxy和Humble最核心的API差别没那么大但一些新功能、新包的兼容性差距会在后续开发中逐渐显现。比如launch系统改用了Python 3.10 的一些特性新版ament_cmake对依赖解析更严格你用到的很多第三方包比如Nav2、MoveIt 2也都在往Humble主分支上对齐。如果现在新开一个项目选Humble是明确的决定毕竟一个能持续维护到2027年的版本至少能保证你毕业后、项目上线后不至于立刻面临生态迁移。还有一个容易忽略的问题树莓派4B官方支持的64位系统路径现在用Ubuntu 22.04跑ARM64版本的ROS2 Humble非常成熟社区里踩过的坑、写好的教程、打包好的驱动基本都是基于这个组合。选择HumbleUbuntu 22.04本质上就是选择了一条被验证过的、相对拥挤的路这对初学者来说反而是好事。1.2 树莓派两个官方系统线路的取舍树莓派官方系统Raspberry Pi OS其实也可以跑ROS2但方式就比较绕要么用Docker容器要么在Debian上是手动从源码编译或者用第三方的预编译仓库。这两种方式我都不太推荐作为新手路线。Docker方案固然干净但树莓派4B的IO性能和SD卡读取速度摆在那里容器内编译和运行的开销对资源敏感型场景并不友好源码编译更是地狱难度一个完整桌面版编译下来4GB内存版本压满Swap跑几个小时都是常有的事。所以我推荐直接用Ubuntu官方发布的树莓派预编译镜像。它分为Server版和Desktop版名字一般是ubuntu-22.04-preinstalled-server-arm64raspi.img.xz或ubuntu-22.04-preinstalled-desktop-arm64raspi.img.xz。如果你问我的真实意见跑ROS2开发优先考虑Server版。Desktop版自带GNOME桌面视觉效果当然漂亮但GNOME在树莓派4B上的流畅度只能说勉强可用。开机占用内存直接就超过1GB再启动rviz2、打开几个终端2GB版本基本就判死刑了4GB版本也紧巴巴的。Server版没有桌面环境内存占用低很多我们可以通过SSH远程开发或者后续只装一个轻量级桌面环境用于图形验证。这个选择背后是树莓派场景的核心原则把资源让给编译和通信而不是让给桌面特效。2. 从烧录到可用的系统底盘选完镜像接下来就是烧录和初始化。这一步看似简单其实有很多值得注意的细节直接决定后面能否顺利跑起来。2.1 镜像烧录的隐藏选项与分区扩容我用的工具是Raspberry Pi Imager。它不只是把镜像写到SD卡里还有一个容易忽略的功能在烧录前通过CtrlShiftX打开高级选项可以直接预配置主机名、开启SSH、设置Wi-Fi国家和无线网络名称密码。这一点对于无头模式特别实用——树莓派插上电就能通过网络访问不用接显示器键盘做初始设置。烧录完成后用lsblk查看SD卡分区你会发现官方预装镜像的根分区通常只分配了较小空间剩下的空间没有被利用。这就需要手动扩容。sudo growpart /dev/mmcblk0 1 sudo resize2fs /dev/mmcblk0p1注意上面假设SD卡设备是/dev/mmcblk0且根分区是第1个分区实际以你机器上lsblk显示结果为准。如果系统提示growpart命令不存在安装一下sudo apt install cloud-guest-utils。这一步不做后面装ROS2 Humble桌面版的时候大概率会遇到根目录空间不足因为ros-humble-desktop完整安装只需要几个GB但加上其他依赖、缓存和后续自己建的工作空间30GB的SD卡很容易捉襟见肘。2.2 软件源与基础工具的标准化配置系统起来后第一步不是急着装ROS2而是收拾软件源。Ubuntu官方源在部分网络环境下下载速度较慢推荐换成国内常见镜像站。以清华镜像站为例树莓派的ARM架构对应的是ubuntu-ports源不是ubuntu源这一点和x86桌面版Ubuntu不一样很容易弄错。编辑/etc/apt/sources.list把原始内容替换成对应的jammy源然后更新sudo apt update sudo apt upgrade -y接着把基础工具装齐curl、git、vim、gnupg、lsb-release、software-properties-common。这些后面配置ROS2源和rosdep都要用到。2.3 4B的性能调校Swap与并发编译接下来是一个很关键但经常被跳过的大坑Swap交换空间。树莓派4B虽然有从2GB到8GB的内存可选但编译大型ROS2工作空间时内存经常不是够不够用的问题而是瞬时峰值的问题。比如编译某个依赖时链接器会同时拉起多个进程内存瞬间冲高如果刚好卡在临界点系统会直接触发OOM Killer随机杀掉编译进程。解决思路就是加大Swap。Ubuntu上可以安装dphys-swapfile这个工具它是树莓派系统上管理Swap的常用方案sudo apt install -y dphys-swapfile安装后编辑/etc/dphys-swapfile找到CONF_SWAPSIZE把默认值改大我这里建议2GB内存版本设置为4096MB4GB及以上设置为2048MB到4096MB之间的值都可以。改完执行sudo dphys-swapfile setup sudo dphys-swapfile swapon设置完之后用free -h确认。这里有个额外提醒SD卡寿命和Swap写入有一定关系但ROS2开发阶段编译频率没那么高正常使用无需担心。内存和Swap管理好之后还需要控制编译并发。树莓派4B是4核Cortex-A72很多人习惯性地colcon build --parallel-workers 4或者设置MAKEFLAGS-j4。这里我建议保守一点使用-j2甚至-j1。原因很直接4个编译进程同时跑每个GCC进程吃数百MB内存再加链接器的内存需求随时可能触发OOM。编译时间虽然会长一点但起码不用反复重来。这一点在低配版上尤其重要。3. 安装ROS2 Humble官方流程的完整落地等到系统基础配置好接下来进入正题安装ROS2 Humble。这一步我会完全按照官方流程走但在每一处都补充说明这样做的原因。3.1 添加apt源与GPG密钥首先要确保系统开启了universe软件源因为ROS2的一些依赖存在这里sudo add-apt-repository universe然后配置ROS2的软件源和GPG密钥。ROS官方文档提供的标准做法是下载ros.key并放到/usr/share/keyrings/目录再写入一个/etc/apt/sources.list.d/ros2.list文件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 $(lsb_release -cs) main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null然后执行sudo apt update这一步有个容易被忽略的检查点arch后面应该是arm64因为树莓派4B如果装的是官方64位镜像dpkg --print-architecture会输出arm64。如果这里变成amd64说明你装成了x86的镜像或者用错了系统版本后面一定会出问题。3.2 安装包组的选择desktop还是baseROS2 Humble在apt仓库里提供了几种安装粒度最常用的两个是ros-humble-desktop包括核心通信、常用工具、可视化插件如rviz2、demo节点、turtlesim等适合日常开发和可视化调试。ros-humble-base只包含通信核心、少量命令行工具和基础库体积小、内存低适合部署和嵌入式场景。我建议开发阶段直接安装desktop版本原因在于图形化工具对新手来说太重要了。rviz2、rqt_graph能让你直观看到话题和节点之间的关系比纯命令行对着ros2 topic list猜结构效率高得多。如果你用的是2GB版本还是可以装desktop的只要不把桌面环境和rviz2同时开起来就还好。完整命令sudo apt install -y ros-humble-desktop这一步会下载不少包根据网速和SD卡写入速度等多久都很正常。安装完成后可以看到/opt/ros/humble目录下已经有一套完整的ROS2文件结构。3.3 环境变量、rosdep与colcon三件套装完二进制包之后最影响体验的环节是环境变量配置。ROS2不像ROS1那样有个全局的setup.bash会被系统自动加载而是需要你在每个新终端里手动source。为了少敲这一行我建议直接写进.bashrcecho source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc验证是否生效echo $ROS_DISTRO如果输出humble说明环境变量已经正常工作。接下来是rosdep。它不是ROS2运行必需的但当你从源码编译第三方包时它负责自动解析和安装依赖少了它你经常会卡在某个包的编译错误上。安装和初始化流程sudo apt install -y python3-rosdep sudo rosdep init rosdep update然后是构建工具colconROS2工作空间编译的标准工具sudo apt install -y python3-colcon-common-extensions到这里ROS2 Humble的基本安装已经完成。但如果你以为就此结束那就太小看实际开发中的问题了。下一步我们要解决通信层的选型这部分直接影响节点发现的速度和稳定性。4. 4B的通信底层DDS与RMW怎么选ROS2和ROS1最大的变化是通信中间件从自研的TCPROS换成了DDS。这一改动带来了真正的分布式通信、服务质量控制但也带来了一个在树莓派上特别容易踩坑的问题默认DDS在嵌入式平台上不一定是最优选择。4.1 ROS2为什么离不开DDSRMW又是什么DDS全称Data Distribution Service是一种以数据为中心的发布订阅中间件标准。ROS2把DDS作为底层传输层上层通过RMWROS Middleware Interface统一抽象接口。你可以把RMW理解成一个适配层ROS2节点代码不直接对接某一家DDS实现而是通过RMW调用底层的发布订阅能力。这意味着你可以在不改动任何机器人代码的前提下切换不同的DDS实现只改一个环境变量。ROS2 Humble默认使用的RMW是rmw_fastrtps_cpp对应的DDS实现是eProsima Fast DDS。它在x86桌面环境里表现不错但在树莓派4B这种有限资源、经常使用Wi-Fi通信的场景下可能遇到几个现象节点启动后要等好几秒甚至更久才能发现彼此、不同网卡之间发现不稳定、话题数据偶尔断流。4.2 默认Fast DDS在树莓派上的问题我实际遇到过的情形是树莓派作为机器人主控通过Wi-Fi与笔记本电脑通信两个节点明明在同一个网段但ros2 node list经常只能看到自己要反复重启或者等待很长时间发现才能成功。这通常不是代码问题而是Fast DDS默认的发现协议在无线网络和弱多播环境下不够果断。为此我建议在树莓派上切换为Cyclone DDS。Cyclone DDS是Eclipse基金会维护的轻量级DDS实现对资源占用更温和在嵌入式平台和无线网络场景下的发现速度通常优于Fast DDS在树莓派社区里也有不错的口碑。安装方法很简单sudo apt install -y ros-humble-rmw-cyclonedds-cpp使用时只需设置环境变量export RMW_IMPLEMENTATIONrmw_cyclonedds_cpp为了持久生效可以写进~/.bashrc。4.3 换成Cyclone DDS与常见网络参数如果想让Cyclone DDS更可靠可以通过配置文件控制它使用的网卡和通信行为。创建一个~/cyclonedds.xmlCycloneDDS xmlnshttps://cdds.io/config Domain General Interfaces NetworkInterface namewlan0/ /Interfaces AllowMulticasttrue/AllowMulticast /General /Domain /CycloneDDS然后设置export CYCLONEDDS_URIfile://$HOME/cyclonedds.xml这里的wlan0不是写死的你需要根据实际网络接口调整。用ip addr查看当前机器上树莓派用的是哪个网卡如果是有线接路由器就换成eth0。除了DDS选型还有两个环境变量对树莓派场景非常实用。一个是ROS_DOMAIN_ID如果周围有多个ROS2机器人同时工作给每个机器人设置不同的域ID可以避免它们互相发现export ROS_DOMAIN_ID1另一个是ROS_LOCALHOST_ONLY。如果你只是单机调试树莓派上同时跑两个节点不需要其他设备参与可以设置为1让通信只在本地回环进行这样能减少网络层面的延迟和干扰export ROS_LOCALHOST_ONLY1这个变量在Wi-Fi信号不稳定的环境下尤其管用因为节点发现不再依赖无线链路的多播传输。配置完DDS这块通信层的隐患基本排完了。接下来就是用实际节点验证整个系统是否真的能跑通。5. 用真实节点验证安装从talker到rviz2安装完毕、通信层选型确定之后不要急着写复杂程序先跑一些系统自带的demo节点把每个层面都验证一遍。5.1 两个终端验证话题通信最基础也最重要的验证是话题通信。开两个SSH终端分别source环境变量后执行终端一ros2 run demo_nodes_cpp talker终端二ros2 run demo_nodes_cpp listener正常的话终端一会持续打印Publishing: Hello World: N终端二会持续打印接收到的消息。如果这一步通了说明ROS2核心通信栈、DDS发现机制、环境变量配置全部正常。此时在第三个终端可以执行ros2 topic list ros2 node list你会看到/chatter话题以及talker和listener两个节点。继续深入一点ros2 topic echo /chatter这条命令会把话题里的数据实时打印出来是排查问题最常用的工具之一。5.2 turtlesim与图形环境注意事项很多教程会让你跑ros2 run turtlesim turtlesim_node来看一个小乌龟窗口以此判断安装成功。但注意turtlesim需要图形界面。如果你用的是Server版系统且没有额外安装桌面环境这条命令会报无法获取显示设备的错误。我个人的建议是如果你打算在树莓派上做需要可视化的开发可以在Server版基础上补装一个轻量级桌面环境或者用X11转发远程显示。但如果只是为了验证ROS2直接用talker/listener就够了没必要为了一个演示窗口给系统增加那么多图形库负担。5.3 rviz2与OpenGL软渲染rviz2是ROS2最重要的可视化工具之一装desktop版时会一并安装。启动ros2 run rviz2 rviz2树莓派4B的GPU虽然支持OpenGL但在某些驱动组合下rviz2可能报出libGL error或者显示黑屏。这时候一个非常实用的环境变量可以帮你绕过硬件加速问题export LIBGL_ALWAYS_SOFTWARE1这个变量强制OpenGL使用软件渲染。代价是帧率低一些但至少能保证rviz2正常显示机器人模型和传感器点云。在树莓派这种平台上软件渲染换来的稳定性是值得的。5.4 一个最小Python节点的运行示例验证完自带demo后我建议再写一个最小的Python节点把工作空间的编译流程也过一遍。创建一个工作空间mkdir -p ~/dev_ws/src cd ~/dev_ws/src ros2 pkg create py_demo --build-type ament_python --dependencies rclpy std_msgs编辑py_demo/py_demo/publisher.pyimport rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalPublisher(Node): def __init__(self): super().__init__(minimal_publisher) self.publisher self.create_publisher(String, demo_topic, 10) self.timer self.create_timer(1.0, self.timer_callback) self.count 0 def timer_callback(self): msg String() msg.data fHello from Raspberry Pi: {self.count} self.publisher.publish(msg) self.get_logger().info(fPublishing: {msg.data}) self.count 1 def main(argsNone): rclpy.init(argsargs) node MinimalPublisher() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ __main__: main()回到工作空间根目录编译cd ~/dev_ws colcon build --symlink-install source install/setup.bash ros2 run py_demo publisher在另一个终端用ros2 topic echo /demo_topic就能看到数据不断输出。这个流程验证的不只是安装还有你自己创建工程、编译、运行的能力这才是今后所有开发工作的基本盘。6. 高频问题与长期使用的调优心得最后这一章不是补充说明而是我在实际使用中遇到最多的坑。如果你能耐心看完树莓派4B上ROS2的开发体验会顺畅不少。6.1 OOM树莓派编译ROS2项目时的头号杀手编译中途终端突然卡死然后SSH断开重连后发现编译进程全部消失dmesg里看到错过OOM Killer的记录——这基本是每个树莓派ROS2用户都会经历的。根因不是内存不够用而是瞬时峰值突破了上限。解决方案有三个层次。第一层是加大Swap前面已经配置过了。第二层是限制编译并发MAKEFLAGS-j2或者colcon build --parallel-workers 2。第三层是不要同时在树莓派上开一堆无关应用。很多人习惯在树莓派上开着浏览器查资料同时还要编译这等于给OOM加码。6.2 终端的source顺序与多工作空间默认环境变量写在.bashrc里每次新终端都会自动加载/opt/ros/humble/setup.bash。但如果你的工作空间里也有install/setup.bash新开终端后需要手动再source一次。要注意顺序先source ROS2的官方环境再source你自己工作空间的环境。后source的会在环境变量上追加路径顺序错了可能导致运行ros2 run时找不到你自定义的包。我习惯把工作空间的source也写进.bashrc但用一个注释分隔开方便维护。如果你同时维护多个工作空间建议不要全部source而是按项目需要手动切换否则会出现包名冲突。6.3 无头模式、远程开发与内存清理树莓派很多时候是不接显示器的而是放在机器人车体上。这种情况下远程开发就很重要。SSH是基础但文件编辑和代码同步可以用VS Code的Remote-SSH插件直接打开远程工作空间代码补全、终端、调试都能在本地完成。在无头模式下内存管理需要更主动。一个常用的小技巧是运行长时间任务后定期清理APT缓存sudo apt clean另外如果发现树莓派启动时间越来越长可以检查一下开机的自启动服务把不用的蓝牙、打印服务等禁用掉。虽然这些服务在平时占用不高但在编译大项目时哪怕多节省一两百MB内存都能减少一次OOM的概率。在实际部署过程中我个人最深的体会是树莓派4B上面跑ROS2真正的瓶颈不是CPU算力而是内存资源和系统配置的细腻度。同样的硬件有人能把编译OOM控制在0次有人一分钟崩三次差的往往不是运气而是Swap有没有配好、编译并发有没有控制、DDS有没有选对。把这些基础盘稳稳打牢树莓派4B完全可以作为一个称职的ROS2机器人主控无论是跑导航、控制机械臂还是做多机通信都有足够的余量。如果你打算长期在这块板上做开发建议从第一天就把这套环境配置的思路内化成习惯后面会替你省下大量排查问题的时间。
返回列表