首页 资讯 应用 高压 设计 行业 低压 电路图 关于

机器人

旗下栏目: 物联网 机器人 新技术 仪器仪表

ROS探索总结(四十)—dynamic reconfigure

机器人 | 发布时间:2018-05-17 | 人气: | #评论# | 本文关键字:ROS
摘要:ROS 中的参数服务器无法在线动态更新,也就是说如果 Listener 不主动查询参数值,就无法获知 Talker 是否已经修改了参数。这就对 ROS 参数服务器的使用造成了很大的局限,很多场景下我们还是

ROS中的参数服务器无法在线动态更新,也就是说如果Listener不主动查询参数值,就无法获知Talker是否已经修改了参数。这就对ROS参数服务器的使用造成了很大的局限,很多场景下我们还是需要动态更新参数的机制,例如参数调试、功能切换等,所以ROS提供了另外一个非常有用的功能包——dynamic_reconfigure,实现这种动态配置参数的机制。

例如下图是启动Kinect后openni功能包所提供的可动态配置参数的可视化列表:

启动Kinect后openni功能包所提供的可动态配置参数的可视化列表

ROS中的动态参数修改采用C/S架构,在运行过程中,用户在客户端修改参数后不需要重新启动,而是向服务端发送请求,然后服务端通过回调函数确认,即完成参数的动态重配置。本篇我们就来探索ROS中参数动态配置的具体实现方法。

一、 创建配置文件

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

$ catkin_create_pkg dynamic_tutorials rospy roscpp dynamic_reconfigure

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

#!/usr/bin/env pythonPACKAGE = "dynamic_tutorials"from dynamic_reconfigure.parameter_generator_catkin import *gen = ParameterGenerator()

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"))

配置文件使用python实现,详细分析一下其中的具体内容:

#!/usr/bin/env python PACKAGE = "dynamic_tutorials" from dynamic_reconfigure.parameter_generator_catkin import *

首先需要导入dynamic_reconfigure功能包提供的参数生成器(parameter generator)。

gen = ParameterGenerator()

然后创建一个参数生成器,接下来就可以开始定义需要动态配置的参数了。

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)

这里定义了四个不同类型的参数,生成参数可以使用参数生成器的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方法定义每一个枚举值的名称、类型、值、描述字符串。

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

最后一行代码用于生成所有C++和Python相关的文件并且退出程序,这里第二个参数表示动态参数运行的节点名,第三个参数是生成文件所使用的前缀,需要和配置文件名相同。

配置文件创建完成后,需要使用如下命令为配置文件添加可执行权限:

$ 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)

配置文件相关的工作就到此为止,接下来需要创建一个dynamic_reconfigure_node,来调用参数的动态配置。

二、创建服务端节点


dynamic_reconfigure_node节点的代码实现server.cpp如下:

#include <ros/ros.h> 

#include <dynamic_reconfigure/server.h> 

#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::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; }

代码的内容不多,分析其实现过程。

#include < ros/ros.h>   #include < dynamic_reconfigure/server.h> #include < dynamic_tutorials/TutorialsConfig.h>

首先需要包含必要的头文件,其中有一个TutorialsConfig.h头文件,就是配置文件所生成的。

ros::init(argc, argv, "dynamic_tutorials");     

dynamic_reconfigure::Server<dynamic_tutorials::TutorialsConfig> server;

先来看main函数的内容。首先初始化ROS节点,然后创建了一个参数动态配置的服务端实例,参数配置的类型就是配置文件中描述的类型。该服务端实例会监听客户端的参数配置请求。

dynamic_reconfigure::Server<dynamic_tutorials::TutorialsConfig>::CallbackType f;     

f = boost::bind(&callback, _1, _2);     

server.setCallback(f);

然后定义一个回调函数,并将回调函数和服务端绑定,当客户端请求修改参数时,服务端即可跳转到回调函数中进行处理。

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); 

}


对于本例程来说,回调函数并不复杂。回调函数的传入参数有两个,一个是新的参数配置值,另外一个表示参数修改的掩码。然后在回调函数中将修改后的参数值打印出来。


代码编辑完成后在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})

现在就可以编译dynamic_tutorials功能包了。

三、实现动态参数修改

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

$ roscore $ rosrun dynamic_tutorials dynamic_reconfigure_node

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

$ rosrun rqt_reconfigure rqt_reconfigure

在打开的如下图所示的可视化界面中,可以通过输入、拖动、下拉选择的方式动态修改参数,输入方式的不同和配置文件中的参数设置有关,例如设置了参数的最大最小值,就会有拖动条;设置为枚举类型,就会是下拉选项。

2

修改后可以在服务端的终端中看到修改成功的打印信息,如下图所示:

3

责任编辑:电气自动化网
首页 | 电气资讯 | 应用技术 | 高压电器 | 电气设计 | 行业应用 | 低压电器 | 电路图 | 关于我们 | 版权声明

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版 原创声明:本站大部分内容为原创,转载请注明电气自动化网转载;部分内容来源网络,如侵犯您的权益请发送邮件到[email protected]联系我们删除。