大家好,感谢邀请,今天来为大家分享一下【ROS2基础知识】系列第八篇——深入解析ROS2文件系统的问题,以及和的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!
1.2 文件结构介绍
ROS2工作空间的文件结构由四个目录组成,分别是build/、install/、src/、log/、其中src/目录下存放最小ROS2构建部件成为功能包package。ROS2工作空间的文件结构src:代码空间、以后编写的代码,脚本需要人为放置在这里;build:编译空间,保存编译过程中产生的中间文件;install:安装空间,放置编译得到的可执行文件和脚本;log:日志空间,保存编译、运行过程中的各种警告、错误、信息等日志。一般来说,我们对这四个空间文件夹的操作大部分都是在src、编译成功后,就会执行install里边的结果中进行的,build和log文件夹很少使用。
二、软件包package
任何ROS2代码,无论是C++还是Python,都必须放在包中才能正常编译和运行。
一个包可以编译多个目标文件(可执行程序、动静态库、头文件等)。
2.1 package结构
包下常见的文件路径有:
CMakeLists.txt #package编译规则(必填)
package.xml #包描述信息(必填)
src/#源代码文件
include/#C++头文件
脚本/#可执行脚本
msg/#自定义消息
srv/#定制服务
models/#3D模型文件
urdf/#urdf 文件
launch/#启动文件其中定义package的是CMakeLists.txt和package.xml,这两个文件是package中必不可少的。在编译之前,colcon编译系统首先要解析这两个文件。这两个文件定义了一个包。
CMakeLists.txt:定义包的包名、依赖、源文件、目标文件等编译规则。它是软件包中不可缺少的组成部分。
package.xml:描述包的包名、版本号、作者、依赖等信息。它是软件包中不可缺少的组成部分。
src/:存放ROS源代码,包括C++源代码(.cpp)和Python模块(.py)
include/:存放C++源代码对应的头文件
script/:存放可执行脚本,如shell脚本(.sh)、Python脚本(.py)
msg/:以自定义格式存储消息(.msg)
srv/:以自定义格式存储服务(.srv)
models/:存储机器人或模拟场景的3D模型(.sda、stl、dae等)
urdf/:存储机器人模型描述(.urdf或.xacro)
launch/:存储启动文件(.launch 或.xml)
通常ROS文件是按照上述形式组织的。这是常见的命名约定,建议遵循它。上述路径中,仅需要CMakeLists.txt和package.xml,其余路径根据是否需要软件包而定。
2.2 package的创建
创建包需要使用catkin_ws/src下的ros2 pkg命令。用法是:
ros2 pkg create--build-type {cmake,ament_cmake,ament_python} --依赖项
其中就是包名。 --build-type 用于指定包的编译类型。共有三个可选选项:ament_python、ament_cmake 和cmake。 --dependencies 指的是这个功能包的依赖关系,可以依赖多个软件包。
为ROS2 创建C++ 包
ros2 pkg create --build-type ament_cmake
为ROS2创建一个python包
ros2 pkg create --build-type ament_python
例如,创建一个名为test_pkg 的新包,该包依赖于rclccpp(公共依赖项)。
ros2 pkg 创建example_cpp --build-type ament_cmake --dependencies rclcpp
这会在当前路径下创建一个新的test_pkg软件包,包括:
CMakeLists.txt
包括
test_pkg
包.xml
srcros2 pkg已经完成了软件包的初始化,填充了CMakeLists.txt和package.xml,并将依赖项填充到了这两个文件中。
三、CMakeLists.txt文件
3.1 CMakeLists.txt作用
CMakeLists.txt原本是Cmake编译系统的规则文件,colcon编译系统基本遵循CMake编译风格,但添加了一些针对ROS2项目的宏定义。所以在写法上,colcon的CMakeLists.txt和CMake的基本一样。
这个文件直接规定了这个包依赖哪些包,要编译生成哪些目标,如何编译等过程。因此,CMakeLists.txt非常重要。它指定了从源代码到目标文件的规则。 colcon编译系统工作时,首先会找到各个包下的CMakeLists.txt,然后按照规则进行编译构建。
3.2 CMakeLists.txt写法
CMakeLists.txt 的基本语法仍然遵循CMake,但colcon 添加了少量宏。整体结构如下:
cmake_minimum_required() #CMake版本号
project() #项目名称
find_package() #查找编译所需的其他CMake/Catkin包
add_message_files() #新建宏,添加自定义Message/Service/Action文件
添加服务文件()
添加动作文件()
generate_message() #新增宏生成不同语言版本的msg/srv/action接口
add_library() #生成库
add_executable() #生成可执行二进制文件
add_dependency() #定义目标文件依赖于其他目标文件,以确保其他目标已经构建
ament_target_dependency() #新增宏,将使得依赖库、头文件以及自身的依赖能够正常找到
target_link_libraries() #link
install() #安装到本机
ament_package # 新添加的宏,安装项目,CMakeLists.txt文件中最后一次调用。
3.3 CMakeLists例子
第一条语句指定cmake的最低版本,第二条语句设置构建的函数包的名称。注意此名称必须与package.xml中的名称一致。
cmake_minimum_required(版本3.5)
project(nav2_costmap_2d) 接下来,查找系统中的依赖项。此外,在构建库或执行文件时需要添加这些依赖项。
find_package(需要ament_cmake)
find_package(需要几何消息)
find_package(需要激光几何)
find_package(需要map_msgs)
find_package(需要消息过滤器)
find_package(nav2_common 必需)
find_package(需要nav2_msgs)
find_package(需要nav2_util)
find_package(需要nav2_voxel_grid)
find_package(需要nav_msgs)
find_package(需要插件库)
find_package(rclcpp 必需)
find_package(rclcpp_lifecycle 必需)
find_package(需要rmw)
find_package(需要sensor_msgs)
find_package(需要std_msgs)
find_package(需要tf2_geometry_msgs)
find_package(tf2 必需)
find_package(tf2_ros 必需)
find_package(需要tf2_sensor_msgs)
find_package(需要可视化消息)
find_package(angles REQUIRED)添加非ROS2功能包依赖时,需要在include_directories中指定头文件路径。当依赖为ROS2功能包时,无需执行此操作。
find_package(需要Eigen3)
包含目录(
包括
${EIGEN3_INCLUDE_DIRS}
)add_library 语句用于构建库。正如您所看到的,下面使用了两个不同的语句来添加依赖项。 ament_target_dependencies 是官方推荐的添加依赖项的方式。会导致依赖的库、头文件以及自身的依赖能够正常找到。
一般来说,如果依赖是ROS2功能包,则使用ament_target_dependencies。如果功能包有多个库,也会包含在内。
target_link_libraries添加依赖项目时需要指明具体库的名称。换句话说,添加的每个项目都是一个库。例如,下面的nav2_costmap_2d_core 添加了libnav2_costmap_2d_core.so 库。
add_executable 用于构建可执行文件。
add_library(nav2_costmap_2d_core 共享
src/array_parser.cpp
src/costmap_2d.cpp
src/layer.cpp
src/layered_costmap.cpp
src/costmap_2d_ros.cpp
src/costmap_2d_publisher.cpp
src/costmap_math.cpp
src/足迹.cpp
src/costmap_layer.cpp
src/observation_buffer.cpp
src/clear_costmap_service.cpp
src/footprint_collision_checker.cpp
src/costmap_collision_checker.cpp
src/costmap_collision_checker_ros.cpp
插件/costmap_filters/costmap_filter.cpp
)
设置(依赖项
几何消息
激光几何
地图消息
消息过滤器
nav2_消息
导航2_util
nav2_voxel_grid
导航消息
插件库
RCCP
rclcpp_生命周期
传感器消息
标准消息
tf2
tf2_geometry_msgs
tf2_ros
tf2_传感器_消息
可视化消息
角度
)
ament_target_dependency(nav2_costmap_2d_core
${依赖项}
)
add_library(共享层
插件/inflation_layer.cpp
插件/static_layer.cpp
插件/obstacle_layer.cpp
src/observation_buffer.cpp
插件/voxel_layer.cpp
插件/range_sensor_layer.cpp
)
ament_target_dependency(层
${依赖项}
)
target_link_libraries(层
nav2_costmap_2d_core
)
add_library(过滤共享
插件/costmap_filters/keepout_filter.cpp
插件/costmap_filters/speed_filter.cpp
)
ament_target_dependency(过滤器
${依赖项}
)
target_link_libraries(过滤器
nav2_costmap_2d_core
)
add_library(nav2_costmap_2d_client 共享
src/footprint_subscriber.cpp
src/costmap_subscriber.cpp
src/costmap_topic_collision_checker.cpp
)
ament_target_dependency(nav2_costmap_2d_client
${依赖项}
)
target_link_libraries(nav2_costmap_2d_client
nav2_costmap_2d_core
)
add_executable(nav2_costmap_2d_markers src/costmap_2d_markers.cpp)
target_link_libraries(nav2_costmap_2d_markers
nav2_costmap_2d_core
)
ament_target_dependency(nav2_costmap_2d_markers
${依赖项}
)
add_executable(nav2_costmap_2d_cloud src/costmap_2d_cloud.cpp)
target_link_libraries(nav2_costmap_2d_cloud)
nav2_costmap_2d_core
)
add_executable(nav2_costmap_2d src/costmap_2d_node.cpp)
ament_target_dependency(nav2_costmap_2d
${依赖项}
)
target_link_libraries(nav2_costmap_2d
nav2_costmap_2d_core
层数
过滤器
)最后还有安装库、可执行文件等文件的语句。它将在install/nav2_costmap_2d/lib 中安装库文件,在install/nav2_costmap_2d/lib/nav2_costmap_2d 中安装可执行文件,并在share/${PROJECT_NAME} 下的/中安装头文件、启动文件和参数文件。
安装(目标
nav2_costmap_2d_core
层数
过滤器
nav2_costmap_2d_client
存档目标库
库目标库
运行时目标箱
)
安装(目标
nav2_costmap_2d
nav2_costmap_2d_markers
nav2_costmap_2d_cloud
运行时目标lib/${PROJECT_NAME}
)
安装(文件costmap_plugins.xml
DESTINATION 分享/${PROJECT_NAME}
)
安装(目录包括/
目的地包括/
)
安装(
目录包括启动参数
DESTINATION 分享/${PROJECT_NAME}
)效果如下:
如果想让其他函数包链接到库文件可执行文件中的这些库,就必须使用下面的语句来声明这些函数包的头文件以及这些库的位置,以便其他函数包能够成功找到对应的当它们依赖于这些函数包时,头文件。和库文件。还可以使用ament_export_dependencies 命令,该命令将依赖项导出到下游包。这样,库的用户就不必为这些依赖项调用find_package 。
ament_export_include_directories(包括)
ament_export_libraries(图层过滤器nav2_costmap_2d_core nav2_costmap_2d_client)
声明ament_export_dependency(${dependencies})后,其他函数包只需要使用以下两条命令即可链接到这些库!
find_package(需要nav2_costmap_2d)
ament_target_dependency(示例_节点
nav2_costmap_2d
)如果该库可以被其它工作空间(不在同一个工作空间下)功能包使用,或者这些库可以作为插件使用,则可以导出插件描述文件,以便其他工作区包调用pluginlib:ClassLoader类来查找插件这些包的ins。
pluginlib_export_plugin_description_file(nav2_costmap_2d costmap_plugins.xml) 最后,项目安装是通过ament_package() 完成的,并且每个包必须执行一次此调用。 ament_package() 安装package.xml 文件,使用ament 索引注册包,并安装CMake 的配置(可能还有目标)文件,以便其他包可以使用find_package 找到该包。由于ament_package()从CMakeLists.txt文件中收集了大量信息,因此它应该是CMakeLists.txt文件中的最后一个调用。
ament_package()
四、package.xml文件
package.xml也是colcon的package的必备文件。是该软件包的描述文件,用于描述该软件包的基本信息。
4.1 package.xml作用
pacakge.xml包含包名、版本号、内容描述、维护者、软件许可证、编译和构建工具、编译依赖、运行依赖等信息。
事实上,ros2 pkg find、rosdep等命令之所以能够快速定位并分析包的依赖信息,是因为它们直接读取每个pacakge中的package.xml文件。它为用户提供了一种快速了解软件包的方法。
4.2 package.xml写法
pacakge.xml遵循xml标签文本的书写方法。由于版本的变化,现在有两种格式并存(format1和format2),但区别不大。旧版本(format1)的pacakge.xml通常包含以下标签:
根标签文件包名版本号内容描述维护者软件许可证编译构建工具,通常是catkin编译依赖,以及Catkin中的运行依赖。 1-6是必需的标签,1是根标签,其余的是嵌套的所有标签,2-6是包的各种属性,7-9是编译相关信息。
在新版本(format2)中,包含的标签有:
根标签文件包名版本号内容描述维护者软件许可编译构建工具,通常为catkin指定的依赖是编译、导出、运行所需的依赖。最常用的编译依赖导出依赖运行依赖测试用例依赖文档依赖:从中可以看到,新版的pacakge.xml格式增加了、相当于对之前的构建和运行依赖描述进行了细分。
目前,ROS 和ROS2 都支持两个版本的package.xml,因此无论您选择哪种格式都可以。
4.3 pacakge.xml例子
以turtlesim软件包为例,其pacakge.xml文件内容如下
?xml version="0.0"?turtlesim0.0.0turtlesim ros2 package.sukhaApache License 2.0ament_cmakerosidl_default_generatorsrclcppstd_msgsgeometry_msgslibqt4-devqt4-qmakermw_implementation_cmakerosidl_default_runtimeament_cmake 这个例子是pacakge.xml的新版本,pacakge是根标签,写在外面。 format属性为2,表示是新版本的格式。编译工具是ament_cmake。使用depend来集成build_depend和run_depend。 build_depend标签保持不变,run_depend需要改为exec_depend。同时,将包导出。 ament_cmake的构建类型表明它是一个C++类型的函数包。
五、其它常见文件类型
在ROS2的软件包中,还有许多其他常见的文件类型。这是一个总结。
5.1 launch文件
ROS2中的启动文件有三种类型,分别是python、xml和yaml。其中,ROS2官方推荐使用python编写launch文件。
它将ROS 需要运行的程序打包并通过单个命令启动它们。一般来说,launch文件会指定要启动哪些包下的哪些可执行程序、用什么参数启动以及一些管理控制命令。 launch文件通常放在软件包的launch/路径下。
5.2 msg/srv/action文件
ROS2程序中可能存在一些定制的消息/服务/动作文件,这些文件是为程序开发人员设计的数据结构。此类文件以.msg、srv、action 结尾,通常放置在包msg/,srv/,action/path 中。
5.3 urdf/xacro文件
urdf/xacro 文件是机器人模型的描述文件,以.urdf 或.xacro 结尾。它定义了机器人连杆和关节的信息,以及它们之间的位置、角度等信息。机器人的物理连接信息可以通过urdf文件来表达。并在可视化调试和仿真中显示。
5.4 yaml文件
yaml文件一般存放ROS2需要加载的参数信息以及一些属性的配置。通常在启动文件或程序中读取.yaml文件并将参数加载到参数服务器中。通常我们将yaml文件存储在param/path中
5.5 dae/stl文件
dae 或stl 文件是3D 模型文件。机器人的urdf或者仿真环境通常指的是这样的文件,它描述了机器人的三维模型。与urdf文件简单定义的特点相比,dae/stl文件可以定义复杂的模型,机器人装配模型可以直接从solidworks或其他建模软件中导出,从而呈现出更精确的外观。
【ROS2基础知识】系列第八篇——深入解析ROS2文件系统和的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!
【【ROS2基础知识】系列第八篇——深入解析ROS2文件系统】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于到了跟进ROS2文件系统这一块
有19位网友表示赞同!
看这标题就知道是讲如何组织ROS2项目的文件结构了,我很久没用ROS2了要来复习一下知识点
有17位网友表示赞同!
希望能详细解释一下ROS2区别于ROS1 File System的地方
有10位网友表示赞同!
我的项目一直使用的是ROS1文件系统,这个 系列文章能让我了解如何迁移到ROS2吗?
有19位网友表示赞同!
最近研究ROS2遇到了一些文件组织问题,期待这篇文章能够给我一些解答
有8位网友表示赞同!
文件管理是机器人程序开发中很重要的环节,对ROS2的理解必不可少
有7位网友表示赞同!
看了前几期的文章,这个系列讲解得很到位了。继续保持啊!
有13位网友表示赞同!
希望讲解能包含常见ROS代码的存放位置和命名规范等细节
有15位网友表示赞同!
要了解如何管理多个包之间互相关联的文件
有9位网友表示赞同!
这篇 ROS2 文件系统 的文章,是不是对初学者比较友好?
有15位网友表示赞同!
文件格式和符号链接的使用方法也是我关心的点!
有15位网友表示赞同!
ROS2的file system 是基于哪些规范设计的?比如POSIX吗?”
有12位网友表示赞同!
想要了解如何使用工具管理工程目录结构
有11位网友表示赞同!
希望能看到一些实际案例来演示不同类型文件的组织方式
有10位网友表示赞同!
学习ROS2文件系统可以帮助我写更规范和易维护的代码
有10位网友表示赞同!
看了标题,感觉内容很实用的!
有13位网友表示赞同!
文章有没有说明包管理器在文件管理中的角色?
有12位网友表示赞同!
这篇文章是不是会介绍一些文件系统安全方面的知识?
有15位网友表示赞同!
期待能学到如何进行高效的文件搜索和管理
有11位网友表示赞同!
ROS2 文件系统的优势在哪里,相对于 ROS1 来说有什么改进?
有6位网友表示赞同!