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

[roslaunch] Add yaml type for <param> tag #1045

Merged

Conversation

wkentaro
Copy link
Contributor

@wkentaro wkentaro commented May 2, 2017

Why?

To set dict, list string as a parameter.
This is ok if we use <rosparam> tag, but it does not have the feature of running arbitrary commands which <param> tag has.

Example

My motivation is ways to use like below:

% cat apc2015_00.json
{
  "bin_contents":
  {
    "bin_I":
    [
      "sharpie_accent_tank_style_highlighters",
      "dr_browns_bottle_brush"
    ]
  },

  "work_order":
  [
    {
      "bin": "bin_I",
      "item": "sharpie_accent_tank_style_highlighters"
    }
  ]
}

% cat spam.launch
<launch>

  <param name="/test" type="yaml"
         command="/usr/local/bin/json2yaml $(find roslaunch)/apc2015_00.json" />

</launch>

% roslaunch ./spam.launch

% rosparam get /test
bin_contents:
  bin_I: [sharpie_accent_tank_style_highlighters, dr_browns_bottle_brush]
work_order:
- {bin: bin_I, item: sharpie_accent_tank_style_highlighters}

@mikepurvis
Copy link
Member

I dig it. I've wanted something like this for ages.

@wkentaro wkentaro force-pushed the roslaunch_param_command_type_yaml branch from 4105d70 to ef0dee9 Compare May 4, 2017 03:50
@wkentaro wkentaro force-pushed the roslaunch_param_command_type_yaml branch from ef0dee9 to b746f71 Compare May 16, 2017 07:11
@@ -32,6 +32,7 @@
<run_depend version_gte="1.13.3">rosunit</run_depend>

<test_depend>rosbuild</test_depend>
<test_depend>rospy</test_depend>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? I don't see any part in the patch which requires it.

@@ -70,30 +70,36 @@ def convert_value(value, type_):
#attempt numeric conversion
try:
if '.' in value:
return float(value)
return float(value.strip())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary. float() already works even if the passed argument has leading / trailing spaces.

Same below.

except ValueError as e:
pass
#bool
lval = value.lower()
lval = value.strip().lower()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case do you expect the strings true and false to have leading / trailing spaces?

# - lazy import
global yaml
if yaml is None:
import yaml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the import to the top of the file and avoid the conditional block.

global yaml
if yaml is None:
import yaml
return yaml.load(value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is that represented on the parameter server? Does this store a complex type (e.g. a nested dictionary) under a single name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is set like this:

% rosparam get /test1
bin_contents:
  bin_I: [sharpie_accent_tank_style_highlighters, dr_browns_bottle_brush]
work_order:
- {bin: bin_I, item: sharpie_accent_tank_style_highlighters}

% rosparam get /test1/bin_contents/bin_I
[sharpie_accent_tank_style_highlighters, dr_browns_bottle_brush]


% rosparam get /test1/bin_contents
bin_I: [sharpie_accent_tank_style_highlighters, dr_browns_bottle_brush]

% rosparam get /test1/bin_contents/bin_I
[sharpie_accent_tank_style_highlighters, dr_browns_bottle_brush]

@@ -94,6 +95,8 @@ def convert_value(value, type_):
elif value == 'false' or value == '0':
return False
raise ValueError("%s is not a '%s' type"%(value, type_))
elif type_ == 'yaml':
return yaml.load(value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should any yaml specific exceptions be catched here and a ValueError be raised instead?

@wkentaro
Copy link
Contributor Author

Had error below:

% nosetests test_xmlloader.py
.............................E............
======================================================================
ERROR: test_params (unit.test_xmlloader.TestXmlLoader)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/test/unit/test_xmlloader.py", line 192, in test_params
    mock = self._load(os.path.join(self.xml_dir, 'test-params-valid.xml'))
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/test/unit/test_xmlloader.py", line 100, in _load
    loader.load(test_file, mock)
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/src/roslaunch/xmlloader.py", line 746, in load
    self._load_launch(launch, ros_config, is_core=core, filename=filename, argv=argv, verbose=verbose)
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/src/roslaunch/xmlloader.py", line 718, in _load_launch
    self._recurse_load(ros_config, launch.childNodes, self.root_context, None, is_core, verbose)
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/src/roslaunch/xmlloader.py", line 662, in _recurse_load
    self._param_tag(tag, context, ros_config, verbose=verbose)
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/src/roslaunch/xmlloader.py", line 95, in call
    return f(*args, **kwds)
  File "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/src/roslaunch/xmlloader.py", line 279, in _param_tag
    "Invalid <param> tag: %s. \n\nParam xml is %s"%(e, tag.toxml()))
XmlParseException: Invalid <param> tag: true
 is not a 'bool' type.

Param xml is <param command="echo true" name="commandoutputbool" type="bool"/>
-------------------- >> begin captured stdout << ---------------------
... loading XML file [/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/test/xml/test-params-valid.xml]
... executing command param [cat "/home/wkentaro/Projects/ros_comm_ws/src/ros/ros_comm/tools/roslaunch/resources/example.launch"]
... executing command param [echo 0]
... executing command param [echo 10]
... executing command param [echo true]

--------------------- >> end captured stdout << ----------------------

----------------------------------------------------------------------
Ran 42 tests in 0.644s

FAILED (errors=1)

@wkentaro wkentaro force-pushed the roslaunch_param_command_type_yaml branch from 2d9ecb7 to c907f36 Compare May 25, 2017 17:39
@dirk-thomas
Copy link
Member

I am sorry for the late response. This looks good now. Merging...

Can you please add appropriate documentation for this new feature to the wiki and link to the change here. Thanks.

@dirk-thomas dirk-thomas merged commit df86805 into ros:lunar-devel Jul 7, 2017
@wkentaro wkentaro deleted the roslaunch_param_command_type_yaml branch July 9, 2017 05:36
@wkentaro
Copy link
Contributor Author

wkentaro commented Jul 9, 2017

@dirk-thomas
Copy link
Member

Thank you. I reformated the paragraph a little bit and changed the note that it is only available as of Lunar atm: http://wiki.ros.org/action/info/roslaunch/XML/param?action=diff&rev2=12&rev1=11

sputnick1124 pushed a commit to sputnick1124/ros_comm that referenced this pull request Jul 30, 2017
* Add yaml type for <param> tag

* Support type for command output of <param> tag

* Add test for yaml type

* Add test for identifying commandline output as types

* Support yaml type with textfile for <param>

* Reserve current behavior with handling strip cleanly

* Revert <test_depend>rospy</test_depend>: no need

* Revert no need strip()

* Remove the lazy import for yaml

* Raise ValueError for yaml parse error

* Strip for boolean rosparam
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants