说明:本文基于ubuntu22.04和ros2 humble版本
一、接口基础
1.接口介绍
接口(interface)其实是一种规范。之前使用过的两种接口,这两种数据类型分别代表字符串和32位二进制的整型数据,是ROS2提前定义的一种规范。
std_msgs/msg/String
std_msgs/msg/UInt32
使用接口的意义:
不同的厂家生产出不同的类型的激光雷达,每种雷达驱动方式、扫描速率等等都不相同。
当机器人进行导航时,需要激光雷达的扫描数据,假如没有统一接口,每次更换一个种类的雷达,都需要重新做程序适配。
于是ROS2中定义了一个统一的接口叫做
sensor_msgs/msg/LaserScan
,现在几乎每个雷达的厂家都会编写程序将自己雷达的数据变成sensor_msgs/msg/LaserScan
格式,提供给用户使用。
ROS2自带的接口:
ROS2
还定义了很多做机器人常用的接口。传感器类的消息包是sensor_msgs
#打开终端输入下一行命令,可以查看sensor_msgs接口包下的所有接口
ros2 interface package sensor_msgs
sensor_msgs/msg/JointState #机器人关节数据
sensor_msgs/msg/Temperature #温度数据
sensor_msgs/msg/Imu #加速度传感器
sensor_msgs/msg/Image #图像
sensor_msgs/msg/LaserScan #雷达数据
......
2.接口文件
2.1可以自定义的三种通信接口
ROS2提供的四种通信方式中除了参数之外,话题、服务和动作(Action)都支持自定义接口,每一种通信方式所适用的场景各不相同,所定义的接口也被分为话题接口、服务接口、动作接口三种。
2.2三种接口定义的格式
话题接口格式:xxx.msg
int64 num
服务接口格式:xxx.srv
int64 a
int64 b
---
int64 sum
动作接口格式:xxx.action
int32 order
---
int32[] sequence
---
int32[] partial_sequence
2.3接口数据类型
根据引用方式的不同,可以分为基础类型和包装类型两类。
基础类型有(同时后面加上[ ]可形成数组)
bool
byte
char
float32,float64
int8,uint8
int16,uint16
int32,uint32
int64,uint64
string
包装类型,即在已有的接口类型上进行包装,比如
uint32 id
string image_name
sensor_msgs/Image
在接口文件中定义通信过程中所使用的数据类型和数据名称。
通过基本类型的组合,可以构成一个新的数据类型,而新的数据类型又可以和基本类型或者另外一个数据类型互相组成另一个数据类型。
图像数据类型sensor_msgs/Image
ros2 interface show sensor_msgs/msg/Image
2.4接口生成代码
只是简单的在接口文件中写了一下变量类型和名称,如何在程序里面怎么调用?是通过导入头文件使用这个消息模块。接口转换的过程:将msg、srv、action文件转换为Python和C++的头文件
3.自定义接口实践
3.1场景
一个机器人开发中的常见控制场景,需要设计满足要求的服务接口和话题接口。
设计两个节点
- 机器人本体节点,对外提供移动指定距离服务,移动完成后返回当前位置,同时对外发布机器人的位置和状态。
- 机器人控制节点,通过服务控制机器人移动指定距离,并实时获取机器人的当前位置和状态。
假设机器人在坐标轴上,只能前后移动。
3.2定义接口
服务接口MoveRobot.srv
# 前进后退的距离
float32 distance
---
# 当前的位置
float32 pose
话题接口,采用基础类型 RobotStatus.msg
uint32 STATUS_MOVEING = 1
uint32 STATUS_STOP = 1
uint32 status
float32 pose
话题接口,混合包装类型 RobotPose.msg
uint32 STATUS_MOVEING = 1
uint32 STATUS_STOP = 2
uint32 status
geometry_msgs/Pose pose
3.3创建接口功能包编写接口
cd chapt3_ws/src
ros2 pkg create example_ros2_interfaces --build-type ament_cmake --dependencies rosidl_default_generators geometry_msgs
注意功能包类型必须为:ament_cmake
依赖
rosidl_default_generators
必须添加,geometry_msgs
视内容情况添加(我们这里有geometry_msgs/Pose pose
所以要添加)。接着创建文件夹和文件将3.2中文件写入,注意话题接口放到
msg
文件夹下,以.msg
结尾。服务接口放到srv
文件夹下,以.srv
结尾。
修改CMakeLists.txt,添加依赖
find_package(rosidl_default_generators REQUIRED)
find_package(geometry_msgs REQUIRED)
# 添加下面的内容
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/RobotPose.msg"
"msg/RobotStatus.msg"
"srv/MoveRobot.srv"
DEPENDENCIES geometry_msgs
)
修改package.xml
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rosidl_default_generators</depend>
<depend>geometry_msgs</depend>
<member_of_group>rosidl_interface_packages</member_of_group> #添加这一行
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
在工作空间下编译
colcon build --packages-select example_ros2_interfaces
编译完成后在chapt3_ws/install/example_ros2_interfaces/include
下应该可以看到C++的头文件。
在chapt3_ws/install/example_ros2_interfaces/local/lib/python3.10/dist-packages
下应该可以看到Python版本的头文件。
编译失败
4.接口常用CLI命令
查看接口列表
ros2 interface list
查看某接口的详细内容
ros2 interface show std_msgs/msg/String