【ROS2】高级:启用主题统计 (C++)

目标:启用 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

1d42575d8ca709c19ff39f2afdcec654.png

 先决条件

从二进制文件或源代码进行安装。

在之前的教程中,您学习了如何创建工作区、创建包以及创建 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

启用或禁用主题统计(默认 rclcpp::TopicStatisticsState::Disable )

topic_stats_options.publish_period

收集统计数据并发布统计消息的时间段(默认 1s )

topic_stats_options.publish_topic

发布统计数据时使用的主题(默认 /statistics )

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 来可视化这一点

f52c09703457171d0c2c8c2851c96534.png

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

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS2中,std::make_unique函数用于创建一个唯一指针。它是C++14中引入的一个函数模板,用于在堆上创建一个对象,并返回一个指向该对象的唯一指针。在ROS2中,可以使用std::make_unique函数来创建ROS2节点。例如,可以使用以下代码创建一个继承自rclcpp::Node的类的实例: ```cpp auto node = std::make_unique<MinimalPublisher>(); ``` 这将创建一个MinimalPublisher类的实例,并返回一个指向该实例的唯一指针。然后,可以使用该指针来访问该节点的成员函数和变量。 引用: \[1\] 截至目前,galactic虽然对以上过程进行了一定程度的封装,但封装也极为简化,同时read的流程仍没有封装,使用还是很麻烦。节点的建立ROS2使用了完全的面向对象设计,以C++为例,大量的ROS API都封装在了rclcpp::Node这个类中,也就意味着需要使用这些API,你必须定义一个继承自Node的类,这也就强制用户必须使用类的方式构建整个系统,官方的一个简单的例子如下:class MinimalPublisher : public rclcpp::Node { public: MinimalPublisher() : Node("minimal_publisher"), count_(0) { publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10); timer_ = this->create_wall_timer( 500ms, std::bind(&MinimalPublisher::timer_callback, this)); } private: rclcpp::TimerBase::SharedPtr timer_; rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_; size_t count_; } \[2\] 只要在同一ID的机器就可以接受到彼此的消息。yaml配置文件比较坑的一个细节,ROS2在yaml使用上有两个变化,如下:test_node: ros__parameters: common: topic: "your_topic" \[3\] 主要是下面三个部分:名称重定向日志配置参数使用命令行传参在eloquent之后需要加 --ros-args标志,dashing版本不需要eloquent:ros2 run my_package node_executable --ros-args ... #### 引用[.reference_title] - *1* *2* [ROS2实践总结](https://blog.csdn.net/liu3612162/article/details/121906612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [[ros2学习]-学习ROS 2工具集](https://blog.csdn.net/weixin_36628778/article/details/106375420)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值