Introduction to ROS2 Launch Files for both Python and C++ Packages
Last updated: December 22, 2024
1. Introduction
In our previous lessons, we built ROS2 packages that each contained two nodes. To run these nodes, we had to source the overlay in separate terminals and manually start each node. While this works for simple projects, it quickly becomes inefficient as the complexity of the system grows. This manual approach not only requires extra effort but also introduces the risk of human error, especially in large-scale applications with multiple interdependent nodes.
To address this challenge, ROS2 introduces launch files, a powerful mechanism that simplifies and automates the process of starting nodes. Written in Python, launch files enable you to start multiple nodes simultaneously, manage parameters, load configuration files, and perform other advanced setup tasks with ease.
In this lesson, you will learn the fundamentals of ROS2 launch files. We’ll begin by creating simple launch files to understand their structure and usage. As we progress, you’ll see how launch files can handle increasingly complex scenarios, making them indispensable for real-world applications.
Complete code: Complete code: talker_listener on Edreate GitHub
1a. Why Use ROS2 Launch Files?
Launch files streamline and enhance your workflow in several key ways:
- Simplify Execution: Launch multiple nodes and configure them with a single command.
- Automation: Automate the startup of complex systems, including nodes with interdependencies and pre-set parameters.
- Reusability: Create reusable configurations for different scenarios, projects, or deployments.
- Scalability: Manage large-scale systems with centralized control over all nodes and configurations.
- Consistency: Reduce human errors by ensuring the same nodes and parameters are launched every time.
3e. ROS2 CLI Output
After setting up and running the Python package, we can use ROS2 CLI tools to observe the active nodes and topics. Here's what we get:
Listing Active Nodes
Run the following command to list all active nodes:
ros2 node list
Output:
/py_listener
/py_talker
The output shows the two nodes, /py_listener
and /py_talker
, created by the Python package.
Listing Active Topics
Next, run the command to list all active topics:
ros2 topic list
Output:
/py_listener
/py_talker
Even though we executed the ros2 topic list
command, the output remains unchanged because no additional topics were created or modified during this process.
These results demonstrate that the nodes and topics defined in the Python package are correctly launched and active. If you run the equivalent commands while using the C++ package, you would see similar output with the node and topic names corresponding to the C++ implementation.
4. Complete Files
src/talker_listener_py/setup.py
from setuptools import find_packages, setup
package_name = "talker_listener_py"
setup(
name=package_name,
version="0.0.1",
packages=find_packages(exclude=["test"]),
data_files=[
(
"share/ament_index/resource_index/packages",
["resource/" + package_name],
),
(
"share/" + package_name,
["package.xml"],
),
# Launch file
(
"share/talker_listener_py/launch",
["launch/talker_listener_py.launch.py"],
),
],
install_requires=["setuptools"],
zip_safe=True,
maintainer="edreate",
maintainer_email="edreate.dev@gmail.com",
description="Basic talker listener node in python.",
license="MIT",
tests_require=["pytest"],
entry_points={
"console_scripts": [
"talker = talker_listener_py.talker:main",
"listener = talker_listener_py.listener:main",
],
},
)
src/talker_listener_cpp/CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(talker_listener_cpp)
# Enable strict compiler warnings for GCC or Clang
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# Define talker executable
add_executable(talker src/talker.cpp)
target_include_directories(talker PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_features(talker PUBLIC cxx_std_17) # Require C++17
ament_target_dependencies(talker rclcpp std_msgs)
# Define listener executable
add_executable(listener src/listener.cpp)
target_include_directories(listener PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_features(listener PUBLIC cxx_std_17) # Require C++17
ament_target_dependencies(listener rclcpp std_msgs)
# Install executables
install(TARGETS
talker
listener
DESTINATION lib/${PROJECT_NAME})
install(DIRECTORY
launch/ DESTINATION share/${PROJECT_NAME}/launch)
# Enable linting and testing (optional)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# Skip copyright and cpplint checks (adjust as needed)
set(ament_cmake_copyright_FOUND TRUE)
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
# Mark package complete
ament_package()
5. Summary
ROS2 launch files provide a structured and efficient way to automate the startup of multiple nodes, manage configurations, and scale systems with minimal manual intervention.
Complete code: Complete code: talker_listener on Edreate GitHub
The typical launch file is written in Python and follows a clear structure:
- Import necessary modules.
- Define a function (
generate_launch_description
) that returns aLaunchDescription
object. - Use
Node
objects to specify nodes, parameters, and remappings.
This mechanism simplifies workflow, reduces human error, and ensures consistency in deploying ROS2 applications. The flexibility of launch files makes them indispensable for both development and production environments.