☰
Ubuntu 24.04 安装 ROS Noetic 方案:Docker、虚拟机与迁移 ROS 2
2026/10/21 4:38:01 网站建设 项目流程

群里最近总有人问一个问题:新电脑装了 Ubuntu 24.04,跑 ROS Noetic 老是装不上,官方源里根本没有ros-noetic-*的包,教材又全拿 Noetic 举例,到底怎么整?

我太懂这个痛点了。Noetic 是 ROS 1 的最后一个长期发行版,官方只给它做了 Ubuntu 20.04(Focal)的二进制包;Ubuntu 24.04(Noble)对应的是 ROS 2 那边的 Jazzy。可现实里大量老工作空间、课程代码、厂商 SDK 还绑死在 Noetic 上,不跑还真不行。这篇文章把我实际踩过的方案全列出来:直接硬装会死在哪个环节、Docker 怎么隔离出一个“合法”的 20.04 环境、虚拟机适合哪些场景、以及什么时候该下狠心迁到 ROS 2 Jazzy。不是让你跟官方对着干,而是分清需求再选路。

1. 先看清事实:Noetic 的官方平台边界为什么划在 20.04

1.1 一个时代的收尾:Noetic 的设计基线是 Focal

ROS Noetic 在 2020 年 5 月发布,当时就是奔着“最后一版 ROS 1”去的,官方明确把它绑定在 Ubuntu 20.04 和 Python 3.8 上。你去看packages.ros.org的仓库目录就会发现,所有ros-noetic-*的 deb 包都放在focal那一层,压根没有noble目录。这不是官方偷懒,而是 Noetic 的依赖版本在整个开发阶段就锁死在 20.04 生态里:Boost 1.71、OpenCV 4.2、GCC 9/10,这些是当时 Focal 系统自带的库版本。

再加上 ROS 1 的维护期在 2025 年 5 月已经画上句号,官方更不可能为一个已经停止维护的发行版去适配新版 Ubuntu。

1.2 Ubuntu 24.04 的生态已经隔了一代

Ubuntu 24.04 默认 Python 3.12,Boost 接近 1.83,GCC 13/14,OpenCV 4.10。表面看都是“同一个软件”,实际上包之间的 ABI(二进制接口)和编译配置早就不是一代了。ROS Noetic 编译出的 .deb 包依赖的是 focal 时期的系统库路径和符号版本,拿到 noble 上装,轻则提示依赖冲突,重则装上后动态库加载直接崩。

我列个对照表,一眼就能看出差距:

环境维度Noetic 设计时用的版本Ubuntu 24.04 实际版本
默认 Python3.83.12
Boost1.71 / 1.721.83
GCC9 / 1013 / 14
OpenCV4.24.10
官方 ROS 1 deb 包有无

这套差异意味着,你不可能通过简单修改几行路径就让老包无缝跑起来。理解这个前提之后,下面的所有方案才有意义:要么隔离环境,要么重新构建,要么换体系。

1.3 关键判断:先别急着跟官方对着干

很多新手上来就搜“Noetic Ubuntu 24.04 安装”,搜到一堆第三方编译教程,照着折腾一整天,最后系统搞得半残。我的建议是先冷静问自己三个问题:

  • 你手里的代码,能改吗?如果能改,优先考虑迁移 ROS 2。
  • 你只是要跑教程例程、做算法验证?那 Docker 就够。
  • 你要接真实硬件、需要 USB 串口、需要内核级驱动?那直接上虚拟机。

这三个问题决定了你走哪条路,别看到方案就硬套。接下来我先把“直接硬装”的路堵死,让你知道为什么这条路不值得走。

2. 直接硬装的三个死法和一条不推荐的血路

2.1 死法一:把 focal 的 ROS 软件源加到 noble 里

最常见的操作是这样的:在/etc/apt/sources.list.d/ros1.list里写一行

deb http://packages.ros.org/ros/ubuntu focal main

然后sudo apt update,这时候你会惊喜地发现ros-noetic-desktop-full能搜到了。别高兴太早,等你执行安装时会看到一堆这样的输出:

The following packages have unmet dependencies: ros-noetic-desktop-full : Depends: ros-noetic-ros-core but it is not installable Depends: liburdfdom-dev but it is not installable

原因是 Noetic 的 deb 包依赖 Focal 时期的系统库,比如libboost1.71-dev、python3-catkin-pkg,这些包在 Ubuntu 24.04 的源里要么不存在,要么版本对不上。APT 是个死心眼,找不到匹配依赖就直接罢工,不会帮你“凑合一下”。

