一.一些废话

你必须知道怎么写ros2的cmake,不过遇到报错可以用gpt,这里建议新手直接用ament_cmake_auto,真的非常好用!

1.我的环境

  • Ubuntu22.04LTS
  • Ros2 humble【在Anaconda环境配置中是安装在系统环境里面】

2.为什么用Clion?

  • 众所周知,Jetbrain家得东西写代码都是互通的,比如Pycharm写C++,Clion也可写Python代码,不过针对ros2来说,我们写C++居多,所以Clion肯定是最合适的

3.为什么我不喜欢用vscode?

  • 相比于clion,vscode的代码补全功能让我觉得太鸡肋了(不过vscode也可以通过Cmake插件加载CmakeLists,但是我没用过,不过实际效果我感觉应该跟Clion差不多)

注意:Clion得代码补全是要我们事先加载cmakeLists,这一点就显得不如vscode


二.在没有配置虚拟环境(Anaconda)下的配置

1.写C++代码

(1)编写cmakeLists.txt

这里使用ament_cmake_auto,非常建议我这种cmake学不太明白,然后添加依赖总是报错的人用这个!!!

  • 这里我参考了这位博主的教程,写的很不错感觉

让ROS2 CMake变得简单!ament_cmake_autohttps://zhuanlan.zhihu.com/p/438191834

  • 我截取里面一段cmake代码模板

注意:

①针对ros2的包或ros2的附属包:使用ament_cmake_auto后 要依赖的包 全都写在 package.xml中。

这里给出ament_cmake_auto的基本代码👇

cmake_minimum_required (VERSION 3.10)
project(test)    # 该ros2功能包名叫什么(注意要和package.xml一致)

find_package (ament_cmake_auto REQUIRED)    # 注意find_package只用查找这个包就可以了,其他包全都写在package.xml
ament_auto_find_build_dependencies ()    # cmake自动查找package.xml中的文件

# 用于生成库文件,这样其他cmakeLists和写C++代码的时候可以引用该ros2功能包的库函数
ament_auto_add_library ( 
    my_lib                 # 你要定义的install的包名叫什么
    SHARED                 # 可选:SHARED创建一个动态链接库,STATIC创建一个静态链接库,INTERFACE创建一个仅包含头文件的接口库
    src/example.cpp        # 你要install library的.cpp文件
    include/example.hpp    # 你要install library的.h文件或.hpp文件
)

ament_auto_package ()    # 自动化包(package)的安装和导出(export)

②针对非ros2的包:要使用原始的cmake进行链接,其实只需要添加两行代码:

find_package(C++原始库 REQUIRED)

target_link_libraries(要链接的ros2节点 C++原始库)

这里给出 引入非ros2的C++库 的部分代码👇

# 创建 ros2 节点
ament_auto_add_executable(
        pnp src/pnp.cpp
)

# 非 ros2 部分,这里是查找 C++ 本身的包
find_package(ZXing REQUIRED)
target_link_libraries(
        pnp ZXing
)

【  示例代码(包括 绑定ros2的包 部分 和 绑定非ros2的C++库 部分)👇  】

# 最小CMake版本要求
cmake_minimum_required(VERSION 3.16)
# 项目名称
project(item_recognition)

set(USE_SCOPED_HEADER_INSTALL_DIR TRUE)


# 编译选项:为GCC和Clang添加常用警告
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# ros2 部分
find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()  # 这里的依赖全都写在package.xml

ament_auto_add_executable(
        PointCloudExtractor src/PointCloudExtractor.cpp
)

ament_auto_add_executable(
        color_detection src/color_detection.cpp
)

ament_auto_add_executable(
        pnp src/pnp.cpp
)

# 非 ros2 部分,这里是查找 C++ 本身的包
find_package(ZXing REQUIRED)
target_link_libraries(
        pnp ZXing
)


# 如果启用了测试,则寻找测试依赖
if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # 禁用版权和cpplint检查
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_auto_package()

(2)编写package.xml

