How to Use ROS 1 Launch Files

Executing and configuring multiple ROS 1 nodes at once

José L. MillánJosé L. Millán ·
9 min read
Published

In previous posts, we’ve seen how ROS 1 nodes communicate using topics, services and actions. We’ve also talked about how we can configure nodes using parameters. In these tutorials, we have been running nodes one by one.

Rather than launching one node at a time, we can leverage launch files to execute and configure multiple nodes with a single command. You can even pull in nodes from other packages to run different processes.

In this tutorial, we will cover how to use a launch file to run multiple nodes, configure them, and group them into meaningful namespaces.

Why ROS 1 launch files?

Running many ROS 1 nodes takes a lot of time and many terminal windows. Even small projects or robots can have many nodes running simultaneously.

Imagine a robot following the "sense-think-act" model that runs one node for each step. A sensor_node is in charge of reading distance data from a sensor, a compute_node receives this data and sends a command to the wheels, and finally a motor_node receives the command and outputs the needed voltage to the motors.

Instead of running each of these nodes in a separate terminal window each time we startup the robot, we can use a launch file to execute them all at once – with a single command, in a single terminal window.

Creating a launch file

Start by creating a new package named launch_pkg in your ROS 1 workspace. In the src folder, create the following files for each of your nodes:

In the root directory of your package, create a launch folder with a launch_example.launch.py file – start by adding the xml version and launch tag:

<?xml version="1.0"?>
<launch>

Next, use the node tag to declare each of your nodes and close the launch tag:

   <!-- Three nodes -->
   <node pkg="launch_pkg" type="sensor_node" name="sensor_node" output="screen"/>
   <node pkg="launch_pkg" type="compute_node" name="compute_node" output="screen"/>
   <node pkg="launch_pkg" type="motor_node" name="motor_node" output="screen"/>
</launch>

Executing the launch file will parse this file and run the list of nodes. Everything else happens behind the curtains of ROS 1.

Before launching our new file, let’s compile the executables by editing your CMakeLists.txt:

# find dependencies
find_package(catkin REQUIRED COMPONENTS
 geometry_msgs
 roscpp
 std_msgs
)
# ...
catkin_package()
# ...
add_executable(motor_node src/motor.cpp)
add_executable(sensor_node src/sensor.cpp)
add_executable(compute_node src/compute.cpp)

target_link_libraries(motor_node
 ${catkin_LIBRARIES}
)
target_link_libraries(sensor_node
 ${catkin_LIBRARIES}
)
target_link_libraries(compute_node
 ${catkin_LIBRARIES}
)

Compile your workspace with catkin_make and source your workspace before you run your launch file:

$ roslaunch launch_pkg launch_example.launch.py
  ... logging to /home/jose/.ros/log/6ceb21b0-56e5-11ed-8d02-ede36847100a/roslaunch-jose-hp-10609.log
  Checking log directory for disk usage. This may take a while.
  Press Ctrl-C to interrupt
  Done checking log file disk usage. Usage is <1GB.

  started roslaunch server http://jose-hp:42669/

  SUMMARY
  ========

  PARAMETERS
  * /rosdistro: noetic
  * /rosversion: 1.15.14

  NODES
    /
    compute_node (launch_pkg/compute_node)
    motor_node (launch_pkg/motor_node)
    sensor_node (launch_pkg/sensor_node)

  auto-starting new master
  process[master]: started with pid [10625]
  ROS_MASTER_URI=http://localhost:11311

  setting /run_id to 6ceb21b0-56e5-11ed-8d02-ede36847100a
  process[rosout-1]: started with pid [10642]
  started core service [/rosout]
  process[sensor_node-2]: started with pid [10645]
  process[compute_node-3]: started with pid [10646]
  process[motor_node-4]: started with pid [10651]
  [ INFO] [1666977890.709897549]: Read value 17767
  [ INFO] [1666977890.712234400]: Received value 17767, sending 1.00
  [ INFO] [1666977890.715850085]: Received value 1.00
  [ INFO] [1666977890.717371423]: Moving motors forward
  [ INFO] [1666977891.709779304]: Read value 9158
  [ INFO] [1666977891.710294371]: Received value 9158, sending 1.00
  [ INFO] [1666977891.710665976]: Received value 1.00
  [ INFO] [1666977891.710717793]: Moving motors forward
  [ INFO] [1666977892.709717886]: Read value -26519
  [ INFO] [1666977892.710128518]: Received value -26519, sending -1.00
  [ INFO] [1666977892.710384523]: Received value -1.00
  [ INFO] [1666977892.710431862]: Moving motors backwards
  [ INFO] [1666977893.709804282]: Read value 18547
  [ INFO] [1666977893.710253914]: Received value 18547, sending 1.00
  [ INFO] [1666977893.710570992]: Received value 1.00
  [ INFO] [1666977893.710637276]: Moving motors forward

Check that your nodes are running by opening a new terminal window with ROS 2 sourced and adding Foxglove Studio's Topic Graph panel to your layout:

Topic graph

We got three nodes running with a single line!

Adding namespaces

Launch files can also group your nodes into families, or namespaces. This makes it easier for you to keep track of and monitor your nodes' behavior.

A node has only one name, but can belong to multiple levels of namespaces. These namespaces can be joined with a forward slash (/) – all nodes without a namespace will always have a single / before their names (e.g. /sensor_node). All topics without a namespace specified during declaration will inherit the node’s namespace, as seen in the previous image.

Let’s add our three nodes to a "sense_think_act" namespace in our launch file:

