Dynamic parameters

Another utility in ROS is the Dynamic Reconfigure utility. Normally, when you are programming a new node, you initialize the variables with data that can only be changed within the node. If you want to change these values dynamically from outside the node, you can use Parameter Server, services, or topics. If you are working in a PID node to control a motor, for example, you should use the Dynamic Reconfigure utility.

In this section, you will learn how to configure a basic node with this feature. Add the necessary lines in the CMakeLists.txt and package.xml files.

To use Dynamic Reconfigure, you should write a configuration file and save it in the cfg folder in your package. Create the folder and a new file as follows:

    $ roscd chapter2_tutorials
    $ mkdir cfg
    $ vim chapter2.cfg  

Write the following code in the chapter2.cfg file:

#!/usr/bin/env python 
PACKAGE = "chapter2_tutorials" 
 
from dynamic_reconfigure.parameter_generator_catkin import * 
 
gen = ParameterGenerator() 
 
gen.add("double_param", double_t, 0, "A double parameter", .1, 0, 
1)gen.add("str_param", str_t, 0, "A string parameter",
"Chapter2_dynamic_reconfigure") gen.add("int_param", int_t, 0, "An Integer parameter", 1, 0, 100) gen.add("bool_param", bool_t, 0, "A Boolean parameter", True) size_enum = gen.enum([ gen.const("Low", int_t, 0, "Low is 0"), gen.const("Medium", int_t, 1, "Medium is 1"), gen.const("High", int_t, 2, "High is 2")], "Select from the list") gen.add("size", int_t, 0, "Select from the list", 1, 0, 3,
edit_method=size_enum) exit(gen.generate(PACKAGE, "chapter2_tutorials", "chapter2_"))

Let's explain the code. These lines initialize ROS and import the parameter generator:

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

The following line initializes the parameter generator, and thanks to that, we can start to add parameters in the following lines:

gen = ParameterGenerator() 
gen.add("double_param", double_t, 0, "A double parameter", .1, 0, 
1)gen.add("str_param", str_t, 0, "A string parameter",
"Chapter2_dynamic_reconfigure") gen.add("int_param", int_t, 0, "An Integer parameter", 1, 0, 100) gen.add("bool_param", bool_t, 0, "A Boolean parameter", True)

These lines add different parameter types and set the default values, description, range, and so on. The parameter has the following arguments:

gen.add(name, type, level, description, default, min, max) 
  • name: This is the name of the parameter
  • type: This is the type of the value stored
  • level: This is a bitmask that is passed to the callback
  • description: This is a short description of the parameter
  • default: This is the default value when the node starts
  • min: This is the minimum value for the parameter
  • max: This is the maximum value for the parameter

The names of the parameters must be unique, and the values have to be in the range and have min and max values:

exit(gen.generate(PACKAGE, "chapter2_tutorials", "chapter2_")) 

The last line generates the necessary files and exits the program. Notice that the .cfg file was written in Python. This section is for C++ snippets, but we will sometimes use Python snippets.

It is necessary to change the permissions for the file because the file will be executed by ROS. To make the file executable and runnable by any user, we will use the chmod command with the a+x parameter as follows:

    $ chmod a+x cfg/chapter2.cfg  

Open CMakeList.txt and add the following lines:

find_package(catkin REQUIRED COMPONENTS 
roscpp 
  std_msgs 
  message_generation 
  dynamic_reconfigure 
) 
 
generate_dynamic_reconfigure_options( 
  cfg/chapter2.cfg 
) 
 
add_dependencies(example4 chapter2_tutorials_gencfg) 

Now we are going to write our new node with Dynamic Reconfigure support. Create a new file in your src folder as follows:

    $ roscd chapter2_tutorials
    $ vim src/example4.cpp  

Write the following code snippet in the file:

#include <ros/ros.h> 
#include <dynamic_reconfigure/server.h> 
#include <chapter2_tutorials/chapter2Config.h> 
 
void callback(chapter2_tutorials::chapter2Config &amp;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, "example4_dynamic_reconfigure"); dynamic_reconfigure::Server<chapter2_tutorials::chapter2Config>
server; dynamic_reconfigure::Server<chapter2_tutorials::chapter2Config>::
CallbackType f; f = boost::bind(&amp;callback, _1, _2); server.setCallback(f); ros::spin(); return 0; }

Let's explain the code and note the important lines. As usual, these lines include the headers for ROS, Parameter Server, and our config file created earlier:

#include <ros/ros.h> 
#include <dynamic_reconfigure/server.h> 
#include <chapter2_tutorials/chapter2Config.h> 

The callback function will print the new values for the parameters. The way to access the parameters is, for example, config.int_param. The name of the parameter must be the same as the one that you configured in the example2.cfg file:

void callback(chapter2_tutorials::chapter2Config &amp;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); }

To continue, the server is initialized in the line where we pass the chapter2_Config configuration file:

dynamic_reconfigure::Server<chapter2_tutorials::chapter2Config> 
server;dynamic_reconfigure::Server<chapter2_tutorials::chapter2Config>::
CallbackType f; f = boost::bind(&amp;callback, _1, _2); server.setCallback(f);

Now we send the callback function to the server. When the server gets a reconfiguration request, it will call the callback function.

Once we are done with the explanation, we need to add lines to the CMakeLists.txt file as follows:

add_executable(example4 src/example4.cpp) 
 
add_dependencies(example4 chapter2_tutorials_gencfg) 
 
target_link_libraries(example4 ${catkin_LIBRARIES}) 

Now you have to compile and run the node and the Dynamic Reconfigure GUI as follows:

    $ roscore
    $ rosrun chapter2_tutorials example4
    $ rosrun rqt_reconfigure rqt_reconfigure  

When you execute the last command, you will see a new window where you can dynamically modify the parameters of the node, as shown in the following screenshot:

Each time you modify a parameter with the slider, the checkbox, and so on, you will see the changes made in the shell where the node is running. You can see an example in the following screenshot:

Thanks to Dynamic Reconfigure, you can program and test your nodes more efficiently and faster. Using the program with hardware is a good choice and you will learn more about it in the following chapters.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.102.182