ROS2自定义消息接口
版权信息
Copyright 2023 Herman Ye@Auromix. All rights reserved.
This course and all of its associated content, including but not limited to text,
images, videos, and any other materials, are protected by copyright law.
The author holds all rights to this course and its contents.
Any unauthorized use, reproduction, distribution, or modification of this course
or its contents is strictly prohibited and may result in legal action.
This includes, but is not limited to:
Copying or distributing course materials without express written permission.
Reposting, sharing, or distributing course content on any platform without proper attribution and permission.
Creating derivative works based on this course without permission.
Permissions and Inquiries
If you wish to use or reproduce any part of this course for purposes other than personal learning,
please contact the author to request permission.
The course content is provided for educational purposes, and the author makes no warranties or representations
regarding the accuracy, completeness, or suitability of the course content for any specific purpose.
The author shall not be held liable for any damages, losses,
or other consequences resulting from the use or misuse of this course.
Please be aware that this course may contain materials or images obtained from third-party sources.
The author and course creator diligently endeavor to ensure that these materials
are used in full compliance with copyright and fair use regulations.
If you have concerns about any specific content in this regard,
please contact the author for clarification or resolution.
By enrolling in this course, you agree to abide by the terms and conditions outlined in this copyright notice.
学习目标
- 了解ROS2消息接口的命令行工具
- 熟悉ROS2的自定义消息类型接口代码编写
- 熟悉ROS2的自定义消息类型接口的测试手段
难度级别
初级 | 中级 | 高级 |
---|---|---|
√ |
预计耗时
45 mins
学习前提
对象 | 类型 | 状态 |
---|---|---|
ROS2 Humble | 软件 | 已安装 |
Ubuntu22.04操作系统 | 软件 | 已确认 |
Shell的基本使用 | 知识 | 已了解 |
ROS2 节点 | 知识 | 已了解 |
ROS2 话题 | 知识 | 已了解 |
ROS2 服务 | 知识 | 已了解 |
ROS2 行动 | 知识 | 已了解 |
消息类型的定义及其特点
ROS2的消息类型是一种用于在ROS2中传递数据的数据结构。 这些消息类型用于在不同ROS2节点之间交换信息,允许节点之间进行通信和协作。ROS消息类型通常以一种结构化的方式定义,以便节点可以准确地理解和解释数据。
可嵌套
每个ROS消息类型都有一个特定的消息定义,其中包含一个或多个字段(成员变量),这些字段可以包含不同类型的数据,如整数、浮点数、字符串、数组等。这嵌套结构允许更复杂的数据组织和传递。标准化
ROS消息类型的优势在于它们提供了一种标准化的方式来传递信息,使不同的ROS节点能够互相通信,无论它们是不是用不同编程语言编写的还是运行在不同的计算机上,只要消息类型及其版本一致就可以通信,并且各个消息类型都是由ROS中基本的消息类型组成(比如Int8、String、Byte)这种标准化确保了节点之间的数据交换的一致性和可靠性。
- 可自定义
除了内置的消息类型,ROS还允许用户创建自定义消息类型以满足特定需求。这些自定义消息类型是ROS中数据交换的基本构建块,用于在机器人控制、传感器数据传递、导航、图像处理等各种领域进行通信。
在turtlesim
的经典案例中,键盘控制小乌龟进行运动是通过/turtle1/cmd_vel
话题来实现的。而/turtle1/cmd_vel
话题所使用的消息类型是geometry_msgs/msg/Twist
。这个消息类型是ROS 2中的一个标准话题消息类型,用于描述机器人的运动命令。
具体来说,geometry_msgs/msg/Twist
消息类型包含线性和角速度的成员变量,允许指定机器人在三维空间中的运动。
通过/turtle1/cmd_vel
话题发布geometry_msgs/msg/Twist
消息,可以控制小乌龟在仿真环境中的运动,例如前进、后退、旋转等。
消息类型的命令行工具
在ROS2中,有一些命令行工具能帮助我们快速地了解、使用消息类型
查看本机上所有的ROS2消息类型
查看本机上所有可用的ROS2消息类型,可以运行以下命令:
ros2 interface list
查看特定消息类型的具体结构
以之前的geometry_msgs/msg/Twist
为例,如果希望查看它的具体消息类型:
ros2 interface show geometry_msgs/msg/Twist
通过这个命令,可以了解geometry_msgs/msg/Twist
消息的具体结构。这个消息类型通常用于控制小乌龟的速度,包含了角速度和线速度等信息,这也解释了为什么小乌龟的速度可以被控制。
寻找功能包中的所有可用消息类型
你可以使用 ros2 interface package
命令来查找特定功能包中的所有消息类型。举例来说,我们以 ros2_learning_interfaces
功能包为例,该功能包包含了在之前的 “ROS2动作” 课程中使用的 Fibonacci
消息类型。这是因为在这个包中,目前只有这一个消息类型可用。
ros2 interface package ros2_learning_interfaces
通过执行上述命令,你可以获得如下结果:
此外,你还可以查看 ROS 默认提供的消息包 std_msgs
,以找到一些常见的消息类型,比如 std_msgs/msg/String
,它用于传递字符串信息。
查看含有指定消息类型的包
有时候也会用到ros2 interface packages
来缩减查找范围,方便调试开发,不过这条用的比较少。
列出本地含有Action消息类型的所有包:
ros2 interface packages -a
自定义消息类型
除了内置的消息类型,ROS还允许用户创建自定义消息类型以满足特定需求。
在ROS2 行动
这一章中我们使用了自定义的动作消息类型接口,除此之外还有话题消息类型和服务消息类型。
这些自定义消息类型通常搭配话题和服务一起使用,以便节点之间进行通信。
在ROS中,已经预先定义了许多常用的消息接口,可以直接使用,无需自定义。例如,之前在turtlesim
中使用的geometry_msgs/msg/Twist
。但有时候,您的应用可能需要更复杂的消息类型,以满足特定的需求。
使用ROS提供的geometry_msgs/msg/Point
消息类型,它用于描述空间中的一个点。如果您只需要表示一个点的空间位置,那么Point
消息已经足够。但如果您需要更高级的信息,希望不仅了解点的空间位置,还需要知道它是否被占用,那么您可能需要引入额外的两个参数来表示该点的占用状态和分辨率。
在这种情况下,就需要考虑自定义一个新的消息类型,因为ROS中可能没有提供一个完全满足您需求的消息类型(假设没有)。这个新的消息类型可以包括以下字段:
x
:表示点的X坐标。y
:表示点的Y坐标。z
:表示点的Z坐标。is_occupied
:一个布尔值,用于指示该点是否被占用(occupied)。resolution
:一个浮点数,表示该点的分辨率。
通过自定义这个消息类型,您可以满足节点之间的通信需求,并在其中包含有关点的空间位置、占用状态和分辨率的信息。这样,您可以更灵活地处理机器人的感知数据和决策过程。
1.建立接口功能包
在ROS2中,自定义的接口通常被放在一个独立的功能包下,通常以_interfaces的方式命名。
值得注意的是,由于相关库依赖,这个包不可以作为一个纯粹的Python包,只能用ros2 pkg create ros2_learning_interfaces
或者指定ament_cmake
的方式来创建,但接口是可以在 C++ 或 Python 节点中通用的。
# Go to your src
cd ~/ros2_workspace/src
# Create interfaces package
ros2 pkg create ros2_learning_interfaces
2.建立自定义的消息类型文件文件夹
消息类型接口包通常包含三个子文件夹,分别用于存放自定义消息、服务和行动接口类型,他们是msg
、srv
、action
。
# Go to interfaces package
cd ros2_learning_interfaces
# Create directory to store interface files
mkdir msg
mkdir srv
mkdir action
# Check
ls
3.了解自定义服务消息类型(Service)
在这个部分,我们将以之前讲解Service机制时的两数加和demo为例,探讨如何创建自定义服务消息类型,以便执行三个整数的加和操作。
首先,让我们回顾一下之前的例子,其中我们使用了example_interfaces/srv/AddTwoInts
消息类型:
ros2 interface show example_interfaces/srv/AddTwoInts
通过查看上述消息类型,我们可以自然地推导出创建自定义服务消息类型以执行三个整数加和所需的消息类型。我们将创建一个名为AddThreeInts.srv
的服务消息类型,其定义如下:
# AddThreeInts.srv
int64 a
int64 b
int64 c
---
int64 sum
这个自定义服务消息类型请求三个名为a、b和c的整数,并返回求和后的sum。
4.创建自定义服务消息类型文件
首先,我们需要创建一个新的服务消息类型文件,名为AddThreeInts.srv
。假设您已进入包含服务消息类型的srv
目录,您可以使用以下命令创建文件:
# 进入包含服务消息类型的srv目录
cd ros2_learning_interfaces/srv/
# 创建文件
touch AddThreeInts.srv
接下来,将刚才推导出的新的三数加和服务消息类型定义填入AddThreeInts.srv
文件,并保存:
# AddThreeInts.srv
int64 a
int64 b
int64 c
---
int64 sum
5.更新CMakeLists.txt文件
在你的CMakeLists.txt文件中,需要添加以下内容:
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"srv/AddThreeInts.srv"
)
解释说明
find_package(rosidl_default_generators REQUIRED)
这行代码用于查找并引入 ROS 2 中与消息和动作生成相关的默认生成器。这些生成器将协助你生成用于编译和使用自定义消息和动作的代码。
rosidl
可能代表 “ROS Interface Definition Language”(ROS接口定义语言)。它用于定义和生成ROS消息、服务和动作的接口以及相关的代码。
rosidl
允许开发者通过一种接口定义语言(IDL)的方式定义消息结构、服务接口和动作接口,然后生成与这些接口相关的代码,以便在ROS 2中进行消息通信、服务调用和动作执行。
rosidl_default_generators
是一个用于生成ROS消息、服务和动作接口代码的工具,它在构建过程中会生成必要的代码,以便你的软件包可以与其他ROS节点进行通信。
rosidl_generate_interfaces(${PROJECT_NAME} "srv/AddThreeInts.srv")
这行代码告诉 ROS 2 生成器为你的项目生成与自定义服务消息类型 "AddThreeInts.srv"
相关的代码。这包括自动生成的C++源代码和头文件,以及与动作相关的其他文件。
6.修改 package.xml
要将以下内容添加到你的 package.xml 文件中:
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
相关解释
<buildtool_depend>rosidl_default_generators</buildtool_depend>
这一行代码指示你的 ROS 软件包在构建时需要依赖于 rosidl_default_generators
。这是一个 ROS 工具,用于生成 ROS 消息、服务和动作的源代码和编译规则。
<member_of_group>rosidl_interface_packages</member_of_group>
这一行代码将你的软件包添加到 rosidl_interface_packages
组中。这是一种组织 ROS 软件包的方式,通常包含定义消息、服务和动作接口的软件包。在 ROS 系统中,有多种不同类型的软件包,包括节点、库、工具等。rosidl_interface_packages
组用于标识具有相似功能和目的的软件包,即包含 ROS 接口(消息、服务和动作)定义的软件包。这有助于开发者更容易找到与 ROS 接口相关的软件包。
<exec_depend>rosidl_default_runtime</exec_depend>
rosidl_default_runtime
是运行时或执行阶段的依赖项,需要在执行软件包时加入。这是 ROS 提供的默认运行时库,用于支持 ROS 接口的运行时功能。
7.编译工作空间
在最后,编译工作空间,相关命令在之后的课程里会讲解,此处不涉及。
# Go to your workspace
cd ~/ros2_workspace
# Build workspace
colcon build --symlink-install
测试自定义消息类型
ros2 interface show ros2_learning_interfaces/srv/AddThreeInts
思考:
如何将这个三数加和的自定义话题用在此前的Service案例代码中?
最简单的自定义话题消息类型是什么样的呢,写一个包含字符串和数字的自定义话题类型试试
如何修改Topic的案例代码,使得它能够使用自定义的包含字符串和数字的自定义话题类型?