ROS开发中,有时需要建多个工作空间, 将不同的功能包区别开来. 但是,多个工作空间会存在相互影响的情况,如何让它们能同时工作且相互不影响,需要技巧. 这里需要清楚ROS工作空间的工作原理. 本文做个详细介绍.
1 ROS_PACKAGE_PATH环境变量
ROS在查找包时,使用的是ROS_PACKAGE_PATH环境变量. 此环境变量下的路径是ROS查找包的所有路径,如果一个工作空间的路径不在ROS_PACKAGE_PATH环境变量中, ROS是找不到这个工作空间中的ROS功能包的.
ROS_PACKAGE_PATH环境变量是通过每个工作空间的setup.bash脚本设置的. 例如,我们安装完ROS 系统后, 需要先执行一个$source /opt/ros/kinetic/setup.bash 命令, 这个命令就是把ROS系统的路径设置到ROS_PACKAGE_PATH环境变量中. 通过echo命令可以查看ROS_PACKAGE_PATH的值. 如下:
$ echo $ROS_PACKAGE_PATH
/opt/ros/kinetic/share
如果这时,再运行另一个工作空间的setup.bash脚本会怎么样的?
是覆盖掉原来的路径还是与原来已经存在的路径共存呢? 答案是都有可能。具体的行为取决于这个工作空间执行catkin_make时的环境。
举例如下:
假设我们已经运行$source /opt/ros/kinetic/setup.bash,这时ROS_PACKAGE_PATH的值为/opt/ros/kinetic/share。
然后,我们创建一个新的工作空间/home/user1/work1_ws, 代码完成后,执行catkin_make编译. 编译完成后,会有/home/user1/work1_ws /devel/setup.bash脚本。执行这个脚本后(source /home/user1/work1_ws/devel/setup.bash),ROS_PACKAGE_PATH的值变为/home/user1/work1_ws /src:/opt/ros/kinetic/share
如果我们在执行work1_ws 工作空间的catkin_make之前,没有运行$source /opt/ros/kinetic/setup.bash,即ROS_PACKAGE_PATH的值为空,则执行完
source /home/user1/work1_ws /devel/setup.bash后,ROS_PACKAGE_PATH的值为/home/user1/work1_ws /src。
为什么会这样呢?
因为在catkin_make时,会检查编译时的ROS环境并记录下来,保存在work1_ws /devel/_setup_util.py python文件的CMAKE_PREFIX_PATH变量中。以后在执行这个工作空间的setup.bash脚本时,会使用编译时的状态覆盖ROS_PACKAGE_PATH的值。
2 两个工作空间同时工作
明白了第1章的原理,让两个工作空间同时工作就很容易了,无非就是确保两个工作空间的目录都出现在ROS_PACKAGE_PATH环境变量中。假设有两个工作空间/home/user1/work1_ws , /home/user1/work2_ws,怎么做呢?显示步骤是:
1)在work1_ws中执行catkin_make, 编译完成后,执行:source /home/user1/work1_ws/devel/setup.bash
2)在work2_ws中执行catkin_make, 编译完成后,执行:source /home/user1/work2_ws/devel/setup.bash
完成后,查看ROS_PACKAGE_PATH的值为/home/user1/work2_ws /src:/home/user1/work1_ws /src:/opt/ros/kinetic/share
两个工作空间可以同时工作了。
注意的核心点就是在catkin_make时确保另一个工作空间的setup.bash已经执行。