You are currently viewing Tutorial: ROS2 launch files – All you need to know

Tutorial: ROS2 launch files – All you need to know

Introduction

ROS2 launch files are a powerful tool for robotics applications. Instead of starting each process manually, they allow you to start multiple nodes with one command and add logic to your startup sequence. This tutorial will explain everything you need to know about ROS2 launch files.

We will start simple by creating a basic launch file and adding it to a package. Then we will discover launch actions, event_handlers, substitutions and conditions in more detail. Afterwards we will discuss common questions and use cases for ROS2 launch files and at the and of the article you can find a list of all the common actions, event_handlers and substitutions that you can use in your launch file. Sounds good? Let’s get started!

In this tutorial we will discuss

Note: In ROS2 you can also create launch files in XML and yaml format but for this tutorial we will concentrate on launch files written in Python. This tutorial is for ROS2 Humble.

This is the first article I am writing for ROS2. I started to look into it a few months ago and got stuck on launch files when porting my tutorials so I decided start with a tutorial on launch files. I hope to publish more articles on ROS2 in the future.

Getting started with ROS2 launch files

Writing the launch file

The following code snippet is the basic skeleton you need for every launch file:

from launch import LaunchDescription

def generate_launch_description():
    return LaunchDescription([
        # add your actions here...
    ])

Every launch file has a generate_launch_description function that returns a LaunchDescription object. To make the launch file do something we need to add actions to that object.

For our first launch let’s choose a simple example. We start the turtlesim node that you might know from the ROS tutorials and that should already be installed. There are two ways you can add actions to a LaunchDescription object. The first option is to add the action to the constructor as follows:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='turtlesim',
            executable='turtlesim_node',
            name='sim'
        ),
    ])

You can add as many actions as you want. Simply put one action after another into the array in the constructor of LaunchDescription and remember to separate them by commas.

The second option is to create the LaunchDescription object (called ld in the following example) and afterwards add the actions via the add_action method:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    ld = LaunchDescription()
    turtlesim_node = Node(
        package="turtlesim",
        executable="turtlesim_node",
        name='sim'
    )

    ld.add_action(turtlesim_node)
    return ld

Either way is fine, just pick one based on your preference. The action we are adding in our first simple launch file is a Node. That means, this launch file will start the node as if you would execute

ros2 run turtlesim turtlesim_node

in your terminal.

In lines 1 and 2 of the example you can see imports to our python file. The launch module contains generic classes that are ROS-independent while the launch_ros module provides ROS-specific classes. The line 1 for importing LaunchDescription is always required. To add the Node we need to import Node from launch_ros.actions in line 2.

Launch files should have the ending launch.py so now you can save the above example in your preferred directory as my_first_launch_file.launch.py. After creating the launch file you can go to that directory and run:

ros2 launch my_first_launch_file.launch.py

This will launch the turtlesim node.

Adding the launch file to an existing package

Instead of lonely files languishing in your file system, waiting for someone to find them, launch files are often part of a package. When a launch file is provided by a package you can run it from everywhere.

To show the steps we will create an example package with only the launch file. You can follow along if you want by executing the following commands inside your workspace (dev_ws in this example):

cd ~/dev_ws/src
ros2 pkg create launch_example_package
cd launch_example_package
rm -rf include/
rm -rf src/
mkdir launch

Now you need to copy the launch file into the launch folder we just created inside the package with the mkdir launch command. Then, inside the CMakeLists.txt file add the following lines after the find_package command:

install(DIRECTORY launch DESTINATION share/${PROJECT_NAME}/)

Now when we rebuild the workspace with

colcon build

all the files inside our launch directory will be installed in the share directory. After sourcing the environment:

source install/local_setup.bash

we can start the launch file from every directory using the following command:

ros2 launch launch_example_package my_first_launch_file.launch.py

If you want to add your launch file to a python package, add the following lines to your setup.py file:

    data_files=[
        ...
        (os.path.join('share', package_name), glob('launch/*.launch.py'))
    ],

It is also good practice to add a dependency to ros2launch to the package.xml file of your package:

<exec_depend>ros2launch</exec_depend>

Now you know how to create launch files and add them to a package. Let’s have a look at the functionalities that make ROS2 launch files so powerful.

Important ROS2 launch concepts

On a basic level, there are actions to define what the launch file should execute and then there are substitutions, event_handlers and conditions to make your launch file more intelligent and flexible. Let’s start with actions.

ROS2 launch actions

