ROS:Dynamic Reconfigure 动态参数调节

1、什么是动态参数调节

  ROS中的参数服务器无法在线动态更新,也就是说如果Listener不主动查询参数值,就无法获知Talker是否已经修改了参数。这就对ROS参数服务器的使用造成了很大的局限,很多场景下我们还是需要动态更新参数的机制,例如参数调试、功能切换等,所以ROS提供了另外一个非常有用的功能包 —— dynamic_reconfigure,实现这种动态配置参数的机制。
  动态重配置的重点是提供一种标准的方法,将节点的一个子集参数公开给外部重配置。使用客户端程序,例如gui,可以向节点查询一组可动态配置的参数,包括它们的名称、类型、范围,并向用户提供一个自定义接口。

2、动态参数配置GUI(rqt_reconfigure)

  rqt_reconfigure工具可以在不重启系统的情况下,动态配置ROS系统中的参数,但该功能的使用需到在代码中设置参数的相关属性,来支持参数的动态配置。使用如下命令启动该工具:

$ rosrun rqt_reconfigure rqt_reconfigure

例如下图是启动机器人仿真环境时,不同节点所能提供的可动态配置参数的可视化:
在这里插入图片描述

3、实现自定义参数的动态调节

3.1、创建配置文件(.cfg)

  首先通过以下命令创建一个功能包——dynamic_tutorials:

$ catkin_create_pkg dynamic_tutorials rospy roscpp dynamic_reconfigure

  实现动态参数配置需要编写一个配置文件,在功能包中创建一个放置配置文件的cfg文件夹,然后在其中创建一个配置文件dynamic_tutorials/cfg/Tutorials.cfg,代码如下:

#!/usr/bin/env python
PACKAGE = "dynamic_tutorials"
#初始化ROS,并导入参数生成器
from dynamic_reconfigure.parameter_generator_catkin import *
#初始化参数生成器
gen = ParameterGenerator()
#定义需动态配置的参数,格式为
#gen.add(name , type, level, description, default, min, max)
gen.add("int_param",    int_t,    0, "An Integer parameter", 50,  0, 100)
gen.add("double_param", double_t, 0, "A double parameter",    .5, 0,   1)
gen.add("str_param",    str_t,    0, "A string parameter",  "Hello World")
gen.add("bool_param",   bool_t,   0, "A Boolean parameter",  True)
#生成一个枚举类型的值
size_enum = gen.enum([ gen.const("Small",      int_t, 0, "A small constant"),                      
					   gen.const("Medium",     int_t, 1, "A medium constant"),                      
					   gen.const("Large",      int_t, 2, "A large constant"),                      
					   gen.const("ExtraLarge", int_t, 3, "An extra large constant")], 
					   "An enum to set size")
gen.add("size", int_t, 0, "A size parameter which is edited via an enum", 1, 0, 3, edit_method=size_enum)
#生成必要文件并退出
exit(gen.generate(PACKAGE, "dynamic_tutorials", "Tutorials"))

详细解读
一、gen.add()

gen.add(name , type, level, description, default, min, max)

name:参数名,使用字符串描述;
type:定义参数的类型,可以是int_t, double_t, str_t, 或者bool_t;
level:需要传入参数动态配置回调函数中的掩码,在回调函数中会修改所有参数的掩码,表示参数已经进行修改;
description:描述参数作用的字符串;
default:设置参数的默认值;
min:可选,设置参数的最小值,对于字符串和布尔类型值不生效;
max:可选,设置参数的较大值,对于字符串和布尔类型值不生效;

二、枚举类型

size_enum = gen.enum([ gen.const("Small",      int_t, 0, "A small constant"),                      
					   gen.const("Medium",     int_t, 1, "A medium constant"),                      
					   gen.const("Large",      int_t, 2, "A large constant"),                      
					   gen.const("ExtraLarge", int_t, 3, "An extra large constant")], 
					   "An enum to set size")
 gen.add("size", int_t, 0, "A size parameter which is edited via an enum", 1, 0, 3, edit_method=size_enum)

  这里定义了一个int_t类型得到参数“size”,该参数的值可以通过一个枚举列出来。枚举的定义使用enum方法进行定义,其中使用const方法定义每一个枚举值的名称、类型、值、描述字符串。

三、生成TutorialsConfig.h文件

