catkin_package的作用

总结

为了方便使用,把结论和代码放在前面,而讲解放在后面。

  • CMakeLists:在catkin_make期间生成文件,如xxxConfig.Cmake导出本包的资源 加入到catkin_INCLUDE_DIRScatkin_LIBRARIESfind_package本包依赖所需依赖(包含依赖包并不会递归其依赖的子包为依赖,因为CMakeLists是独立的)
  • Package.xml:是了解一个包的所有入口,依赖项可以用来解决包之间的编译和执行顺序,包含某个包会自动递归其所依赖的子包作为依赖
  • 因此在Package.xml声明依赖(包间依赖关系)和CMakeLists中find_package(包所需依赖)都要有,否则前者导致编译顺序出错,后者导致无头文件目标文件链接失败

应用包中:

CMakeLists:

find_package(catkin REQUIRED COMPONENTS
        my_dep
)

include_directories(include ${catkin_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES})

---

Package.xml:

  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>my_dep</build_depend>
  <exec_depend>my_dep</exec_depend>

被依赖包中:

CMakeLists:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES my_dep
#  CATKIN_DEPENDS ros_cpp ros_py std_msgs
#  DEPENDS system_lib
)

---

Package.xml:

  <buildtool_depend>catkin</buildtool_depend>

  按实际需求填写

提示:如果用clion可能发生终端中catkin_make能通过,但是clion中自动cmake栏提示找不到依赖包,可能可以通过关闭当前clion,从对于source过的ws启动clion来解决


前言

在开发ROS程序时,有时候希望把一个流程通过分成几个包来完成,比如点云物体识别时

  • 获取数据进行预处理和拼接
  • DNN部分包
  • 输出处理可视化和其他后期功能
  • ...

但是以上各个part的连接,需要每个包中都有一个node且包含topics/srv/action等这样才能在ros中交互。当软件比较复杂的时候,可能还会分的更细,这样我们就会有一堆的node,虽然说可以通过launch文件来进行批量启动,但是还存在几个问题:

  • 不整洁,起码看着很冗余。
  • 通信是要占用资源的,让费。
  • ...

因此除非是两个part之间是不同语言完成的,比如DNN部分用pytorch而某个部分是cpp库写的,这样整合两个不同语言的程序用两个node来连接是可以接受的。


但是如果只是单纯的想把一个Cpp程序干净的分为几个part,那么不妨使用本文的方法,即创建的package只包含lib而不含node可执行文件(好像没差)。


其实直接在某个包内把源文件生成各种lib然后手动链接也是一样的。

target_link_libraries(${PROJECT_NAME}_node
        oslam ${ALL_LIBS}
        )

但是写成ROS库就可像调ROS的API一样,更具有通用性?更具有移植性?更贴近ROS框架?

find_package(catkin REQUIRED COMPONENTS
        my_dep
        ...
)
#然后所有的ROS依赖包头文件和库文件都包含在宏 ${catkin_INCLUDE_DIRS} ${catkin_LIBRARIES}

背景

首先资料放送:catkin详解0catkin详解1catkin详解2ROS包形式2详解

然后我们知道ROS包中有两个文件是重要的

  • CMakeLists.txt是cmake编译框架下的文件,而catkin是cmake加入了一些宏命令来适配ROS(个人理解)。因此在CMakeLists中写入catkin支持的宏如catkin_package add_service_files generate_messages等会自动帮你生成一些文件
  • package.xml才是ROS包的命根子,无论是rospack rosruncatkin_make等ros中用的命令,甚至是roslaucnh 中的$(find package)都是通过搜索ros_path下的所有文件夹中的package.xml的。然后通过该文件来获取程序包信息。


CMakeLists

然后我们来看看CMakeLists在catkin编译系统下相比cmake编译系统下有哪些特殊的点

首先就是多了:

find_package(catkin REQUIRED COMPONENTS
        ...
)

和普通cmake下一样,find_package来寻找catkin环境中xxxConfig.Cmake来寻找ROS包,比如roscpp rospy std_msgs。然后将找到的包中在xxxConfig.Cmake中指定头文件和库文件等依赖包含到对应的${catkin_INCLUDE_DIRS} ${catkin_LIBRARIES}中。而xxxConfig.Cmake文件是在ws中进行catkin_make会自动生成的文件 。在cmake体系中,find_package能找到的包,一般都是在cmake搜索目录如/usr/local/lib/cmake(也可以自己设定cmake的Module路径)搜对应的xxxConfig.cmakefindxxx.cmake


然后是

#生产 消息类型/服务类型/动作类型的宏
 add_message_files(FILES Message1.msg)
 add_service_files( FILES Service1.srv)
 add_action_files(FILES Action1.action )
 generate_messages(DEPENDENCIES std_msgs)


再就是在add_libraryadd_exacutable前调用的

catkin_package(
  INCLUDE_DIRS include   #- 导出包的include路径
  LIBRARIES my_dep_app   #- 导出项目中的库
  CATKIN_DEPENDS my_dep  #- 该项目依赖的其他catkin项目
  DEPENDS system_lib     #- 该项目所依赖的非catkin CMake项目,如普通的opencv库。
)

如果指定了INCLUDE_DIRSLIBRARIEScatkin_make产生对应xxxConfig.Cmake时会此处的include目录本库产生的库文件加入到xxxConfig.Cmake的list中如下图

然后别的包通过find_package就可以在那两个宏中得到所依赖库对应的头文件和库文件。

package.xml

其余信息都比较显然这里说说比较特殊的也就是依赖项,我们知道catkin_make的时候每个包或说CMakeLists是作为一个个体进行独立编译的,而且编译顺序是按字母排序的即它不知道那些包之间有先后关系。如果你的功能包依赖于某个catkin库则需要在package.xml的依赖中写清楚,这样catkin_make的时候就会自动帮你把顺序捋清楚咯。

否则会编译顺序出错导致其他包的 xxxConfig.Cmake文件还未生产,无法find_package找到

其中depend =build_depend+exec_depend

  <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>

  • buildtool_depend:指定编译工具为catkin
  • build_depend:编译时依赖,比如message_generation先编译所依赖的包再编译本包
  • build_export_depend:编译导出依赖,本包需要导出(被依赖),因此被导出的那部分的依赖为。
  • exec_depend:执行依赖(解释性语言如python脚本只需要填写这个而无需填写两个build依赖)比如message_runtime 是用来生成ros-msg消息代码的python文件

当你在xml中depend某个包,那么被依赖的包的依赖也会被导入到当前包中可用rospack depend xxx查询

如果不加build_depend可能也能编过,这是因为命名使得默认顺序对了,但是谁能保证命名不同后顺序一直是对的呢?


此外package.xml下的export标签用处可以看看这个pluginlib

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值