ROS1中source xxx.bash失效

如题,你在bashrc中写了source xxx.bash,但是你打开新的终端后,提示报错,并且找不到这个package

即使你在bashrc中写了

不知道原因之前,总是觉得怪怪的,知道原因后,其实很简单。

这里其实就是ROS工作空间source的核心机制 ------每个工作空间的setup.bash不是简单"追加"路径,而是基于该工作空间编译时的依赖关系,重新构建ROS_PACKAGE_PATH

一、核心机制

每个ROS工作空间编译(catkin_make/catkin build)时,会在devel/setup.bash中记录:

  1. 该工作空间编译时,生效的「父工作空间」(也就是当时ROS_PACKAGE_PATH里的路径);
  2. 当你source这个setup.bash时,ROS会:
    • 当前工作空间的路径放到最前面(最高优先级);
    • 然后拼接上编译时记录的「父工作空间」路径;
    • 最后只保留系统ROS路径(/opt/ros/noetic/share);
    • 不会保留之前手动source过的、但和当前工作空间无关的路径

简单说:source一个工作空间的setup.bash,相当于"重置"ROS_PACKAGE_PATH,只保留「当前工作空间 + 它编译时依赖的工作空间 + 系统ROS」。

二、我这边做了测试

1. 初始状态(.bashrc加载后的默认值)
bash 复制代码
echo $ROS_PACKAGE_PATH 
/home/wu/code/ros/neor_mini/mini_sim18_ws/src:/home/wu/grasp_ws/src:/home/wu/catkin_workspace/src:/home/wu/catkin_ws/src:/opt/ros/noetic/share
  • 原因:.bashrc里最后source的是mini_sim18_ws,且mini_sim18_ws编译时依赖了grasp_wscatkin_workspacecatkin_ws,所以初始路径包含这些。
2. source catkin_ws
bash 复制代码
echo $ROS_PACKAGE_PATH 
/home/wu/catkin_ws/src:/home/wu/Moveit_test03_ws/src:/opt/ros/noetic/share
  • 原因:catkin_ws编译时只依赖Moveit_test03_ws和系统ROS,所以source它时,ROS会"重置"路径,只保留catkin_ws(当前) + Moveit_test03_ws(父) + 系统ROS,删掉了mini_sim18_wsgrasp_ws等无关路径
3. source catkin_workspace
bash 复制代码
echo $ROS_PACKAGE_PATH 
/home/wu/catkin_workspace/src:/home/wu/catkin_ws/src:/opt/ros/noetic/share
  • 原因:catkin_workspace编译时依赖catkin_ws和系统ROS,所以source后路径变成:catkin_workspace(当前) + catkin_ws(父) + 系统ROS,删掉了Moveit_test03_ws
4. source Moveit_test03_ws
bash 复制代码
echo $ROS_PACKAGE_PATH 
/home/wu/Moveit_test03_ws/src:/opt/ros/noetic/share
  • 原因:Moveit_test03_ws编译时没有依赖任何自定义工作空间 ,只依赖系统ROS,所以source后路径只有它自己 + 系统ROS,其他自定义工作空间路径全被删掉。
5. source mini_sim18_ws
bash 复制代码
echo $ROS_PACKAGE_PATH 
/home/wu/code/ros/neor_mini/mini_sim18_ws/src:/home/wu/grasp_ws/src:/home/wu/catkin_workspace/src:/home/wu/catkin_ws/src:/opt/ros/noetic/share
  • 原因:回到初始状态,因为mini_sim18_ws编译时依赖了grasp_wscatkin_workspacecatkin_ws,所以source后这些路径又被加回来。

每个ROS工作空间的setup.bash就像一个"预设清单":

  • 编译时:你告诉它"我依赖A、B、C工作空间",它就把A、B、C记到清单里;
  • source时:它会清空当前所有路径,只按清单加载"自己 + 依赖的A/B/C + 系统ROS"。
  • 不同工作空间的"清单"不同,所以sourceROS_PACKAGE_PATH就不一样。

总结

  1. 核心原因source工作空间的setup.bash会"重置"ROS_PACKAGE_PATH,只保留「当前工作空间 + 它编译时依赖的工作空间 + 系统ROS」,而非简单追加;
  2. 关键现象 :不同工作空间编译时的依赖不同,导致source后路径组成不同;

最后

这就是我最开始存在的困惑:为啥我bashrc中source路径放置的顺序不同,最后有些能直接跑起来,有些就是需要重新source指定bash。

相关推荐
2603_965148116 分钟前
如何解析JSON数据?API返回的商品信息处理教程
开发语言·数据库·python·自动化·json·api
知无不研3 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_29143 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
C++ 老炮儿的技术栈5 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011165 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据5 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
zlinear数据采集卡5 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Poo_Chai5 小时前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库
瑞码空间6 小时前
Java 图形界面(GUI)完整知识点手册
java·开发语言·图形界面·swing
小努蛋6 小时前
linux编译openresty异常问题,lua_cjson.c:706:5: 错误: ‘for‘ 循环初始化声明只在 C99 或 C++ 模式下允许
开发语言·lua·openresty