ROS2 Humble 笔记(七)标准与自定义 Interface 接口

这篇博客是 B 站《古月·ROS2入门21讲》的第十个视频的图文记录,主要介绍了如何自定义 srv 与 msg 接口并将其编译成不同语言可以使用的对象。原始视频链接如下:


1. ROS 自带的标准数据接口

你可以前往 /opt/ros/humble/share 目录下查看 ROS 自带的标准数据接口有哪些:

这里以最常用的 /opt/ros/humble/share/sensor_msgs/msg 为例,进入该文件夹可以看到以下内容:

打开其中的 Image.msg 即可看到官分如何定义标准数据接口,当我们在写自定义接口的时候可以将其作为参考,特别是明确注释的撰写,因为 接口是为了方便沟通 而设计的,如果你的接口只有你自己看的懂,那这个接口将失去作用。


2. ros2 interface 命令

2.1 list

可以通过下面的命令查看 ROS 自带的接口有哪些:

python 复制代码
$ ros2 interface list

2.2 show

如果想要查看某个接口的详细信息可以使用 show 命令:

bash 复制代码
$ ros2 interface show sensor_msgs/msg/PointCloud2

2.3 package

如果想查看某个功能包中定义了哪些接口,可以使用下面的命令:

bash 复制代码
$ ros2 interface package sensor_msgs 

该命令在自己的工作空间中也是生效的,但一定要注意 source 操作,否则无法找到环境变量:

bash 复制代码
$ cd dev_ws
$ source install/local_setup.sh
$ ros2 interface package learning_interface 

3. 自定义 srv 接口

在上一篇博客 《ROS2 Humble 笔记(六)Service 服务 Server & Client 交互》 中提了一句有关自定义服务接口的内容,在此处将详细介绍一下如何定义并实现。


3.1 srv 文件内容

在 learning_interface 功能包中有一个 srv 文件夹,具体位置为 src/ros2_21_tutorials/learning_interface/srv 处,该文件夹下有两个文件:

  • AddTwoInts.srv:
python 复制代码
int64 a        # 第一个加数
int64 b        # 第二个加数
---
int64 sum      # 求和结果
  • GetObjectPosition.srv:
python 复制代码
bool get      # 获取目标位置的指令
---
int32 x       # 目标的X坐标
int32 y       # 目标的Y坐标

自定义服务文件的编写格式如下,请求和响应中间用 三个 - 分割,并且 请求部分是非必须的:

python 复制代码
# Request
DataType req_variable_name	# 请求中的变量信息
---
# Response
DataType res_variable_name	# 相应中的变量信息

3.2 编译 srv 文件

在同级目录下有一个 CMakeLists.txt 文件,具体位置为 src/ros2_21_tutorials/learning_interface/CMakeLists.txt,找到 25 行附近内容如下:

cmake 复制代码
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/ObjectPosition.msg"
  "srv/AddTwoInts.srv"
  "srv/GetObjectPosition.srv"
  "action/MoveCircle.action"
 )

这段内容的意思将上面几个 srv、msg 文件编译成不同语言可以使用的通用接口。


3.3 使用自定义接口

打开 learning_services 功能包找到 service_object_server.py 文件,具体位置为 src/ros2_21_tutorials/learning_service/learning_service/service_object_server.py,可以看到在导入库的部分从 learning_interface 包中的 srv 模块直接导入 GetObjectPosition 对象:

python 复制代码
import rclpy                                           # ROS2 Python接口库
from rclpy.node import Node                            # ROS2 节点类
from sensor_msgs.msg import Image                      # 图像消息类型
import numpy as np                                     # Python数值计算库
from cv_bridge import CvBridge                         # ROS与OpenCV图像转换类
import cv2                                             # Opencv图像处理库
from learning_interface.srv import GetObjectPosition   # 自定义的服务接口

该 GetObjectPosition 对象的具体内容可以从 install/learning_interface/local/lib/python3.10/dist-packages/learning_interface/srv/_get_object_position.py 文件中查看,这个文件就是上面 CMakeLists.txt 文件编译生成的内容:

python 复制代码
import builtins  # noqa: E402, I100

import rosidl_parser.definition  # noqa: E402, I100


class Metaclass_GetObjectPosition_Request(type):
    """Metaclass of message 'GetObjectPosition_Request'."""

    _CREATE_ROS_MESSAGE = None
    _CONVERT_FROM_PY = None
    _CONVERT_TO_PY = None
    _DESTROY_ROS_MESSAGE = None
    _TYPE_SUPPORT = None

