- First, you should be sure that your programs are part of a fully-formed ROS package. This is necessary because the most direct way to use the launch system is it specify which nodes to run based on the package that contains them. As a refresher, you may want to consult the notes on creating ROS2 packages. You should finish the usual package creation and package configuration steps before moving on to the process of creating the launch file itself.
- Now that you have a package created, you can add a launch file to the
package. The recommended place for launch files is a subdirectory called
launchwithin the packagesrcdirectory. Here's an example launch file name:This should be a (usually short) Python module containing a function called
ros_ws/src/package_name/launch/launch.pygenerate_launch_descriptionwhich returns an object of typeLaunchDescription. Here's a very simple example that launches one node:The basic ideas are:from launch import LaunchDescription from launch_ros.actions import * def generate_launch_description(): node = Node(package='turtlesim', executable='turtlesim_node') ld = LaunchDescription([ node ]) return ld- Create a Nodeobject describing the node you want to launch, specifying the package name and the executable within that package. (Note that thisNodeclass is different from the similarly-named class that you use within yourrclpyROS client programs.)
- Create a LaunchDescriptionobject, passing a list of “actions” that should be executed. Nodes are the most common type of action. There are also other types of actions, some of which we'll discuss below.
- Return the LaunchDescriptionobject.
- Create a
- Next, you need to configure the package to include the launch files
when you build. To do this, you should mention your launch directory in
the data_filessection of your package'ssetup.py. Here's an example, showing one option for the line that you need to add:You may also need to add this line near the top of
data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), ('share/' + package_name, glob.glob('launch/*')) ],setup.py:These changes are meant to ensure that when you runimport globcolcon build, your launch files are included the built package. - To use this launch file, be sure to rebuild your package and then use the
ros2 launchcommand. Here's an example:
ros2 launch package_name launch.py - Finally, you may be interested in a few additional wrinkles in your
launch file.
- Launch files can have launch arguments. Each launch argument is
a nugget of additional information, provided on the ros2 launchcommand line, that is used to configure or modify the behavior of the launch file or the nodes it launches. To provide values to launch arguments on the command line, use:=, like this:Within the launch file itself, launch arguments are actions just like the
ros2 launch package_name launch_file_name.py arg_name:=arg_valueNodeactions we've already seen. You can create a launch argument using aDeclareLaunchArgumentobject:Then include this object in the list of actions when you create thearg = DeclareLaunchArgument('arg_name')LaunchDescription. For example, if you have one argument and one node, you might use something like this:To access the specific value assigned to this argument, you can use ald = LaunchDescription([ arg, node ])Launch Configurationobject, in places where you might otherwise use a hard coded value:ThisLaunchConfiguration('arg_name')LaunchConfigurationis technically an object called a substitution within the launch system, so you'll need a import like this to access it:from launch.substitution import * - In some cases, you'll want your launch file to run commands that
don't fit exactly within the mold required for Nodeactions. That is, things for which you cannot specific a package name and an executable within that package. For example, this is the case if you want to includeros2 bag playorros2 bag recordin your launch file. In these kinds of cases, you can use anExecuteProcessaction instead of aNode. Here's an example that plays a hard coded bag file:The
ep = ExecuteProcess(cmd=['ros2', 'bag', 'play', 'bags/example1'])cmdargument here is just a list of the arguments you'd supply on the command line for the command you'd like to run, Then you would include this action in the list of actions when you create yourLaunchDescription. - One last thing: You may want your launch file to stop the entire
system when the playback of the original bag file has completed.
This requires us to create an event handler and attach that event
handler to an action in our launch description.
First, import modules both for the definitions of various events and
for handlers that respond to those events:
Then, within the main code of the launch file, create an event handler:
from launch.event_handlers import * from launch.events import *In this example, we are creating an event handler that waits forevent_handler = OnProcessExit(target_action=your_action, on_exit=[EmitEvent(event=Shutdown())])your_actionto complete, and responds by initiating an overall shutdown when that occurs. Then construct an action from that event handler:Be sure to include this action in the action list that you supply to the constructor of yourterminate_at_end = RegisterEventHandler(event_handler)LaunchDescription.
- Launch files can have launch arguments. Each launch argument is
a nugget of additional information, provided on the