My current hacky and likely very brittle solution is to create the python dynamic reconfigure module at runtime that is normally created at compile time.
This shows the creation of the Config.py module and a dynamic reconfigure server from it:
https://github.com/lucasw/dynamic_rec...
It requires rosparams to exist in a certain format on the same namespace.
And an application specific example that creates the params is at https://github.com/lucasw/v4l2ucp/blo...
Because the node in control of the hardware is in C++, it can't use the python reconfigure server, so there is an intermediary layer of regular ros topics to communicate from the dr server to C++ node.
The params look like:
/controls/Brightness
/controls/Brightness_max
/controls/Brightness_min
/controls/Brightness_type
/controls/Contrast
/controls/Contrast_max
/controls/Contrast_min
/controls/Contrast_type
...
(_default
for each control would be a good addition.)
The standard generated python object looks like devel/lib/python2.7/dist-packages/screen_grab/cfg/ExampleConfig.py
:
from dynamic_reconfigure.encoding import extract_params
inf = float('inf')
config_description = {'upper': 'DEFAULT', 'lower': 'groups', 'srcline': 235, 'name': 'Default', 'parent': 0, 'srcfile': '/opt/ros/jade/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'cstate': 'true', 'parentname': 'Default', 'class': 'DEFAULT', 'field': 'default', 'state': True, 'parentclass': '', 'groups': [], 'parameters': [{'srcline': 280, 'description': 'x offset', 'max': 2048, 'cconsttype': 'const int', 'ctype': 'int', 'srcfile': '/opt/ros/jade/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'x_offset', 'edit_method': '', 'default': 0, 'level': 1, 'min': 0, 'type': 'int'},
...
min = {}
max = {}
defaults = {}
level = {}
type = {}
all_level = 0
for param in extract_params(config_description):
min[param['name']] = param['min']
max[param['name']] = param['max']
defaults[param['name']] = param['default']
level[param['name']] = param['level']
type[param['name']] = param['type']
all_level = all_level | param['level']
So if that format changes it would break my system. But likely I could generate an actual cfg and generate the python Config file at run time, and this would make the code more future proof. (just need to see what the Config.py generation commands are)
Can I change the min and max values or add new controls during execution? Maybe but rqt_reconfigure would probably have to be refreshed to see them.
I don't think this is possible for C++, for that the only solution may be dynamic reconfigure itself ought to change so there is an api to create any control prior to setting up the server.
https://github.com/lucasw/dynamic_rec... https://github.com/lucasw/v4l2ucp
Update
I haven't looked at this in detail at this 'dynamic dynamic reconfigure' solution, it may be doing something similar to my code or perhaps has a more robust approach:
https://github.com/pal-robotics/ddyna...
https://github.com/ros/dynamic_reconf...
https://vimeo.com/187699289
Did you find a solution to this?
Not using the dynamic reconfigure. In one project ( https://github.com/lucasw/v4l2ucp ) I set up a bunch of subscribers with rosparams to define their type, min and max, and the publisher goes through the rosparams and creates rqt controls for each- it isn't finished yet though.
Ok thanks! I'll have a look at it.