ROS2高效学习第三章 -- 梳理 ros 编译工具,开始 ros2 编程,第一个 hello ros2 样例

梳理 ros 编译工具,开始 ros2 编程,第一个 hello ros2 样例

  • [1 背景和资料](#1 背景和资料)
  • [2 正文](#2 正文)
    • [2.1 ros 构建工具和构建系统梳理](#2.1 ros 构建工具和构建系统梳理)
    • [2.2 CI/CD 粗讲](#2.2 CI/CD 粗讲)
    • [2.3 创建工作空间以及配置 colcon](#2.3 创建工作空间以及配置 colcon)
    • [2.4 hello_ros2_cpp](#2.4 hello_ros2_cpp)
    • [2.5 hello_ros2_py](#2.5 hello_ros2_py)
  • 总结

1 背景和资料

从本文开始,我们学习 ros2 编程,每一个样例我们都会用 c++ 和 python 实现两次,感受两套语言实现的区别。本文我们重点介绍 ros 构建工具的发展历史,从而引入 colcon 和 ament 。然后分别实现 hello_ros2_cpp 和 hello_ros2_py,体验 ros2 的编译方式。至于如何搭建 ros2 环境,请参考本人上一篇文章 ROS2高效学习第二章 -- ros2常用命令和相关概念学习,熟练玩起来小乌龟样例 .

本文参考资料如下:

(1)A universal build tool

(2)Colcon-Tutorial

(3)Creating-A-Workspace

(4)Creating-Your-First-ROS2-Package

(5)古月 ros2_21_tutorials

(6)git 简单教程

(7)Conan tutorial

2 正文

2.1 ros 构建工具和构建系统梳理

(1)构建系统引入:学 Linux C/C++ 编程的人都知道,程序写出来,需要编程成二进制文件才能运行。C 语言的编译器就是 gcc ,C++ 的编译器就是 g++。如果你的程序只有一个 hello_world.cpp 文件,最简单的编译指令如下:

bash 复制代码
g++ -std=c++11 hello_world.cpp -o hello_world

但一个合格的程序员,不能只写 hello world 。稍微大一些的项目,就会有很多个 .cpp 和 .h 文件,他们彼此之间相互依赖。此时,把整个项目编译出一个可执行程序,这个过程就是构建。目前针对 C/C++ 程序,最常用的构建系统就是 cmake,其底层依赖 makefile,而最下层就是 gcc/g++。

(2)构建工具引入:对于 hello world 级别的程序,只需要一行编译指令就能解决构建问题。稍微大一点的项目,就需要构建系统了。如果项目再大一点,比如实现一个自动驾驶系统,就需要把整个系统分为很多个模块或软件包,分别进行开发。这些模块之间会彼此依赖,比如多个终端模块都依赖 log 日志模块。此时就需要引入构建工具,解决复杂系统内多模块的构建问题。

(3)构建工具和构建系统比较:

构建系统:构建系统的作用范围在单个模块或单个 ros 软件包,负责程序构建。

构建工具:构建工具的作用范围是整个大型系统或一组 ros 软件包,其根据依赖关系图,按照拓扑顺序调用每个包的特定构建系统,依次完成整个系统的构建任务。比如必须先编译 log 日志软件包,然后才能编译终端模块软件包。除了构建任务之外,构建工具还需要为程序运行设置环境变量,比如那个经典的 LD_LIBRARY_PATH 。

(4)ros 历代构建系统:ros1 时我们主要使用 cmake ,以及基于 cmake 的 catkin 构建系统。

c 复制代码
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs)

到 ros2 时,我们将使用 ament_cmake,其源于 catkin ,也基于 cmake 。针对 python 软件包 ,ros2 还引入了 setuptools ,这是 python 常用的打包工具。按理说 python 属于解释型语言,不需要编译,setuptools 只是打包工具,但我们仍把他作为一种构建系统。

(5)ros 历代构建工具:ros1 时我们主要使用 catkin_make 构建工具,其继承自 rosbuild 。

bash 复制代码
catkin_make --source src/hello_ros/

在 catkin_make 之后,ros1 还发布了 catkin_make_isolated ,catkin_tools 。到 ros2 ,ROS 官方先发布了 ament_tools ,后来又重新开发了 colcon (collective construction,集中构建)构建工具。

(6)为啥重新开发 colcon :ros 经过 ros1 ,ros2 两个大版本的迭代,积累了多款构建工具和构建系统,急需一款统一的构建工具,能同时解决多种版本(ros1,ros2),多种语言(c++ ,python),多种平台(linux,mac,windows)的构建问题。因此重新开发了 colcon。命名方式上也不再坚持构建工具与构建系统的统一,如 catkin和 catkin_make,ament 和 ament_tools,以此强调 colcon 能支持多种构建系统。colcon 也将是 ros 未来唯一的构建工具,更详细的信息可以参考 ros build_tool

(7)构建工具不支持的功能:ros 的构建工具不支持代码拉取功能;不支持安装包依赖项功能,依赖项需要自己在构建之前手动安装好;不支持创建二进制包功能,例如 Debian 包。

2.2 CI/CD 粗讲

(1)CI/CD 概念:Continuous Integration (持续集成),Continuous Deployment (持续部署),这是软件工程中非常重要的概念,也是一种软件开发实践。旨在帮助软件团队快速、可靠地交付他们的产品。

(2)CI/CD 粗讲:在 CI 这步,首先需要一个版本控制系统,当前最好用的就是 git( git 简单教程) 。围绕着 git ,一般会在主线分支上设置静态代码检查,用来检测每一笔提交的质量,比如命名规范等。还会设置自动化单元测试,看守代码功能,并进行代码覆盖率分析。

然后就需要一个工具,很类似 ros 的构建工具,能依次实现代码拉取,代码构建,二进制包管理(如C++ Conan,Conan tutorial)和二进制产物生成。

最后就是 CD,其自动化的把二进制产物部署到测试或生成环境,运行集成测试和冒烟测试。

(3)整个 CI 和 CD 过程几乎涉及软件工程的方方面面,这里推荐一本书:持续交付 发布可靠软件的系统方法,Jez Humble / David Farley

2.3 创建工作空间以及配置 colcon

(1)创建工作空间

bash 复制代码
mkdir -p ~/colcon_ws/src

(2)配置 colcon_cd :ros1 中有 roscd 命令,可以方便的进行软件包目录切换。到 ros2 ,对应的是 colcon_cd,但需要手动配置一下

bash 复制代码
echo "source /usr/share/colcon_cd/function/colcon_cd.sh" >> ~/.bashrc
echo "export _colcon_cd_root=/opt/ros/humble/" >> ~/.bashrc

测试命令:

bash 复制代码
source ~/.bashrc
colcon_cd turtlesim

(3)colcon 有很多命令选项,用户最好设置下他的命令联想功能,方便使用:

bash 复制代码
echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> ~/.bashrc

2.4 hello_ros2_cpp

(1)创建 hello_ros2_cpp 软件包和相关文件

bash 复制代码
cd ~/colcon_ws/src
ros2 pkg create --build-type ament_cmake  --license Apache-2.0 hello_ros2_cpp
cd hello_ros2_cpp/src
touch hello_ros2.cpp

(2)编写 hello_ros2.cpp

c 复制代码
// rcl 是指 ROS Client Library 的缩写,它是 ROS 2 中的一个底层库。
// rcl 抽象了底层的中间件通信功能,为上层的客户端库提供统一的 API 接口。
// 在ros c++ 编程中,我们使用 rclcpp;ros python 编程中,我们使用 rclpy
#include "rclcpp/rclcpp.hpp"
// ros2 更推荐用户使用面向对象编程 OOP,
// 它提供了一种清晰且结构化的方式来组织和管理复杂的软件系统,
// 而机器人软件需要 OOP 的这些优点。
class HelloRos2 : public rclcpp::Node {
public:
    HelloRos2() : Node("hello_ros2") {
        RCLCPP_INFO(this->get_logger(), "start hello ros2 in cpp !!");
    }
    void run() {
        while(rclcpp::ok()) {
            RCLCPP_INFO(this->get_logger(), "hello ros2 in cpp !!");
            sleep(1);
        }
    }
};

int main(int argc, char* argv[]) {
    rclcpp::init(argc, argv);
    auto node = std::make_shared<HelloRos2>();
    node->run();
    rclcpp::shutdown();
    return 0;
}

(3)编写CmakeLists.txt

c 复制代码
cmake_minimum_required(VERSION 3.8)
project(hello_ros2_cpp)
find_package(ament_cmake REQUIRED)
// 下面四句是手动添加的,不可少
find_package(rclcpp REQUIRED)
add_executable(${PROJECT_NAME} src/hello_ros2.cpp)
ament_target_dependencies(${PROJECT_NAME} rclcpp)
install(TARGETS
  ${PROJECT_NAME}
  DESTINATION lib/${PROJECT_NAME})
ament_package()

(4)编译并运行

bash 复制代码
~/colcon_ws
colcon build --packages-select hello_ros2_cpp
source install/local_setup.bash
ros2 run hello_ros2_cpp hello_ros2_cpp

2.5 hello_ros2_py

(1)创建 hello_ros2_py 软件包和相关文件

bash 复制代码
cd ~/colcon_ws/src
ros2 pkg create --build-type ament_python --license Apache-2.0 hello_ros2_py
cd hello_ros2_py/hello_ros2_py
touch hello_ros2.py

(2)编写 hello_ros2.py

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# ros python 编程使用rclpy,也推荐面向对象
import rclpy
from rclpy.node import Node
import time
class HelloRos2(Node):
    def __init__(self, name):
        super().__init__(name)
        self.get_logger().info("start hello_ros2_py node !!")
        
    def run(self):
        try:
            while rclpy.ok():
                self.get_logger().info("hello ros2 in python !!")
                time.sleep(1)
        except KeyboardInterrupt:
            self.get_logger().info("Node was interrupted, shutting down...")

def main(args=None):
    rclpy.init(args=args)
    node = HelloRos2("hello_ros2_py")
    try:
        node.run()
    except KeyboardInterrupt:
        node.destroy_node()
        rclpy.shutdown()

if __name__ == '__main__':
    main()

(3)编写 setup.py

bash 复制代码
from setuptools import find_packages, setup
package_name = 'hello_ros2_py'
setup(
    name=package_name,
    version='0.0.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='ycao',
    maintainer_email='1641395022@qq.com',
    description='TODO: Package description',
    license='Apache-2.0',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
        	# 其他都是自动生成的,只有这里需要修改
        	# ros2 引入了 setuptools ,这里的setup.py 用来定义程序的入口
        	# 这里的格式请遵循:'my_node = my_py_pkg.my_node:main'
            'hello_ros2 = hello_ros2_py.hello_ros2:main'
        ],
    },
)

(4)编译并运行

bash 复制代码
~/colcon_ws
colcon build --packages-select hello_ros2_py
source install/local_setup.bash
ros2 run hello_ros2_py hello_ros2

(5)踩坑记录

第一,编译 hello_ros2_py 时,总是遇到:

txt 复制代码
--- stderr: hello_ros2_py
/usr/lib/python3/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
  warnings.warn(
---

解决:setuptools 必须使用 58 版本,参考:setuptools执行问题

bash 复制代码
pip install setuptools==58

第二,运行 hello_ros2_py 时,总是遇到:

txt 复制代码
ModuleNotFoundError: No module named 'hello_ros2_py'
[ros2run]: Process exited with failure 1

解决:下面这个文件不能删除,尽管他是空白的。

txt 复制代码
hello_ros2_py/hello_ros2_py/__init__.py

总结

这篇文章从想写到写完,将近一个月,进度实在令人抱歉。得益于媳妇的支持,最终在春节假期结束前赶出来了,完成后确实有一吐为快的感觉。本文样例托管在本人的 github 上:ros2_code

相关推荐
Godspeed Zhao6 分钟前
自动驾驶中的传感器技术42——Radar(3)
人工智能·机器学习·自动驾驶
Godspeed Zhao8 分钟前
自动驾驶中的传感器技术41——Radar(2)
人工智能·机器学习·自动驾驶
Broken Arrows8 小时前
Linux学习——管理网络安全(二十一)
linux·学习·web安全
今天也要学习吖8 小时前
谷歌nano banana官方Prompt模板发布,解锁六大图像生成风格
人工智能·学习·ai·prompt·nano banana·谷歌ai
雁于飞8 小时前
vscode中使用git、githup的基操
笔记·git·vscode·学习·elasticsearch·gitee·github
索迪迈科技8 小时前
INDEMIND亮相2025科技创变者大会,以机器人空间智能技术解锁具身智能新边界
人工智能·机器人·扫地机器人·空间智能·陪伴机器人
rannn_1119 小时前
【Javaweb学习|实训总结|Week1】html基础,CSS(选择器、常用样式、盒子模型、弹性盒布局、CSS定位、动画),js(基本类型、运算符典例)
css·笔记·学习·html
沫儿笙9 小时前
FANUC发那科焊接机器人铝材焊接节气
人工智能·机器人
zskj_qcxjqr10 小时前
告别传统繁琐!七彩喜艾灸机器人:一键开启智能养生新时代
大数据·人工智能·科技·机器人