ROS2 中的工作空间类似我们常说的概念——“工程”,是我们在 ROS 中开发具体项目的空间,所有功能包的源码、配置、编译都在该空间下完成。
工作空间(workspace,也叫工作区)是包含 ROS 2 软件包的目录。在使用ROS 2之前,必须在计划使用的终端中提供 ROS 2 安装工作区。这使 ROS 2 的软件包可供您在该终端中使用。
您还可以选择“overlay” –一个辅助工作区,在其中可以添加新软件包而不会干扰正在扩展的现有 ROS 2 工作区或“underlay”。underlay 必须包含 overlay 中所有软件包的依赖项。overlay 中的包将覆盖 underlay 中的包。也可以有多个参考 underlay 和 overlay,每个后续的 overlay 都使用其父 overlay 的包。
通俗地说,我们可能会同时开发多个项目,就会产生多个工作空间,所以工作空间之间也有一个层次的问题,类似于优先级的概念,比如不同工作空间中有同名的功能包,那运行的时候是启动哪一个呢?ROS 默认是启动最上层的工作空间( overlay),上层工作空间中的功能包会覆盖(override)下层工作空间(underlay)中的同名功能包。所以有多个工作空间存在的时候,我们还需要注意设置工作空间的层次。
1 Source ROS 2 environment¶
工作空间的层次是通过环境变量来配置的,简单来说:下一个配置的工作空间会放到上一个配置的工作空间之上。
ROS2 安装路径下的功能包一般会被我们设置为最下层的工作空间,所以我们在安装好 ROS2 之后,一定要记得在 bashrc 中设置如下 ROS2 安装路径的环境变量:
$ source /opt/ros/<distro>/setup.bash
比如:
$ source /opt/ros/foxy/setup.bash
2 Create a new directory¶
最佳实践是为每个新工作空间创建一个新目录。名称无关紧要,但可以指出工作空间的用途会很有帮助。让我们为“开发工作空间”选择目录名称 dev_ws
:
mkdir -p dev_ws/src
cd dev_ws/src
另一个最佳实践是将工作空间中的所有软件包放入 src
目录。上面的代码在 dev_ws
内创建一个 src
目录,然后导航到该目录。
3 Clone a sample repo¶
现在我们使用的终端已经 cd
到 dev_ws/src
路径下,接下来我们在这里先放置一些示例的功能包。您将使用的现有软件包来自 ros_tutorials
存储库(on GitHub)。在 dev_ws/src
目录中,对要使用的发行版运行以下命令:
$ git clone https://github.com/ros/ros_tutorials.git -b <distro>-devel
比如:
$ git clone https://github.com/ros/ros_tutorials.git -b foxy-devel
稍等片刻, ros_tutorials
中的示例功能包就全部放到工作空间的 src
下边啦,其中我们可以看到这些内容:
现在,您已经在工作区中填充了一个示例程序包,但这不是一个功能齐全的工作区。您需要解决依赖关系并首先构建工作区。
4 Resolve dependencies¶
在构建工作空间之前,您需要解决程序包依赖性。您可能已经具有所有依赖关系,但是最佳实践是每次克隆时都要检查依赖关系。您不会希望由于长时间缺少依赖关系而导致构建失败。
如果,没有安装 rosdep
,可以运行:
$ sudo apt install python-rosdep2
$ sudo rosdep init
$ rosdep update
更多细节见:rosdep wiki。
ROS2 提供了自动化的依赖安装方式,需要我们在工作空间的根目录 dev_ws
下运行如下命令:
$ rosdep install -i --from-path src --rosdistro <distro> -y
将 <distro>
替换为您的发行版。
运行之后,会自动安装确实的依赖,如果依赖全部满足的话,就会显示:
这里需要注意一点,以上自动化安装依赖的前提是:每个功能包已经完整的将所依赖的包和库在 package.xml
文件中声明。
5 Build the workspace with colcon¶
接下来就可以编译代码啦,需要在工作空间的根目录 dev_ws
下运行:
$ colcon build
如果提示 colcon
没有安装的话,可以使用如下命令安装:
$ sudo apt install python3-colcon-common-extensions
colcon
是 ROS2 的编译工具,类似于 ROS1 中的 catkin。运行之后可以看到:
colcon build
后边还可以跟一些常用的参数:
-
--packages-up-to
:编译指定的功能包,而不是整个工作空间 -
--symlink-install
:节省每次重建 python 脚本的时间 -
--event-handlers console_direct+
:在终端中显示编译过程中的详细日志(否则可以在log
目录中找到)
构建完成后,在工作区根目录(dev_ws
)中输入 ls
,您将看到 colcon
创建了新目录:
build install log src
install
目录是您工作区的安装文件所在的目录,您可以使用该目录来获取 overlay
。
6 Source the overlay¶
接下来需要重新打开一个终端,然后来设置 dev_ws
工作空间的环境变量。
在获取 overlay
之前,非常重要的一点是,要打开一个新终端,与构建工作区的终端分开。在您构建的同一终端中 sourcing overlay
,或者在生成 overlay
的地方同样进行 sourced,可能会造成复杂的问题。
在新终端中,您的主要 ROS 2 环境作为 “underlay” source,因此您可以在其“on top of”构建 overlay:
$ source /opt/ros/<distro>/setup.bash
进入工作空间的根目录,接着,source
你的 overlay
:
$ . install/local_setup.bash
install
里有两个很类似的文件:local_setup.sh
和 setup.sh
,前者仅会设置当前工作空间中功能包的相关环境变量,后者还会设置该工作空间下其他底层工作空间的环境变量。
现在我们就可以来运行 dev_ws
工作空间下的 turtlesim
功能包了:
ros2 run turtlesim turtlesim_node
这时会有一个问题,ROS2 安装的路径下有一个 turtlesim
功能包,这里又有一个 turtlesim
功能包,我怎么能确定现在运行的就是 dev_ws
里的 turtlesim
呢?
不如我们来尝试修改下这个包,看下是否会有变化。
7 Modify the overlay¶
您可以通过在 turtlesim
窗口上编辑标题栏来修改覆盖中的 turtlesim
。为此,请在 ~/dev_ws/src/ros_tutorials/turtlesim/src
中找到 turtle_frame.cpp
文件。用您喜欢的文本编辑器打开 turtle_frame.cpp
。
在第 52 行,您将看到函数 setWindowTitle("TurtleSim")
;。将值 ”TurtleSim” 更改为“ ”MyTurtleSim”,然后保存文件。
返回到您之前运行 colcon build
的第一个终端,然后再次运行它。返回第二个终端(overlay 的 sourced)并再次运行 turtlesim
:
$ ros2 run turtlesim turtlesim_node
没错,打开的小海龟窗口中,标题名已经变啦。
可见,当前运行的确实是dev_ws工作空间下的turtlesim包。
如果再打开一个新终端,不 source dev_ws 的环境变量,那么运行一下命令时就不一样啦:
$ ros2 run turtlesim turtlesim_node
您可以看到 overlay
中的修改实际上并没有影响 underlay
中的任何内容。
所以在这里,dev_ws
是上层工作空间,ROS2 安装路径是下层工作空间,具体运行哪里的包,全看你在终端中如何设置环境变量了
8 总结
在本教程中,您将主要的 ROS 2 发行版安装作为 underlay,并通过在新工作区中克隆和构建软件包来创建了 overlay。如您在修改过的 turtlesim
中所看到的,overlay 位于路径的前面,并且优先于 underlay。
建议使用 overlay 来处理少量程序包,因此您不必将所有内容都放在同一工作区中,而不必在每次迭代时都重建一个巨大的工作区。
网友评论