def setParam(self, caller_id, key, value): """ Parameter Server: set parameter. NOTE: if value is a dictionary it will be treated as a parameter tree, where key is the parameter namespace. For example::: {'x':1,'y':2,'sub':{'z':3}} will set key/x=1, key/y=2, and key/sub/z=3. Furthermore, it will replace all existing parameters in the key parameter namespace with the parameters in value. You must set parameters individually if you wish to perform a union update. @param caller_id: ROS caller id @type caller_id: str @param key: parameter name @type key: str @param value: parameter value. @type value: XMLRPCLegalValue @return: [code, msg, 0] @rtype: [int, str, int] """ key = resolve_name(key, caller_id) self.param_server.set_param(key, value, self._notify_param_subscribers) mloginfo("+PARAM [%s] by %s", key, caller_id) return 1, "parameter %s set" % key, 0
def setParam(self, caller_id, key, value): """ Parameter Server: set parameter. NOTE: if value is a dictionary it will be treated as a parameter tree, where key is the parameter namespace. For example::: {'x':1,'y':2,'sub':{'z':3}} will set key/x=1, key/y=2, and key/sub/z=3. Furthermore, it will replace all existing parameters in the key parameter namespace with the parameters in value. You must set parameters individually if you wish to perform a union update. @param caller_id: ROS caller id @type caller_id: str @param key: parameter name @type key: str @param value: parameter value. @type value: XMLRPCLegalValue @return: [code, msg, 0] @rtype: [int, str, int] """ key = resolve_name(key, caller_id) self.param_server.set_param(key, value, self._notify_param_subscribers) mloginfo("+PARAM [%s] by %s",key, caller_id) return 1, "parameter %s set"%key, 0
def validator(param_value, caller_id): if not isinstance(param_value, basestring): raise ParameterInvalid("ERROR: parameter [%s] must be a string"%param_name) if not param_value: return '' #return resolve_name(param_value, namespace(caller_id)) return resolve_name(param_value, caller_id)
def subscribeParam(self, caller_id, caller_api, key): """ Retrieve parameter value from server and subscribe to updates to that param. See paramUpdate() in the Node API. @param caller_id str: ROS caller id @type caller_id: str @param key: parameter to lookup. @type key: str @param caller_api: API URI for paramUpdate callbacks. @type caller_api: str @return: [code, statusMessage, parameterValue]. If code is not 1, parameterValue should be ignored. parameterValue is an empty dictionary if the parameter has not been set yet. @rtype: [int, str, XMLRPCLegalValue] """ key = resolve_name(key, caller_id) try: # ps_lock has precedence and is required due to # potential self.reg_manager modification self.ps_lock.acquire() val = self.param_server.subscribe_param(key, (caller_id, caller_api)) finally: self.ps_lock.release() return 1, "Subscribed to parameter [%s]" % key, val
def test_resolve_name(self): from roslib.names import resolve_name # TODO: test with remappings tests = [ ('', '/', '/'), ('', '/node', '/'), ('', '/ns1/node', '/ns1/'), ('foo', '', '/foo'), ('foo/', '', '/foo'), ('/foo', '', '/foo'), ('/foo/', '', '/foo'), ('/foo', '/', '/foo'), ('/foo/', '/', '/foo'), ('/foo', '/bar', '/foo'), ('/foo/', '/bar', '/foo'), ('foo', '/ns1/ns2', '/ns1/foo'), ('foo', '/ns1/ns2/', '/ns1/foo'), ('foo', '/ns1/ns2/ns3/', '/ns1/ns2/foo'), ('foo/', '/ns1/ns2', '/ns1/foo'), ('/foo', '/ns1/ns2', '/foo'), ('foo/bar', '/ns1/ns2', '/ns1/foo/bar'), ('foo//bar', '/ns1/ns2', '/ns1/foo/bar'), ('foo/bar', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'), ('foo//bar//', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'), ('~foo', '/', '/foo'), ('~foo', '/node', '/node/foo'), ('~foo', '/ns1/ns2', '/ns1/ns2/foo'), ('~foo/', '/ns1/ns2', '/ns1/ns2/foo'), ('~foo/bar', '/ns1/ns2', '/ns1/ns2/foo/bar'), ] for name, node_name, v in tests: self.assertEquals(v, resolve_name(name, node_name))
def validator(param_value, caller_id): if not isinstance(param_value, basestring): raise ParameterInvalid("ERROR: parameter [%s] must be a string" % param_name) if not param_value: return '' #return resolve_name(param_value, namespace(caller_id)) return resolve_name(param_value, caller_id)
def valid_name_validator_resolved(param_name, param_value, caller_id): if not param_value or not isinstance(param_value, basestring): raise ParameterInvalid("ERROR: parameter [%s] must be a non-empty string"%param_name) #TODO: actual validation of chars # I added the colon check as the common error will be to send an URI instead of name if ':' in param_value or ' ' in param_value: raise ParameterInvalid("ERROR: parameter [%s] contains illegal chars"%param_name) #return resolve_name(param_value, namespace(caller_id)) return resolve_name(param_value, caller_id)
def valid_name_validator_resolved(param_name, param_value, caller_id): if not param_value or not isinstance(param_value, basestring): raise ParameterInvalid( "ERROR: parameter [%s] must be a non-empty string" % param_name) #TODO: actual validation of chars # I added the colon check as the common error will be to send an URI instead of name if ':' in param_value or ' ' in param_value: raise ParameterInvalid("ERROR: parameter [%s] contains illegal chars" % param_name) #return resolve_name(param_value, namespace(caller_id)) return resolve_name(param_value, caller_id)
def hasParam(self, caller_id, key): """ Check if parameter is stored on server. @param caller_id str: ROS caller id @type caller_id: str @param key: parameter to check @type key: str @return: [code, statusMessage, hasParam] @rtype: [int, str, bool] """ key = resolve_name(key, caller_id) if self.param_server.has_param(key): return 1, key, True else: return 1, key, False
def deleteParam(self, caller_id, key): """ Parameter Server: delete parameter @param caller_id: ROS caller id @type caller_id: str @param key: parameter name @type key: str @return: [code, msg, 0] @rtype: [int, str, int] """ try: key = resolve_name(key, caller_id) self.param_server.delete_param(key, self._notify_param_subscribers) mloginfo("-PARAM [%s] by %s",key, caller_id) return 1, "parameter %s deleted"%key, 0 except KeyError, e: return -1, "parameter [%s] is not set"%key, 0
def deleteParam(self, caller_id, key): """ Parameter Server: delete parameter @param caller_id: ROS caller id @type caller_id: str @param key: parameter name @type key: str @return: [code, msg, 0] @rtype: [int, str, int] """ try: key = resolve_name(key, caller_id) self.param_server.delete_param(key, self._notify_param_subscribers) mloginfo("-PARAM [%s] by %s", key, caller_id) return 1, "parameter %s deleted" % key, 0 except KeyError, e: return -1, "parameter [%s] is not set" % key, 0
def test_resolve_name(self): from roslib.names import resolve_name # TODO: test with remappings tests = [ ('', '/', '/'), ('', '/node', '/'), ('', '/ns1/node', '/ns1/'), ('foo', '', '/foo'), ('foo/', '', '/foo'), ('/foo', '', '/foo'), ('/foo/', '', '/foo'), ('/foo', '/', '/foo'), ('/foo/', '/', '/foo'), ('/foo', '/bar', '/foo'), ('/foo/', '/bar', '/foo'), ('foo', '/ns1/ns2', '/ns1/foo'), ('foo', '/ns1/ns2/', '/ns1/foo'), ('foo', '/ns1/ns2/ns3/', '/ns1/ns2/foo'), ('foo/', '/ns1/ns2', '/ns1/foo'), ('/foo', '/ns1/ns2', '/foo'), ('foo/bar', '/ns1/ns2', '/ns1/foo/bar'), ('foo//bar', '/ns1/ns2', '/ns1/foo/bar'), ('foo/bar', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'), ('foo//bar//', '/ns1/ns2/ns3', '/ns1/ns2/foo/bar'), ('~foo', '/', '/foo'), ('~foo', '/node', '/node/foo'), ('~foo', '/ns1/ns2', '/ns1/ns2/foo'), ('~foo/', '/ns1/ns2', '/ns1/ns2/foo'), ('~foo/bar', '/ns1/ns2', '/ns1/ns2/foo/bar'), # #3044 ('~/foo', '/', '/foo'), ('~/foo', '/node', '/node/foo'), ('~/foo', '/ns1/ns2', '/ns1/ns2/foo'), ('~/foo/', '/ns1/ns2', '/ns1/ns2/foo'), ('~/foo/bar', '/ns1/ns2', '/ns1/ns2/foo/bar'), ] for name, node_name, v in tests: self.assertEquals(v, resolve_name(name, node_name))
def getParam(self, caller_id, key): """ Retrieve parameter value from server. @param caller_id: ROS caller id @type caller_id: str @param key: parameter to lookup. If key is a namespace, getParam() will return a parameter tree. @type key: str getParam() will return a parameter tree. @return: [code, statusMessage, parameterValue]. If code is not 1, parameterValue should be ignored. If key is a namespace, the return value will be a dictionary, where each key is a parameter in that namespace. Sub-namespaces are also represented as dictionaries. @rtype: [int, str, XMLRPCLegalValue] """ try: key = resolve_name(key, caller_id) return 1, "Parameter [%s]" % key, self.param_server.get_param(key) except KeyError, e: return -1, "Parameter [%s] is not set" % key, 0
def getParam(self, caller_id, key): """ Retrieve parameter value from server. @param caller_id: ROS caller id @type caller_id: str @param key: parameter to lookup. If key is a namespace, getParam() will return a parameter tree. @type key: str getParam() will return a parameter tree. @return: [code, statusMessage, parameterValue]. If code is not 1, parameterValue should be ignored. If key is a namespace, the return value will be a dictionary, where each key is a parameter in that namespace. Sub-namespaces are also represented as dictionaries. @rtype: [int, str, XMLRPCLegalValue] """ try: key = resolve_name(key, caller_id) return 1, "Parameter [%s]"%key, self.param_server.get_param(key) except KeyError, e: return -1, "Parameter [%s] is not set"%key, 0
def unsubscribeParam(self, caller_id, caller_api, key): """ Retrieve parameter value from server and subscribe to updates to that param. See paramUpdate() in the Node API. @param caller_id str: ROS caller id @type caller_id: str @param key: parameter to lookup. @type key: str @param caller_api: API URI for paramUpdate callbacks. @type caller_api: str @return: [code, statusMessage, numUnsubscribed]. If numUnsubscribed is zero it means that the caller was not subscribed to the parameter. @rtype: [int, str, int] """ key = resolve_name(key, caller_id) try: # ps_lock is required due to potential self.reg_manager modification self.ps_lock.acquire() retval = self.param_server.unsubscribe_param(key, (caller_id, caller_api)) finally: self.ps_lock.release() return 1, "Unsubscribe to parameter [%s]"%key, 1
def unsubscribeParam(self, caller_id, caller_api, key): """ Retrieve parameter value from server and subscribe to updates to that param. See paramUpdate() in the Node API. @param caller_id str: ROS caller id @type caller_id: str @param key: parameter to lookup. @type key: str @param caller_api: API URI for paramUpdate callbacks. @type caller_api: str @return: [code, statusMessage, numUnsubscribed]. If numUnsubscribed is zero it means that the caller was not subscribed to the parameter. @rtype: [int, str, int] """ key = resolve_name(key, caller_id) try: # ps_lock is required due to potential self.reg_manager modification self.ps_lock.acquire() retval = self.param_server.unsubscribe_param( key, (caller_id, caller_api)) finally: self.ps_lock.release() return 1, "Unsubscribe to parameter [%s]" % key, 1
def subscribeParam(self, caller_id, caller_api, key): """ Retrieve parameter value from server and subscribe to updates to that param. See paramUpdate() in the Node API. @param caller_id str: ROS caller id @type caller_id: str @param key: parameter to lookup. @type key: str @param caller_api: API URI for paramUpdate callbacks. @type caller_api: str @return: [code, statusMessage, parameterValue]. If code is not 1, parameterValue should be ignored. parameterValue is an empty dictionary if the parameter has not been set yet. @rtype: [int, str, XMLRPCLegalValue] """ key = resolve_name(key, caller_id) try: # ps_lock has precedence and is required due to # potential self.reg_manager modification self.ps_lock.acquire() val = self.param_server.subscribe_param(key, (caller_id, caller_api)) finally: self.ps_lock.release() return 1, "Subscribed to parameter [%s]"%key, val