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  import roslib; roslib.load_manifest('dynamic_reconfigure') 
 34  import rospy 
 35  import inspect 
 36   
 37  from dynamic_reconfigure.msg import Config as ConfigMsg 
 38  from dynamic_reconfigure.msg import ConfigDescription as ConfigDescrMsg 
 39  from dynamic_reconfigure.msg import Group as GroupMsg 
 40  from dynamic_reconfigure.msg import GroupState 
 41  from dynamic_reconfigure.msg import IntParameter, BoolParameter, StrParameter, DoubleParameter, ParamDescription 
 42   
 43  # Wrapper object for the config dictionary 
44 -class Config:
45 - def __init__(self, **args):
46 for k, v in args.items(): 47 if type(v) is dict: 48 self.__dict__[k] = Config(**v) 49 elif type(v) is list: 50 for d in v: 51 if type(d) is dict: 52 self.__dict__[d['name']] = Config(**d) 53 else: 54 self.__dict__[k] = v
55 56 # Preserve backwards compatibility by allowing dictionary style lookup
57 - def __getitem__(self, key):
58 if not type(key) is str: 59 raise TypeError 60 elif key == "groups": 61 groups = [] 62 for k,v in self.items(): 63 if isinstance(v, Config): 64 groups.append(v) 65 return groups 66 elif not key in self.__dict__: 67 raise KeyError 68 else: 69 return self.__dict__[key]
70
71 - def __setitem__(self, key, value):
72 if not type(key) is str: 73 raise TypeError 74 else: 75 if type(value) is dict: 76 self.__dict__[key] = Config(**value) 77 elif isinstance(value, Config): 78 self.__dict__[key] = value 79 elif type(value) is list: 80 for d in value: 81 if type(d) is dict: 82 self.__dict__[d['name']] = Config(**d) 83 else: 84 self.__dict__[key] = value 85 self.__setparam__(key, value)
86
87 - def __setparam__(self, name, value):
88 for k, v in self.items(): 89 if name == k: 90 self.__dict__[name] = value 91 elif isinstance(v, Config): 92 v.__setparam__(name, value)
93
94 - def __repr__(self):
95 return repr(self.__dict__)
96
97 - def update(self, *args):
98 for set in args: 99 try: 100 for k,v in set.items(): 101 self[k] = v 102 except Exception as exc: 103 raise exc
104 105 # TODO:Implement proper form of items
106 - def items(self):
107 return self.__dict__.items()
108
109 -def encode_description(descr):
110 msg = ConfigDescrMsg() 111 msg.max = encode_config(descr.max) 112 msg.min = encode_config(descr.min) 113 msg.dflt = encode_config(descr.defaults) 114 msg.groups = encode_groups(None, descr.config_description) 115 return msg
116
117 -def encode_groups(parent, group):
118 group_list = [] 119 120 msg = GroupMsg() 121 122 msg.name = group['name'] 123 msg.id = group['id'] 124 msg.parent = group['parent'] 125 msg.type = group['type'] 126 127 for param in group['parameters']: 128 msg.parameters.append(ParamDescription(param['name'], param['type'], param['level'], param['description'], param['edit_method'])) 129 130 group_list.append(msg) 131 for next in group['groups']: 132 group_list.extend(encode_groups(msg, next)) 133 134 return group_list
135
136 -def encode_config(config, flat=True):
137 msg = ConfigMsg() 138 for k, v in config.items(): 139 ## @todo add more checks here? 140 if type(v) == int: msg.ints.append(IntParameter(k, v)) 141 elif type(v) == bool: msg.bools.append(BoolParameter(k, v)) 142 elif type(v) == str: msg.strs.append(StrParameter(k, v)) 143 elif type(v) == float: msg.doubles.append(DoubleParameter(k, v)) 144 elif type(v) == dict or type(v) == list or isinstance(v, Config): 145 if flat is True: 146 def flatten(g): 147 groups = [] 148 for x in g['groups']: 149 groups.extend(flatten(x)) 150 groups.append(GroupState(x['name'], x['state'], x['id'], x['parent'])) 151 return groups
152 msg.groups.append(GroupState(v['name'], v['state'], v['id'], v['parent'])) 153 msg.groups.extend(flatten(v)) 154 else: 155 msg.groups = [GroupState(x['name'], x['state'], x['id'], x['parent']) for x in v] 156 157 return msg 158
159 -def group_dict(group):
160 try: 161 state = group.state 162 except AttributeError: 163 state = True 164 if hasattr(group, 'type'): 165 type = group.type 166 else: 167 type ='' 168 return { 169 'id' : group.id, 170 'parent' : group.parent, 171 'name' : group.name, 172 'type' : type, 173 'state': state, 174 'groups' : [], 175 'parameters' : [], 176 }
177
178 -def decode_description(msg):
179 mins = decode_config(msg.min) 180 maxes = decode_config(msg.max) 181 defaults = decode_config(msg.dflt) 182 groups = {} 183 grouplist = msg.groups 184 185 def params_from_msg(msg): 186 params = [] 187 for param in msg.parameters: 188 name = param.name 189 params.append({ 190 'name': name, 191 'min' : mins[name], 192 'max' : maxes[name], 193 'default' : defaults[name], 194 'type' : param.type, 195 'description' : param.description, 196 'edit_method' : param.edit_method, 197 }) 198 return params
199 200 # grab the default group 201 for group in grouplist: 202 if group.id == 0: 203 groups = group_dict(group) 204 groups['parameters'] = params_from_msg(group) 205 206 def build_tree(group): 207 children = [] 208 for g in grouplist: 209 if g.id == 0: 210 pass 211 elif g.parent == group['id']: 212 gd = group_dict(g) 213 214 gd['parameters'] = params_from_msg(g) 215 gd['groups'].extend(build_tree(gd)) 216 # add the dictionary into the tree 217 children.append(gd) 218 return children 219 220 groups['groups'].extend(build_tree(groups)) 221 222 return groups 223
224 -def get_tree(m, group = None):
225 if group is None: 226 for x in m.groups: 227 if x.id == 0: 228 group = x 229 230 children = [] 231 for g in m.groups: 232 if g.id == 0: 233 pass 234 elif g.parent == group.id: 235 gd = group_dict(g) 236 237 gd['groups'] = get_tree(m, g) 238 children.append(gd) 239 240 if group.id == 0: 241 ret = group_dict(group) 242 ret['groups'] = children 243 return ret 244 else: 245 return children
246
247 -def initial_config(msg, description = None):
248 d = dict([(kv.name, kv.value) for kv in msg.bools + msg.ints + msg.strs + msg.doubles]) 249 def gt(m, descr, group = None): 250 if group is None: 251 for x in m.groups: 252 if x.id == 0: 253 group = x 254 255 children = [] 256 for g in m.groups: 257 if g.id == 0: 258 pass 259 elif g.parent == group.id: 260 gd = group_dict(g) 261 262 def find_state(gr, dr): 263 for g in dr['groups']: 264 if g['id'] == gr['id']: 265 gr['state'] = g['state'] 266 return 267 else: 268 find_state(gr, g) 269 return
270 271 find_state(gd, descr) 272 gd['groups'] = gt(m, descr, g) 273 children.append(gd) 274 275 if group.id == 0: 276 ret = group_dict(group) 277 ret['groups'] = children 278 return ret 279 else: 280 return children 281 282 if not msg.groups == [] and description is not None: 283 d["groups"] = gt(msg, description) 284 285 def add_params(group, descr): 286 for param in descr['parameters']: 287 group[param['name']] = d[param['name']] 288 for g in group['groups']: 289 for dr in descr['groups']: 290 if dr['name'] == g['name']: 291 add_params(g, dr) 292 293 add_params(d['groups'], description) 294 295 return Config(**d) 296
297 -def decode_config(msg, description = None):
298 d = dict([(kv.name, kv.value) for kv in msg.bools + msg.ints + msg.strs + msg.doubles]) 299 if not msg.groups == [] and description is not None: 300 d["groups"] = get_tree(msg) 301 302 def add_params(group, descr): 303 for param in descr['parameters']: 304 group[param['name']] = d[param['name']] 305 for g in group['groups']: 306 for dr in descr['groups']: 307 if dr['name'] == g['name']: 308 add_params(g, dr)
309 310 add_params(d['groups'], description) 311 312 return Config(**d) 313
314 -def extract_params(group):
315 params = [] 316 params.extend(group['parameters']) 317 for next in group['groups']: 318 params.extend(extract_params(next)) 319 return params
320
321 -def get_parents(group, descriptions):
322 parents = [] 323 for p in descriptions['group']: 324 if p['id'] == group['parent']: 325 parents.extend(get_parents(p, descriptions)) 326 parents.append(p) 327 return parents
328