Ask Your Question
1

[ROS2 YAML] Config file without node name

asked 2018-09-26 11:19:43 -0600

Myzhar gravatar image

updated 2018-09-27 04:20:23 -0600

Is it possible to write a YAML parameter file without specifying the ROS2 node name?

The current format for a YAML file is the following:

namespace:
    node_name:
        ros__parameters:
            general:
                param_1: 0
                param_2: 'a'
                param_3: 3.14

The problem comes when I have a launch file that can dynamically change the namespace and the node_name (multi robot for example). How can the config YAML file be adapted to the dynamic change?

Thank you Walter

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2019-12-10 12:57:32 -0600

yossi_ov gravatar image

Well, I found a solution to that.

TL;DR put double asterisk instead of the node name in YAML file.

Elaborate demonstration is on GitHub: https://github.com/yossioo/ros2-yaml-unnamed-node

Feel free to comment is something is unclear.

edit flag offensive delete link more
0

answered 2018-09-26 12:16:25 -0600

dhood gravatar image

It is not currently possible to write a parameters YAML file that does not include the node's name. However, there is a very recent pull request that added functionality to launch_ros so that parameters can be specified in the launch file. If the node's name/namespace is modified in the launch file, that will be taken into account.

This feature has been implemented but not yet released; it will be included (with more documentation) in the Crystal release at the end of 2018. If you would like to use the functionality in the meantime, you can build ROS 2 from source using the 'master' branches as described here. This is an example of the usage today (syntax and naming may change in the future).

import os

from launch import LaunchDescription
from launch.substitutions import EnvironmentVariable
import launch_ros.actions

def generate_launch_description():
    os.environ['MY_ENV_VAR'] ='my_env_value'
    return LaunchDescription([
        launch_ros.actions.Node(
            package='demo_nodes_cpp', node_executable='talker', node_name='my_talker', node_namespace='my_ns',
            output='screen',
            parameters=[
                {'my_param': EnvironmentVariable(name='MY_ENV_VAR')},
            ],
            log_cmd=True,
        ),
    ])
edit flag offensive delete link more

Comments

Interesting. A curiosity: why the variable must be an Environment Variable?

Myzhar gravatar imageMyzhar ( 2018-09-26 13:29:36 -0600 )edit

Just showing an example of the substitutions; you can use plain strings/python variables in the dictionary also.

dhood gravatar imagedhood ( 2018-09-26 15:07:11 -0600 )edit
0

answered 2018-11-08 12:04:53 -0600

lucasw gravatar image

updated 2018-11-08 13:44:42 -0600

I'm writing the yaml file to a temp location in bouncy:

import yaml
...
   prefix = "/tmp/"  # TODO make a unique name base on current time
   # usb camera
    usb_cam_params = prefix + "usb_cam.yaml"
    with open(usb_cam_params, 'w') as outfile:
        print("opened " + usb_cam_params + " for yaml writing")
        data = dict(
            usb_cam = dict(
                ros__parameters = dict(
                    video_device = device,
                    framerate = framerate,
                    io_method = "mmap",
                    frame_id = "camera",
                    pixel_format = "yuyv",
                    image_width = width,
                    image_height = height,
                    camera_name = "camera",
                )
            )
        )
        yaml.dump(data, outfile, default_flow_style=False)
    # TODO probably should check if above succeeded
    launches.append(launch_ros.actions.Node(
        package='usb_cam', node_executable='usb_cam_node', output='screen',
        arguments=["__params:=" + usb_cam_params]
        ))

The 'usb_cam' is hard coded above but the dict can be changed to use a variable for the name like:

        data = {}
        data[node_name] = dict(ros__parameters = dict(
                    frame_rate = 0.0,
                    width = small_width,
                    height = small_height,
                    ))

https://github.com/lucasw/image_manip...

But then the parameters are still hard coded within the launch.py - get them from command line with sys.argv? Argparse works.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2018-09-26 11:19:43 -0600

Seen: 781 times

Last updated: Dec 10 '19