...

如果你想看 C++ 生成的文件内容是什么样的话,可以查看 install/learning_interface/include/learning_interface/learning_interface/srv/get_object_position.h 文件:

cpp 复制代码
// generated from rosidl_generator_c/resource/idl.h.em
// with input from learning_interface:srv/GetObjectPosition.idl
// generated code does not contain a copyright notice

#ifndef LEARNING_INTERFACE__SRV__GET_OBJECT_POSITION_H_
#define LEARNING_INTERFACE__SRV__GET_OBJECT_POSITION_H_

#include "learning_interface/srv/detail/get_object_position__struct.h"
#include "learning_interface/srv/detail/get_object_position__functions.h"
#include "learning_interface/srv/detail/get_object_position__type_support.h"

#endif  // LEARNING_INTERFACE__SRV__GET_OBJECT_POSITION_H_

4. 自定义 msg 接口

4.1 使用自定义接口

【Note】:由于我的设备没有相机,因此这里不进行演示,有条件的读者可以自行体验。

  • 启动相机节点 usb_cam_node_exe:
bash 复制代码
$ ros2 run usb_cam usb_cam_node_exe
  • 启动相机画面订阅节点 interface_object_pub,在处理后发布出来:
bash 复制代码
$ ros2 run learning_topic interface_object_pub
  • 启动订阅节点 interface_object_sub:
bash 复制代码
$ ros2 run learning_topic interface_object_sub

4.2 msg 文件内容

这三个节点之间的交互是通过话题实现的,定义的接口的位置为 src/ros2_21_tutorials/learning_interface/msg/ObjectPosition.msg:

  • ObjectPosition.msg:
python 复制代码
int32 x      # 表示目标的X坐标
int32 y      # 表示目标的Y坐标

4.3 编译 msg 文件

在 learning_interface 功能包下的 CMakeLists.txt 文件可以找到编译该 msg 文件的写法,具体位置在 src/ros2_21_tutorials/learning_interface/CMakeLists.txt:

cmake 复制代码
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/ObjectPosition.msg"
  "srv/AddTwoInts.srv"
  "srv/GetObjectPosition.srv"
  "action/MoveCircle.action"
 )

4.4 节点内部使用

打开 interface_object_pub 节点可以看到在导入库的位置处将自定义的 msgs 对象导入,具体位置为 src/ros2_21_tutorials/learning_topic/learning_topic/interface_object_pub.py:

python 复制代码
import rclpy                                       # ROS2 Python接口库
from rclpy.node import Node                        # ROS2 节点类
from sensor_msgs.msg import Image                  # 图像消息类型
from cv_bridge import CvBridge                     # ROS与OpenCV图像转换类
import cv2                                         # Opencv图像处理库
import numpy as np                                 # Python数值计算库
from learning_interface.msg import ObjectPosition  # 自定义的目标位置消息
相关推荐
杨逢昌工厂6S管理22 分钟前
116——杨逢昌:归位三定闭环法的旺季轻量化执行方案与工具清单
经验分享·笔记·职场和发展·学习方法
想喝奶茶啾啾23 分钟前
AMBA CHI架构以及规范中使用的术语 翻译笔记(1)
笔记·arm·chi
LeeZhao@35 分钟前
【具身智能】VLA-DM0.5:让机器人真正理解世界
人工智能·计算机视觉·机器人·agi
yi0112 小时前
LeetCode 3. 无重复字符的最长子串|不定长滑动窗口:什么时候更新最大值?
笔记·python·算法·leetcode·双指针·滑动窗口
XMAIPC_Robot2 小时前
工商业储能EMS边缘计算:本地AI负荷预测,彻底摆脱云端依赖
人工智能·fpga开发·机器人·边缘计算·arm+fpga·rk3588+fpga
Water_based2 小时前
水性滚涂漆应用于滚喷机小五金件喷涂工艺详解
经验分享·笔记·产品经理
只愿云淡风清3 小时前
正则表达式学习笔记-01 正则表达式的来源
笔记·学习·正则表达式
wjkjpcba3 小时前
机器人控制板PCBA贴片厂家制造工艺解析:SMT贴片、DIP插件与检测流程
人工智能·机器人·smt贴片加工·pcba贴片加工厂
ljt27249606613 小时前
Vue笔记(十三)--mixin
vue.js·笔记
启观川4 小时前
数据结构与算法 -第 3 章 常用算法-回溯算法
数据结构·笔记·python·算法