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 14631 2011-08-10 03:37:14Z 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 try: 132 import xmlrpc.client as xmlrpcclient #Python 3.x 133 except ImportError: 134 import xmlrpclib as xmlrpcclient #Python 2.x 135 136 # #1730 validate URL for better error messages 137 uri = roslib.rosenv.get_master_uri() 138 try: 139 roslib.network.parse_http_host_and_port(uri) 140 except ValueError: 141 raise roslib.exceptions.ROSLibException("invalid master URI: %s"%uri) 142 return xmlrpcclient.ServerProxy(uri)
143 144
145 -def get_param_server():
146 """ 147 @return: ServerProxy XML-RPC proxy to ROS parameter server 148 @rtype: xmlrpclib.ServerProxy 149 """ 150 return get_master()
151
152 -def is_subscriber(topic, subscriber_id):
153 """ 154 Check whether or not master think subscriber_id subscribes to topic 155 @return: True if still register as a subscriber 156 @rtype: bool 157 @raise roslib.exceptions.ROSLibException: if communication with master fails 158 """ 159 m = get_master() 160 code, msg, state = m.getSystemState(_GLOBAL_CALLER_ID) 161 if code != 1: 162 raise roslib.exceptions.ROSLibException("Unable to retrieve master state: %s"%msg) 163 _, subscribers, _ = state 164 for t, l in subscribers: 165 if t == topic: 166 return subscriber_id in l 167 else: 168 return False
169
170 -def is_publisher(topic, publisher_id):
171 """ 172 Predicate to check whether or not master think publisher_id 173 publishes topic 174 @return: True if still register as a publisher 175 @rtype: bool 176 @raise roslib.exceptions.ROSLibException: if communication with master fails 177 """ 178 m = get_master() 179 code, msg, state = m.getSystemState(_GLOBAL_CALLER_ID) 180 if code != 1: 181 raise roslib.exceptions.ROSLibException("Unable to retrieve master state: %s"%msg) 182 pubs, _, _ = state 183 for t, l in pubs: 184 if t == topic: 185 return publisher_id in l 186 else: 187 return False
188
189 -def ask_and_call(cmds, cwd=None):
190 """ 191 Pretty print cmds, ask if they should be run, and if so, runs 192 them using subprocess.check_call. 193 194 @param cwd: (optional) set cwd of command that is executed 195 @type cwd: str 196 @return: True if cmds were run. 197 """ 198 # Pretty-print a string version of the commands 199 def quote(s): 200 return '"%s"'%s if ' ' in s else s
201 sys.stdout.write("Okay to execute:\n\n%s\n(y/n)?\n"%('\n'.join([' '.join([quote(s) for s in c]) for c in cmds]))) 202 while 1: 203 input = sys.stdin.readline().strip().lower() 204 if input in ['y', 'n']: 205 break 206 accepted = input == 'y' 207 if accepted: 208 for c in cmds: 209 if cwd: 210 subprocess.check_call(c, cwd=cwd) 211 else: 212 subprocess.check_call(c) 213 return accepted 214