从此篇开始我们即将进入client library系列,主要包含包的创建、主题、服务、参数、消息等功能的自定义实现,开始真正进入ROS的大门咯。
前言
从ROS 1到ROS 2,对应的构建工具集由 catkin_make
-> catkin_make_isolated
->catkin_tools
-> ament_tools
一直迭代到如今的colcon,
我只使用过catkin_make,比如编写好一个功能包里面的文件时,我们可以catkin_make一下,再运行结果文件,相当于ROS的编译工具。
工作空间
所谓的工作空间,简单理解其实就是一种特定结构组成的这样一种目录(一个文件夹下包含几个特定名称的子文件夹)。
在ROS 2下,一个工作空间文件夹下存在四种同级的子文件夹,分别是:
src:ROS源代码存在的地方,后续我们要手动编写的源代码文件都会保存到这个地方;
build:在编译过程中生成的中间文件会保存在这个地方,其中还包含CMake文件;
install:源代码在编译之后会生成目标文件,这里就是这些最终编译完成的目标文件保存的地方,不同的功能包会在这里生成不同的子子文件夹用来存放各自的目标文件;
log:顾名思义,保存各种各样的日志信息。
从上面可以注意到,不同于catkin中的工作空间,这里面没有devel文件夹。
创建工作空间
Linux下我们创建名称为ros2_ws的文件夹作为我们使用的工作空间,同时我们也必须手动在ros2_ws下创建src子文件夹,我们可以一条命令搞定:
$mkdir -p ros2_ws/src
-p是为了保证在创建src文件夹时如果其父目录不存在的情况可以自动先创建其父目录再创建目标子目录,通过tree命令可以查看这个目录的一个结构:
src中添加例子
我们通过如下命令将官方提供的例子保存到src路径下:
$git clone https://github.com/ros2/examples src/examples -b iron
如果不成功的话(国内的网络环境还是不友好哇),我这里提供几种解决方法:
1. 修改hosts文件内容
1.1 如果是在Ubuntu里面,我们sudo gedit /etc/hosts,在其最后添加如下内容保存即可:
140.82.113.4 github.com 199.232.69.194 github.global.ssl.fastly.net 185.199.108.153 assets-cdn.github.com 185.199.109.153 assets-cdn.github.com 185.199.110.153 assets-cdn.github.com 185.199.111.153 assets-cdn.github.com
1.2 如果是在Windows下, 在C:/Windows/System32/drivers/etc 找到hosts文件 ,同样在最后添加上面的内容保存即可;
2. 用谷歌浏览器(比Edge好用)直接进入资源页下载压缩包文件解压到src路径下(如果网络依然很费力的话可以考虑申请个免费的VPN,也方便我们其他科学上网需求),这种无需修改什么,只不过速度会慢一点,具体得看运营商的策略。
下载完成后的情况如下:
source an underlay
这小节不太好翻译(自己理解的不够),就直搬原文了。
对于我们现有的ROS 2安装,重要的是我们已经为其配置了环境,这将为我们的工作空间提供示例包所需的构建依赖项。这是通过配置由二进制安装或源代码安装提供的设置脚本来实现的,即另一个colcon工作空间(参见安装部分)。我们将这个环境称为基础层(underlay)。
我们的工作空间ros2_ws将是现有ROS 2安装之上的一个上层(overlay)。一般来说,当您计划对少量包进行迭代时,建议使用上层,而不是将所有包都放入同一个工作空间中。
对于underlay和overlay的解释大家可以参见下篇文章。此处只需留个印象就行。
简单来讲,我们通过一个相对最上层顶级的setup脚本文件激活 ROS 环境变量,从而解决一些安装文件(可能多个子文件夹下的多种功能包)在编译及运行时的各种资源依赖问题。
构建工作空间
我们在工作空间的根路径下(ros2_ws路径)执行如下命令构建安装刚刚下载好的例子:
$colcon build --symlink-install
--syslink-install命令的作用是当源码空间中的文件改变时,安装路径下的对应目标文件也能更快地自动更新(针对于python或其他非编译型语言源码文件)。
由于例子里面的内容比较多,构建完成的时间比较长(接近5分钟),工作空间下自动创建了build、install、log文件夹:
安装包整体测试
我们可以一键测试刚刚构建安装好的所有例程,如下:
$colcon test
同样需要花点时间,整体测试完成后,终端会打印出整体测试的结果:
可以看到,我们一共测试了22个功能包,其中14个包有给出标准错误输出信息(罗列出那些包),4个包测试失败(罗列出对应失败的包) 。
source环境变量
下面我们将测试单独的包,在这之前我们得刷新下ROS的环境变量,将这些目标文件和库添加到相关的路径当中去,防止目标包文件在运行时由于各种依赖项或其他原因导致失败的情况。在install文件夹下,我们会找到一个setup.bash脚本文件,这个脚本文件会帮助我们将install文件夹下生成的所有目标包信息统一添加到环境变量中去(回忆下之前的小海龟例子,是不是也是每次新开一个终端后我们都要source一下setup.bash)。
$source install/setup.bash
试试小demo
既然准备工作都搞定了,我们找个主题订阅/发布的小例子来看看,它们分别是install下的examples_rclcpp_minimal_subscriber包和examples_rclcpp_minimal_publisher包,我们打开两个终端(新打开的终端依旧需要source),分别启动订阅节点subscriber_member_function和发布节点publisher_member_function:
$ros2 run examples_rclcpp_minimal_subscriber subscriber_member_function
$ros2 run examples_rclcpp_minimal_publisher publisher_member_function
创建自己的包
我们可以简单地执行ros2 pkg create来创建一个新包(后面需添加一些依赖的文件和库),具体可以跟哪些参数呢,我们执行ros2 pkg create -h来瞅瞅:
有一个必选项(包名称),剩下的都是可选项(比如构建类型可以选择cmake、ament_cmake、ament_python),这些选项内容我们可以通过例子中的package.xml文件进行了解。
我们可以在例子路径下(src/examples/rclcpp/topics/minimal_subscriber)找到这样一份package.xml(体现了该包的构建信息),内容如下:
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2"><name>examples_rclcpp_minimal_subscriber</name><version>0.18.0</version><description>Examples of minimal subscribers</description><maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer><maintainer email="alejandro@openrobotics.org">Alejandro Hernandez Cordero</maintainer><license>Apache License 2.0</license><author email="jacob@openrobotics.org">Jacob Perron</author><author>Mikael Arguedas</author><author>Morgan Quigley</author><author email="sloretz@openrobotics.org">Shane Loretz</author><buildtool_depend>ament_cmake</buildtool_depend><build_depend>rclcpp</build_depend><build_depend>rclcpp_components</build_depend><build_depend>std_msgs</build_depend><exec_depend>rclcpp</exec_depend><exec_depend>rclcpp_components</exec_depend><exec_depend>std_msgs</exec_depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export>
</package>
包含了版本信息、构建类型信息、包格式、源文件信息、构建/执行依赖库信息、测试 依赖库信息等等内容,本篇不再细究,后面会继续涉及。
设置colcon_cd
colcon_cd命令可以方便我们从当前的工作目录切换到目标包的源文件目录 (当然也可以用cd命令),比如说我们想快速进入some_ros_package这个包目录,直接colcon_cd some_ros_package(如果用cd,还得回忆查找下各级路径的文件夹名称,稍显麻烦),我们就进入了~/ros2_ws/src/some_ros_package目录。
为了让系统找到colcon_cd命令,我们得提前将colcon_cd的命令添加到系统的环境变量中去,一劳永逸的方法直接加入到永久性配置文件中,在终端执行如下命令:
$echo "source /usr/share/colcon_cd/function/colcon_cd.sh" >> ~/.bashrc
$echo "export _colcon_cd_root=/opt/ros/iron/" >> ~/.bashrc
上面的/usr/share/colcon_cd路径你得根据安装ROS 2时的实际路径来写,默认情况都是这个路径。
设置colcon命令补全功能
前提是你得安装了colcon_argcomplete包(安装了完整桌面版的ROS 2默认都是有的),我们可以将这个colcon自动补全功能添加到系统环境变量中去(其实默认已经全局使能了):
$echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> ~/.bashrc
补充
1. 如果不想构建特定的包,请在目录中放置一个名为 COLCON_IGNORE 的空文件,该文件将不会被索引;
2.如果你想避免在 CMake 包中配置和构建测试,你可以添加参数:--cmake-args -DBUILD_TESTING=0;
3.如果你想运行某个包中的单独测试,你可以这样:
$colcon test --packages-select YOUR_PKG_NAME --ctest-args -R YOUR_TEST_IN_PKG
本篇完。