<node ns="sense_think_act" pkg="launch_pkg" type="sensor_node" name="sensor_node" output="screen"/>
<node ns="sense_think_act" pkg="launch_pkg" type="compute_node" name="compute_node" output="screen"/>
<node ns="sense_think_act" pkg="launch_pkg" type="motor_node" name="motor_node" output="screen"/>

Run the launch file again, and check the new results with the Topic Graph panel – you'll see that the nodes and the topics have the namespace specified in the launch file:

Nodes with namespaces

Including nodes from other packages

Another great feature of launch files is the possibility to include nodes from another package. Let's pull the robot_node node created in our ROS 1 parameters tutorial into our launch file and configure it with some parameters:

  <!-- Adding node from another package with parameters -->
  <rosparam command="load" file="$(find params_pkg)/params/warehouseA_core.yaml" />
  <node ns="core" pkg="params_pkg" type="robot_node" name="robot_node" output="screen"/>

If you have a different workspace, you have to source as well. Remember that you can source as many workspaces as you want. Run your launch file again:

$ roslaunch launch_pkg launch_example.launch.py
  ... logging to /home/jose/.ros/log/f1802984-56e5-11ed-8d02-ede36847100a/roslaunch-jose-hp-10913.log
  Checking log directory for disk usage. This may take a while.
  Press Ctrl-C to interrupt
  Done checking log file disk usage. Usage is <1GB.

  started roslaunch server http://jose-hp:45537/

  SUMMARY
  ========

  PARAMETERS
  * /core/robot_node/max_speed: 1.4
  * /core/robot_node/robot_name: RobotA
  * /core/robot_node/waypoints: ['Home', 'Corrido...
  * /rosdistro: noetic
  * /rosversion: 1.15.14

  NODES
    /core/
    robot_node (params_pkg/robot_node)
    /sense_think_act/
    compute_node (launch_pkg/compute_node)
    motor_node (launch_pkg/motor_node)
    sensor_node (launch_pkg/sensor_node)

  auto-starting new master
  process[master]: started with pid [10928]
  ROS_MASTER_URI=http://localhost:11311

  setting /run_id to f1802984-56e5-11ed-8d02-ede36847100a
  process[rosout-1]: started with pid [10946]
  started core service [/rosout]
  process[sense_think_act/sensor_node-2]: started with pid [10949]
  process[sense_think_act/compute_node-3]: started with pid [10950]
  process[sense_think_act/motor_node-4]: started with pid [10955]
  process[core/robot_node-5]: started with pid [10957]
  [ INFO] [1666978112.180216384]: Hi! I'm 'RobotA'
  [ INFO] [1666978112.181028565]: My max speed is 1.4
  [ INFO] [1666978112.181063065]: I will follow the waypoints:
  [ INFO] [1666978112.181083044]: 1) Home
  [ INFO] [1666978112.181104531]: 2) Corridor
  [ INFO] [1666978112.181124876]: 3) Home
  [ INFO] [1666978113.161815262]: Read value 17767
  [ INFO] [1666978113.163937606]: Received value 17767, sending 1.00
  [ INFO] [1666978113.167211139]: Received value 1.00
  [ INFO] [1666978113.168465613]: Moving motors forward
  [ INFO] [1666978114.161610631]: Read value 9158
  [ INFO] [1666978114.161951609]: Received value 9158, sending 1.00
  [ INFO] [1666978114.162253739]: Received value 1.00
  [ INFO] [1666978114.162292001]: Moving motors forward
  [ INFO] [1666978115.161723949]: Read value -26519
  [ INFO] [1666978115.162189397]: Received value -26519, sending -1.00
  [ INFO] [1666978115.162619920]: Received value -1.00
  [ INFO] [1666978115.162685572]: Moving motors backwards

And check your nodes again with Foxglove Studio:

All nodes in the Topic Graph panel

Using Foxglove Studio

Now that we’ve created launch files that execute multiple nodes, let’s include Foxglove Studio in the development process.

In this particular Studio layout, we are using Foxglove Studio to monitor the sensor and command values:

Foxglove Studio layout L to R, top to bottom: ROS computational graph in a Topic Graph panel, raw sensor data and cmd_vel values in two Raw Messages panels, sensor data plotted with a Plot panel, cmd_vel.linear.x monitored with a Gauge panel

Summary

ROS 1 launch files can dramatically streamline your robotics development, by making it possible to execute multiple nodes with a single command. We hope you found this tutorial useful, and learned how to streamline your workflows in the future!

For a reference to all the code covered in this post, check out our GitHub repo.

As always, feel free to reach out to the Foxglove team in our Slack community to ask questions, give us feedback, and request a topic for the next tutorial!


Read more:

How to Use ROS 2 Launch Files
tutorial
ROS
How to Use ROS 2 Launch Files

Executing and configuring multiple ROS 2 nodes at once.

José L. MillánJosé L. MillánJosé L. Millán
9 min read
Spotlight: How FST Lisboa Used the Foxglove Platform to Build an Award-Winning Autonomous Racecar
interview
studio
data platform
Spotlight: How FST Lisboa Used the Foxglove Platform to Build an Award-Winning Autonomous Racecar

Leveraging Foxglove Studio and Data Platform to achieve podium places at Formula Student 2022.

Miguel GonçalvesMiguel GonçalvesMiguel Gonçalves
Rita FardilhaRita FardilhaRita Fardilha
6 min read

Get blog posts sent directly to your inbox.

Ready to get started?Download today on Linux, Windows, or macOS.