对于使用ROS2来讲,编译与节点功能实现是最基本,也是最重要的开发工作,因为ROS2的编译涉及多个工具软件,节点功能实现则涉及C++(当然也包括Python)的复杂的语法规则和ROS2系统的接口,这使得ROS2的开发人员对这两个问题的理解不是很深入。虽然线上很多关于ROS2编译和节点功能实现的资料和文档,很多ROS2的开发人员只是照葫芦画瓢,并没有真正理解ROS2中这两个功能是怎么实现的。因此本文通过典型的实例来详细说明这两个问题。
ROS2中可以使用C++和Python,本文使用C++来进行说明,通过C++理解这两个问题之后,使用Python的ROS2开发道理是一样的。
一、关于ROS2中编译工具的一些基本说明
1.1 关于colcon:
colcon(CMake Order-of-Length CONstraints)是独立于ROS的一个编译工具,colcon可以在ROS2中进行编译,但是colcon不是只能在ROS2进行使用,它可以单独完成编译功能。
colcon的官网:https://colcon.readthedocs.io/
1.2 关于ament_tools:
ament_tools(ament_cmake,ament_python)是供ROS2使用的构建工具,只能在ROS2中使用。
ament_tools是ROS 2中的一个构建工具,主要用于编译、测试、安装和卸载软件包。ament_tools是ament构建系统的一部分,旨在提供一种命令行工具,帮助用户完成功能包的构建和管理工作
历史背景和功能:
ament_tools是ROS 2特定的构建工具,最初是为了与现有的ROS 1软件包并排安装而设计的,因为不同的目标Python版本导致了一些问题。随着ROS 2的发展,ament_tools逐渐被colcon取代,colcon是一个通用的构建工具,能够调用CMake和Python setuptools来完成构建任务。
使用方法和命令:
ament_tools提供了一系列命令来管理软件包的构建和安装,包括:
ament build:编译软件包。
ament test:测试软件包。
ament install:安装软件包。
ament uninstall:卸载软件包。
与其他构建工具的比较:
在ROS 2的早期版本中,ament_tools是主要的构建工具,但在后来的版本中被colcon取代。
1.3 关于colcon与cmake的关系:
Colcon通过调用CMake和其他工具(如Python的setuptools)来完成具体的构建任务。Colcon自动化了构建过程,处理了软件包的依赖关系,并设置了使用软件包的环境。
CMake是一个跨平台的构建系统生成器,用于描述、配置和生成编译系统。在ROS2中,CMake用于生成构建配置文件,如Makefile或项目文件,这些文件随后被用于实际的编译过程。Colcon在构建过程中会调用CMake来生成这些必要的构建文件,并执行实际的编译操作。
具体来说,Colcon通过CMake args(命令行参数)来控制构建过程,例如指定构建类型(如release或debug)、构建工具(如GitHub)等。这些参数帮助简化构建操作,提高构建效率。
1.4 关于colcon与cmake的关系:
colcon和ament_tools是两个不同的工具,但它们在ROS2开发中有着密切的关系。
colcon是一个功能包构建工具,可以用于编译ROS2的代码。它替代了之前的构建工具如catkin_make、catkin_make_isolated和catkin_tools,成为ROS2推荐的构建工具。Colcon通过调用CMake和Python setuptools来完成构建任务。
ament_tools则是一个元工具集,提供了构建系统、测试框架和包管理等功能。ament_tools包括多个组件,如ament_cmake、ament_python等,用于支持ROS2的开发和构建过程。ament_cmake是基于CMake的构建系统,提供了更丰富的功能和更好的集成体验。
简而言之,Colcon是一个构建工具,主要用于编译ROS2的功能包;而ament_tools是一个工具集,包含了构建系统、测试框架和包管理等功能,两者在ROS2开发中各有分工,但相互协作,共同支持ROS2的开发和构建过程。
二、关于编译过程的说明
2.1 用于说明的实例的功能包结构:
2.2 节点的代码:
节点代码文件的文件名为:hello_code_c.cpp
#include "rclcpp/rclcpp.hpp"
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("hello_world_node"); //创建hello_world节点
RCLCPP_INFO(node->get_logger(), "approach1: hello world!!");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
2.3 对cmakelist.txt和package.xml进行修改:
在package.xml中添加依赖项
<depend>rclcpp</depend>
对cmakelist.txt进行修改
修改cmakelist.txt的过程主要涉及4个地方,find_package(),add_executable(), ament_target_dependencies()和install()
cmakelist.txt的完整截图如下图所示:
在这里需要修改的4个地方,其中1区修改的是find_package(),2区和3区分别采用不同的内容对add_executable(), ament_target_dependencies()和install()进行修改的。
2.4 对cmakelist.txt修改内容的解释:
根据这里的cmakelist.txt内容做如下解释:
- find_package()是指节点代码需要包括进来的外部功能包
- add_executable()是将代码文件对应指定可执行文件名(注意,linux系统中的可执行文件不是exe文件),也就是对应代码文件编译之后进行运行时对应的命令,其实际效果相当于windows系统下代码文件编译之后得到的可执行文件对应的文件名,这个指定的名字不一定要与代码文件一致。在ROS中有时把这个名字指定为跟代码中Node对象名字一致,