ROS2 节点使用 Conda 环境运行 Python 依赖的解决方案

ROS2 节点使用 Conda 环境运行 Python 依赖的解决方案

适用场景 :ROS2 节点需要 PyTorch、NumPy 等仅在 Conda 中安装的 Python 包,但 ros2 launch / ros2 run 启动时出现 ModuleNotFoundError,或 rclpy 与 Python 版本不匹配。


一、问题现象

在 Conda 环境(如 metarobotics)中已安装 PyTorch,且终端中 python3 -c "import torch" 正常,但通过 ROS2 launch 启动节点时报错:

复制代码
ModuleNotFoundError: No module named 'torch'

或改用 conda run 后出现:

复制代码
ModuleNotFoundError: No module named 'rclpy._rclpy_pybind11'
The C extension '...cpython-38-x86_64-linux-gnu.so' isn't present on the system.

二、原因分析

2.1 为什么 ModuleNotFoundError: No module named 'torch'

ros2 run / ros2 launch 启动的节点,实际执行的是 colcon 安装时生成的入口脚本(如 install/lib/xxx_pkg/executable_name)。该脚本的 shebang 通常指向构建时的 Python 解释器 ,多为系统自带的 /usr/bin/python3,而非 Conda 环境中的 Python。

因此:

  • 终端中 python3 来自 Conda → 能找到 torch
  • 节点进程使用的 Python 来自系统 → 找不到 torch

2.2 为什么 rclpy._rclpy_pybind11 报错?

ROS2 Humble 的 rclpy C 扩展是为 Python 3.10 编译的。若 Conda 环境使用 Python 3.8

  • Conda 的 Python 3.8 能 import torch ✓
  • 但 rclpy 的 .so 文件是为 cpython-310 编译的,Python 3.8 无法加载 ✓
  • 报错提示缺少 rclpy._rclpy_pybind11 或 C 扩展不匹配

本质是 Python 版本不一致:ROS2 用 Python 3.10,Conda 用 Python 3.8。


三、解决方案

方案一:创建 Python 3.10 的 Conda 环境(推荐)

使 Conda 环境与 ROS2 Humble 使用同一 Python 版本,同时安装所需依赖:

bash 复制代码
# 1. 创建 Python 3.10 环境
conda create -n ros2_torch python=3.10 -y
conda activate ros2_torch

# 2. 安装 PyTorch 等依赖
pip install torch numpy

# 3. 使用该环境启动 ROS2 节点(见下文 launch 配置)

在 launch 文件中通过 conda run 在指定环境中运行节点,例如:

python 复制代码
from launch.actions import ExecuteProcess

eeg_simulator_node = ExecuteProcess(
    cmd=[
        'conda', 'run', '-n', 'ros2_torch', '--no-capture-output',
        'python3', '-m', 'your_pkg.your_node_module',  # 用 python -m 避免走系统 Python
        '--ros-args', '--params-file', params_file,
    ],
    output='screen',
    shell=False,
)

注意 :必须用 python3 -m your_pkg.your_node_module,而不要用 ros2 run。否则 ros2 run 调用的仍是 colcon 安装的脚本,可能继续使用系统 Python。


四、launch 中通过 conda run 指定环境的示例

eeg_bci_go2 包为例,支持通过 launch 参数指定 Conda 环境:

python 复制代码
# launch 参数
conda_env_arg = DeclareLaunchArgument(
    'conda_env',
    default_value='ros2_torch',  # 或 metarobotics(需 Python 3.10)
    description='Conda environment for nodes that need PyTorch',
)

# 需要 PyTorch 的节点:用 python3 -m 在 Conda 中运行
eeg_simulator_node = ExecuteProcess(
    cmd=[
        'conda', 'run', '-n', LaunchConfiguration('conda_env'), '--no-capture-output',
        'python3', '-m', 'eeg_bci_go2.eeg_simulator_node',
        '--ros-args', '--params-file', params_file,
    ],
    output='screen',
    shell=False,
)

# 不需要 PyTorch 的节点:可用 ros2 run 或同样用 conda run
eeg_cmd_bridge_node = ExecuteProcess(
    cmd=[
        'conda', 'run', '-n', LaunchConfiguration('conda_env'), '--no-capture-output',
        'ros2', 'run', 'eeg_bci_go2', 'eeg_cmd_bridge_node',
        '--ros-args', '--params-file', params_file,
    ],
    output='screen',
    shell=False,
)

启动方式

bash 复制代码
# 默认使用 ros2_torch
ros2 launch my_package my_nodes_launch.py

# 指定 Conda 环境
ros2 launch my_package my_nodes_launch.py conda_env:=metarobotics

这样即使当前终端未激活 Conda,launch 也会在指定 Conda 环境中启动相关节点。


相关推荐
张健11564096485 分钟前
使用信号量限制并发数量
开发语言·c++
步辞22 分钟前
Redis如何利用LFU算法优化缓存命中率
jvm·数据库·python
糯米团子74923 分钟前
Web Worker
开发语言·前端·javascript
forEverPlume36 分钟前
golang如何实现日志按级别过滤_golang日志按级别过滤实现教程
jvm·数据库·python
我命由我123451 小时前
JavaScript 开发 - 获取函数名称、获取函数参数数量、获取函数参数名称
开发语言·前端·javascript·css·html·html5·js
白晨并不是很能熬夜1 小时前
【PRC】第 2 篇:Netty 通信层 — NIO 模型 + 自定义协议 + 心跳
java·开发语言·后端·面试·rpc·php·nio
简简单单就是我_hehe1 小时前
后端链路追踪局部采集和全量采集配置说明
java·开发语言
北京理工大学软件工程2 小时前
C#111
开发语言·c#
m0_624578592 小时前
MySQL主从复制支持跨版本吗_不同版本间同步的注意事项
jvm·数据库·python
yuanpan2 小时前
Python Pygame 入门教程:从零学会创建窗口、绘图和游戏交互
python·游戏·pygame