目标:启用 ROS 2 主题统计topic statistics 并查看输出统计数据。
教程级别:高级
时间:10 分钟
目录
背景
先决条件
任务
1 编写启用统计信息的订阅者节点
1.1 检查代码
1.2 CMakeLists.txt
2 构建并运行
3 观察已发布的统计数据
摘要
相关内容
背景
这是一个简短的教程,介绍如何在 ROS 2 中启用主题统计,并使用命令行工具(ros2topic)查看发布的统计输出。
https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Topics/Understanding-ROS2-Topics.html
ROS 2 提供了对任何订阅接收到的消息进行统计测量的集成功能,称为主题统计 topic statistics 。启用主题统计后,您可以表征系统的性能或使用数据来帮助诊断任何存在的问题。
有关更多详细信息,请参阅主题统计概念页面。
https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-Topic-Statistics.html
先决条件
从二进制文件或源代码进行安装。
在之前的教程中,您学习了如何创建工作区、创建包以及创建 C++发布者和订阅者。
本教程假设您仍然拥有 C++ 教程中的 cpp_pubsub
包。
任务
1 编写启用统计信息的订阅者节点
导航到在上一个教程中创建的 ros2_ws/src/cpp_pubsub/src
文件夹,并通过输入以下命令下载示例对话代码:
cxy@ubuntu2404-cxy:~/ros2_ws/src/cpp_pubsub/src$ wget -O member_function_with_topic_statistics.cpp https://raw.githubusercontent.com/ros2/examples/jazzy/rclcpp/topics/minimal_subscriber/member_function_with_topic_statistics.cpp
现在将有一个名为 member_function_with_topic_statistics.cpp
的新文件。使用您喜欢的文本编辑器打开该文件。
#include <chrono> // 包含用于处理时间的库
#include <memory> // 包含用于动态内存管理的库
#include "rclcpp/rclcpp.hpp" // 包含ROS 2的C++客户端库
#include "rclcpp/subscription_options.hpp" // 包含订阅选项的库
#include "std_msgs/msg/string.hpp" // 包含标准字符串消息类型的库
class MinimalSubscriberWithTopicStatistics : public rclcpp::Node // 定义一个继承自rclcpp::Node的类MinimalSubscriberWithTopicStatistics
{
public:
MinimalSubscriberWithTopicStatistics() // 构造函数
: Node("minimal_subscriber_with_topic_statistics") // 调用基类构造函数并命名节点
{
// 手动通过选项启用主题统计
auto options = rclcpp::SubscriptionOptions(); // 创建订阅选项对象
options.topic_stats_options.state = rclcpp::TopicStatisticsState::Enable; // 启用主题统计
// 配置收集窗口和发布周期(默认1秒)
options.topic_stats_options.publish_period = std::chrono::seconds(10); // 设置发布周期为10秒
// 配置主题名称(默认'/statistics')
// options.topic_stats_options.publish_topic = "/topic_statistics" // 设置发布主题名称(此行被注释掉了)
auto callback = [this](const std_msgs::msg::String & msg) { // 定义回调函数
this->topic_callback(msg); // 调用成员函数处理接收到的消息
};
subscription_ = this->create_subscription<std_msgs::msg::String>( // 创建订阅对象
"topic", 10, callback, options); // 订阅名为"topic"的主题,队列大小为10,使用定义的回调函数和选项
}
private:
void topic_callback(const std_msgs::msg::String & msg) const // 定义回调函数
{
RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.data.c_str()); // 打印接收到的消息
}
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_; // 声明订阅对象
};
int main(int argc, char * argv[]) // 主函数
{
rclcpp::init(argc, argv); // 初始化ROS 2
rclcpp::spin(std::make_shared<MinimalSubscriberWithTopicStatistics>()); // 创建节点并进入循环
rclcpp::shutdown(); // 关闭ROS 2
return 0; // 返回0表示程序正常结束
}
1.1 检查代码
与 C++教程中一样,我们有一个订阅节点,它从 topic_callback
函数的 topic
主题接收字符串消息。然而,我们现在添加了选项来配置订阅,以便使用 rclcpp::SubscriptionOptions()
选项结构启用主题统计。
// manually enable topic statistics via options
auto options = rclcpp::SubscriptionOptions();
options.topic_stats_options.state = rclcpp::TopicStatisticsState::Enable;
可选地,还可以配置诸如统计数据收集/发布周期和用于发布统计数据的主题等字段。
// configure the collection window and publish period (default 1s)
options.topic_stats_options.publish_period = std::chrono::seconds(10);
// configure the topic name (default '/statistics')
// options.topic_stats_options.publish_topic = "/my_topic"
可配置字段在下表中描述:
订阅配置字段 | 目的 |
---|---|
topic_stats_options.state | 启用或禁用主题统计(默认 |
topic_stats_options.publish_period | 收集统计数据并发布统计消息的时间段(默认 |
topic_stats_options.publish_topic | 发布统计数据时使用的主题(默认 |
1.2 CMakeLists.txt
现在打开 CMakeLists.txt
文件。
添加可执行文件并将其命名为 listener_with_topic_statistics
,以便您可以使用 ros2 run
运行您的节点:
add_executable(listener_with_topic_statistics src/member_function_with_topic_statistics.cpp)
ament_target_dependencies(listener_with_topic_statistics rclcpp std_msgs)
install(TARGETS
talker
listener
listener_with_topic_statistics
DESTINATION lib/${PROJECT_NAME})
确保保存文件,然后启用主题统计信息的发布/订阅系统应该可以使用。
2. 构建并运行
要构建,请参阅发布/订阅教程中的构建和运行部分。
运行启用统计信息的节点的订阅者:
ros2 run cpp_pubsub listener_with_topic_statistics
现在运行 talker 节点:
ros2 run cpp_pubsub talker
终端应该每 0.5 秒发布一次信息消息,如下:
cxy@ubuntu2404-cxy:~/ros2_ws$ ros2 run cpp_pubsub talker
[INFO] [1721004747.160892628] [minimal_publisher]: Publishing: 'Hello, world! 0'
[INFO] [1721004747.660903609] [minimal_publisher]: Publishing: 'Hello, world! 1'
[INFO] [1721004748.160821637] [minimal_publisher]: Publishing: 'Hello, world! 2'
[INFO] [1721004748.660733687] [minimal_publisher]: Publishing: 'Hello, world! 3'
[INFO] [1721004749.160727870] [minimal_publisher]: Publishing: 'Hello, world! 4'
[INFO] [1721004749.660718014] [minimal_publisher]: Publishing: 'Hello, world! 5'
[INFO] [1721004750.160726266] [minimal_publisher]: Publishing: 'Hello, world! 6'
[INFO] [1721004750.660721875] [minimal_publisher]: Publishing: 'Hello, world! 7'
监听器将开始向控制台打印消息,从发布者当时的消息计数开始,如下:
cxy@ubuntu2404-cxy:~/ros2_ws$ colcon build --packages-select cpp_pubsub
Starting >>> cpp_pubsub
Finished <<< cpp_pubsub [23.8s]
Summary: 1 package finished [34.9s]
cxy@ubuntu2404-cxy:~/ros2_ws$ . install/setup.bash
cxy@ubuntu2404-cxy:~/ros2_ws$ ros2 run cpp_pubsub listener_with_topic_statistics
[INFO] [1721004747.161922839] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 0'
[INFO] [1721004747.661603507] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 1'
[INFO] [1721004748.161512967] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 2'
[INFO] [1721004748.661377462] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 3'
[INFO] [1721004749.161396950] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 4'
[INFO] [1721004749.661388234] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 5'
[INFO] [1721004750.161379764] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 6'
[INFO] [1721004750.661367882] [minimal_subscriber_with_topic_statistics]: I heard: 'Hello, world! 7'
现在订阅节点正在接收消息,它将定期发布统计消息。我们将在下一节中观察这些消息。
3 观察已发布的统计数据
在节点运行时,打开一个新的终端窗口。执行以下命令:
ros2 topic list
这将列出所有当前活动的主题。您应该看到以下内容:
cxy@ubuntu2404-cxy:~/ros2_ws$ ros2 topic list
/parameter_events
/rosout
/statistics
/topic
如果您在教程的早期可选地更改了 topic_stats_options.publish_topic
字段,那么您将看到该名称而不是 /statistics
。
您创建的订阅节点正在发布主题 topic
的统计数据,输出到主题 /statistics
。
我们可以使用 RQt https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-RQt.html 来可视化这一点
rqt_graph
现在我们可以使用以下命令查看发布到此主题的统计数据:
ros2 topic echo /statistics
终端应每 10 秒开始发布统计消息,因为在教程的早期阶段, topic_stats_options.publish_period
订阅配置是可选更改的。
cxy@ubuntu2404-cxy:~/ros2_ws$ ros2 topic echo /statistics
measurement_source_name: minimal_subscriber_with_topic_statistics
metrics_source: message_period
unit: ms
window_start:
sec: 1721005252
nanosec: 383289390
window_stop:
sec: 1721005262
nanosec: 383371401
statistics:
- data_type: 1
data: 499.99529599999994
- data_type: 3
data: 500.509363
- data_type: 2
data: 499.655469
- data_type: 5
data: 20.0
- data_type: 4
data: 0.1540366137858181
---
measurement_source_name: minimal_subscriber_with_topic_statistics
metrics_source: message_age
unit: ms
window_start:
sec: 1721005262
nanosec: 383371401
window_stop:
sec: 1721005272
nanosec: 383312331
statistics:
- data_type: 1
data: 0.48194245
- data_type: 3
data: 0.617711
- data_type: 2
data: 0.163832
- data_type: 5
data: 20.0
- data_type: 4
data: 0.09550604905265161
---
从消息定义中, data_types
如下所示
数据类型值 | statistics | 统计数据 |
---|---|---|
1 | average | 平均 |
2 | minimum | 最小值 |
3 | maximum | 最大 |
4 | standard deviation | 标准差 |
5 | sample count | 样本计数 |
在这里,我们看到由 minimal_publisher
发布到 /topic
的 std_msgs::msg::String
消息的两个当前可能的计算统计数据。如果 std_msgs::msg::String
没有消息头,因此无法执行 message_age
计算,将返回 NaN。然而,可以计算 message_period
,我们看到上面的消息中填充了统计数据。
摘要
您创建了一个启用主题统计信息的订阅节点,该节点发布了来自 C++发布节点的统计数据。您能够编译并运行此节点。在运行时,您能够观察到统计数据。
相关内容
要观察如何计算 message_age
周期,请参见 ROS 2 主题统计演示。https://github.com/ros2/demos/tree/jazzy/topic_statistics_demo