ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

[ROS2] Substituting a parameter from confg file while keeping others within Python launch file

asked 2022-06-09 11:54:11 -0500

updated 2022-06-10 03:06:11 -0500

Hey all,

I am trying to substitute (or prepend) specific parameters from a Python launch file in ROS2. I have filenames specified in launch files, that must be passed as full paths to ROS nodes via launch parameters. Therefore, the filenames from

The problem is, is there a way to prepend some text to specifically one parameters out of the configuration file? All I can think of is to parse the YAML config file in python and then just place it as a dict into the parameters field.

My YAML config file:

tb_lm:
      efficiency_map:
        ros__parameters:
          filename: "PMSynRM.csv"

And this is my launch file:

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():

    ld = LaunchDescription()
    config = os.path.join(
        get_package_share_directory('loading_motor_dt'),
        'config',
        'params.yaml'
        )

    data_processor=Node(
        package = 'loading_motor_dt',
        namespace = 'tb_lm',
        name = 'efficiency_map',
        executable = 'efficiency_map',
        parameters = [config]
    )
    ld.add_action(data_processor)
    return ld

How can I grab the filename out of config and prepend to it the $HOME path for example (or even a string?) is there a ROS2 way to do this, or better to just transform the YAML into dict, and substitute whatever is required, and pass it to the parameters?

EDIT 1

Here is the update config file for what I am trying to achieve:

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
import yaml
from pathlib import Path

home = str(Path.home())

"""Used to grab the contents of configuration YAML and
   prepend full paths to all the filenames fields"""
def prepend_to_filenames(config_file, package_name):

    with open(config_file, "r") as f:
        config_yaml = yaml.safe_load(f)

    for ns in config_yaml:
        for node in config_yaml[ns]:
            try:
                filename = config_yaml[ns][node]["ros__parameters"]["filename"]
                config_yaml[ns][node]["ros__parameters"]["filename"] = os.path.join(
                    get_package_share_directory(package_name),'data_files', filename)
            except:
                pass
    # For DEBUG purposes only
    with open(os.path.join(home,"debug.yaml"),'w') as f:
        yaml.dump(config_yaml, f)

    return config_yaml

def generate_launch_description():

    ld = LaunchDescription()
    config = os.path.join(
        get_package_share_directory('loading_motor_dt'),
        'config',
        'params.yaml'
        )

    params_prepended = prepend_to_filenames(config, "loading_motor_dt")

    data_processor=Node(
        package = 'loading_motor_dt',
        namespace = 'tb_lm_left',
        name = 'efficiency_map',
        executable = 'efficiency_map',
        parameters = [params_prepended]
    )
    ld.add_action(data_processor)
    return ld
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2022-06-09 12:18:29 -0500

Joe28965 gravatar image

Yes, you can! Nav2 has a tool called RewrittenYaml that does just that! I couldn't find an actual tutorial for RewrittenYaml but I did find this that does use it in the launch file.

edit flag offensive delete link more

Comments

Hey! Thanks for the RewrittenYaml suggestion! I will tinker with it a bit and get back here if I get any results

sejego gravatar image sejego  ( 2022-06-09 14:30:56 -0500 )edit

Hey again @Joe28965.

RewrittenYaml works well for replacement of parameters, but I did not find a good way to prepend file names to the specific parameters.

I tried to opening the configuration yaml with PyYaml and substituting the parameters, it works well (I verified by looking at created debug YAML file), however, it seems that the Python dictionary is not accepted by the parameters field of the Node from launch_ros.actions. Please refer to the EDIT 1 of my question to see the updated launch file.

sejego gravatar image sejego  ( 2022-06-10 03:05:17 -0500 )edit

What would happen if you use RewrittenYaml to write os.path.join(get_package_share_directory(package_name),'data_files', filename) to config_yaml in the same way as that example i gave you replaces yaml_filename with mask_yaml_file.

If that doesn't work, you might also look at how Nav2 does it with RViz in these lines. In those lines it replaces <robot_namespace> with the namespace in the rviz file. I don't know 100% if that would work with yaml files too, but I don't see why it wouldn't

Joe28965 gravatar image Joe28965  ( 2022-06-13 01:32:45 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2022-06-09 11:54:11 -0500

Seen: 707 times

Last updated: Jun 10 '22