ros_logo ROS

警告

此功能为实验性功能,可能会有破坏性更改。更多信息请参阅Conan 稳定性部分。

Conan 为您的 Robot Operating System (ROS) C/C++ 项目提供集成。这将允许您在 ROS 包项目中使用 Conan 包。Conan 包可以借助为此目的创建的 ROSEnv 生成器 在 CMake 中安装和使用。

它提供了一个干净的集成,在您的 CMakeLists.txt 中不需要任何特定于 Conan 的修改。

重要

此集成支持 ROS2,它是使用 Kilted 版本开发的,并且目标是 未来支持新版本。如果您对其他 ROS 版本有任何问题,请在我们的 GitHub 仓库中提出 issue 告知我们。

注意

运行示例的先决条件

  1. 为了运行示例,您需要一个安装了 ROS2 的 Ubuntu 环境。为了方便起见,您也可以使用此 Dockerfile

    FROM osrf/ros:kilted-desktop
    RUN apt-get update && apt-get install -y \
    curl \
    python3-pip \
    git \
    ros-kilted-nav2-msgs \
    && rm -rf /var/lib/apt/lists/*
    RUN pip3 install --upgrade pip && pip3 install conan==2.*
    RUN conan profile detect
    CMD ["bash"]
    

    只需复制 Dockerfile,使用 docker build -t conanio/ros-kilted . 构建您的镜像,最后使用 docker run -it conanio/ros-kilted 运行它。

也有可能在 Windows 上运行 ROS2。请遵循 [ROS 2 文档中的安装说明](https://docs.ros.org/en/kilted/Installation/Windows-Install-Binary.html)。

  1. 此示例的文件可以在 我们的示例仓库 中找到。像这样克隆它以开始

    $ git clone https://github.com/conan-io/examples2.git
    $ cd examples2/examples/tools/ros/rosenv
    

使用 ROSEnv 生成器消耗 Conan 包

假设我们有一个名为 str_printer 的 ROS C++ 包,它使用第三方字符串格式化库 fmt 的某些功能来打印漂亮的字符串。

我们有以下项目结构

$  tree /f
workspace
├───str_printer
│      CMakeLists.txt
│      conanfile.txt
│      package.xml
│   ├───include
│      └──str_printer
│            str_printer.h
│   └───src
│          str_printer.cpp
└───consumer
       CMakeLists.txt
       package.xml
    └───src
           main.cpp

其中

  • str_printer 是一个 ROS 包,它实现了一个函数,并且依赖于 fmt Conan 包

  • consumer 也是一个 ROS 包,它依赖于 str_printer ROS 包,并在最终的可执行文件中使用其功能。

str_printer 包与普通 ROS 包的唯一区别在于它包含一个 conanfile.txt 文件。这是 Conan 用于安装所需依赖项并生成执行构建所需文件的文件。

str_printer/conanfile.txt
 [requires]
 fmt/11.0.2

 [generators]
 CMakeDeps
 CMakeToolchain
 ROSEnv

在这种情况下,我们将安装 fmt 的 11.0.2 版本,Conan 将为 CMake 和 ROS 生成文件,以便我们稍后可以构建 str_printer 包。

要使用 Conan 安装 fmt 库,我们应该这样做

$ cd workspace
$ conan install str_printer/conanfile.txt --build missing --output-folder install/conan
======== Computing dependency graph ========
fmt/11.0.2: Not found in local cache, looking in remotes...
fmt/11.0.2: Checking remote: conancenter
fmt/11.0.2: Downloaded recipe revision 5c7438ef4d5d69ab106a41e460ce11f3
Graph root
    conanfile.txt: /home/user/examples2/examples/tools/ros/rosenv/workspace/str_printer/conanfile.txt
Requirements
    fmt/11.0.2#5c7438ef4d5d69ab106a41e460ce11f3 - Downloaded (conancenter)

======== Computing necessary packages ========
Requirements
    fmt/11.0.2#5c7438ef4d5d69ab106a41e460ce11f3:29da3f322a17cc9826b294a7ab191c2f298a9f49#d8d27fde7061f89f7992c671d98ead71 - Download (conancenter)

======== Installing packages ========

-------- Downloading 1 package --------
fmt/11.0.2: Retrieving package 29da3f322a17cc9826b294a7ab191c2f298a9f49 from remote 'conancenter'
fmt/11.0.2: Package installed 29da3f322a17cc9826b294a7ab191c2f298a9f49
fmt/11.0.2: Downloaded package revision d8d27fde7061f89f7992c671d98ead71

======== Finalizing install (deploy, generators) ========
conanfile.txt: Writing generators to /home/user/examples2/examples/tools/ros/rosenv/workspace/install/conan
conanfile.txt: Generator 'CMakeDeps' calling 'generate()'
conanfile.txt: CMakeDeps necessary find_package() and targets for your CMakeLists.txt
    find_package(fmt)
    target_link_libraries(... fmt::fmt)
conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'
conanfile.txt: CMakeToolchain generated: conan_toolchain.cmake
conanfile.txt: Preset 'conan-release' added to CMakePresets.json. Invoke it manually using 'cmake --preset conan-release' if using CMake>=3.23
conanfile.txt: If your CMake version is not compatible with CMakePresets (<3.23) call cmake like: 'cmake <path> -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/danimtb/examples2/examples/tools/ros/rosenv/workspace/install/conan/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release'
conanfile.txt: CMakeToolchain generated: CMakePresets.json
conanfile.txt: CMakeToolchain generated: ../../str_printer/CMakeUserPresets.json
conanfile.txt: Generator 'ROSEnv' calling 'generate()'
conanfile.txt: Generated ROSEnv Conan file: conanrosenv.sh
Use 'source /home/user/examples2/examples/tools/ros/rosenv/workspace/install/conan/conanrosenv.sh' to set the ROSEnv Conan before 'colcon build'
conanfile.txt: Generating aggregated env files
conanfile.txt: Generated aggregated env files: ['conanrosenv.sh']
Install finished successfully

这将把 fmt Conan 包下载到本地缓存,并在 install 目录的 conan 子文件夹中生成 CMake 和 ROS 环境文件。

现在我们可以 source 我们的 ROS 环境,然后source Conan ROSEnv 环境,这样 conan 安装的包就能被 CMake 找到,然后我们可以像往常一样使用 Colcon 构建 str_printer 包。

$ source /opt/ros/kilted/setup.bash
$ source install/conan/conanrosenv.sh
$ colcon build --packages-select str_printer
Starting >>> str_printer
Finished <<< str_printer [10.8s]

Summary: 1 package finished [12.4s]

将 Conan 提供的传递依赖项桥接到另一个 ROS 包

由于 consumer ROS 包依赖于 str_printer,因此传递依赖项的目标应该被导出。这在 str_printersCMakeLists.txt 中使用 ament_export_dependencies() 正常完成

str_printer/CMakeLists.txt
 cmake_minimum_required(VERSION 3.8)
 project(str_printer)

 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(fmt REQUIRED)  # Retrieved with Conan C/C++ Package Manager

 add_library(str_printer src/str_printer.cpp)

 target_include_directories(str_printer PUBLIC
 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/str_printer>
 $<INSTALL_INTERFACE:include>)

 target_compile_features(str_printer PUBLIC c_std_99 cxx_std_17)  # Require C99 and C++17
 ament_target_dependencies(str_printer fmt)

 ament_export_targets(str_printerTargets HAS_LIBRARY_TARGET)
 ament_export_dependencies(fmt)

 install(
 DIRECTORY include/
 DESTINATION include
 )

 install(
 TARGETS str_printer
 EXPORT str_printerTargets
 LIBRARY DESTINATION lib
 ARCHIVE DESTINATION lib
 RUNTIME DESTINATION bin
 INCLUDES DESTINATION include
 )

 ament_package()

要构建 consumer ROS 包,您可以照常进行(确保您已 source 了 ROS 环境和 Conan ROSEnv 环境,如上一步所示)

$ colcon build --packages-select consumer
Starting >>> consumer
Finished <<< consumer [7.9s]

Summary: 1 package finished [9.4s]

在此之后,我们的 consumer 应用程序应该准备好运行,只需

$ source install/setup.bash
$ ros2 run consumer main
Hi there! I am using fmt library fetched with Conan C/C++ Package Manager

另请参阅