有人会想:那我先把 focal 的源也加进来,让 APT 能拉到老库?这种操作在桌面上基本等于自残——focal 的库和 noble 的库混在一个系统里,APT 的依赖解析会越来越乱,分分钟把系统包管理器搞坏。

2.2 死法二:用 dpkg --force-depends 强行灌包

APT 装不了,有人就上dpkg -i --force-depends强拆,把ros-noetic-ros-base等一组 deb 包硬灌进去。我可以明确说:装完百分之百跑不起来。

最典型的报错是rospy导入失败。因为 Noetic 的rospy会调用系统 Python 的特定库,而 Ubuntu 24.04 默认 Python 3.12 对老包的兼容性很差,尤其是一些依赖distutils的模块,3.12 里直接没了。你source /opt/ros/noetic/setup.bash之后执行roscore,大概率看到这样的东西:

ModuleNotFoundError: No module named 'rospy'

或者更恶心的:模块能导入,但加载共享库时libboost_python版本冲突,程序起来就段错误。这种半残状态最难救,因为你根本分不清是哪个包坏了,最后只能重装系统。

2.3 死法三:从源码编译 Noetic 全家桶

理论上,源码编译是唯一能“原生适配” Ubuntu 24.04 的硬核路线。但 ROS 1 全家桶包含上百个包,编译依赖链极其庞大。光是把rosdep、catkin_pkg这些 Python 工具在 Python 3.12 下跑通,就要打不少补丁,因为 3.12 移除了一堆旧 API,而 Noetic 时代的工具链没跟上。

就算你把基础工具链搞定,后面还有一堆 C++ 包会哭着找老版本 Boost、老版本 Qt、老版本 OpenCV。你要做的就是不断修改 CMakeLists、临时装旧库、手动指定路径……这不是搞科研,这是给官方擦屁股。除非你是想借机深入理解 ROS 底层构建系统,否则别碰,时间和精力不值。

2.4 血路:社区非官方二进制包与 conda

有人会给你推荐“某某非官方源已经编译好 Noetic for noble”。我对这类源的态度一向是:仅限应急,别进生产。

原因是 ROS 1 已经停止维护,非官方源基本都是某个开发者或小团队用自己的机器编译的,覆盖面不全,更新随缘,出了问题也没人管。相比之下,社区里基于 conda 维护的 ROS Noetic 发行渠道相对成熟一点,至少能在一个隔离环境里解决 Python 老版本的问题,做法大概是这样:

conda create -n ros_noetic python=3.9 conda activate ros_noetic conda install -c conda-forge ros-noetic-desktop

但别指望它等于 Ubuntu 20.04 里原生的 Noetic,很多包有兼容问题,Gazebo 这类重量级工具也别想太完美。它对环境隔离做得不错,适合“只想跑个算法 demo 不想折腾 Docker”的开发者。不过我自己用下来的感受是:真到了非 Noetic 不可的地步,Docker 的稳定性比 conda 强很多。

3. Docker 隔离方案:在 24.04 里开一个“合法”的 20.04 世界

3.1 为什么首选 Docker

Docker 的核心优势是:宿主机是 Ubuntu 24.04 完全不用动,容器里跑的就是一个原汁原味的 Ubuntu 20.04。官方 ROS 镜像仓库里有ros:noetic-ros-base-focal这样的镜像,底层就是 focal,装的就是 Noetic 的官方软件包。这等于绕过了所有“版本不兼容”问题,因为你在容器里拥有了一个官方支持的环境。

很多开发者担心“容器是不是性能很差?”,实际跑 ROS 节点完全没问题,因为 ROS 只是进程间通信,不是重负载虚拟化。算法、图像处理、SLAM 这些计算都在容器里直通宿主机 CPU 和内存,性能损耗可以忽略。

3.2 最小可用:把 roscore 和命令行节点跑起来

先拉一个基础镜像,进容器里补必要的包:

docker run -it --rm \ --name noetic \ --network=host \ ros:noetic-ros-base-focal \ bash

进入容器后先做基础准备:

apt-get update apt-get install -y ros-noetic-ros-base python3-rosdep rosdep init rosdep update source /opt/ros/noetic/setup.bash roscore

这里有个关键点:--network=host一定要带上,它让容器直接使用宿主机的网络栈。ROS 1 的 master 和节点之间通过 TCP/UDP 连接,端口和 IP 乱配会造成各种玄学通信问题,--network=host直接让话题数据走本地回环,最省心。

3.3 桌面版 GUI:让 RViz、Gazebo 能弹窗

光跑命令行不算完整,很多人还要开 RViz 看点云、开 Gazebo 跑仿真。容器里启动 GUI 的核心思路:把宿主机的 X11 显示服务映射给容器。

