机器人系统ros2-开发实践03-监听节点的参数变化(C++)

news/2024/5/17 20:55:40

背景:

通常,节点需要响应其自身参数或另一个节点参数的更改。 ParameterEventHandler 类可以轻松侦听参数更改,以便您的代码可以响应它们。本教程将向您展示如何使用 ParameterEventHandler 类的 C++ 版本来监视节点自身参数的更改以及另一个节点参数的更改。

应用场景

  • 动态配置:在机器人系统中,经常需要根据不同的环境或任务需求动态调整算法的参数。例如,调整机器人速度、感知算法的灵敏度等。通过监听参数的变化,系统可以即时响应并调整运行参数,而无需重启节点。
  • 实时调试和优化:开发者或操作者可以在系统运行时实时修改参数,以测试不同配置的效果,从而找到最优解。这对于算法的调试和优化尤为重要。
  • 适应性控制:在变化的环境条件下,如光照、温度或机器人负载变化时,能够自动调整控制策略的参数,使得机器人能更好地适应环境变化。
  • 用户交互:在需要用户输入或选择配置的应用中,监听参数变化可以使得系统更加响应用户的操作,提供更加灵活和个性化的服务。
  • 条件触发:可以设置参数监听来作为触发某些操作的条件,例如当监测到特定参数达到某个阈值时自动启动或停止某个过程。
  • 故障响应:通过实时监控关键参数,系统可以在参数异常时快速做出反应,执行如错误记录、发送警报或启动备用系统等应对措施。

1. 创建包

导航到ros2_study /src并在那里创建一个新包:

ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_parameter_event_handler --dependencies rclcpp

cpp_parameter_event_handler您的终端将返回一条消息,验证您的包及其所有必需文件和文件夹的创建。

--dependencies参数将自动将必要的依赖行添加到package.xml和CMakeLists.txt。

1.1 更新package.xml

由于您--dependencies在包创建期间使用了该选项,因此无需手动将依赖项添加到package.xml或CMakeLists.txt。

  1. 编写实现代码

在这里插入图片描述
在ros2_ws/study/cpp_parameter_event_handler/src目录中,创建一个名为的新文件parameter_event_handler.cpp,并将以下代码粘贴到其中:

#include <memory>#include "rclcpp/rclcpp.hpp"class SampleNodeWithParameters : public rclcpp::Node
{
public:SampleNodeWithParameters(): Node("node_with_parameters"){this->declare_parameter("an_int_param", 0);// Create a parameter subscriber that can be used to monitor parameter changes// (for this node's parameters as well as other nodes' parameters)param_subscriber_ = std::make_shared<rclcpp::ParameterEventHandler>(this);// Set a callback for this node's integer parameter, "age"auto cb = [this](const rclcpp::Parameter & p) {RCLCPP_INFO(this->get_logger(), "cb: Received an update to parameter \"%s\" of type %s: \"%ld\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_int());};cb_handle_ = param_subscriber_->add_parameter_callback("age", cb);}private:std::shared_ptr<rclcpp::ParameterEventHandler> param_subscriber_;std::shared_ptr<rclcpp::ParameterCallbackHandle> cb_handle_;
};int main(int argc, char ** argv)
{rclcpp::init(argc, argv);rclcpp::spin(std::make_shared<SampleNodeWithParameters>());rclcpp::shutdown();return 0;
}

2.1 上面关键代码说明

包引用:

代码引用 rclcpp 接口提供的各种功能,包括 ParameterEventHandler 类。#include <memory>#include "rclcpp/rclcpp.hpp"

在类声明之后,代码定义了一个类,SampleNodeWithParameters.该类的构造函数声明一个整数参数 age ,默认值为 0。接下来,代码创建一个ParameterEventHandler将用于监视参数更改的 。最后,代码创建一个 lambda 函数并将其设置为每当 age 更新时调用的回调。

注意数据类型定义 :在这里插入图片描述

保存返回的句柄非常重要add_parameter_callback;否则,回调将无法正确注册。

接下来SampleNodeWithParameters是一个典型的main函数,它初始化 ROS,示例节点以便它可以发送和接收消息,然后在用户在控制台输入 Ctrl +C 后关闭。

int main(int argc, char ** argv)
{rclcpp::init(argc, argv);rclcpp::spin(std::make_shared<SampleNodeWithParameters>());rclcpp::shutdown();return 0;
}

在调用rclcpp::spin时,实际上就调用了单线程节点执行器

2.2 添加可执行文件

要构建此代码,首先打开文件CMakeLists.txt并在依赖项下方添加以下代码行find_package(rclcpp REQUIRED)

add_executable(parameter_event_handler src/parameter_event_handler.cpp)
ament_target_dependencies(parameter_event_handler rclcpp)install(TARGETSparameter_event_handlerDESTINATION lib/${PROJECT_NAME}
)

在这里插入图片描述

3. 构建并运行

在构建之前,最好rosdep在工作区的根目录 ( ros2_study) 中运行以检查是否缺少依赖项:

rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y

构建新包

colcon build --packages-select cpp_parameter_event_handler

回顾--packages-select 指定这个包构建

构建成功如下图
在这里插入图片描述

运行:

打开一个新终端,导航到ros2_study并获取安装文件:

. install/setup.bash

运行节点:

ros2 run cpp_parameter_event_handler parameter_event_handler

该节点现在处于活动状态并且具有单个参数,并且每当该参数更新时都会打印一条消息。要测试这一点,请打开另一个终端并像以前一样获取 ROS 安装文件 (.install/setup.bash),然后执行以下命令:

ros2 param set node_with_parameters age  18

运行该节点的终端将显示类似以下内容的消息:

在这里插入图片描述
我们之前在节点中设置的回调已被调用并显示了新的更新值。您现在可以在终端中使用 Ctrl+ C 终止正在运行的parameter_event_handler 示例。

3.1 从另外一个节点监听

您还可以使用 ParameterEventHandler 来监视另一个节点参数的参数更改。让我们更新 SampleNodeWithParameters 类,以监视另一个节点中参数的更改。我们将使用parameter_blackboard演示应用程序来托管我们将监视其更新的双参数。

首先更新构造函数,在现有代码后面添加以下代码:

   auto cb2 = [this](const rclcpp::Parameter & p) {RCLCPP_INFO(this->get_logger(), "cb2: Received an update to parameter \"%s\" of type: %s: \"%.02lf\"",p.get_name().c_str(),p.get_type_name().c_str(),p.as_double());};auto remote_node_name = std::string("parameter_blackboard");auto remote_param_name = std::string("price");cb_handle2_ = param_subscriber_->add_parameter_callback(remote_param_name, cb2, remote_node_name);

重新编译:

colcon build --packages-select cpp_parameter_event_handler

在这里插入图片描述

然后获取安装文件:

. install/setup.bash

现在,要测试远程参数的监控,首先运行新建的parameter_event_handler代码:

ros2 run cpp_parameter_event_handler parameter_event_handler

接下来,从另一个终端(已初始化 ROS)运行parameter_blackboard 演示应用程序,如下所示:

ros2 run demo_nodes_cpp parameter_blackboard

执行此命令后,您应该在parameter_event_handler窗口中看到输出,表明在参数更新时调用了回调函数

最后,从第三个终端(已初始化 ROS),让我们在parameter_blackboard 节点上设置一个参数:

ros2 param set parameter_blackboard price  3.45

http://www.mrgr.cn/p/48241181

相关文章

MATLAB 和 Octave 之间的区别

MATLAB 和 Octave 之间的区别 MATLAB 和 Octave 有一些区别,但大多数都是相同的。你可以说 Octave 是 MATLAB 的免费版本,语法几乎与 MATLAB 相同。但是 MATLAB 比 Octave 具有更多功能,就像具有 Simulink 一样,后者用于开发和分析控制系统和电源系统。MATLAB 运行起来比 O…

JDK特性概览(5-21)

Java各版本特性 Java 5泛型 Generics 泛型本质是参数化类型,解决不确定具体对象类型的问题。List<String> strList=new ArrayList<String>();枚举 Enumeration 关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使…

linux 系统调用分析

一、linux系统调用介绍 linux系统调用是linux为用户空间与内核空间交换提供的一组标准API,这些api能够让用户态进程访问内核代码,从而实现系统资源、硬件、文件读写的访问。需要注意的是,系统调用是用户态进入内核态的唯一入口,为了保证linux内核运行的稳定性,用户程序不能…

一觉醒来 AI科技圈发生的大小事儿 04月29日

&#x1f4f3;特斯拉FSD国内封印解除&#xff0c;推送只差临门一脚&#xff01;马斯克宣布700亿投资加码AI 特斯拉解除封印&#xff0c;马斯克宣布700亿投资加码AI。马斯克访华并宣布特斯拉今年将投入100亿美元用于训练汽车AI&#xff0c;以实现自动驾驶。特斯拉通过数据安全检…

STM32之串口中断接收丢失数据

五六年没搞STM32了&#xff0c;这个项目一切都挺顺利&#xff0c;万万没想到被串口接收中断恶心到了。遇到的问题很奇怪 HAL_UART_Receive_IT(&huart1, &rx_buffer[rx_index], LCD_UART_LEN); 这个代码中 LCD_UART_LEN1的时候&#xff0c;接收过来的数据&#xff0c;数…

CogVLM/CogAgent环境搭建推理测试

​ 引子 对于多模态大语言模型,一直没有怎么接触。刚巧一朋友有问到这方面的问题,也就顺手调研下。智谱AI的东西一直以来,还是很不错的。ChatGLM的忠实fans,看到白嫖网站github上有他们开源的多模态CogVLM/CogAgent,那就顺手看看了。OK,让我们开始吧。 一、模型介绍 CogV…

使用input对电话号码实现隐藏显示

1、首先选择利用表格来呈现html结构<!-- html代码 --><table border="1px solid"><thead><tr><th>姓名</th><th>电话号码</th></tr></thead><tbody><tr><td align="center"&g…

科研新纪元已至:实验室场景可视化技术点亮科研之路

实验室场景可视化,通过先进的技术手段,将实验室内的设备、仪器、环境等以三维立体的形式呈现在人们眼前。这种技术的出现,彻底改变了传统实验室的呈现方式,让科研人员能够更加直观、全面地了解实验室的各个方面。在科技日新月异的今天,实验室作为科研创新的摇篮,正迎来一…

MATLAB中simulink中scope同时显示两个输入信号

在使用scope时,需要两个输入信号的设置方法 1.点开scope图标2 点击设置按钮, 然后弹出configuration properties:scope配置图,在Main选项下,在Number of input ports:1这里面更改数字,需要几个输入信号就更改几,此时这里更改为23 设置layout 选择自己喜欢的窗口显示排列…

C语言 | Leetcode C语言题解之第50题Pow(x,n)

题目&#xff1a; 题解&#xff1a; double myPow(double x, int n){if(n 0 || x 1){return 1;}if(n < 0){return 1/(x*myPow(x,-(n1)));}if(n % 2 0){return myPow(x*x,n/2);}else{return x*myPow(x*x,(n - 1)/2);} }

记录些RAG-Fusion、Agent、NL2SQL的问题

RAG-Fusion RAG-Fusion 的实现原理 Query Duplication with a Twist&#xff1a;用 LLM 根据用户的 Query 生成几个相关的但不同的 Queries。Vector Search Unleashed&#xff1a;对原 Query 和生成的 Queries 都进行向量&#xff08;或者其他方式的&#xff09;搜索。Intell…

微信读书助手迎来史诗级增强

大家好,我前夕.最近,我分享了个人开发的微信读书网页插件,这个小项目意外收获了众多用户的喜爱. 这让我意识到技术作品能跨越专业界限,帮助到有需要的人.受此激励,我决定对插件进行全面重构与优化背景 20天前, 发布了一篇文章讲述我自己写的浏览器插件, 帮助自己在阅读微信读书…

python脚本获取当前浏览器客户端的公共ip以及其详细信息

python脚本获取当前客户端的公共ip以及其详细信息 import requests from flask import Flask, request, make_response, send_from_directory from datetime import datetime import asyncio from hypercorn.asyncio import serve from hypercorn.config import Config import …

shell命令jq用法详解

摘自:https://blog.csdn.net/weixin_44799217/article/details/1314933981、jq介绍 jq是Linux系统中把文本字符串格式化成json格式的工具。jq命令用于将JSON数据转换为更易读的格式并将其打印到 Linux 上的标准输出。jq命令是围绕过滤器构建的,过滤器用于从JSON文件中…

Android 音视频播放器 Demo(一)—— 视频解码与渲染

本篇作为 Android 音视频实战系列的第二篇文章&#xff0c;主要介绍视频解码与渲染过程。本系列文章目录如下&#xff1a; Android 音视频基础知识 Android 音视频播放器 Demo&#xff08;一&#xff09;—— 视频解码与渲染 Android 音视频播放器 Demo&#xff08;二&#xff…

golang beego结合wire依赖注入及自动路由

1 安装wire 1.1 通过命令直接安装 go install github.com/google/wire/cmd/wirelatest 1.2 通过go get方式安装 go get github.com/google/wire/cmd/wire进入目录编译 cd C:\Users\leell\go\pkg\mod\github.com\google\wirev0.6.0\cmd\wire go build 然后将wire.exe移动到…

keytool,openssl的使用

写在前面 在生成公钥私钥&#xff0c;配置https时经常需要用到keytool&#xff0c;openssl工具&#xff0c;本文就一起看下其是如何使用的。 keytool是jdk自带的工具&#xff0c;不需要额外下载&#xff0c;但openssl需要额外下载 。 1&#xff1a;使用keytool生成jks私钥文件…

Linux Bridge和Tap关系详解

Bridge(桥)是Linux上用来做TCP/IP二层协议交换的设备,与现实世界中的交换机功能相似。Bridge设备实例可以和Linux上其他网络设备实例连接,既attach一个从设备,类似于在现实世界中的交换机和一个用户终端之间连接一根网线。当有数据到达时,Bridge会根据报文中的MAC信息进行…

SpringBoot的JSR303校验

关于JSR JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。 关于 JSR-303 JSR-303 是JAVA EE 6…

C++笔记:C++中的重载

重载的概念 一.函数重载 代码演示例子&#xff1a; #include<iostream> using namespace std;//函数名相同&#xff0c;在是每个函数的参数不相同 void output(int x) {printf("output int : %d\n", x);return ; }void output(long long x) {printf("outp…