ROS1ROS2之CmakeList.txt和package.xml用法详解

前言:目前还在学习ROS+无人机框架中,,,
更多更新文章详见我的个人博客主页【前往】

文章目录

    • 1. CMakeLists.txt与package.xml的作用
    • 2. 生成CMakeLists.txt
      • 2.1 ROS1
      • 2.2 ROS2
    • 3. CMakeLists.txt编写
      • 3.1 ROS1
      • 3.2 ROS2
    • 4. package.xml编写
    • 5. 其他--Setup.py的修改

1. CMakeLists.txt与package.xml的作用

ROS系统的功能包中 要包含 CMakeLists.txtpackage.xml 文件来编译功能包的内容

CMakeLists.txt原本是Cmake编译系统的规则文件,而Catkin编译系统基本沿用了CMake的编译风格,只是针对ROS工程添加了一些宏定义。所以在写法上,catkinCMakeLists.txtCMake的基本一致。用cmake命令创建功能包时,会自动生成CMakeList.txt文件,已配置了多数编译选项,且包含详细的注释,只需稍作修改便可编译自己的文件。

package.xml文件是描述功能包清单的文件,包括功能包的名称版本号作者信息许可信息编译依赖运行依赖等。

所以 CMakeLists.txt 非常重要,它指定了由源码到目标文件的规则,catkin编译系统在工作时首先会找到每个package下的 CMakeLists.txt ,然后按照规则来编译构建

2. 生成CMakeLists.txt

2.1 ROS1

ROS1可通过用catkin_create_pkg命令创建功能包,这会自动生成CMakeLists.txtpackage.xml文件的。

# 创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src# 注:std msgs rospy roscpp为创建功能时指定的铱赖,test为包名
# 也可以先不指定,后面在CMakeLists.txt和package.xmL中手动添加
catkin_create_pkg test std_msgs rospy roscpp# 查看一下在~/catkin_ws/src目录下自动生成了哪些文件夹和文件
tree

通过上面的命令生成的工作空间如下

image-20230726150753757

include:存放**.h**的头文件

src:可同时存放**.cpp.py的源文件,但一般.py**文件存放在scripts目录中

scripts:习惯存放**.pypython**文件,需要自己创建

注:python代码和c++代码不分家,可同时存放在同一功能包中

2.2 ROS2

ROS2可通过如下的命令来创建功能包以及必要的CMakeList.txtpackage.xml文件

# 创建工作空间
mkdir -p ~/dev_ws/src
cd ~/dev_ws/src# ament_cmake和ament_python分别代表c++和python两种代码的功能包
# test_c和test_python代表包名
ros2 pkg create --build-type ament_cmake test_c
ros2 pkg create --build-type ament_python test_python# 查看一下在~/dev_ws/src目录下自动生成了哪些文件夹和文件
tree

通过以上命令生成的工作空间如下:

image-20230726151618480

  • test_c/include:存放**.h**的头文件

  • test_c/src:存放**.cppC++**源文件

  • test_python/test_python:存放**.pypython**文件

注:与ROS1不同,同一功能包内只能同时包含python文件或者C++文件中的一种

3. CMakeLists.txt编写

3.1 ROS1

  1. 常用的ROS1CMakeLists.txt架构如下

视频解析参考:中科院软件所-机器人操作系统入门(ROS入门教程)

cmake_minimum_required()	#CMake的最低版本号project()					#项目名称find_package()				#找到编译需要的其他CMake/Catkin	package catkin_python_setup()		#catkin新加宏,打开catkin的Python Module的支持add_message_files()			#catkin新加宏,添加自定义Message文件 add_service_files()         #catkin新加宏,添加自定义Service文件 add_action_files()          #catkin新加宏,添加自定义Action文件 generate_message()			#catkin新加宏,生成不同语言版本的msg/srv/action接口 catkin_package()			#catkin新加宏,生成当前package的cmake配置,供依赖本包的其他软件包调用 add_library()				#生成库 add_executable()			#生成可执行二进制文件add_dependencies()			#定义目标文件依赖于其他目标文件,确保其他目标已被构建 target_link_libraries()		#链接catkin_add_gtest()			#catkin新加宏,生成测试install()					#生成可安装目标