Actions are specific things we want our launch file to do. In our simple example we already used the Node action. Generic actions can be imported from launch.actions while ROS-specific actions come from the ros_launch.actions module.

Let’s have a look at the Node we defined in our simple launch file example:

    turtlesim_node = Node(
        package="turtlesim",
        executable="turtlesim_node",
        name='sim'
    )

You can see that in lines 2 to 4 we specify different arguments for the Node action. The executable option is mandatory while others are optional. However, in most cases your executable will be in a specific package and you will want to give it a name as in the example above. You will see the specified name if the action writes a terminal output.

Additional Node options are:

  • namespace: Launch the Node in a namespace, e.g. turtlesim1
  • exec_name: Name of the process. Default is the same as name
  • parameters: List of parameter files that are loaded for the Node (e.g. parameters="my_params.yaml")
  • remappings: Remapping of node names, e.g. remappings=[('/input/pose', '/turtlesim1/turtle1/pose')]
  • ros_arguments: List of ROS arguments to hand over to the Node, e.g. ros_arguments=['__log_disable_rosout', 'true']
  • arguments: List of arguments to hand over to the Node, e.g. arguments=['-name', 'my_robot']

These options are specific for a Node action and as you can see, there are a lot of configurations. For other actions there are different configuration options. You can check how to use the actions with the mandatory options in the list of common actions at the end of this article. If you want to know all the options in detail you need to find example usages or bite the bullet and check the respective class definition in the source code (e.g. action classes for launch_ros actions are defined here)

One option you can add to any actions is a condition, e.g. condition=IfCondition(use_gui). We will discuss the use of conditions in detail in this section.

One special type of action is the GroupAction that allows you to group actions and that way scope them. What does that mean? It means that you can define conditions, set parameters, forward launch configurations etc. only for the actions in that specific group:

       LaunchDescription([
            ...,
            GroupAction(
                condition=IfCondition(use_gui),
                actions = [
                    ...,
                    SetParametersFromFile('path/to/file.yaml'),
                    ...,
                    Node(...),  // the Node will be started when the condition is
 fullfilled and params will be passed to this node
                    ...,
                ]
            ),
            Node(...),  // This node is not dependent on the condition and the
 parameters will not be passed, as it is not in the same scope
            ...
        ])

There are many additional actions you can add to your launch file. You can find a list of the most common ROS2 launch actions at the end of the article. Now let’s talk about event handlers to make our launch files more intelligent!

ROS2 launch event handlers

The processes we are starting from the launch files have different states, i.e. they are starting, running, stopping, etc.. When the state of a process changes we call it an event and event handlers allow us to react to those events.

Let’s look at a concrete example. One common event handler is OnExecutionComplete which triggers when a process finished its execution:

from launch import LaunchDescription
from launch.actions import RegisterEventHandler
from launch_ros.actions import Node
from launch.event_handlers import OnExecutionComplete
 
def generate_launch_description():
    
    turtlesim1 = Node(
        package="turtlesim",
        executable="turtlesim_node",
        name='turtlesim1'
    )

    turtlesim2 = Node(
        package="turtlesim",
        executable="turtlesim_node",
        name='turtlesim2'
    )

    return LaunchDescription([
        RegisterEventHandler(
            event_handler=OnExecutionComplete(
                target_action=turtlesim1,
                on_completion=[turtlesim2],
            )
        ),
        turtlesim1
    ])

In our example, turtlesim2 will be started after turtlesim1 finished its execution. As you see in line 21 we need to register our event handler using the RegisterEventHandler() action. With the event_handler argument in line 22 we define the type of handler to use, in our case OnExecutionComplete. The two arguments we hand over to the handler are target_action which defines the process that triggers the event and on_completion where we can give an array of processes that should be executed after the event occurred.

Note that you need to define your actions, like the turtlesim1 Node, just as before. The event handler is just additional logic that connects your actions.

There are additional event handlers like OnShutdown which allows you to start e.g. a clean up process when the launch file is shut down. You can find a list of additional event handlers with brief descriptions at the end of this article.

ROS2 launch substitutions

Substitutions are convenient to make your launch file more flexible. Instead of hard coding all values you can get information from outside your launch file which is then substituted only when you execute it. That information can be environment variables, launch configurations or even Python expressions.

Let’s look at an example using the EnvironmentVariable substitution:

from launch import LaunchDescription
from launch.substitutions import EnvironmentVariable
from launch_ros.actions import Node

