Package dynamic_reconfigure :: Module server

Source Code for Module dynamic_reconfigure.server

  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  """ 
 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  import roslib; roslib.load_manifest('dynamic_reconfigure') 
 41  import rospy 
 42  import rosservice                   
 43  import threading 
 44  import time 
 45  from dynamic_reconfigure import DynamicReconfigureCallbackException 
 46  from dynamic_reconfigure.srv import Reconfigure as ReconfigureSrv 
 47  from dynamic_reconfigure.msg import Config as ConfigMsg 
 48  from dynamic_reconfigure.msg import ConfigDescription as ConfigDescrMsg 
 49  from dynamic_reconfigure.msg import IntParameter, BoolParameter, StrParameter, DoubleParameter, ParamDescription 
 50  from dynamic_reconfigure.encoding import * 
 51   
52 -class Server(object):
53 - def __init__(self, type, callback):
54 self.mutex = threading.Lock() 55 self.type = type 56 self.config = type.defaults 57 self.description = encode_description(type) 58 self._copy_from_parameter_server() 59 self.callback = callback 60 self._clamp(self.config) 61 62 self.descr_topic = rospy.Publisher('~parameter_descriptions', ConfigDescrMsg, latch=True) 63 self.descr_topic.publish(self.description); 64 65 self.update_topic = rospy.Publisher('~parameter_updates', ConfigMsg, latch=True) 66 self._change_config(self.config, type.all_level) 67 68 self.set_service = rospy.Service('~set_parameters', ReconfigureSrv, self._set_callback)
69
70 - def update_configuration(self, changes):
71 with self.mutex: 72 new_config = dict(self.config) 73 new_config.update(changes) 74 self._clamp(new_config) 75 return self._change_config(new_config, self._calc_level(new_config, self.config))
76
78 for param in self.type.config_description: 79 try: 80 self.config[param['name']] = rospy.get_param("~" + param['name']) 81 except KeyError: 82 pass
83
85 for param in self.type.config_description: 86 rospy.set_param('~' + param['name'], self.config[param['name']])
87
88 - def _change_config(self, config, level):
89 self.config = self.callback(config, level) 90 if self.config is None: 91 msg = 'Reconfigure callback should return a possibly updated configuration.' 92 rospy.logerr(msg) 93 raise DynamicReconfigureCallbackException(msg) 94 95 self._copy_to_parameter_server() 96 97 self.update_topic.publish(encode_config(self.config)) 98 99 return self.config
100
101 - def _calc_level(self, config1, config2):
102 level = 0 103 for param in self.type.config_description: 104 if config1[param['name']] != config2[param['name']]: 105 level |= param['level'] 106 107 return level
108
109 - def _clamp(self, config):
110 for param in self.type.config_description: 111 maxval = self.type.max[param['name']] 112 minval = self.type.min[param['name']] 113 val = config[param['name']] 114 if val > maxval and maxval != "": 115 config[param['name']] = maxval 116 elif val < minval and minval != "": 117 config[param['name']] = minval
118
119 - def _set_callback(self, req):
120 return encode_config(self.update_configuration(decode_config(req.config)))
121