需要自己配置的项目一般就下面几种:

  • include_directories

    • 用于设置头文件的相对路径
    • 全局路径默认为功能包所在目录,功能包的头文件一般放在功能包根目录下的include文件夹,
      所以需要此处添加此文件夹
    • 还包含catkin编译器默认的其他头文件路径,如:ROS默认安装路径、Linux系统路径等
  • add_exectuable

    • 用于设置需要编译的代码和可执行文件
    • 第一个参数为期望生成的可执行文件(节点)名称
    • 后面的参数为参与编译的源文件(.cpp),若需要多个代码文件,可依次列出,空格分隔
  • target_link_libraries

    • 用于设置链接库
    • 有些功需要使用系统或第三方库函数,通过该选项可以配置执行文件链接的库文件
    • 第一个参数与add_exectuable相同,为可执行文件(节点)名称
    • 后面的参数为需要链接的库,依次列出,空格分隔
  • add_dependencies

    • 用于设置依赖
    • 有时候需要自定义消息类型,消息类型会在编译过程中产生相应语言的代码。若编译的可执行文
      件依赖这些动态生成的代码,则需要添加${PROJECT NAME}generate messages_cpp配置
  • 自定义数据类型:消息msg、服务srv、动作action

    • find_package(catkin REQUIRE COMPONENTS message_generation)
    • catkin_package(CATKIN_DEPENDS message_runtime)
    • add_message_files(FILES xxx.msg)
    • add_service_files(FILES xxx.srv)
    • add_action_files(FILES xxx.action)
    • generate_messages(DEPENDENCIES std_msgs)

CMakeLists.txt模板参考:CMakeLists.txt

更多教程参考:catkin/CMakeLists.txt - ROS Wiki

3.2 ROS2

常用的ROS2CMakeLists.txt架构如下

cmake_minimum_required()			#CMake的最低版本号project()				  		   #项目名称find_package()   				    #查找系统中的依赖项ament_target_dependencies()          #依赖于其他目标文件,确保其他目标已被构建 add_executable()				    #生成可执行二进制文件install()						   #生成可安装目标ament_package()						#生成功能包rosidl_generate_interfaces()		# 自定义消息类型接口

示例模板如下

cmake_minimum_required(VERSION 3.5)
project(test_c)# Default to C99
if(NOT CMAKE_C_STANDARD)set(CMAKE_C_STANDARD 99)
endif()# Default to C++14
if(NOT CMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD 14)
endif()if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)add_executable(talker src/publisher_member_function.cpp)	# 修改2
ament_target_dependencies(talker rclcpp std_msgs)			# 修改3install(TARGETStalker												# 修改4DESTINATION lib/${PROJECT_NAME})if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)# the following line skips the linter which checks for copyrights# uncomment the line when a copyright and license is not present in all source files#set(ament_cmake_copyright_FOUND TRUE)# the following line skips cpplint (only works in a git repo)# uncomment the line when this package is not in a git repo#set(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()
endif()# 添加自定义消息类型需要添加项
find_package(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"msg/Num.msg"				# 自定义1"msg/Sphere.msg"			# 自定义2"srv/AddThreeInts.srv"     # 自定义3DEPENDENCIES geometry_msgs
)ament_package()

相较于基于catkinCMake文件,基于ament的明显简洁很多

假设你编写了~/dev_ws/src/test.cpp文件后,需要修改的步骤如下:

  1. 链接源代码
add_executable(test src/test.cpp)	# test为你输入节点后执行的名称,如ros2 run test_c test(前一个test_c为包名,后一个test则为这里的设置的名称,代表具体执行的代码)
ament_target_dependencies(test rclcpp)	# 添加依赖项
  1. 添加下面这两行代码的目的是让编译器编译~/dev_ws/src/test_c/test.cpp这个文件
install(TARGETStestDESTINATION lib/${PROJECT_NAME}
)

当你自定义消息类型时还需要消息类型文件

# 添加自定义消息类型需要添加项
# 下面两项是固定的,geometry_msgs是用于生成消息依赖包
find_package(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"msg/Num.msg"				# 自定义1"msg/Sphere.msg"			# 自定义2"srv/AddThreeInts.srv"     # 自定义3DEPENDENCIES geometry_msgs
)

4. package.xml编写

package.xml的框架如下

<package format="3"><name>..</name><version>0.0.0</version><description>...</description><maintainer email="lanhanba@todo.todo">...</maintainer><license>...</license><buildtool_depend>...</buildtool_depend><exec_depend>...</exec_depend><exec_depend>...</exec_depend><export><build_type>...</build_type></export>
</package>

相较于CMakeList.txtpackage.xml的语法就简单许多,且ROS1ROS2的标签语法通用

  • <build_depend></build_depend>: 标签定义了功能包中代码编译时所依赖的其他功能包
  • <exec_depend><exec_depend>: 标签定义了功能包中可执行程序运行时所依赖的其他功能包
  • 自定义数据类型:话题消息msg、服务数据srv、动作数据action

