Can DeclareLaunchArgument accept dictionaries?
Problem (TL;DR)
ROS2 uses the DeclareLaunchArgument
object to create launch parameters that can be overwritten by command line or an including launch file. I know you can use this with parameters that are strings (incl filepaths), bools, integers and floats. But I want to know if it is possible to input dictionaries as well. I haven't yet found a way to do this, and I'm not sure if it's possible.
Problem (in full)
Problem described as above. So far I've tried in ROS2 Foxy, and I haven't yet found anything that would lead me to believe this is explicitly possible in Galactic. The example I'm working with looks something like this:
// In including_launch.py
launch_description = IncludeLaunchDescription(
PythonLaunchDescriptionSource(["~/some_package/launch/included_launch.py"]),
launch_arguments={
params={'num' : 1234, 'bool' : true, 'str' : "hello" },
}
)
// In included_launch.py
params = LaunchConfiguration('params')
params_declare = DeclareLaunchArgument('params', default_value={})
node1 = Node(
package="some_package",
...
parameters=[params]
...
)
If I try this example as-is, I get the following warning:
[WARNING] [launch_ros.actions.node]: Parameter file path is not a file: numboolstr
If I try turning the dictionary into a string inside the IncludeLaunchDescription call, the dictionary doesn't get mangled, but DeclareLaunchArgument still doesn't like it:
[WARNING] [launch_ros.actions.node]: Parameter file path is not a file: {'num' : 1234, 'bool' : true, 'str' : "hello" }
I've been reading through examples and source code to see if this can be achieved, but so far haven't found anything that works.
Asked by M@t on 2021-08-23 19:21:08 UTC
Answers
Looking at the DeclareLaunchArgument
constructor: no, it cannot accept dictionaries.
It looks like your intent is to provide a map of argument names (key) and default values (value). If so, may I suggest maintaining a collection of DeclareLaunchArgument
actions? That way, you could do:
launch_args = [DeclareLaunchArgument(name, default_value=default_value) for name, default_value in params.items()]
Then, as required, you could do a map(launch_args, LaunchDescription.add_action)
- which would add each of your DeclareLaunchArgument
actions to the LaunchDescription
you are instantiating.
Asked by aprotyas on 2021-08-24 03:26:07 UTC
Comments
Interesting suggestion, but I'm unclear on some of the implementation details - what would that look like as an example similar to the one in my question?
Asked by M@t on 2021-08-24 18:15:00 UTC
Sorry, my suggestion was a bit unclear. I mean something like this:
Instead of the line where you use params_declare = DeclareLaunchArgument('params', default_value={})
, just replace it with launch_args = [DeclareLaunchArgument(name, default_value=default_value) for name, default_value in params.items()]
. Also, for the LaunchDescription
you generate, you can add the DeclareLaunchArgument
actions by performing a map procedure on launch_args
(the collection of DeclareLaunchArgument
s): this can be achieved using map(launch_args, ld.add_action)
, where ld
is the LaunchDescription
you initialized beforehand.
Asked by aprotyas on 2021-08-24 18:29:31 UTC
In the launch_ros repo examples there is the following example which I think achieves what you are looking for.
def generate_launch_description():
"""Launch the example.launch.py launch file."""
return LaunchDescription([
LogInfo(msg=[
'Including launch file located at: ', ThisLaunchFileDir(), '/example.launch.py'
]),
IncludeLaunchDescription(
PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/example.launch.py']),
launch_arguments={'node_prefix': 'FOO'}.items(),
),
])
Asked by msmcconnell on 2021-11-24 10:44:30 UTC
Comments