当前位置: 首页 > news >正文

ros2-3.4话题通信最佳实践

3.4.1 工程架构设计

需求背景:

第一,通过这个小工具可以看到系统的实时状态信息包括记录信息的时间、主机名称、CPU使用率、内存使用率、内存总大小、剩余内存、网络接收数据量和网络发送数据量;
第二,要有一个简单的界面,可以将系统信息显示出来;
第三,要能在局域网内其他主机上查看数据

设计:

第一,要能获取系统状态信息;Python库psutils
第二,要有一个展示界面:Qt
第三,要能共享数据。ROS2话题

3.4.2 自定义通信接口

在topic_practice_ws/src下面创建一个新的功能包

ros2 pkg create status_interfaces --dependencies builtin_interfaces rosidl_default_generators --license Apache-2.0

其中2个依赖:

builtin_interfaces 可以使用时间接口Time

rosidl_default_generators 是用来把自定义消息转换为C++、python的源码。

在功能包下新建msg文件夹,并在该文件夹下新建文件SystemStatus.msg。内容如下:

builtin_interfaces/Time stamp # 记录时间戳
string host_name 		# 系统名称
float32 cpu_percent 	# CPU使用率
float32 memory_percent 	# 内存使用率
float32 memory_total 	# 内存总量
float32 memory_available 	# 剩余有效内存
float64 net_sent 		# 网络发送数据总量
float64 net_recv 		# 网络接收数据总量

修改CMakeLists.txt,对接口文件进行注册,声明为接口文件,并增加builtin_interfaces 依赖。

cmake_minimum_required(VERSION 3.8)
project(status_interfaces)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# find dependencies
find_package(ament_cmake REQUIRED)
find_package(builtin_interfaces REQUIRED)
find_package(rosidl_default_generators REQUIRED)
#cmake 函数,来自依赖rosidl_default_generators,用于讲msg消息接口定义文件转换成库或者头文件
rosidl_generate_interfaces(${PROJECT_NAME}"msg/SystemStatus.msg"DEPENDENCIES builtin_interfaces
)if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)# the following line skips the linter which checks for copyrights# comment the line when a copyright and license is added to all source filesset(ament_cmake_copyright_FOUND TRUE)# the following line skips cpplint (only works in a git repo)# comment the line when this package is in a git repo and when# a copyright and license is added to all source filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()
endif()ament_package()

修改packages.xml中,增加声明

<member_of_group>rosidl_interface_packages</member_of_group>

接下来构建,并查看

bohu@bohu-TM1701:~/3/topic_practice_ws$ colcon build
Starting >>> status_interfaces
Finished <<< status_interfaces [6.51s]                     Summary: 1 package finished [6.88s]
bohu@bohu-TM1701:~/3/topic_practice_ws$ source install/setup.bash 
bohu@bohu-TM1701:~/3/topic_practice_ws$ ros2 interface show status_interfaces/msg/SystemStatus 
builtin_interfaces/Time stamp # 记录时间戳int32 secuint32 nanosec
string host_name                # 系统名称
float32 cpu_percent     # CPU使用率
float32 memory_percent  # 内存使用率
float32 memory_total    # 内存总量
float32 memory_available        # 剩余有效内存
float64 net_sent                # 网络发送数据总量
float64 net_recv                # 网络接收数据总量

 还可以去install/status_interfaces/include下面,是否生成了C++文件及python库。

现在已经完成了自定义消息接口。

3.4.3 系统信息获取与发布

创建功能包status_publisher。

ros2 pkg create status_publisher --build-type ament_python --dependencies rclpy status_interfaces --license Apache-2.0

在功能包下创建文件sys_status_pub.py.代码如下:

import rclpy
from status_interfaces.msg import SystemStatus
from rclpy.node import Node
import psutil
import platformclass SysStatusPub(Node):def __init__(self, node_name):super().__init__(node_name)self.status_publisher_ = self.create_publisher(SystemStatus,'sys_status',10)self.timer_ = self.create_timer(1.0,self.timer_callback)def timer_callback(self):cpu_percent = psutil.cpu_percent()memory_info = psutil.virtual_memory()net_io_counters = psutil.net_io_counters()msg = SystemStatus()msg.stamp = self.get_clock().now().to_msg()msg.host_name = platform.node()msg.cpu_percent = cpu_percentmsg.memory_percent = memory_info.percentmsg.memory_total = memory_info.total/1024/1024msg.memory_available = memory_info.available/1024/1024msg.net_sent = net_io_counters.bytes_sent/1024/1024msg.net_recv = net_io_counters.bytes_recv/1024/1024self.get_logger().info(f'发布:{str(msg)}')self.status_publisher_.publish(msg)def main():rclpy.init()node = SysStatusPub('sys_status_pub')rclpy.spin(node)rclpy.shutdown