<?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>item_recognition</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="1310946137@qq.com">amiya</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <!--需要的依赖全部扔到这里-->
  <depend>OpenCV</depend>
  <depend>cv_bridge</depend>
  <depend>Eigen3</depend>
  <depend>rclcpp</depend>
  <depend>sensor_msgs</depend>
  <depend>tf2_ros</depend>
  <depend>tf2_geometry_msgs</depend>
  <depend>quirc</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

(3)退出Clion,执行Colon build编译工作空间

目的在于把那些msg、srv等自定义消息文件 和 ament_auto_add_library 生成的库文件一起安装到ros2工作空间

(4)source工作空间,并且在终端打开Clion

这样做可以把当前的环境变量传入到Clion,让Clion找得到依赖的路径

(5)在Clion中加载cmakeLists.txt

方式:每次写一个功能包之前都加载一次该功能包的CmakeLists.txt

注意:在写代码之前一定要看看所写的CPP文件左上角有没有一个蓝色框,如果没有,说明你没有把这个文件添加到ament_auto_add_executable或ament_auto_add_library。此时写代码是没有提示的。

(6)效果演示

做到这一步的话,恭喜你,你已经成功完成了配置

2.写Python代码

(1)配置Clion中的Python解释器

  • 打开 Clion->设置 -> 构建、执行、部署 -> Python解释器 
  • 点击 添加解释器 -> 生成新的(生成虚拟环境)/选择现有(直接调用系统环境) ...

(2)编写package.xml

(不要忘了配置setup.py了!!!)

<?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>yolo_qr_detection</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="amiya@todo.todo">amiya</maintainer>
  <license>TODO: License declaration</license>

  <!--需要的依赖全部扔到这里-->
  <depend>rclpy</depend>
  <depend>sensor_msgs</depend>
  <depend>geometry_msgs</depend>
  <depend>OpenCV</depend>
  <depend>numpy</depend>
  <depend>ultralytics</depend>
  <depend>cv_bridge</depend>
  <depend>pyzbar</depend>

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

(3)退出Clion,执行Colon build编译工作空间

目的在于把那些msg、srv等自定义消息文件 和 ament_auto_add_library 生成的库文件一起安装到ros2工作空间

(4)source工作空间,并且在终端打开Clion

这样做可以把当前的环境变量传入到Clion,让Clion找到依赖的路径

然后就可以开心地写Python代码啦!


三.在配置虚拟环境(Anaconda)下的配置【如:因为要跑Yolo所以要隔离Python环境】

1.写C++代码

(1)配置Clion中的CMake

  • 打开 Clion->设置 -> 构建、执行、部署 -> CMake
  • 在CMake选项中输入:
-DPython3_EXECUTABLE=/usr/bin/python3

(加入这行配置的含义:我们在编译的时候我们是必须要使用系统环境,否则就会报错。)

错误配置:

  • 我没有在CMake选项中输入  -DPython3_EXECUTABLE=/usr/bin/python3
  • 我的Python解释器选择了 Conda虚拟环境
  • 这就会导致以下报错👇

(即:找不到 ros2 的 Python依赖,因为 Cmake 跑去 Conda虚拟环境 中找 ros2的Python依赖)

 (2)编写cmakeLists.txt

这里使用ament_cmake_auto,非常建议我这种cmake学不太明白,然后添加依赖总是报错的人用这个!!!

  • 这里我参考了这位博主的教程,写的很不错感觉

让ROS2 CMake变得简单!ament_cmake_autohttps://zhuanlan.zhihu.com/p/438191834

  • 我截取里面一段cmake代码模板

注意:

  • 使用ament_cmake_auto后 要依赖的包 全都写在 package.xml中。
  • 针对非ros2的包要使用原始的cmake进行链接,反正报错了就找GPT修就对了
cmake_minimum_required (VERSION 3.10)
project(test)    # 该ros2功能包名叫什么(注意要和package.xml一致)

find_package (ament_cmake_auto REQUIRED)    # 注意find_package只用查找这个包就可以了,其他包全都写在package.xml
ament_auto_find_build_dependencies ()    # cmake自动查找package.xml中的文件

