ROS:参数服务器通信

2023-05-16

为什么需要

在机器人开发中,会有很多参数和设置可以后期需要调整的,如果都放到源码里很难实现动态修改和管理,ROS2为了解决这一问题,提出了参数这一通信机制。

是什么

如何理解“参数”?

  • ROS2的参数就是节点的设置
  • 参数类似于ROS中的全局变量,由ROS Master进行管理,其通信机制较为简单,不涉及TCP/UDP的通信。

参数服务器是一种特殊的“通信方式”。特殊点在于参数服务器是节点存储参数的地方、用于配置参数、全局共享参数。

  • 参数服务器使用互联网传输,在节点管理器中运行,实现整个通信过程
  • 参数服务器,作为ROS中另外一种数据传输方式,有别于topic和service,它更加静态。
  • 参数服务器维护者一个数据字典,字典里存储着各种参数和配置
    • 参数服务器在ROS中主要用于实现不同节点之间的数据共享。一般用于存储一些多节点共享的数据,类似于全局变量。
    • 参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据。

维护方式

参数服务器的维护方式非常的简单灵活,总的来讲有三种方式:

  • 命令行维护
  • launch文件内读写
  • node源码

命令行维护

使用命令行来维护参数服务器,主要使用rosparam语句来进行操作的各种命令,如下表:

ROS1:rosparam 命令作用
rosparam set param_key param_value设置参数
rosparam get param_key显示参数
rosparam load file_name从文件加载参数
rosparam dump file_name保存参数到文件
rosparam delete删除参数
rosparam list列出参数名称

load&&dump文件

load和dump文件需要遵守YAML格式,一般格式如下:

key : value

具体示例如下:

name:'Zhangsan'
age:20
gender:'M'
score{Chinese:80,Math:90}
score_history:[85,82,88,90]

一般格式如下:

launch文件内读写

launch文件中有很多标签,而与参数服务器相关的标签只有两个,一个是< param>,另一个是< rosparam>

node源码

除了上述最常用的两种读写参数服务器的方法,还有一种就是修改ROS的源码,也就是利用API来对参数服务器进行操作。具体内容我们学习完后面章节再进行介绍。

ROS2:体验一下

(1)运行小乌龟模拟器节点和小乌龟控制节点

# 终端一
ros2 run turtlesim turtlesim_node

# 终端二
ros2 run turtlesim turtle_teleop_key

(2)查看参数

  • 查看节点有哪些参数(设置)
ros2 param list

在这里插入图片描述

  • 看参数的详情信息:参数的名字,参数的描述,参数的类型,还有对参数的约束,最大值最小值等。
# ---- 语法--------
ros2 param describe <node_name> <param_name>

# ------ 举例 ---
ros2 param describe /turtlesim background_b

在这里插入图片描述

  • 获取参数名
param list
  • 获取参数值
ros2 param get /turtlesim background_b

在这里插入图片描述

  • 设置参数值:注意这里只是临时修改
# ------------语法
ros2 param set <node_name> <parameter_name> <value>

# ---------- 举个例子
ros2 param set /turtlesim background_r 44
ros2 param set /turtlesim background_g 156
ros2 param set /turtlesim background_b 10

  • 把参数存起来:相当去把当前的参数值拍一张快照,然后保存下来,后面可以用于恢复参数到当前的数值。
# ------------语法
ros2 param dump <node_name>


# ---------- 举个例子
ros2 param dump /turtlesim
# 文件被保存成了yaml格式,用cat指令看一看
文件被保存成了yaml格式,用cat指令看一看

# 恢复参数:
	# 方法一:
		# 我们Ctrl+C关闭乌龟模拟器,然后再重新运行。
		ros2 run turtlesim turtlesim_node
		# 着通过param的load的方法把参数值恢复成我们之前存储的。
		ros2 param load  /turtlesim ./turtlesim.yaml

	# 方法二:启动节点时加载参数快照
		# 语法:
		ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
		# 先关闭乌龟,然后重新运行
		ros2 run turtlesim turtlesim_node --ros-args --params-file ./turtlesim.yaml
	

