ROS2 学习(三)话题

话题

节点之间的通信。

叫话题很形象。发布者发布一定数据类型的话题,订阅者订阅发布者。

  • 订阅者发布者不唯一。

  • 异步通信,适用于周期发布的数据而不是逻辑性强的数据。

  • .msg 格式的消息结构,一种通信接口。

每个话题 topic 有话题名,数据类型和数据三个属性。

Hello world

pub 按一定周期发布 helloworld 信息,sub 接收。

pub:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2话题示例-发布“Hello World”话题
"""import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
from std_msgs.msg import String                  # 字符串消息类型"""
创建一个发布者节点
"""
class PublisherNode(Node):def __init__(self, name):super().__init__(name)                                    # ROS2节点父类初始化self.pub = self.create_publisher(String, "chatter", 10)   # 创建发布者对象(消息类型、话题名、队列长度)self.timer = self.create_timer(0.5, self.timer_callback)  # 创建一个定时器(单位为秒的周期,定时执行的回调函数)def timer_callback(self):                                     # 创建定时器周期执行的回调函数msg = String()                                            # 创建一个String类型的消息对象msg.data = 'Hello World'                                  # 填充消息对象中的消息数据self.pub.publish(msg)                                     # 发布话题消息self.get_logger().info('Publishing: "%s"' % msg.data)     # 输出日志信息,提示已经完成话题发布def main(args=None):                                 # ROS2节点主入口main函数rclpy.init(args=args)                            # ROS2 Python接口初始化node = PublisherNode("topic_helloworld_pub")     # 创建ROS2节点对象并进行初始化rclpy.spin(node)                                 # 循环等待ROS2退出node.destroy_node()                              # 销毁节点对象rclpy.shutdown()                                 # 关闭ROS2 Python接口

sub:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2话题示例-订阅“Hello World”话题消息
"""import rclpy                                     # ROS2 Python接口库
from rclpy.node   import Node                    # ROS2 节点类
from std_msgs.msg import String                  # ROS2标准定义的String消息"""
创建一个订阅者节点
"""
class SubscriberNode(Node):def __init__(self, name):super().__init__(name)                                    # ROS2节点父类初始化self.sub = self.create_subscription(\String, "chatter", self.listener_callback, 10)        # 创建订阅者对象(消息类型、话题名、订阅者回调函数、队列长度)def listener_callback(self, msg):                             # 创建回调函数,执行收到话题消息后对数据的处理self.get_logger().info('I heard: "%s"' % msg.data)        # 输出日志信息,提示订阅收到的话题消息def main(args=None):                                 # ROS2节点主入口main函数rclpy.init(args=args)                            # ROS2 Python接口初始化node = SubscriberNode("topic_helloworld_sub")    # 创建ROS2节点对象并进行初始化rclpy.spin(node)                                 # 循环等待ROS2退出node.destroy_node()                              # 销毁节点对象rclpy.shutdown()                                 # 关闭ROS2 Python接口

物品识别

之前 webcam 最好是分开写为两个节点之间的通信,一个是摄像头,一个是呈现的视频。

主要是拿到识别的图像数据之后不是第一时间就调用 opencv 算法处理,而是发给 sub,sub 进行处理。

这个发送的过程中的消息数据类型应当是 imgmsg 类型,所以需要一个 opencv -> imgmsg 类型的转换方法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2话题示例-发布图像话题
"""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图像处理库"""
创建一个发布者节点
"""
class ImagePublisher(Node):def __init__(self, name):super().__init__(name)                                           # ROS2节点父类初始化self.publisher_ = self.create_publisher(Image, 'image_raw', 10)  # 创建发布者对象(消息类型、话题名、队列长度)self.timer = self.create_timer(0.1, self.timer_callback)         # 创建一个定时器(单位为秒的周期,定时执行的回调函数)self.cap = cv2.VideoCapture(0)                                   # 创建一个视频采集对象,驱动相机采集图像(相机设备号)self.cv_bridge = CvBridge()                                      # 创建一个图像转换对象,用于稍后将OpenCV的图像转换成ROS的图像消息def timer_callback(self):ret, frame = self.cap.read()                                     # 一帧一帧读取图像if ret == True:                                                  # 如果图像读取成功self.publisher_.publish(self.cv_bridge.cv2_to_imgmsg(frame, 'bgr8'))             # 发布图像消息self.get_logger().info('Publishing video frame')                 # 输出日志信息,提示已经完成图像话题发布def main(args=None):                                 # ROS2节点主入口main函数rclpy.init(args=args)                            # ROS2 Python接口初始化node = ImagePublisher("topic_webcam_pub")        # 创建ROS2节点对象并进行初始化rclpy.spin(node)                                 # 循环等待ROS2退出node.destroy_node()                              # 销毁节点对象rclpy.shutdown()                                 # 关闭ROS2 Python接口

sub 代码:

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的图像消息的互相转换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)                         # 将苹果的图像中心点画出来cv2.imshow("object", image)                             # 使用OpenCV显示处理后的图像效果cv2.waitKey(10)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)                               # 苹果检测

流程是 opencv 图像数据转换成 ros2 可以传输的图像数据,传输给 sub,sub 再转回来再调用 opencv 库。

其实常用 usb 相机驱动基本都是一致的,所以 pub 节点我们不需要自己手动写。可以用下面的命令替代 pub,有一行 ERR 不影响。

$ sudo apt install ros-humble-usb-cam
$ ros2 run usb_cam usb_cam_node_exe 

ros2 topic bw 可以看带宽数据量。

可以通过 /rqt_graph 查看节点关系图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/41460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java高级开发高频面试题】面试者角度的口述版

文章目录 1.具备扎实的Java基础集合HashMap底层工作原理HashMap版本问题HashMap并发修改异常HashMap影响HashMap性能的因素HashMap使用优化 SynchronizedThreadLocalAQS线程池JVM内存模型类加载机制与双亲委派垃圾回收算法、垃圾回收器、空间分配担保策略引用计数器算法、可达性…

创建 Web 内容目录

创建 Web 内容目录 按照下方所述&#xff0c;创建一个名为 /home/curtis/ansible/webcontent.yml 的 playbook &#xff1a; 该 playbook 在 dev 主机组中的受管节点上运行 创建符合下列要求的目录 /webdev &#xff1a; 所有者为 webdev 组 具有常规权限&#xff1a;ownerread…

Nginx反向代理

目录 一.简介1.反向代理 二.案例1.案例12.案例2 一.简介 1.反向代理 1.1反向代理&#xff1a; 是指代理服务器来接收Internet上的客户端请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;并将从服务器上得到的结果返回给客户端。此时代理服务器对外就表现为一…

循环队列的实现(c语言)

前言 循环队列是队列的一种特殊的结构&#xff0c;在生产者——消费者模型中常常使用它&#xff0c; 它在逻辑上是一个环形的连续的结构。在物理可以使用数组来实现。 目录 1.循环队列的逻辑结构 2.空的循环队列和满的循环队列 3.循环队列插入和删除 4.代码实现 …

浅谈Redis的maxmemory设置以及淘汰策略

推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享&#xff0c;打开手机app&#xff0c;额外获得1T空间 https://dr…

音视频实时通话解决方案

1、问题提出 想要实现音视频通话,对于大部分人可能会觉得很难,但是实际上,有些事情并没有大家想的那样困难,只要功夫深,铁杵磨成针。 机缘巧合下,在业务中,我也遇到了一个业务场景需要实现音视频通话,我们不可能自己从零开始干,我本次用到的核心是WebRTC。 2、WebRT…

治疗偏头痛等亚疼痛的远程电神经调控(REN)设备

原文链接&#xff1a; NERIVIO CE标志适应症扩展到青少年和成人偏头痛的预防和急性治疗 (prnewswire.com) 公司官网&#xff1a; Homepage - Theranica APP下载链接&#xff1a; Migraine Headache Treatment - Nerivio 使用过程问题&#xff1a; 常见问题 - 无药物偏头痛两…

统计XML标注文件中各标注类别的标签数量

目标检测任务重&#xff0c;担心数据集中各标签类别不均衡&#xff0c;想统计XML标注文件中各标注类别的标签数量&#xff0c;可以使用以下脚本&#xff1a; import os import glob import xml.etree.ElementTree as etdef count_labels(source_dir):file_list glob.glob(os.…

Flink状态和状态管理

1.什么是状态 官方定义&#xff1a;当前计算流程需要依赖到之前计算的结果&#xff0c;那么之前计算的结果就是状态。 这句话还是挺好理解的&#xff0c;状态不只存在于Flink&#xff0c;也存在生活的方方面面&#xff0c;比如看到一个认识的人&#xff0c;如何识别认识呢&am…

神经网络基础-神经网络补充概念-24-随机初始化

由来 在神经网络的训练过程中&#xff0c;权重和偏差的初始值对模型的性能和训练过程的收敛速度都有影响。随机初始化是一种常用的权重和偏差初始值设置方法&#xff0c;它有助于打破对称性&#xff0c;避免网络陷入局部最优解。 概念 当所有权重和偏差都被设置为相同的初始…

Python Web框架:Django、Flask和FastAPI巅峰对决

今天&#xff0c;我们将深入探讨Python Web框架的三巨头&#xff1a;Django、Flask和FastAPI。无论你是Python小白还是老司机&#xff0c;本文都会为你解惑&#xff0c;带你领略这三者的魅力。废话不多说&#xff0c;让我们开始这场终极对比&#xff01; Django&#xff1a;百…

web基础入门和php语言基础入门 二

web基础入门和php语言基础入门 二 MySQL入门-续MySQL之数据查询操作MySQL其他知识点 php语言基础入门认识PHPPHP的工作流程安装PHP环境认识一个PHP程序PHP基础知识点进入正题 PHP与WEB交互PHP与MySQL交互总结 MySQL入门-续 MySQL之数据查询操作 WHERE 子句&#xff0c;条件限…

# 快速评估立功科技基于S32K324的TMS方案

文章目录 1.前言2.立功科技的TMS方案介绍2.1 介绍资料2.2 简要介绍 3.S32K3_TriMotor评估板测试3.1 环境搭建S32 Design Studio for S32 Platform 3.4安装RTD 2.0.0安装Freemaster 3.2 3.2 例程测试3.3 例程适配3.4 双核烧录3.5 测试 1.前言 最近和一些做汽车水泵/风机的客户交…

算法概述-Java常用算法

算法概述-Java常用算法 1、算法概念2、算法相关概念3、算法的性能评价4、算法应用归纳 1、算法概念 广泛算法定义&#xff1a;算法是模型分析的一组可行性的、确定的和有穷的规则。 经典算法特征&#xff1a;有穷性、确切性、输入、输出和可行性。 常用的算法包括递推、递归、穷…

maven如何建立JavaWeb项目并连接数据库,验证登录

这里是建立建立web项目&#xff1a;Maven如何创建Java web项目&#xff08;纯干货版&#xff09;&#xff01;&#xff01;&#xff01;_明天更新的博客-CSDN博客 我们主要演示如何连接数据库验证登录。 1.在webapp目录下创建我们的登录页面&#xff1a;index.jsp 还需要再…

Android漏洞之战——整体加壳原理和脱壳技巧详解

一、前言 为了帮助更加方便的进行漏洞挖掘工作&#xff0c;前面我们通过了几篇文章详解的给大家介绍了动态调试技术、过反调试技术、Hook技术、过反Hook技术、抓包技术等&#xff0c;掌握了这些可以很方便的开展App漏洞挖掘工作&#xff0c;而最后我们还需要掌握一定的脱壳技巧…

opencv基础:几个常用窗口方法

开始说了一些opencv中的一些常用方法。 namedWindow方法 在OpenCV中&#xff0c;namedWindow函数用于创建一个窗口&#xff0c;并给它指定一个名字。这个函数的基本语法如下&#xff1a; import cv2cv2.namedWindow(窗口名称, 标识 )窗口名称&#xff1a;其实窗口名称&…

Azure创建自定义VM镜像

创建一个虚拟机&#xff0c;参考 https://blog.csdn.net/m0_48468018/article/details/132267096&#xff0c;入站端口开启80&#xff0c;22 进行远程远程连接 使用CLI命令部署NGINX,输入如下命令 sudo su apt-get update -y apt-get install nginx git -y最后的效果 4. 关闭…

非结构化数据库-MinIO基本集成

是什么 MinIO 是一个高性能的分布式对象存储服务&#xff0c;适合存储非结构化数据&#xff0c;如图片&#xff0c;音频&#xff0c;视频&#xff0c;日志等。对象文件最大可以达到5TB。 安装启动 mkdir -p /usr/local/minio cd /usr/local/minio# 下载安装包 wget https:/…

pandas.errors.ParserError: Error tokenizing data. C error: out of memory

目录 用pandas读入数据的时候发现数据读入时出错了&#xff0c;数据量感觉也不是很大 十万多条数据。电脑内存是16个G。报错信息为&#xff1a;“ pandas.errors.ParserError: Error tokenizing data. C error: out of memory” 想想不对啊 昨天都可以顺利的读入&#xff0c;现…