Appearance
03 安装与环境配置
在知识图谱中的位置:模块一 · 基础概念 · 03 难度:⭐⭐⭐ | 前置知识:什么是 ROS 2、基本 Linux 包管理(apt)
1. 概述
安装 ROS 2 的实质是:选对一个"发行版 ↔ 操作系统"组合,用 apt(或预编译包)装上二进制包,再让每个新 shell 正确 source 该发行版的 setup.bash 以建立环境。 环境配置(source、环境变量)是 ROS 2 上手期最高频的翻车点,理解 ROS_DISTRO 机制与 rosdep 依赖元数据是走向工程化的第一道门槛。
2. 核心概念
2.1 发行版与 Ubuntu 版本强绑定
ROS 2 每个发行版只支持特定 Ubuntu LTS 版本(二进制包层面),选错组合 apt 会直接找不到包:
| 发行版 | 发布时间 | 支持的 Ubuntu(二进制) | 说明 |
|---|---|---|---|
| Foxy Fitzroy | 2020-06 | 20.04 | 首个 LTS(已 EOL) |
| Galactic Geochelone | 2021-05 | 20.04 | 已 EOL |
| Humble Hawksbill | 2022-05 | 22.04 | LTS,广泛使用 |
| Iron Irwini | 2023-05 | 22.04 | 已 EOL |
| Jazzy Jalisco | 2024-05 | 24.04(Tier 1)、22.04 | LTS |
| Kilted Kaiju | 2025-05 | 24.04 | 非 LTS |
| Lyrical Luth | 2026-05 | 24.04(预计) | 最新 |
| Rolling | 滚动 | 跟随最新 | 不冻结 |
表中"Tier"指 REP-2000 定义的平台支持等级;Jazzy 同时提供 22.04/24.04 二进制,24.04 为一等公民。具体以官方发布页为准。
2.2 setup.bash 与 ROS_DISTRO
ROS 2 安装后,环境是通过 source 脚本注入的,而不是"装上就能用":
/opt/ros/<distro>/setup.bash:设置ROS_DISTRO、把 ROS 2 的 bin/lib 加入PATH/LD_LIBRARY_PATH、激活 colcon 补全等。ROS_DISTRO:标识当前激活的发行版(如jazzy)。谁被最后 source,谁生效——在一个 shell 里先后 source 两个发行版,后者覆盖前者。
2.3 rosdep:跨发行版的依赖元数据
rosdep 把"包名 → 各系统安装命令"的映射做成独立数据库:
rosdep init:创建/etc/ros/rosdep/sources.list.d/20-default.list,指向官方规则源。rosdep update:下载规则到用户目录,供后续rosdep install查询。
它的意义是把 package.xml 里的依赖声明翻译成 apt install ... 等本机命令,做到"源码包在不同平台都能装依赖"。
3. 技术原理
3.1 apt 安装流程(Ubuntu)
bash
# 1) 确认系统与发行版匹配(Jazzy → 24.04/22.04)
lsb_release -a
# 2) 添加 ROS 2 软件源(先配仓库与 GPG key,用 Debian 官方源方式)
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" \
| sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
# 3) 安装
sudo apt update
sudo apt install ros-jazzy-desktop # 完整版(含 rviz2);轻量用 ros-jazzy-ros-base
# 4) 使环境生效(每个新终端都要,或写入 ~/.bashrc)
source /opt/ros/jazzy/setup.bash
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
# 5) 验证
ros2 run demo_nodes_cpp talker3.2 source setup.bash 到底做了什么
setup.bash 是 colcon/ament 生成的 shell 脚本,核心动作:
export ROS_DISTRO=jazzy。- 把
/opt/ros/jazzy/bin前插到PATH,把/opt/ros/jazzy/lib前插到LD_LIBRARY_PATH。 export AMENT_PREFIX_PATH=/opt/ros/jazzy(关键!colcon 与 ros2 CLI 靠它找包)。- 注册 shell 补全函数。
失败模式:不 source 就 ros2 → command not found;source 错了发行版 → 装的包与 ROS_DISTRO 不一致,ros2 run 报"找不到包/库不匹配"。
3.3 源码级证据:AMENT_PREFIX_PATH 是包查找的根
ros2 CLI 与 colcon 通过 AMENT_PREFIX_PATH(冒号分隔的前缀列表)遍历每个前缀下的 share/ament_index/resource_index/ 索引来发现包。rclcpp 启动时也依赖 ament_index_cpp::get_package_prefix() 定位资源。多工作区叠加时,AMENT_PREFIX_PATH 靠 "underlay → overlay" 的 source 顺序决定优先级,后 source 的 overlay 覆盖 underlay。
4. 实践指南
4.1 rosdep 初始化与依赖安装
bash
sudo apt install python3-rosdep
sudo rosdep init # 只需一次
rosdep update # 建议定期更新规则
# 在工作区根目录装依赖:逐参数解释见 04 工作空间文档
rosdep install -y --from-paths src --ignore-src -r4.2 最佳实践
- 把
source写进~/.bashrc,但要注释注明发行版,避免日后混装两个发行版互相覆盖。 - 用
printenv ROS_DISTRO AMENT_PREFIX_PATH快速自查当前激活环境。 - 一台机器装多个发行版时,用不同终端或
ros2 env检查,别在同一个 shell 里来回 source。 - 生产环境固定
ROS_DOMAIN_ID,用/etc/environment或 systemd unit 注入,别散落在各自.bashrc。
4.3 常见陷阱(conda / broken 环境)
| 坑 | 现象 | 解法 |
|---|---|---|
| conda 的 Python 抢 PATH | ROS 2 报 ImportError: No module named rclpy 或 ABI 不匹配 | conda deactivate 后再 source ROS 2;或改用 conda 装的 ros 包(RoboStack),别混用 |
混装两个发行版且都写进 .bashrc | 环境变量指向错乱 | 只 source 一个;多发行版用独立脚本按需激活 |
rosdep init 报 /etc/ros 已存在 | 重复初始化 | 该步只需一次,跳过即可 |
rosdep update 网络失败 | 规则下不完整 | 重试 / 换镜像 / 确认代理 |
| apt 装错发行版代号 | Unable to locate package ros-jazzy-* | 核对 lsb_release 与发行版支持表 |
4.4 平台差异注意事项
- Windows:官方提供预编译二进制(zip 解压 + Chocolatey
choco install ros-jazzy-desktop),以及源码编译两种路线。预编译包无需本地编译、上手快;源码编译需 Visual Studio + Python + 大量依赖,用于定制 RMW 或调试。⚠️windows.ros.org这一独立站点来源待验证,官方入口以 https://docs.ros.org/en/jazzy/Installation/Windows-Install-Binary.html 为准。 - macOS:无官方二进制包,需源码编译或使用 conda-forge 的 RoboStack;编译门槛高、DDS 实时性弱,通常只用于开发/教学。
- Linux(Ubuntu):最省事,apt 二进制 + 完整实时性路径(PREEMPT_RT + rmw_cyclonedds)。
4.5 环境变量速查表
| 环境变量 | 含义 | 取值示例 | 典型坑 |
|---|---|---|---|
ROS_DISTRO | 当前发行版 | jazzy | 被最后 source 的 setup 覆盖 |
RMW_IMPLEMENTATION | 选择通信后端 | rmw_cyclonedds / rmw_fastrtps | 不同进程必须用同一 RMW 才能互通 |
ROS_DOMAIN_ID | DDS 域隔离(0~101) | 42 | 同网络不同机器人要不同值,否则串台 |
ROS_LOCALHOST_ONLY | 仅本机通信 | 0 / 1 | 设 1 后跨机通信失效 |
ROS_AUTOMATIC_DISCOVERY_RANGE | 发现范围收敛 | LOCALHOST/SUBNET/OFF | OFF 时需手动配 peers |
AMENT_PREFIX_PATH | 包查找前缀 | /opt/ros/jazzy | 顺序决定 underlay/overlay 覆盖 |
ROS_LOG_LEVEL | 日志级别 | debug/info/warn/error/fatal | 设太低会漏掉关键诊断 |
5. 方案对比
| 方案 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| apt 二进制(Ubuntu) | 一键、稳定、实时路径完整 | 版本锁定、不可自定义 RMW 编译选项 | 主流开发/生产 |
| 源码编译 | 可定制 RMW/调试符号 | 耗时、易错 | 内核/中间件定制 |
| Windows 预编译 | 上手快 | 无硬实时、生态工具少 | 开发/仿真 |
| RoboStack(conda) | 跨平台统一、隔离好 | 与系统 apt 混用易冲突 | 跨平台/CI |
在什么场景下绝对不能使用:绝不能在一台机器上混用"apt 装的 ROS 2"与"conda 装的 ROS 2"并同时 source——两套 Python/库路径会互相污染,导致
rclpyABI 不匹配或 Segfault;同理,绝不能把不同发行版的setup.bash同时写进一个 shell 的.bashrc并期望它们"共存",实际是后者覆盖前者。
6. 工具链
| 工具 | 用途 | 链接 |
|---|---|---|
| rosdep | 依赖元数据与安装 | https://docs.ros.org/en/jazzy/Tutorials/Intermediate/Rosdep.html |
| vcstool | 批量管理多仓库源码 | https://github.com/dirk-thomas/vcstool |
| ros2 CLI | 环境/节点/话题操作 | https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools.html |
| RoboStack | conda 版 ROS | https://robostack.github.io/ |
7. 参考资料
- Ubuntu 二进制安装(Jazzy):https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html ✅已验证
- Windows 二进制安装:https://docs.ros.org/en/jazzy/Installation/Windows-Install-Binary.html ✅已验证
- 发布/发行版总览:https://docs.ros.org/en/rolling/Get-Started/Releases.html ✅已验证
- Kilted Kaiju 发布说明:https://docs.ros.org/en/rolling/Releases/Release-Kilted-Kaiju.html ✅已验证
- Jazzy Jalisco 发布博客:https://www.openrobotics.org/blog/2024/5/ros-jazzy-jalisco-released ✅已验证
- rosdistro 源(含 ros.key 与发行版元数据):https://github.com/ros/rosdistro ✅已验证
- RoboStack:https://robostack.github.io/ ✅已验证
windows.ros.org独立站点:⚠️ 来源待验证(官方 Windows 安装入口在 docs.ros.org)
8. 学习路径
- Level 1:在匹配的 Ubuntu 上用 apt 装好 Jazzy,跑通 talker/listener。
- Level 2:理解
source setup.bash与ROS_DISTRO/AMENT_PREFIX_PATH,能排查command not found。 - Level 3:掌握
rosdep init/update/install,从源码工作区装依赖。 - Level 4:用
RMW_IMPLEMENTATION/ROS_DOMAIN_ID做跨机、跨 RMW 实验。 - Level 5:自建 overlay 工作区 + 定制 RMW 编译,沉淀团队环境标准化脚本。
9. 核心面试三问
Q1:source /opt/ros/jazzy/setup.bash 到底改了什么?为什么新开终端就失效?
参考要点:它是 shell 脚本,导出 ROS_DISTRO、AMENT_PREFIX_PATH,把 ROS 2 的 bin/lib 前插到 PATH/LD_LIBRARY_PATH,并注册补全。这些是当前 shell 进程的导出变量,不持久化;新终端是独立进程,所以失效,需写入 ~/.bashrc 自动执行。
Q2:两台机器 ROS_DOMAIN_ID 相同且网络互通会发生什么?怎么隔离?
参考要点:它们会进入同一个 DDS 域,互相发现并可能订阅到对方话题,导致"串台"(机器人 A 收到 B 的指令/数据)。隔离靠:设不同 ROS_DOMAIN_ID;或用 ROS_LOCALHOST_ONLY=1 限本机;或 ROS_AUTOMATIC_DISCOVERY_RANGE + partition 收敛。
Q3:conda 激活状态下跑 ROS 2 出现 ImportError: No module named rclpy,根因是什么?
参考要点:conda 把自己的 Python 与 site-packages 前插到 PATH/PYTHONPATH,导致 ros2 脚本用错了 Python 解释器或找不到 /opt/ros/.../local/lib/python*/dist-packages 里的 rclpy,或版本/ABI 不匹配。解法:先 conda deactivate 回到系统 Python 再 source ROS 2,或统一走 RoboStack 的 conda 版 ROS,绝不能两套混用。