Package roslib :: Module scriptutil
[frames] | no frames]

Source Code for Module roslib.scriptutil

  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: scriptutil.py 10609 2010-08-05 21:50:24Z kwc $ 
 34  # $Author: kwc $ 
 35   
 36  """ 
 37  Common ros script utilities, such as methods convenience methods for 
 38  creating master xmlrpc proxies and executing rospack. This library 
 39  is relatively immature and much of the functionality here will 
 40  likely be moved elsewhere as the API solidifies. 
 41  """ 
 42   
 43  import itertools 
 44  import os 
 45  import re 
 46  import string 
 47  import subprocess 
 48  import sys 
 49   
 50  import roslib.exceptions 
 51  import roslib.launcher 
 52  import roslib.message 
 53  import roslib.msgs  
 54  import roslib.names  
 55  import roslib.network 
 56  import roslib.packages 
 57  import roslib.rosenv  
 58   
 59  PRODUCT = 'ros' 
 60   
 61  ## caller ID for master calls where caller ID is not vital 
 62  _GLOBAL_CALLER_ID = '/script' 
 63   
 64  _is_interactive = False 
65 -def set_interactive(interactive):
66 """ 67 General API for a script specifying that it is being run in an 68 interactive environment. Many libraries may wish to change their 69 behavior based on being interactive (e.g. disabling signal 70 handlers on Ctrl-C). 71 72 @param interactive: True if current script is being run in an interactive shell 73 @type interactive: bool 74 """ 75 global _is_interactive 76 _is_interactive = interactive
77
78 -def is_interactive():
79 """ 80 General API for a script specifying that it is being run in an 81 interactive environment. Many libraries may wish to change their 82 behavior based on being interactive (e.g. disabling signal 83 handlers on Ctrl-C). 84 85 @return: True if interactive flag has been set 86 @rtype: bool 87 """ 88 return _is_interactive
89
90 -def myargv(argv=None):
91 """ 92 Remove ROS remapping arguments from sys.argv arguments. 93 @return: copy of sys.argv with ROS remapping arguments removed 94 @rtype: [str] 95 """ 96 if argv is None: 97 argv = sys.argv 98 return [a for a in argv if not roslib.names.REMAP in a]
99
100 -def script_resolve_name(script_name, name):
101 """ 102 Name resolver for scripts. Supports ROS_NAMESPACE. Does not 103 support remapping arguments. 104 @param name: name to resolve 105 @type name: str 106 @param script_name: name of script. script_name must not 107 contain a namespace. 108 @type script_name: str 109 @return: resolved name 110 @rtype: str 111 """ 112 if not name: #empty string resolves to namespace 113 return roslib.names.get_ros_namespace() 114 #Check for global name: /foo/name resolves to /foo/name 115 if roslib.names.is_global(name): 116 return name 117 #Check for private name: ~name resolves to /caller_id/name 118 elif roslib.names.is_private(name): 119 return ns_join(roslib.names.make_caller_id(script_name), name[1:]) 120 return roslib.names.get_ros_namespace() + name
121
122 -def get_master():
123 """ 124 Get an XMLRPC handle to the Master. It is recommended to use the 125 `rosgraph.masterapi` library instead, as it provides many 126 conveniences. 127 128 @return: XML-RPC proxy to ROS master 129 @rtype: xmlrpclib.ServerProxy 130 """ 131 import xmlrpclib 132 # #1730 validate URL for better error messages 133 uri = roslib.rosenv.get_master_uri() 134 try: 135 roslib.network.parse_http_host_and_port(uri) 136 except ValueError: 137 raise roslib.exceptions.ROSLibException("invalid master URI: %s"%uri) 138 return xmlrpclib.ServerProxy(uri)
139 140
141 -def get_param_server():
142 """ 143 @return: ServerProxy XML-RPC proxy to ROS parameter server 144 @rtype: xmlrpclib.ServerProxy 145 """ 146 return get_master()
147
148 -def is_subscriber(topic, subscriber_id):
149 """ 150 Check whether or not master think subscriber_id subscribes to topic 151 @return: True if still register as a subscriber 152 @rtype: bool 153 @raise roslib.exceptions.ROSLibException: if communication with master fails 154 """ 155 m = get_master() 156 code, msg, state = m.getSystemState(_GLOBAL_CALLER_ID) 157 if code != 1: 158 raise roslib.exceptions.ROSLibException("Unable to retrieve master state: %s"%msg) 159 _, subscribers, _ = state 160 for t, l in subscribers: 161 if t == topic: 162 return subscriber_id in l 163 else: 164 return False
165
166 -def is_publisher(topic, publisher_id):
167 """ 168 Predicate to check whether or not master think publisher_id 169 publishes topic 170 @return: True if still register as a publisher 171 @rtype: bool 172 @raise roslib.exceptions.ROSLibException: if communication with master fails 173 """ 174 m = get_master() 175 code, msg, state = m.getSystemState(_GLOBAL_CALLER_ID) 176 if code != 1: 177 raise roslib.exceptions.ROSLibException("Unable to retrieve master state: %s"%msg) 178 pubs, _, _ = state 179 for t, l in pubs: 180 if t == topic: 181 return publisher_id in l 182 else: 183 return False
184
185 -def ask_and_call(cmds, cwd=None):
186 """ 187 Pretty print cmds, ask if they should be run, and if so, runs 188 them using subprocess.check_call. 189 190 @param cwd: (optional) set cwd of command that is executed 191 @type cwd: str 192 @return: True if cmds were run. 193 """ 194 # Pretty-print a string version of the commands 195 def quote(s): 196 return '"%s"'%s if ' ' in s else s
197 print "Okay to execute:\n\n%s\n(y/n)?"%('\n'.join([' '.join([quote(s) for s in c]) for c in cmds])) 198 while 1: 199 input = sys.stdin.readline().strip() 200 if input in ['y', 'n']: 201 break 202 accepted = input == 'y' 203 import subprocess 204 if accepted: 205 for c in cmds: 206 if cwd: 207 subprocess.check_call(c, cwd=cwd) 208 else: 209 subprocess.check_call(c) 210 return accepted 211