[Documentation] [TitleIndex] [WordIndex

Basic Setup

To begin lets create a package called dynamic_tutorials which depends on rospy, roscpp and dynamic_reconfigure.

catkin_create_pkg --rosdistro ROSDISTRO dynamic_tutorials rospy roscpp dynamic_reconfigure

Where ROSDISTRO is the ROS distribution you are using.

Now in your package create a cfg directory, this is where all cfg files live:

mkdir cfg

Lastly you will need to create a cfg file, for this example we'll call it Tutorials.cfg, and open it in your favorite editor.

The cfg File

Add the following to your Tutorials.cfg file:

   1 #!/usr/bin/env python
   2 PACKAGE = "dynamic_tutorials"
   3 
   4 from dynamic_reconfigure.parameter_generator_catkin import *
   5 
   6 gen = ParameterGenerator()
   7 
   8 gen.add("int_param",    int_t,    0, "An Integer parameter", 50,  0, 100)
   9 gen.add("double_param", double_t, 0, "A double parameter",    .5, 0,   1)
  10 gen.add("str_param",    str_t,    0, "A string parameter",  "Hello World")
  11 gen.add("bool_param",   bool_t,   0, "A Boolean parameter",  True)
  12 
  13 size_enum = gen.enum([ gen.const("Small",      int_t, 0, "A small constant"),
  14                        gen.const("Medium",     int_t, 1, "A medium constant"),
  15                        gen.const("Large",      int_t, 2, "A large constant"),
  16                        gen.const("ExtraLarge", int_t, 3, "An extra large constant")],
  17                      "An enum to set size")
  18 
  19 gen.add("size", int_t, 0, "A size parameter which is edited via an enum", 1, 0, 3, edit_method=size_enum)
  20 
  21 exit(gen.generate(PACKAGE, "dynamic_tutorials", "Tutorials"))

Now lets break the code down line by line.

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

This first lines are pretty simple, they just initialize ros and import the parameter generator.

   6 gen = ParameterGenerator()

Now that we have a generator we can start to define parameters. The add function adds a parameter to the list of parameters. It takes a few different arguments:

   8 gen.add("int_param",    int_t,    0, "An Integer parameter", 50,  0, 100)
   9 gen.add("double_param", double_t, 0, "A double parameter",    .5, 0,   1)
  10 gen.add("str_param",    str_t,    0, "A string parameter",  "Hello World")
  11 gen.add("bool_param",   bool_t,   0, "A Boolean parameter",  True)

These lines simply define more parameters of the different types.

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

Here we define an integer whose value is set by an enum. To do this we call gen.enum and pass it a list of constants followed by a description of the enum. Now that we have created an enum we can now pass it to the generator. Now the param can be set with "Small" or "Medium" rather than 0 or 1.

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

The last line simply tells the generator to generate the necessary files and exit the program. The second parameter is the name of a node this could run in (used to generate documentation only), the third parameter is a name prefix the generated files will get (e.g. "<name>Config.h" for c++, or "<name>Config.py" for python.


NOTE: The third parameter should be equal to the cfg file name, without extension. Otherwise the libraries will be generated in every build, forcing a recompilation of the nodes which use them.


Use the cfg File

In order to make this cfg file usable it must be executable, so lets use the following command to make it excecutable

chmod a+x cfg/Tutorials.cfg

Next we need to add the following lines to our CMakeLists.txt. For Groovy and above

#add dynamic reconfigure api
#find_package(catkin REQUIRED dynamic_reconfigure)
generate_dynamic_reconfigure_options(
  cfg/Tutorials.cfg
  #...
)

# make sure configure headers are built before any node using them
add_dependencies(example_node ${PROJECT_NAME}_gencfg)

Note that you need a node example_node that is already built, before the add_dependencies line is reached (ref Create a node in C++).

This will run our cfg when the package is built. The last thing to do is to build the package and we're done!


2024-11-09 14:28