Understanding ROS: parameter server & dynamic parameters

One, getparam and param in the program

1. getparam (no default value)

bool getParam (const std::string& key, parameter_type& output_value)//返回值判断是否获取参数成功

among them:

  • The key is the parameter name (equivalent to the interface, similar to the topic), naming method reference: ros naming (refer to follow-up learning)
  • output_value is used to hold the value of the
    parameter. The parameter_type type includes bool, int, double, string, or a specific XmlRpcValue type. The XmlRpcValue type includes all types, even lists/maps

For example:

std::string s;
n.getParam("my_param", s);

2. param (has a default value)

int i;
n.param("my_num", i, 42);//默认参数为42

3. Delete parameters

n.deleteParam("my_param");

4. Set parameters in the program

n.setParam("my_param", "hello there");

5. Check the parameters

This step is not required

 if (!n.hasParam("my_param"))
 {
    
    
    ROS_INFO("No param named 'my_param'");
 }

6. Search parameters

For example: if the parameter server has a parameter of /a/b and your NodeHandle is in the /a/c workspace, searchParam() will get /a/b when searching for b. If the parameter of /a/c/b is increased, the search will get /a/c/b parameters. Examples are as follows:

 std::string param_name;
 if (n.searchParam("b", param_name))   {
    
         
 // Found parameter, can now query it using param_name     
 int i = 0;     
 n.getParam(param_name, i);   
 }   
 else   {
    
         
 ROS_INFO("No param 'b' found in an upward search");   
 }

2. Parameter setting method in launch

There are three types: param, rosparam, arg

Param

Set parameters in the launch file:

节点内:
< node name=“node_keyboard_control” pkg=“keyboardControl” type=“node_keyboard_control” output=“screen”>
< param name=“linear_min” value=“0.3” />
< /node>

全局:
< param name=“use_gui” value="$(arg gui)" />

snarled

Set parameters in the launch file:

< rosparam file=“param.yaml” command=“load”/>

arg

Used internally by launch, similar to the syntax in launch.

Set parameters in the launch file:

< arg name=“gui” default=“false” />
< param name=“use_gui” value="$(arg gui)" />
//一起使用

Three, dynamic parameters

Sometimes the parameters of ros alone cannot meet our work requirements. For example, when debugging the parameters of the robot, we hope to dynamically change the parameters to observe the corresponding response of the robot. So we next introduce the dynamic parameters in ros.
The dynamic parameters in ros are similar to topic publication and subscription forms. Once the dynamic parameter file is configured, we only need to subscribe to the corresponding parameters in the program.

Create configuration parameters

  • Create ros package

catkin_create_pkg dynamic_tutorials rospy roscpp dynamic_reconfigure

If you already have a functional package, you only need to add dynamic_reconfigure in CmakeList.txt and package.xml.

  • Create a cfg configuration file
    Create a folder cfg under the same level directory as the src of the function package, and add a file named my_cfg.cfg in cfg. Its content is:
#!/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)

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

It can be seen that it is implemented in python form, and the content of the configuration is briefly introduced below.

Create a parameter generator:

gen = ParameterGenerator()

Dynamic configuration parameters:

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)

The realization form of dynamic parameters : add(name, type, level, description, default, min, max).

  • name: the parameter name, which is described by a string;
  • type: defines the type of the parameter, which can be int_t, double_t, str_t, or bool_t;
  • level: Need to pass in parameters to dynamically configure the mask in the callback function. In the callback function, the mask of all parameters will be modified, indicating that the parameters have been modified;
  • description: a string describing the role of the parameter;
  • default: set the default value of the parameter;
  • min: Optional, set the minimum value of the parameter, it does not take effect for string and boolean values;
  • max: Optional, set the maximum value of the parameter, it does not take effect for string and boolean values;

The dynamic parameter realization form of enumeration type : 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)

Generate C++ and python related files and exit the program:

exit(gen.generate(PACKAGE, "dynamic_tutorials", "my_cfg"))
  • dynamic_tutorials: the name of the package
  • my_cfg: The name of the configuration file created (it may not be the name of the configuration file, but it must be consistent with the program), which is the header file that needs to be included in the program

Create server node

The server node, that is, the subscription node, the code is implemented as follows, see the notes for details:

#include <ros/ros.h>
#include <dynamic_reconfigure/server.h>//实现动态参数的头文件
#include <dynamic_tutorials/TutorialsConfig.h>//cfg生成的头文件

/****回调函数****/
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, "node_dy_param");

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

Increase the content of CmakeList.txt:

add_executable(node_dy_param src/main.cpp)
target_link_libraries(node_dy_param ${
    
    catkin_LIBRARIES})
add_dependencies(node_dy_param ${
    
    ${
    
    PROJECT_NAME}_EXPORTED_TARGETS} ${
    
    catkin_EXPORTED_TARGETS})
add_dependencies(node_dy_param ${
    
    PROJECT_NAME}_gencfg)

run

Start the subscriber node:

$ roscore
$ rosrun dynamic_tutorials node_dy_param

Run the publishing end node:

 rosrun rqt_reconfigure rqt_reconfigure

Guess you like

Origin blog.csdn.net/QLeelq/article/details/111060091