定义了SysStatusPub类,继承了Node.初始化创建发布者status_publisher_跟定时器timer_。定时器每秒调用一次回调timer_callback来发布数据,timer_callback内部使用了psutil获取系统信息。还有单位转换为MB.

接下来去setup.py中去注册节点sys_status_pub。编译运行。

ros2 run status_publisher sys_status_pub

bohu@bohu-TM1701:~/3/topic_practice_ws$ ros2 run status_publisher sys_status_pub 
[INFO] [1736234385.803543118] [sys_status_pub]: 发布:status_interfaces.msg.SystemStatus(stamp=builtin_interfaces.msg.Time(sec=1736234385, nanosec=761086615), host_name='bohu-TM1701', cpu_percent=7.1, memory_percent=77.4, memory_total=7824.6953125, memory_available=1771.0078125, net_sent=484.4188470840454, net_recv=5299.850911140442)
[INFO] [1736234386.762844262] [sys_status_pub]: 发布:status_interfaces.msg.SystemStatus(stamp=builtin_interfaces.msg.Time(sec=1736234386, nanosec=760874264), host_name='bohu-TM1701', cpu_percent=10.2, memory_percent=77.3, memory_total=7824.6953125, memory_available=1774.328125, net_sent=484.4210395812988, net_recv=5299.852033615112)
[INFO] [1736234387.763212697] [sys_status_pub]: 发布:status_interfaces.msg.SystemStatus(stamp=builtin_interfaces.msg.Time(sec=1736234387, nanosec=760907123), host_name='bohu-TM1701', cpu_percent=9.0, memory_percent=77.2, memory_total=7824.6953125, memory_available=1781.57421875, net_sent=484.4244565963745, net_recv=5299.8582944869995)

可以看到能够获取系统状态并发布了。

3.4.4 在功能包中使用QT

这个就是为了熟悉下QT的使用。

先在 src下创建功能包status_display

ros2 pkg create status_display --build-type ament_cmake  --dependencies  rclcpp status_interfaces --license Apache-2.0

测试类hello_qt.cpp,效果如下

消除引用警告,修改c_cpp_properties.json

{"configurations": [{"name": "Linux","includePath": ["${workspaceFolder}/**","/opt/ros/humble/include/**","/usr/include/x86_64-linux-gnu/qt5/**"],"defines": [],"compilerPath": "/usr/bin/gcc","cStandard": "c17","cppStandard": "gnu++17","intelliSenseMode": "linux-gcc-x64"}],"version": 4
}

 3.4.5 订阅数据并用QT显示

在src/status_display/src下新建sys_status_display.cpp.代码如下

#include <QApplication>
#include <QLabel>
#include <QString>
#include <rclcpp/rclcpp.hpp>
#include <status_interfaces/msg/system_status.hpp>using SystemStatus = status_interfaces::msg::SystemStatus;
using namespace std;class SysStatusDisplay :public rclcpp::Node
{
private:/* data */rclcpp::Subscription<SystemStatus>::SharedPtr subscriber_;QLabel* label_;
public:SysStatusDisplay(/* args */):Node("sys_status_display"){label_ = new QLabel();subscriber_ = this->create_subscription<SystemStatus>("sys_status",10,[&](const SystemStatus::SharedPtr msg)->void{label_->setText(get_qstr_from_msg(msg));});label_->setText(get_qstr_from_msg(std::make_shared<SystemStatus>()));label_->show();};QString get_qstr_from_msg(const SystemStatus::SharedPtr msg){stringstream show_str;show_str << "================可视化状态显示===============\n"<< "数 据 时 间:\t" << msg->stamp.sec << "\ts\n"<< "用  户  名:\t" << msg->host_name << "\t\n"<< "CPU使用率:\t" << msg->cpu_percent << "\t%\n"<< "内存使用率:\t" << msg->memory_percent << "\t%\n"<< "内存总大小:\t" << msg->memory_total << "\tMB\n"<< "剩余有效内存:\t" << msg->memory_available << "\tMB\n"<< "网络发送量:\t" << msg->net_sent << "\tMB\n"<< "网络接收量:\t" << msg->net_recv << "\tMB\n"<< "==========================================";return QString::fromStdString(show_str.str());}};int main(int argc,char * argv[]){rclcpp::init(argc,argv);QApplication app(argc,argv);auto node = std::make_shared<SysStatusDisplay>();std::thread spin_thread([&]()->void{rclcpp::spin(node);});spin_thread.detach();app.exec();//执行,阻塞代码rclcpp::shutdown();return 0;
}

SysStatusDisplay 类继承来Node节点,定义了两个属性:label_ 用于显示,subscriber_ 订阅话题。

接着对它们进行初始化,subscriber_ 使用了lambda表达式作为回调函数。处理显示字符串放在方法get_qstr_from_msg()。

主函数设计比较巧妙,因为之前默认的rclcpp::spin(node);会阻塞执行。app.exec();也会阻塞程序运行。无论调整顺序不满足需求导致无法正常显示,所以小鱼老师讲spin单独放到一个线程中进行处理。界面退出后app.exec()退出,接着调用rclcpp::shutdown();程序正常退出。

修改CMakeLists.txt,添加节点及依赖。

cmake_minimum_required(VERSION 3.8)
project(status_display)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(status_interfaces REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Widgets)add_executable(hello_qt src/hello_qt.cpp)
target_link_libraries(hello_qt Qt5::Widgets)
add_executable(sys_status_display src/sys_status_display.cpp)
target_link_libraries(sys_status_display Qt5::Widgets)# 对于非ROS功能包使用Cmake原生指令进行链接库
ament_target_dependencies(sys_status_display rclcpp status_interfaces)if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)# the following line skips the linter which checks for copyrights# comment the line when a copyright and license is added to all source filesset(ament_cmake_copyright_FOUND TRUE)# the following line skips cpplint (only works in a git repo)# comment the line when this package is in a git repo and when# a copyright and license is added to all source filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()
endif()
install(TARGETS hello_qt sys_status_display
DESTINATION lib/${PROJECT_NAME})ament_package()

 构建并运行运行,依赖上一个sys_status_pub节点发布话题,

ros2 run status_publisher sys_status_pub

ros2 run status_display sys_status_display

效果如下:

本节一下子接触的知识点还是挺多的。

相关文章:

ros2-3.4话题通信最佳实践

3.4.1 工程架构设计 需求背景&#xff1a; 第一&#xff0c;通过这个小工具可以看到系统的实时状态信息包括记录信息的时间、主机名称、CPU使用率、内存使用率、内存总大小、剩余内存、网络接收数据量和网络发送数据量; 第二&#xff0c;要有一个简单的界面&#xff0c;可以将…...

Vmware安装centos

用来记录自己安装的过程 一、创建虚拟机安装centos镜像 点击完成后&#xff0c;等待一会会进入centos的系统初始化界面 二、centos初始化配置 三、配置网络 1、虚拟网络编辑器&#xff0c;开启VMnet1、VMnet8的DHCP vmware左上角工具栏&#xff0c;点击【编辑】->【虚拟网…...

51单片机——按键实验

由于机械点的弹性作用&#xff0c;按键开关在闭合时不会马上稳定的接通&#xff0c;在断开时也不会一下子断开&#xff0c;因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的&#xff0c;一般为 5ms 到 10ms&#xff0c;为了确保 CPU 对按键的…...

QT c++ 自定义按钮类 加载图片 美化按钮

如果你有需要利用图片美化按钮的情况&#xff0c;本文能帮助你。 鼠标左键按下按钮和松开&#xff0c;按钮显示不同的图片。 1.按钮类 //因为此类比较简单&#xff0c;1个头文件搞定&#xff0c;没有cpp文件 #ifndef CUSTOMBUTTON_H #define CUSTOMBUTTON_H #include <Q…...

Django:构建高效Web应用的强大框架

在当今快速发展的Web开发领域&#xff0c;选择一个合适的框架对于项目的成功至关重要。Django&#xff0c;作为Python编程语言中最受欢迎的Web框架之一&#xff0c;凭借其强大的功能、高度的可扩展性和简洁的语法&#xff0c;成为了众多开发者心中的首选。本文将深入探讨Django…...

代码随想录算法【Day11】

150. 逆波兰表达式求值 class Solution { public:int evalRPN(vector<string>& tokens) {// 力扣修改了后台测试数据&#xff0c;需要用longlongstack<long long> st; for (int i 0; i < tokens.size(); i) {if (tokens[i] "" || tokens[i] &…...

[SeaTunnel] [MySql CDC] Generate Splits for table db.table error

在使用 SeaTunnel 的 MySQL CDC 时报错&#xff1a; Caused by: org.apache.seatunnel.engine.common.exception.SeaTunnelEngineException: java.lang.RuntimeException: Generate Splits for table db.table error SeaTunnel 版本为 2.3.8 在 GitHub 上找到一种解决方法&am…...

Spring Boot | 基于MinIO实现文件上传和下载

关注&#xff1a;CodingTechWork 介绍 在现代的 web 应用中&#xff0c;文件上传和下载是常见的需求。MinIO 是一个开源的高性能分布式对象存储服务&#xff0c;可以用来存储和管理大量的非结构化数据&#xff0c;如图片、视频、日志文件等。本文将介绍如何在 Spring Boot 应用…...

企业手机号搜索API接口

每日免费每次消耗&#xff1a;按量每日限制&#xff1a;10 次每次请求积分消耗&#xff1a;50 积分 / 次总次数限制&#xff1a;10000 次每次请求间隔&#xff1a;0 秒&#xff0c;并发&#xff1a;50 请求地址 http(s)://api.aiqimao.com/index/apiphoneget/ 调试 请求方法…...

VirtualBox Main API 学习笔记

1. Philosophy 1.1 对于Python&#xff0c;推荐使用"WEBSERVICE"连接方式 Gemini 2.0 Flash Experimental: 对于 Java 和 Python&#xff1a; 文档建议您首先使用"WEBSERVICE"&#xff0c;因为它提供了一种更直观的方式来使用 API。 2. Configuration pi…...

[Linux]Mysql9.0.1服务端脱机安装配置教程(redhat)

前言 本教程适用于在yum源不可用的LInux主机上安装Mysql的场景。 以redhat系主机做操作示例&#xff0c;debian系主机可参照步骤&#xff0c;将对应的rpm -ivh命令换成dpkg -i。 1. 官网下载安装包 https://dev.mysql.com/downloads/mysql/ 1.1 版本分类 MySQL Enterprise…...

uniapp--HBuilder开发

提示&#xff1a;本文为学习内容&#xff0c;若有错误&#xff0c;请联系作者&#xff0c;谦虚受教。 文章目录 前言一、下载HBuilder二、添加modbus相关库1.下载nodejs2.下载modbus库3.项目添加modbus库 三、HBuilder相关功能语句1.文件夹说明2.消息信息框3.开关按钮4.选中按钮…...

计算机毕业设计学习项目-P10080 基于springboot+vue的社团管理系统的设计与实现

项目说明 本号所发布的项目均由我部署运行验证&#xff0c;可保证项目系统正常运行&#xff0c;以及提供完整源码。 如需要远程部署/定制/讲解系统&#xff0c;可以联系我。定制项目未经同意不会上传&#xff01; 项目源码获取方式放在文章末尾处 注&#xff1a;项目仅供学…...

with as提高sql的执行效率

实战sql with cte(UNIT_ID, UNIT_NAME, PARENT_UNIT_ID, UNIT_CODE ) as (select UNIT_ID, UNIT_NAME, PARENT_UNIT_ID , UNIT_CODEfrom HPFM_UNITunion allselect t.UNIT_ID, t.UNIT_NAME, t.PARENT_UNIT_ID, t.UNIT_CODEfrom HPFM_UNIT tjoin cte on t.PARENT_UNIT_ID cte.U…...

【银河麒麟高级服务器操作系统实例】tcp半链接数溢出分析及处理全过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…...

计算机毕业设计Python中华古诗词知识图谱可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析模型 自然语言处理NLP 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

分布式ID生成-雪花算法实现无状态

雪花算法这里不再赘述&#xff0c;其缺点是有状态&#xff08;多副本隔离时&#xff0c;依赖手动配置workId和datacenterId&#xff09;&#xff0c;代码如下&#xff1a; /*** 雪花算法ID生成器*/ public class SnowflakeIdWorker {/*** 开始时间截 (2017-01-01)*/private st…...

【问题】配置 Conda 与 Pip 源

通常情况下,使用 conda 命令或者 pip 命令都是从国外的服务器上下载需要的模块包的,这在网速不佳的情况下会消耗大量的时间。所以这里建议更换国内的源来进行模块下载,速度会大大提升。 具体方法如下: 打开命令行 cmd 工具,输入以下命令。 ① Conda 换源 conda config…...

Zookeeper是如何保证事务的顺序一致性的?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper是如何保证事务的顺序一致性的?】面试题。希望对大家有帮助&#xff1b; Zookeeper是如何保证事务的顺序一致性的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper 通过多个机制来保证事务的顺序一…...

东土科技参股广汽集团飞行汽车初创公司,为低空经济构建新型产业生态

近日&#xff0c;广汽集团旗下专注于飞行汽车领域的初创公司广东高域科技有限公司于2024年12月31日正式成立&#xff0c;在穿透后的股东信息中&#xff0c;东土科技通过广州瓴云科技投资合伙企业&#xff08;有限合伙&#xff09;赫然在列。 此前12月18日&#xff0c;广汽集团…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...