ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

rosdep update失败全解析与fishros一键安装实战(树莓派/Jetson)

rosdep update失败全解析与fishros一键安装实战(树莓派/Jetson) 很多刚入坑ROS的朋友第一次跑到rosdep update这一步时心里都是一万个问号明明前面装得好好的怎么偏偏在这里卡住网络也试了代理也配了源也换了结果还是红字报错。更难受的是这个问题在不同机器上表现还不一样台式机上折腾一下能过树莓派上又给你变个花样出来。我自己从ROS1的Kinetic一路用到ROS2的Humble前后装过不下二十次系统每次重装都要跟rosdep斗智斗勇。后来接触到fishros这套一键配置脚本算是彻底把这块心病治好了。这篇文章就把我这几年的安装经验做个总结重点聊聊rosdep update为什么会失败、fishros脚本到底做了什么以及树莓派和Jetson这类ARM平台上安装ROS/ROS2时那些文档里查不到的坑。这篇文章适合所有被ROS安装折磨过的人不管你是刚接触ROS的新手还是已经被rosdep搞到没脾气的老人只要你手上有Ubuntu系统的电脑、树莓派或者Jetson开发板想快速跑起来一个能用的ROS环境这篇内容都能帮你省下至少半天时间。1. 先搞清楚为什么rosdep update总爱失败1.1 rosdep到底在干什么要理解rosdep update失败的根源得先知道这个命令的职责。rosdep是ROS的依赖管理工具它的作用是告诉你某个功能包还缺哪些系统级的依赖库然后帮你把这些依赖装好。比如你编译一个包它提示需要libopencv-devrosdep就能根据当前Ubuntu版本自动解析出对应的安装包名并完成安装。而rosdep update做的事情是从ros/rosdistro这个GitHub仓库拉取全量索引数据把这些数据缓存在本地。这个索引记录了每个ROS发行版里所有功能包对应的系统依赖关系。所以当你执行rosdep install --from-paths src --ignore-src -r -y时rosdep要先去查本地缓存如果缓存里没有某个包的数据就会请求远端仓库把缺失的部分补上。问题就出在这里rosdep跟GitHub之间的通信夹着一层并不稳定的网络环境。时区、运营商防火墙策略、DNS解析结果任何一个环节抽风都会导致rosdep update卡住或者直接超时。很多人在这一步反复重试运气好能过去一次运气不好就一直卡在那。1.2 失败的原因其实就那么三类我把这几年遇到过的rosdep update失败情况归了个类主要有三类。第一类是单纯的网络超时。rosdep update默认去访问raw.githubusercontent.com和github.com这些域名在国内网络环境下响应很不稳定。表现就是卡在reading in raw list...或者Hit https://raw.githubusercontent.com/...之后长时间没有动静最后报一个连接超时的错误。这种情况在晚上的高峰时段尤其明显同一个命令早上跑可能就成功了。第二类是指纹验证失败。rosdep在拉取数据时需要校验GPG key如果你的rosdep或者ros-keyring版本太老本地的公钥过期了服务器返回的新公钥又没法通过校验就会报类似W: GPG error: ... The repository ... is not signed的错。这类错误跟网络无关纯粹是密钥同步问题网上不少教程会教你直接从某个key server导入公钥这确实能解决但每次重装系统都得再来一遍挺烦的。第三类是ROS发行版与Ubuntu版本匹配错乱。ubuntu的软件源里有ROS源如果你装的是Ubuntu 24.04却用了旧版ROS1的源或者装ROS2的时候不小心把ROS1的源也加进去了rosdep update在合并索引时就会因为版本不匹配而中断。这类错误最迷惑因为报错信息看起来像网络问题实际是源配置写错了。2. fishros脚本是干什么的2.1 fishros脚本的定位与原理fishros是社区开发者小鱼维护的一套开源配置工具官方名我就不去考据了大家平时都叫它鱼香ROS一键安装。它本质上是一个封装好的shell脚本把ROS安装过程中所有容易出错的环节都做成了自动化操作。这个脚本下载后直接执行不需要手动配源、不需要手动加key、不需要手动写~/.rosdep配置。很多人一听到一键脚本就觉得不够专业觉得还是手动敲命令靠谱。这个观点我部分同意对于纯学习目的、想要搞懂底层原理的人手动安装确实能让你理解ROS的依赖体系。但如果你是想快速搭好环境、把时间花在算法和功能开发上那fishros这类工具的性价比就非常高。它帮你省去的不是几条命令而是排查网络故障、GPG key同步、依赖冲突这些无底洞式的调试时间。脚本的原理其实不复杂它做的事情就是把你手动安装时的所有步骤集中起来通过判断当前系统的架构、Ubuntu版本、网络状况选择合适的镜像源和依赖版本。特别值得表扬的是它对Arm64架构的适配做得很好树莓派和Jetson都能正确识别不会像很多通用教程那样默认你是x86_64然后装出个不能用的环境。2.2 一条命令背后的流程拆解fishros最核心的使用方式就是这一条命令wget http://fishros.com/install -o fishros . fishros执行之后脚本会先检测当前系统的发行版信息然后显示一个交互式菜单里面包含换源、安装ROS1、安装ROS2、安装rosdep等多个选项。选择对应的功能后脚本会按顺序执行以下动作更新apt源列表将默认源替换为公司维护的镜像源或者你手动指定的其他源安装ROS仓库签名用的GPG key添加ROS软件源到apt源列表执行apt update并安装ros-distro-desktop或ros-distro-ros-base初始化rosdep并完成rosdep update配置ROS环境变量到~/.bashrc这里面最关键的其实是换源这一步。脚本会把packages.ros.org替换为一个国内可达性更好的镜像地址同时也处理了raw.githubusercontent.com的访问问题。镜像源的数据同步做得比较及时所以rosdep在后续使用中基本不会再遇到索引缺失的问题。2.3 为什么很多老手也愿意用它你可能觉得这种脚本是给新手偷懒用的但我认识的好几个做了三四年ROS项目的工程师重装系统时也会用fishros来搭基础环境。原因很简单省事且稳定。手动安装最大的问题是每个环节都有潜在的环境依赖。比如你在一台新机器上装ROS2 Humble需要先确认Ubuntu是22.04版本然后添加ROS2的apt源再手动安装python3-vcstool等多个工具包最后初始化rosdep。任何一步的网络都可能导致后续安装失败而脚本因为有重试机制和更稳定的源整个过程的可靠性高很多。还有一个实用场景是批量部署。比如实验室里要给十台机器人统一装环境手动一台台敲命令是非常低效的。用fishros的话每台机器只要执行那一条命令然后选同样的选项十分钟左右就能把环境统一好。对于做多机协作、分布式SLAM这类项目的团队来说这算刚需了。3. 实操从零到ROS2跑通全家桶3.1 环境准备一台干净系统是最省心的不管你是用电脑、树莓派还是Jetson装ROS之前系统本身要干净这是我最想强调的一点。很多人喜欢在已经用了一段时间、装过很多软件的系统上直接装ROS结果经常遇到Python版本冲突、OpenCV版本不匹配、或者cmake版本过旧导致的编译失败。所以我的建议是准备一块单独的分区或者一张新SD卡来装系统。如果你用的是树莓派4B/5可以直接用树莓派官方镜像工具烧录Ubuntu Server 22.04 LTS注意要选64位版本因为从Ubuntu 22.04开始树莓派官方对64位系统的支持已经很完善了没必要再折腾32位那套。对于Jetson系列系统烧录稍麻烦一些。Jetson不像树莓派那样可以随便刷第三方Ubuntu镜像它需要借助NVIDIA官方提供的JetPack SDK进行烧录JetPack里面自带了一套深度定制过的Ubuntu系统内核和驱动都是和硬件绑定的。我在Jetson Orin Nano上用的JetPack 5.1.2对应的就是Ubuntu 20.04这个版本搭配ROS2 Foxy比较合适。如果你拿到的是更新版本的JetPack 6.0底层Ubuntu版本会变成22.04就可以直接上ROS2 Humble。3.2 安装过程实录含命令输出解读假设你现在是一台干净的Ubuntu 22.04系统架构是x86_64或者aarch64都行。打开终端执行wget http://fishros.com/install -o fishros . fishros脚本下载完成后会自动运行你会看到类似下面的交互界面输出[INFO] 检测到系统为 Ubuntu 22.04.3 LTS [INFO] 架构为 x86_64 [INFO] 是否更换系统源 [y/N]这里建议选y因为默认源在国内的下载速度实在太感人了尤其是装desktop版需要拉取大量软件包时镜像源能帮你省下大量时间。选完之后脚本会继续询问[INFO] 是否安装rosdep [y/N]这里也必须选y。rosdep是后续编译功能包时绕不开的工具你现在不装等后面编译别人的包时再回来装就麻烦了。接下来是功能选择菜单不同版本的脚本菜单项可能略有差异大致是[1] 一键安装ROS1 Noetic [2] 一键安装ROS2 Humble [3] 安装rosdep [4] 配置rosdep如果你需要ROS1和ROS2共存建议先装ROS1 Noetic再装ROS2 Humble。共存时需要注意环境变量的切换不过这是后话后面会单独讲。整个过程大约需要5到15分钟取决于你的网络速度和选择的软件包规模。装完之后脚本会提示你执行source /opt/ros/humble/setup.bash然后你就可以用ros2 --version验证安装结果了。如果输出类似ros2 2.6.x这样的版本号说明核心安装成功。3.3 装完之后必须做的验证环境装好了不等于万事大吉我强烈建议你跑一遍最基础的功能验证确保系统是真正可用的。先验证ROS2的核心通信ros2 run demo_nodes_cpp talker开一个新终端跑ros2 run demo_nodes_py listener两个终端都能正常运行且listener能收到talker发过来的消息说明底层DDS通信正常。这一步非常重要因为很多人在跑功能包之前根本不知道自己的ROS环境有问题等编译大工程时才突然报错那时候排查的复杂度就高多了。再来验证一下rosdep是否好用cd ~/your_ros2_ws rosdep install --from-paths src --ignore-src -r -y正常情况下这个命令会提示没有缺失的依赖包或者自动安装几个缺失的库。如果它卡住或者超时那就是rosdep的配置还有问题可以继续用fishros的rosdep修复功能再处理一波。4. 树莓派和Jetson平台单独说4.1 ARM平台的共性问题树莓派和Jetson虽然都是嵌入式平台但它们的共同点是CPU架构都是ARM前者根据型号不同可能是armhf或arm64后者则统一是arm64。这个架构差异带来了一系列连锁反应。第一点是软件包兼容性。很多ROS生态里的二进制包是x86架构编译好的在ARM平台上根本装不上只能从源码编译。这也是为什么同一个ROS功能包在苹果笔记本上装可能只需要apt install一条命令在树莓派上却要编译半小时的直观原因。第二点是性能瓶颈。ARM平台普遍内存小、CPU弱编译大包时经常内存耗尽。我自己的经验是树莓派4B编译稍微大一点的包时最好先增加swap空间不然编到一半进程被杀是常有的事。Jetson虽然性能好一些但Jetson Nano那种2GB内存的老型号同样面临这个问题。第三点是ROS发行版的选择空间被压缩。Jetson的JetPack版本和Ubuntu版本是绑定的而ROS对Ubuntu版本又有严格要求所以你能选择的ROS发行版其实是有限的。比如JetPack 4.x自带Ubuntu 18.04那ROS2就只能装Dashing或者Eloquent这两者都比较老很多新功能包已经不再支持。如果你跟不上NVIDIA的更新节奏还是老老实实先确认清楚系统版本再规划。4.2 树莓派4B系统选型与摄像头驱动树莓派4B是目前最便宜的ROS学习平台之一性能虽然不能说强但跑跑基础SLAM和导航仿真还是够的。选系统时首推Ubuntu Server 22.04 LTS的64位版本原因有两个一是Ubuntu Server比Raspberry Pi OS更接近PC端Linux环境很多ROS教程里写的依赖包在Ubuntu源里都能直接找到二是64位系统能用完整内存寻址对于树莓派4B的4GB/8GB内存版本来说是必要选项。树莓派上另一个常见需求是接入OV5647摄像头模块做视觉应用。在树莓派官方系统里摄像头驱动是整合在固件里的到了Ubuntu Server上就要另想办法。比较通用的方案是使用raspicam库的ROS封装包raspicam_node这个包可以通过源码编译安装。需要提前安装libraspberrypi-dev等底层依赖库否则编译时会报找不到头文件的错。我实测下来的流程是先在系统里安装gstreamer相关插件然后克隆raspicam_node仓库到ROS2工作空间编译后通过raspicam_node/camera话题发布图像。虽然配置过程有点繁琐但效果比用ROS的usb_cam驱动模拟摄像头要好很多延迟更低帧率也稳定。4.3 Jetson系列从烧录到spconv的典型坑Jetson系列因为自带GPU在机器人视觉和深度学习推理方面有明显优势很多做目标检测的ROS项目都会优先选它。但Jetson的软件栈比树莓派复杂得多。首先是烧录系统不是简单往SD卡里写镜像就行的必须用JetPack SDK通过host machine进行烧录整个过程涉及多个组件的刷写耗时还挺长。另一个高频需求是在Jetson上部署力控相关的深度学习库比如涉及点云的spconv库。这个库在Jetson上编译时需要手动指定GPU的算力代际不同的Jetson型号对应不同的算力值。我在Jetson Orin上编译时需要在CMakeLists.txt或环境变量里设置TORCH_CUDA_ARCH_LIST参数比如Jetson Orin系列对应的是8.7或8.9如果是Jetson Nano则对应5.3设置不对就会在编译时直接报不支持。这类算力适配问题fishros脚本没法直接帮你解决因为涉及的是第三方库跟硬件底层的交互。但好消息是只要ROS基础环境和CUDA环境能正常共存这类问题一般都有迹可循多看看编译日志就能定位。5. 常见问题与排查技巧实录5.1 高频报错排查速查表这几年来实际遇到并且帮人排查过的报错实在太多我整理一个高频问题速查表按出现频率排序方便你遇到问题时先对着查一遍。报错信息可能原因解决方法ERROR: cannot download from ...网络访问不了GitHub源换镜像源后重试或使用fishros修复rosdepW: GPG error: The repository ... is not signedGPG key过期或导入不全重新导入ROS仓库公钥rosdep: command not foundpython3-rosdep未安装安装python3-rosdep后再执行sudo rosdep initERROR: Rosdep experienced an error: ...rosdep数据源配置损坏删除~/.ros/rosdep缓存后重新updatePackage ros-distro-desktop has no installation candidate软件源未添加或版本不匹配检查Ubuntu版本与ROS发行版对应关系fatal error: xxx.h: No such file or directory缺少系统级依赖库用rosdep install或apt安装对应dev包/usr/bin/ld: cannot find -lxxx链接库文件缺失安装对应库的开发包一般为libxxx-dev特别注意第一行这个报错绝大多数rosdep update失败都落在这个类别里。如果你用了fishros的换源功能还是失败可以试试清理本地缓存后再跑一次有时候是之前残留的半截索引把新数据挤掉了。5.2 不小心装坏了怎么恢复我见过不少同学在安装过程中因为命令执行到一半CtrlC中断或者改源改到一半把系统搞坏了结果想重来又不知道从哪里下手。这里分享两个恢复技巧。第一个技巧是清理rosdep缓存。如果你只是rosdep出问题但ROS主包没问题那不用重装系统只需要把缓存目录删干净再重新初始化rm -rf ~/.ros/rosdep sudo rm -rf /etc/ros/rosdep sudo rosdep init rosdep update第二个技巧是卸载ROS相关包。如果你装的版本不对或者想换发行版可以直接用apt把ROS系列包全卸掉sudo apt purge ros-* sudo apt autoremove卸载之后再把/etc/apt/sources.list.d/ros*.list里的软件源删掉或者注释掉然后apt update一下系统就基本回到没装ROS的状态了。这两个技巧配合fishros脚本基本上可以应对95%的ROS安装失败场景。我自己的原则是能局部修复就局部修复不要动不动就重装系统重装虽然干净但代价是时间成本太高。5.3 几个值得记住的小习惯最后分享几个平常不太容易在教程里看到的习惯都是我踩过坑之后慢慢养成的。第一个习惯是每次重装完系统先把fishros脚本下载到本地存一份。虽然官方链接很稳定但保不齐哪天网络抽风下载不了本地有一份总归心里有底。而且脚本更新频率不高存一份用上一年完全没问题。第二个习惯是ROS2环境变量的切换要小心。如果你的机器上同时装了ROS1和ROS2环境变量会在source的时候互相覆盖。我的方案是分别写两个别名命令一个source /opt/ros/noetic/setup.bash一个source /opt/ros/humble/setup.bash平时用哪个就source哪个不混用。第三个习惯是如果你要在树莓派5这类新硬件上编译大量功能包建议先加大swap空间再开工。树莓派5的内存虽然最大有16GB版本但只靠内存编译很多大包还是会撞到墙。加一个8GB的swap文件能有效避免编译进程被OOM杀掉。6. 写在最后的一点实际体会从ROS1的Kinetic一路到ROS2的Jazzy我自己经历过完全手动安装、半自动脚本安装、以及现在的fishros全流程安装三个阶段。早期手动安装的时候每次成功都很有成就感但次次都被rosdep update折磨一遍之后我才意识到工具的作用不是让你变懒而是帮你把精力花在更有价值的事情上。现在的做法是拿到一台新设备先用fishros把基础环境和rosdep配好然后花十分钟手动过一遍验证命令确认无误之后再开始折腾具体功能。这套流程看起来简单但帮我省下的时间实在太多了。如果你也在被ROS安装问题折磨或者正准备给树莓派/Jetson搭环境不妨试试这个方案实测下来确实稳。
返回列表