def generate_launch_description():
   return LaunchDescription([
      Node(
            package='turtlesim',
            executable='turtlesim_node',
            name=[EnvironmentVariable('USER'), '_turtlesim'],
      ),
   ])

We start a turtlesim_node just as before but Inside the name option in line 10 we get the environment variable USER and substitute part of the name with it. When you try the above example you should see a log message saying something like:

[turtlesim_node-1] [INFO] [1668755981.563376983] [<your_name>_turtlesim]: Starting turtlesim with node name /<your_name>_turtlesim

When I start the launch file, the node will be called “alex_turtlesim” because alex is my user name.

Note: In case you never heard of environment variables: They are dynamic values that you can access inside the environment your process runs in, in this case the terminal from which you start the launch file. The environment variable ‘USER’ is defined by the system and holds the name of the user that is currently logged in.

Another convenient substitution is the PathJoinSubstitution class. It allows you to construct the path to a file. The following example starts the visualizer Rviz with a config file that was constructed by the PathJoinSubstitution class:

from launch_ros.substitutions import FindPackageShare
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
 
def generate_launch_description():

   rviz_config_file = PathJoinSubstitution(
           [FindPackageShare("ur_description"), "rviz", "view_robot.rviz"]
   )
   
   return LaunchDescription([
        Node(
            package="rviz2",
            executable="rviz2",
            name="rviz2",
            output="log",
            arguments=["-d", rviz_config_file],
        ),
   ])

The path rviz_config_file we get from PathJoinSubstitution in line 7 will be something like “<path-to-ur_description-package>/rviz/view_robot.rviz“. It is then handed over as an argument to the Rviz Node in line 17. To get the path to the ur_description package we use FindPackageShare which is also part of the substitutions module. Note that this example will only work if you have a ur_description package installed (package that contains description files for the UR robots).

To discover more substitutions you can find a list of common substitution classes with brief descriptions at the end of this article. Now finally, let’s look at conditions.

ROS2 launch conditions

Conditions help to add even more logic to your start up procedure. Just as the name suggests, they allow you to make the execution of your actions dependent on something.

Let’s look at a simple example using the IfCondition:

from launch import LaunchDescription
from launch.actions import LogInfo
from launch.conditions import IfCondition
from launch.substitutions import PythonExpression, EnvironmentVariable
 
def generate_launch_description():
    return LaunchDescription([
        LogInfo(condition=IfCondition(
            PythonExpression(["'",
                EnvironmentVariable('USER'),
                "' == 'alex'"
            ])
        ),
        msg='Welcome back Alex'
        )
    ])

LogInfo in line 8 is an action that will print a message to your terminal output. In our case we make the printing dependent on the environment variable USER which we already used in the previous example. Inside the IfCondition we evaluate a python expression. This expression returns true if the environment variable USER equals alex and in that case prints a welcoming log message. If USER doesn’t equal alex, nothing will be printed.

There is also the UnlessCondition which can be used accordingly:

...
def generate_launch_description():
    return LaunchDescription([
        LogInfo(condition=UnlessCondition(
            PythonExpression(["'",
                EnvironmentVariable('USER'),
                "' == 'alex'"
            ])
        ),
        msg=['Nice to meet you ', EnvironmentVariable('USER')]
        )
    ])

In this example, if USER doesn’t equal alex we greet our new acquaintance. On the other hand if it’s alex, we just wave and don’t say anything.

The LaunchConfigurationEquals and the LaunchConfigurationNotEquals conditions provide an easy way to define the behavior of the launch file based on input arguments:

from launch import LaunchDescription
from launch.actions import LogInfo, DeclareLaunchArgument
from launch.conditions import LaunchConfigurationEquals, LaunchConfigurationNotEquals
from launch.substitutions import TextSubstitution
 
def generate_launch_description():
    return LaunchDescription([
        DeclareLaunchArgument(
            'launch_arg', default_value=TextSubstitution(text='default')
        ),

        LogInfo(condition=LaunchConfigurationEquals('launch_arg', 'default'),
        msg=['Okay, no launch argument.']
        ),
        
        LogInfo(condition=LaunchConfigurationNotEquals('launch_arg', 'default'),
        msg=['Yay, a launch argument!']
        )
    ])

In this example we define a launch argument called launch_arg in line 8. Based on its value we print different info messages. We are happy (Yay!) in line 16 if the user hands over a launch argument, but it’s also okay if he doesn’t and we need to go with the default argument in line 12. A more detailed description of command line arguments for launch files and their usage is given in the first question of the FAQs.

