ROS2-5章:节点参数parameter详细讲解

目录

[目录... 1](#目录... 1)

[一、Parameter(参数)... 2](#一、Parameter(参数)... 2)

[1. 参数是什么?... 2](#1. 参数是什么?... 2)

[2. 参数有什么用?... 2](#2. 参数有什么用?... 2)

[3. 如何与参数进行交互?... 2](#3. 如何与参数进行交互?... 2)

[1.1 创建话题 参数(Parameter)... 3](#1.1 创建话题 参数(Parameter)... 3)

[1.1.1先进入代码空间... 3](#1.1.1先进入代码空间... 3)

[1.1.2创建一个功能包parameter_test,以及一个参数节点parameter;... 3](#1.1.2创建一个功能包parameter_test,以及一个参数节点parameter;... 3)

[1.1.3打开 vs code. 4](#1.1.3打开 vs code. 4)

[1.1.4修改 parameter.py文件内容... 4](#1.1.4修改 parameter.py文件内容... 4)

[1.1.5 编译、安装、运行... 5](#1.1.5 编译、安装、运行... 5)

[1.2 代码理解... 6](#1.2 代码理解... 6)

[1.2.1. 它们是什么关系?... 6](#1.2.1. 它们是什么关系?... 6)

[1.2.2. 这个参数是怎么设置和传入的?(完整生命周期)... 6](#1.2.2. 这个参数是怎么设置和传入的?(完整生命周期)... 6)

[1.2.3总结... 7](#1.2.3总结... 7)

一、Parameter(参数)

在 ROS 2 中,参数(Parameter) 是专门用于**外部配置节点(Node)**的一种机制。你可以把它理解为节点的"全局设置"或"运行时开关"。

1. 参数是什么?

  • 绑定于节点:每个 ROS 2 节点都可以拥有并维护自己的一套参数,参数的生命周期与节点绑定。
  • 数据类型丰富:参数可以存储多种类型的数据,包括整数(integers)、浮点数(floats)、布尔值(booleans)、字符串(strings)以及列表(lists)。
  • 动态可重配置:所有的参数在节点运行时都是动态可修改的,且这一功能是基于 ROS 2 的服务(Services)机制构建的。

2. 参数有什么用?

参数的核心作用是在不修改代码、不重新编译的情况下,动态改变节点的运行行为

在实际的机器人开发中,参数常用于以下场景:

  • 调整算法阈值:例如修改避障算法中的安全距离、PID控制器的比例系数等。
  • 修改硬件配置:例如更改摄像头传感器的曝光度、修改电机的最大转速限制。
  • 切换运行模式:例如通过一个布尔值参数,让节点在"调试模式"和"正常运行模式"之间切换,从而控制日志的输出级别。
  • 外部初始化配置:在节点启动时,通过参数文件或命令行传入初始配置值,避免将配置硬编码在代码中。

3. 如何与参数进行交互?

在 ROS 2 中,你可以通过命令行工具非常方便地对节点参数进行查看和修改:

  • 查看参数列表:使用 ros2 param list 命令可以查看当前系统中所有节点拥有的参数。
  • 获取参数值:使用 ros2 param get <node_name> <parameter_name> 可以查看某个参数的当前值和类型。
  • 动态修改参数:使用 ros2 param set <node_name> <parameter_name> <value> 可以在运行时直接修改参数,节点会立即响应这一变化。
  • 保存与加载:你可以将当前的参数配置导出保存为 YAML 文件,并在下次启动节点时直接加载该文件,从而复用之前的配置。
    1. 创建话题 参数(Parameter)

以下是 Topic 代码逻辑的通用步骤(以 Python 为例,C++ 逻辑完全对称):创建一个功能包topic_test;包含一个话题发布者节点Publiser;

1.1.1先进入代码空间

|--------------------------------------------------------------|
| root@LHAYR:~# cd ~/ros2_ws/src/ root@LHAYR:~/ros2_ws/src# |

1.1.2创建一个功能包parameter_test,以及一个参数节点parameter;

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws/src# ros2 pkg create --build-type ament_python --node-name parameter --dependencies rclpy --license MIT parameter_test going to create a new package package name: parameter_test destination directory: /root/ros2_ws/src package format: 3 version: 0.0.0 description: TODO: Package description maintainer: 'root \' licenses: 'MIT' build type: ament_python dependencies: 'rclpy' node_name: parameter creating folder ./parameter_test creating ./parameter_test/package.xml creating source folder creating folder ./parameter_test/parameter_test creating ./parameter_test/setup.py creating ./parameter_test/setup.cfg creating folder ./parameter_test/resource creating ./parameter_test/resource/parameter_test creating ./parameter_test/parameter_test/init.py creating folder ./parameter_test/test creating ./parameter_test/test/test_copyright.py creating ./parameter_test/test/test_flake8.py creating ./parameter_test/test/test_pep257.py creating ./parameter_test/parameter_test/parameter.py root@LHAYR:~/ros2_ws/src# 指令中各个参数的详细解析: * ros2 pkg create:这是 ROS 2 中用于创建新软件功能包(Package)的核心命令。 * --build-type ament_python:指定该功能包的构建类型为 Python。ament_python 表示系统会按照 Python 项目的标准(如使用 setup.py)来编译和安装这个包。 * --node-name publisher:这是一个可选参数,用于在创建包时自动生成一个名为 publisher 的节点模板文件(即 publisher.py)。 * --dependencies rclpy std_msgs:声明该功能包运行所需的依赖库。这里指定了 rclpy(ROS 2 的 Python 客户端库)。 * --license MIT:声明该功能包的开源许可证类型为 MIT。 * parameter_test:这是你自定义的功能包名称,必须放在命令的最后。系统会在当前目录下生成一个名为parameter_test 的文件夹。 |

1.1.3打开 vs code

|--------------------------------------------------------------|
| root@LHAYR:~/ros2_ws/src# code . root@LHAYR:~/ros2_ws/src# |

1.1.4修改 parameter.py文件内容

修改parameter.py文件内容(src/ parameter _test/ parameter _test/ parameter.py

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| import rclpy # 导入 ROS 2 的 Python 核心接口库 from rclpy.node import Node # 导入 ROS 2 节点基类,所有的 ROS 2 节点都需要继承它 import rclpy.parameter # 导入参数处理模块,用于在代码中动态创建或修改参数对象 from rcl_interfaces.msg import SetParametersResult # 导入参数修改结果的响应消息类型,用于回调函数返回 class ParamNode(Node): # 定义 ParamNode 类,继承自 Node 基类 def init(self): # 类的构造函数,节点启动时首先执行 # 1. 初始化父类节点 super().init('param_node') # 调用父类构造函数,将节点在 ROS 网络中的名称注册为 'param_node' self.logger = self.get_logger()# 获取日志记录器,后续可以通过 self.logger.info() 等打印日志 # 2. 声明参数 self.declare_parameter('number', 10) # 声明一个名为 'number' 的参数,默认整型值为 10 self.declare_parameter('string', 'hello world!') # 声明一个名为 'string' 的参数,默认字符串值为 'hello world!' # 3. 测试是否有参数 if self.has_parameter('string'): # 检查节点中是否已经成功声明了名为 'string' 的参数 self.logger.info('Has param string') # 如果存在,打印一条 Info 级别的日志 # 4. 创建并获取参数最新的值 self.length = self.declare_parameter('length', 3).get_parameter_value().integer_value # 这一行做了三件事: # (1) declare_parameter('length', 3):声明参数 'length',默认值为 3 # (2) .get_parameter_value():获取该参数的值对象 # (3) .integer_value:提取其中的整型数值,并赋值给类的成员变量 self.length self.logger.info(f'Parameter length is {self.length}') # 打印获取到的 length 参数值 # 5. 参数修改回调函数 self.add_on_set_parameters_callback(self.show) # 注册一个"参数设置前"的回调函数。当外部(如命令行)尝试修改参数时,会先触发此函数。 # 该函数必须返回 SetParametersResult,以决定是允许还是拒绝这次修改。 # 6. 调用更新参数的方法 self.updateparam() # 在初始化阶段主动调用内部方法,测试在代码内部修改参数的逻辑 def updateparam(self): # 自定义方法,用于在节点内部主动修改参数 # 取得参数 num_param = self.get_parameter('number').get_parameter_value().integer_value # 获取已声明参数 'number' 的当前整型值,赋给局部变量 num_param self.logger.info(f'Param number = {num_param}') # 打印修改前的 number 值 # 创建新参数 my_new_param = rclpy.parameter.Parameter('number', rclpy.Parameter.Type.INTEGER, 1) # 构造一个新的 Parameter 对象:名称为 'number',类型为整型,新值为 1 all_new_parameters = my_new_param # 将新参数对象放入列表中(set_parameters 方法要求传入列表) self.logger.info('Change param number') # 打印提示日志,表示即将修改参数 # 修改参数 self.set_parameters(all_new_parameters) # 调用 ROS 2 内置方法应用新参数。这会触发上面注册的 self.show 回调函数 def show(self, params): # 参数修改回调函数,params 是一个包含待修改参数的列表 """ 参数修改回调函数。 注意:on_set_parameters_callback 必须返回 SetParametersResult 对象, 否则 ROS2 会拒绝修改并报错。 """ result = SetParametersResult(successful=True) # 创建一个返回结果对象,默认设置为允许修改(successful=True) for i in params: # 遍历所有正在被修改的参数 if i.type_ == rclpy.Parameter.Type.INTEGER: # 判断参数类型是否为整型 value = i.get_parameter_value().integer_value # 如果是整型,提取整型值 else: # 否则(如字符串类型) value = i.get_parameter_value().string_value # 提取字符串值 self.logger.info(f'Param {i.name} = {value}') # 打印正在被修改的参数名和新值 return result # 【关键】必须返回 result 对象,告诉 ROS 2 系统允许这次参数修改 def main(args=None): # 定义程序的主入口函数 rclpy.init(args=args) # 初始化 ROS 2 通信基础设施(必须在创建节点前调用) node = ParamNode() # 实例化 ParamNode 节点对象,触发 init 中的所有逻辑 try: rclpy.spin(node) # 让节点进入阻塞循环,保持节点存活,处理回调和事件(按 Ctrl+C 退出) except KeyboardInterrupt: # 捕获键盘中断信号(Ctrl+C) pass # 捕获后不做额外操作,直接进入 finally 块 finally: # 无论是否发生异常,都会执行此块(确保资源被正确清理) node.destroy_node() # 销毁节点对象,释放底层资源 rclpy.shutdown() # 关闭 ROS 2 通信基础设施 if name == 'main': # Python 标准入口判断:如果直接运行此脚本,则执行 main() main() # 调用主函数启动节点 |

1.1.5 编译、安装、运行

  1. 保存代码,进行编译,安装(跟新环境变量) 和运行

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws# colcon build --packages-select parameter_test --symlink-install Starting >>> parameter_test Finished <<< parameter_test 0.60s Summary: 1 package finished 0.67s root@LHAYR:~/ros2_ws# source install/setup.bash root@LHAYR:~/ros2_ws# ros2 run parameter_test parameter INFO 1782987793.144229166 param_node: Has param string INFO 1782987793.144452547 param_node: Parameter length is 3 INFO 1782987793.144569444 param_node: Param number = 10 INFO 1782987793.144681076 param_node: Change param number INFO 1782987793.144806037 param_node: Param number = 1 |

  1. 修改参数,验证 ros2 run parameter_test parameter --ros-args -p length:=33

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws# ros2 run parameter_test parameter --ros-args -p length:=33 INFO 1782988966.378955454 param_node: Has param string INFO 1782988966.379188286 param_node: Parameter length is 33 INFO 1782988966.379305061 param_node: Param number = 10 INFO 1782988966.379414819 param_node: Change param number INFO 1782988966.379537070 param_node: Param number = 1 |

1.2 代码理解

在 ROS 2 中,参数是属于节点私有的,节点必须在代码中先"占位"(声明参数),外部才能通过命令行将值"注入"进去。

下面我为你详细拆解这个参数是如何被设置和传入的:

1.2.1. 它们是什么关系?

  • 代码中的 declare_parameter('length', 3):相当于在节点内部建了一个"变量容器",并给了一个默认值 3。
  • 命令行中的 -p length:=33:相当于在节点启动的瞬间,从外部向这个"容器"里强制塞入了一个新值 33。

1.2.2. 这个参数是怎么设置和传入的?(完整生命周期)

当你运行 ros2 run parameter_test parameter --ros-args -p length:=33 时,底层发生了以下 4 个步骤:

第一步:解析命令行参数

--ros-args 是一个关键的分隔符,它告诉 ROS 2 系统:"后面的内容不是给 Python 解释器或可执行文件的,而是 ROS 2 框架专用的配置参数"。-p 是 --param 的缩写,表示接下来要设置一个参数。

第二步:节点初始化与参数声明

节点启动,执行到代码 self.declare_parameter('length', 3)。此时,ROS 2 系统会检查命令行是否传入了同名参数。

第三步:值的覆盖(核心机制)

系统发现命令行传入了 length:=33,于是直接忽略代码中设置的默认值 3,将参数 length 的初始值强制修改为 33。

第四步:获取并应用

代码继续执行 .get_parameter_value().integer_value,此时提取到的已经是被命令行覆盖后的最新值 33,并将其赋值给 self.length,最后通过 self.logger.info 打印在终端上。

1.2.3总结

这就是 ROS 2 参数系统的强大之处:代码负责定义参数和默认值,而命令行(或 YAML 文件)负责在不修改代码、不重新编译的情况下,灵活地改变节点的运行配置

    1. 代码详细解析

1. 导入依赖模块

|----------------------------------------------------------------------------|
| |

2. 定义节点类与初始化

|----------------------------------------------------------------------------|
| |

指令:self.declare_parameter('number', 10);ROS2规定:参数必须先声明,才能读、才能改。declare_parameter 是 ROS2 自带的方法,

 self:你当前这个节点对象

 declare_parameter:ROS2 提供的声明参数的内置方法

 'number':参数的名字(你随便起,但要见名知意)

 10:参数的默认值

指令:self.has_parameter('string') ;也是 ROS 2 Node 基类自带的内置方法。

has_parameter(参数名):作用就是:查一下这个节点里,有没有声明过这个名字的参数。

这些全都是 ROS 2 内置方法,自带的,你只要继承 Node,就能直接用:

  • self.declare_parameter(名字, 默认值)→ 声明一个参数
  • self.has_parameter(名字)→ 检查有没有这个参数
  • self.get_parameter(名字)→ 获取参数当前值
  • self.set_parameter(...)→ 修改参数值
  • self.add_on_set_parameters_callback(...)→ 参数被改时触发回调

全是 ROS 2 封装好的内置功能,你只负责调用就行。

3. 内部修改参数的方法

|----------------------------------------------------------------------------|
| |

4. 参数修改回调函数

|----------------------------------------------------------------------------|
| |

5. 节点主入口与生命周期管理

|----------------------------------------------------------------------------|
| |

相关推荐
诚信定制8394 小时前
PrivaZer逆向解析:深度清理背后的三大隐患
windows
love530love8 小时前
WorkBuddy + 本地 ComfyUI Wan2.1 文生视频实战:从连续报错到成功出片的完整踩坑记录
人工智能·windows·python·音视频·devops·comfyui·mcp
TrisighT9 小时前
Electron 跑鸿蒙 PC 上,这 4 个 API 的行为跟 Windows 完全不一样——但文档一行都没写
windows·electron·harmonyos
XUHUOJUN10 小时前
Azure Local离线模式PKI规划(系列篇之五)
microsoft·azure local
春日见11 小时前
E2E自驾JD理解
人工智能·深度学习·算法·microsoft·transformer
编码者卢布1 天前
【Azure Storage Account】跨存储账号复制 Blob 会产生大量网络流量费用吗?
microsoft·flask·azure
qq_3692243317 天前
Windows全系通用!ntdll.dll文件丢失、报错、闪退问题的完整排查与修复教程
windows·dll·dll修复·dll丢失·dll错误
Data-Miner17 天前
大语言模型+智能体AI,122页PPT详解落地应用培训!
人工智能·microsoft·语言模型
阿米亚波17 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm