ROS2系列 (16) : Python服务通信实例——自定义消息接口
ROS2系列 (16) : Python服务通信实例——自定义消息接口(人脸检测服务前置)
在ROS2服务通信中,自定义消息接口是实现个性化“请求-响应”的基础。本文将以“人脸检测服务”为例,详解如何创建自定义服务接口包,为后续服务端和客户端开发奠定基础。
一、需求与技术拆解
需求:创建人脸检测服务,客户端提供图像,服务端返回人脸数量和位置信息。
技术拆解:
- 如何定义服务接口?—— 自定义
.srv文件,声明请求(图像)和响应(人脸信息)结构。 - 如何组织文件架构?—— 遵循ROS2功能包规范,通过
rosidl_default_generators自动生成多语言接口。 - 如何确保跨语言兼容?—— 依赖官方消息类型(如
sensor_msgs/Image),保证Python和C++节点的互操作性。
二、创建工作空间与功能包
2.1 搭建工作空间
mkdir -p ~/chapt4/chapt4_ws/src
cd ~/chapt4/chapt4_ws
code . # 可选:用VSCode打开工作空间
2.2 创建自定义接口功能包
在src目录下创建功能包,用于管理人脸检测的服务接口:
cd src
ros2 pkg create chapt4_interfaces --dependencies sensor_msgs rosidl_default_generators --license Apache-2.0
--dependencies sensor_msgs:依赖官方图像消息类型,用于传输人脸检测的输入图像;--dependencies rosidl_default_generators:依赖消息生成工具,自动生成Python/C++接口代码。
三、组织自定义服务接口文件架构
功能包的文件架构需遵循ROS2规范,重点关注srv目录和配置文件:
chapt4_interfaces/
├── srv/ # 存放自定义服务接口文件
│ └── FaceDetector.srv # 人脸检测服务的请求-响应定义
├── CMakeLists.txt # 构建配置(声明服务接口和依赖)
├── package.xml # 功能包元信息(声明依赖和接口类型)
└── LICENSE
四、编写自定义服务接口(.srv文件)
在chapt4_interfaces/srv/目录下创建FaceDetector.srv,定义请求和响应结构:
sensor_msgs/Image image # 人脸图像(请求字段)
---
int16 number # 人脸个数(响应字段)
float32 use_time # 识别耗时
int32[] top # 人脸在图像中的位置(上边界)
int32[] right # 人脸在图像中的位置(右边界)
int32[] bottom # 人脸在图像中的位置(下边界)
int32[] left # 人脸在图像中的位置(左边界)
- 请求部分:仅包含一个
sensor_msgs/Image类型的字段image,用于传输待检测的图像; - 响应部分:包含人脸数量、识别耗时和人脸位置数组,用于反馈检测结果。
五、配置package.xml
打开chapt4_interfaces/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>chapt4_interfaces</name><version>0.0.0</version><description>人脸检测服务的自定义接口包</description><maintainer email="your@email.com">your_name</maintainer><license>Apache-2.0</license><!-- 构建依赖 --><buildtool_depend>ament_cmake</buildtool_depend><buildtool_depend>rosidl_default_generators</buildtool_depend><!-- 运行依赖 --><depend>sensor_msgs</depend><depend>rosidl_default_runtime</depend><!-- 声明为接口包 --><member_of_group>rosidl_interface_packages</member_of_group><export><build_type>ament_cmake</build_type></export>
</package>
<member_of_group>rosidl_interface_packages</member_of_group>:声明该功能包是ROS2接口包,确保工具链能识别并生成多语言代码;rosidl_default_generators和rosidl_default_runtime:分别为构建和运行时的消息生成依赖。
六、配置CMakeLists.txt
打开chapt4_interfaces/CMakeLists.txt,添加服务接口的构建规则:
cmake_minimum_required(VERSION 3.8)
project(chapt4_interfaces)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# 查找依赖包
find_package(ament_cmake REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)# 声明自定义服务接口文件
set(srv_files"srv/FaceDetector.srv"
)# 生成服务接口的多语言代码(Python/C++)
rosidl_generate_interfaces(${PROJECT_NAME}${srv_files}DEPENDENCIES sensor_msgs # 依赖sensor_msgs以使用Image类型
)ament_package()
rosidl_generate_interfaces:核心指令,自动解析.srv文件,生成Python的模块和C++的头文件;DEPENDENCIES sensor_msgs:声明依赖sensor_msgs,确保生成的接口能正确引用Image类型。
七、构建并验证自定义接口
7.1 构建功能包
在工作空间根目录执行构建:
cd ~/chapt4/chapt4_ws
colcon build --packages-select chapt4_interfaces
7.2 验证接口生成
先source环境变量,再通过ros2 interface show查看生成的服务接口:
source install/setup.bash
ros2 interface show chapt4_interfaces/srv/FaceDetector
输出应与我们编写的.srv文件一致:
sensor_msgs/Image imagestd_msgs/Header headerbuiltin_interfaces/Time stampint32 secuint32 nanosecstring frame_iduint32 heightuint32 widthstring encodinguint8 is_bigendianuint32 stepuint8[] data
---
int16 number
float32 use_time
int32[] top
int32[] right
int32[] bottom
int32[] left
这表明自定义服务接口已成功生成,且正确引用了sensor_msgs/Image的结构。
八、总结
本文完成了“人脸检测服务”的自定义接口开发,核心流程包括:
- 功能包创建与依赖配置:基于
sensor_msgs和rosidl_default_generators创建接口包; - 服务接口定义:通过
.srv文件声明“图像请求-人脸信息响应”的结构; - 构建与验证:通过
colcon build生成多语言接口,并通过ros2 interface show验证。
后续会接着基于该接口开发服务端(人脸检测算法实现)和客户端(图像发送与结果解析),完成完整的人脸检测服务闭环。