That’s it, we covered actions, event handlers substitutions and conditions so now we know about all basic functionalities of launch files. With that knowledge you will be able to encrypt any launch file you will encounter in the wild.

ROS2 launch file FAQ

Obviously, knowing about the basic concepts doesn’t make you an expert. That’s why we want to have a look at some common problems and use cases that you can solve with launch files to see the functionalities you learned in action.

How to hand over command line arguments to a ROS2 launch file

You want to create a launch file that changes it’s behavior based on input arguments? Let’s look at an example launch file that takes an argument handed over from the command line. The following launch file launches the turtlesim node and afterwards uses the ros2 param set command to change the background color (specifically the red component in the RGB spectrum). The value of the red component can be specified with an input argument to the launch file:

from launch_ros.actions import Node

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess
from launch.substitutions import LaunchConfiguration

def generate_launch_description():
    new_background_r_value = LaunchConfiguration('new_background_r')

    new_background_r_launch_arg = DeclareLaunchArgument(
        'new_background_r',
        default_value='200'
    )

    turtlesim_node = Node(
        package='turtlesim',
        executable='turtlesim_node',
        name='sim'
    )

    change_background_r_conditioned = ExecuteProcess(
        cmd=[[
            'ros2 param set ',
            '/sim background_r ',
            new_background_r_value
        ]],
        shell=True
    )

    return LaunchDescription([
        new_background_r_launch_arg,
        turtlesim_node,
        change_background_r_conditioned
    ])

With the DeclareLaunchArgument action in line 10 we determine that we expect an argument named new_background_r to be handed over to the launch file. We specify the name of the argument and optionally a default value which is used if the user doesn’t pass an argument.

To be able to use the launch argument we receive from the command line we use the LaunchConfiguration substitution. In line 8 we get the value of the launch argument new_background_r and store it in the new_background_r_value launch configuration variable which we can use inside the ExecuteProcess action in line 25. The ExecuteProcess action then sets the parameter background_r of the turtlesim Node to the value of new_background_r_value. Remember that DeclareLaunchArgument is an action which also needs to be added to LaunchDescription as it’s done in line 31.

In this example you would call the launch file with the arguments as follows:

ros2 launch package_name launch_file_name.launch.py new_background_r:=100

How to find out the launch arguments of a ROS2 launch file

We just discussed how you can add command line arguments to your launch file. If you have a existing launch file and you want to know which command line arguments it takes you can use the following command:

ros2 launch package_name <launch_file_name>.launch.py -s

This will print the arguments with description and default values in your terminal.

How to set arguments for a node in a ROS2 launch file

You want to hand over arguments to a Node you start from a ROS2 launch file? Here is an example how to do it:

    classic_gaz_spawn_entity = Node(
        package='gazebo_ros',
        executable='spawn_entity.py',
        output='screen',
        arguments=['-topic', 'robot_description',
                   '-entity', 'ur5',
                   '-z', '0.1']
    )

This code snippet defines an action that spawns an entity inside the Gazebo simulator using the executable spawn_entity.py. An entity could for example be the URDF description of a robot. In the arguments option in line 5 we hand over three arguments to the Node: topic, entity and z. The meaning of these arguments is not important here but with the arguments option in the Node action constructor you can hand over as many arguments as you want in an array.

How to include a ROS2 launch file in another launch file

If you want to call a launch file from another launch file you can use the IncludeLaunchDescription action. The following is an example which includes the gazebo.launch.py launch file from the gazebo_ros package to launch an empty gazebo world:

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch_ros.substitutions import FindPackageShare
from launch.launch_description_sources import PythonLaunchDescriptionSource

def generate_launch_description():
    return LaunchDescription([
        IncludeLaunchDescription(
                PythonLaunchDescriptionSource([
                    FindPackageShare("gazebo_ros"), '/launch', '/gazebo.launch.py'])
            )
    ])

IncludeLaunchDescription takes an object of the class PythonLaunchDescriptionSource as an argument. In the above example we construct the path to the launch file we want to include in line 10 by getting the directory of the gazebo_ros package with the FindPackageShare substitution class. Then we add the launch subdirectory and the gazebo.launch.py launch file name. Now this launch file will be called where ever we add the IncludeLaunchDescription action in the launch file.

How to use event handlers for lifecycle nodes

Lifecycle Nodes are another concept that was introduced in ROS2. In contrast to normal Nodes, managed (lifecycle) Nodes have states that can be controlled by the developer and state transitions can be based on certain conditions (you can read more about managed Nodes here). The ROS-specific event handler OnStateTransition is useful to manage these lifecycle nodes.

