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

【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 中添加:

<license>Apache-2.0</license>
<member_of_group>rosidl_interface_packages</member_of_group>
<buildtool_depend>ament_cmake</buildtool_depend>
  • <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 platformclass 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()  # 关闭 rclpyif __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 <QApplication>
#include <QLabel>
#include <QString>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 <QApplication>
#include <QLabel>
#include <QString>
#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<SystemStatus>("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<SystemStatus>()));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<SystemStatus>::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<SysStatusDisplay>();// 多线程处理: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(TARGETS hello_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.dtcms.com/a/435164.html

相关文章:

  • 苏州门户网站平台推广员
  • ICT 数字测试原理 4 --电源监控电路(PMC)
  • 网站内页要不要加上关键词和描述广告型网站怎么做的
  • 深圳市建设局工程交易中心网站贵州 网站建设
  • 【C/C++】 函数形参—指针传递
  • 门限签名与多方安全计算(MPC)
  • 东莞公司高端网站建设高大上网站
  • 基于websocket的多用户网页五子棋(一)
  • PCA 主成分分析:数据世界的 “旅行清单整理师”—— 从 30 维杂乱到 2 维清晰的诗意降维
  • wordpress兼容mipseo加盟代理
  • 台州网站排名优化费用网站建设设计风格描述
  • 利用 ZoneABC 免费域名 零成本接入 Cloudflare 企业版 CDN
  • 企业网站建设费用属于什么科目dw软件网站建设教程
  • Streamlit:基础入门——零基础搭建第一个 Web 应用
  • Netty粘包和半包问题产生的原因和解决方案
  • 【小沐学GIS】基于C++绘制地形DEM(OpenGL、Terrain、TIFF、hgt)第十二期
  • 怎么搭建本地网站外贸营销工具
  • MySQL常用命令全攻略
  • 郑州市网站和公众号建设长沙公积金网站怎么做异动
  • 平面设计有什么网站wordpress 汽车模板下载
  • 珠宝首饰网站开发郑州微盟网站建设公司
  • 网站建设毕业设计指导老师意见什么网站可以做设计
  • 想学做网站要去哪里学健身网站开发过程中遇到的麻烦
  • 网站建设方案设计书参考西安最新消息今天
  • 代做道具网站备案网站可以做论坛么
  • SnapTube v7.46.1.74675101 | 免登下载油管4K视频,支持上百个网站的视频和音乐下载
  • 图像AUROC和像素AUROC
  • 网站加载速度影响因素为什么不能自己做网站
  • 网站正在建设中 htmlwordpress开发手册中文
  • 开发手机应用网站竞价托管推广代运营