Package dynamic_reconfigure :: Module encoding

Source Code for Module dynamic_reconfigure.encoding

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2009, Willow Garage, Inc. 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Willow Garage, Inc. nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  try: 
 34      import roslib; roslib.load_manifest('dynamic_reconfigure') 
 35  except: 
 36      pass 
 37  import rospy 
 38  import inspect 
 39  import copy 
 40  import sys 
 41   
 42  from dynamic_reconfigure.msg import Config as ConfigMsg 
 43  from dynamic_reconfigure.msg import ConfigDescription as ConfigDescrMsg 
 44  from dynamic_reconfigure.msg import Group as GroupMsg 
 45  from dynamic_reconfigure.msg import GroupState 
 46  from dynamic_reconfigure.msg import IntParameter, BoolParameter, StrParameter, DoubleParameter, ParamDescription 
 47   
48 -class Config(dict):
49 - def __init__(self, *args, **kwargs):
50 dict.__init__(self, *args, **kwargs)
51
52 - def __getstate__(self):
53 return self.__dict__.items()
54
55 - def __setstate__(self, items):
56 for key, val in items: 57 self.__dict__[key] = val
58
59 - def __repr__(self):
60 return super(Config, self).__repr__()
61
62 - def __setitem__(self, key, value):
63 return super(Config, self).__setitem__(key, value)
64
65 - def __getitem__(self, name):
66 return super(Config, self).__getitem__(name)
67
68 - def __delitem__(self, name):
69 return super(Config, self).__delitem__(name)
70 71 __getattr__ = __getitem__ 72 __setattr__ = __setitem__ 73
74 - def copy(self):
75 return Config(self)
76
77 - def __deepcopy__(self, memo):
78 c = type(self)({}) 79 for key, value in self.iteritems(): 80 c[copy.deepcopy(key)] = copy.deepcopy(value) 81 82 return c
83 84
85 -def encode_description(descr):
86 msg = ConfigDescrMsg() 87 msg.max = encode_config(descr.max) 88 msg.min = encode_config(descr.min) 89 msg.dflt = encode_config(descr.defaults) 90 msg.groups = encode_groups(None, descr.config_description) 91 return msg
92
93 -def encode_groups(parent, group):
94 group_list = [] 95 96 msg = GroupMsg() 97 98 msg.name = group['name'] 99 msg.id = group['id'] 100 msg.parent = group['parent'] 101 msg.type = group['type'] 102 103 for param in group['parameters']: 104 msg.parameters.append(ParamDescription(param['name'], param['type'], param['level'], param['description'], param['edit_method'])) 105 106 group_list.append(msg) 107 for next in group['groups']: 108 group_list.extend(encode_groups(msg, next)) 109 110 return group_list
111
112 -def encode_config(config, flat=True):
113 msg = ConfigMsg() 114 for k, v in config.items(): 115 ## @todo add more checks here? 116 if type(v) == int: msg.ints.append(IntParameter(k, v)) 117 elif type(v) == bool: msg.bools.append(BoolParameter(k, v)) 118 elif type(v) == str: msg.strs.append(StrParameter(k, v)) 119 elif sys.version_info.major < 3 and type(v) == unicode: 120 msg.strs.append(StrParameter(k, v)) 121 elif type(v) == float: msg.doubles.append(DoubleParameter(k, v)) 122 elif type(v) == dict or isinstance(v, Config): 123 if flat is True: 124 def flatten(g): 125 groups = [] 126 for name, group in g['groups'].items(): 127 groups.extend(flatten(group)) 128 groups.append(GroupState(group['name'], group['state'], group['id'], group['parent'])) 129 return groups
130 msg.groups.append(GroupState(v['name'], v['state'], v['id'], v['parent'])) 131 msg.groups.extend(flatten(v)) 132 else: 133 msg.groups = [GroupState(x['name'], x['state'], x['id'], x['parent']) for x in v] 134 135 return msg 136
137 -def group_dict(group):
138 try: 139 state = group.state 140 except AttributeError: 141 state = True 142 if hasattr(group, 'type'): 143 type = group.type 144 else: 145 type ='' 146 return Config({ 147 'id' : group.id, 148 'parent' : group.parent, 149 'name' : group.name, 150 'type' : type, 151 'state': state, 152 'groups' : Config({}), 153 'parameters' : Config({}), 154 })
155
156 -def decode_description(msg):
157 mins = decode_config(msg.min) 158 maxes = decode_config(msg.max) 159 defaults = decode_config(msg.dflt) 160 groups = {} 161 grouplist = msg.groups 162 163 def params_from_msg(msg): 164 params = [] 165 for param in msg.parameters: 166 name = param.name 167 params.append({ 168 'name': name, 169 'min' : mins[name], 170 'max' : maxes[name], 171 'default' : defaults[name], 172 'type' : param.type, 173 'level': param.level, 174 'description' : param.description, 175 'edit_method' : param.edit_method, 176 }) 177 return params
178 179 # grab the default group 180 for group in grouplist: 181 if group.id == 0: 182 groups = group_dict(group) 183 groups['parameters'] = params_from_msg(group) 184 185 def build_tree(group): 186 children = Config({}) 187 for g in grouplist: 188 if g.id == 0: 189 pass 190 elif g.parent == group['id']: 191 gd = group_dict(g) 192 193 gd['parameters'] = params_from_msg(g) 194 gd['groups'] = build_tree(gd) 195 # add the dictionary into the tree 196 children[gd['name']] = gd 197 return children 198 199 groups['groups'] = build_tree(groups) 200 201 return groups 202
203 -def get_tree(m, group = None):
204 if group is None: 205 for x in m.groups: 206 if x.id == 0: 207 group = x 208 209 children = Config({}) 210 for g in m.groups: 211 if g.id == 0: 212 pass 213 elif g.parent == group.id: 214 gd = group_dict(g) 215 216 gd['groups'] = get_tree(m, g) 217 children[gd['name']] = gd 218 219 if group.id == 0: 220 ret = group_dict(group) 221 ret['groups'] = children 222 return ret 223 else: 224 return children
225
226 -def initial_config(msg, description = None):
227 d = Config([(kv.name, kv.value) for kv in msg.bools + msg.ints + msg.strs + msg.doubles]) 228 def gt(m, descr, group = None): 229 # get the default group 230 if group is None: 231 for x in m.groups: 232 if x.id == 0: 233 group = x 234 235 children = Config({}) 236 for g in m.groups: 237 if g.id == 0: 238 pass 239 elif g.parent == group.id: 240 gd = group_dict(g) 241 242 def find_state(gr, dr): 243 for g in dr['groups']: 244 if g['id'] == gr['id']: 245 gr['state'] = g['state'] 246 return 247 else: 248 find_state(gr, g) 249 return
250 251 find_state(gd, descr) 252 253 # Get the tree for this group 254 gd['groups'] = gt(m, descr, g) 255 children[gd['name']] = gd 256 257 if group.id == 0: 258 ret = group_dict(group) 259 ret['groups'] = children 260 return ret 261 else: 262 return children 263 264 if not msg.groups == [] and description is not None: 265 d["groups"] = gt(msg, description) 266 267 def add_params(group, descr): 268 for param in descr['parameters']: 269 group['parameters'][param['name']] = d[param['name']] 270 for n, g in group['groups'].items(): 271 for dr in descr['groups']: 272 if dr['name'] == g['name']: 273 add_params(g, dr) 274 275 add_params(d['groups'], description) 276 277 return d 278
279 -def decode_config(msg, description = None):
280 if sys.version_info.major < 3: 281 for s in msg.strs: 282 if not isinstance(s.value, unicode): 283 try: 284 s.value.decode('ascii') 285 except UnicodeDecodeError: 286 s.value = s.value.decode('utf-8') 287 288 d = Config([(kv.name, kv.value) for kv in msg.bools + msg.ints + msg.strs + msg.doubles]) 289 if not msg.groups == [] and description is not None: 290 d["groups"] = get_tree(msg) 291 292 def add_params(group, descr): 293 for param in descr['parameters']: 294 if param['name'] in d.keys(): 295 group[param['name']] = d[param['name']] 296 for n, g in group['groups'].items(): 297 for nr, dr in descr['groups'].items(): 298 if dr['name'] == g['name']: 299 add_params(g, dr)
300 301 add_params(d['groups'], description) 302 303 return d 304
305 -def extract_params(group):
306 params = [] 307 params.extend(group['parameters']) 308 try: 309 for n,g in group['groups'].items(): 310 params.extend(extract_params(g)) 311 except AttributeError: 312 for g in group['groups']: 313 params.extend(extract_params(g)) 314 return params
315
316 -def get_parents(group, descriptions):
317 parents = [] 318 for p in descriptions['group']: 319 if p['id'] == group['parent']: 320 parents.extend(get_parents(p, descriptions)) 321 parents.append(p) 322 return parents
323