1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 """
34 Python client API for dynamic_reconfigure (L{DynamicReconfigureClient}) as well as
35 example server implementation (L{DynamicReconfigureServer}).
36 """
37
38 from __future__ import with_statement
39
40 try:
41 import roslib; roslib.load_manifest('dynamic_reconfigure')
42 except Exception:
43 pass
44 import rospy
45 import threading
46 import copy
47
48 from dynamic_reconfigure import DynamicReconfigureCallbackException
49 from dynamic_reconfigure.encoding import decode_config, encode_config, encode_description, extract_params, get_tree, initial_config
50 from dynamic_reconfigure.msg import Config as ConfigMsg
51 from dynamic_reconfigure.msg import ConfigDescription as ConfigDescrMsg
52 from dynamic_reconfigure.srv import Reconfigure as ReconfigureSrv
53
54
56 - def __init__(self, type, callback, namespace=""):
57 self.mutex = threading.Lock()
58 if not namespace:
59 self.ns = "~"
60 else:
61 if namespace[0] not in ["/", "~"]:
62 namespace = "~" + namespace
63 self.ns = (namespace + "/").replace("//", "/")
64
65 self.type = type
66 self.config = type.defaults.copy()
67
68 self.description = encode_description(type)
69 self._copy_from_parameter_server()
70 self.callback = callback
71 self._clamp(self.config)
72
73
74 self.config['groups'] = get_tree(self.description)
75 self.config = initial_config(encode_config(self.config), type.config_description)
76
77 self.descr_topic = rospy.Publisher(self.ns + 'parameter_descriptions', ConfigDescrMsg, latch=True, queue_size=10)
78 self.descr_topic.publish(self.description)
79
80 self.update_topic = rospy.Publisher(self.ns + 'parameter_updates', ConfigMsg, latch=True, queue_size=10)
81 self._change_config(self.config, ~0)
82
83 self.set_service = rospy.Service(self.ns + 'set_parameters', ReconfigureSrv, self._set_callback)
84
86 with self.mutex:
87 new_config = copy.deepcopy(self.config)
88 new_config.update(changes)
89 self._clamp(new_config)
90 return self._change_config(new_config, self._calc_level(new_config, self.config))
91
93 for param in extract_params(self.type.config_description):
94 try:
95 self.config[param['name']] = rospy.get_param(self.ns + param['name'])
96 except KeyError:
97 pass
98
100 for param in extract_params(self.type.config_description):
101 rospy.set_param(self.ns + param['name'], self.config[param['name']])
102
104 self.config = self.callback(config, level)
105 if self.config is None:
106 msg = 'Reconfigure callback should return a possibly updated configuration.'
107 rospy.logerr(msg)
108 raise DynamicReconfigureCallbackException(msg)
109
110 self._copy_to_parameter_server()
111
112 self.update_topic.publish(encode_config(self.config))
113
114 return self.config
115
117 level = 0
118 for param in extract_params(self.type.config_description):
119 if config1[param['name']] != config2[param['name']]:
120 level |= param['level']
121
122 return level
123
125 for param in extract_params(self.type.config_description):
126 maxval = self.type.max[param['name']]
127 minval = self.type.min[param['name']]
128 val = config[param['name']]
129 if val > maxval and maxval != "":
130 config[param['name']] = maxval
131 elif val < minval and minval != "":
132 config[param['name']] = minval
133
136