三个角色

  • ROS Master (管理者):管理者作为一个公共的容器保存数据
  • Talker (参数设置者):参数设置者往容器中存储数据
  • Listener (参数调用者): 参数调用者读取容器中所需的数据

建立流程

在这里插入图片描述

  • step1:
    • 参数设置者使用RPC向参数服务器发送参数(包括参数名与参数值)
    • ROS Master 将参数保存到参数列表中。
  • step2:
    • 参数调用者使用RPC向参数服务器发送参数查找请求,请求中包含要查找的参数名。
  • step3:
    • ROS Master 根据步骤2请求提供的参数名查找参数值,并使用RPC将查询结果发送给参数调用者。

参数组成成分

ROS2参数是由键值对组成的.

  • 名字的数据类型是字符串
  • 值的数据类型可以是:
    • bool 和bool[],布尔类型用来表示开关,比如我们可以控制雷达控制节点,开始扫描和停止扫描。
    • int64 和int64[],整形表示一个数字,含义可以自己来定义
    • float64 和float64[],浮点型,可以表示小数类型的参数值
    • string 和string[],字符串,可以用来表示雷达控制节点中真实雷达的ip地址
    • byte[],字节数组,这个可以用来表示图片,点云数据等信息

代码实现

ROS2将日志分为五个级别,在RCLCPP中通过不同的宏可以实现不同日志级别日志的打印,例程如下

RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
RCLCPP_INFO(this->get_logger(), "我是INFO级别的日志,我被打印出来了!");
RCLCPP_WARN(this->get_logger(), "我是WARN级别的日志,我被打印出来了!");
RCLCPP_ERROR(this->get_logger(), "我是ERROR级别的日志,我被打印出来了!");
RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出来了!");

有时候日志太多,会让人眼花缭乱找不到重要信息,所以我们需要对日志的级别进行过滤,比如只看INFO以上级别的,ROS2中可以通过已有的API设置日志的级别,RCLCPP中API如下:

this->get_logger().set_level(log_level);

目标:声明参数并实现动态修改打印的日志级别功能

RCLCPP实现

创建功能包和节点

mkdir -p chapt4/chapt4_ws/
ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic --maintainer-name "fishros" --maintainer-email "fishros@foxmail.com"

parameters_basic.cpp

#include <chrono>
#include "rclcpp/rclcpp.hpp"

class ParametersBasicNode : public rclcpp::Node {
 public:
  explicit ParametersBasicNode(std::string name) : Node(name) {
    RCLCPP_INFO(this->get_logger(), "节点已启动:%s.", name.c_str());
  }
 private:
};

int main(int argc, char** argv) {
  rclcpp::init(argc, argv);
  /*产生一个的节点*/
  auto node = std::make_shared<ParametersBasicNode>("parameters_basic");
  /* 运行节点,并检测退出信号*/
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

构建测试:

colcon build  --packages-select example_parameters_rclcpp
source install/setup.bash
ros2 run example_parameters_rclcpp parameters_basic

参数API

在RCLCPP的API中,关于参数相关的函数比较多些,但都是围绕参数获取、参数设置、参数描述、列出参数、添加和移除参数回调事件。

使用参数控制节点日志级别

#include <chrono>
#include "rclcpp/rclcpp.hpp"
/*
    # declare_parameter            声明和初始化一个参数
    # describe_parameter(name)  通过参数名字获取参数的描述
    # get_parameter                通过参数名字获取一个参数
    # set_parameter                设置参数的值
*/
class ParametersBasicNode : public rclcpp::Node {
 public:
  // 构造函数,有一个参数为节点名称
  explicit ParametersBasicNode(std::string name) : Node(name) {
    RCLCPP_INFO(this->get_logger(), "节点已启动:%s.", name.c_str());
    this->declare_parameter("rcl_log_level", 0);     /*声明参数*/
    this->get_parameter("rcl_log_level", log_level); /*获取参数*/
    /*设置日志级别*/
    this->get_logger().set_level((rclcpp::Logger::Level)log_level);
    using namespace std::literals::chrono_literals;
    timer_ = this->create_wall_timer(
        500ms, std::bind(&ParametersBasicNode::timer_callback, this));
  }

 private:
  int log_level;
  rclcpp::TimerBase::SharedPtr timer_;

  void timer_callback() {
    this->get_parameter("rcl_log_level", log_level); /*获取参数*/
    /*设置日志级别*/
    this->get_logger().set_level((rclcpp::Logger::Level)log_level);
    std::cout<<"======================================================"<<std::endl;
    RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
    RCLCPP_INFO(this->get_logger(), "我是INFO级别的日志,我被打印出来了!");
    RCLCPP_WARN(this->get_logger(), "我是WARN级别的日志,我被打印出来了!");
    RCLCPP_ERROR(this->get_logger(), "我是ERROR级别的日志,我被打印出来了!");
    RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出来了!");
  }
};

int main(int argc, char** argv) {
  rclcpp::init(argc, argv);
  /*产生一个的节点*/
  auto node = std::make_shared<ParametersBasicNode>("parameters_basic");
  /* 运行节点,并检测退出信号*/
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

上面set_level,设置日志级别,ROS2的日志级别定义在文件/opt/ros/humble/include/rcutils/rcutils/logging.h的167-175行

/// The severity levels of log messages / loggers.
enum RCUTILS_LOG_SEVERITY
{
  RCUTILS_LOG_SEVERITY_UNSET = 0,  ///< The unset log level
  RCUTILS_LOG_SEVERITY_DEBUG = 10,  ///< The debug log level
  RCUTILS_LOG_SEVERITY_INFO = 20,  ///< The info log level
  RCUTILS_LOG_SEVERITY_WARN = 30,  ///< The warn log level
  RCUTILS_LOG_SEVERITY_ERROR = 40,  ///< The error log level
  RCUTILS_LOG_SEVERITY_FATAL = 50,  ///< The fatal log level
};

编译测试

colcon build --packages-select example_parameters_rclcpp
source install/setup.bash
ros2 run example_parameters_rclcpp parameters_basic

运行后你会发现DEBUG级别的日志并没有被打印出来,原因在于我们将节点的日志级别设置为了0,0对应的日志级别为RCUTILS_LOG_SEVERITY_UNSET即未设置使用默认级别,节点默认的日志级别就是INFO级别的,所以只能打印INFO以上的日志信息。

运行节点的时候可以指定参数的值,我们尝试将log_level的值改成10即DEBUG级别。

ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10

除了在节点运行前通过CLI传递参数,在运动的过程中也可以动态的修改参数

#查看参数列表
ros2 param list 
#设置参数级别
ros2 param set /parameters_basic rcl_log_level 10

在这里插入图片描述

补充

上面我们通过参数实现了动态控制节点日志级别的功能,其实像这样的功能ROS2早已为我们准备好了,在运行任意节点时候可以通过CLI传递日志级别配置。

ros2 run package-name node-name --ros-args --log-level debug

除了命令行设置参数和查看日志,通过rqt也可以可视化设置和查看
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS:参数服务器通信 的相关文章

  • 强化学习之美

    强化学习作为一门灵感来源于心理学中的行为主义理论的学科 xff0c 其内容涉及概率论 统计学 逼近论 凸分析 计算复杂性理论 运筹学等多学科知识 xff0c 难度之大 xff0c 门槛之高 xff0c 导致其发展速度特别缓慢 随着近年来以
  • 直线型一阶倒立摆2---建模

    三 直线型一阶倒立摆模型建立 一级倒立摆系统是一个不稳定的系统 xff0c 需要对其进行机理建模 在研究过程中 xff0c 应忽略空气摩擦 等 xff0c 而后可将倒立摆系统进行抽象化 xff0c 认为其由小车和匀质刚性杆两部分组成并对这两
  • 可用性和可靠性的区别

    首先 xff0c 这两个属性都是质量 xff08 可维护性 xff09 的一部分 按照书上的定义 xff0c 可靠性 xff08 reliability xff09 xff1a 在规格时间间隔内和规定条件下 xff0c 系统或部件执行所要求
  • 直线型一阶倒立摆3---控制器设计

    四 控制器设计 如前文所述 xff0c 倒立摆状态空间方程表明系统能够被控制 被观测 倒立摆或者其它受控系统达到受控稳定状态 xff0c 其实质上是指系统的各状态量收敛至一目标稳定值 对于状态空间描述而言 xff0c 系统矩阵A的特征值为负
  • Centos7 关闭防火墙

    Centos7 关闭防火墙 CentOS 7 0默认使用的是firewall作为防火墙 xff0c 使用iptables必须重新设置一下 1 直接关闭防火墙 systemctl stop firewalld service 停止firewa
  • 485无线通信/数传模块_zigbee模块_RS485转ZigBee_顺舟智能

    一 概述 顺舟智能 SZ02系列 ZigBee无线串口通信设备 xff08 485无线通信 数传设备 xff09 xff0c 采用了加强型的ZigBee无线技术 xff0c 集成了符合 ZIGBEE协议的射频收发器和微处理器 xff0c 符
  • 华清远见嵌入式学院学员实践项目案例介绍一

    基于GPRS的远程安防监控系统 1 项目背景 随着现代电力电子技术和微电子技术的迅猛发展 xff0c 自动化 xff0c 智能化程度的不断的提高 xff0c 家居安防技术正在不断发展 传统的家居安防系统已经越来越不能满足现代人的需求 消费者
  • Ubuntu 20.04.05安装ceres-1.14.0

    1 安装Ceres1 14 0 链接 Ubuntu20 04安装Ceres1 14 0 3 cmake编译ceres遇到的问题 xff08 1 xff09 TBB 问题描述 xff1a Did not find Intel TBB libr
  • ubuntu18.04 安装编译ceres-solver-1.14.0 编译错误

    在Ubuntu18 04 安装Ceres solver 1 14 0 xff0c make时出现了98 Built target bundle adjuster xff0c ecipe for target examples CMakeFi
  • ls-remote -h -t git://github.com/adobe-webplatform/eve.git

    npm WARN deprecated bfj node4 64 5 3 1 Switch to the bfj package for fixes and new features npm WARN deprecated nomnom 6
  • 数据可视化图表插件调研:Echarts、Highcharts、G2、D3

    目前常用于前端网页数据可视化实现的图表插件主要有四款 xff1a Echarts Highcharts G2 D3 xff0c 开发一些产品工具的时候可能会集成这些开源的可视化插件 xff08 这里Highcharts不开源 xff09 1
  • 31岁转行的我

    2011年从一所普通二本师范大学毕业后先后从事了两年的教育工作 xff0c 但都没有挣到钱 xff0c 12年从深圳回到西安 xff0c 参加了几次公务员和事业单位的招考 xff0c 几次因0 1分的微小差距与国家饭碗擦肩而过 后来决定不再
  • git submodule 如何同步更新

    摘要 xff1a git submodule 更新之后 xff0c 如果在父仓库里直接调用 git submodule update init recursive 会发现 子模块的代码不会更新 初学者会很迷惑 xff0c 怎么能把子模块更新
  • egret 入门 初试

    整理的文章 白鹭引擎入门 趁着今天周六 xff0c 把苹果放下一边先 今天早上一醒来就装上了js编辑神器Webstorm xff0c 最近也开始关注了一些移动方面的 js 前端框架 如 谷歌的Angularjs 和 fackbook 的Re
  • Ubuntu 18之vnc连接不上问题(已解决)

    在配置vnc时所以的准备动作已经准备好了 xff0c 该配的文件也配好了 xff0c 但就是一直连接不上 在主机端报time out的错误 xff0c 后来查百度得知vncserver xff1a 1对应5901端口 xff0c 2就是59
  • Matlab R2019a Win64位 迅雷下载链接

    鉴于百度云和PanDownload各种限速 xff0c 所以我特意寻了迅雷磁力链接供大家下载 实在是因为百度云下载只有50 k s xff0c 而迅雷下载5 m s啊 Matlab R2019a Win64位 链接内容包括Matlab和Ca
  • 力扣K神图解算法数据结构解析08

    力扣K神图解算法数据结构点这里 八 位运算 剑指15 xff0c 二进制中1的个数 class Solution public int hammingWeight uint32 t n int cnt 61 0 for int i 61 0
  • 吴军老师《给中学生/大学生的书单》----Yohao整理

    2018 7 27记录 span class hljs code 给中学生的书单 span 一 文学类 18本 span class hljs code 1 金庸和琼瑶各一本 长篇的比短篇的好 span span class hljs co
  • 北航2系921 2021考研历年真题及参考答案(2020-2004)

    需要自取 百度网盘 提取码 xff1a iwbg 关于2020北航921试题 相信大家都听说了 xff0c 2020年的921试题整体难度较2019年小 2019考完后 xff0c 群里面怨声载道 xff0c 信号10年没考电路题了怎么就今
  • 姿态解算

    姿态解算全过程 关于这方面 xff0c 姿态计算的理解大致需要经过以下几个步骤 1 秦永元的 惯性导航 xff0c 不但十分基础而且写的也十分好 xff0c 适合入门 但是并不是所有章节都是需要看的 xff0c 其中1 2节 9 2节和9

随机推荐

  • 匿名飞控代码解读汇总

    由于本人临近毕业 xff0c 所做的毕设是有关无人机方面的 xff0c 所使用的也是匿名的飞控 lt 资料包 20171217 gt xff0c 所以首先需要读懂匿名代码然后才能增加自己的功能 xff0c 临近毕业还有两个月左右 xff0c
  • 融合磁力计的Mahony互补滤波算法

    https blog csdn net qq 21842557 article details 50993809 上面博客有关于磁力计的详细解释 xff0c 不过由于本人资质愚钝 xff0c 至今还不是完全理解 不过思想大致和加速度计差不多
  • 代码解读一 文件名“ANO_Imu.c”

    我把这个文件的所有代码贴上来了 xff0c 供大家参考 xff0c 由于本人水平有限 xff0c 且匿名代码注释比较少 xff0c 所以很多也不是很懂 xff0c 实在是一些莫名的定义太多了 xff0c 什么w x y z h之类的 xff
  • 每周学一点 egret(2): EgretConversion 工具转换ts

    今晚无聊试了一下wing的格式化和这个转换工具 开始的时候我尝试手写翻译 xff0c 发现这一款转换也比较简单 所以尝试做了一下转换 对于如果文件名是中文 要小心一点 总是出现怪怪的 转换后 xff0c 没有直接跳转到对于的目录去 如果加上
  • 代码解读二 文件名“Ano_Math.c”

    这里面都是一些关于数学函数的骚操作 xff0c 既然不使用math h xff0c 那么至少说明这里面的数学函数调用不应比math h里面的函数慢 下面贴出代码 xff0c 简要做了个注释 xff0c 看看就行 至于怎么做的 xff0c 有
  • 关于单级PID及串级PID

    简单记录下我在学习PID过程中遇到的困难及解决方法 xff0c 希望能对大家有所帮助 1 首先 xff0c 关于PID这块理论知识必须非常清楚 xff0c 能够自行推导公式 xff0c 包括位置式PID公式和增量式PID公式 2 实现位置式
  • 代码解读三 文件名“Ano_Pid.c”

    关于PID这部分匿名代码里面有很多 xff0c 此文件是最基础的即单级PID的实现 xff0c 后面的关于速度和角速度环的串级PID及高度和高度速度环的串级PID都是以此为基础的 xff0c 所以此文件内容务必搞懂 C COPYRIGHT
  • 代码解读四 文件名“Ano_AttCtrl.c”

    这部分是关于匿名串级PID的 xff0c 我觉得有需要的同学可以直接移植 xff0c 不需要自己写了 xff0c 确实有点麻烦 xff0c 基本上代码里面都注释的很清楚了 xff0c 且由于本人水平有限 xff0c 所以也不是都很懂 xff
  • 代码解读六 文件名“Ano_AltCtrl.c”

    写了一大堆 xff0c 也不知道对不对 xff0c 贴上来让大家看看 include 34 Ano AltCtrl h 34 高度控制 include 34 Ano Imu h 34 include 34 Drv icm20602 h 34
  • 代码解读五 文件名“Ano_LocCtrl.c”

    关于这个位置速度环我还不是很理解 xff0c 因为单凭这一个文件确实看不出来什么东西 xff0c 这并不像角度环和角速度环一样有丰富的理论支撑 xff0c 至少我现在还没看到 xff0c 可能是我水平不够额 xff0c 但这并不妨碍我们继续
  • 代码解读七 文件名“Ano_MotorCtrl.c

    本文件比较简单 xff0c 代码比较少 xff0c 主要涉及解锁后四个电机依次1 2 3 4转动 xff0c 然后四轴也不会飞 xff0c 只是在原地轻微转动 xff0c 随后需要逐渐加油门至50 到达临界点 xff0c 稍微往上推一点 x
  • 代码解读八 文件名“Ano_FlightCtrl.c”

    这个文件代码有点乱啊 xff0c 反正没怎么看懂 xff0c 涉及到一键起飞和降落 xff0c 以及关于不同任务对应不同的灯光的切换 而且注释也还可以 xff0c 凑活着看下呗 xff0c 其实这个并不是什么关键文件 xff0c 看不懂就算
  • 代码解读九 文件名“Ano_MagProcess.c”

    本部分主要是关于磁力计进行校准操作的 xff0c 用户手册上有详细步骤 xff0c 有需要可以看看 include 34 Ano MagProcess h 34 include 34 Drv LED h 34 本文件是关于磁力计校准及相关处
  • 代码解读十 文件名“Ano_FlightDataCal.c”

    本部分主要是对IMU测量模块测量的值进行后续处理 xff0c 同时在飞行过程中不断对数据进行更新 xff0c 然后进行姿态解算 xff0c 便于后续丢进PID中进行进一步处理 根据所处位置及函数调用情况不难发现此部分算是对底层的进一步封装
  • 【阅读笔记】联邦学习实战——联邦学习攻防实战

    联邦学习实战 联邦学习攻防实战 前言1 后门攻击1 1 问题定义1 2 后门攻击策略1 3 详细实现 2 差分隐私2 1 集中式差分隐私2 2 联邦差分隐私2 3 详细实现 3 模型压缩3 1 参数稀疏化3 1 1 详细实现3 1 2 实验
  • 关于后续部分

    关于算法这块基本上算是读完了 xff0c 只能从大致上理解下了 xff0c 毕竟代码不是自己写的没有最直接的感受 xff0c 那么我们来回顾下 xff0c 试着从整体上来理解下匿名代码除了最上层之外的部分 最上层也就是包含main c在内的
  • cmake:设置编译选项

    此文为 xff1a 轻松入门cmake系列教程 常用 1 cmake debug和release设置 span class token macro property span class token directive hash span
  • cmake:pkg_check_modules

    此文为 xff1a 轻松入门cmake系列教程 理论 是什么 xff1f pkg check modules是 CMake 自己的 pkg config 模块的一个用来简化的封装 xff1a 你不用再检查 CMake 的版本 xff0c 加
  • Unix/Linux编程:针对目录文件描述符的相关操作

    始于版本2 6 16 xff0c Linux内核提供了一系列新的系统调用 xff0c 在执行与传统系统调用相似任务的同时 xff0c 还提供了一些附加功能 xff0c 对某些应用程序非常有用 新 接 口类似的传统接口备 注faccessat
  • ROS:参数服务器通信

    为什么需要 在机器人开发中 xff0c 会有很多参数和设置可以后期需要调整的 xff0c 如果都放到源码里很难实现动态修改和管理 xff0c ROS2为了解决这一问题 xff0c 提出了参数这一通信机制 是什么 如何理解 参数 xff1f