模板如下

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"><name>test_c</name><version>0.0.0</version><description>TODO: Package description</description><maintainer email="lanhanba@todo.todo">lanhanba</maintainer><license>TODO: License declaration</license><!-- ROS1 --><buildtool_depend>catkin</buildtool_depend><build_depend>roscpp</build_depend><build_depend>rospy</build_depend><build_depend>std_msgs</build_depend><build_export_depend>roscpp</build_export_depend><build_export_depend>rospy</build_export_depend><build_export_depend>std_msgs</build_export_depend><exec_depend>roscpp</exec_depend><exec_depend>rospy</exec_depend><exec_depend>std_msgs</exec_depend><!-- ROS2_C++ --><buildtool_depend>ament_cmake</buildtool_depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export><!-- ROS2_python --><test_depend>ament_copyright</test_depend><test_depend>ament_flake8</test_depend><test_depend>ament_pep257</test_depend><test_depend>python3-pytest</test_depend><export><build_type>ament_python</build_type></export><!-- ROS2中C++功能包添加自定义消息类型还需添加下面三行(固定形式,和上面的CMake修改搭配使用,python不需要) --><depend>rosidl_default_generators</depend><depend>geometry_msgs</depend><member_of_group>rosidl_interface_packages</member_of_group></package>

5. 其他–Setup.py的修改

ROS2-Python功能包中,如果添加类似~/dev_ws/src/test_python/test.pypython文件,则需要对功能包中的Setup.py进行如下的修改

from setuptools import setuppackage_name = 'test_python'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),],install_requires=['setuptools'],zip_safe=True,maintainer='lanhanba',maintainer_email='lanhanba@todo.todo',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': [# 结构如下:节点名 = 功能包名.代码文件.执行入口函数名(一般执行入口函数名都是main,也就是说python代码中一般要有main函数)# 通过ros2 run test_python test 来执行test_python.test:main下的函数# 如果有多个python代码文件都需要一一添加,名称不能一样"test = test_python.test:main","test2 = test_python.test2:main"],},
)

参考:

  • catkin/CMakeLists.txt - ROS Wiki

  • CMakeLists.txt - ROS Humble Wiki

  • 【ROS 学习笔记】CMakeLists.txt 与 package.xml - 知乎 (zhihu.com)

  • 详细分析一个ROS2 CMakeLists.txt文件_首飞爱玩机器人的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python:给MySQL创建1000张表和创建1张有50个字段的表

1、创建1000张表 import pymysqldbhost "10.1.1.143" dbuser "root" dbpassword "123456" dbname "demo_cg1000" dbport 3306 dbconn pymysql.connect(hostdbhost, userdbuser, passworddbpassword, dbdbname, portdbport)mycu…

深入学习 Redis - 基于 Spring Data Redis 操作 Redis

目录 一、前置工作 1.1、引入 Spring Data Redis 依赖 1.2、编写配置文件 二、Spring Data Redis 2.1、前置知识 2.2、演示 Demo 一、前置工作 1.1、引入 Spring Data Redis 依赖 1.2、编写配置文件 spring:redis:host: 127.0.0.1port: 8888二、Spring Data Redis 2.1、…

【粒子群算法和蝴蝶算法组合】粒子群混沌混合蝴蝶优化算法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

20.1 HTML 介绍

1. W3C组织 万维网联盟(World Wide Web Consortium, W3C): 是一个国际性的标准化组织, 致力于开发和推广Web标准.W3C的使命是通过制定和推广Web技术标准, 促进Web的长期发展和互操作性, 它由许多组织和个人组成, 包括浏览器制造商, 软件开发商, 网络服务提供商, 学术机构和个…

C++ 哈希的应用【布隆过滤器】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2022 版本 17.6.5 文章目录 &#x1f307;前言&#x1f3d9;️正文1、字符串比较2、布隆过滤器的概念3、布隆过滤器的实现3.1、基本结构3.2、插入…

一、Postfix[安装与配置、smtp认证、Python发送邮件以及防垃圾邮件方法、使用腾讯云邮件服务]

Debian 11 一、安装 apt install postfix 二、配置 1.dns配置 解释&#xff1a;搭建真实的邮件服务器需要在DNS提供商那里配置下面的dns 配置A记录mail.www.com-1.x.x.x配置MX记录www.com-mail.www.com 解释&#xff1a;按照上面的配置通常邮件格式就是adminwww.com其通过…

Python 教程之标准库概览

概要 Python 标准库非常庞大&#xff0c;所提供的组件涉及范围十分广泛&#xff0c;使用标准库我们可以让您轻松地完成各种任务。 以下是一些 Python3 标准库中的模块&#xff1a; 「os 模块」 os 模块提供了许多与操作系统交互的函数&#xff0c;例如创建、移动和删除文件和…

C#,中国福利彩票《刮刮乐》的数学算法(02)——时来运转

1 中国福利彩票 中国福利彩票始于1987年7月27日&#xff0c;以“团结各界热心社会福利事业的人士&#xff0c;发扬社会主义人道主义精神&#xff0c;筹集社会福利资金&#xff0c;兴办残疾人、老年人、孤儿福利事业和帮助有困难的人”、即“扶老、助残、救孤、济困”为宗旨。随…

