1. 为什么这个安装流程值得单独写一篇
ROS Melodic 是 2018 年随 Ubuntu 18.04 一起进入大家视野的机器人操作系统版本,虽然现在 ROS2 已经铺开,但大量实验室设备、教学套件、老项目代码仍然跑在 Melodic 上。我前后在三四台机器上装过这套环境,最深的感受是:安装本身不难,难的是网络环节。官方教程里rosdep update那一步,在正常的网络条件下可能几十秒就过了,但在某些网络环境里,它会反复超时、卡住、报 SSL 错误,甚至让你误以为是系统坏了。
所以这篇内容的核心思路很明确:把需要联网拉取的资源提前准备好,把 rosdep 的更新源改到本地,让整个安装过程尽量不依赖实时网络。这套方法我实测下来在离线或弱网环境下非常稳,适合以下人群:
- 在实验室或公司内网环境下装 ROS 的同学;
- 网络条件不稳定,官方源经常连不上的开发者;
- 需要批量部署多台相同配置机器,想做成可复现流程的运维人员;
- 第一次装 ROS,被
rosdep update卡到怀疑人生的新手。
整篇内容我会按照真实操作顺序展开,每一步都说明为什么这么做,以及我踩过哪些坑。你照着走一遍,基本可以一次装好。
2. 装之前先把这几件事想清楚
2.1 版本对应关系不能错
ROS 的版本和 Ubuntu 版本是强绑定的,装错版本会出现大量依赖冲突。这个对应关系必须记牢:
| ROS 版本 | 对应 Ubuntu 版本 | 发布年份 |
|---|---|---|
| Melodic | 18.04 | 2018 |
| Noetic | 20.04 | 2020 |
| Kinetic | 16.04 | 2016 |
Melodic 只支持 Ubuntu 18.04,你如果拿 20.04 去装 Melodic,会在添加源那一步就开始报错。反过来,18.04 装 Noetic 也不行。所以第一步先确认系统版本:
lsb_release -a输出里Release那一行必须是18.04。如果是18.04.x也没问题,小版本不影响。
2.2 提前准备好本地压缩包
这是整篇内容的关键。官方流程里,rosdep update会去几个固定的地址拉取索引文件,这些文件不大,但网络不通就完全卡死。我的做法是:先在能正常访问的机器上把这些文件下载好,打包拷到目标机器。
需要提前准备的东西包括:
- ROS 的 apt 源安装包(
ros-melodic-desktop-full及其依赖,可以用apt-get install --download-only提前下好); - rosdep 的索引文件(
/etc/ros/rosdep/sources.list.d/里配置的那些源对应的文件); - 一些常用的工具包,比如
python-rosdep、python-rosinstall等。
提示:如果你手上有一台能正常联网的 Ubuntu 18.04 机器,最省事的办法是在那台机器上完整装一遍,然后把
/var/cache/apt/archives/下的 deb 包和 rosdep 的缓存目录整个拷过来。
2.3 系统基础环境检查
装 ROS 之前,有几个基础项要先确认:
# 确认软件源里有 universe 仓库 sudo add-apt-repository universe # 更新一次系统 sudo apt-get update sudo apt-get upgradeuniverse仓库必须开启,ROS 的很多依赖包都在里面。如果你之前手动改过/etc/apt/sources.list,要确保没有把 universe 注释掉。
另外,locale 设置也容易被忽略。如果系统 locale 是POSIX或者中文环境,某些 ROS 工具会报编码错误。建议统一设成 UTF-8:
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这一步做完,后面编译工作空间时能少很多莫名其妙的报错。
3. 离线准备阶段:把该下的都下下来
3.1 在联网机器上导出 deb 包
如果你有一台能正常联网的 Ubuntu 18.04 机器,可以这样操作:
# 先按官方流程添加 ROS 源 sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt-get update # 只下载不安装,把 deb 包缓存到本地 sudo apt-get install --download-only ros-melodic-desktop-full执行完之后,所有 deb 包都在/var/cache/apt/archives/目录下。把这个目录整个打包:
tar -czvf ros-debs.tar.gz /var/cache/apt/archives/*.deb这个包可能有几百 MB 到 1 GB 左右,取决于你选的安装类型。desktop-full是最全的,包含仿真、感知、导航等模块;如果只需要基础功能,可以换成ros-melodic-desktop或ros-melodic-ros-base,体积会小很多。
3.2 rosdep 索引文件的本地化处理
rosdep update的本质是去几个固定地址下载 YAML 格式的索引文件,然后缓存到~/.ros/rosdep/目录下。这些地址在/etc/ros/rosdep/sources.list.d/20-default.list里定义。
在联网机器上正常执行一次rosdep update,然后把整个缓存目录拷出来:
# 联网机器上执行 sudo rosdep init rosdep update # 打包缓存 tar -czvf rosdep-cache.tar.gz ~/.ros/rosdep/ tar -czvf rosdep-sources.tar.gz /etc/ros/rosdep/目标机器上,把这两个包解压到对应位置,就相当于完成了rosdep update。这是整个离线方案里最核心的一步。
3.3 用本地源替代在线源
如果目标机器完全不能联网,还需要把 apt 源也改成本地目录。做法是:
# 在目标机器上创建本地源目录 sudo mkdir -p /var/local/ros-debs sudo cp /path/to/ros-debs/*.deb /var/local/ros-debs/ # 生成 Packages 索引 cd /var/local/ros-debs dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz # 添加到 sources.list echo "deb [trusted=yes] file:/var/local/ros-debs ./" | sudo tee /etc/apt/sources.list.d/local-ros.list sudo apt-get update这样apt-get install就会从本地目录读取 deb 包,完全不依赖网络。
4. 正式安装:按顺序走完每一步
4.1 添加源与密钥
如果目标机器能访问 ROS 官方源,这一步直接按官方来:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt-get update如果连密钥服务器都连不上,可以手动导入密钥文件。在联网机器上执行:
apt-key export C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 > ros-key.gpg把ros-key.gpg拷到目标机器,然后:
sudo apt-key add ros-key.gpg4.2 安装 ROS 主体
sudo apt-get install ros-melodic-desktop-full如果你已经配好了本地源,这一步会直接从本地读取 deb 包,速度非常快。安装过程中如果提示依赖缺失,检查一下本地源目录里的 deb 包是否完整。
安装完成后,验证一下核心命令是否可用:
source /opt/ros/melodic/setup.bash roscore如果roscore能正常启动并输出日志,说明主体安装成功。
4.3 初始化 rosdep
这一步是重点。正常流程是:
sudo rosdep init rosdep update但在网络受限的环境下,rosdep init可能会因为无法访问默认地址而失败。这时候用我们之前准备的本地文件:
# 手动创建目录 sudo mkdir -p /etc/ros/rosdep/sources.list.d/ # 把之前打包的 sources 文件解压进去 sudo tar -xzvf rosdep-sources.tar.gz -C / # 把缓存解压到用户目录 mkdir -p ~/.ros tar -xzvf rosdep-cache.tar.gz -C ~/.ros/做完之后,验证一下:
rosdep update如果它直接读取本地缓存并快速完成,说明配置正确。如果还是尝试联网,检查~/.ros/rosdep/目录下是否有完整的索引文件。
4.4 配置环境变量
每次打开新终端都要source一次很麻烦,直接写进.bashrc:
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc source ~/.bashrc如果你有多个工作空间,注意source的顺序:先 source ROS 主体,再 source 你的工作空间,否则会出现包找不到的问题。
4.5 安装常用工具
sudo apt-get install python-rosinstall python-rosinstall-generator python-wstool build-essential这些工具在后续编译工作空间时会用到。如果本地源里有对应的 deb 包,直接装;没有的话,提前在联网机器上下好。
5. 那些让我卡了半天的坑
5.1 rosdep update 超时但没报错
这个最坑。命令执行后光标一直闪,没有任何输出,等十几分钟也没反应。原因通常是它在尝试连接某个地址,但连接被挂起而不是直接拒绝。解决办法就是前面说的本地化方案,把索引文件提前准备好。
5.2 apt-get update 报 GPG 错误
有时候密钥导入成功,但apt-get update还是报NO_PUBKEY。这种情况一般是密钥没有正确关联到源。可以这样排查:
# 查看当前密钥 apt-key list # 如果密钥存在但报错,尝试重新导入 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654如果密钥服务器也连不上,就用前面说的手动导出导入方式。
5.3 安装到一半提示磁盘空间不足
desktop-full完整安装加上后续编译,占用空间可能超过 10 GB。建议根目录至少留 20 GB 空闲。如果空间紧张,可以选ros-melodic-ros-base,只装核心通信库,后续按需添加包。
5.4 编译工作空间时找不到 Python 依赖
Melodic 默认用的是 Python 2.7,如果你系统里 Python 3 是默认版本,catkin_make可能会报错。检查一下:
python --version如果是 Python 3,需要显式指定:
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python2.7或者在CMakeLists.txt里设置好 Python 路径。
5.5 环境变量冲突导致包找不到
如果你之前装过其他版本的 ROS,或者.bashrc里有多个source语句,会出现包路径混乱。排查方法:
echo $ROS_PACKAGE_PATH正常情况下应该包含/opt/ros/melodic/share。如果里面有其他版本的路径,去.bashrc里把多余的 source 语句删掉。
6. 装完之后怎么验证整套环境是好的
6.1 跑一个最小示例
开两个终端,第一个跑:
roscore第二个跑:
rosrun turtlesim turtlesim_node如果能看到一个小乌龟的窗口,说明核心通信和图形界面都正常。
6.2 检查 rosdep 是否真的可用
rosdep check roscpp如果输出All system dependencies have been satisfied,说明 rosdep 工作正常。如果报错说找不到 rosdep 数据库,回去检查~/.ros/rosdep/目录。
6.3 创建一个测试工作空间
mkdir -p ~/catkin_test/src cd ~/catkin_test catkin_make source devel/setup.bash如果编译过程没有报错,并且source之后echo $ROS_PACKAGE_PATH包含~/catkin_test/src,说明工作空间配置正确。
7. 关于这套离线方案的一些个人体会
这套流程我用了大概两年多,前后部署过十几台机器,最大的感受是:提前准备比现场排错省事得多。尤其是实验室批量装机的时候,把 deb 包和 rosdep 缓存做成一个 U 盘镜像,插上去十几分钟就能装好一台,比每台都去等网络快太多了。
有几个细节值得再强调一下:
- deb 包要定期更新。ROS 的包会持续发布小版本更新,如果你用的镜像太老,装完之后
apt-get upgrade可能会拉取大量新包,又回到网络问题。建议每隔几个月重新导出一份。 - rosdep 缓存也有时效性。索引文件会更新,如果目标机器上的缓存太旧,某些新包的依赖可能解析不出来。同样建议定期刷新。
- 不同机器的架构要一致。如果你在 x86_64 机器上导出的 deb 包,拿到 ARM 机器上是装不上的。导出前确认目标机器的架构。
- 本地源目录不要放在根分区。如果根分区空间紧张,把 deb 包放在单独挂载的数据盘上,通过软链接或者直接改源路径来引用。
最后说一个我自己的习惯:每次装完一台机器,我会把整个/opt/ros/melodic目录和~/.ros目录打包备份。下次再装同配置的机器,直接解压覆盖,连 apt 都省了。这个方法在完全相同的硬件和系统版本上非常有效,但跨版本或跨架构就不行了,只能作为快速恢复手段。
如果你也在折腾 Melodic 的安装,希望这篇内容能帮你少走点弯路。网络问题看起来是小事,但卡起来是真的耽误时间,提前把资源准备好,整个流程会顺畅很多。