Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added execute argument to rosparam, to load the output of a command as yaml #1170

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions tools/roslaunch/src/roslaunch/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ def add_param(self, ros_config, param_name, param_value, verbose=True):
else:
ros_config.add_param(Param(param_name, param_value), verbose=verbose)

def load_rosparam(self, context, ros_config, cmd, param, file_, text, verbose=True):
def load_rosparam(self, context, ros_config, cmd, param, file_, execute, text, verbose=True):
"""
Load rosparam setting

Expand All @@ -376,7 +376,9 @@ def load_rosparam(self, context, ros_config, cmd, param, file_, text, verbose=Tr
@type cmd: str
@param file_: filename for rosparam to use or None
@type file_: str
@param text: text for rosparam to load. Ignored if file_ is set.
@param execute: command to execute for rosparam load or None
@type execute: str
@param text: text for rosparam to load. Ignored if file_ or execute are set.
@type text: str
@raise ValueError: if parameters cannot be processed into valid rosparam setting
"""
Expand All @@ -387,7 +389,12 @@ def load_rosparam(self, context, ros_config, cmd, param, file_, text, verbose=Tr
raise ValueError("file does not exist [%s]"%file_)
if cmd == 'delete':
raise ValueError("'file' attribute is invalid with 'delete' command.")

elif execute is not None:
if cmd == 'delete':
raise ValueError("'execute' attribute is invalid with 'delete' command.")
if cmd == 'dump':
raise ValueError("'execute' attribute is invalid with 'dump' command.")

full_param = ns_join(context.ns, param) if param else context.ns

if cmd == 'dump':
Expand All @@ -399,6 +406,28 @@ def load_rosparam(self, context, ros_config, cmd, param, file_, text, verbose=Tr
if file_:
with open(file_, 'r') as f:
text = f.read()
elif execute:
try:
if type(execute) == unicode:
execute = execute.encode('utf-8') #attempt to force to string for shlex/subprocess
except NameError:
pass
if verbose:
print("... executing command param [%s]" % execute)
import subprocess, shlex #shlex rocks
try:
p = subprocess.Popen(shlex.split(execute), stdout=subprocess.PIPE)
text = p.communicate()[0]
if not isinstance(text, str):
text = text.decode('utf-8')
if p.returncode != 0:
raise ValueError("Cannot load command parameter [%s]: command [%s] returned with code [%s]"%(name, execute, p.returncode))
except OSError as e:
if e.errno == 2:
raise ValueError("Cannot load command parameter [%s]: no such command [%s]"%(name, execute))
raise
if text is None:
raise ValueError("parameter: unable to get output of command [%s]"%execute)

# parse YAML text
# - lazy import: we have to import rosparam in oder to to configure the YAML constructors
Expand Down
6 changes: 3 additions & 3 deletions tools/roslaunch/src/roslaunch/xmlloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,12 @@ def _check_attrs(self, tag, context, ros_config, attrs):
# 'ns' attribute is now deprecated and is an alias for
# 'param'. 'param' is required if the value is a non-dictionary
# type
ROSPARAM_OPT_ATTRS = ('command', 'ns', 'file', 'param', 'subst_value')
ROSPARAM_OPT_ATTRS = ('command', 'ns', 'file', 'execute', 'param', 'subst_value')
@ifunless
def _rosparam_tag(self, tag, context, ros_config, verbose=True):
try:
self._check_attrs(tag, context, ros_config, XmlLoader.ROSPARAM_OPT_ATTRS)
cmd, ns, file, param, subst_value = self.opt_attrs(tag, context, (XmlLoader.ROSPARAM_OPT_ATTRS))
cmd, ns, file, execute, param, subst_value = self.opt_attrs(tag, context, (XmlLoader.ROSPARAM_OPT_ATTRS))
subst_value = _bool_attr(subst_value, False, 'subst_value')
# ns atribute is a bit out-moded and is only left in for backwards compatibility
param = ns_join(ns or '', param or '')
Expand All @@ -237,7 +237,7 @@ def _rosparam_tag(self, tag, context, ros_config, verbose=True):
value = _get_text(tag)
if subst_value:
value = self.resolve_args(value, context)
self.load_rosparam(context, ros_config, cmd, param, file, value, verbose=verbose)
self.load_rosparam(context, ros_config, cmd, param, file, execute, value, verbose=verbose)

except ValueError as e:
raise loader.LoadException("error loading <rosparam> tag: \n\t"+str(e)+"\nXML is %s"%tag.toxml())
Expand Down