| Home | Trees | Indices | Help |
|
|---|
|
|
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2008, 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 # Revision $Id$
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], # remap key
53 'setParam': [0], # remap key
54 'getParam': [0], # remap key
55 'searchParam': [0], # remap key
56 'subscribeParam': [0], # remap key
57 'unsubscribeParam': [0], # remap key
58 'hasParam': [0], # remap key
59 'registerService': [0], # remap service
60 'lookupService': [0], # remap service
61 'unregisterService': [0], # remap service
62 'registerSubscriber': [0], # remap topic
63 'unregisterSubscriber': [0], # remap topic
64 'registerPublisher': [0], # remap topic
65 'unregisterPublisher': [0], # remap topic
66 'lookupNode': [0], # remap node
67 'getPublishedTopics': [0], # remap subgraph
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 #print "Remap indicies", remappings
99 for i in remappings:
100 i = i + 1 #callerId does not count
101 #print "Remap %s => %s"%(args[i], rospy.names.resolve_name(args[i]))
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 #NOTE: remapping occurs here!
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: #unwrap value with Python semantics
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 # #1810 searchParam has to use unresolved form of mappings
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
162 resolved_key = rospy.names.resolve_name(key)
163 try:
164 # check for value in the parameter server cache
165 return rospy.impl.paramserver.get_param_server_cache().get(resolved_key)
166 except KeyError:
167 # first access, make call to parameter server
168 code, msg, value = self.target.subscribeParam(rospy.names.get_caller_id(), rospy.core.get_node_uri(), resolved_key)
169 if code != 1: #unwrap value with Python semantics
170 raise KeyError(key)
171 # set the value in the cache so that it's marked as subscribed
172 rospy.impl.paramserver.get_param_server_cache().set(resolved_key, value)
173 if isinstance(value, dict) and not value:
174 raise KeyError(key)
175 return value
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
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Mar 1 07:33:45 2022 | http://epydoc.sourceforge.net |