首先在宿主机上放行本机图形连接:

xhost +local:

然后启动容器时挂载 X11 相关路径:

docker run -it --rm \ --name noetic \ --network=host \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ ros:noetic-ros-base-focal \ bash

进容器后安装桌面组件:

apt-get update apt-get install -y ros-noetic-desktop-full rviz

只要能看到 RViz 窗口,就说明 GUI 打通了。提个醒:xhost +local:会让本机所有本地用户都能连你的 X 服务,用完记得执行xhost -收回权限。

如果你的显卡是 NVIDIA,并且需要在容器里做 GPU 加速渲染,需要装nvidia-container-toolkit,启动参数加--gpus all。一般跑 RViz 不加也能用,只是吃 CPU 渲染会卡一点。

3.4 日常工作流:挂载工作空间、编辑和构建

容器里的文件系统是临时的,代码必须放在宿主机上,然后挂载进去。典型的启动命令:

docker run -it --rm \ --name noetic \ --network=host \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v $HOME/catkin_ws:/catkin_ws \ ros:noetic-ros-base-focal \ bash

进容器后构建工作空间:

source /opt/ros/noetic/setup.bash cd /catkin_ws catkin_make source devel/setup.bash

代码在宿主机上编辑,构建在容器里完成,互不干扰。唯一要注意的是文件权限:容器默认是 root 用户,构建出来的devel、build目录属于 root,在宿主机上清理时要加sudo。想彻底解决就启动容器时加--user $(id -u):$(id -g),但有时代价是某些需要写系统路径的步骤会失败,新手建议先老老实实用 root 容器。

3.5 传感器、串口和 USB 设备的直通

很多机器人传感器走 USB 转串口,比如雷达、IMU、下位机控制板。Docker 要访问它们,启动时显式映射设备文件:

docker run -it --rm \ --network=host \ --device=/dev/ttyUSB0 \ -v /dev:/dev \ ros:noetic-ros-base-focal \ bash

需要注意,容器内访问串口的用户权限要和宿主机一致,否则还是要手动chmod 666 /dev/ttyUSB0。摄像头可以用--device=/dev/video0。USB 设备特别多、或者想偷懒的,可以加--privileged,但这会放大容器权限,自己玩玩可以,别在生产环境这么干。

Docker 方案覆盖了 80% 的 Noetic 使用场景,尤其是纯软件仿真和算法开发。但是如果你想做电机控制、接很复杂的多传感器系统、需要 systemd 管理一堆服务,容器就会开始别扭,这时候虚拟机更痛快。

4. 虚拟机 / 系统容器:适合需要内核和硬件驱动的场景

4.1 什么时候该放弃 Docker 上虚拟机

Docker 虽然能映射设备文件,但容器和宿主机共用一个 Linux 内核。有些场景卡在这里:

  • 需要加载特定内核模块做实时控制,比如机器人运动控制里的rt_preempt补丁
  • 需要用 systemd 管理 ROS 服务和依赖,容器里没有 systemd
  • 需要频繁插拔各种 USB 设备,Docker 的设备映射要重启容器才生效,太麻烦
  • 需要和宿主机用不同内核配置,比如老驱动只认特定内核版本

遇到这些,直接在虚拟机里装一个完整的 Ubuntu 20.04,是最省脑子的做法。

4.2 装一个 20.04 虚拟机的正确姿势

我用的组合是 VirtualBox + Ubuntu 20.04.6 LTS,配 4 核 CPU、8GB 内存、动态分配的 40GB 硬盘,日常跑仿真完全够。装系统没有特别技巧,重点在于后续开发流程:

  • 网络模式选“桥接网卡”,这样虚拟机和宿主机在同一局域网段,之后 ROS 多机通信方便
  • 在虚拟机里装好 Noetic 后开启 SSH,宿主机直接用终端连过去,体验和远程服务器一样
  • 源码同步建议用 Git,别依赖共享文件夹。VirtualBox 的共享文件夹对 ROS 的符号链接不友好,经常出现链接断掉的问题

宿主机和虚拟机之间的 ROS 通信也能打通。比如在虚拟机里跑 roscore,宿主机上装一个 ROS 2 的桥接工具或干脆只当终端用。如果需要宿主机上运行 RViz 这种 GUI,最稳妥的方法是直接在虚拟机里跑 RViz,SSH 加 X11 转发也可以,但性能差不少。

4.3 LXD / Incus:介于 Docker 和 VM 之间的第二选择

Linux 自带的系统容器方案(LXD 或 Incus)也被很多人用来跑 ROS Noetic。它和 Docker 不同的地方是,每个容器更像一个轻量虚拟机,可以用 systemd,网络和存储也更接近完整系统体验。