exit(gen.generate(PACKAGE, "dynamic_tutorials", "Tutorials"))

第二个参数为运行时的节点名,第三个参数为生成文件所使用的前缀,需要与配置文件名相同。

3.2、配置文件

  两种方法:
一、手动添加权限
  使用如下命令添加配置文件的可执行权限:

$ chmod a+x cfg/Tutorials.cfg

  类似于消息的定义,这里也需要生成代码文件,所以在CMakeLists.txt中添加如下编译规则:

#add dynamic reconfigure api
generate_dynamic_reconfigure_options(  
		cfg/Tutorials.cfg  
		#...
		)
# make sure configure headers are built before any node using them
add_dependencies(dynamic_reconfigure_node ${PROJECT_NAME}_gencfg)

二、自动添加
  适用于代码移植,直接自动由.cfg文件编译生成。

set (DYNAMIC_RECONFIGURE_PATH cfg/Tutorials.cfg)
execute_process(COMMAND chmod a+x ${DYNAMIC_RECONFIGURE_PATH}
      		  	WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
      		  	RESULT_VARIABLE cmd_result
      		 	OUTPUT_VARIABLE cmd_ver)
message(STATUS "Chmod a+x the dynamic_reconfigure file")

generate_dynamic_reconfigure_options(
        ${DYNAMIC_RECONFIGURE_PATH}
)

3.3、创建服务器节点

  dynamic_reconfigure_node节点的代码实现server.cpp如下,代码解析在代码注释中

#include <ros/ros.h>
#include <dynamic_reconfigure/server.h>
//TutorialsConfig.h为 #3.2 编译过程中自动生成头文件
#include <dynamic_tutorials/TutorialsConfig.h>

//定义回调函数,当客户端请求修改参数时,服务端即可跳转到回调函数中进行处理。
//传入值有两个,一个是参数更新的配置值,一个是表示参数修改的掩码
void callback(dynamic_tutorials::TutorialsConfig &config, uint32_t level) 
{  
	ROS_INFO("Reconfigure Request: %d %f %s %s %d",             
			config.int_param, config.double_param,             
			config.str_param.c_str(),             
			config.bool_param?"True":"False",
	        config.size);
}

int main(int argc, char **argv)
{    
	//初始化ROS节点
	ros::init(argc, argv, "dynamic_tutorials");
	//创建了一个参数动态配置的服务端实例,参数配置的类型就是配置文件中描述的类型
	//该服务端实例会监听客户端的参数配置请求。
	dynamic_reconfigure::Server<dynamic_tutorials::TutorialsConfig> server;    
	dynamic_reconfigure::Server<dynamic_tutorials::TutorialsConfig>::CallbackType f;    
	//并将回调函数和服务端绑定
	f = boost::bind(&callback, _1, _2);    
	server.setCallback(f);    
	ROS_INFO("Spinning node");    
	ros::spin();    
	return 0;
}

  在 CmakeLists.txt 中加入以下编译规则:

# for dynamic reconfigure
add_executable(dynamic_reconfigure_node src/server.cpp)
# make sure configure headers are built before any node using them
add_dependencies(dynamic_reconfigure_node ${PROJECT_NAME}_gencfg)
# for dynamic  reconfigure
target_link_libraries(dynamic_reconfigure_node ${catkin_LIBRARIES})

  然后使用catkin_make命令编译dynamic_tutorials功能包。

3.4、实现参数动态配置

  编译成功后使用如下命令将roscore和dynamic_reconfigure_node运行起来:

$ roscore
$ rosrun dynamic_tutorials dynamic_reconfigure_node

  这个时候参数动态配置的服务端就运行起来了,使用ROS提供的可视化参数配置工具来修改参数:

$ rosrun rqt_reconfigure rqt_reconfigure

  在打开的如下图所示的可视化界面中,可以通过输入、拖动、下拉选择的方式动态修改参数,输入方式的不同和配置文件中的参数设置有关,例如设置了参数的较大最小值,就会有拖动条;设置为枚举类型,就会是下拉选项。
在这里插入图片描述
  修改后可以在服务端的终端中看到修改成功的打印信息,如下图所示:在这里插入图片描述
参考文献:

  1. ROS机器人开发实践 第十二章 (P409–12.4)
  2. ROS dynamic reconfigure
  3. ROS_Dynamic Reconfig 动态参数调节
  • 18
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值