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

Add param dump <node-name> #285

Merged
merged 24 commits into from
Jul 26, 2019
Merged

Add param dump <node-name> #285

merged 24 commits into from
Jul 26, 2019

Conversation

artivis
Copy link
Contributor

@artivis artivis commented Jun 19, 2019

Add the param dump <node-name> which dumps the parameters of a given node to a yaml file.

From the test, the following

node.declare_parameter('bool_param', True)
node.declare_parameter('int_param', 42)
node.declare_parameter('double_param', 1.23)
node.declare_parameter('str_param', 'Hello World')
node.declare_parameter('foo.str_param', 'foo')
node.declare_parameter('foo.bar.str_param', 'foobar')

generates the yaml file (test_node.yaml) :

test_node:
  ros__parameters:
    bool_param: true
    double_param: 1.23
    foo:
      bar:
        str_param: foobar
      str_param: foo
    int_param: 42
    str_param: Hello World

Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
return value

def insert_dict(self, dict, key, value):
split = key.split("/", 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if namespaces are delimited with / or . as I have seen both :s .

Copy link
Contributor

Choose a reason for hiding this comment

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

Depends what you mean by namespace.

A node namespace (the thing set with __ns:=/foo/bar) has tokens delimited with /. Multiple levels in a parameter name are delimited with a .. You can get the character with this import from rclpy.parameter import PARAMETER_SEPARATOR_STRING

$ ros2 run demo_nodes_cpp parameter_blackboard  __ns:=/foo/bar &
[1] 25174
...
$ ros2 node list
/foo/bar/parameter_blackboard
$ ros2 param list /foo/bar/parameter_blackboard
  use_sim_time
$ ros2 param set /foo/bar/parameter_blackboard ping.pong 5
Set parameter successful
$ ros2 param list /foo/bar/parameter_blackboard
  ping.pong
  use_sim_time

If you're dumping to a yaml file, you can just use indentation.

$ ros2 run demo_nodes_cpp parameter_blackboard  __ns:=/lidar_ns/lidar_1/lidar11 __node:=lidar111 __params:=/home/sloretz/ws/ros2/src/ros2/rcl/rcl_yaml_param_parser/test/multi_ns_correct.yaml &
[1] 25358
...
$ ros2 param list /lidar_ns/lidar_1/lidar11/lidar111
  driver1.driver11.bk_sensor_specs
  driver1.driver11.driver111.dx
  driver1.driver11.driver111.dy
  driver1.driver11.driver111.fr_sensor_specs
  driver2.driver21.dx
  driver2.driver21.dy
  id
  is_front
  name
  ports
  use_sim_time

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did mean "Multiple levels in a parameter name", didn't know about PARAMETER_SEPARATOR_STRING thanks.
This new verb does dump into a yaml file using multi-level indentation for multi-level parameters, see the example in my very first comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But how does one declare those multi-level parameters in python ?? The following does not work,

node.declare_parameter('foo.str_param', 'foo')

for topic name must not contain characters other than alphanumerics, '_', '~', '{', or '}'

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

@artivis Would you be willing to open an issue about declare_parameter('foo.str_param', 'foo') not working on the rclpy repo? https://github.com/ros2/rclpy/issues/new

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like an issue has been opened ros2/rclpy#373

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok great, thanks.

@artivis
Copy link
Contributor Author

artivis commented Jun 19, 2019

Before this PR to be ready for review,

@artivis artivis changed the title Feature/param dump Add param dump <node-name> Jun 19, 2019
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
@artivis
Copy link
Contributor Author

artivis commented Jun 20, 2019

PR is subject to changes once ros2/rclpy#373 is fixed.
In the meantime the overall script works and review can start.

@artivis artivis marked this pull request as ready for review June 20, 2019 12:53
@jacobperron jacobperron added the in review Waiting for review (Kanban column) label Jun 25, 2019
@kyrofa
Copy link
Member

kyrofa commented Jun 27, 2019

@artivis ros2/rclpy#377 has been merged, can this be updated?

@artivis
Copy link
Contributor Author

artivis commented Jun 27, 2019

@kyrofa yep, I'll get to it 👍

Signed-off-by: artivis <jeremie.deray@canonical.com>
@artivis
Copy link
Contributor Author

artivis commented Jun 27, 2019

@sloretz This PR now uses PARAMETER_SEPARATOR_STRING and the test is passing properly.
Ready for review.

@artivis
Copy link
Contributor Author

artivis commented Jul 16, 2019

@sloretz Please let me know if there is anything I can do to help push this forward.

Copy link
Contributor

@sloretz sloretz left a comment

Choose a reason for hiding this comment

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

Added a few comments


# extract type specific value
pvalue = response.values[0]
if pvalue.type == ParameterType.PARAMETER_BOOL:
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this code could be shared with ros2 param get. In fact, here's a function with part of it. Mind moving this code to ros2param/api/__init__.py? I'll create a ticket to follow up with get.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done here.

'--include-hidden-nodes', action='store_true',
help='Consider hidden nodes as well')
parser.add_argument(
'--file-path',
Copy link
Contributor

Choose a reason for hiding this comment

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

nit, recommend --output-dir. Despite the help text I mistakenly thought this was the name of a file. Alternatively outputing to stdout with the expectation that users will pipe to a file seems like another reasonable option.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How about having both options ? Adding a --print flag or such that take precedence over saving to a file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good to me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done 907f1be

ros2param/ros2param/verb/dump.py Outdated Show resolved Hide resolved
"'{node_name.full_name}': {e}".format_map(locals()),
file=sys.stderr)

print('Saving to: ', os.path.join(args.file_path, node_name.name + ".yaml"))
Copy link
Contributor

Choose a reason for hiding this comment

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

There are a few places that assume a fully qualified node name is unique, so making the output file name include the namespace seems appropriate. Recommend replacing node_name.name with absolute_node_name.replace('/', '__')

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The output file name and only that ? Not sure how it works with namespaces now that the node name is the first entry in the yaml file...
Also should I filter for leading ' / ' in absolute_node_name ?

Copy link
Contributor

Choose a reason for hiding this comment

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

The output file name and only that ?

Yeah, I was just thinking it would make this case more convenient. It looks like the second call would overwrite the first if only using node_name.name for the file name.

ros2 param dump /left/camera --output-dir .
ros2 param dump /right/camera --output-dir .

Also should I filter for leading ' / ' in absolute_node_name ?

Sure. The absolute name always begins with /, so that should be easy to remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done e41232c

ros2param/test/test_verb_dump.py Outdated Show resolved Hide resolved
@artivis
Copy link
Contributor Author

artivis commented Jul 24, 2019

@sloretz Thanks for the review, will address it asap.

Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
artivis and others added 5 commits July 25, 2019 16:11
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: artivis <jeremie.deray@canonical.com>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz<sloretz@openrobotics.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
@sloretz
Copy link
Contributor

sloretz commented Jul 25, 2019

@artivis This looks good to me! Would you mind checking that commits: 38944d9,
04d9112, and 0f1b534 look ok?

CI (Build up to ros2param, testing ros2param)

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@sloretz
Copy link
Contributor

sloretz commented Jul 25, 2019

@artivis Looks like there are some linter complaints. Mind addressing them?

https://ci.ros2.org/job/ci_linux/7667/testReport/junit/ros2param.test/test_flake8/test_flake8/

@@ -127,5 +127,5 @@ def main(self, *, args): # noqa: D102
file_name = absolute_node_name.replace('/', '__')

print('Saving to: ', os.path.join(args.output_dir, file_name + '.yaml'))
with open(os.path.join(args.output_dir, node_name.name + '.yaml'), 'w') as yaml_file:
with open(os.path.join(args.output_dir, file_name + '.yaml'), 'w') as yaml_file:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oups ><

@artivis
Copy link
Contributor Author

artivis commented Jul 26, 2019

@artivis This looks good to me! Would you mind checking that commits: 38944d9,
04d9112, and 0f1b534 look ok?

Looks good to me 👍

@artivis
Copy link
Contributor Author

artivis commented Jul 26, 2019

@artivis Looks like there are some linter complaints. Mind addressing them?

https://ci.ros2.org/job/ci_linux/7667/testReport/junit/ros2param.test/test_flake8/test_flake8/

I'll take care of it no problem. However that linter test passes on my machine. Do I have something mis-configured or something ?

@clalancette
Copy link
Contributor

I'll take care of it no problem. However that linter test passes on my machine. Do I have something mis-configured or something ?

Typically that is the case, yeah. Flake8 has an annoying behavior that it will only run the linters that are installed, so if you forget one, it just won't run it. Anyway, I'd suggest re-running through the installation instructions, which should fetch the ones you are missing.

Signed-off-by: artivis <jeremie.deray@canonical.com>
@artivis
Copy link
Contributor Author

artivis commented Jul 26, 2019

@clalancette Thanks, I was indeed missing some linters 👍.
However I am getting some warnings now like the following:

lib/python3.6/site-packages/_pytest/mark/structures.py:332: PytestUnknownMarkWarning: Unknown pytest.mark.copyright - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
    PytestUnknownMarkWarning,

lib/python3.6/site-packages/_pytest/mark/structures.py:332: PytestUnknownMarkWarning: Unknown pytest.mark.linter - is this a typo? ....

Any idea ?

@clalancette
Copy link
Contributor

Any idea ?

Yeah, I see those as well. I think those are just warnings from Python itself, and can be safely ignored. At least, they don't seem to cause problems in CI or in the code itself.

@artivis
Copy link
Contributor Author

artivis commented Jul 26, 2019

Yeah, I see those as well. I think those are just warnings from Python itself, and can be safely ignored. At least, they don't seem to cause problems in CI or in the code itself.

Ok, thanks 👍

@sloretz
Copy link
Contributor

sloretz commented Jul 26, 2019

CI (testing just ros2param)

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status -- failed to delete workspace
    • Build Status


# Make sure the file was not create, thus '--print' did preempt
expected_err = '[Errno 2] No such file or directory: ' \
"'{not_generated_param_file}'".format_map(locals())
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like the error text is slightly different on windows. Maybe relax this check to assert 'No such file or directory' in context.exception?

https://ci.ros2.org/job/ci_windows/7522/testReport/junit/ros2param.test.test_verb_dump/TestVerbDump/test_verb_dump_print/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's surprising.
See 7b508a0.

Signed-off-by: artivis <jeremie.deray@canonical.com>
@sloretz
Copy link
Contributor

sloretz commented Jul 26, 2019

CI (testing ros2param)

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@artivis
Copy link
Contributor Author

artivis commented Jul 26, 2019

@sloretz Genuine curiosity, does the ci kicks in from keywords ? Can anyone launch it ??

@sloretz
Copy link
Contributor

sloretz commented Jul 26, 2019

@artivis The CI jobs for all platforms are started manually. The ros2 build farm supports PR jobs which would run an ubuntu job automatically, but it looks like this repo isn't yet set up for that

Copy link
Contributor

@sloretz sloretz left a comment

Choose a reason for hiding this comment

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

CI looks good. Thanks for the PR @artivis !

@sloretz sloretz merged commit d804e11 into ros2:master Jul 26, 2019
@artivis artivis deleted the feature/param_dump branch July 26, 2019 20:33
@kyrofa kyrofa mentioned this pull request Sep 4, 2019
34 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in review Waiting for review (Kanban column)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants