【ROS2学习笔记】话题通信篇:话题通信项目实践——系统状态监测与可视化工具 - 实践

news/2025/10/4 15:42:38/文章来源:https://www.cnblogs.com/slgkaifa/p/19125651

【ROS2学习笔记】话题通信篇:话题通信项目实践——系统状态监测与可视化工具 - 实践

前言

本系列博文是本人的学习笔记,自用为主,不是教程,学习请移步其他大佬的相关教程。主要学习途径为@鱼香ROS大佬的教程,欢迎各位大佬交流学习,若有错误,轻喷。

一、项目背景与准备

需制作系统状态监测与可视化工具,结合 ROS2 话题通信、Python(获取并发布系统信息)、C++/Qt(订阅并界面显示)实现。首先创建工作空间:在 chapt3 目录下执行:

mkdir -p chapt3/topic_practice_ws/src
cd chapt3/topic_practice_ws
colcon build  # 初始化工作空间

二、步骤 1:自定义通信接口(消息类型)

ROS2 内置接口无法满足 “系统状态(CPU、内存、网络等)传输” 需求,需自定义消息接口。

1. 创建接口功能包

在 topic_practice_ws/src 目录下执行:

ros2 pkg create status_interfaces --build-type ament_cmake --dependencies rosidl_default_generators builtin_interfaces --license Apache-2.0
  • --build-type ament_cmake:指定构建类型(适合 C++ 及接口生成)。
  • --dependencies:依赖 rosidl_default_generators(将自定义消息转为 C++/Python 代码)、builtin_interfaces(内置接口,如时间类型)。

2. 编写消息定义文件

在 status_interfaces 功能包下创建 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               # 网络接收数据总量
  • 语法:类似 C++ 变量定义(类型 名称 # 注释)。
  • 基础类型:ROS2 还支持 boolbytecharint8/uint8 等 9 种基础类型。

3. 注册消息文件(修改 CMakeLists.txt

在 status_interfaces/CMakeLists.txt 中添加:

# 查找依赖
find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(builtin_interfaces REQUIRED)
# 声明消息接口文件,并指定依赖
rosidl_generate_interfaces(${PROJECT_NAME}"msg/SystemStatus.msg"DEPENDENCIES builtin_interfaces
)
ament_package()

4. 声明接口包(修改 package.xml

在 status_interfaces/package.xml 中添加:

Apache-2.0
rosidl_interface_packages
ament_cmake
  • <member_of_group>:声明为 “消息接口功能包”,让 ROS2 特殊处理。

5. 构建与验证接口

  • 构建:在工作空间根目录执行 colcon build --packages-select status_interfaces
  • 生效环境:source install/setup.bash
  • 验证:执行 ros2 interface show status_interfaces/msg/SystemStatus,若输出消息结构(时间戳、各字段),则接口创建成功。

三、步骤 2:系统信息获取与发布(Python 节点)

创建 Python 节点,通过 psutil 获取系统 CPU、内存、网络信息,再通过话题发布。

1. 创建发布者功能包

在 topic_practice_ws/src 目录下执行:

ros2 pkg create status_publisher --build-type ament_python --dependencies rclpy status_interfaces --license Apache-2.0
  • --build-type ament_python:指定为 Python 类型功能包。
  • --dependencies:依赖 rclpy(Python 的 ROS2 客户端库)、status_interfaces(自定义接口)。

2. 编写发布节点代码

在 status_publisher/status_publisher/ 下新建 sys_status_pub.py,代码如下:

import rclpy
from rclpy.node import Node
from status_interfaces.msg import SystemStatus  # 导入自定义消息
import psutil  # 系统信息获取库
import platform
class SysStatusPub(Node):def __init__(self, node_name):super().__init__(node_name)# 创建发布者:话题名 sys_status,队列大小 10self.status_publisher_ = self.create_publisher(SystemStatus, 'sys_status', 10)# 创建定时器:1 秒调用一次 timer_callbackself.timer = self.create_timer(1, self.timer_callback)def timer_callback(self):# 获取系统信息cpu_percent = psutil.cpu_percent()memory_info = psutil.virtual_memory()net_io_counters = psutil.net_io_counters()# 构造 SystemStatus 消息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 / 1024  # 字节转 MBmsg.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()  # 初始化 rclpynode = SysStatusPub('sys_status_pub')rclpy.spin(node)  # 循环运行节点(等待回调)rclpy.shutdown()  # 关闭 rclpy
if __name__ == '__main__':main()

在 ROS2 的 ament_python 类型包 中,setup.py 的 entry_points 是核心配置:它负责告诉 ROS2:

  1. 节点命令名(比如 sys_status_pub,用于 ros2 run 调用);
  2. 对应的 Python 文件(比如 status_publisher/sys_status_pub.py);
  3. 文件中的入口函数(比如 main 函数)。

默认用 ros2 pkg create 生成的 setup.py 中,entry_points 是空的(如下),必须手动补充:

# 默认生成的空entry_points(无法识别节点)
entry_points={'console_scripts': [],
},

3. 运行发布节点

  • 构建:在工作空间根目录执行 colcon build --packages-select status_publisher
  • 生效环境:source install/setup.bash
  • 运行:ros2 run status_publisher sys_status_pub
  • 验证:新开终端,执行 ros2 topic echo /sys_status,若看到系统信息持续输出,说明发布成功。

四、步骤 3:Qt 界面显示(C++ 节点)

用 Qt 创建界面,订阅 /sys_status 话题并显示系统状态。

1. 创建显示功能包

在 topic_practice_ws/src 目录下执行:

ros2 pkg create status_display --build-type ament_cmake --dependencies rclcpp status_interfaces --license Apache-2.0
  • 依赖 rclcpp(C++ 的 ROS2 客户端库)、status_interfaces(自定义接口)。

2. 简单 Qt 界面测试(hello_qt

在 status_display/src 下新建 hello_qt.cpp,代码如下:

#include 
#include 
#include 
int main(int argc, char* argv[]) {QApplication app(argc, argv);  // Qt 应用对象QLabel* label = new QLabel();  // 文本标签组件QString message = QString::fromStdString("Hello Qt!");  // 字符串转换label->setText(message);  // 设置显示文本label->show();  // 显示组件return app.exec();  // Qt 事件循环(阻塞,处理界面事件)
}

3. 配置 CMakeLists.txthello_qt

在 status_display/CMakeLists.txt 中添加:

cmake_minimum_required(VERSION 3.8)
project(status_display)
find_package(status_interfaces REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Widgets)  # 查找 Qt 的 Widgets 组件
# 生成可执行文件 hello_qt
add_executable(hello_qt src/hello_qt.cpp)
# 链接 Qt 的 Widgets 库
target_link_libraries(hello_qt Qt5::Widgets)
install(TARGETS hello_qtDESTINATION lib/${PROJECT_NAME})
ament_package()

4. 运行 hello_qt

  • 构建:colcon build --packages-select status_display
  • 生效环境:source install/setup.bash
  • 运行:ros2 run status_display hello_qt,会看到显示 “Hello Qt!” 的小窗口。

5. 订阅话题并显示系统状态

在 status_display/src 下新建 sys_status_display.cpp,代码分两部分:

(1)类定义与消息转换
#include 
#include 
#include 
#include "rclcpp/rclcpp.hpp"
#include "status_interfaces/msg/system_status.hpp"  // 自定义消息头文件
// 为自定义消息起别名,简化代码
using SystemStatus = status_interfaces::msg::SystemStatus;
class SysStatusDisplay : public rclcpp::Node {
public:SysStatusDisplay() : Node("sys_status_display") {// 创建订阅者:话题 sys_status,队列 10,Lambda 回调更新界面subscription_ = this->create_subscription("sys_status", 10,[this](const SystemStatus::SharedPtr msg) {label_->setText(get_qstr_from_msg(msg));});// 初始化标签(先显示空消息结构)label_ = new QLabel(get_qstr_from_msg(std::make_shared()));label_->show();}// 从 SystemStatus 消息转成 QString(格式化显示)QString get_qstr_from_msg(const SystemStatus::SharedPtr msg) {std::stringstream show_str;show_str << "=============系统状态可视化工具=============\n"<< "数据时间:\t" << msg->stamp.sec << "\t\n"<< "主机名:\t" << msg->host_name << "\t\n"<< "CPU 使用率:\t" << msg->cpu_percent << "%\t\n"<< "内存使用率:\t" << msg->memory_percent << "%\t\n"<< "内存总大小:\t" << msg->memory_total << " MB\t\n"<< "剩余有效内存:\t" << msg->memory_available << " MB\t\n"<< "网络发送量:\t" << msg->net_sent << " MB\t\n"<< "网络接收量:\t" << msg->net_recv << " MB\t\n"<< "============================================";return QString::fromStdString(show_str.str());}
private:rclcpp::Subscription::SharedPtr subscription_;  // 订阅者对象QLabel* label_;  // 标签组件
};
(2)主函数(处理 ROS2 与 Qt 事件循环)
int main(int argc, char* argv[]) {rclcpp::init(argc, argv);  // ROS2 初始化QApplication app(argc, argv);  // Qt 应用初始化// 创建显示节点auto node = std::make_shared();// 多线程处理:ROS2 的 spin 放单独线程,避免阻塞 Qt 事件循环std::thread spin_thread([node]() { rclcpp::spin(node); });spin_thread.detach();  // 后台运行线程int result = app.exec();  // Qt 事件循环(处理界面更新)rclcpp::shutdown();  // 关闭 ROS2return result;
}

6. 配置 CMakeLists.txtsys_status_display

在 status_display/CMakeLists.txt 中添加:

# 生成 sys_status_display 可执行文件
add_executable(sys_status_display src/sys_status_display.cpp)
# 链接 Qt Widgets 库
target_link_libraries(sys_status_display Qt5::Widgets)
# 为 ROS2 节点添加依赖
ament_target_dependencies(sys_status_display rclcpp status_interfaces)
# 安装可执行文件
install(TARGETShello_qtsys_status_displayDESTINATION lib/${PROJECT_NAME})

7. 运行显示节点

  • 构建:colcon build --packages-select status_display
  • 生效环境:source install/setup.bash
  • 启动流程:
    1. 先启动发布节点ros2 run status_publisher sys_status_pub
    2. 再启动显示节点ros2 run status_display sys_status_display,界面会实时显示系统状态数据。

五、整体流程回顾

  1. 自定义接口:创建 status_interfaces 包,定义 SystemStatus 消息,生成跨语言接口代码。
  2. 发布系统信息:创建 status_publisher 包(Python),用 psutil 采集信息,通过 /sys_status 话题发布。
  3. 订阅并显示:创建 status_display 包(C++/Qt),订阅 /sys_status 话题,用 Qt 界面实时展示系统状态。

每个环节核心是功能包创建、代码编写、CMake/package 配置、构建与运行,多实践即可熟悉 ROS2 开发流程

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

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

相关文章

建设个人网站需要什么条件php 视频播放网站开发

精排 正样本&#xff1a;曝光点击负样本&#xff1a;曝光未点击 粗排 正样本&#xff1a;曝光点击负样本&#xff1a;如果只复用精排的负样本&#xff0c;粗排模型对精排模型的拟合就会出现比较大的偏差。因为粗排打分高的item可能会被精排打低分&#xff0c;导致不能下发曝…

详细介绍:CS50ai: week2 Uncertainty我的笔记B版——当 AI 开始“承认不确定”

详细介绍:CS50ai: week2 Uncertainty我的笔记B版——当 AI 开始“承认不确定”2025-10-04 15:38 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflo…

2025多校冲刺CSP模拟赛2(普通的颓唐)

写在前面:普通的废话 普通的一天,笑早了的不普通考好前天,今天普通地爆炸了,炸得很普通彻底,令人万万没想到的是普通的肝硬化写错了普通的 \(freopen\) :把普通的 \(stdout\) 拼成了不知道什么的诡异东西。于是肝…

网站制作公司优势企业网站适合做成响应式吗

文章目录一、常用命令&#xff08;Linux&#xff09;二、搭建Vsftpd流程2.1. 检测系统2.2. yum安装一、常用命令&#xff08;Linux&#xff09; 作用命令启动sudo service vsftpd start关闭sudo service vsftpd stop重启sudo service vsftpd restart查看运行状态sudo service …

模板大全

【永远置顶】万能程序模板 #include<bits/stdc++.h> using namespace std; //#define Inc #ifdef Inc #include<bits/extc++.h> #include<windows.h> #endif #define Define #ifdef Define #define …

杭州微信网站制作凤凰手机网官网

目录 一.fopen 函数简介二.fopen 函数实战三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.fopen 函数简介 C 语言 fopen 函数表示以指定的模式&#xff0c;打开一个文件&#xff0c;函数声明如下&#xff1a; /* *描述&#xff1a;使用指定…

网站登录不上怎么回事音乐网站开发与需求

BlueFox Free PDF to HTML Converter是一款pdf文件转换软件&#xff0c;能直接查看PDF文件和对PDF文件进行编辑&#xff0c;支持批量进行转换&#xff0c;使用非常方便&#xff0c;操作简单&#xff0c;有需要可以下载。软件特色通过将PDF转换为HTML网页&#xff0c;您的网站访…

如何在工商局网站做企业年报wordpress文章和页面的区别

一、权限的分类 Linux权限分为r(读取)、w(写入)、x(执行)。我们在终端执行ls -l命令查看文件详细信息显示如下: [root@srv sun]# ls -l 总用量 0 drwxr-xr-x. 2 sun root 6 7月 5 14:05 公共 drwxr-xr-x. 2 sun root 6 7月 5 14:05 模板 drwxr-xr-x. 2 sun root…

springCloudMaven打包配置 - br

springCloud配置maven打包时使用profile激活当前运行环境并且打包时使用案例 <project><!-- ... 其他配置 ... --><!-- 第1步:定义环境Profile --><profiles><!-- 开发环境 (默认激活) --…

springCloud打包时根目录配置和公共包打包配置 - br

当有公共模块打包时并不需要打包成springbootJar时需要跳过打包 <build><plugins><!-- 公共模块需要声明使用该插件,但将其跳过 --><plugin><groupId>org.springframework.boot</gr…

我的网站百度搜不到营销 推广 网站

作者持续关注WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;WPS二次开发QQ群:250325397&#xff09;&#xff0c;摸鱼吹牛嗨起来&#xff01…

如何查网站备案号网站前端设计公司

目录 一、介绍二、强缓存三、协商缓存今天主要介绍 HTTP请求缓存中的强缓存和协商缓存。 一、介绍 浏览器每次发起请求时,会先在浏览器缓存中查找请求的缓存结果和缓存标识。 当浏览器第一次向服务器发起请求后,浏览器缓存肯定是没有对应缓存的,所以向服务器发起请求,服…

学习网站建设有前景没浙江住房和建设网站首页

yaml语法学习 1、配置文件 SpringBoot使用一个全局的配置文件 &#xff0c; 配置文件名称是固定的 application.properties 语法结构 &#xff1a;keyvalue application.yml 语法结构 &#xff1a;key&#xff1a;空格 value 配置文件的作用&#xff1a;修改SpringBoot自动…

题解:P5504 [JSOI2011] 柠檬

题目: 下面给个经典的 DP 式子不多说了: \[f_i=f_j+s_iqz^2(s_i,i)+s_iqz^2(s_{j+1},j)-2s_iqz(s_i,i)qz(s_{j+1},j),s_{j+1}=s_i \]单调栈太阴了!下面有个 hack: 11 2 10 2 2 10 2 2 10 2 2 2 ans:128众所周知 \…

Thymeleaf教程

一 Thymeleaf是什么 Thymeleaf 是一款现代服务器端 Java 模板引擎,专为 Web 开发设计,尤其适合与 Spring Boot 框架搭配使用。它的核心目标是实现 “自然模板”(Natural Templates)—— 即模板文件本身可直接作为纯…

商务网站建设的流程图专注新乡网站建设

1. 聚量推客&#xff1a; “聚量推客”汇聚了众多市场上有的和没有的地推网推拉新接单项目&#xff0c;目前比较火热&#xff0c;我们做地推和网推从业者如果长期在这行业去做推广可以使用这个平台&#xff0c;价格高数据也好&#xff0c;大部分拉新项目也都是官签一手资源 一…

VMware虚拟机设置中处理器数量和内核内存再次探讨

VMware虚拟机设置中处理器数量和内核内存再次探讨, 如何设置性能较好.设置内核数量 1*8 根据VMWARE虚拟机的CPU分配(VMWARE14):处理器数量、核心数量分配验证 - imxiangzi - 博客园 VMware Workstation CPU如何设置…

VMware中Ubuntu迁移(复制)后进入紧急模式You are in emergency mode.

解决了VMware虚拟机迁移后报错You are in emergency mode.在复制或迁移虚拟机后, Ubuntu进入紧急模式, 可以看见Error -107 cannot open Connection 这是共享文件夹功能被禁用导致的! 开启后输入reboot -f重启即可. 解…

2025年全国大学生电子设计竞赛A题:能量回馈的变流器负载试验装置(国一方案分享+代码工程+仿真) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …