很多玩 ROS 的朋友都遇到过这个尴尬:Ubuntu 24.04 都出来大半年了,新电脑预装的就是这个版本,结果一查才发现,ROS 1 官方只支持到 Ubuntu 20.04,ROS 1 最后的版本 Noetic 压根就没有为 24.04 准备预编译包。手头项目代码全是 ROS 1 的,又不想重装系统回到老版本,怎么办?这篇文章我从头到尾给你捋一遍,在 Ubuntu 24.04 上装 ROS 1 Noetic 的几条可行路线,包括最省事的 Docker 方案、比较折腾的源码编译方案,以及一堆我踩过的坑和排查思路。适合刚接触 ROS 的新手,也适合给老手当个备忘。
1. 安装前必须搞清楚的底层逻辑
1.1 为什么 Ubuntu 24.04 装 ROS 1 这么麻烦
先说结论:不是不能装,而是官方没有为这个组合做适配。ROS 1 Noetic 是 2020 年发布的版本,官方指定的操作系统是 Ubuntu 20.04(Focal)。到了 Ubuntu 24.04(Noble),系统底层库变化非常大,尤其是 Python 版本从 3.8 跳到了 3.12,还有一堆依赖库的版本都更新了。ROS 1 的核心组件 ros_comm、roscpp、rospy 这些,都是基于旧版 Python 和旧版 Boost、console_bridge 等库编译的,直接拿 Ubuntu 20.04 的 .deb 包装到 24.04 上,依赖关系会直接炸掉。
我用一个生活化的类比解释一下:ROS 1 Noetic 就像一套定制的家具,每个螺丝、每块板材都是按照 Ubuntu 20.04 这个"房间"的尺寸量好裁好的。现在你要把它搬进 Ubuntu 24.04 这个"新房间",墙面厚了、地板高了、插座位置变了,硬塞进去的结果只能是门关不上、抽屉拉不开。
如果你不信邪,直接在 Ubuntu 24.04 上添加 ROS 的官方软件源,然后执行 apt install ros-noetic-desktop-full,大概率会看到类似这样的报错:
The following packages have unmet dependencies: ros-noetic-desktop-full : Depends: ros-noetic-desktop but it is not installable Depends: ros-noetic-urdf-tutorial but it is not installable ...这就是典型的依赖地狱。所以,正经的方案只有三条路:Docker 容器隔离、源码编译、或者用第三方维护的适配源。
1.2 三条路线怎么选:先看你的真实需求
在动手之前,先想清楚你要拿这个环境干什么。这决定了你选哪条路最划算。
| 需求场景 | 推荐方案 | 理由 |
|---|---|---|
| 跑仿真、看 RViz、跑跑现有功能包 | Docker 容器方案 | 开箱即用,不污染宿主机,删了重来也方便 |
| 开发自己的功能包,需要频繁修改、编译 | Docker 容器 + 工作空间挂载 | 既能隔离环境,又能实时同步代码 |
| 需要和硬件(如 USB 摄像头、雷达)通信 | 源码编译或 Docker 容器(需配置 USB 透传) | 容器需要额外配置设备映射,源码编译最省心 |
| 团队协作、部署到多台机器 | Docker 镜像分发 | 环境完全一致,不用每台机器都折腾一遍 |
| 只是想体验一下 ROS 1,不想深入 | 在线体验环境或直接放弃 ROS 1 转向 ROS 2 | 避免浪费时间 |
我个人的建议是:除非你有非常明确的理由必须原生安装(比如要接特定硬件、或者公司内部规定),否则一律优先考虑 Docker 方案。原因很简单:时间成本。源码编译 Noetic 全部功能包,在配置比较好的机器上也要一两个小时,而且中间任何一个小依赖出问题都可能卡住;而 Docker 方案下,pull 一个镜像只要几分钟,跑起来就能用。
2. Docker 方案:五分钟跑起一个干净可用的 ROS 1 Noetic
2.1 为什么 Docker 是 24.04 上最优雅的解法
Docker 的思路说白了就是"搬家不如重盖房"。它直接在宿主机上划出一个隔离空间,在这个空间里给你装一个完整的 Ubuntu 20.04 环境,然后在里面装 ROS 1 Noetic。这样宿主机是 24.04 也好、25.04 也好,对 ROS 1 来说完全无感,它看到的始终是一个"自己熟悉的家"。
这个方案最大的优势有两块:
- 不动宿主机:不会为了 ROS 1 去改系统的 Python 版本、不去动系统的库文件,避免搞坏现有开发环境。我之前见过有人强行装 ROS 1 把系统 Python 给换了,结果一堆 GUI 工具直接罢工,血泪教训。
- 可复制性强:你配好的环境可以打成镜像发给队友,大家拿到的是完全一致的开发环境,再也不用听"在我电脑上明明是好的"这种话了。
2.2 先装 Docker 引擎
在 Ubuntu 24.04 上安装 Docker 本身很简单,官方提供了 apt 仓库,照着走就行。
第一步:卸载可能存在的旧版本
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done第二步:用官方脚本安装(推荐)
curl -fsSL https://get.docker.com | sh这个脚本会自动检测你的系统(Ubuntu 24.04 是支持的),然后配置好官方仓库并安装最新版 Docker Engine。装完后启动服务:
sudo systemctl enable docker && sudo systemctl start docker第三步:把当前用户加入 docker 组(这样不用每次敲 sudo)
sudo usermod -aG docker $USER newgrp docker验证一下:
docker run hello-world如果看到 "Hello from Docker!" 的输出,说明环境就绪。
注意:如果你在国内服务器上,pull 镜像可能会比较慢,建议配置镜像加速器。在 /etc/docker/daemon.json 里写入镜像源地址,然后重启 docker 服务。
2.3 拉取 ROS Noetic 官方镜像并配置环境
Docker Hub 上有 ROS 官方镜像,直接拉取即可:
docker pull ros:noetic-ros-core-focal如果你想用桌面完整版(带 RViz、Gazebo 等可视化工具),拉这个:
docker pull ros:noetic-desktop-full这两个镜像的区别在于体积和功能:ros-core只有 700MB 左右,适合跑纯算法逻辑;desktop-full有 3GB 多,包含了机器人开发几乎所有的常用工具,我们做开发一般直接拉这个。
创建容器并挂载工作空间
拉下来之后,我们需要创建一个容器,同时把宿主机上的工作空间目录挂载进去,这样在容器里编辑的代码才能保存在宿主机上:
mkdir -p ~/ros1_ws/src docker run -it \ --name ros1_noetic \ --network host \ --privileged \ -v ~/ros1_ws:/ros1_ws \ -v /tmp/.X11-unix:/tmp/.X11-unix:rw \ -e DISPLAY=$DISPLAY \ -e LIBGL_ALWAYS_SOFTWARE=1 \ ros:noetic-desktop-full \ /bin/bash解释几个关键参数:
--network host:让容器直接使用宿主机网络,方便后面用 roscore 跟其他机器通信;--privileged:给容器更高的权限,方便访问硬件设备(比如 USB 雷达);-v ~/ros1_ws:/ros1_ws:挂载工作空间目录,这样在容器内编译的代码、生成的日志都存在宿主机上;-v /tmp/.X11-unix:/tmp/.X11-unix和-e DISPLAY=$DISPLAY:这两行是为了让容器里的 GUI 程序(RViz、rqt)能显示到宿主机屏幕上。
如果显示报错,多数是图形转发没成功。我们后面在"常见问题"一节里会专门讲排查方法。
进入容器后,先更新一下 rosdep:
sudo apt update sudo apt install -y python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential sudo rosdep init rosdep update然后验证 ROS 环境:
source /opt/ros/noetic/setup.bash roscore看到started core service [/rosout]就说明 ROS 1 Noetic 已经在 Docker 里正常跑起来了。
2.4 每次使用的工作流:start、exec、stop
Docker 方案唯一的"不习惯"在于,每次要用 ROS 都得先启动容器再进去,不像原生安装那样直接开终端就能 source。但习惯之后其实挺顺手的。
启动容器并进入终端:
docker start ros1_noetic docker exec -it ros1_noetic /bin/bash退出容器(容器停止运行):
exit下次再用,直接docker start+docker exec两步搞定。如果你有常用的终端命令,还可以在宿主机上写一个别名:
echo "alias ros1='docker exec -it ros1_noetic /bin/bash'" >> ~/.bashrc source ~/.bashrc之后在宿主机终端输入ros1就能直接进入 ROS 环境,体验接近原生。
3. 源码编译:硬核玩家的原生安装指南
3.1 为什么源码编译值得一试
Docker 虽好,但有些人就是不喜欢容器这个"壳"——可能是要接特殊硬件、可能是对性能有极致要求、也可能只是单纯想搞清楚系统里到底装了什么东西。如果你属于这类人,源码编译就是你的路。
在 Ubuntu 24.04 上源码编译 ROS 1 Noetic,思路和官方在 20.04 上的源码安装类似,但有几个关键坑要提前填好:
- Python 3.12 缺少
distutils模块,很多 ROS 编译脚本会报错; catkin_pkg等工具依赖的旧版本可能与新 Python 不兼容;- 系统的 Boost 库版本(1.83)比 Noetic 预期的(1.71)新,个别包可能编译报错;
- OpenCV 版本从 4.2 升到了 4.10,cv_bridge 需要手动适配。
这些坑我们不一个个踩一遍确实不知道,下面给你一条我验证过的路径。
3.2 第一步:准备系统依赖
先把编译工具链和系统依赖装齐:
sudo apt update sudo apt install -y \ build-essential cmake git python3-pip python3-dev \ libboost-all-dev libeigen3-dev libpoco-dev \ libopencv-dev libyaml-cpp-dev libconsole-bridge-dev \ libtinyxml2-dev liburdfdom-dev libassimp-dev \ liblz4-dev libbz2-dev libconsole-bridge-dev \ python3-catkin-pkg python3-empy python3-nose python3-setuptools \ python3-numpy python3-yaml python3-lxml python3-netifaces \ libgtest-dev libprotobuf-dev protobuf-compiler \ libpcl-dev libflann-dev libqhull-dev libvtk9-dev这里特别注意libvtk9-dev,24.04 上默认是 VTK 9,而 ROS 的很多可视化模块在老版本上用的是 VTK 7/8。装 9 是因为没有其他选择,后面编译时个别包可能需要打补丁。
补上 distutils这一步很关键:
sudo apt install -y python3-setuptools python3 -m pip install setuptools==65.5.0不要用最新版的 setuptools,最新版已经移除了对distutils的兼容支持,ROS 的编译脚本用不了。65.5.0 是最后一版内置distutils的版本,实测在 Python 3.12 上能正常用。
3.3 第二步:初始化 ROS Noetic 源码环境
源码编译的官方工具叫rosinstall_generator,它可以按照你的需求生成需要拉取的仓库列表。
sudo apt install -y python3-rosinstall-generator python3-wstool python3-vcstool mkdir -p ~/ros_catkin_ws/src cd ~/ros_catkin_ws rosinstall_generator desktop_full --rosdistro noetic --deps --tar > noetic-desktop-full.rosinstall--deps参数会把所有依赖包也包含进来,这样生成的环境是完整的。为了让系统知道去哪里找这些源码包,还需要创建一个.rosinstall文件:
vcs import src < noetic-desktop-full.rosinstallvcs import会从 GitHub、GitLab 等仓库拉取所有 ROS 源码。这里有个小坑:国内网络拉 GitHub 可能很慢甚至失败,如果遇到这种情况,可以用镜像地址替代。把.rosinstall文件里的https://github.com/ros/替换成https://ghproxy.com/https://github.com/ros/这种镜像前缀,或者直接用 Gitee 上的镜像仓库。
3.4 第三步:编译前的重要修改
由于这是 24.04 而不是 Noetic 官方支持的 20.04,编译前需要动两处配置。
修改 Python 路径
打开src/ros_comm/rospy/CMakeLists.txt,找到以下内容:
find_package(PythonLibs 3.8 REQUIRED)改成:
find_package(PythonLibs 3.12 REQUIRED)不用太担心版本号问题,CMake 搜索的时候会找到系统最高的 Python 版本,写 3.12 只是让它如实相告。
闭掉不兼容的包
有几个包在 24.04 上大概率编不过,建议直接从编译清单里去掉。在src/目录下找到这些包并删掉对应文件夹(或者用 wstool 的 rm 命令):
wstool rm -t src laser_geometry wstool rm -t src camera_calibration_parsers wstool rm -t src camera_info_manager这几个包依赖的库版本跟 24.04 冲突太大,暂时移除不影响主流程,如果之后确实需要可以单独修复编译。
修改 CMakeLists.txt 根文件
在~/ros_catkin_ws/src/CMakeLists.txt顶部加上一行:
set(CMAKE_CXX_STANDARD 14)ROS 1 的很多包还在用 C++11 的语法,但 Boost 1.83 的某些头文件要求 C++14 才能编译,统一提升标准可以避免很多不必要的报错。
3.5 第四步:编译并配置环境变量
准备工作做完,开始编译。这一步时间较长,推荐用-j$(nproc-1)让 CPU 多核并行编译:
cd ~/ros_catkin_ws sudo rosdep init rosdep update rosdep install --from-paths src --ignore-src --rosdistro noetic -y ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release -j$(nproc-1)catkin_make_isolated是 ROS 1 推荐的源码安装方式,它会逐个包独立编译和安装,某个包失败不会影响已经编好的部分。首次编译大概需要 1~3 小时,取决于机器性能。
编译成功之后,会生成一个install_isolated目录,把它写进环境变量即可:
echo "source ~/ros_catkin_ws/install_isolated/setup.bash" >> ~/.bashrc source ~/.bashrc验证一下:
roscore如果能正常启动,恭喜你,你已经在 Ubuntu 24.04 上原生跑起了 ROS 1 Noetic。
4. 环境配置与工作空间创建实操
4.1 安装完成后必须做的初始化设置
不管你是用 Docker 方案还是源码编译方案,装好之后的初始化步骤是通用的。这里我以 Docker 方案为例,但操作在两种环境下都一样。
初始化 rosdep
sudo rosdep init rosdep updaterosdep 用于自动安装功能包的依赖项,几乎每个 ROS 项目都用得到。第一次执行rosdep update时如果失败,大概率是网络问题——rosdep 需要访问 GitHub 上的 raw 文件。国内环境建议直接配置 rosdep 镜像源,或者多试几次,偶发失败重试一般能过。
创建一个测试工作空间
mkdir -p ~/ros1_ws/src cd ~/ros1_ws catkin_make source devel/setup.bash这里有一个细节:catkin_make会生成devel和build两个目录,devel里面是编译后的环境脚本,build是中间文件。每次打开新终端都需要source devel/setup.bash才能用工作空间里的功能包,所以建议把这个命令加到~/.bashrc里:
echo "source ~/ros1_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc4.2 用 catkin_create_pkg 创建一个最简单的功能包
工作空间创建好后,我们来创建一个简单的功能包验证整个链路是否通畅:
cd ~/ros1_ws/src catkin_create_pkg test_pkg roscpp rospy std_msgs这个命令会生成一个名为test_pkg的功能包,roscpp、rospy、std_msgs是我们要依赖的库。catkin_create_pkg本质上是帮你生成CMakeLists.txt和package.xml的模板文件,你可以进去看看内容,理解一下包的结构。
回到工作空间根目录编译:
cd ~/ros1_ws catkin_make source devel/setup.bash如果没有报错,说明整个编译链路是通的。
4.3 验证 RViz 和 rqt 可视化工具能正常打开
ROS 1 最常用的可视化工具就是 RViz 和 rqt。在容器里跑图形程序需要 X11 转发,前面我们已经设置过了。这时候启动试试:
rosrun rviz rviz如果窗口弹出,说明图形转发没问题。如果报错或者窗口闪退,通常是两个原因:一是 X11 的 socket 文件没有正确挂载,二是 OpenGL 渲染问题。改用LIBGL_ALWAYS_SOFTWARE=1启动通常能解决后者:
LIBGL_ALWAYS_SOFTWARE=1 rosrun rviz rviz不过要提醒的是,软件渲染的 RViz 会比较卡,拖动模型时能明显感受到掉帧。如果是做重度的 RViz 调试,还是建议走源码安装路线。
4.4 集成 Visual Studio Code 或 CLion 等 IDE
很多新手在容器里写代码会觉得别扭,其实用 VS Code 的 Remote Development 插件就能解决。在宿主机 VS Code 里安装好Remote - Containers插件,然后让 VS Code 直接 attach 到正在运行的ros1_noetic容器上。这样你既可以在宿主机舒服地写代码,编译和调试又都在容器里完成,体验和本地开发几乎一样。
如果你用的是 CLion,也支持远程开发模式,但配置起来更繁琐一些,需要设置 Toolchain 指向容器内路径。
5. 常见问题与排查技巧实录
5.1 问题一:apt 安装时出现依赖冲突
现象:执行sudo apt install ros-noetic-desktop-full,系统提示一堆包存在依赖冲突,无法安装。
原因:ROS Noetic 的二进制包只针对 Ubuntu 20.04 构建,在 24.04 上直接安装必然产生依赖地狱。
解决:停止尝试用 apt 直接装。除非你用的是下面 5.2 里提到的第三方适配源,否则这个方向走不通。切换到 Docker 方案或者源码编译方案,别再浪费时间。
5.2 问题二:第三方 PPA 源是否可靠
现象:有人推荐添加某个维护者的 PPA 源,可以快速在 24.04 上装 ROS 1。
分析:GitHub 上确实有一些个人或社区维护的 Noetic 适配源,比如通过sudo add-apt-repository ppa:xxx/ros-noetic这种方式安装。我的建议是:非官方源务必谨慎。这类源往往没有经过大范围测试,装的时候可能很顺利,但你后续安装其他功能包时,很可能因为包的依赖版本不一致而突然崩掉。真要用,也要选 star 数高、持续维护的源。
经验:我测过一个社区源,安装还算顺利,但在编译某个依赖libpcl的包时出了问题,PPA 提供的libpcl版本和系统中自带的版本冲突,最后只能把 PPA 卸掉重新来过。折腾成本其实不比源码编译低。
5.3 问题三:容器内 GUI 程序无法显示
现象:在 Docker 容器里运行rviz,报错cannot connect to X server。
排查步骤:
- 先确认宿主机有 X Server 在跑。如果你是纯命令行的服务器,没有桌面环境,容器里的 GUI 肯定起不来,必须先在宿主机装好桌面。
- 检查挂载参数:
docker ps查看容器是否带上了-e DISPLAY=$DISPLAY和-v /tmp/.X11-unix:/tmp/.X11-unix这两个参数。如果容器已经创建了而没有这些参数,只能docker rm删掉重建。 - 在容器里执行
echo $DISPLAY,确认环境变量是:0或:1之类的值,而不是空。 - 在宿主机上执行
xhost +local:允许容器访问 X Server,注意用完最好关掉(xhost -),避免安全风险。
5.4 问题四:Python 版本导致脚本执行失败
现象:编译通过,但运行某些 Python 写的 ROS 节点时,报错提示ModuleNotFoundError: No module named 'distutils',或者ImportError: cannot import name 'Mapping' from 'collections'。
原因:Ubuntu 24.04 的 Python 3.12 移除了distutils,collections.Mapping也已经被移除。
解决:安装 setuptools 65.5.0 可以解决 distutils 的问题;collections.Mapping的报错则需要在脚本里用from collections.abc import Mapping替换。这些兼容性问题大多数都可以在源码里做小修改,但前提是你知道报错在哪个文件。实际遇到时用traceback定位一下,一般改个 import 就能跑起来。
5.5 问题五:编译时找不到 OpenCV
现象:源码编译时,某些包报错提示找不到OpenCVConfig.cmake。
原因:Ubuntu 24.04 的 OpenCV 是 4.10 版本,ROS Noetic 的 cv_bridge 期望的是 4.2 或 4.5,CMake 的查找路径对不上。
解决:在编译前先手动设置 OpenCV 的路径:
export OpenCV_DIR=/usr/lib/x86_64-linux-gnu/cmake/opencv4这样 CMake 就能找到系统自带的 OpenCV。如果还找不到,可以检查一下是否安装了libopencv-dev:
sudo apt install -y libopencv-dev5.6 问题六:ROS 1 和 ROS 2 能共存吗
现象:想同时保留 ROS 1 Noetic 和 ROS 2(如 Humble 或 Jazzy),在 24.04 上是否可行?
回答:可以,但要做到环境分离。ROS 1 默认使用.bashrc里的source /opt/ros/noetic/setup.bash,ROS 2 默认使用source /opt/ros/jazzy/setup.bash,两者并不冲突。冲突主要集中在环境变量上(ROS_DISTRO、CMAKE_PREFIX_PATH),所以要么在/opt/ros下分别安装两套环境,用不同的终端 source 不同的 setup.bash,要么用 Docker 把两个环境隔离开。在同一个 shell 里同时 source 两套环境是不可行的,catkin_make和colcon build会互相干扰。
我自己实测过:宿主机原生装 ROS 2 Jazzy,ROS 1 Noetic 放 Docker 容器,两者共存没有任何问题。
5.7 问题七:编译中途内存不足导致进程被杀
现象:源码编译进行到一半,终端提示Killed,或者系统变得非常卡顿。
原因:ROS 的某些包(比如pcl_ros、moveit)编译时非常吃内存,-j$(nproc-1)会一次性把所有核心拉满,内存不够就会被 OOM Killer 干掉。
解决:降低并行度,用-j2甚至-j1重新编译;或者增加 swap 空间:
sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile注意fallocate命令在某些文件系统上不可用,如果报错就用dd命令创建:
sudo dd if=/dev/zero of=/swapfile bs=1M count=8192加好 swap 之后再编译,内存问题基本可以缓解。
6. 我的一点心里话与最后的建议
折腾完这一整套,我最想跟各位说的是:选方案之前先弄清楚你的真实使用场景,别为了一时爽快把事情搞复杂。我见过太多人,系统是 24.04,又没搞明白 Docker,愣是在源码编译上耗了一整天,最后因为某个依赖编译不过而崩溃放弃。如果你是初学者,Docker 方案是你最好的起点,它让你把精力花在学 ROS 本身而不是折腾环境上。等你在容器里把 ROS 玩熟了,再考虑要不要换成原生环境。
另外一个经验是,ROS 1 其实已经进入了维护末期,除了学习老项目和在这个领域里有一些历史包袱的项目,新项目我真的建议直接上 ROS 2。ROS 2 的分布式通信、实时性支持、DDS 中间件这些设计,比 ROS 1 那种一个 roscore 管全局的架构要强太多。Ubuntu 24.04 是官方支持 ROS 2 Jazzy 的版本,如果你还没有投入很多 ROS 1 的代码,直接学 ROS 2 反而是一条更省事的路。
最后再分享一个我在操作中摸索出来的小技巧:不管走哪条路,都建议把整个安装过程写成一个 shell 脚本或者 Dockerfile 保存起来。这样即便以后换电脑,或者团队来了新人,一行命令就能把环境复现出来,省去大量重复劳动。我在团队里就是这么干的,现在每台新电脑的 ROS 环境搭建时间从原来的大半天缩短到了十几分钟。