ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

This is exactly an example of what I was talking. Thanks joq. Just notice that two different node have to be created with different subnames.

bool configure_server_callback_a(mypkg::myconfig &config, uint32_t level)
{
  return config;
}

bool configure_server_callback_b(mypkg::myconfig &config, uint32_t level)
{
  return config;
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "test_multiple_configure");

  ros::NodeHandle nh_a("~/a");
  ros::NodeHandle nh_b("~/b");

  dynamic_reconfigure::Server<mypkg::myconfig> cfg_server_a(nh_a);
  dynamic_reconfigure::Server<mypkg::myconfig> cfg_server_b(nh_b);

  dynamic_reconfigure::Server<mypkg::myconfig>::CallbackType f_a, f_b;
  f_a = boost::bind(configure_server_callback_a, _1, _2);
  f_b = boost::bind(configure_server_callback_a, _1, _2);

  cfg_server_a.setCallback(f_a);
  cfg_server_b.setCallback(f_b);

  ros::spin();
}

This is exactly an example of what I was talking. Thanks joq. Just notice that two different node have to be created with different subnames.

Thanks. I show a example code below. In any case IHMO it is worthnote that multiple does not seem possible in python because the dynamic_reconfigure server implementation. See $ head -70 rospack find dynamic_reconfigure/src/dynamic_reconfigure/server.py

bool configure_server_callback_a(mypkg::myconfig &config, uint32_t level)
{
  return config;
}

bool configure_server_callback_b(mypkg::myconfig &config, uint32_t level)
{
  return config;
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "test_multiple_configure");

  ros::NodeHandle nh_a("~/a");
  ros::NodeHandle nh_b("~/b");

  dynamic_reconfigure::Server<mypkg::myconfig> cfg_server_a(nh_a);
  dynamic_reconfigure::Server<mypkg::myconfig> cfg_server_b(nh_b);

  dynamic_reconfigure::Server<mypkg::myconfig>::CallbackType f_a, f_b;
  f_a = boost::bind(configure_server_callback_a, _1, _2);
  f_b = boost::bind(configure_server_callback_a, _1, _2);

  cfg_server_a.setCallback(f_a);
  cfg_server_b.setCallback(f_b);

  ros::spin();
}

This is exactly an example of what I was talking. Thanks joq. Just notice that two different node have to be created with different subnames.

Thanks. I show a example code below. In any case IHMO it is worthnote that multiple does not seem possible in python because the dynamic_reconfigure server implementation. See

$ head -70 rospack `rospack find dynamic_reconfigure/src/dynamic_reconfigure/server.pydynamic_reconfigure`/src/dynamic_reconfigure/server.py

I propose a patch at the end of this response with some modification on this file to achieve this feature.

I show a example code below about how could be done it with C++.

bool configure_server_callback_a(mypkg::myconfig &config, uint32_t level)
{
  return config;
}

bool configure_server_callback_b(mypkg::myconfig &config, uint32_t level)
{
  return config;
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "test_multiple_configure");

  ros::NodeHandle nh_a("~/a");
  ros::NodeHandle nh_b("~/b");

  dynamic_reconfigure::Server<mypkg::myconfig> cfg_server_a(nh_a);
  dynamic_reconfigure::Server<mypkg::myconfig> cfg_server_b(nh_b);

  dynamic_reconfigure::Server<mypkg::myconfig>::CallbackType f_a, f_b;
  f_a = boost::bind(configure_server_callback_a, _1, _2);
  f_b = boost::bind(configure_server_callback_a, _1, _2);

  cfg_server_a.setCallback(f_a);
  cfg_server_b.setCallback(f_b);

  ros::spin();
}

To have multiple dynamic_reconfigure servers on the same node I propose the following patch for the dynamic_reconfigure source:

--- a/src/dynamic_reconfigure/server.py Sun Jan 15 19:33:19 2012 -0800
+++ b/src/dynamic_reconfigure/server.py Thu Aug 16 14:06:26 2012 +0200
@@ -51,7 +51,7 @@
 from dynamic_reconfigure.encoding import *

 class Server(object):
-    def __init__(self, type, callback):
+     def __init__(self, type, callback,namespace_prefix=""):
         self.mutex = threading.Lock()
         self.type = type
         self.config = type.defaults.copy()
@@ -61,17 +61,19 @@
         self.callback = callback
         self._clamp(self.config) 

+   self.namespace_prefix=("~/"+namespace_prefix+'/').replace('//','/')
+
         # setup group defaults
         self.config['groups'] = get_tree(self.description)
         self.config = initial_config(encode_config(self.config), type.config_description)

-        self.descr_topic = rospy.Publisher('~parameter_descriptions', ConfigDescrMsg, latch=True)
+        self.descr_topic = rospy.Publisher(self.namespace_prefix+'parameter_descriptions', ConfigDescrMsg, latch=True)
         self.descr_topic.publish(self.description);
-        
-        self.update_topic = rospy.Publisher('~parameter_updates', ConfigMsg, latch=True)
+
+        self.update_topic = rospy.Publisher(self.namespace_prefix+'parameter_updates', ConfigMsg, latch=True)
         self._change_config(self.config, type.all_level)

-        self.set_service = rospy.Service('~set_parameters', ReconfigureSrv, self._set_callback)
+        self.set_service = rospy.Service(self.namespace_prefix+'set_parameters', ReconfigureSrv, self._set_callback)

     def update_configuration(self, changes):
         with self.mutex:
@@ -89,7 +91,7 @@

     def _copy_to_parameter_server(self):
         for param in extract_params(self.type.config_description):
-            rospy.set_param('~' + param['name'], self.config[param['name']])
+            rospy.set_param(self.namespace_prefix+ param['name'], self.config[param['name']])

     def _change_config(self, config, level):
         self.config = self.callback(config, level)