Skip to content

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 Fitzroy2020-0620.04首个 LTS(已 EOL)
Galactic Geochelone2021-0520.04已 EOL
Humble Hawksbill2022-0522.04LTS,广泛使用
Iron Irwini2023-0522.04已 EOL
Jazzy Jalisco2024-0524.04(Tier 1)、22.04LTS
Kilted Kaiju2025-0524.04非 LTS
Lyrical Luth2026-0524.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 talker

3.2 source setup.bash 到底做了什么 ​

setup.bash 是 colcon/ament 生成的 shell 脚本,核心动作:

  1. export ROS_DISTRO=jazzy。
  2. 把 /opt/ros/jazzy/bin 前插到 PATH,把 /opt/ros/jazzy/lib 前插到 LD_LIBRARY_PATH。
  3. export AMENT_PREFIX_PATH=/opt/ros/jazzy(关键!colcon 与 ros2 CLI 靠它找包)。
  4. 注册 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 -r

4.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 抢 PATHROS 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_IDDDS 域隔离(0~101)42同网络不同机器人要不同值,否则串台
ROS_LOCALHOST_ONLY仅本机通信0 / 1设 1 后跨机通信失效
ROS_AUTOMATIC_DISCOVERY_RANGE发现范围收敛LOCALHOST/SUBNET/OFFOFF 时需手动配 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/库路径会互相污染,导致 rclpy ABI 不匹配或 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
RoboStackconda 版 ROShttps://robostack.github.io/

7. 参考资料 ​

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,绝不能两套混用。