ROS has a cool mechanism called Dynamic Reconfigure where parameters of nodes can be set
at runtime. The concept is explained here. Sometimes you want to change
these parameters from your code. There is a supported python API to do this but there is no API for C/C++ yet.
After some research I found a good thread on the ROS forum here explaining how it is possible use dynamic reconfigure from C++ code in ROS.
Based on that thread I got the dynamic reconfigure working. I wrote this blogpost to take you through the steps needed. Hope this helps you.
In my case, the reason I needed this was that our project is using ar_track_alvar to scan for AR tags. However, this uses a tremendous amount of CPU so I want to be able to switch if off when it's not needed. Alternatively, and arguably better, I could have also modified the ar_track_alvar package when nobody is subscribed to any of the topics. Maybe I'll look into that sometime. But for now, let's dive in.
Nodes that support dynamic reconfigure have a ros service that allows one to set it. Via the command
We will be invoking this service via C++.
If we run the command
Node: /ar_track_alvar
URI: rosrpc://ubuntu:42524
Type: dynamic_reconfigure/Reconfigure
Args: config
The argument that we can pass to this service is called 'config'. This is parameter of type
The first is of type
To find out the parameters that you can set, you can simply look at the content of the topic /ar_track_alvar/parameter_updates via the command
Here we can see the boolean parameter 'enabled' that we need to set. Now we have all the information needed to write the code. This is actually pretty straightforward. As we need to set a boolean parameter we use the include file BoolParameter.h. There are corresponding include files for the other elementary data types (IntParameter.h, DoubleParameter.h, etc).
Alright, that's it folks. Hope this was of use!
GUI for dynamic reconfigure which can be launched via rosrun rqt_reconfigure rqt_reconfigure |
After some research I found a good thread on the ROS forum here explaining how it is possible use dynamic reconfigure from C++ code in ROS.
Based on that thread I got the dynamic reconfigure working. I wrote this blogpost to take you through the steps needed. Hope this helps you.
In my case, the reason I needed this was that our project is using ar_track_alvar to scan for AR tags. However, this uses a tremendous amount of CPU so I want to be able to switch if off when it's not needed. Alternatively, and arguably better, I could have also modified the ar_track_alvar package when nobody is subscribed to any of the topics. Maybe I'll look into that sometime. But for now, let's dive in.
Nodes that support dynamic reconfigure have a ros service that allows one to set it. Via the command
rosservice list
you can get a list of those services.
In my case it revealed the service that I needed:/ar_track_alver/set_parameters
We will be invoking this service via C++.
If we run the command
rosservice info /ar_track_alvar/set_parameters
we can see
information about this service:Node: /ar_track_alvar
URI: rosrpc://ubuntu:42524
Type: dynamic_reconfigure/Reconfigure
Args: config
The argument that we can pass to this service is called 'config'. This is parameter of type
dynamic_reconfigure::Config
and contains all the parameters that the node
allows to be set. To find out more about its internal structure we can look at some
of the topics published. Via rostopic list
we can quickly find out that
there are 2 interesting topics that we can look at:
/ar_track_alvar/parameter_descriptions
/ar_track_alvar/parameter_updates
The first is of type
dynamic_reconfigure/ConfigDescription
and the
latter is of type dynamic_reconfigure/Config
.To find out the parameters that you can set, you can simply look at the content of the topic /ar_track_alvar/parameter_updates via the command
rostopic echo /ar_track_alvar/parameter_updates
.
For this node, the output will look like:
bools:
-
name: enabled
value: True
ints: []
strs: []
doubles:
-
name: max_frequency
value: 10.0
-
name: marker_size
value: 5.5
-
name: max_new_marker_error
value: 0.05
-
name: max_track_error
value: 0.05
groups:
-
name: Default
state: True
id: 0
parent: 0
Here we can see the boolean parameter 'enabled' that we need to set. Now we have all the information needed to write the code. This is actually pretty straightforward. As we need to set a boolean parameter we use the include file BoolParameter.h. There are corresponding include files for the other elementary data types (IntParameter.h, DoubleParameter.h, etc).
#include <dynamic_reconfigure/BoolParameter.h>
#include <dynamic_reconfigure/Reconfigure.h>
#include <dynamic_reconfigure/Config.h>
.
.
.
void ApproachMarker::EnableArTrackAlvar(bool enable) {
dynamic_reconfigure::ReconfigureRequest srv_req;
dynamic_reconfigure::ReconfigureResponse srv_resp;
dynamic_reconfigure::BoolParameter enable_param;
dynamic_reconfigure::Config conf;
enable_param.name = "enabled";
enable_param.value = enable;
conf.bools.push_back(enable_param);
srv_req.config = conf;
if (ros::service::call("/ar_track_alvar/set_parameters", srv_req, srv_resp)) {
ROS_INFO("call to set ar_track_alvar parameters succeeded");
} else {
ROS_INFO("call to set ar_track_alvar parameters failed");
}
}
Alright, that's it folks. Hope this was of use!