Ubuntu 22.04 从源码编译安装 ROS 2 Jazzy 笔记

先在 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 跳过三个键(官方文档固定写法):
    • fastcdrurdfdom_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/ 下的 binlibshare 及 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 / 交付验收
相关推荐
_Narcissus_1 小时前
B+树的概念和操作笔记(含完整代码实现)
c语言·数据结构·数据库·c++·笔记·b树·算法
raindayinrain1 小时前
深入理解Linux内核-页表,TLB,高速缓存,性能优化
linux·性能优化·高速缓存·页表·tlb
Wang's Blog1 小时前
PostgreSQL笔记33: 索引底层原理、扫描类型与属性体系深度解析
数据库·笔记·postgresql
是上好佳佳佳呀1 小时前
【深度学习|DAY05】卷积神经网络深度学习笔记
笔记·深度学习·cnn
蒸蒸yyyyzwd2 小时前
cpp 选手备战秋招学习笔记 day11
redis·笔记·求职招聘
秣宇2 小时前
银河麒麟服务器操作系统关闭 Swap 分区
linux·运维·服务器·github·kylin
RisunJan2 小时前
Linux命令-usernetctl(已废弃 - 通过 usermode-helper 控制网络接口的包装器)
linux·运维·服务器
ElectroComp2 小时前
选对1.5uH功率电感:线艺XEL4030V与同于的兼容评估笔记
笔记
你要飞2 小时前
VSP3 转 STL
笔记·github