【C++进阶:哈希--unordered系列的容器及封装】

本课涉及到的所有代码都见以下链接&#xff0c;欢迎参考指正&#xff01; practice: 课程代码练习 - Gitee.comhttps://gitee.com/ace-zhe/practice/tree/master/Hash unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在…

拓扑排序详解(带有C++模板)

目录 介绍&#xff1a; 实现原理&#xff1a; 简答来说&#xff1a; 例子 模板&#xff08;C&#xff09; 介绍&#xff1a; 拓扑排序&#xff08;Topological Sorting&#xff09;是一种针对有向无环图&#xff08;DAG&#xff09;的节点进行排序的算法。DAG是一个图&…

PHP数据库

PHP MySQL 连接数据库 MySQL 简介MySQL Create 免费的 MySQL 数据库通常是通过 PHP 来使用的。 连接到一个 MySQL 数据库 在您能够访问并处理数据库中的数据之前&#xff0c;您必须创建到达数据库的连接。 在 PHP 中&#xff0c;这个任务通过 mysql_connect() 函数完成。 …

Linux环境安装MySQL(详细教程)

1、下载MySQL MySQL官网&#xff1a;MySQLhttps://www.mysql.com/ 下载社区版&#xff08;免费&#xff0c;但不提供技术支持&#xff09; 简单说明一下rpm和tar包的区别&#xff1a; tar 只是一种压缩文件格式&#xff0c;所以&#xff0c;它只是把文件压缩打包 rpm&#xf…

【字节跳动青训营】后端笔记整理-3 | Go语言工程实践之测试

**本文由博主本人整理自第六届字节跳动青训营&#xff08;后端组&#xff09;&#xff0c;首发于稀土掘金&#xff1a;&#x1f517;Go语言工程实践之测试 | 青训营 目录 一、概述 1、回归测试 2、集成测试 3、单元测试 二、单元测试 1、流程 2、规则 3、单元测试的例…

我的第一个flutter项目(Android Webview)

前言&#xff1a;flutter开发环境搭建Flutter的开发环境搭建-图解_☆七年的博客-CSDN博客 第一个flutter简单项目&#xff0c;内容是一个主界面&#xff0c;其中&#xff1a; 1.内容点击数字自增 2.跳转一个空页&#xff0c; 3.跳转一个WebView界面 其中涉及添加主键&#xf…

QT: 用定时器完成闹钟的实现

闹钟项目&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QDebug> #include <QTextToSpeech> #include <QMessageBox> #include <QTimer>QT_BEGIN…

Quartz项目搭建与任务执行源码分析

数据库准备 准备一个MySQL数据库&#xff0c;版本为8.0&#xff0c;然后创建一个库&#xff0c;并从quartz官方的版本包中找到名称为tables_mysql_innodb.sql的脚本执行进去&#xff08;脚本内容文后也有提供&#xff09;。 项目依赖说明 创建一个Maven项目&#xff0c;引入…

gitignore文件使用方法(gitignore教程)(git status --ignored)(git check-ignore -v <file>)

文章目录 Gitignore文件使用描述Gitignore基本语法1. 基本语法★★★★★2. 配置方法 匹配示例示例1示例2示例3 其他命令git status --ignored&#xff08;用于显示被Git忽略的文件和文件夹的状态&#xff09;git check-ignore -v <file>&#xff08;用于检查指定文件是否…

一个灵活、现代的Android应用架构

一个灵活、现代的Android应用架构 学习Android架构的原则&#xff1a;学习原则&#xff0c;不要盲目遵循规则。 本文旨在通过示例演示实际应用&#xff1a;通过示范Android架构来进行教学。最重要的是&#xff0c;这意味着展示出如何做出各种架构决策。在某些情况下&#xff0…

网络层IP协议的基本原理 数据链路层ARP协议 域名解析以及一些重要技术

目录 1 网络层IP协议协议头格式网段划分DHCPCIDR&#xff1a;基于子网掩码的划分方式特殊的IP号IP地址的数量限制私有IP地址和公网IP地址路由路由表 2 数据链路层 — 局域网的转发问题以太网认识以太网以太网帧格式局域网通信原理 MTUMTU对IP协议的影响MTU对UDP协议的影响MTU对…

人类文明进入下个纪元奇点:UFO听证会-恒温超导发现-GPT大模型

今年以来&#xff0c;科技领域出圈的事件频繁发生&#xff0c;每一个事件都意味着一个领域的重大突破的可能。这些事件是UFO听证会、恒温超导LK99的论文、GPT类大模型的广泛应用&#xff0c;我常将这些事件串在一起思考&#xff0c;细思极恐&#xff0c;一种”火鸡与农场主“的…