先在 Docker 中走一遍流程
0. 创建docker 容器
bash
sudo docker run -it \
--name ros2_01 \
-v /home/jimmy/ex_ros2/tmp01:/root/tmp01 \
ubuntu:22.04
# 进入 docker 容器后执行
apt update && \
apt install --reinstall ca-certificates && \
update-ca-certificates --fresh
如果机器内有 nvidia 的 image,可以这么启动:
bash
sudo docker run --gpus all -it \
--name ros2_01 \
-v /home/jimmy/ex_ros2/tmp1:/root/tmp1 \
-v /home/jimmy/.ssh:/root/.ssh \
nvidia/cuda:12.6.3-devel-ubuntu22.04
sudo docker attach <容器名或容器ID>
sudo docker exec -it <容器名或容器ID> /bin/bash
sudo docker exec -it ros2_01 /bin/bash
1. Ubuntu 22.04 从源码编译安装 ROS 2 Jazzy 全过程记录
参考官方文档:
记录时间:2026-08-20
1.0. 背景与关键决策
| 项目 | 说明 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS (Jammy Jellyfish),x86_64 |
| ROS 2 发行版 | Jazzy Jalisco(LTS,支持至 2029-05) |
| 平台支持级别 | Jazzy 的 Tier 1 平台是 Ubuntu 24.04 (Noble);Ubuntu 22.04 (Jammy) 为 Tier 3(可源码编译,官方文档明确列出,但需留意个别依赖版本) |
| 硬件 | 256 核 CPU / 566 GB 内存 |
| 安装位置 | ~/ros2_jazzy(即 /root/ros2_jazzy,遵循官方文档的目录约定) |
| 源码集合 | ros2.repos(jazzy 分支),共 108 个 git 仓库、366 个 colcon 软件包(即 ROS 2 核心 + 常用工具 + 示例,不含完整 desktop 中的大型 GUI 附加包) |
最终构建结果:366 个软件包全部编译成功(耗时 12 分 11 秒),talker/listener 验证通过。
1.1. 环境准备检查
bash
cat /etc/os-release # 确认 Ubuntu 22.04
curl -sI https://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos
curl -sI http://packages.ros.org/ros2/ubuntu/dists/jammy/Release
作用 :确认系统版本与网络连通性。后续步骤依赖三类外部资源:Ubuntu 官方 apt 源(系统依赖)、GitHub(ROS 2 源码与 colcon mixin)、packages.ros.org(ROS 2 apt 源,提供 ros-dev-tools 等构建工具)。
1.2. 设置 locale(UTF-8)
bash
apt update && apt install -y locales
locale-gen en_US en_US.UTF-8
update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale # 验证
作用 :ROS 2 官方文档要求系统使用 UTF-8 编码。默认的 POSIX locale 会导致 ROS 2 命令行工具(ros2cli)及部分 Python 包在处理文本输出时出现编码错误。此步骤生成并启用 en_US.UTF-8。
1.3. 启用 universe 仓库并添加 ROS 2 apt 源
bash
apt install -y software-properties-common
add-apt-repository universe # 启用 Ubuntu universe 组件
apt update && apt install -y curl
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.jammy_all.deb"
dpkg -i /tmp/ros2-apt-source.deb
作用:
- ROS 2 的大量系统依赖(如
python3-flake8-*、各种lib*-dev)位于 Ubuntu 的 universe 组件中,需先启用。 - 虽然 ROS 2 本体要从源码编译,但构建工具链 (colcon、vcs、rosdep、bloom 等)仍需通过 apt 安装。
ros2-apt-source是新版官方推荐的仓库配置方式:一个 deb 包同时完成 GPG keyring 安装与/etc/apt/sources.list.d/ros2.sources源配置(取代了旧版手动curl密钥 + 手写 sources.list 的方式)。 - 本次安装的版本为
ros2-apt-source 1.2.0~jammy。
1.4. 系统更新 + 安装开发工具
bash
apt update && apt upgrade -y # 文档特别警告:避免"系统库过旧 vs rosdep 依赖过新"的 ABI 错配
apt install -y \
python3-flake8-blind-except \
python3-flake8-class-newline \
python3-flake8-deprecated \
python3-mypy \
python3-pip \
python3-pytest \
python3-pytest-cov \
python3-pytest-mock \
python3-pytest-repeat \
python3-pytest-rerunfailures \
python3-pytest-runner \
python3-pytest-timeout \
ros-dev-tools
作用:
ros-dev-tools是 ROS 官方元包(metapackage),一次性拉入源码构建所需的整套工具链:colcon (构建工具)、vcs (多仓库管理)、rosdep(依赖解析安装)、bloom(打包)、编译器/CMake/git 等。python3-flake8-*/python3-pytest-*/python3-mypy:ROS 2 各软件包在package.xml中声明的测试/代码检查依赖,rosdep 阶段会校验它们是否已存在;提前按文档装好可避免遗漏。- 安装后关键工具版本:GCC 11.4.0、CMake 3.22.1、Python 3.10.12、colcon-core 0.21.0、vcs 0.3.0、rosdep 0.26.0。
1.5. 创建工作空间并拉取 ROS 2 全部源码
bash
mkdir -p ~/ros2_jazzy/src
cd ~/ros2_jazzy
vcs import --workers 16 --input https://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos src
作用:
- ROS 2 不是单一仓库,而是由
ros2.repos清单文件描述的 108 个独立 git 仓库 (rclcpp、rclpy、Fast DDS、rmw、rosbag2、urdf、示例等)。vcs import按清单批量克隆到src/下,并自动检出 jazzy 分支。 --workers 16为并行克隆加速(非文档必需参数)。- 完成后
src/约 670 MB,colcon 识别出 366 个软件包。 - 工作空间采用标准 colcon 布局:
src/(源码)、build/(中间产物)、install/(安装结果)、log/(构建日志)。
注:
ros2.repos对应的是 "ROS 2 核心 + 常用工具" 集合;如需 RViz 之外的更多 desktop 组件,可额外导入。本次按官方文档使用默认ros2.repos。
1.6. 使用 rosdep 安装依赖
bash
rosdep init # 初始化(仅首次,生成 /etc/ros/rosdep/sources.list.d/20-default.list)
rosdep update # 拉取最新 rosdep 规则数据库
rosdep install --from-paths src --ignore-src -y \
--skip-keys "fastcdr rti-connext-dds-6.0.1 urdfdom_headers"
作用:
rosdep遍历src/下每个软件包package.xml中声明的<depend>/<build_depend>等,映射为 Ubuntu 系统包名并批量 apt 安装(本次共安装了 libasio-dev、libssl-dev、libsqlite3-dev、libbullet-dev、libassimp-dev、liborocos-kdl-dev、Qt5 相关库、lttng 等上百个依赖),最终输出All required rosdeps installed successfully。--from-paths src:以源码目录为输入;--ignore-src:忽略"将由源码自行构建"的包(避免把 ROS 包本身当作 apt 依赖安装)。--skip-keys跳过三个键(官方文档固定写法):fastcdr、urdfdom_headers:已包含在ros2.repos中,将由源码一起编译;rti-connext-dds-6.0.1:商业 DDS,需付费许可,默认不用(ROS 2 默认中间件为开源的 Fast DDS)。
Tier 3 平台敏感点核查(Jazzy on Jammy 的已知风险项,全部通过):
| 依赖 | 要求 | 实际 | 说明 |
|---|---|---|---|
| empy | 必须 3.3.x | 3.3.4 ✅ | empy 4.x 会破坏接口文件生成(rosidl) |
| lark | ≥ 1.1 | 1.1.1 ✅ | launch 前端解析 |
| catkin_pkg | ≥ 1.0 | 1.1.0 ✅ | package.xml 解析 |
| numpy | --- | 1.21.5 ✅ | Python 3.10 配套 |
1.7. 配置 colcon mixin
bash
colcon mixin add default https://github.com/colcon/colcon-mixin-repository/raw/master/index.yaml
colcon mixin update default
作用 :mixin 是 colcon 的命令行参数预设集。注册官方 mixin 仓库后即可使用 --mixin release 等快捷方式(release mixin 等价于传入 --cmake-args -DCMAKE_BUILD_TYPE=Release 等优化参数),免去手写冗长参数。
1.8. 编译整个工作空间
bash
cd ~/ros2_jazzy/
# 文档警告:确保环境干净------没有 source 过任何其他 ROS 安装
printenv | grep -i ROS # 输出应为空(已验证为空)
colcon build --symlink-install --mixin release
作用:
colcon build:按依赖拓扑顺序编译全部 366 个软件包(ament_cmake/ament_python 构建体系),结果安装到install/。--symlink-install:尽量以符号链接方式安装(尤其 Python 包),改源码后无需完全重新安装,便于二次开发------官方文档推荐的开发者模式。--mixin release:以 Release 模式编译(-O2优化,无调试符号,运行更快)。
构建结果:
Summary: 366 packages finished [12min 11s]
11 packages had stderr output: cyclonedds foonathan_memory_vendor
google_benchmark_vendor iceoryx_posh lttngpy point_cloud_transport_py
qt_gui_cpp rclpy rosbag2_py test_tracetools zstd_vendor
- 退出码 0,366/366 全部成功(256 核并行,总耗时 12 分 11 秒)。
- 11 个包有 stderr 输出:均为编译器警告/第三方库提示(如 vendor 包、Qt 相关),非错误,不影响使用------这在上游 CI 中也属常见现象。
磁盘占用:src/ 670 MB,build/ 3.7 GB,install/ 259 MB,log/ 106 MB。
1.9. 配置环境变量并验证
bash
source ~/ros2_jazzy/install/local_setup.bash
作用 :source 该脚本会把 install/ 下的 bin、lib、share 及 Python 路径注入当前 shell 的 PATH / LD_LIBRARY_PATH / PYTHONPATH / AMENT_PREFIX_PATH 等环境变量,使 ros2 命令可用。local_setup.bash 只叠加当前工作空间;setup.bash 还会级联其底层依赖环境(源码单工作空间场景二者等效)。
验证:
bash
$ echo $ROS_DISTRO # → jazzy
$ ros2 pkg list | wc -l # → 351
# 终端 1(C++ 发布者)
$ ros2 run demo_nodes_cpp talker
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
...
# 终端 2(Python 订阅者)
$ ros2 run demo_nodes_py listener
[INFO] [listener]: I heard: [Hello World: 3]
[INFO] [listener]: I heard: [Hello World: 4]
...
✅ talker 发布、listener 收到相同消息 ------ 官方文档判定标准达成,C++ API(rclcpp)与 Python API(rclpy)均工作正常,默认 RMW(Fast DDS)通信正常。
1.10. 日常使用与维护
每次新开终端使用 ROS 2:
bash
source ~/ros2_jazzy/install/local_setup.bash
(可选)写入 .bashrc 自动加载:
bash
echo "source ~/ros2_jazzy/install/local_setup.bash" >> ~/.bashrc
注意:官方文档提醒------若之后还要再次编译 该工作空间,请先确保当前 shell 没有 source 任何 ROS 环境(
printenv | grep -i ROS应为空),避免新旧产物互相干扰。
保持源码更新(对应文档 Maintaining-a-Source-Checkout):
bash
cd ~/ros2_jazzy
vcs pull src # 拉取各仓库更新
rosdep install --from-paths src --ignore-src -y --skip-keys "fastcdr rti-connext-dds-6.0.1 urdfdom_headers"
colcon build --symlink-install --mixin release
卸载:源码安装不写系统目录,直接删除整个工作空间即可:
bash
rm -rf ~/ros2_jazzy
1.11. 过程总结
| # | 步骤 | 命令核心 | 作用 |
|---|---|---|---|
| 1 | locale | locale-gen en_US.UTF-8 |
满足 ROS 2 对 UTF-8 编码的要求 |
| 2 | 仓库 | add-apt-repository universe + ros2-apt-source deb |
启用依赖来源;安装 ROS 官方 apt 源(提供构建工具) |
| 3 | 工具链 | apt install ros-dev-tools ... |
安装 colcon/vcs/rosdep 及代码检查工具 |
| 4 | 源码 | vcs import ... ros2.repos src |
批量克隆 108 个仓库(366 包) |
| 5 | 依赖 | rosdep init/update/install |
按 package.xml 自动安装全部系统依赖 |
| 6 | 预设 | colcon mixin add/update default |
注册构建参数预设(release 等) |
| 7 | 编译 | colcon build --symlink-install --mixin release |
Release 模式编译并安装到 install/ |
| 8 | 验证 | source install/local_setup.bash + talker/listener |
注入环境变量;验证 C++/Python 通信 |
整个流程与官方文档 Ubuntu (source) 完全一致。尽管 Jazzy 在 Ubuntu 22.04 上属于 Tier 3 平台,实践中未遇到任何阻塞性问题,一次构建即全部成功。
2. 自动编译脚本
bash
#!/usr/bin/env bash
#===============================================================================
# build_ros2_jazzy_ubuntu2204.sh
#
# 在"几乎空白"的 Ubuntu 22.04 (Jammy) 上,从源码自动编译并安装 ROS 2 Jazzy。
# 流程严格遵循官方文档:
# https://docs.ros.org/en/jazzy/Installation/Alternatives/Ubuntu-Development-Setup.html
#
# 用法:
# bash build_ros2_jazzy_ubuntu2204.sh
#
# 可选环境变量:
# WORKSPACE=/path/to/ws 工作空间目录(默认 ~/ros2_jazzy)
# VCS_WORKERS=16 vcs 并行克隆线程数(默认 16)
# RUN_DEMO_TEST=0 设为 0 跳过构建后的 talker/listener 自动验证(默认 1)
#
# 特性:
# - root / 普通用户(需 sudo)均可运行
# - 幂等:重复运行不会出错(已装组件自动跳过或更新)
# - 全流程日志,失败即停(set -euo pipefail)
#===============================================================================
set -euo pipefail
#----------------------------- 可配置变量 --------------------------------------
ROS_DISTRO="${ROS_DISTRO:-jazzy}"
WORKSPACE="${WORKSPACE:-$HOME/ros2_${ROS_DISTRO}}"
REPOS_URL="https://raw.githubusercontent.com/ros2/ros2/${ROS_DISTRO}/ros2.repos"
VCS_WORKERS="${VCS_WORKERS:-16}"
# 官方文档固定的跳过键:fastcdr/urdfdom_headers 由源码构建;RTI Connext 为商业 DDS
SKIP_KEYS="fastcdr rti-connext-dds-6.0.1 urdfdom_headers"
RUN_DEMO_TEST="${RUN_DEMO_TEST:-1}"
#----------------------------- 工具函数 ----------------------------------------
log() { echo -e "\n\033[1;32m==================================================================\033[0m"
echo -e "\033[1;32m[$(date '+%F %T')] $*\033[0m"
echo -e "\033[1;32m==================================================================\033[0m"; }
info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $*" >&2; exit 1; }
# root 则直接执行,否则使用 sudo
if [ "$(id -u)" -eq 0 ]; then SUDO=""; else SUDO="sudo"; fi
export DEBIAN_FRONTEND=noninteractive
# 基本环境检查
[ -f /etc/os-release ] || die "无法识别操作系统"
. /etc/os-release
[ "${ID}" = "ubuntu" ] || die "本脚本仅适用于 Ubuntu(当前:${ID})"
info "目标系统:${PRETTY_NAME} | ROS 发行版:${ROS_DISTRO} | 工作空间:${WORKSPACE}"
#===============================================================================
# 步骤 1/8:设置 locale (UTF-8)
# 作用:ROS 2 要求 UTF-8 编码,否则 ros2cli 及部分 Python 包会出编码错误
#===============================================================================
log "步骤 1/8:设置 locale (en_US.UTF-8)"
$SUDO apt update
$SUDO apt install -y locales
$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
locale | head -3
#===============================================================================
# 步骤 2/8:启用 universe 仓库 + 添加 ROS 2 apt 源
# 作用:universe 提供大量系统依赖;ROS 2 apt 源提供 ros-dev-tools 构建工具链
# (官方推荐的 ros-apt-source deb 包:一次完成 GPG keyring + sources 配置)
#===============================================================================
log "步骤 2/8:启用 universe 并添加 ROS 2 apt 源"
$SUDO apt install -y software-properties-common curl
$SUDO add-apt-repository -y universe
ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest \
| grep -F "tag_name" | awk -F\" '{print $4}')
if [ -n "${ROS_APT_SOURCE_VERSION}" ]; then
info "安装 ros2-apt-source ${ROS_APT_SOURCE_VERSION} (${VERSION_CODENAME})"
curl -sL -o /tmp/ros2-apt-source.deb \
"https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.${VERSION_CODENAME}_all.deb"
$SUDO dpkg -i /tmp/ros2-apt-source.deb
elif [ -f /etc/apt/sources.list.d/ros2.sources ] || [ -f /etc/apt/sources.list.d/ros2.list ]; then
info "无法获取 ros-apt-source 最新版本号,但 ROS 2 apt 源已存在,跳过"
else
die "无法获取 ros-apt-source 版本号,且本机未配置 ROS 2 apt 源(检查网络)"
fi
#===============================================================================
# 步骤 3/8:系统更新 + 安装开发工具与 ros-dev-tools
# 作用:apt upgrade 避免系统库与依赖 ABI 错配(文档明确警告);
# ros-dev-tools 元包拉入 colcon / vcs / rosdep / 编译器等整套工具链;
# flake8/pytest/mypy 为各 ROS 包声明的测试依赖,提前装好
#===============================================================================
log "步骤 3/8:系统更新并安装开发工具 (ros-dev-tools)"
$SUDO apt update
$SUDO apt upgrade -y
$SUDO apt install -y \
python3-flake8-blind-except \
python3-flake8-class-newline \
python3-flake8-deprecated \
python3-mypy \
python3-pip \
python3-pytest \
python3-pytest-cov \
python3-pytest-mock \
python3-pytest-repeat \
python3-pytest-rerunfailures \
python3-pytest-runner \
python3-pytest-timeout \
ros-dev-tools
info "工具版本:$(gcc --version | head -1) | $(cmake --version | head -1) | $(python3 --version)"
#===============================================================================
# 步骤 4/8:创建工作空间并用 vcs 拉取 ROS 2 全部源码
# 作用:ros2.repos 清单描述 ~108 个 git 仓库,vcs 批量克隆到 src/(幂等)
#===============================================================================
log "步骤 4/8:拉取 ROS 2 ${ROS_DISTRO} 源码 -> ${WORKSPACE}/src"
mkdir -p "${WORKSPACE}/src"
cd "${WORKSPACE}"
vcs import --workers "${VCS_WORKERS}" --input "${REPOS_URL}" src
REPO_COUNT=$(find src -maxdepth 3 -name ".git" -type d | wc -l)
PKG_COUNT=$(colcon list --base-paths src | wc -l)
info "共 ${REPO_COUNT} 个仓库 / ${PKG_COUNT} 个软件包"
[ "${PKG_COUNT}" -gt 0 ] || die "未发现任何软件包,源码拉取失败"
#===============================================================================
# 步骤 5/8:rosdep 安装依赖
# 作用:解析每个包 package.xml 的依赖声明并批量 apt 安装;
# --ignore-src 跳过将由源码构建的包;--skip-keys 见变量注释
#===============================================================================
log "步骤 5/8:rosdep 安装全部系统依赖"
if [ ! -f /etc/ros/rosdep/sources.list.d/20-default.list ]; then
$SUDO rosdep init # 仅首次需要
else
info "rosdep 已初始化,跳过 rosdep init"
fi
rosdep update
rosdep install --from-paths src --ignore-src -y --skip-keys "${SKIP_KEYS}"
#===============================================================================
# 步骤 6/8:配置 colcon mixin
# 作用:注册官方参数预设仓库,之后可用 --mixin release(= Release 编译参数)
#===============================================================================
log "步骤 6/8:配置 colcon mixin"
colcon mixin add default \
https://github.com/colcon/colcon-mixin-repository/raw/master/index.yaml 2>/dev/null || true
colcon mixin update default
#===============================================================================
# 步骤 7/8:编译整个工作空间
# --symlink-install:符号链接安装,便于二次开发;--mixin release:-O2 优化
# 文档要求:构建环境必须是"干净"的(未 source 任何 ROS 安装)
#===============================================================================
log "步骤 7/8:colcon build --symlink-install --mixin release"
if printenv | grep -qi '^ROS_'; then
die "检测到已加载的 ROS 环境变量(printenv | grep ROS),请在未 source ROS 的干净 shell 中运行"
fi
cd "${WORKSPACE}"
colcon build --symlink-install --mixin release
#===============================================================================
# 步骤 8/8:验证(C++ talker + Python listener 跨语言通信)
#===============================================================================
log "步骤 8/8:验证安装"
if [ "${RUN_DEMO_TEST}" = "1" ]; then
# colcon 生成的 setup 脚本会引用未定义变量(如 COLCON_CURRENT_PREFIX),
# 与 set -u 不兼容,source 期间需临时关闭
set +u
# shellcheck disable=SC1091
source "${WORKSPACE}/install/local_setup.bash"
set -u
info "ROS_DISTRO=${ROS_DISTRO},已安装软件包数量:$(ros2 pkg list | wc -l)"
TALKER_LOG=$(mktemp) LISTENER_LOG=$(mktemp)
ros2 run demo_nodes_cpp talker >"${TALKER_LOG}" 2>&1 &
TALKER_PID=$!
sleep 2
# listener 收 15 秒后由 timeout 结束(退出码 124 属预期)
timeout 15 ros2 run demo_nodes_py listener >"${LISTENER_LOG}" 2>&1 || true
kill "${TALKER_PID}" 2>/dev/null || true
sleep 1
echo "----- talker 输出(前 3 行)-----"; head -3 "${TALKER_LOG}" || true
echo "----- listener 输出(前 3 行)-----"; head -3 "${LISTENER_LOG}" || true
if grep -q "I heard" "${LISTENER_LOG}"; then
info "✅ 验证通过:listener 收到 talker 消息(C++ 与 Python API 均正常)"
else
die "验证失败:listener 未收到消息,请检查 ${LISTENER_LOG}"
fi
rm -f "${TALKER_LOG}" "${LISTENER_LOG}"
else
info "RUN_DEMO_TEST=0,跳过自动验证"
fi
log "全部完成!ROS 2 ${ROS_DISTRO} 已安装到 ${WORKSPACE}/install"
echo -e "\033[1;33m使用方法(每个新终端执行一次):\033[0m"
echo " source ${WORKSPACE}/install/local_setup.bash"
echo -e "\033[1;33m可选(写入 .bashrc 自动加载):\033[0m"
echo " echo \"source ${WORKSPACE}/install/local_setup.bash\" >> ~/.bashrc"
3. ROS 2 安装验证方法
适用对象:在 Ubuntu 22.04 上从源码编译的 ROS 2 Jazzy(
~/ros2_jazzy),同样适用于其他安装方式/发行版。所有命令均已在本机实测通过(2026-08-20)。
验证由浅入深分为 5 个层次。日常安装后做 <1> + <3> + <4> 即可(秒级完成);CI 或交付验收场景追加 <5>。
< 1.> 环境层 ------ 确认环境变量注入正确
bash
source ~/ros2_jazzy/install/local_setup.bash
printenv | grep -iE "^(ROS_|AMENT_|COLCON)"
which ros2
实测输出(关键项):
ROS_DISTRO=jazzy
ROS_VERSION=2
ROS_PYTHON_VERSION=3
AMENT_PREFIX_PATH=/root/ros2_jazzy/install/rqt_bag_plugins:...(每个包一个前缀)
COLCON_PREFIX_PATH=/root/ros2_jazzy/install
ROS_AUTOMATIC_DISCOVERY_RANGE=SUBNET # Jazzy 新增:DDS 自动发现范围限制在子网内
$ which ros2
/root/ros2_jazzy/install/ros2cli/bin/ros2
解释 :源码安装不写系统目录,ros2 之所以可用,全靠 source 脚本注入环境变量------
AMENT_PREFIX_PATH:ament 资源索引的搜索路径,ros2 pkg等命令靠它发现软件包;PATH/LD_LIBRARY_PATH/PYTHONPATH:分别覆盖可执行文件、动态链接库、Python 模块。
反向利用:没 source 的终端里 ros2 命令应不存在 ------官方文档在编译前要求 printenv | grep -i ROS 输出为空,正是用这一点确认构建环境干净。
< 2.> 包管理层 ------ 确认所有包被正确安装与索引
bash
ros2 pkg list | wc -l # 实测:351
ros2 pkg list | grep -E "^(rclcpp|rclpy)$" # 抽查关键包
ros2 pkg executables demo_nodes_cpp # 查看某包的可执行文件
解释 :ros2 pkg 系列命令通过 ament index 扫描 AMENT_PREFIX_PATH 下每个包的注册信息。包数量符合预期,说明安装产物完整、索引未损坏。若某包编译时"假装成功"但安装产物缺失,会在这里暴露。
< 3.> 诊断层 ------ 官方一体化体检
bash
ros2 doctor # 快速检查
ros2 doctor --report # 完整报告(版本、平台、网络、RMW、话题等)
实测输出:
All 5 checks passed
解释 :ros2 doctor(ros2doctor 包)自动检查 ROS 版本与平台匹配、网络 loopback/多播、DDS 中间件配置、话题健康度(如"有发布者无订阅者")等,按 WARN/ERROR 分级提示。
真实插曲 :本机第一次运行
ros2 doctor时警告Publisher without subscriber detected on /chatter。排查发现是自动化脚本早期版本的 bug------kill只杀掉了ros2 run的 Python 包装器,真正的 talker 子进程变成孤儿残留(pgrep -af talker可见)。这正体现了诊断工具的价值:暴露"安装成功但环境脏"的问题 。脚本已修复为pkill -P <包装器PID>先杀子进程,再杀包装器(修复后实测无残留)。
< 4.> 通信层 ------ 官方最终判据:端到端 DDS 通信
官方文档标准做法(跨语言):
bash
# 终端 1(C++ 发布者)
source ~/ros2_jazzy/install/local_setup.bash
ros2 run demo_nodes_cpp talker
# [INFO] [talker]: Publishing: 'Hello World: 1' ...
# 终端 2(Python 订阅者)
source ~/ros2_jazzy/install/local_setup.bash
ros2 run demo_nodes_py listener
# [INFO] [listener]: I heard: [Hello World: 1] ...
等价的无侵入式 CLI 验证(起一个 talker 后在另一终端执行,实测输出):
$ ros2 node list
/talker
$ ros2 topic list
/chatter /parameter_events /rosout
$ ros2 topic info /chatter
Type: std_msgs/msg/String
Publisher count: 1
Subscription count: 0
$ ros2 topic echo /chatter --once
data: 'Hello World: 7'
$ ros2 topic hz /chatter
average rate: 1.000
min: 0.999s max: 1.001s std dev: 0.00082s window: 3
解释 :这是官方文档把 talker/listener 作为安装最终判定标准的原因------C++ 发布、Python 收到连续递增的消息,证明整条链路编译、链接、运行全部正确:
rosidl 消息接口生成 → rclcpp(C++)/rclpy(Python) → rcl 客户端库 → rmw 抽象层 → Fast DDS(发现 + 传输)
其中任何一环出错,listener 都收不到消息。ros2 topic echo/hz/info 则用独立第三方进程从 DDS 层旁路复验同一链路;hz 测得的 1.000 Hz 与 demo 代码设定的发布周期精确吻合,说明通信实时性正常。
自动化脚本中的写法 (见 build_ros2_jazzy_ubuntu2204.sh 步骤 8):
bash
ros2 run demo_nodes_cpp talker >"$TALKER_LOG" 2>&1 &
TALKER_PID=$!
sleep 2
timeout 15 ros2 run demo_nodes_py listener >"$LISTENER_LOG" 2>&1 || true
pkill -P "$TALKER_PID" 2>/dev/null || true # 先杀 talker(包装器的子进程)
kill "$TALKER_PID" 2>/dev/null || true # 再杀 ros2 run 包装器
grep -q "I heard" "$LISTENER_LOG" && echo "验证通过"
< 5.> 质量层 ------ 运行包自带的测试套件(最彻底)
bash
cd ~/ros2_jazzy
colcon test --packages-select demo_nodes_py # 按需:--packages-up-to <包> 或全量
colcon test-result --all
实测输出:
build/demo_nodes_py/pytest.xml: 3 tests, 0 errors, 0 failures, 0 skipped
Summary: 3 tests, 0 errors, 0 failures, 0 skipped
解释 :每个 ROS 包自带单元测试(gtest/pytest)、集成测试与代码风格检查(flake8/uncrustify 等)。colcon test 逐包执行,colcon test-result 汇总所有 xUnit 结果文件------这正是 ROS 2 上游 CI 的验收方式。全量运行数百个包的测试耗时较长,验收场景可按依赖范围选择(--packages-up-to)。
总结:如何选择验证层次
| 层次 | 命令核心 | 验证内容 | 通过标准 | 适用场景 |
|---|---|---|---|---|
| ① 环境层 | printenv + which ros2 |
环境变量注入 | ROS_DISTRO=jazzy,路径指向 install 目录 |
每次 source 后 |
| ② 包管理层 | ros2 pkg list |
ament 索引完整性 | 包数量符合预期(351) | 安装后快速确认 |
| ③ 诊断层 | ros2 doctor |
版本/网络/中间件/话题健康 | All checks passed |
安装后、排查问题时 |
| ④ 通信层 | talker/listener、ros2 topic echo/hz |
端到端 DDS 链路 | listener 收到连续消息,hz≈设定值 | 官方最终判据 |
| ⑤ 质量层 | colcon test + test-result |
包自带测试 | 0 errors, 0 failures |
CI / 交付验收 |