🌑

Hi Folks.

ROS 2 构建后运行节点报 `UnsupportedTypeSupport` 错误?可能是 Python 版本惹的祸!

问题现象

在 ROS 2 Humble 工作空间中,你顺利执行了 colcon build,一切看起来都很正常:

1
2
3
4
5
Starting >>> system_status_interfaces
Finished <<< system_status_interfaces [0.62s]
Starting >>> status_publisher
Finished <<< status_publisher [0.92s]
Summary: 2 packages finished [1.78s]

可当你满怀期待地运行节点时,却迎面撞上异常:

1
ros2 run status_publisher monitor

错误堆栈如下(关键部分):

1
2
3
4
ModuleNotFoundError: No module named 'system_status_interfaces.system_status_interfaces_s__rosidl_typesupport_c'
...
rosidl_generator_py.import_type_support_impl.UnsupportedTypeSupport:
Could not import 'rosidl_typesupport_c' for package 'system_status_interfaces'

问题定位

ROS 2 的接口包(system_status_interfaces)在编译时会为 C++ 和 Python 分别生成类型支持(type support)库。Python 的类型支持库是一个动态链接库(.so 文件),它的命名中包含 Python 的版本号,例如 cpython-36m 表示是为 Python 3.6 编译的。

当我们查看 install/system_status_interfaces/local/lib/python3.10/dist-packages/system_status_interfaces/ 目录时,发现:

1
system_status_interfaces_s__rosidl_typesupport_c.cpython-36m-x86_64-linux-gnu.so

而当前 Ubuntu 22.04 默认的 Python 是 3.10。Python 3.10 的解释器无法加载为 Python 3.6 编译的扩展模块,因此 import_type_support 失败,抛出 UnsupportedTypeSupport

同时,构建时还出现了符号链接创建失败的问题:

1
failed to create symbolic link ... because existing path cannot be removed: Is a directory

这说明工作空间有残留的构建文件,需要彻底清理。


解决步骤

1. 彻底清理工作空间(去除残留)

1
2
cd ~/sms
rm -rf build install log

这一步可以清除所有旧的构建产物,避免符号链接冲突和版本残留。

2. 显式指定 Python 解释器版本

错误产生的根本原因是 CMake 在构建时错误地找到了 Python 3.6(可能因为环境变量或历史配置)。我们需要强制 CMake 使用系统当前的 Python 3.10。

在构建前,设置环境变量:

1
2
export Python3_EXECUTABLE=/usr/bin/python3
export PYTHON_EXECUTABLE=/usr/bin/python3

或者,如果你希望一劳永逸,可以将这两行添加到 ~/.bashrc 中。

更推荐的做法:在接口包的 CMakeLists.txt 中加入以下内容,明确查找 Python 3:

1
2
3
# 在 find_package(ament_cmake REQUIRED) 之后添加
set(Python3_FIND_STRATEGY LOCATION)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)

这样 CMake 就会自动使用系统找到的 Python 3.10,而不是随意猜测。

3. 检查并补全 CMakeLists.txtpackage.xml

如果你的 CMakeLists.txt 中没有正确依赖 rosidl_default_generators,也会导致类型支持生成不完整。确保包含:

1
2
3
4
5
6
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
"msg/SystemStatus.msg" # 替换为你的实际 msg 文件名
DEPENDENCIES builtin_interfaces # 如果有依赖则添加
)

package.xml 中也需有:

1
2
3
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

4. 重新构建并测试

1
2
3
4
5
6
cd ~/sms
colcon build --symlink-install --packages-select system_status_interfaces status_publisher
# 如果成功,再构建所有包
colcon build --symlink-install
source ~/sms/install/setup.bash
ros2 run status_publisher monitor

此时你应该能看到节点顺利启动,不再报错。


为什么会出现这个问题?

  • CMake 的 Python 探测机制:在某些环境下(比如曾经安装过多个 Python 版本),CMake 可能优先找到旧的 Python 库路径,导致生成的 .so 文件带错版本标签。
  • 工作空间重复构建:之前可能构建时使用了不同的 Python 版本,而 install 目录中的文件没有被完全覆盖,导致版本混乱。
  • --symlink-install 与普通安装混合:符号链接安装有时会遗留目录结构,导致后续构建无法覆盖,需要手动清理。

✅ 预防措施

  1. 始终使用 --symlink-install 并定期清理:在开发阶段,建议每次重大改动后执行 rm -rf build install log 再重新构建。
  2. 明确 Python 版本:在构建脚本或 CMakeLists.txt 中固定 Python 版本,避免依赖系统默认。
  3. 检查 .so 文件名:如果再次遇到类似错误,可以先检查 install 下生成的 .so 文件名是否与当前 Python 版本匹配(python3 -c "import sys; print(sys.version)" 查看版本号)。
  4. 使用 Docker 或虚拟环境:确保开发环境的一致性,避免多版本 Python 干扰。

总结

UnsupportedTypeSupport 错误在 ROS 2 开发中并不少见,其本质是类型支持库与 Python 解释器版本不兼容。通过以下三个关键动作:

  • 彻底清理构建目录;
  • 显式指定 Python 3.10
  • 确保接口包依赖完整

— 2026年8月4日


Search