15 from typing
import List
17 from launch
import LaunchDescription
18 from launch
import LaunchDescriptionSource
19 from launch.actions
import DeclareLaunchArgument
20 from launch.actions
import IncludeLaunchDescription
21 from launch.actions
import OpaqueFunction
23 from launch.utilities
import perform_substitutions
24 from launch.substitutions
import LaunchConfiguration
26 from launch_ros.actions
import Node
27 from launch_ros.descriptions
import Parameter
33 """Decorate generate_launch_description function to resolve launch arguments early."""
35 def decorator(get_launch_description_f):
37 launch_configurations_for_arguments = [
38 LaunchConfiguration(arg.name)
for arg
in arguments_to_declare
43 perform_substitutions(
44 context, config.variable_name
45 ): config.perform(context)
46 for config
in launch_configurations_for_arguments
49 IncludeLaunchDescription(
50 LaunchDescriptionSource(
51 get_launch_description_f(**resolved_args)
56 return LaunchDescription(
58 *arguments_to_declare,
59 OpaqueFunction(function=action),
69 *, params_file, name, namespace='/', extra_params={}, **kwargs
72 Declare arguments from param file.
74 Currently ROS 2 argument handling is a bit broken ...
75 If you specify a parameter file, there's no way to override the parameter value, except with
78 Some magic to be able to easily override parameter values specified in a file from launch ...
80 full_name = f
'{namespace}/{name}'
81 full_name_without_starting_slash = full_name.lstrip(
'/')
82 full_name_with_slash = f
'/{full_name_without_starting_slash}'
83 with open(params_file)
as params_file:
84 params_file_dict = yaml.safe_load(params_file)
86 if full_name_with_slash
in params_file_dict:
87 node_name_key = full_name_with_slash
88 if full_name_without_starting_slash
in params_file_dict:
89 node_name_key = full_name_without_starting_slash
90 if node_name_key
is None:
91 launch.logging.get_logger().warning(
92 f
"parameters file has no parameters for node '{full_name_without_starting_slash}'"
94 return [Node(name=name, namespace=namespace, **kwargs)]
95 entries_for_node = params_file_dict[node_name_key]
96 if 'ros__parameters' not in entries_for_node:
97 launch.logging.get_logger().warning(
98 f
"parameters file does not have a 'ros__parameters' entry for node "
99 f
"'{full_name_without_starting_slash}'"
101 return [Node(name=name, namespace=namespace, **kwargs)]
102 params_dict = entries_for_node[
'ros__parameters']
103 params_dict.update(extra_params)
106 for param_name, param_value
in params_dict.items():
108 DeclareLaunchArgument(
109 name=f
'{full_name_without_starting_slash}.{param_name}',
110 default_value=str(param_value),
116 value=LaunchConfiguration(
117 f
'{full_name_without_starting_slash}.{param_name}'
122 Node(name=name, namespace=namespace, parameters=parameters, **kwargs)