ubuntu22.04+miniconda安装ROS2踩坑实录

先讲一下经过。

我现是用ubuntu22.04+miniconda玩了一把RAG,所以用conda配的环境。

然后又开始玩ROS2,跟着鱼香肉丝(fishros)的教程安装了ROS2,还玩了海龟模型。

第一天玩得很开心,第二天编写第一个python节点,第一句话

复制代码
import rclpy

直接给我干废了。
写的py文件命令行能跑起来,pycharm就报错说找不到包。我在网上还找了一堆教程,尝试修复。

比如找到rclpy库所在文件夹,临时修改了环境变量:

复制代码
export PYTHONPATH='/opt/ros/humble/local/lib/python3.10/dist-packages:$PYTHONPATH'

又报错:modulenotfounderror: No module named '_distutils_hack'

解决方案:

1、找到报错的文件,通过记事本打开

在 import os; 后面(注意是分号后面)敲一个回车,就是改成这样:

接着保存关闭就可以运行了

又报错: ImportError: librmw_fastrtps_cpp.so: cannot open shared object file: No such file or directory

++我不得不说这个时候我就感觉有点不对了。怎么什么库都找不到,怎么个意思需要我一个个export?++

然后我梳理了一下昨天到今天的操作。

昨天装完ros2以后在终端输入命令ros2,结果是这样的:

然后我搜了教程配置了一番,详情记录在https://blog.csdn.net/thinkpad1234567890/article/details/155458847?spm=1011.2124.3001.6209

重点来了朋友们,就是这句

复制代码
source /opt/ros/humble/setup.bash 

它的核心作用就是激活 ROS 2 的运行环境

我们从Linux 操作系统机制Shell 脚本原理 以及 ROS 2 的构建系统(Ament) 三个底层层面来细致拆解。


第一层:Linux Shell 机制 ------ 为什么要用 source

在 Linux 终端中,执行脚本有两种主要方式:

  1. 直接运行 (例如 ./setup.bash):

    • 系统会启动一个新的子 Shell (Sub-shell) 进程来运行脚本。
    • 脚本里修改的变量(环境变量)只在这个子进程里有效。
    • 脚本运行结束,子进程销毁,所有变量修改随之消失。你的当前终端(父进程)什么都不会改变。
    • 结果 :你依然无法运行 ros2 命令。
  2. 使用 source 运行 (例如 source setup.bash. setup.bash):

    • source 是 Shell 的内建命令。
    • 它指示当前 Shell 在当前进程中逐行读取并执行脚本中的命令。
    • 脚本里修改的环境变量会直接作用于当前终端
    • 结果 :环境变量被修改并保留下来,你可以运行 ros2 命令了。

总结source /opt/ros/humble/setup.bash 是为了让脚本能够"通过修改当前终端的内存"来配置环境。


第二层:环境变量 ------ 到底修改了什么?

当脚本执行时,它主要是在你的内存中操作环境变量 (Environment Variables)。这就像是告诉系统去哪里找东西。

最关键的几个变量如下:

  1. PATH (寻找可执行程序)

    • 修改前 :系统只知道去 /usr/bin 等默认路径找命令。
    • 修改后 :脚本把 /opt/ros/humble/bin 加到了 PATH 的最前面。
    • 作用 :当你输入 ros2rviz2 时,系统能在这个目录下找到对应的可执行文件。
  2. PYTHONPATH (寻找 Python 库)

    • 作用 :ROS 2 大量使用 Python(比如 rclpy)。脚本会将 /opt/ros/humble/lib/python3.10/site-packages 加入此变量。
    • 后果 :你的 Python 脚本才能成功 import rclpy 或导入各种消息类型。
  3. LD_LIBRARY_PATH (寻找 C++ 动态链接库)

    • 作用 :ROS 2 底层是 C++。脚本会将 /opt/ros/humble/lib 加入此变量。
    • 后果 :程序运行时能加载 .so 动态库文件(比如 DDS 通讯库)。
  4. AMENT_PREFIX_PATH (ROS 2 专属核心变量)

    • 作用:这是 ROS 2 构建系统 (Ament) 的核心。它告诉 ROS 2 工具链,ROS 安装在哪里。
    • 后果ros2 pkg list 能列出包,ros2 launch 能找到 launch 文件,全靠这个变量指路。
  5. CMAKE_PREFIX_PATH

    • 作用 :让 CMake 构建工具能找到 ROS 2 的包,以便你在编译自己的代码时能 find_package(rclcpp)

第三层:脚本逻辑与 Ament 钩子 (Hooks) ------ 它是怎么工作的?

ROS 2 的 setup.bash 并不是一个简单的硬编码脚本,它设计得非常巧妙,支持模块化

当你运行 source /opt/ros/humble/setup.bash 时,底层逻辑流如下:

  1. 入口setup.bash 只是一个入口,它会确定当前的 Shell 类型(bash, zsh 等)。
  2. 调用 local_setup.bash :它会调用同一目录下的 local_setup.bash。这个脚本负责处理当前安装目录下的所有包。
  3. 环境钩子 (Environment Hooks)
    • 这是 ROS 2 (Ament) 最精妙的地方。
    • ROS 2 的每个功能包(Package)在安装时,如果需要修改环境变量,会生成一个小的 shell 脚本片段(Hook)。
    • setup.bash 会利用工具(通常是 Python 脚本 _local_setup_util_sh)去扫描 /opt/ros/humble/share 下所有包定义的钩子。
    • 举例
      • ros_workspace 包会提供钩子来设置 AMENT_PREFIX_PATH
      • 某些特定的包可能需要设置特殊的驱动路径。
  4. 循环执行 :脚本会遍历所有找到的钩子并 source 它们。

这意味着:ROS 2 的环境配置是动态生成的,而不是写死的。如果你在这个目录下新装了一个包,下次 source 时,脚本会自动把新包的环境变量也加上。


第四层:工作空间覆盖 (Overlaying) ------ 为什么要这么设计?

你可能会问:"为什么不直接把这些路径写死在系统的 /etc/profile 里,让它永久生效?"

这就涉及到了 ROS 的工作空间覆盖(Workspace Overlaying) 机制:

  1. 底层 (Underlay)/opt/ros/humble 是基础层。
  2. 上层 (Overlay) :你自己写的代码(比如 ~/ros2_ws)。

当你编译自己的代码后,你需要 source ~/ros2_ws/install/setup.bash。 此时,新的 setup.bash 会:

  • 检测到已经存在 AMENT_PREFIX_PATH(指向 /opt/ros/humble)。
  • 把你自己的路径(~/ros2_ws/install)插到变量的最前面

这就是"激活环境"的终极奥义 : 通过 source 操作,你在内存中构建了一个优先级列表

  • 系统找包时,先去你的工作空间找。
  • 找不到,再去 /opt/ros/humble 找。

这让你可以在不修改系统源码的情况下,修改或替换系统自带的节点(例如,你可以自己写一个同名的包来覆盖官方包)。

那么很显然,我这命令行能跑起来(说明库已经存在),pycharm就报错说找不到包,pycharm中反复出现各种动态连接库找不到的问题就是和环境配置有很大关系。

明明文件就在那里,系统却是个瞎子。哭了。

然后,罪魁祸首是谁呢?是miniconda !
如果你安装了 Anaconda 或 Miniconda,Conda 环境会劫持系统的路径。Conda 有自己的一套库文件(比如 libstdc++ 等),可能会屏蔽掉 ROS 需要的系统库,或者重置了 LD_LIBRARY_PATH

妈妈咪呀,我的老天乃!

接下来是我的自救过程。

首先在上次ROS2配置过程中,我在bashrc中加了一句:

复制代码
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc

这句是个全局配置,我们现把这句删掉:

复制代码
sudo gedit ~/.bashrc

找到source /opt/ros/humble/setup.bash这句(通常在文件末尾),然后注释掉或者删掉

复制代码
# source /opt/ros/humble/setup.bash

保存文件,然后重新开一个终端,等于说回退到

然后在 Conda 内部装 ROS

操作步骤:

  1. 创建一个新的 Conda 环境(不要污染你的 base 环境)

    复制代码
    conda create -n ros_env python=3.10
    conda activate ros_env
  2. 添加 RoboStack 源并安装 ROS 2 Humble

    复制代码
    conda config --env --add channels conda-forge
    conda config --env --add channels robostack-staging
    conda config --env --remove channels defaults
    # 安装 ROS 2 Humble 基础包
    conda install ros-humble-desktop
  3. 在这个环境里,你不需要 source /opt/ros/...,直接就能用。而且你可以随意安装 pytorch 等库,它们会自动处理依赖兼容

  4. 验证Conda ROS 是否正常: 在新终端里激活你的 Conda 环境

    复制代码
    conda activate ros2

    检查 ros2 命令到底用的是谁的

    复制代码
    which ros2

    正确结果 :应该显示类似 /home/你的用户名/anaconda3/envs/ros2/bin/ros2

    测试运行

    复制代码
    ros2 run demo_nodes_cpp talker

    如果能跑起来,恭喜你,环境完美了!

写到这里基本能解决我的问题了,还有一个问题是:

如果你偶尔还想用系统自带的 ROS 怎么办?

既然去掉了自动 source,如果你某天突然想用 /opt/ros/humble 下的系统版,该怎么办?

方法:使用别名 (Alias)

你可以再次编辑 ~/.bashrc,加上这一行:

复制代码
alias load_sys_ros='source /opt/ros/humble/setup.bash'

使用逻辑:

  • 日常使用 Conda 版 :打开终端 -> conda activate ros2 -> 直接用。
  • 偶尔使用系统版 :打开终端 -> 确保没有 激活 Conda -> 输入 load_sys_ros -> 激活系统版环境。

核心原则: 永远不要在同一个终端里同时激活 Conda 环境和系统 ROS 环境,除非你是能够手写 CMakeList 的高级玩家。

如果你一打开终端conda就是激活的,那就不停地退出

复制代码
conda deactivate

多退几次,直到前面没有括号了。

或者修改conda的全局配置,禁止自动激活 base:

复制代码
conda config --set auto_activate_base false

你需要用环境时,再手动输入 conda activate xxx

相关推荐
Trouville0115 小时前
Pycharm软件初始化设置,字体和shell路径如何设置到最舒服
ide·python·pycharm
今天没有盐19 小时前
Python 数据分析实战:多场景数据处理与可视化全解析
python·pycharm·编程语言
大飞记Python20 小时前
【2025全攻略】PyCharm专业版 / 社区版如何打开.db 数据库文件
数据库·python·sql·pycharm
shx66661 天前
2.2 ROS2 使用功能包组织 Python 节点
ros2·功能包
沟通QQ:4877392781 天前
Apollo之em - planner算法深度剖析:从路径规划到公式推导
pycharm
Aries·Zhao2 天前
Python小白学习之环境安装
python·pycharm·visual studio code
q***54752 天前
解决no main manifest attribute错误
ide·python·pycharm
老黄编程2 天前
ros2 jazzy 支持 gazebo jetty 吗?兼容性如何?
ros2·jetty·jazzy
叠叠乐2 天前
gmapping 重置地图(修改版本,提供了服务,调用服务可运行时清空地图)
ros2