在 Ubuntu 24.04 上创建一个 20.04 容器:

lxc launch ubuntu:20.04 noetic-20.04 lxc exec noetic-20.04 -- bash

之后在容器里按官方教程装 Noetic 就行。它比 Docker 重一点,但比虚拟机轻很多,还能方便地做设备透传。缺点是配置门槛比 Docker 高,而且系统容器和宿主机共享内核,实时补丁这类需求照样搞不定。我给它的定位是:Docker 用得不顺、又不想开重量级 VM 的折中方案。

5. 如果还能改代码:迁移到 ROS 2 Jazzy 的成本与收益

5.1 Jazzy 和 Ubuntu 24.04 是原生一对

ROS 2 Jazzy Jalisco 是官方为 Ubuntu 24.04 做的 LTS 发行版,安装方式简单粗暴:

apt install ros-jazzy-desktop

装完直接就能跑,没有 Noetic 那套“官方不支持”的悲剧。这个方案我从头到尾都是推荐的,但前提是:你手里的代码允许重写。

5.2 迁移不是“升个版本”,是换一套架构

ROS 1 和 ROS 2 的差异不是版本号数字,而是整个通信架构推倒重来。ROS 1 要 roscore 当中心节点,ROS 2 去中心化;ROS 1 用话题和服务,ROS 2 加了 QoS;ROS 1 的 launch 文件是 XML,ROS 2 默认用 Python;TF 换成了 tf2;消息生成和包管理方式也变了。哪怕写个最简单的节点,API 都不一样:

# ROS 1 风格 import rospy rospy.init_node('demo') rospy.Subscriber('/chatter', String, callback) # ROS 2 风格 import rclpy rclpy.init() node = rclpy.create_node('demo') sub = node.create_subscription(String, '/chatter', callback, 10)

如果你的项目是一个带几十个节点的完整机器人系统,迁移工作量是几周甚至几个月。但如果只是课程作业、算法验证、论文复现,重写成本通常在一两天到一周,这时候别犹豫,直接上 Jazzy。

5.3 我的决策标准,供你参考

我给自己定的规则是这样的:

场景推荐方案
只有源码,近期要做功能迭代直接迁移 ROS 2 Jazzy
依赖厂商 SDK,厂商只支持 NoeticDocker 容器跑 Noetic
老机器人硬件驱动只兼容 ROS 1虚拟机上 20.04
新手刚接触 ROS,没有历史包袱直接学 ROS 2 Jazzy,别碰 ROS 1
教材教案必须用 NoeticDocker 镜像分发给学生

这个表不是绝对标准,但能帮你快速定位。我最怕的是那种“我会 ROS 1,所以不想换”的心态。技术栈这东西,停在那就是包袱,换过去才是资产。

6. 实测经验与踩坑记录:我的最终选型路径

这篇文章看到这里,你应该已经有方向了。我再把实操中碰到的几个典型坑列出来,省得你再走一遍。

6.1 三个高频翻车点

第一个坑:Docker 容器里跑 RViz,忘记挂载 X11,结果报cannot connect to X server。这是所有容器跑 GUI 的人都会遇到的第一道坎。检查三件事:DISPLAY变量传了没,/tmp/.X11-unix挂载了没,宿主机xhost +local:执行了没。

第二个坑:容器里rosdep init失败。因为基础镜像里可能没安装python3-rosdep,或者还没apt-get update。先执行这两步,再rosdep init。别上来就一堆Unable to locate package的报错,那基本都是源没更新的问题。

第三个坑:挂载工作空间后,宿主机编辑文件,容器里catkin_make报权限错误。我之前说过,容器默认 root,产生的文件宿主删除时要 sudo。反过来也烦:宿主机的文件,容器里如果映射了非 root 用户权限不足,编译时写不进目录。最简单的处理是保持容器 root 身份,构建完用sudo chown把产物还给宿主机用户。

6.2 我自己的选型原则

最后说说我平时怎么选。做纯算法、仿真、调 RViz,我永远先开 Docker,五分钟就能进 Noetic 环境,宿主机干干净净。接机器人实物、挂一堆 USB 设备、要跑 systemd 服务,我直接开虚拟机,图个省心。项目有未来,代码量可控,我就毫不犹豫迁 ROS 2 Jazzy,哪怕花两周重写都值。

Noetic 这个东西,我感情也挺深,ROS 1 陪伴了机器人开发者整整一个时代。但时代就是会翻页,你可以用容器延长它的寿命,却不必把它焊死在每一台新电脑上。换句话讲:让老系统待在该待的地方,别让它拖住你向前走的脚步。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询