# 用于生成库文件,这样其他cmakeLists和写C++代码的时候可以引用该ros2功能包的库函数
ament_auto_add_library ( 
    my_lib                 # 你要定义的install的包名叫什么
    SHARED                 # 可选:SHARED创建一个动态链接库,STATIC创建一个静态链接库,INTERFACE创建一个仅包含头文件的接口库
    src/example.cpp        # 你要install library的.cpp文件
    include/example.hpp    # 你要install library的.h文件或.hpp文件
)

ament_auto_package ()    # 自动化包(package)的安装和导出(export)

(3)编写package.xml

<?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>item_recognition</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="1310946137@qq.com">amiya</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <!--需要的依赖全部扔到这里-->
  <depend>OpenCV</depend>
  <depend>cv_bridge</depend>
  <depend>Eigen3</depend>
  <depend>rclcpp</depend>
  <depend>sensor_msgs</depend>
  <depend>tf2_ros</depend>
  <depend>tf2_geometry_msgs</depend>
  <depend>quirc</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

(4)退出Clion,在系统环境下执行Colon build编译工作空间

目的在于把那些msg、srv等自定义消息文件 和 ament_auto_add_library 生成的库文件一起安装到ros2工作空间

(4)source工作空间,并且在终端打开Clion

这样做可以把当前的环境变量传入到Clion,让Clion找得到依赖的路径

(5)在Clion中加载cmakeLists.txt

方式:每次写一个功能包之前都加载一次该功能包的CmakeLists.txt

注意:在写代码之前一定要看看所写的CPP文件左上角有没有一个蓝色框,如果没有,说明你没有把这个文件添加到 ament_auto_add_executable 或 ament_auto_add_library。此时写代码是没有提示的。

(6)效果演示

做到这一步的话,恭喜你,你已经成功完成了配置

【注意:编译的时候一定一定要在系统环境下编译!!!】

2.写Python代码

(1)配置Clion中的Python解释器

  • 打开 Clion->设置 -> 构建、执行、部署 -> Python解释器 
  • 点击 添加解释器 -> 选择 你创建的Conda虚拟环境

(2)编写package.xml

(不要忘了配置setup.py了!!!)

<?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>yolo_qr_detection</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="amiya@todo.todo">amiya</maintainer>
  <license>TODO: License declaration</license>

  <!--需要的依赖全部扔到这里-->
  <depend>rclpy</depend>
  <depend>sensor_msgs</depend>
  <depend>geometry_msgs</depend>
  <depend>OpenCV</depend>
  <depend>numpy</depend>
  <depend>ultralytics</depend>
  <depend>cv_bridge</depend>
  <depend>pyzbar</depend>

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

(3)退出Clion,执行Colon build编译工作空间

目的在于把那些msg、srv等自定义消息文件 和 ament_auto_add_library 生成的库文件一起安装到ros2工作空间

(4)source工作空间,并且在终端打开Clion

这样做可以把当前的环境变量传入到Clion,让Clion找到依赖的路径(包括自定义信息的库文件、ros2的Python依赖【因为我们使用的环境是Conda虚拟环境】)

(5)写Python代码时必须要添加 Conda虚拟环境变量

我们只需要知道,在写ros2 python程序时,如果我要引入pytorch、yolo等在虚拟环境才有的玩意,我们就要引入虚拟环境的环境变量,即输入:

# 引入环境变量,这里我们要把我们创建的Anaconda虚拟环境加入环境变量
import sys
new_path = '/home/【你的用户名】/anaconda3/envs/【你的Conda环境名】/lib/python3.10/site-packages'
if new_path not in sys.path:
    sys.path.insert(0,new_path)

# 然后我们就可以引入Anaconda虚拟环境中的包
from ultralytics import YOLO
import torch

效果如图,可以看到代码都没有报错👇

这个时候我们会发现,我们同时向Clion引入了:

  • 系统环境变量:如rclpy、std_msgs等ros2的Python依赖
  • Conda虚拟环境变量:如我这里是在Conda虚拟环境中增加了Yolo

然后就可以开心地写Python代码啦!

【注意:编译的时候一定一定要在系统环境下编译!!!】

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