ROS2 accessing command line argument values in launch.py files
using ROS2 Foxy
I have really been struggling how to do 2 seemly simply thing with a launch file. By launch file I mean launch.py not xml.
The 2 things I am trying to do are: 1 pass a command line argument the controls whether to launch a node or not. Recently I found 2 ways to do that see below. 2 pass in the name of a specific config file or world (the file name only not the full path) and have the launch file append the current package config or world folder and pass it on to a node as a parameter or argument
Maybe I am missing something and to help someone else I am including my understand of a launch.py. For ROS1 there were clear tutorials for this but I could find any for ROS2.
My understanding of how this works
First imports
import os ---import this so you can use os.path.join( function
from launch.actions import IncludeLaunchDescription --- import this if you want to include another launch.py file using IncludeLaunchDescription( function
from launch.conditions import IfCondition -- import this to conditional launch a node (only discovered this yesterday and answers my #1)) use on this function condition=IfCondition(LaunchConfiguration('use_rviz')) on a Node( statement
from ament_index_python.packages import get_package_share_directory -- allows pkg_gazebo_ros = get_package_share_directory('gazebo_ros') to get share folder so that you could then use os.path.join to point to the config or world folder
from launch import LaunchDescription -- required
from launch.actions import DeclareLaunchArgument --- needed to declare command line arguments
from launch.substitutions import LaunchConfiguration --- I think this is a way to access the argument??
from launch_ros.actions import Node -- required to use Node statement
Second functions
After you have the imports you need this line def generate_launch_description():
You also need return LaunchDescription([ alistofnodes ])
How to declare arguments
in order for commandline argument to work you need to use DeclareLaunchArgument.
DeclareLaunchArgument( 'use_rviz', default_value='false', description='Use rviz if true'),
Does this have to happen inside the LaunchDescription( function? If so that seem too late. I would think these are like variable declarations and you would want them well before the LaunchDescription( which is typically the last section.
How to access those values I think you use LaunchConfiguration use_rviz = LaunchConfiguration('use_rviz') But this actual returns a LaunchConfiguration object not the value see below
How to launch a node
apparently there are several options you can use Node()
Node( package='rviz2', executable='rviz2', name='rviz2', argument=[], paramters=[] output='screen')
there is ExecuteProcess( also
OpaqueFunction
This is a function that can bee called inside LaunchDescription( that calls a function you write. It can access argument by using LaunchConfiguration('use_rviz').perform(context). You can then use an if statement to build nodes and then return those nodes
Is my understanding correct? Does anyone see anything wrong with my statements above?
Now for the 2 things I am trying to do.
Conditionally create nodes based on command line argument. I figures out 2 ways to do this ...