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"
 )

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


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  # 自定义的目标位置消息
相关推荐
whale fall2 小时前
【剑雅14】笔记
笔记
星空的资源小屋3 小时前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Xudde.4 小时前
Quick2靶机渗透
笔记·学习·安全·web安全·php
AA陈超4 小时前
Git常用命令大全及使用指南
笔记·git·学习
愚戏师5 小时前
Python3 Socket 网络编程复习笔记
网络·笔记
降临-max6 小时前
JavaSE---网络编程
java·开发语言·网络·笔记·学习
大白的编程日记.7 小时前
【计算网络学习笔记】MySql的多版本控制MVCC和Read View
网络·笔记·学习·mysql
IMPYLH8 小时前
Lua 的 require 函数
java·开发语言·笔记·后端·junit·lua
WWZZ20259 小时前
快速上手大模型:深度学习12(目标检测、语义分割、序列模型)
深度学习·算法·目标检测·计算机视觉·机器人·大模型·具身智能
YJlio11 小时前
进程和诊断工具学习笔记(8.29):ListDLLs——一眼看清进程里加载了哪些 DLL,谁在偷偷注入
android·笔记·学习