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

Robot Operating System——ParameterEventHandler监控Parameters的增删改行为

大纲

  • 创建订阅"/parameter_events"的Node
  • 监控自身Node内部Parameter
  • 监控自身Node外部Parameter
  • 监听所有Node的所有Parameter的变动
  • 执行效果
  • 总结

在《Robot Operating System——AsyncParametersClient监控Parameters的增删改行为》一文中,我们通过AsyncParametersClient和SyncParametersClient的on_parameter_event方法对Parameters的变动进行了监控。本文我们将介绍另一种监控工具类ParameterEventHandler的使用。

我们将通过demo_nodes_cpp/src/parameters/parameter_event_handler.cpp来讲解。

创建订阅"/parameter_events"的Node

这类对Parameters行为进行监控,其底层都是通过订阅"/parameter_events"主题的形式实现的(后面我们会对其进行分析)。所以我们第一步需要创建一个Node,并订阅该主题。

int main(int argc, char ** argv)
{setvbuf(stdout, NULL, _IONBF, BUFSIZ);rclcpp::init(argc, argv);const char * node_name = "this_node";const char * param_name = "an_int_param";// Create a node with an integer parameterauto node = rclcpp::Node::make_shared(node_name);node->declare_parameter(param_name, 0);// Now, create a parameter subscriber that can be used to monitor parameter changes on// our own local node as well as other remote nodesauto param_subscriber = std::make_shared<rclcpp::ParameterEventHandler>(node);

ParameterEventHandler的构造函数中,实现了主题的订阅功能。

///opt/ros/jazzy/include/rclcpp/rclcpp/parameter_event_handler.hpp/// Construct a parameter events monitor./*** \param[in] node The node to use to create any required subscribers.* \param[in] qos The QoS settings to use for any subscriptions.*/template<typename NodeT>explicit ParameterEventHandler(NodeT node,const rclcpp::QoS & qos =rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(rmw_qos_profile_parameter_events))): node_base_(rclcpp::node_interfaces::get_node_base_interface(node)){auto node_topics = rclcpp::node_interfaces::get_node_topics_interface(node);callbacks_ = std::make_shared<Callbacks>();event_subscription_ = rclcpp::create_subscription<rcl_interfaces::msg::ParameterEvent>(node_topics, "/parameter_events", qos,[callbacks = callbacks_](const rcl_interfaces::msg::ParameterEvent & event) {callbacks->event_callback(event);});}

监控自身Node内部Parameter

ParameterEventHandler在API层面可以方便的支持对某个Parameter修改行为的订阅。而在AsyncParametersClient和SyncParametersClient中,我们只能在监控回调中自己判断。

如下例,add_parameter_callback方法对名字是param_name(= “an_int_param”)的Parameter进行了监控。一旦这个参数发生变动,则cb1会被回调。

  // First, set a callback for the local integer parameter. In this case, we don't// provide a node name (the third, optional, parameter).auto cb1 = [&node](const rclcpp::Parameter & p) {RCLCPP_INFO(node->get_logger(),"cb1: Received an update to parameter \"%s\" of type %s: \"%" PRId64 "\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_int());};auto handle1 = param_subscriber->add_parameter_callback(param_name, cb1);

监控自身Node外部Parameter

我们先创建一个其他命名空间(/a_namespace)的Node。

  // Let's create another "remote" node in a separate namespace with its own string parameterauto remote_node_name = "a_remote_node";auto remote_node_namespace = "/a_namespace";auto remote_param_name = "a_string_param";auto remote_node = rclcpp::Node::make_shared(remote_node_name, remote_node_namespace);remote_node->declare_parameter(remote_param_name, "default_string_value");auto remote_thread = std::make_unique<NodeThread>(remote_node);

该Node运行于一个线程中

// A utility class to assist in spinning a separate node
class NodeThread
{
public:explicit NodeThread(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base): node_(node_base){thread_ = std::make_unique<std::thread>([&](){executor_.add_node(node_);executor_.spin();executor_.remove_node(node_);});}template<typename NodeT>explicit NodeThread(NodeT node): NodeThread(node->get_node_base_interface()){}~NodeThread(){executor_.cancel();thread_->join();}protected:rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_;std::unique_ptr<std::thread> thread_;rclcpp::executors::SingleThreadedExecutor executor_;
};

然后我们只需要告知add_parameter_callback第三个参数的值,即外部Node的名称(包含命名空间),就可以监听这个Node下名字叫remote_param_name(= “a_string_param”)的Parameter的变动。

  // Now, add a callback to monitor any changes to the remote node's parameter. In this// case, we supply the remote node name.auto cb2 = [&node](const rclcpp::Parameter & p) {RCLCPP_INFO(node->get_logger(), "cb2: Received an update to parameter \"%s\" of type: %s: \"%s\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_string().c_str());};auto fqn = remote_node_namespace + std::string("/") + remote_node_name;auto handle2 = param_subscriber->add_parameter_callback(remote_param_name, cb2, fqn);

监听所有Node的所有Parameter的变动

这次我们需要调用add_parameter_event_callback方法,并传入回调即可。因为这会收到全部Node的所有Parameter的变动,所以其信息也非常繁杂。这就需要我们自己在回调函数中做大量的手工处理。

  // We can also monitor all parameter changes and do our own filtering/searchingauto cb3 =[fqn, remote_param_name, &node](const rcl_interfaces::msg::ParameterEvent & event) {// Use a regular expression to scan for any updates to parameters in "/a_namespace"// as well as any parameter changes to our own nodestd::regex re("(/a_namespace/.*)|(/this_node)");if (regex_match(event.node, re)) {// You can use 'get_parameter_from_event' if you know the node name and parameter name// that you're looking forrclcpp::Parameter p;if (rclcpp::ParameterEventHandler::get_parameter_from_event(event, p,remote_param_name, fqn)){RCLCPP_INFO(node->get_logger(), "cb3: Received an update to parameter \"%s\" of type: %s: \"%s\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_string().c_str());}// You can also use 'get_parameter*s*_from_event' to enumerate all changes that came// in on this eventauto params = rclcpp::ParameterEventHandler::get_parameters_from_event(event);for (auto & p : params) {RCLCPP_INFO(node->get_logger(), "cb3: Received an update to parameter \"%s\" of type: %s: \"%s\"",p.get_name().c_str(),p.get_type_name().c_str(),p.value_to_string().c_str());}}};auto handle3 = param_subscriber->add_parameter_event_callback(cb3);

执行效果

在这里插入图片描述
在这里插入图片描述

总结

AsyncParametersClient和SyncParametersClient的on_parameter_event的功能和ParameterEventHandler::add_parameter_event_callback比较类似,会通知所有Parameter的变动;但是ParameterEventHandler::add_parameter_callback提供了更细粒度的控制,我们可以通过指定Parameter名称和Node名称让ParameterEventHandler帮我们自动过滤掉我们不关心的事件。

相关文章:

Robot Operating System——ParameterEventHandler监控Parameters的增删改行为

大纲 创建订阅"/parameter_events"的Node监控自身Node内部Parameter监控自身Node外部Parameter监听所有Node的所有Parameter的变动执行效果总结 在《Robot Operating System——AsyncParametersClient监控Parameters的增删改行为》一文中&#xff0c;我们通过AsyncPa…...

计算机网络(Wrong Question)

一、计算机网络体系结构 1.1 计算机网络概述 D 注&#xff1a;计算机的三大主要功能是数据通信、资源共享、分布式处理。&#xff08;负载均衡、提高可靠性&#xff09; 注&#xff1a;几段链路就是几段流水。 C 注&#xff1a;记住一个基本计算公式&#xff1a;若n个分组&a…...

Docker+consul容器服务的更新与发现

1、Consul概述 &#xff08;1&#xff09;什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点…...

全网最详细!! Linux 安装、配置教程

一、下载安装包 首先去官网下载VMware最新版本&#xff0c;以及发行版CentOS -7&#xff0c;懒得下载的可以私信我&#xff0c;我给你发包 其中&#xff0c;CentOS&#xff08;Community Enterprise Operating System&#xff09;是一个基于Linux的开源操作系统&#xff0c;它是…...

cocos creator 3学习记录01——如何替换图片

一、动态加载本地图片 1、通过将图片关联到CCClass属性上来进行代码切换。 1、这种方法&#xff0c;需要提前在脚本文件中声明好代表图片的CCClass属性。 2、然后拖动图片资源&#xff0c;到脚本内声明好的属性上以进行关联。 3、然后通过程序&#xff0c;来进行切换展示。…...

【Android Compose】ListView效果

【Android Compose】ListView效果 1、Column、Row 和 Box2、LazyColumn和LazyRow3、Compose 中的状态4、ListView效果5、android-compose-codelabs Jetpack Compose 使用入门 Jetpack Compose 教程 Jetpack Compose 1、Column、Row 和 Box Compose 中的三个基本标准布局元素是 …...

【Pytorch实战教程】Pytorch中.detach()的详细介绍

detach() 是 PyTorch 中用于分离张量的计算图的一个方法。它在处理计算图时非常有用,尤其是在需要停止梯度传播的情况下。以下是 detach() 方法的详细介绍: 方法概述 detach() 方法返回一个新的张量,从当前计算图中分离出来,即返回的张量不会参与梯度计算。这在某些情况下…...

AR 眼镜之-充电动画定制-实现方案

目录 &#x1f4c2; 前言 AR 眼镜系统版本 充电动画 1. &#x1f531; 技术方案 1.1 方案介绍 1.2 实现方案 关机充电动画 亮屏/锁屏充电动画 2. &#x1f4a0; 关机充电动画 2.1 关机充电动画核心处理类与路径 2.2 实现细节 步骤一&#xff1a;1&#xff09;定制 …...

AJAX-XMLHttpRequest 详解

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 前言 XMLHttpRequest 概述 主要用途 工作流程 示例代码 GET 请求示例 POST 请求示例 注意事项 工作…...

内容管理系统 Contentful 与 Baklib

对于希望管理其产品和服务的在线文档或知识库以支持其客户和员工的组织来说&#xff0c;市场上有太多的平台和工具。 遵循的做法之一是使用无头内容管理系统 (CMS)。 如果您是这样的组织之一&#xff0c;正在考虑使用无头 CMS - Contentful 之一来管理您的在线知识库&#xff0…...

[Mysql-视图和存储过程]

视图 视图是从一个或者几个基本表&#xff08;或视图&#xff09;导出的表。它与基 本表不同&#xff0c;是一个虚表。 创建使用视图 # 视图 -- 视图只能用来查询&#xff0c;不能做增删改 -- 创建视图 -- create view 视图名【view_xxx / v_xxx】 -- as 查询语句 create view…...

Linux下C++静态链接库的生成以及使用

目录 一.前言二.生成静态链接库三.使用静态链接库 一.前言 这篇文章简单讨论一下Linux下如何使用gcc/g生成和使用C静态链接库&#xff08;.a文件&#xff09;。 二.生成静态链接库 先看下目录结构 然后看下代码 //demo.h#ifndef DEMO_H #define DEMO_H#include<string&g…...

【8月EI会议推荐】第四届区块链技术与信息安全国际会议

一、会议信息 大会官网&#xff1a;http://www.bctis.nhttp://www.icbdsme.org/ 官方邮箱&#xff1a;icbctis126.com 组委会联系人&#xff1a;杨老师 19911536763 支持单位&#xff1a;中原工学院、西安工程大学、齐鲁工业大学&#xff08;山东省科学院&#xff09;、澳门…...

2024年【甘肃省安全员B证】考试资料及甘肃省安全员B证模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年甘肃省安全员B证考试资料为正在备考甘肃省安全员B证操作证的学员准备的理论考试专题&#xff0c;每个月更新的甘肃省安全员B证模拟试题祝您顺利通过甘肃省安全员B证考试。 1、【多选题】5kW以上电动机开关箱中电…...

结合el-upload上传组件,验证文件格式及大小

结合el-upload上传组件&#xff0c;验证文件格式及大小 效果如下&#xff1a; 代码如下&#xff1a; upgradeFirmwareInfo.vue页面 <template><div><el-dialog title"新增固件升级包" :visible.sync"dialogFormVisible"top"7vh&qu…...

配置php-fpm服务

nginx(unix domain socket方式) server {listen 80;#root /test/php/publiclocation / {#URL重写 例如隐藏index.phpif (!-f $request_filename) {rewrite ^(.*)$ /index.php?s/$1 last;break;}}location ~ [^/]\.php(/|$) {#try_files $uri 404;fastcgi_index index.php;…...

科普文:Linux系统安全加固指南

本指南仅关注安全性和隐私性&#xff0c;而不关注性能&#xff0c;可用性或其他内容。 列出的所有命令都将需要root特权。以“$”符号开头的单词表示一个变量&#xff0c;不同终端之间可能会有所不同。 选择正确的Linux发行版 选择一个好的Linux发行版有很多因素。 避免分发…...

MFC开发,自定义消息

在MFC开发中&#xff0c;主要核心机制就是消息机制。QT与之类似的机制就是信号与槽。QT中的信号与槽是非常容易自定义的&#xff0c;MFC也是如此&#xff0c;自定义也是比较方便&#xff0c;况且自定义消息或者控件在整个GUI图形化界面开发中也是非常重要的部分&#xff0c;上篇…...

如何在 SpringBoot 中优雅的做参数校验?

一、故事背景 关于参数合法性验证的重要性就不多说了&#xff0c;即使前端对参数做了基本验证&#xff0c;后端依然也需要进行验证&#xff0c;以防不合规的数据直接进入服务器&#xff0c;如果不对其进行拦截&#xff0c;严重的甚至会造成系统直接崩溃&#xff01; 本文结合…...

Godot入门 03世界构建1.0版

在game场景&#xff0c;删除StaticBody2D节点&#xff0c;添加TileMap节点 添加TileSet图块集 添加TileSet源 拖动图片到图块&#xff0c;自动创建图块 使用橡皮擦擦除。取消橡皮擦后按住Shift创建大型图块。 进入选择模式&#xff0c;TileMap选择绘制&#xff0c;选中图块后在…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...