ROS 2 Variables Substitution Inside YAML
Hi,
in ROS1, I was able to use $(arg variable) inside the YAML if the attribute subst_value was set to true in the Launch file.
However, in ROS 2 (using KUbuntu 20 LTS + ROS 2 Foxy), there seems to be no alternative to do that.
Although setting the parameter in the launch file could be an alternative, I am uses environment variable to set the namespace of the nodes. And that is not possible to properly define the parameters in the YAML without putting in plain text the variable's value.
launch.py
import os
import yaml
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.launch_context import LaunchContext
from launch.substitutions import EnvironmentVariable, LaunchConfiguration
def generate_launch_description():
context = LaunchContext()
robot_id = LaunchConfiguration('robot_id')
robot_id_launch_arg = DeclareLaunchArgument(
name='robot_id',
default_value=EnvironmentVariable(
name='ROBOT_ID',
default_value='unnamed_robot'
)
)
sdpo_hangfaq2_driver_param_path = os.path.join(
FindPackageShare('sdpo_hangfaq2_driver').perform(context),
'config','sdpo_hangfaq2_driver.yaml'
)
with open(sdpo_hangfaq2_driver_param_path, 'r') as param_file:
sdpo_hangfaq2_driver_param = yaml.load(
stream=param_file,
Loader=yaml.SafeLoader
)
sdpo_hangfaq2_driver_node = Node(
namespace=robot_id,
package='sdpo_hangfaq2_driver',
executable='sdpo_hangfaq2_driver',
name='sdpo_hangfaq2_driver',
parameters=[sdpo_hangfaq2_driver_param]
)
return LaunchDescription([
robot_id_launch_arg,
sdpo_hangfaq2_driver_node
])
yaml
/$(var robot_id):
sdpo_hangfaq2_driver:
ros__parameters:
encoder_res: 48.06666
gear_reduction: 64.06666
serial_port_name: "/dev/ttyACM06666"
Best regards,
Ricardo
Asked by Ricardo B. Sousa on 2023-07-20 05:09:56 UTC
Answers
I'm not sure if doing a substitution in the yaml parameters file is possible. However, you should be able to load a default parameters files and then replace an element of the loaded dict with your LaunchConfiguration
variable. This should enable setting the robot_id at runtime.
Asked by jdlangs on 2023-07-20 10:15:29 UTC
Comments
The problem is that /$(var robot_id): in the YAML file is a key of the dictionary, not a parameters' value... only if we pop the variable, change the key accordingly, and then push again the variable to the dictionary...
Asked by Ricardo B. Sousa on 2023-07-20 11:37:10 UTC
Isn't that key a node namespace? Why not use the namespace
argument for launch_ros.actions.Node
(which can be substituted) and then load parameters as a plain dict?
Asked by jdlangs on 2023-07-20 15:32:35 UTC
Although I did not find a way to substitute values inside YAML similar to ROS 1, launch.xml format allows nested parameters and use the substitution:
<launch>
<arg name="robot_id" default="$(env ROBOT_ID 'unnamed_robot')"/>
<node pkg="vineslam_ros" exec="slam_node"
name="slam_node"
namespace="$(var robot_id)">
<remap from="/odom_topic" to ="odom"/>
<remap from="/scan_topic" to ="scan"/>
<param name="world_frame_id" value="$(var robot_id)/map"/>
<param name="odom_frame_id" value="$(var robot_id)/odom"/>
<param name="base_frame_id" value="$(var robot_id)/base_footprint"/>
<param name="lidar_sensor_frame" value="$(var robot_id)/rslidar"/>
<param name="use_semantic_features" value="False"/>
<param name="use_lidar_features" value="True"/>
<param name="use_vertical_planes" value="False"/>
<param name="use_ground_plane" value="False"/>
<param name="use_imu" value="False"/>
<param name="use_gyroscope" value="False"/>
<param name="use_gps" value="False"/>
<param name="use_gps_altitude" value="False"/>
<param name="use_gps_heading" value="False"/>
<param name="publish_level" value="2"/>
<param name="robot_dimensions">
<param name="x" value="0.42"/>
<param name="y" value="0.32"/>
<param name="z" value="0.37"/>
</param>
<param name="multilayer_mapping">
<param name="datum">
<param name="latitude" value="45.706199"/>
<param name="longitude" value="7.2495435"/>
<param name="altitude" value="668.63"/>
</param>
<param name="topological_map">
<param name="autogen_topological_map" value="True"/>
<param name="folder" value="/home/sousarbarb/.ros/vineslam/"/>
<param name="dimensions">
<param name="x" value="100.0"/>
<param name="y" value="100.0"/>
<param name="square_size" value="20.0"/>
</param>
</param>
<param name="grid_map">
<param name="origin">
<param name="z" value="0.0"/>
</param>
<param name="height" value="30.0"/>
<param name="resolution" value="0.25"/>
</param>
</param>
<param name="pf">
<param name="n_particles" value="300"/>
<param name="sigma_xx" value="0.3"/>
<param name="sigma_yy" value="0.3"/>
<param name="sigma_zz" value="0.2"/>
<param name="sigma_RR" value="0.1"/>
<param name="sigma_PP" value="0.1"/>
<param name="sigma_YY" value="0.2"/>
</param>
</node>
</launch>
Asked by Ricardo B. Sousa on 2023-07-26 03:49:37 UTC
Comments