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 """
35 Master/Slave XML-RPC Wrappers.
36
37 The L{MasterProxy} simplifies usage of master/slave
38 APIs by automatically inserting the caller ID and also adding python
39 dictionary accessors on the parameter server.
40 """
41
42 from threading import Lock
43
44 import rospy.core
45 import rospy.exceptions
46 import rospy.names
47
48 import rospy.impl.paramserver
49 import rospy.impl.masterslave
50
51 _master_arg_remap = {
52 'deleteParam': [0],
53 'setParam': [0],
54 'getParam': [0],
55 'searchParam': [0],
56 'subscribeParam': [0],
57 'unsubscribeParam': [0],
58 'hasParam': [0],
59 'registerService': [0],
60 'lookupService': [0],
61 'unregisterService': [0],
62 'registerSubscriber': [0],
63 'unregisterSubscriber': [0],
64 'registerPublisher': [0],
65 'unregisterPublisher': [0],
66 'lookupNode': [0],
67 'getPublishedTopics': [0],
68 }
69
71 """
72 Convenience wrapper for ROS master API and XML-RPC
73 implementation. The Master API methods can be invoked on this
74 object and will be forwarded appropriately. Names in arguments
75 will be remapped according to current node settings. Provides
76 dictionary-like access to parameter server, e.g.::
77
78 master[key] = value
79
80 All methods are thread-safe.
81 """
82
84 """
85 Constructor for wrapping a remote master instance.
86 @param uri: XML-RPC URI of master
87 @type uri: str
88 """
89 self.target = rospy.core.xmlrpcapi(uri)
90
92 if key in _master_arg_remap:
93 remappings = _master_arg_remap[key]
94 else:
95 remappings = rospy.impl.masterslave.ROSHandler.remappings(key)
96 def wrappedF(*args, **kwds):
97 args = [rospy.names.get_caller_id(),]+list(args)
98
99 for i in remappings:
100 i = i + 1
101
102 args[i] = rospy.names.resolve_name(args[i])
103 f = getattr(self.target, key)
104 return f(*args, **kwds)
105 return wrappedF
106
108 """
109 Fetch item from parameter server and subscribe to future updates so that
110 values can be cached.
111 @param key: parameter key
112 @type key: str
113 @raise KeyError: if key is not set
114 """
115
116 resolved_key = rospy.names.resolve_name(key)
117 try:
118 return rospy.impl.paramserver.get_param_server_cache().get(resolved_key)
119 except KeyError:
120 pass
121 code, msg, value = self.target.getParam(rospy.names.get_caller_id(), resolved_key)
122 if code != 1:
123 raise KeyError(key)
124 return value
125
127 """
128 Set parameter value on Parameter Server
129 @param key: parameter key
130 @type key: str
131 @param val: parameter value
132 @type val: XMLRPC legal value
133 """
134 resolved_key = rospy.names.resolve_name(key)
135
136 self.target.setParam(rospy.names.get_caller_id(), resolved_key, val)
137 try:
138 rospy.impl.paramserver.get_param_server_cache().update(resolved_key, val)
139 except KeyError:
140 pass
141
143 """
144 Search for a parameter matching key on the parameter server
145 @return: found key or None if search did not succeed
146 @rtype: str
147 @raise ROSException: if parameter server reports an error
148 """
149
150 mappings = rospy.names.get_mappings()
151 if key in mappings:
152 key = mappings[key]
153 code, msg, val = self.target.searchParam(rospy.names.get_caller_id(), key)
154 if code == 1:
155 return val
156 elif code == -1:
157 return None
158 else:
159 raise rospy.exceptions.ROSException("cannot search for parameter: %s"%msg)
160
176
178 """
179 Delete parameter key from the parameter server.
180 @raise KeyError: if key is not set
181 @raise ROSException: if parameter server reports an error
182 """
183 resolved_key = rospy.names.resolve_name(key)
184 code, msg, _ = self.target.deleteParam(rospy.names.get_caller_id(), resolved_key)
185 if code == -1:
186 raise KeyError(key)
187 elif code != 1:
188 raise rospy.exceptions.ROSException("cannot delete parameter: %s"%msg)
189
191 """
192 Check if parameter is set on Parameter Server
193 @param key: parameter key
194 @type key: str
195 @raise ROSException: if parameter server reports an error
196 """
197 code, msg, value = self.target.hasParam(rospy.names.get_caller_id(), rospy.names.resolve_name(key))
198 if code != 1:
199 raise rospy.exceptions.ROSException("cannot check parameter on server: %s"%msg)
200 return value
201
203 """
204 @raise ROSException: if parameter server reports an error
205 """
206 code, msg, value = self.target.getParamNames(rospy.names.get_caller_id())
207 if code == 1:
208 return value.__iter__()
209 else:
210 raise rospy.exceptions.ROSException("cannot retrieve parameter names: %s"%msg)
211