ROS2——通信接口(十)
ROS2机器人操作系统
文章目录
- ROS2机器人操作系统
- 前言
- 一、ROS通信接口
- 语言无关
- 标准接口
- 二、接口案例
- 1.服务接口的定义与使用
- 接口定义
- 程序调用
- 2.话题接口的定义与使用
- 接口定义
- 接口命令行操作
前言
通信并不是一个人自言自语,而是两个甚至更多个人,你来我往的交流,交流的内容是什么呢?为了让大家都好理解,我们可以给传递的数据定义一个标准的结构,这就是通信接口。
一、ROS通信接口
接口可以让程序之间的依赖降低,便于我们使用别人的代码,也方便别人使用我们的代码,这就是ROS的核心目标,减少重复造轮子。
ROS有三种常用的通信机制,分别是话题、服务、动作,通过每一种通信种定义的接口,各种节点才能有机的联系到一起。
语言无关
为了保证每一个节点可以使用不同语言编程,ROS将这些接口的设计做成了和语言无关的,比如这里看到的int32表示32位的整型数,int64表示64位的整型数,bool表示布尔值,还可以定义数组、结构体,这些定义在编译过程中,会自动生成对应到C++、Python等语言里的数据结构。
话题通信接口的定义使用的是.msg文件,由于是单向传输,只需要描述传输的每一帧数据是什么就行,比如在这个定义里,会传输两个32位的整型数,x、y,我们可以用来传输二维坐标的数值。
服务通信接口的定义使用的是.srv文件,包含请求和应答两部分定义,通过中间的“—”区分,比如之前我们学习的加法求和功能,请求数据是两个64位整型数a和b,应答是求和的结果sum。
动作是另外一种通信机制,用来描述机器人的一个运动过程,使用.action文件定义,比如我们让小海龟转90度,一边转一边周期反馈当前的状态,此时接口的定义分成了三个部分,分别是动作的目标,比如是开始运动,运动的结果,最终旋转的90度是否完成,还有一个周期反馈,比如每隔1s反馈一下当前转到第10度、20度还是30度了,让我们知道运动的进度。
标准接口
大家可能好奇ROS系统到底给我们定义了哪些接口呢?我们可以在ROS安装路径中的share文件夹中找到,涵盖众多标准定义,大家可以打开几个看看。
二、接口案例
1.服务接口的定义与使用
有三个节点,第一个驱动相机发布图像话题,第二个是机器视觉识别节点,封装了一个服务的服务端对象,提供目标识别位置的查询服务,第三个节点在需要目标位置的时候,就可以发送请求,收到位置进行使用了。
接口定义
bool get # 获取目标位置的指令
---
int32 x # 目标的X坐标
int32 y # 目标的Y坐标
用三横线来区分话题里面的请求数据和应答数据
定义中有两个部分,上边是获取目标位置的指令,get为true的话,就表示我们需要一次位置,服务端就会反馈这个x、y坐标了。
完成定义后,还需要在功能包的CMakeLists.txt中配置编译选项,让编译器在编译过程中,根据接口定义,自动生成不同语言的代码:
…
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
“srv/GetObjectPosition.srv”
)
…
功能包的package.xml文件中也需要添加代码生成的功能依赖:
…c
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
…
程序调用
客户端接口调用
import rclpy # ROS2 Python接口库
from rclpy.node import Node # ROS2 节点类
from learning_interface.srv import GetObjectPosition # 自定义的服务接口class objectClient(Node):def __init__(self, name):super().__init__(name) # ROS2节点父类初始化self.client = self.create_client(GetObjectPosition, 'get_target_position')while not self.client.wait_for_service(timeout_sec=1.0):self.get_logger().info('service not available, waiting again...')self.request = GetObjectPosition.Request()def send_request(self):self.request.get = Trueself.future = self.client.call_async(self.request)def main(args=None):rclpy.init(args=args) # ROS2 Python接口初始化node = objectClient("service_object_client") # 创建ROS2节点对象并进行初始化node.send_request()while rclpy.ok():rclpy.spin_once(node)if node.future.done():try:response = node.future.result()except Exception as e:node.get_logger().info('Service call failed %r' % (e,))else:node.get_logger().info('Result of object position:\n x: %d y: %d' %(response.x, response.y))breaknode.destroy_node() # 销毁节点对象rclpy.shutdown() # 关闭ROS2 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 # 自定义的服务接口lower_red = np.array([0, 90, 128]) # 红色的HSV阈值下限
upper_red = np.array([180, 255, 255]) # 红色的HSV阈值上限class ImageSubscriber(Node):def __init__(self, name):super().__init__(name) # ROS2节点父类初始化self.sub = self.create_subscription(Image, 'image_raw', self.listener_callback, 10) # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)self.cv_bridge = CvBridge() # 创建一个图像转换对象,用于OpenCV图像与ROS的图像消息的互相转换self.srv = self.create_service(GetObjectPosition, # 创建服务器对象(接口类型、服务名、服务器回调函数)'get_target_position',self.object_position_callback) self.objectX = 0self.objectY = 0 def object_detect(self, image):hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 图像从BGR颜色模型转换为HSV模型mask_red = cv2.inRange(hsv_img, lower_red, upper_red) # 图像二值化contours, hierarchy = cv2.findContours(mask_red, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # 图像中轮廓检测for cnt in contours: # 去除一些轮廓面积太小的噪声if cnt.shape[0] < 150:continue(x, y, w, h) = cv2.boundingRect(cnt) # 得到苹果所在轮廓的左上角xy像素坐标及轮廓范围的宽和高cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)# 将苹果的轮廓勾勒出来cv2.circle(image, (int(x+w/2), int(y+h/2)), 5,(0, 255, 0), -1) # 将苹果的图像中心点画出来self.objectX = int(x+w/2)self.objectY = int(y+h/2)cv2.imshow("object", image) # 使用OpenCV显示处理后的图像效果cv2.waitKey(50)def listener_callback(self, data):self.get_logger().info('Receiving video frame') # 输出日志信息,提示已进入回调函数image = self.cv_bridge.imgmsg_to_cv2(data, 'bgr8') # 将ROS的图像消息转化成OpenCV图像self.object_detect(image) # 苹果检测def object_position_callback(self, request, response): # 创建回调函数,执行收到请求后对数据的处理if request.get == True:response.x = self.objectX # 目标物体的XY坐标response.y = self.objectYself.get_logger().info('Object position\nx: %d y: %d' %(response.x, response.y)) # 输出日志信息,提示已经反馈else:response.x = 0response.y = 0self.get_logger().info('Invalid command') # 输出日志信息,提示已经反馈return responsedef main(args=None): # ROS2节点主入口main函数rclpy.init(args=args) # ROS2 Python接口初始化node = ImageSubscriber("service_object_server") # 创建ROS2节点对象并进行初始化rclpy.spin(node) # 循环等待ROS2退出node.destroy_node() # 销毁节点对象rclpy.shutdown() # 关闭ROS2 Python接口
2.话题接口的定义与使用
话题通信接口的定义也是类似的,继续从之前的机器视觉案例中来衍生,我们想把服务换成话题,周期发布目标识别的位置,不管有没有人需要。
运行效果
现在我们会运行三个节点:
第一个节点,将驱动相机并发布图像话题,此时的话题数据使用的是ROS中标准定义的Image图像消息;
第二个节点,会运行视觉识别功能,识别目标的位置,这个位置我们希望封装成话题消息,发布出去,谁需要使用谁就来订阅;
第三个节点,订阅位置话题,打印到终端中。
$ ros2 run usb_cam usb_cam_node_exe
$ ros2 run learning_topic interface_object_pub
$ ros2 run learning_topic interface_object_sub
接口定义
int32 x # 表示目标的X坐标
int32 y # 表示目标的Y坐标
话题消息的内容是一个位置,我们使用x、y坐标值进行描述。
接口命令行操作
ros2 interface list # 查看系统接口列表
ros2 interface show <interface_name> # 查看某个接口的详细定义
ros2 interface package <package_name> # 查看某个功能包中的接口定义
ROS2——通信接口(十)相关推荐
- 【STC32G12K128开发板】——STC32G12K128开发板介绍
版权声明:本文为博主原创文章,转载请附上原文出处链接. 文章目录 前言 一.STC32G12K128系列单片机介绍 二.STC32G12K128开发板概述 三.STC32G12K128开发板硬件框图 ...
- 系统规划与管理备考整理
@ 一.信息系统综合知识 1.1 信息的定义和属性 1.信息是客观事物状态和运动特征的一种普遍相识,客观世界中大量存在.产生和传递着以这些方式表示出各种各样的信息 (1)信息的定性描述 控制论的创始人 ...
- ROS2学习(十二).ROS概念 - RQt工具的使用
RQt工具的概述和使用 概述 系统设置 Debian安装包 源码编译安装 RQt组件结构 RQt框架优势 扩展阅读 概述 RQt是一个图形用户界面框架,它以插件的形式实现了各种工具和人机界面接口.我们 ...
- 单片机小白学步系列(十八) 单片机/计算机系统概述:通信接口与协议
前面说了信息与数据的概念,这里要说的是与之关系密切的问题--通信. 通信 何为通信?在英文中,通信用Communication表示,这个词也有交流的意思.实际上,通信和交流确实是一样的意思.不过在汉语 ...
- 无人驾驶汽车系统入门(三十二)——ROS2概述和实践入门(一)
ROS可以说是目前机器人相关开源社区最流行的项目之一,它是一个易用且完备的机器人开发框架.生态乃至社区,海量的机器人开源项目(涵盖感知.规划.控制.定位.SLAM和建图.可视化等几乎所有机器人领域)均 ...
- ROS2学习笔记(十)-- ROS2 launch启动文件
简介:接触过ROS1的同学对launch肯定不陌生,在ROS1中,我们常用launch实现node和master同时启动.多节点同时启动配置等功能,ROS2中的launch也是用于多节点启动.配置功能 ...
- ROS2——Rviz:三维可视化显示平台(十八)
ROS2机器人操作系统 文章目录 ROS2机器人操作系统 前言 一.启动rviz 二.使用步骤 1.图像数据可视化 2.相机点云数据可视化 3.雷达点云数据可视化 总结 前言 一句话说明Rviz的功能 ...
- ROS2学习(十六).ROS概念 - 构建系统
关于ROS 2的构建系统 `ament_package`包 **package.xml** **ament package** `ament_cmake`代码库 `ament_lint`代码库 构建工 ...
- ROS2学习(十).ROS概念 - 主题的统计
主题统计 概述 如何计算统计数据 统计数据种类 行为 同ROS 1的比较 支持 参考 概述 ROS 2为任何订阅所接收的消息提供综合统计功能.这允许用户收集订阅统计信息,同时可以更好地描述系统的性能或 ...
- 十大机器智能新型芯片:华为抢占一席,Google占比最多
(图片付费下载自视觉中国) 整理 | 胡巍巍 来源 | CSDN(ID:CSDNnews) 当年,阿基米德爷爷说出"给我一个支点,我就能撬动地球"这句话时,估计没少遭受嘲讽. 然而 ...
最新文章
- 【转】 LINUX中IPTABLES和TC对端口的带宽限制 端口限速
- FBEC2021暨第六届金陀螺奖颁奖典礼盛大开幕
- vmware安装渗透系统 Linux Kail最新版
- Salesforce 中获取数据表字段的 picklist 的值
- 06Matplotlib数据可视化--6.2散点图
- ODOO v10.0 自动生成财务凭证的科目设置
- Windows Server 2008R2 Web服务器
- kotlin 泛型约束
- UGUI的image
- 模拟处理机作业调度---短作业优先调度算法
- 5.docker 命令
- TreeSet与TreeMap
- c语言 鼠标指针图标,WIN7系统鼠标图案DIY!自己动手,美不胜收!-win7鼠标指针...
- V5Shop网店系统更新 版本V8.30.0606 RC1
- 内存映射文件原理探索
- 小米8可以刷鸿蒙os,鸿蒙 OS 2.0 来了!小米也能用么?
- python学习笔记(6)
- Python OpenCV 保存mp4视频
- 01 - Python 调用outlook发送邮件
- EfficientNet V1 V2总结
热门文章
- 网页中插入透明Flash的方法和技巧
- 802.11n无线网卡驱动linux,Ubuntu 无线网卡驱动安装教程
- 专业的笔记本测试软件,专业软件性能测试
- 网页右下角3秒自动弹出悬浮在线客服代码
- 三字代码html,【涨知识】原来三字代码是这样来的!四字代码是什么?
- java社交框架,java毕业设计_springboot框架的社交平台
- 小说网站源码_ptcms精美小说阅读网站源码(带采集规则)
- 网吧的监控系统和服务器如何连接,网吧监控系统安装解决方案
- 中望3D2022弹簧的设计
- 太阳高度角计算题_【难点突破】太阳高度角与正午太阳高度角区别(附例题解析)...