Launch: Automate Initial Executions
1. Motivation
Until so far, we have relied on terminals and CLIs to perform the below operations:
- Running nodes
- Publishing topic
- Remapping names of topics and nodes
- Calling services
- Assigning namespace
- Loading parameters
As you might guess, it is not feasible to perform the initial operations every time by opening terminals and memorizing all the CLIs. Instead, we programmatically describe the initial executions in launch (opens in a new tab) files based on Python language. On this page, we learn how to automate all the above operations by running a single launch file.
Scenario
In this chapter, we run two turtlesim_node
executables in different namespaces: turtle_original
and turtle_mimic
, along with a new executable called mimic_controller
.
As the names suggest,
the turtle in turtle_mimic
will mimic the turtle in turtle_original
.
This can be done as mimic_controller
subscribes pose of the original and controls the mimic turtle.
2. Running Node with Configurations
Running Node Under Namespace
In the directory you want, create a python file called turtle.launch.py
, and start to write the description of actions (in the context of launch, actions refer to operations).
First of all, we describe a node to be run:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
ld = LaunchDescription() # Initialize the list of actions
turtle_original = Node(package='turtlesim',
executable='turtlesim_node',
namespace='turtle_original')
ld.add_action(turtle_original) # run turtlesim_node under namespace
return ld
Try launching the file:
ros2 launch turtle.launch.py
This will run a node turtle_original/turtlesim
under the namespace turtle_original
as shown in the below:
rosmarry@rosmarry:~$ ros2 node list
/turtle_original/turtlesim
Loading Parameters
Now, we want to set the background color of the turtlesim node. Previously, we created a yaml
file and loaded it.
Same here, create a parameter.yaml
in a directory /<path/to/parameter>/
and change the top namespace:
turtle_original: # Note the namespace
turtlesim:
ros__parameters: # parameters
background_r: 200
background_g: 200
Then, we will add parameter
argument into Node
class. Note that you should use your directory in /<path/to/parameter>/parameter.yaml
.
...
def generate_launch_description():
ld = LaunchDescription()
turtle_original = Node(package='turtlesim',
executable='turtlesim_node',
namespace='turtle_original',
parameters=['/<path/to/parameter>/parameter.yaml'])
ld.add_action(turtle_original)
return ld
3. Running Multiple Nodes
Add another action & Topic Remapping
In the above code, we only added a single node ld.add_action(turtle_original)
.
Now, we add another node in the launch description:
...
def generate_launch_description():
ld = LaunchDescription()
turtle_original = Node(package='turtlesim',
executable='turtlesim_node',
namespace='turtle_original',
parameters=['/<path/to/parameter>/parameter.yaml'])
turtle_mimic = Node(package='turtlesim',
executable='turtlesim_node',
remappings=[("turtle1/cmd_vel", "cmd_vel_mimic")])
ld.add_action(turtle_original)
ld.add_action(turtle_mimic)
return ld
For demonstration, we have a twist: topic remapping from /turtlesim/turtle1/cmd_vel
into /turtlesim/cmd_vel_mimic
.
In this way, we can easily remap when we run a node by the launch file.
Launching the file will open two turtlesims.
ros2 launch turtle.launch.py
will lead to the below:
rosmarry@rosmarry:~/ros2_ws/src$ ros2 node list
/turtle_original/turtlesim
/turtlesim
Receiving Arguments for Launch
As other programs do, we can pass arguments to the launch.
We differentiate argument and ROS parameter. The former is not managed by ROS and takes effect only when starting launch. Parameter is managed under ROS and we can perform the operations mentioned in the previous chapter.
The argument from users can substitute the values in the python file:
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
ARGUMENTS = [
DeclareLaunchArgument('mimic_namespace', default_value='turtle_mimic',
description='Namespace of mimic turtle')]
def generate_launch_description():
ld = LaunchDescription(ARGUMENTS)
mimic_namespace = LaunchConfiguration("mimic_namespace")
turtle_original = Node(package='turtlesim',
executable='turtlesim_node',
namespace='turtle_original',
parameters=['/<path/to/parameter>/parameter.yaml'])
turtle_mimic = Node(package='turtlesim',
executable='turtlesim_node',
namespace=mimic_namespace,
remappings=[("turtle1/cmd_vel", "cmd_vel_mimic")])
ld.add_action(turtle_original)
ld.add_action(turtle_mimic)
return ld
In the above launch file, we declare launch arguments in L6. By doing this, the users can look up which arguments they can provide by:
rosmarry@rosmarry:~$ ros2 launch turtle.launch.py --show-args
Arguments (pass arguments as '<name>:=<value>'):
'mimic_namespace':
Namespace of mimic turtle
(default: 'turtle_mimic')
As the output suggests, users will put arguments by
ros2 launch turtle.launch.py mimic_namespace:="my_mimic"
In the launch file, mimic_namespace
will substitute the namespace of turtle_mimic
with my_mimic
, as can be seen below after launch the file:
rosmarry@rosmarry:~$ ros2 node list
/my_mimic/turtlesim
/turtle_original/turtlesim
4. Executing Process
Using launch file, we can also run any terminal command. As an example, we will try to publish a topic when we run the launch file. Add another action as the below:
...
from launch.actions import DeclareLaunchArgument, ExecuteProcess
...
def generate_launch_description():
...
velocity_publish = ExecuteProcess(
cmd=[
'ros2 topic pub /turtle_original/turtle1/cmd_vel -r 10 geometry_msgs/msg/Twist',
'"{linear: {x: 1.0, y: 0, z: 0}, angular: {x: 0, y: 0, z: 1}}" --print 0'],
shell=True
)
...
ld.add_action(turtle_original)
ld.add_action(turtle_mimic)
ld.add_action(velocity_publish)
return ld
Launching this file will make the turtle in turtle_original
move along a circle.
Final Launch File
Until here, our launch description opened two turtlesim
nodes and published a topic to move the original turtle.
Now, we introduce another node to move the other turtle to mimic the original.
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument, ExecuteProcess
from launch.substitutions import LaunchConfiguration
ARGUMENTS = [
DeclareLaunchArgument('mimic_namespace', default_value='turtle_mimic',
description='Namespace of mimic turtle')]
def generate_launch_description():
ld = LaunchDescription(ARGUMENTS)
mimic_namespace = LaunchConfiguration("mimic_namespace")
turtle_original = Node(package='turtlesim',
executable='turtlesim_node',
namespace='turtle_original',
parameters=['/home/rosmarry/ros2_ws/src/bcr_bot/launch/parameter.yaml'])
turtle_mimic = Node(package='turtlesim',
executable='turtlesim_node',
namespace=mimic_namespace,
remappings=[("turtle1/cmd_vel", "cmd_vel_mimic")])
velocity_publish = ExecuteProcess(
cmd=[
'ros2 topic pub /turtle_original/turtle1/cmd_vel -r 10 geometry_msgs/msg/Twist',
'"{linear: {x: 1.0, y: 0, z: 0}, angular: {x: 0, y: 0, z: 1}}" --print 0'],
shell=True
)
mimic_controller = Node(package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtle_original/turtle1/pose'),
('/output/cmd_vel',
[mimic_namespace, '/cmd_vel_mimic']),
])
ld.add_action(turtle_original)
ld.add_action(turtle_mimic)
ld.add_action(velocity_publish)
ld.add_action(mimic_controller)
return ld
Adding the action mimic_controller
will move the turtle in the mimic namespace so that it can follow the pose of the original turtle.
In the below figure, the right window is the original, and the left is the mimic turtle.

5. Summary
On this page, we learned how to use the launch file to automate various actions. In most cases, running launch files will be the first command that a user will try for a large enough project. There are lots of lines not covered in this chapter. For further investigation, visit the below links:
- https://docs.ros.org/en/foxy/Tutorials/Intermediate/Launch/Creating-Launch-Files.html (opens in a new tab)
- https://docs.ros.org/en/foxy/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.html (opens in a new tab)
- https://docs.ros.org/en/rolling/Tutorials/Intermediate/Launch/Using-Event-Handlers.html (opens in a new tab)