ROS Noetic 这套东西,说新不新,说旧也没到淘汰的地步。到今天我自己的几台开发机上还留着这个版本,原因很直接:一堆机械臂、AGV小车、工业相机的驱动和算法包,写的就是 catkin 那套构建体系,迁到 ROS2 得把整条链路重写一遍。所以每次换电脑、重装系统、给新人配机器,ROS Noetic 的安装配置这件事还是得老老实实做一遍。这篇就把我这些年反复装、反复踩坑的过程整理出来,从系统选型、软件源处理、三条安装路线对比,到装完怎么验证、报错怎么查,全部讲清楚。不管你是刚接触 ROS 的学生,还是被安排给实验室配环境的工程师,照着走一遍基本能省掉半天时间。
1. 为什么现在还有人在装 ROS Noetic
1.1 Noetic 在 ROS 版本谱系里的位置
先把版本关系理清楚,否则你会被各种教程里的名词绕晕。ROS1 的命名规则是首字母顺序对应年份,Kinetic 对应 Ubuntu 16.04,Melodic 对应 18.04,Noetic 对应 20.04,而且 Noetic 是 ROS1 的最后一个长期支持版本。它 2020 年发布,官方维护周期到 2025 年 5 月,也就是说现在这个时间点上,它已经进入生命周期的尾声,官方仓库不再新增功能,只做必要的修补。这个背景很重要,它解释了两件事:一是网上大量教程还是基于它写的,二是新项目不该再以它作为起点。
但“维护结束”和“不能用”是两码事。ROS1 的软件包分发体系是 apt 仓库加源码编译混合的模式,已经装好的包不会消失,社区里的第三方包也大多还在。你在实验室里看到的那台五年前搭起来的移动平台,它的导航参数、标定文件、启动脚本全都是为 Noetic 调的,只要硬件没坏,它就能一直跑下去。我见过不少课题组,主力设备还是 Noetic,新买的机器反而是用来试 ROS2 的。这种新旧并存的状态会持续相当长一段时间。
再补一个常被忽略的点:Noetic 默认绑定的 Python 是 Python3,而它前面的 Melodic 还是 Python2。这个差异看起来只是版本号,实际影响很大——你在网上抄到的 Melodic 教程里的pip install全都要改成pip3,print语句的写法、字符串编码的处理方式也都不一样。很多人装完发现某个脚本跑不起来,排查半天,最后发现是抄了 Python2 时代的代码。记住这条:Noetic 是 Python3 的世界,凡是看到不带 3 的 python 命令都要警惕。
1.2 哪些项目到现在还离不开它
我接触过的场景大致分几类。第一类是教学和课程实验,教材还没更新,实验指导书里写的还是catkin_make,学生没得选,只能装 Noetic。第二类是存量工业设备,机械臂厂商提供的 ROS 驱动包更新很慢,有些品牌的 SDK 到 2024 年还在发 ROS1 版本,客户现场跑的也是 ROS1,你没法单方面升级。第三类是某些特定算法包,比如一些老的 SLAM 实现、标定工具、点云处理库,作者早就不维护了,源码里到处是ros::NodeHandle,移植成本远大于继续用。
反过来说,如果你是从零开始的新项目,尤其是要长期维护、要上产品的,就别再往 Noetic 上投了。ROS2 的 Humble 对应 Ubuntu 22.04,是当前的长期支持版本,通信机制、生命周期管理、实时性都比 ROS1 好一大截。我一般给别人的建议是:先想清楚你手上的硬件和依赖包支持哪个版本,别被“新版本更好”这种直觉带着走。装错的代价是整条开发链路推倒重来。
还有一类人是纯学习目的,想先建立对 ROS 基本概念的理解再决定方向。这种情况其实两条路都行,但如果你打算跟着网上大部分中文教程走,Noetic 的资料确实更多,遇到问题搜到的答案也更全。等你把话题、服务、参数服务器、TF 变换这些概念搞明白了,换到 ROS2 时思维方式的迁移成本并不高,变的只是 API 写法和构建工具。
1.3 装之前先想清楚的三件事
第一件事:你用的是不是 Ubuntu 20.04。这是硬绑定关系,Noetic 的二进制包只针对 focal 这个发行版编译,你在 22.04 上强行装,apt 会直接告诉你找不到软件包。网上偶尔有人发“在 22.04 装 Noetic 成功”的帖子,走的都是源码编译或者容器方案,那是另一条完全不同的路,不在本文讨论范围内。先确认系统版本,再往下走。
第二件事:你有没有管理员权限。ROS 的安装要写系统目录、要改 apt 源、要动环境变量文件,全都是需要 sudo 的操作。公司或学校的机器如果是别人给你配好的账号,先确认能不能提权,否则你会卡在第一条命令上。
第三件事:你的网络环境能不能顺畅访问软件源。ROS 的服务器在境外,国内直连下载速度可能只有几十 KB,装一个 desktop-full 要拉几百个包,算下来几个小时都有可能。所以安装前先决定用官方源还是镜像源,这个决策比后面所有细节都重要。我的习惯是直接上国内镜像,省下来的时间够你多看两章文档。
2. 环境准备:从系统到网络的前置工作
2.1 Ubuntu 20.04 该装在哪种环境里
这个选择很多人不重视,装到一半才发现不合适。三种主流方案我分别说说适用场景。
虚拟机的优势是安全、可回滚、可以随时快照。你可以在装 ROS 之前打一个干净的快照,装崩了直接回退,五分钟恢复。缺点是图形性能弱,跑 Gazebo 这种三维仿真会卡,尤其是默认的虚拟显卡驱动,经常出现 RViz 黑屏或者 Gazebo 启动后一片灰。如果你只是学语法、写节点、跑跑 turtlesim,虚拟机完全够用,给 4 核 8G 内存、60G 硬盘就行。
双系统的优势是能用到全部硬件性能,独显直连、CPU 不被虚拟化层吃掉。缺点是要分区,操作不当有丢数据的风险,而且切换系统要重启。搞视觉、点云、强化学习这类吃算力的方向,双系统是性价比最高的方案。分区时给 Ubuntu 至少留 80G,ROS 全套加上 Gazebo 模型库、数据集,很快就会吃掉几十个 G。
物理机单系统最省心,性能也是最好的,适合实验室给专门设备配的开发机。缺点是这台机器就干不了别的了,而且系统出问题要重装的话,整个环境得重来一遍,所以一定要养成备份工作空间的习惯。
我的实际做法是:主力开发机用双系统,Ubuntu 那边不装任何娱乐软件,纯粹干活;测试和教学演示用虚拟机,随开随关;如果是要跑长时间训练任务,就用一台单独的物理机。还有一个折中方案是 Windows 上装 WSL2,好处是启动快、和 Windows 文件互通,但图形界面的支持一直是个麻烦事,Gazebo 和 RViz 经常需要额外折腾 X 服务器转发,新手不建议从这里入手。
2.2 硬件门槛与显卡驱动的关系
ROS 本体对硬件要求很低,一个单核 CPU 加 2G 内存就能跑核心节点。真正吃资源的是后面要用的 Gazebo 和 RViz。想流畅跑一个带激光雷达和深度相机的仿真小车,我的经验是 8G 内存打底,16G 比较舒服,CPU 四核以上,因为 Gazebo 的物理引擎是单线程密集计算。
显卡这块是踩坑重灾区。开源的 nouveau 驱动跑 Gazebo 基本就是灾难现场,画面撕裂、帧率个位数、偶尔直接黑屏。你需要在 Ubuntu 的“软件和更新”里切换到 NVIDIA 的专有驱动,装完重启确认nvidia-smi能正常输出。如果这一步没做,后面遇到的“RViz 打开一片黑”“Gazebo 启动后模型不显示”这类问题,九成都是驱动导致的,白白浪费排查时间。
还有一个隐性坑是显卡驱动的版本和内核版本冲突。Ubuntu 20.04 的默认内核在长期更新中换过好几个小版本,有些时候专有驱动需要重新编译内核模块。如果你在系统更新后突然进不了图形界面,用 Ctrl+Alt+F3 切到 tty,卸载驱动重装通常能救回来。这个经验很值钱,遇到的时候别慌。
内存不够的情况下,Gazebo 会先卡后崩,日志里出现 OOM 相关的字样。有条件就上 16G,实在不行把仿真场景简化,减少传感器数量,也能凑合跑。
2.3 软件源、时区与语言环境
装 ROS 之前,先把 Ubuntu 自己的软件源换成国内镜像,这一步能让你后面所有 apt 操作都快起来。在“软件和更新”的图形界面里改,或者直接编辑/etc/apt/sources.list,把archive.ubuntu.com替换成国内镜像站的地址。改完之后跑一次:
sudo apt update sudo apt upgrade -y把系统更新到最新状态。这一步在装 ROS 之前做,能避免很多依赖版本冲突。我遇到过好几次因为系统补丁太旧,导致 ROS 的某个依赖包版本对不上,apt 报一堆“依赖关系不满足”。
时区建议改成 Asia/Shanghai,ROS 里的时间戳、日志、TF 变换都和系统时间强相关,时区不对的话,跨机器通信时的时间同步会出问题。命令是:
sudo timedatectl set-timezone Asia/Shanghai date语言环境这块,保持英文界面比较省事。ROS 的终端输出、路径名都是英文,中文界面下某些工具的输出会混入中文字符,日志分析时会有点烦。如果你确实需要中文输入法,建议把界面语言设为英文,只装中文输入法框架,这样两不误。
最后确认一下系统架构,ROS 是 64 位的:
uname -m lsb_release -a输出里应该看到 x86_64 和 Ubuntu 20.04.x LTS,代号 focal。这两条信息后面配置源的时候会用上,先记住。
3. 三条安装路线,我该怎么选
3.1 官方 apt 源:标准流程与逐条命令解释
这是最规范的做法,也是理解整个安装过程的最好方式。我建议不管你最后用哪条路线,都先把这个流程看一遍,因为镜像源和脚本本质上都是在这个基础上做替换。
第一步,添加软件源。ROS 的包放在自己的 apt 仓库里,Ubuntu 默认不认识,要先告诉系统去哪找:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'这条命令里的$(lsb_release -sc)会自动展开成系统代号,在 Ubuntu 20.04 上就是 focal。它的好处是通用,你把同样的命令拿到 18.04 上跑,会自动生成 melodic 需要的源地址——虽然后面装的包名不一样,但思路一致。
第二步,导入签名密钥。apt 需要验证软件包的来源,所以要装公钥:
sudo apt install curl gnupg2 lsb-release -y curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key | sudo apt-key add -这里有个历史遗留问题要说清楚。老教程用的是F42ED6FBAB17C654这个密钥,ROS 在 2021 年换过一次签名密钥,新的是C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654。如果你抄的是几年前的博客,执行完会看到NO_PUBKEY的报错,导致后面apt update直接失败。解决办法是手动拉取新密钥:
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654另外补充一句,apt-key这个工具在 Ubuntu 20.04 里已经被标记为弃用,虽然还能用,但控制台会打印警告。如果你想更规范,可以用gpg --dearmor的方式把密钥存到/etc/apt/trusted.gpg.d/目录下。不过对个人开发机来说,用 apt-key 图个方便也没什么问题,警告可以忽略。
第三步,更新索引并安装。先sudo apt update让系统感知新源,然后安装主体:
sudo apt install ros-noetic-desktop-full -yros-noetic-desktop-full是包含内容最多的版本,带了 ROS 核心、常用工具、RViz、Gazebo 插件、感知和仿真相关的一堆东西,装完体积大概两三个 G。如果你硬盘紧张或者只需要跑纯计算的节点,可以换成更精简的ros-noetic-desktop或者最基础的ros-noetic-ros-base。我的建议是第一次装直接上 full,省得后面缺东西再一个个补,那种“跑起来发现少个包”的体验很糟糕。
3.2 国内镜像源加速:换源的原理和写法
官方源的下载速度在国内实在感人,所以我几乎所有机器都用镜像。原理很简单:镜像站定期把 ROS 的仓库同步一份到国内服务器,你从国内服务器下载,速度能到几 MB 每秒。内容完全一样,包名、版本、校验值都对应,不存在兼容性问题。
以清华的镜像为例,把第一步的源地址替换掉:
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros-latest.list'注意这里用的是单引号和点命令加载/etc/lsb-release,比之前的写法更稳妥,因为某些环境下lsb_release命令可能没装。
中科大、阿里云、华为云也都有 ROS 镜像,地址结构类似,把域名换掉就行。我个人习惯用清华源,同步比较及时。有个小技巧:你可以打开镜像站的网页,直接看它的 ros/ubuntu/dists/ 目录下有没有 focal 这个文件夹,有就说明同步到位了。有时候某个镜像站同步滞后,装到一半报 404,就是因为源里还没有最新的包。
换源之后一定要重新sudo apt update,而且要注意看输出里有没有报错行。如果某个源的地址写错了,apt 会跳过它继续用其他源,这时候你可能装到一半发现包缺失,却不知道是源的问题。
密钥的获取也能走镜像,不过大多数镜像站不托管 ROS 的 gpg 密钥,这一步还是得从官方渠道拿。如果这一步卡住,参考 3.3 节里提到的一键脚本,它们内部也会处理密钥问题。
3.3 一键脚本:省事背后的取舍
社区里有不少自动化安装脚本,比如常被提到的“鱼香ROS”一键安装,就是这类工具的代表。它的思路是把上面的步骤全部封装起来,你执行一行命令,脚本自动判断系统版本、选择匹配的镜像源、处理密钥、安装主体包、初始化依赖、配置环境变量,全程几乎不用你干预。
它最大的价值在于处理rosdep初始化。这个步骤在国内网络下失败率很高,因为rosdep要从境外的代码托管站点拉取索引文件,直连经常超时。一键脚本一般会提供一个替代工具,把索引换到国内地址,这个问题就绕过去了。对新手来说,能省下大量排查时间。
但用脚本有几件事必须清楚。第一,你得知道它到底做了什么。脚本执行完,源文件被改了、系统目录被写了、环境变量被追加了,如果你完全不了解,后面出问题就无从下手。我的建议是脚本跑完之后,回头检查一遍/etc/apt/sources.list.d/ros-latest.list和~/.bashrc这两个文件,看看它改了什么。第二,脚本更新不及时的风险。ROS 仓库地址、密钥、依赖关系都可能在某个时间点变化,脚本作者如果没跟进,执行到一半就会卡住。所以最好选用最近还在更新的脚本。第三,安全性。下载别人的脚本直接执行,本质上是在信任作者。稳妥的做法是把脚本先下载下来读一遍,确认没有奇怪的系统改动再执行。
三种方案的对比我整理成表,你可以按自己的情况选:
| 对比项 | 官方 apt 源 | 国内镜像源 | 一键脚本 |
|---|---|---|---|
| 下载速度 | 慢,几十分钟到数小时 | 快,几分钟到十几分钟 | 快 |
| 操作复杂度 | 中,需要逐步执行并理解 | 中,比官方源多一步换源 | 低,一条命令 |
| 出错可排查性 | 高,每步都能看到输出 | 高 | 低,黑盒执行 |
| rosdep 初始化 | 容易失败 | 容易失败 | 通常已处理 |
| 学习价值 | 高 | 中 | 低 |
| 适合人群 | 想搞懂原理的人 | 大多数实际开发者 | 完全新手、赶时间的人 |
我自己的做法是:第一次装必须走官方源或镜像源的手动流程,把每一步都过一遍;之后图快就用镜像源加几条命令拼成一个自己的脚本,比用别人的脚本更放心。
3.4 环境变量与 rosdep 初始化
不管走哪条路线,装完主体包之后都有两步收尾工作,缺一不可。
第一步是环境变量。ROS 的命令行工具、Python 模块、库文件路径都靠环境变量暴露,不配置的话你敲roscore会提示找不到命令:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc source ~/.bashrc这里有个细节值得说明:/opt/ros/noetic/setup.bash和/opt/ros/noetic/setup.zsh的区别在于你用的 shell。Ubuntu 默认是 bash,所以改~/.bashrc。如果你把默认 shell 换成了 zsh,那就得改~/.zshrc并 source 对应的脚本。我见过有人改了 zsh 的配置却一直在 bash 里测试,怎么都不生效,白白折腾。
顺带提一个进阶用法:工作空间的覆盖机制。当你后面创建了自己的 catkin 工作空间,需要 source 工作空间里的devel/setup.bash。这个脚本会把自己叠加在/opt/ros/noetic之上,实现包的覆盖。所以~/.bashrc里的 source 顺序很重要,工作空间的一定要放在系统 ROS 的后面,否则覆盖不生效。
第二步是 rosdep,它是 ROS 的依赖管理工具,你在编译别人的包之前需要先用它把系统依赖装齐:
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential -y sudo rosdep init rosdep updaterosdep init做的是在/etc/ros/rosdep/sources.list.d/下生成默认索引列表,rosdep update则是把这些索引实际下载到本地缓存。失败基本都出在第二步,因为要访问境外的托管站点。常见的报错长这样:
ERROR: unable to process source [https://raw.githubusercontent.com/...]遇到这种情况,几个处理思路。一是多试几次,网络波动有时能碰运气成功。二是用前面提到的一键脚本自带的替代工具,它把本地索引源替换成了国内地址,命令改成对应的名字再跑一次就行,原理是在/etc/ros/rosdep/sources.list.d/里换了一份指向国内镜像的列表。三是手动配置:自己下载索引文件放到本地,然后在配置里指向file://路径。这个方法最麻烦但最可控,适合内网环境批量部署。
rosdep 配置好之后,你在工作空间里执行rosdep install --from-paths src --ignore-src -r -y,它会自动分析package.xml里声明的依赖,把缺的系统包装上。这个命令在编译别人开源包的时候是救命的,很多人编译报错说找不到某个库,其实跑一遍 rosdep 就自动解决了,不需要手动一个个 apt install。
4. 装完之后怎么验证与建工作空间
4.1 五分钟验证清单
装完别急着上手写代码,先按这个清单过一遍,确认各个组件都正常。这样后面出问题时你能确定是代码的问题还是环境的问题。
第一,检查核心命令是否存在:
which roscore which rosrun which rostopic rosversion -d最后一条应该输出noetic。如果前面几个 which 都找不到路径,说明环境变量没生效,回 3.4 节检查。
第二,启动核心节点。开一个终端跑roscore,正常输出里会显示 ROS_MASTER_URI、端口号、进程 ID 等信息。这个窗口保持不动,另开一个终端跑rostopic list,应该能看到/rosout和/rosout_agg两个话题。这一步验证的是节点间通信的基础设施。
第三,跑小海龟。这是 ROS 圈子里最经典的“Hello World”:
rosrun turtlesim turtlesim_node rosrun turtlesim turtle_teleop_key第一个命令会弹出一个图形窗口,里面有一只小乌龟。第二个命令在另一个终端里执行,然后用键盘方向键控制,乌龟应该能动。如果窗口弹不出来,重点怀疑显示环境和显卡驱动;如果窗口出来了但按键没反应,检查是不是焦点没在 teleop 的那个终端上,这个坑我踩过不止一次。
第四,验证 RViz:
rviz应该能打开一个深色的三维可视化界面。第一次打开会提示选择配置文件,直接关掉对话框即可。如果一片黑屏或者直接崩溃,基本都是显卡驱动的问题,回到 2.2 节处理。
第五,验证 Gazebo:
gazebo第一次启动会下载模型库,这一步也会访问境外服务器,慢是正常的。如果卡在下载阶段一直不动,可以考虑预先配置模型库的国内镜像,或者手动下载模型包放到~/.gazebo/models目录。Gazebo 能打开并且能往场景里拖一个立方体,就说明仿真环境基本可用。
4.2 catkin 工作空间的创建与理解
ROS1 的代码组织方式是工作空间加分包。系统自带的包在/opt/ros/noetic里,你自己写的代码放在单独的工作空间里。创建流程:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/ catkin_makecatkin_make第一次执行会生成build和devel两个目录。build存放编译中间产物,devel存放编译结果和几个 setup 脚本。然后:
source devel/setup.bash echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc这里要理解src目录的语义:它不只是一个源码文件夹,而是 catkin 的“链接空间”。catkin 在编译时会扫描src下的每一个含package.xml的目录,把它们当作包来处理。所以你在src下建包的时候,一定要用catkin_create_pkg或者手动创建完整的包结构,不能只是随便建个文件夹丢代码进去。
创建包的典型命令:
cd ~/catkin_ws/src catkin_create_pkg my_first_pkg roscpp rospy std_msgs后面的三个参数是依赖项,分别是 C++ 接口、Python 接口和标准消息类型。这三个基本是每个包的标配。新手常犯的错误是漏写依赖,然后在代码里 include 了某个头文件,编译时报“找不到文件”,其实只要在package.xml和CMakeLists.txt里补上就行。养成习惯:每引入一个新的库,就同步更新这两个文件。
关于catkin_make和catkin build的选择,我建议新手先用catkin_make,它简单直接,对整个工作空间一次性编译。catkin build是按包并行编译的,速度快,还能单独编译某个包,但它需要额外安装,而且对包之间的依赖关系更敏感,配置不当会出现奇怪的问题。我的习惯是:单包开发用catkin_make --pkg 包名,多包项目再考虑切换。
4.3 常用功能包与工具链补装
desktop-full 虽然全,但有些常用的东西还是得单独装。下面这些是我几乎每台机器都会补的:
sudo apt install ros-noetic-rqt ros-noetic-rqt-common-plugins -y sudo apt install ros-noetic-rqt-robot-plugins ros-noetic-rqt-graph -y sudo apt install ros-noetic-gazebo-ros-pkgs ros-noetic-gazebo-ros-control -y sudo apt install ros-noetic-joint-state-publisher ros-noetic-robot-state-publisher -y sudo apt install ros-noetic-xacro ros-noetic-urdf -y sudo apt install python3-pip python3-catkin-tools -yrqt 系列是图形化调试工具,节点图、话题监控、参数调整都靠它,比纯命令行直观得多。rqt_graph能画出一张节点和话题的连接图,排查“为什么我的节点收不到数据”时特别有用,一眼就能看出话题名字是不是写错了。
Gazebo 相关的包如果你的 full 版本里已经带了就跳过。joint-state-publisher和robot-state-publisher是做机器人模型可视化必须的,配合 URDF 和 xacro 使用。xacro 是 URDF 的宏扩展,能用变量、函数、包含等方式简化模型描述,稍微复杂一点的机器人模型都靠它,手写纯 URDF 会很痛苦。
Python 这边,pip 建议换国内源,否则装 numpy、opencv 这类包会等到天荒地老:
mkdir -p ~/.pip cat > ~/.pip/pip.conf << 'EOF' [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple timeout = 120 EOF这个配置写一次就行,以后所有 pip 安装都会走国内源。我在给别人配环境时经常发现他们的 pip 还是默认源,装个 opencv-python 要十几分钟,换源后几十秒就好了。
5. 报错排查实录:我踩过的那些坑
5.1 apt 相关报错
报错:E: 无法定位软件包 ros-noetic-desktop-full
这个最常见,原因按概率排序有这么几种。第一个是忘了sudo apt update,源加了但索引没更新,系统不知道有这个包。第二个是源文件写错了,比如把 focal 写成了别的代号,或者域名拼错了。用cat /etc/apt/sources.list.d/ros-latest.list看一眼内容,再用lsb_release -sc确认代号,两边对一下。第三个是系统版本不对,你在 22.04 上装 Noetic,那确实没有对应的包,这不是配置问题,是根本性的不匹配。
有个排查技巧是直接在浏览器里打开源地址,比如访问镜像站的dists/focal/main/binary-amd64/Packages文件路径,如果能看到内容,说明源是好的,问题在本地配置;如果 404,说明这个镜像站没同步这个版本。
报错:NO_PUBKEY或由于没有公钥,无法验证下列签名
前面说过,ROS 换过密钥。解决命令:
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update如果密钥服务器连不上,换个 keyserver,比如keyserver.ubuntu.com直连、或者用hkp://pgp.mit.edu:80。实在不行就用 gpg 手动导入的方式,从镜像站找到密钥文件,gpg --dearmor之后放到/etc/apt/trusted.gpg.d/ros.gpg。
报错:依赖关系不满足
以下软件包有未满足的依赖关系: ros-noetic-xxx : 依赖: yyy 但是它将不会被安装这种基本是系统里的某个库版本太旧或者被锁定了。先sudo apt update && sudo apt upgrade把系统更新到最新,再看能不能装。如果还是不行,用apt-cache policy 包名看看有哪些版本可选。有时候是某个第三方 PPA 把包版本锁住了,把那个 PPA 移除就好。
5.2 rosdep 相关报错
报错:ERROR: cannot download default sources list from ...
这是 rosdep init 的经典失败。核心原因是访问不到境外的索引地址。处理方式和 3.4 节说的一样:多次重试、用国内替代工具、或者手动配置本地索引。有个细节要注意:如果你之前执行rosdep init失败过,可能已经在/etc/ros/rosdep/sources.list.d/下留下了半成品文件,重新执行会报“文件已存在”。先删掉那个目录再重试:
sudo rm -rf /etc/ros/rosdep/sources.list.d/ sudo rosdep init报错:ERROR: unable to process source ...
这是rosdep update阶段的报错,同样是网络问题。有个技巧是增大超时时间,在/etc/ros/rosdep/sources.list.d/20-default.list里把地址改成本地缓存路径,或者调整/etc/ros/rosdep/sources.list.d/里的超时参数。我一般直接用替代工具搞定,省事。
缓存不一致导致的奇怪报错
如果你换过索引源,旧的缓存可能和新索引对不上,出现“找不到某个 key 的解析规则”这类报错。清理缓存重来:
rm -rf ~/.ros/rosdep rosdep update~/.ros这个目录是 ROS 存放用户级缓存的,很多东西都放在这里。遇到莫名其妙的缓存问题时,删掉整个~/.ros/rosdep再重建,往往能解决。
5.3 图形界面与仿真相关报错
RViz 或 Gazebo 打开黑屏
按这个顺序排查。第一步确认显卡驱动,跑glxinfo | grep "OpenGL renderer",如果输出的是 llvmpipe 或者 software rasterizer,说明你在用软件渲染,性能极差且容易显示异常,需要装专有驱动。第二步检查是否在虚拟机里,虚拟机需要开启 3D 加速选项。第三步试试export LIBGL_ALWAYS_SOFTWARE=1强制软件渲染,如果能显示了,反过来证实是驱动问题。
Gazebo 卡在“Downloading model”
Gazebo 第一次启动会从境外服务器下载模型素材库,几百兆到几个 G。卡住的话,可以配置模型库镜像,或者手动把模型包下载下来解压到~/.gazebo/models。另一个办法是启动时加参数跳过在线模型检查:
gazebo --verbose看 verbose 输出能确认卡在哪一步。如果只是模型下载慢,可以先不管,等它下载完第一次之后,后面启动就快了。
终端里 source 之后仍然提示 command not found
九成是改错了配置文件。确认你的默认 shell:echo $SHELL。如果是/bin/bash,改的是~/.bashrc;如果是/bin/zsh,改的是~/.zshrc。改完记得source一次让当前终端生效,或者关掉终端重开。还有一种情况是.bashrc里有前面的错误命令导致后续行没执行,用bash -x ~/.bashrc能看出卡在哪一行。
5.4 报错速查表
| 现象 | 最可能的原因 | 处理方式 |
|---|---|---|
| 无法定位软件包 | 没 apt update / 源写错 / 系统版本不匹配 | 检查源文件和系统代号 |
| NO_PUBKEY | 密钥过期或未导入 | 导入 C1CF6E31 新密钥 |
| rosdep init 失败 | 索引地址访问不通 | 多次重试或换国内索引 |
| rosdep update 卡住 | 网络超时 | 清理缓存后重试 |
| RViz 黑屏 | 显卡驱动缺失 | 装专有驱动或开 3D 加速 |
| Gazebo 卡下载 | 模型库访问慢 | 配置镜像或手动放置模型 |
| 命令找不到 | 环境变量未生效 | 检查 shell 和 source 顺序 |
| catkin_make 报错找不到头文件 | package.xml 缺依赖声明 | 补声明并重新编译 |
| 节点收不到话题数据 | 话题名不一致 | 用 rqt_graph 查看连接 |
| 编译时内存爆掉 | 并行编译占用过大 | 用 -j2 限制并行数 |
6. 装完只是开始:配套工具与后续路线
6.1 编辑器、终端与版本管理
ROS 开发离不开一个好用的编辑器。VSCode 是当前最主流的选择,装几个扩展就很顺手:C/C++ 扩展负责代码跳转和调试,Python 扩展负责脚本,CMake Tools 能直接调用 catkin 的构建。再配一个 ROS 相关的扩展,能解析package.xml、launch文件和消息定义。配置的时候记得把/opt/ros/noetic/include加到 include 路径里,否则代码里 include ROS 头文件会有红色波浪线,虽然不影响编译,但看着很烦。
终端建议换成 Terminator 或者 tmux。ROS 开发经常要同时开四五个终端跑不同的节点,用标签页管理会清爽很多。Terminator 的好处是可以分屏,一个窗口里上下左右切分,配合快捷键效率很高。tmux 更强大,支持会话保持,ssh 断线后重新连上还能继续看之前的输出,远程开发时特别有用。
版本管理用 git。每个工作空间一个仓库,或者按包拆分。这里有个细节:build和devel目录不要提交,写一个.gitignore:
build/ devel/ *.pyc __pycache__/ .vscode/很多人第一次提交把编译产物一起提交了,仓库瞬间膨胀到几百兆,后面清理起来很麻烦。另外注意工作空间里有多个包时,每个包目录是独立仓库还是整个工作空间一个仓库,这个要提前定好。我的习惯是:工作空间级的一个仓库,包作为子目录,简单省事;如果某个包要单独发布给别人用,再抽出去单独建仓库。
6.2 从 turtlesim 到机械臂、小车与相机
环境装好之后,学习路径建议按这个顺序走:先用 turtlesim 理解话题和消息,写一个订阅/turtle1/pose并打印位置的节点,再用/turtle1/cmd_vel发速度指令让它走个方形。这两步做完,你对 ROS 的通信机制就有感觉了。
然后进阶到 URDF 建模。自己定义一个简单的两轮小车或者机械臂模型,用 xacro 写,在 RViz 里用robot_state_publisher和joint_state_publisher把它显示出来,再手动拖动关节看运动。这个过程能让你理解 TF 变换是怎么回事,TF 是 ROS 里最难理解也最重要的概念之一,早接触早受益。
再往下是仿真。把模型放进 Gazebo,加上差速驱动插件、激光雷达插件、惯性单元插件,让它在一个带障碍物的环境里跑起来,然后接入导航功能包。这套流程走通一遍,你就具备了做移动机器人自主导航仿真的完整能力,这也是很多招聘岗位要求的核心技能。
再往上就是真机方向了,分为几支。机械臂方向要学 moveit,做运动规划、轨迹执行、抓取,典型平台像 AR3 这类开源机械臂,配套的 ROS 包挺全,适合入门。视觉方向要学相机标定,用camera_calibration包做内参标定,然后接触点云处理,把深度相机或者工业相机接进来,做目标检测、位姿估计。做工业相机的话,要特别注意厂商提供的驱动包,不同品牌的接入方式差别很大,有的提供 ROS 节点,有的需要你自己封装 SDK。我接触过的项目里,相机驱动这一环往往比算法本身还费时间,提前确认好资料和支持力度很重要。
6.3 什么时候该转 ROS2
这个问题我被问过很多次。给几个具体的判断依据。
硬件平台刚起步,或者正在选型,那直接上 ROS2。ROS2 的通信基于 DDS,多机通信、服务质量配置、实时性都比 ROS1 强,而且生命周期管理、组件化这些特性对工程化很友好。当前长期支持的版本对应 Ubuntu 22.04,生态已经相当成熟,常用的导航、MoveIt、仿真都有对应版本。
已有 ROS1 项目在维护、短期内不做大改,那就留在 Noetic,别折腾。迁移一个中等规模的 ROS1 项目到 ROS2,工作量往往被严重低估,话题名改了、参数接口变了、launch 文件格式从 xml 换成了 python 为主、构建工具从 catkin 换成 colcon、消息定义语法也有细微差异,这些都是要一处处改的。
介于两者之间的情况,可以用桥接方案做渐进式过渡,让 ROS1 和 ROS2 的节点在同一套系统里互发消息,新的模块用 ROS2 写,老模块暂时保留。这样能给团队一个平滑的迁移窗口。
还有个经常被忽略的点是微控制器方向。如果你要做嵌入式端的 ROS 集成,比如在 ESP32 上跑节点,ROS2 的 micro-ROS 生态是更合适的路径,资源占用小,通信方式也更适合低功耗设备。这块 ROS1 基本没有对应方案,属于选 ROS2 的硬理由。
我个人的实际状态是两套环境并存在同一台机器上:Noetic 用来维护老项目,Humble 用来做新东西。两个版本各装各的,靠 docker 或者独立工作空间隔离,互不干扰。刚开始上手的时候别这么搞,先把一套玩明白,再考虑并行。
最后分享一个我反复验证过的小习惯:装完 ROS 之后,立刻给系统打一个快照或者做一次完整备份,把~/.bashrc、/etc/apt/sources.list.d/、/etc/ros/这几个关键位置单独复制一份出来。后面不管怎么折腾坏了环境,照着这几份文件恢复,比重新装一遍快得多。我有一台机器因为误删了源文件,重装花了两个小时,后来养成备份习惯,再出问题基本都是十分钟内解决。