一文讲透,ROS2工程引入第三方库,如何编写CMakeList.txt

一文讲透,ROS2工程引入第三方库,如何编写CMakeLists.txt

大家好,我是爱学习爱劳动的小鱼,今天换个口味,来点ROS 2 跟工程实践相关的。

具体需求是这样的,最近的项目有用到 USB 转 CAN 的设备,用的驱动是几个 .so 的动态链接库。

最终部署的平台有amd64和arm64之分,开发的时候用的电脑是amd64架构,最终使用的是 arm64 系统。

所以这里就涉及了两个问题

1.如何在 ROS 2 的工程中引入第三方的CAN驱动库

2.针对不同平台,如何编写CMake 实现,自动根据平台选择动态库

对于第一个问题,我们知道,在创建ROS 2功能包的时候,自动选择的构建类型是 ament_cmake

ament_cmake 链接库的方式是使用 ament_target_dependencies

CMakeLists.txt 默认使用链接库的方式是 target_link_libraries

所以你可以认为 ament_target_dependencies 是专门用于链接ROS 2 的库, target_link_libraries 用于链接普普通通的第三方库。

看一下卖家提供的驱动库

.
├── libcanbus.a
├── libcanbus.so
├── libusb-1.0.a
├── libusb-1.0.la
├── libusb-1.0.so
├── libusb-1.0.so.0
└── libusb-1.0.so.0.3.0

0 directories, 7 files

USB 库+CANBUS动态库

现在创建一个功能包,名字就叫 candriver

然后在功能包下新建 lib 目录,把所有的库文件拷贝进去

对了,卖家还提供了 arm64的库,一样的,新建 libarm,把库拷贝进去

然后把卖家提供的头文件放在include目录下,然后在是src下新建cantest.cpp下 最终得到如下目录结构

├── CMakeLists.txt
├── include
│   ├── canbus.h
│   └── candriver
├── install_lib.sh
├── lib
│   ├── libcanbus.a
│   ├── libcanbus.so
│   ├── libusb-1.0.a
│   ├── libusb-1.0.la
│   ├── libusb-1.0.so
│   ├── libusb-1.0.so.0
│   └── libusb-1.0.so.0.3.0
├── libarm
│   ├── libcanbus.a
│   ├── libcanbus.so
│   ├── libusb-1.0.a
│   ├── libusb-1.0.la
│   ├── libusb-1.0.so -> libusb-1.0.so.0.3.0
│   ├── libusb-1.0.so.0 -> libusb-1.0.so.0.3.0
│   └── libusb-1.0.so.0.3.0
├── package.xml
├── src
│   └── cantest.cpp
├── test

接着我们来编写CMakeLists

要让代码找到头文件,加这句话

include_directories(include)

要添加可执行文件

add_executable(cantest
  src/cantest.cpp
)

要链接ROS2的库,先find_package,再添加ament_target_dependencies

要链接支持find_package 的第三方库,要用target_link_libraries来链接

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(guidebot_interfaces REQUIRED)

ament_target_dependencies(cantest
  rclcpp
  guidebot_interfaces
)

对于不支持的,要先找到对应库路径,我们放到工程目录下,可以直接通过CMakeLists.txt提供的${PROJECT_SOURCE_DIR}获取路径,拼接lib即可获取库

加上link所以这样写

set(CAN_LIB lib)  
message(STATUS "Linking libraries...")  
target_link_libraries(cantest  
  ${PROJECT_SOURCE_DIR}/${CAN_LIB}/libcanbus.so  
  ${PROJECT_SOURCE_DIR}/${CAN_LIB}/libusb-1.0.so  
)  

如果你这样直接编译,是没有问题的,但最后运行的时候就会无法link,这是因为src目录下的库目录没有被 ROS 2的 setup.bash 添加到搜索目录

那问题来了,ROS 2 搜索哪些目录?

你随便source 一下setup.bash

然后echo $LD_LIBRARY_PATH

找找可以看到 /home/fishros/guidebot/install/candriver/lib

所以这个目录 install/candriver/lib 就是ROS2 运行期间会检索动态链接库的目录

知道了就可以把库拷贝过去

# 安装库文件  
message(STATUS "Installing libraries...")  
install(DIRECTORY ${CAN_LIB}/  
  DESTINATION lib/     
)

好的,此时再构建和运行就没问题了,我们的第一个问题就解决了

接着第二个问题,如果保证不同架构可以用同一份代码(这个还设计如果交叉编译,如何发布ROS2的工程等等,以后再说,有空了可以出一个ROS2工程实践系列)

这里我们还是从 CMakeLists.txt 动手

这样干

# 判断是否为arm64系统  
message(STATUS "Checking if the system is aarch64...")  
if(CMAKE_SYSTEM_PROCESSOR MATCHES aarch64)  
  message(STATUS "The system is aarch64!")  
  set(CAN_LIB libarm)  
else()  
  message(STATUS "The system is not aarch64.")  
  set(CAN_LIB lib)  
endif() 

最后记得安装可执行文件

install(TARGETS cantest
  RUNTIME DESTINATION lib/${PROJECT_NAME}   
)

好了,到这里就把ROS2如何使用第三方库给讲清楚了,欢迎留言,下次抽空讲讲ROS 2在工程实践中遇到的速率不够,丢数据问题如何解决。

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值