# ros2_21_tutorials **Repository Path**: zgrxmm/ros2_21_tutorials ## Basic Information - **Project Name**: ros2_21_tutorials - **Description**: 《ROS2入门21讲 · 古月》课程代码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: https://class.guyuehome.com - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 108 - **Created**: 2023-09-25 - **Last Updated**: 2025-02-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ROS2入门21讲 · 古月 - 课程视频:[https://class.guyuehome.com/detail/p_628f4288e4b01c509ab5bc7a/6](https://class.guyuehome.com/detail/p_628f4288e4b01c509ab5bc7a/6) - 图文教程:[https://book.guyuehome.com/](https://book.guyuehome.com/) - 课程问答:[https://www.guyuehome.com/Bubble/circleDetail/id/90/](https://www.guyuehome.com/Bubble/circleDetail/id/90/) - 博客泡圈:[https://www.guyuehome.com/](https://www.guyuehome.com/) ![课程大纲](docs/课程大纲.png) ![交流群](docs/交流群.png) # 构建编译 ## 编译工作空间 ''' sudo apt install python3-colcon-ros cd ~/dev_ws/ colcon build ''' ## 设置环境变量 source install/local_setup.sh # 仅在当前终端生效 echo " source ~/dev_ws/install/local_setup.sh" >> ~/.bashrc # 所有终端均生效 # 创建功能包 ## ros2 pkg create --build-type ros2命令中: pkg:表示功能包相关的功能; create:表示创建功能包; build-type:表示新创建的功能包是C++还是Python的,如果使用C++或者C,那这里就跟ament_cmake,如果使用Python,就跟ament_python; package_name:新建功能包的名字。 ## example cd ~/dev_ws/src ros2 pkg create --build-type ament_cmake learning_pkg_c # C++ ros2 pkg create --build-type ament_python learning_pkg_python # Python ## 编译功能包 在创建好的功能包中,我们可以继续完成代码的编写,之后需要编译和配置环境变量,才能正常运行 cd ~/dev_ws colcon build # 编译工作空间所有功能包 source install/local_setup.bash ### C++功能包 首先看下C++类型的功能包,其中必然存在两个文件:package.xml和CMakerLists.txt - package.xml文件的主要内容如下,包含功能包的版权描述,和各种依赖的声明 - CMakeLists.txt文件是编译规则,C++代码需要编译才能运行,所以必须要在该文件中设置如何编译,使用CMake语法。 ### Python功能包 C++功能包需要将源码编译成可执行文件,但是Python语言是解析型的,不需要编译,所以会有一些不同,但也会有这两个文件:package.xml和setup.py。 - package.xml文件的主要内容和C++版本功能包一样,包含功能包的版权描述,和各种依赖的声明。 - setup.py文件里边也包含一些版权信息,除此之外,还有“entry_points”配置的程序入口,在后续编程讲解中,我们会给大家介绍如何使用。 # 节点 ## 案例一:Hello World节点(面向过程) ros2 run learning_node node_helloworld ## 案例二:Hello World节点(面向对象) ros2 run learning_node node_helloworld_class # 话题 - 通讯模型 - 发布订阅模型(异步通讯) ## 消息接口 消息是ROS中的一种接口定义方式,与编程语言无关,我们也可以通过.msg后缀的文件自行定义,有了这样的接口,各种节点就像积木块一样,通过各种各样的接口进行拼接,组成复杂的机器人系统。 ## 案例一:Hello World话题通信 ros2 run learning_topic topic_helloworld_pub ros2 run learning_topic topic_helloworld_sub # 服务 - 通讯模型 - 客户端/服务器模型 CS模型(同步通讯) ## 服务接口 和话题通信类似,服务通信的核心还是要传递数据,数据变成了两个部分,一个请求的数据,比如请求苹果位置的命令,还有一个反馈的数据,比如反馈苹果坐标位置的数据,这些数据和话题消息一样,在ROS中也是要标准定义的,话题使用.msg文件定义,服务使用的是.srv文件定义,后续我们会给大家介绍定义的方法。 ## 案例一:加法求解器 ros2 run learning_service service_adder_server ros2 run learning_service service_adder_client 2 3 # 通讯接口 - ROS通信接口 ROS有三种常用的通信机制,分别是话题、服务、动作,通过每一种通信种定义的接口,各种节点才能有机的联系到一起。 - 话题通信接口的定义使用的是.msg文件,由于是单向传输,只需要描述传输的每一帧数据是什么就行,比如在这个定义里,会传输两个32位的整型数,x、y,我们可以用来传输二维坐标的数值。 - 服务通信接口的定义使用的是.srv文件,包含请求和应答两部分定义,通过中间的“---”区分,比如之前我们学习的加法求和功能,请求数据是两个64位整型数a和b,应答是求和的结果sum。 - 动作是另外一种通信机制,用来描述机器人的一个运动过程,使用.action文件定义,比如我们让小海龟转90度,一边转一边周期反馈当前的状态,此时接口的定义分成了三个部分,分别是动作的目标,比如是开始运动,运动的结果,最终旋转的90度是否完成,还有一个周期反馈,比如每隔1s反馈一下当前转到第10度、20度还是30度了,让我们知道运动的进度。 # 动作 客户端/服务器模型 动作和服务类似,使用的也是客户端和服务器模型,客户端发送动作的目标,想让机器人干什么,服务器端执行动作过程, 控制机器人达到运动的目标,同时周期反馈动作执行过程中的状态。 客户端发送一个运动的目标,想让机器人动起来,服务器端收到之后,就开始控制机器人运动,一边运动,一边反馈当前的状态,如果是一个导航动作,这个反馈可能是当前所处的坐标,如果是机械臂抓取,这个反馈可能又是机械臂的实时姿态。当运动执行结束后,服务器再反馈一个动作结束的信息。整个通信过程就此结束。 ## 由服务和话题合成 大家再仔细看下上边的动图,是不是还会发现一个隐藏的秘密。 动作的三个通信模块,竟然有两个是服务,一个是话题,当客户端发送运动目标时,使用的是服务的请求调用,服务器端也会反馈一个应带,表示收到命令。动作的反馈过程,其实就是一个话题的周期发布,服务器端是发布者,客户端是订阅者。 没错,动作是一种应用层的通信机制,其底层就是基于话题和服务来实现的。 ## 案例一:小海龟的动作 我们再用小海龟的案例加深对动作概念的理解。 按照以下命令启动小海龟仿真器,接下来使用action命令控制小海龟的动作,可以让海龟运动到某一指定的姿态: ros2 run turtlesim turtlesim_node ros2 run turtlesim turtle_teleop_key ros2 action info /turtle1/rotate_absolute ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback ## 案例二:机器人画圆 $ ros2 run learning_action action_move_server $ ros2 run learning_action action_move_client # 参数 话题、服务、动作,不知道这三种通信机制大家是否已经了解清楚,本节我们再来介绍一种ROS系统中常用的数据传输方式——参数。 类似C++编程中的全局变量,可以便于在多个程序中共享某些数据,参数是ROS机器人系统中的全局字典,可以运行多个节点中共享数据。 在ROS系统中,参数是以全局字典的形态存在的,什么叫字典?就像真实的字典一样,由名称和数值组成,也叫做键和值,合成键值。或者我们也可以理解为,就像编程中的参数一样,有一个参数名 ,然后跟一个等号,后边就是参数值了,在使用的时候,访问这个参数名即可。 - 可动态监控 在ROS2中,参数的特性非常丰富,比如某一个节点共享了一个参数,其他节点都可以访问,如果某一个节点对参数进行了修改,其他节点也有办法立刻知道,从而获取最新的数值。这在参数的高级编程中,大家都可能会用到。 - 查看参数列表 ros2 param list - 参数查询与修改 $ ros2 param describe turtlesim background_b # 查看某个参数的描述信息 $ ros2 param get turtlesim background_b # 查询某个参数的值 $ ros2 param set turtlesim background_b 10 # 修改某个参数的值 - 参数文件保存与加载 一个一个查询/修改参数太麻烦了,不如试一试参数文件,ROS中的参数文件使用yaml格式,可以在param命令后边跟dump子命令,将某个节点的参数都保存到文件中,或者通过load命令一次性加载某个参数文件中的所有内容: $ ros2 param dump turtlesim >> turtlesim.yaml # 将某个节点的参数保存到参数文件中 $ ros2 param load turtlesim turtlesim.yaml # 一次性加载某一个文件中的所有参数