Launch files
What is a launch file?
Launch files provide a convenient way to organize and manage the launch process of a ROS 2 application, simplifying the initialization of complex robotic systems.
Allows to specify which nodes should be started and with which parameters. This includes specifying the node name, package name, executable name, and any parameters that need to be passed to the node
Launch files support the use of namespaces for nodes, which helps in organizing and structuring your ROS 2 system.
Allows to remap topics, services, and parameters, providing flexibility in connecting nodes together.
Other launch files can be included within a launch file, facilitating modularization and reuse of launch configurations.
Do not forget
Remember to have your environment properly setup. Perform the following, if the ROS 2 package cannot be found when executing it:
source install/setup.sh
See this example:
Look at the error of not being able to find the desired package. This is because the workspace was not configured correctly.
Source the appropriate setup script to correctly configure the environment.
Notice that the sourcing is performed inside the workspace folder. More information on sourcing the environment, check it here.
Running a launch file
Make sure to be in a brand new terminal window and no ROS command is currently running.
This is the structure to run a launch file:
ros2 launch <package_name> <launch_file_name.launch.py>
However, it is also possible to write launch files in .xml or .yaml formats rather than .py scripts. But for this course only .py scripts for launch files will be explained.
See the following example of a launch file execution:
ros2 launch turtlesim multisim.launch.py
This will run two turtlesim nodes:
It can be further inspected the multisim.launch.py file. This is its content:
# turtlesim/launch/multisim.launch.py
from launch import LaunchDescription
import launch_ros.actions
def generate_launch_description():
return LaunchDescription([
launch_ros.actions.Node(
namespace= "turtlesim1", package='turtlesim', executable='turtlesim_node', output='screen'),
launch_ros.actions.Node(
namespace= "turtlesim2", package='turtlesim', executable='turtlesim_node', output='screen'),
])
The code details will be addressed in the next section of this tutorial.
Creating a launch file
Make sure to be in a brand new terminal window and no ROS command is currently running.
Create a new package. This package should be contained in the ros2_ws workspace, within its /src folder. The name provided to this new package will be py_launch_example. For more reference on package creation consult the package creation section.
ros2 pkg create --build-type ament_python --license Apache-2.0 py_launch_example
Next, create a launch folder inside ros2_ws/src/py_launch_example. This is where the launch file scripts will be stored.
Inside py_launch_example/launch create a new file named turtlesim_mimic_launch.py. Edit the content of turtlesim_mimic_launch.msg to include:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
])
Explaining the code
First, some libraries import:
from launch import LaunchDescription
from launch_ros.actions import Node
from launch import LaunchDescription: This line imports theLaunchDescriptionclass from thelaunchpackage. TheLaunchDescription classis a key component in ROS 2 launch files. It is used to define the structure and contents of a launch file. When a launch file is created in ROS 2, an instance ofLaunchDescriptionis typically created and various actions (such as starting nodes) are added to it.from launch_ros.actions import Node: This line imports the Node class from thelaunch_ros.actionsmodule. TheNodeclass is a specialized action in ROS 2 launch files that is used to start a ROS 2 node. To execute a node in a launch file, an instance ofNodeis created and the package name, executable name, node name, and any parameters or remappings that are needed for the node are specified.
Next, a function defintion:
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim'
),
Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
])
This function returns a
LaunchDescriptionobject, which contains all the actions (in this case, node launches) to be performed when the launch file is executed.Node(...)This line starts the definition of a ROS 2 node to be launched.The
package,namespace,executableandnameparameters are specified.
- It executes three nodes:
Two nodes from the
turtlesim_nodeexecutable file; each one with a different namespace name.And one node from the
mimicexecutable file.
- At the moment of executing the
mimicnode two remap actions are performed: /input/pose, which is the topic thatmimicnode is initially subscribed to, is now remapped to/turtlesim1/turtle1/pose, meaning that themimicnode is now subscribed to/turtlesim1/turtle1/pose, which happens to be theposetopic to which the first turtle simulation publishes messages to./output/cmd_veltopic, which is the topic that themimicnode initially published to, is now remapped to/turtlesim2/turtle1/cmd_vel, meaning that themimicnode is now publishing to/turtlesim2/turtle1/cmd_vel, which happens to be thecmd_veltopic to which the second turtle simulation is subscribed to.
- At the moment of executing the
Test the launch file
Navigate to py_launch_example/launch and execute the following:
ros2 launch turtlesim_mimic_launch.py
This will open two turtlesim node windows, where the same turtle is spawned in each window. It will also be seen a similar output in the terminal:
[INFO] [launch]: All log files can be found below /root/.ros/log/2024-04-11-12-24-49-571023-4cf9af68214c-1556
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [turtlesim_node-1]: process started with pid [1557]
[INFO] [turtlesim_node-2]: process started with pid [1559]
[INFO] [mimic-3]: process started with pid [1561]
[turtlesim_node-1] QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
[turtlesim_node-2] QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
[turtlesim_node-1] [INFO] [1712838290.327688850] [turtlesim1.sim]: Starting turtlesim with node name /turtlesim1/sim
[turtlesim_node-2] [INFO] [1712838290.328043552] [turtlesim2.sim]: Starting turtlesim with node name /turtlesim2/sim
[turtlesim_node-1] [INFO] [1712838290.357751302] [turtlesim1.sim]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
[turtlesim_node-2] [INFO] [1712838290.358168704] [turtlesim2.sim]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
Indicating that the two turtlesim nodes have been initiated.
Next, in a new terminal, execute:
rqt_graph
This will show how the mimic node is linking the two turtlesim nodes; it subscribes to /turtlesim1/turtle1/pose which corresponds to the first turtle simulation and publishes to /turtlesim2/turtle1/cmd_vel which affects the second turtle simulation.
Now, in a a new terminal, execute:
ros2 topic pub -r 1 /turtlesim1/turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}"
And see that both turtles move towards the same direction.
Observations on this launch file
See that this launch file will not work when executed from a different directory than py_launch_example/launch. Even if building the package and sourcing it with these commands:
colcon build --packages-select py_launch_example
source install/setup.bash
Some message like this will be the output of executing this launch file.
This is because the correct setup for this launch file to be used was not followed. In the next section see how to properly setup the launch file.
Integrating launch files in ROS 2 packages
To enable colcon tool to locate and utilize launch files, the setup.py file should be edited. Open the setup.py file, add the necessary import statements at the top, and include the launch files into the data_files parameter of setup(...) section:
import os
from glob import glob
# Other imports ...
package_name = 'py_launch_example'
setup(
# Other parameters ...
data_files=[
# ... Other data files
# Include all launch files.
(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]*')))
]
)
The setup.py file should be similar to this one:
Navigate to py_launch_example/launch and check the launch file name since this needs to end with launch.py to be recognized and autocompleted by ros2 launch.
Now, build and test. Open a new terminal window and make sure no ROS command is currently running.
Build and source the package.
colcon build --packages-select py_launch_example
source install/setup.bash
And test the launch file by executing:
ros2 launch py_launch_example turtlesim_mimic_launch.py
The result should look similar to this picture:
With the two turtle windows open.
Working with launch files in C++ packages
In a brand new terminal, navigate to ros2_ws workspace, within its /src folder.
Create a new package with name: cpp_launch_example. For more reference on package creation consult the package creation section.
ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_launch_example
Next, create a launch folder inside ros2_ws/src/cpp_launch_example. This is where the launch file scripts will be stored.
Inside cpp_launch_example/launch copy the launch file of name turtlesim_mimic_launch.py, that was coded in this section.
Next, adjust the CMakeLists.txt file to include the following:
# Install launch files.
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME}/
)
Build and source.
colcon build --packages-select cpp_launch_example
source install/setup.bash
Run the following command:
ros2 launch cpp_launch_example turtlesim_mimic_launch.py
The two turtlesim windows should be oppened.
Practice
In a brand new terminal, execute:
ros2 launch py_launch_example turtlesim_mimic_launch.py
Similar to the example of controlling the turtle movement with this command:
ros2 topic pub -r 1 /turtlesim1/turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}"
Now, instead of making the turtles go in circle, execute the turtle_teleop_key to control the motion of /turtlesim1/sim. The result should be the user controlling the movement of turtle1 and turtle2 following it.