The following is an example how to use the OnStateTransition event handler with a lifecycle node:

import launch_ros.events.lifecycle
...

# When the talker node reaches the 'active' state, log a message and start the listener node.
register_event_handler_for_talker_reaches_active_state = launch.actions.RegisterEventHandler(
    launch_ros.event_handlers.OnStateTransition(
        target_lifecycle_node=talker_node, goal_state='active',
        entities=[
            launch.actions.LogInfo(
                msg="node 'talker' reached the 'active' state, launching 'listener'."),
            launch_ros.actions.LifecycleNode(
                name='listener', namespace='',
                package='lifecycle', executable='lifecycle_listener', output='screen'),
        ],
    )
)

This example is taken from the the launch_ros repository (link). With the target_lifecycle_node option we define the node we want to monitor. When this node reaches the state we define with the goal_state option, the event is triggered. In the entities option we specify the actions that should than be executed as an array. Besides goal_state there are other matching options available (e.g. transition to trigger not when a state is reached but instead on the transition between states). You can find the options in the source code.

Conclusion

I hope you enjoyed this tutorial and you now understand more about launch files than before. I tried to combine all the functionalities that the new launch framework provides in one article for a better overview. In the end, launch files in ROS2 are powerful and combining the different basic functionalities makes them very flexible.

I am always happy about feedback in the comments and also directly via the contact form. Stay tuned for more and make sure to check out my other Robotics Tutorials!

Here follows the lists of commonly used actions, action_handlers and substitutions:

List of actions in ROS2 launch files

Remember that actions always need to be added to the LaunchDescription, either by adding it directly in the constructor or by using the add_action(...) function.

Actions are defined in the launch.actions or the launch_ros.actions module so you always need to import the actions you are using inside your launch file:

from launch.actions import <action_name>
#or
from launch_ros.actions import <action_name>

General actions inside launch.actions:

  • With ExecuteProcess you can start any process as if you would start one from the command line:
ExecuteProcess(cmd=['ls', '-las'], name='my_ls_process', output='both')
  • IncludeLaunchDescription allows you to add a launch description to your launch file:
        IncludeLaunchDescription(
                PythonLaunchDescriptionSource([
                    FindPackageShare("gazebo_ros"), '/launch', '/gazebo.launch.py'])
            )

This launch file will then be started where ever it is visited in the launch file.

  • With SetEnvironmentVariable you can set environment variables, e.g.
SetEnvironmentVariable(name='PATH', value='path/to/something')
  • DeclareLaunchArgument allows you to set and define an argument that can be passed to the launch file e.g.
DeclareLaunchArgument(name='background_color', default='red')
  • With LogInfo you can create log messages e.g.
LogInfo(msg="Logging message")

ROS-specific actions that are defined in launch_ros.actions:

  • The Node actions allows you to start a ROS2 Node:
    turtlesim_node = Node(
        package='turtlesim',
        executable='turtlesim_node',
        name='sim'
    )
  • The LifecycleNode allows to start a managed node from a launch file.

In contrast to normal Nodes, managed Nodes have states that can be controlled by the developer and state transitions can be based on certain conditions (you can read more about managed Nodes here).

  • The ComposableNodeContainer allows to launch composable nodes.

A container allows you to compose different nodes in a single process and is based on the concept of components (If you want to know more you can find readings on components, composition in the ROS2 documentation). Here you can find a detailed description how to use the ComposableNodeContainer. A related action is LoadComposableNodes.

  • PushRosNamespace adds a namespace to the Nodes launched after the PushRosNamespace action was called:
PushRosNamespace('my_namespace')

It can also be used inside a GoupAction to only be added to specific Nodes.

  • With SetParameter you can set parameters in the current scope. The following example sets the parameter use_sim_time to True:
launch_ros.actions.SetParameter(name='use_sim_time', value=True)
  • With SetParametersFromFile you can also get the parameters from a .yaml file:
SetParametersFromFile('path/to/file.yaml'),

For controlling the scope you can use SetParametersFromFile within a GroupAction such that parameters are only set for the actions in that group.

       LaunchDescription([
            ...,
            GroupAction(
                actions = [
                    ...,
                    SetParametersFromFile('path/to/file.yaml'),
                    ...,
                    Node(...),  // the params will be passed to this node
                    ...,
                ]
            ),
            Node(...),  // here it won't be passed, as it's not in the same scope
            ...
        ])
  • With SetRemap you can do remapping of node names for the current scope. E.g. with:
