1. 为什么在Ubuntu 20.04上安装ROS是个技术活?
如果你刚接触机器人操作系统,可能会觉得“安装ROS”不就是几条命令的事吗?网上教程一搜一大把,照着敲不就完了?但作为一个在机器人领域摸爬滚打多年的老手,我必须告诉你,在Ubuntu 20.04上安装ROS,尤其是ROS Noetic Ninjemys,远不止是复制粘贴那么简单。这背后涉及到系统版本、软件源、依赖库、环境配置等一系列环环相扣的步骤,任何一个环节的疏忽,都可能导致后续开发工作举步维艰。我见过太多新手卡在“找不到包”、“编译失败”或者“roscore跑不起来”的环节,浪费大量时间排查,最后发现是安装时埋下的雷。
Ubuntu 20.04 LTS是一个长期支持版本,以其稳定性和广泛的社区支持著称,而ROS Noetic正是官方为其量身定制的最后一个支持Python 2/3混合的ROS 1发行版。这意味着,选择这个组合,你获得的是一个经过充分测试、生态成熟且文档齐全的开发环境。但成熟也意味着复杂,官方源、密钥、依赖的链条很长。这篇指南的目的,就是带你走通这条看似标准、实则暗藏玄机的安装之路,不仅告诉你每一步怎么做,更会解释清楚每一步为什么这么做,以及如果出了问题,你应该从哪里开始排查。我们不仅要完成安装,更要建立一个干净、可控、可复现的ROS开发基础。
2. 安装前的核心准备:理清思路与规避大坑
在动手敲下任何命令之前,充分的准备工作能帮你避开90%的常见问题。很多人一上来就急着配置软件源,结果连自己系统的具体版本都没搞清楚,导致后续的软件源地址错误,安装自然失败。
2.1 确认你的Ubuntu 20.04系统详情
首先,打开终端,使用以下命令确认你的系统架构和具体版本号:
lsb_release -a关键要看Description和Release字段,确保是Ubuntu 20.04.x LTS。同时,运行:
uname -m这会输出你的系统架构,最常见的是x86_64(即64位系统)。ROS Noetic官方主要支持amd64(对应x86_64) 和arm64架构。确认这些信息是为了确保你后续下载的软件包与你的系统完全兼容。
注意:如果你的系统是全新安装的,建议先执行
sudo apt update && sudo apt upgrade进行一次全面的系统更新,这能修复一些基础库的潜在问题,但并非强制步骤。如果系统已经使用了一段时间,这步则非常必要。
2.2 理解软件源与密钥的作用
ROS的软件包并不在Ubuntu的官方源中,因此我们需要将ROS官方的软件仓库(Repository)添加到系统的软件源列表里。sources.list文件就是记录这些仓库地址的清单。而apt在从这些仓库下载软件前,会使用仓库提供的GPG密钥来验证软件包的完整性和真实性,防止被篡改。所以流程是:添加密钥 -> 添加软件源 -> 更新本地软件包索引 -> 安装。
这里有一个关键选择:使用官方源还是国内镜像源?
- 官方源 (packages.ros.org):最稳定,与全球开发者同步,但国内访问速度可能很慢,甚至超时,导致安装失败。
- 国内镜像源 (如清华、中科大):下载速度极快,是国内开发者的首选。但镜像可能存在同步延迟(通常很短)。
对于国内用户,我强烈建议使用国内镜像源。以清华大学镜像站为例,这不仅关乎速度,更关乎安装过程的稳定性。网络超时是安装ROS最常见的失败原因之一。
3. 分步安装ROS Noetic完整版
接下来,我们进入核心安装环节。我将以使用清华大学镜像源为例,展示最稳妥的安装流程。
3.1 配置软件源与密钥
首先,设置你的系统能够接受来自packages.ros.org的软件包。即使使用镜像,密钥也需要从官方添加。
添加ROS官方GPG密钥:
sudo apt install curl # 如果尚未安装curl curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -注意:
apt-key命令在更新的Ubuntu版本中已被标记为弃用,但在20.04上仍可正常工作。它的作用是将密钥添加到受信任的APT密钥列表中。添加清华大学镜像的ROS软件源:
sudo sh -c 'echo "deb https://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'这条命令做了两件事:
$(lsb_release -sc)会自动获取你的Ubuntu代号(对于20.04是focal);然后将正确的镜像源地址写入到/etc/apt/sources.list.d/ros-latest.list这个新文件中。将不同来源的源文件分开管理是一个好习惯。更新APT软件包索引:
sudo apt update这一步至关重要。它会让
apt去读取新添加的ROS源,并获取所有可用软件包的列表及其版本信息。如果这一步出现NO_PUBKEY错误,通常意味着密钥添加有问题,需要回头检查第一步。
3.2 安装ROS Noetic桌面完整版
ROS提供了多种安装套件,对于绝大多数开发者,我推荐安装桌面完整版 (Desktop-Full)。
sudo apt install ros-noetic-desktop-full为什么是桌面完整版?
ros-noetic-desktop-full:包含了ROS核心、基础工具、GUI工具(如Rviz、Rqt)、2D/3D仿真器(如Gazebo)、导航库、感知库等。这是最全的版本,为你后续学习、开发、仿真提供了一站式环境,避免后续因为缺少某个功能包而反复安装。ros-noetic-desktop:包含核心、GUI工具和基础库,但不包含Gazebo和部分高级功能包。ros-noetic-ros-base:仅包含核心、构建工具和通信库,没有GUI工具。
安装过程会持续一段时间(取决于网速),它会自动处理大量复杂的依赖关系。你会看到一个很长的软件包安装列表,这是正常的。
3.3 配置Shell环境
安装完成后,ROS的核心命令(如roscore,rosrun)还无法直接使用。因为相关的环境变量(主要是ROS_PACKAGE_PATH和ROS_DISTRO)没有被设置到你的Shell会话中。
ROS提供了一个很方便的脚本来设置这些环境变量。最常用的方法是每次打开新的终端时自动 source 这个设置脚本。
对于bash用户(Ubuntu默认):
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc source ~/.bashrc第一行命令将source /opt/ros/noetic/setup.bash这行代码追加到你的~/.bashrc文件末尾。~/.bashrc是bash shell在每次启动时都会执行的脚本。第二行source ~/.bashrc是立即生效当前终端的配置。
对于zsh用户:
echo "source /opt/ros/noetic/setup.zsh" >> ~/.zshrc source ~/.zshrc验证环境配置是否成功:
printenv | grep ROS你应该能看到类似ROS_ROOT=/opt/ros/noetic/share/ros和ROS_DISTRO=noetic的环境变量。再尝试一个核心命令:
roscore --help如果能正常显示roscore的帮助信息,而不是command not found,那么基础环境就配置好了。
3.4 安装构建工具与依赖管理工具
ROS有一套自己的包构建系统。为了能够创建和管理你自己的ROS工作空间,还需要安装两个关键工具。
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essentialpython3-rosdep:这是ROS依赖管理工具。它用于安装ROS功能包所需的系统依赖(非ROS库)。这是解决“编译时找不到某个头文件或库”问题的关键。python3-rosinstall,python3-wstool:用于管理多个代码仓库的工具,在从源码安装多个ROS包时非常有用。build-essential:提供GCC、G++、make等基础编译工具链。
其中,rosdep的使用需要初始化:
sudo rosdep init rosdep updatesudo rosdep init会下载一个默认的依赖规则列表到/etc/ros/rosdep/sources.list.d/。rosdep update则是将这些规则更新到本地用户缓存。请注意:sudo rosdep init只需要在系统安装后执行一次。如果执行时提示文件已存在,可以忽略或使用sudo rosdep init --include-eol-distros尝试。
4. 验证安装与运行第一个ROS节点
理论安装完成,现在让我们通过一个最经典的“Hello World”示例来验证整个ROS系统是否工作正常。
4.1 启动ROS核心——roscore
ROS是一个分布式系统,所有节点都需要一个“管理器”来帮助它们互相发现和通信,这个管理器就是roscore。在任何ROS工作开始前,都需要先启动它。
打开一个新的终端窗口(重要,以确保环境变量已加载),输入:
roscore你会看到一系列启动日志,最后停留在类似started core service [/rosout]的信息上。这个终端窗口现在被roscore占用了,不要关闭它。
4.2 运行小海龟仿真器
再打开第二个新的终端窗口。ROS内置了一个有趣的演示程序:小海龟仿真器。我们首先启动一个节点来打开仿真器窗口:
rosrun turtlesim turtlesim_node稍等片刻,一个带有随机小海龟的蓝色窗口应该会弹出来。这个节点模拟了一只海龟。
4.3 控制小海龟运动
打开第三个终端窗口,我们启动一个键盘控制节点来控制这只海龟:
rosrun turtlesim turtle_teleop_key根据窗口中的提示(Use arrow keys to move the turtle.),你现在可以通过键盘的上下左右方向键来控制蓝色窗口中的海龟移动了。
4.4 理解背后发生了什么
这个简单的演示验证了ROS核心组件的正常运行:
- 通信机制:
turtlesim_node和turtle_teleop_key是两个独立的进程(节点),它们之间互不认识。是roscore提供的ROS Master充当了“中介”,让它们能够互相发现并传递控制指令( Twist 消息)。你可以通过rostopic list命令看到它们之间通信的话题(如/turtle1/cmd_vel)。 - 环境与工具链:你能成功运行
rosrun命令,说明环境变量配置正确。turtlesim这个功能包能被找到并执行,说明ROS的包管理系统工作正常。 - 基础依赖:图形窗口能正常弹出,说明GUI相关的依赖也已就绪。
5. 安装后的关键配置与工作空间创建
验证通过后,我们还需要进行一些重要的后续设置,为真正的开发工作铺平道路。
5.1 解决可能的依赖问题:深入使用rosdep
虽然桌面完整版安装了很多包,但当你未来从源码编译第三方或自己写的ROS包时,几乎一定会遇到系统依赖缺失的问题。rosdep就是解决这个问题的利器。
假设你有一个名为my_awesome_robot的ROS包需要编译,标准的做法是进入该包的根目录(包含package.xml的目录),然后运行:
rosdep install --from-paths src --ignore-src -r -y让我解释一下这个常用命令的参数:
--from-paths src:从src目录(通常存放所有ROS包)开始查找package.xml文件。--ignore-src:忽略那些已经是源码形式(在src目录下)的包本身,只安装它们的系统依赖。-r:递归地处理所有子目录。-y:对所有安装提示自动回答“yes”,避免交互式确认。
这个命令会解析每个package.xml中<depend>标签指定的系统依赖(例如libopencv-dev,python3-numpy),并尝试通过系统的apt包管理器来安装它们。这是保证跨机器可复现编译环境的关键步骤。
5.2 创建并初始化你的ROS工作空间
ROS代码通常组织在“工作空间”中。标准的工作空间结构有助于catkin(ROS的构建系统)管理和编译你的代码。
按照以下步骤创建你的第一个工作空间,假设我们命名为catkin_ws:
# 1. 创建并进入工作空间目录 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src # 2. 初始化工作空间。这会在src目录下生成CMakeLists.txt的符号链接。 catkin_init_workspace # 3. 返回工作空间根目录并编译。虽然src里还没有自己的代码,但可以编译一次以生成必要的环境设置文件。 cd ~/catkin_ws catkin_makecatkin_make会进行编译,并在~/catkin_ws下生成build和devel两个文件夹。devel文件夹里就包含了你这个工作空间专属的环境设置脚本。
5.3 使你的自定义工作空间生效
为了让系统知道你这个新工作空间里的ROS包,你需要 source 它的setup.bash文件。和之前一样,我们把它加到~/.bashrc中,并且要放在ROS系统环境设置的后面,以确保你的包能覆盖系统或其它空间的同名包(如果需要的话)。
打开~/.bashrc文件,确保顺序如下:
source /opt/ros/noetic/setup.bash source ~/catkin_ws/devel/setup.bash然后执行source ~/.bashrc使其生效。
现在,你的开发环境就完全搭建好了。你可以将下载的ROS包源码或自己编写的包放入~/catkin_ws/src目录下,然后通过catkin_make进行编译。
6. 实战中高频问题排查与解决心法
即便按照指南操作,你也可能会遇到问题。这里我分享几个最常见的“坑”及其解决思路,这比具体的错误代码更有价值。
6.1 软件源更新失败或安装包找不到
症状:执行sudo apt update时,在hit或ign之后出现404 Not Found或Failed to fetch错误,或者执行sudo apt install ros-noetic-desktop-full时提示“无法定位软件包”。
根因分析:
- 软件源地址错误:最可能的原因是添加软件源时,Ubuntu版本代号不匹配。确保
/etc/apt/sources.list.d/ros-latest.list文件中的地址包含focal(20.04的代号)。 - 密钥无效或过期:APT无法验证软件源,拒绝使用。可能是密钥服务器连接问题,或密钥未成功添加。
- 网络问题:连接镜像站或官方源超时。特别是使用官方源时在国内网络环境下极易发生。
排查与解决:
- 首先检查源文件内容:
cat /etc/apt/sources.list.d/ros-latest.list。 - 如果使用镜像,尝试换成另一个国内镜像,如中科大(
mirrors.ustc.edu.cn/ros/ubuntu/)。 - 重新添加密钥。有时网络问题会导致密钥添加不完整。可以尝试使用
hkp://keyserver.ubuntu.com:80作为密钥服务器:sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654。 - 最彻底的方法是:删除现有源文件
sudo rm /etc/apt/sources.list.d/ros-latest.list,然后从本文第3.1节开始重新执行。
6.2 ROS命令找不到(command not found)
症状:在任何终端中输入roscore、rosrun等命令,系统提示command not found。
根因分析: Shell环境变量未正确设置。可能是~/.bashrc(或~/.zshrc)中没有 source ROS的setup.bash,或者 source 了但当前终端会话没有生效。
排查与解决:
- 首先,手动 source 一次看是否解决问题:
source /opt/ros/noetic/setup.bash。然后尝试roscore --help。如果好了,说明是自动配置没生效。 - 检查
~/.bashrc文件末尾是否有source /opt/ros/noetic/setup.bash这一行。确保没有拼写错误,路径正确。 - 如果你使用了
zsh等其它shell,请确认你修改的是对应的配置文件(如~/.zshrc)。 - 一个常见疏忽:修改了
~/.bashrc后,没有在新打开的终端中测试,或者没有执行source ~/.bashrc让当前终端生效。记住,修改.bashrc只影响之后新打开的终端。
6.3 编译工作空间时出现CMake或Make错误
症状:在运行catkin_make时,编译过程在某个包中断,报错信息通常包含CMake Error,Could NOT find ..., 或fatal error: xxx.h: No such file or directory。
根因分析: 这几乎总是缺少系统依赖。ROS包在package.xml中声明了它需要哪些非ROS的系统库。catkin_make不会自动安装这些依赖。
排查与解决:
- 在运行
catkin_make的目录(即工作空间根目录)下,运行之前提到的rosdep安装命令:
仔细阅读输出,看它是否成功安装了所有缺失的包。rosdep install --from-paths src --ignore-src -r -y - 如果
rosdep执行失败或报错某个依赖无法解析,可能是该依赖的规则在rosdep的数据库中不存在或名称不匹配。此时需要根据CMake错误信息手动安装。例如,错误提示找不到OpenCV,则可以尝试sudo apt install libopencv-dev。 - 确保你在正确的工作空间目录下运行
catkin_make。它应该在包含src,build,devel文件夹的层级运行。 - 有时清理一下再重新编译能解决奇怪的问题:
catkin_make clean然后catkin_make。
6.4 运行节点时出现库链接错误
症状:使用rosrun启动一个节点时,报错如error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory。
根因分析: 系统动态链接器找不到ROS包编译生成的共享库。这通常发生在你编译了自己的包之后。这些库位于工作空间的devel/lib目录下,但该目录没有被加入到系统的库搜索路径中。
排查与解决:
- 你已经正确执行了
source ~/catkin_ws/devel/setup.bash吗?这个脚本的作用之一就是将devel/lib等路径添加到环境变量LD_LIBRARY_PATH中。你可以用echo $LD_LIBRARY_PATH检查是否包含了你的工作空间路径。 - 如果你有多个工作空间,并且交替 source 它们的
setup.bash,可能会造成路径覆盖。确保你 source 的是你当前想要使用的工作空间的脚本,并且顺序正确(后source的会覆盖或扩展先source的)。 - 一种临时解决方法是手动添加库路径:
export LD_LIBRARY_PATH=~/catkin_ws/devel/lib:$LD_LIBRARY_PATH,但这只是临时生效。永久解决方案还是确保devel/setup.bash被正确 source。
安装ROS是一次性的工作,但建立一个稳定、可维护的ROS开发环境却是一项持续的任务。我的经验是,保持耐心,仔细阅读终端输出的每一条错误信息(它们通常已经指明了方向),善用apt,rosdep,catkin_make这些工具,并理解它们各自负责的层面。当你能顺利跑通小海龟演示,并成功创建编译自己的第一个工作空间时,你就已经跨过了ROS开发的第一道,也是最重要的一道门槛。后续的所有开发、调试、部署,都将建立在这个坚实的基础之上。如果在安装过程中遇到了本文未涵盖的特定错误,记住一个终极技巧:将完整的错误信息复制到搜索引擎中,你大概率会发现,你踩到的坑,早已有同行填平并分享了经验。