文章目录
前言
之前的学习中,曾了解过ROS参数服务器的通信机制,如果Listenner不主动查询参数值,就无法获取Talker是否已经向Master更新了参数值。
很多情况下,我们需要动态的更新参数,比如参数调试等,ROS提供了dynamic_reconfigure功能包,实现动态参数配置。
一、原理
ROS的动态参数修改采用C/S架构,在运行过程中,客户端修改参数后不需要重启,而是向服务器发送请求;服务器通过回调函数确认,即可完成参数的动态配置。
二、实现
1、创建功能包
创建名为dynamic_tutorials的功能包,命令如下:
catkin_create_pkg dynamic_tutorials rospy roscpp dynamic_reconfigure
2、创建配置文件
在功能包下的cfg文件夹下,创建名为Tutorials.cfg的文件,内容如下:
#!/usr/bin/env python
PACKAGE = "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)
#生成所有与C++和python相关的文件,并且退出程序,第二个参数表示运行时的节点名,第三个参数为生成文件所使用的前缀,需要与配置文件名相同
exit(gen.generate(PACKAGE, "dynamic_tutorials", "Tutorials"))
真正运行时,需要去掉中文注释。配置完成后,对该文件添加可执行权限。
3、修改CMakeLists.txt文件
添加编译规则,内容如下:
generate_dynamic_reconfigure_options(
cfg/Tutorials.cfg
)
add_dependencies(dynamic_reconfigure_node ${PROJECT_NAME}_gencfg)
4、创建dynamic_reconfigure_node节点
4、1 创建服务器节点
在src目录下,创建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节点
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;
}
4、2 修改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})
完成上述配置后,编译功能包。
5、参数动态配置
运行roscore和dynamic_reconfigure_node节点,命令如下:
roscore
rosrun dynamic_tutorials dynamic_reconfigure_node
此时,参数动态配置的服务器就开始运行了,接下来使用ROS提供的可视化参数配置工具来修改参数,命令如下:
rosrun rqt_reconfigure rqt_reconfigure
如图:
可以通过拖动、输入、下拉框等方式修改参数,值得注意的是,这里的输入方式不同与配置文件中的参数设置有关,例如设置了最大值/最小值,就会有拖动条;设置了枚举,就会出现下拉框。
伴随着参数值的变化,在服务器节点的输出中,会看到修改后的信息,如图:
评论(0)
您还未登录,请登录后发表或查看评论