SetRemap(src='/input/pose', dst='/turtlesim1/turtle1/pose')

a topic called /input/pose would appear as /turtlesim1/turtle1/pose.

  • ROSTimer can be used to execute action(s) only after a certain amount of time. The following line starts the turtlesim_node after 2.5 seconds:
ROSTimer(period=2.5, actions=[turtlesim_node])
  • SetROSLogDir allows you to set the log directory of Nodes in the current scope:
SetROSLogDir("tmp/custom_logging_directory/")
  • With SetUseSimTime you can set the use_sim_time parameter in the current context as follows:
SetUseSimTime(True)

This is useful e.g. if you want to simulate a robot and launch its controllers from a launch file.

List of event handlers in ROS2 launch files

Remember, event handlers are included in the launch file as follows:

from launch.event_handlers import <event_handler>
#or
from launch_ros.event_handlers import <event_handler>
...
        RegisterEventHandler(
            event_handler=<event_handler>(
                <args>
            )

Event handlers inside launch.event_handlers:

  • OnExecutionComplete triggers when the execution of an action is finished e.g.
OnExecutionComplete(target_action=turtlesim1, on_exit=[turtlesim2])
  • OnProcessExit triggers when a process exits e.g.
OnProcessExit(target_action=process1, on_exit=[process2])
  • OnProcessIO triggers when there is an input to or output from the process e.g. the following triggers on standard output from turtlesim1:
OnExecutionComplete(target_action=turtlesim1, on_stdout=[turtlesim2])
  • OnProcessStart triggers when a process starts, e.g. the following event handler starts turtlesim2 as soon as turtlesim1 was started:
OnProcessStart(target_action=process1, on_start=[process2])
  • OnShutdown triggers when the launch file is asked to shut down, e.g.
OnShutdown(on_shutdown=[LogInfo(msg=['Launch file is shutting down'])])

Currently there is only on ROS-specific event handler in launch_ros.event_handlers:

  • OnStateTransition triggers when the state of a lifecycle node finishes e.g.
OnStateTransition(
        target_lifecycle_node=talker_node, goal_state='active',
        entities=[
            launch.actions.LogInfo(
                msg="node 'talker' reached the 'active' state, launching 'listener'.")]
)

List of substitutions in ROS2 launch files

To use substitutions inside your launch file you need to import the corresponding modules either for general or for ROS-specific substitutions:

from launch.substitutions import <substitution_name>
#or
from launch_ros.substitutions import <substitution_name>

General substitutions inside launch.substitutions:

  • EnvironmentVariable Substitution that gets an environment variable value as a string, e.g.
EnvironmentVariable('USER')
  • LaunchConfiguration Substitution that can access launch configuration variables
LaunchConfiguration('use_sim_time', default=True)
  • PathJoinSubstitution Substitution to join paths, in a platform independent way
PathJoinSubstitution([FindPackageShare("ur_description"), "rviz", "view_robot.rviz"])
  • PythonExpression Substitution that can access contextual local variables. The expression may contain Substitutions, but must return something that can be converted to a string with str().
PythonExpression([EnvironmentVariable('USER'), " == 'Alex'"])
  • TextSubstitution Substitution that wraps a single string text.
TextSubstitution(text='my_substitution_text')
  • ThisLaunchFile Substitution that takes no arguments and returns the absolute path to the current launch file:
ThisLaunchFile()
  • ThisLaunchFileDir Substitution that takes no arguments and returns the absolute path to the directory of the current launch file:
ThisLaunchFileDir()
  • FindExecutable Substitution that tries to locate an executable on the PATH, e.g.:
FindExecutable('executable_name')
  • LocalSubstitution Substitution that can access contextual local variables. e.g.:
LocalSubstitution('event.reason')
  • Command Substitution that gets the output of a command as a string
Command(command='linux_command')
  • AnonName Generates an anonymous id based on name.
AnonName('name_that_gets_an_anonymous_id')
  • NotSubstitution Substitution that returns ‘not’ of the input boolean value
NotSubstitution(PythonExpression('true')

ROS-specific substitutions inside launch_ros.substitutions:

  • ExecutableInPackage Substitution that tries to locate an executable in the libexec directory of a ROS package. Will raise errors if the package or the executable is not found.
ExecutableInPackage(executable='turtlesim_node', package='turtlesim')
  • Parameter Substitution that tries to get a parameter that was set by SetParameter.
Parameter(name='use_sim_time', default='false')