Welcome to the exciting world of ROS 2! Whether you’re building your first robot or scaling complex robotic systems, understanding the core concepts is crucial. This 4 part guide will walk you through the essential building blocks:
- setting up your ROS 2 environment
- understanding the structure of ROS 2 packages
- leveraging the powerful command-line interface (CLI)
- and mastering the different ways ROS 2 nodes communicate.
Let’s dive into part 1!
Table of Contents
Unlock The ROS 2 Potential: Why Sourcing Your Environment Matters
Whether you have installed ROS 2 via your package manager, use it inside a container environnment, or built it from source before you can run any ROS 2 commands or launch your robotic applications, you need to properly configure your terminal environment.
This process is called sourcing, and it essentially tells your shell where to find all the necessary ROS 2 tools, libraries, and your own custom packages. Without it, your terminal simply won’t recognize commands like ros2
.
There are typically two main setup files you’ll interact with:
The ROS 2 Distribution Underlay (
/opt/ros/$ROS_DISTRO/setup.bash
)- What it does: This file configures your environment to use the core ROS 2 distribution you installed (e.g., Jazzy, Humble, Iron). It adds essential executables and libraries to your system’s
PATH
,LD_LIBRARY_PATH
,PYTHONPATH
, and sets crucial environment variables likeAMENT_PREFIX_PATH
among others. - When to source: You must source this first in every new terminal you open before using ROS 2 commands, or automate it by adding it to your shell’s startup script (like
.bashrc
or.zshrc
).
- What it does: This file configures your environment to use the core ROS 2 distribution you installed (e.g., Jazzy, Humble, Iron). It adds essential executables and libraries to your system’s
- Your Workspace Overlay (
~/ros2_ws/install/setup.bash
)- What it does: After you build your own custom ROS 2 packages (or in a workspace (e.g.,
~/ros2_ws
) using tools likecolcon
, aninstall
directory is created at~/ros2_ws/install/
. Sourcing thesetup.bash
file inside this install directory adds your newly built packages to the environment. Crucially, it prepends your workspace paths to the environment variables set by the underlay. This allows your custom packages (the overlay) to take precedence over the system-installed ones (the underlay), which is essential for development and testing. - When to source: Source this file after sourcing the distribution underlay, and immediately after successfully building your workspace with
colcon build
.
- What it does: After you build your own custom ROS 2 packages (or in a workspace (e.g.,
Pro-Tip: There’s also a local_setup.bash
in your workspace’s install
directory. This only sources the current workspace environment, ignoring any parent underlays. Use this in specific scenarios where you want to isolate the workspace environment completely.
Hint: $ROS_DISTRO
is an environment variable that contains the name of your ROS distribution (e.g. jazzy, iron, humble, …).
What Happens if You Forget to Source
- Commands Not Found: Your shell won’t find the
ros2
executable or any other ROS 2 tools because they aren’t in thePATH
. - Build & Runtime Failures: Essential environment variables needed by the build system (ament/colcon), DDS middleware (for node discovery), and launch files remain unset, leading to failures.
- Packages Not Visible: Even if you just built a package successfully, ROS 2 tools won’t be able to find or interact with it because your workspace isn’t part of the
AMENT_PREFIX_PATH
.
Example
I will now demonstrate you the importance of sourcing the ROS 2 configuration files and how the under-/ and overlaying mechanism works.
For this we will use the container environment detailed in one of my earlier posts: Leveraging VS Code Devcontainers for Efficient ROS 2 Development. However, we will use the entrypoint /bin/bash
rather then the /entrypoint.sh
script packed in the container.
Let’s get started!
Step 1: Download the Github Repository
First things first.
We need to download the repository that contains the scripts requried to bringup our ROS 2 dev environment:
git clone https://github.com/Robotics-Content-Lab/ros2_devcontainer
Step 2: Start the Container
Now we can startup the container.
Please note that here we provide an additional docker run
argument --entrypoint=/bin/bash
that will allow us to override the default entrypoint of our container.
We do this to start inside a container without ROS 2 configurations available.
cd ros2_devcontainer
bash scripts/run_container.sh --entrypoint=/bin/bash
Step 3: Why we Source
We will now see that even though we have the ROS 2 binaries installed we cannot use them until we souce the environment.
echo ${ROS_DISTRO}
# jazzy
if [ -e /opt/ros/${ROS_DISTRO}/ ]; then echo "ROS2 exists"; fi
# ROS2 exists
ros2
# bash: ros2: command not found
As we can see above, even though the ROS 2 distro jazzy is installed, we cannot use the ros2
binary. This happens because the shell’s environment variables (like PATH
, which tells the shell where to look for executables) haven’t been configured yet to include the ROS 2 installation directories.
To provide the ros2
binary we will now utilize the source
command.
source /opt/ros/jazzy/setup.bash
ros2
# usage: ros2 [-h] [--use-python-default-buffering]
# Call `ros2 <command> -h` for more detailed usage. ...
# ...
We can now utilize the ros2
binary, great stuff!
Here is what the source /opt/ros/jazzy/setup.bash
command does:
- Updates Execution Path (
$PATH
): It modifies your shell’s$PATH
environment variable by adding the directories containing core ROS 2 executables (likeros2
,rviz2
,rqt
) and potentially executables from other installed ROS packages. This allows you to simply typeros2
or other ROS commands directly into the terminal without specifying their full location. - Configures Library and Module Paths: It adjusts environment variables like
$LD_LIBRARY_PATH
(for C++ shared libraries) and$PYTHONPATH
(for Python modules). This ensures that when you run ROS 2 nodes or tools, they can correctly find and load the necessary underlying libraries (likerclcpp
,rclpy
) and Python code, including generated message/service/action types. - Sets Package Discovery Path (
$AMENT_PREFIX_PATH
): It sets or adds to the$AMENT_PREFIX_PATH
variable. This crucial variable tells ROS 2 tools where to look for installed packages and their resources (like launch files, parameter files, plugins, interface definitions). This allows commands likeros2 launch
,ros2 run
, andros2 pkg prefix
to locate and interact with the installed ROS 2 packages.
Overlaying a Workspace
As you have seen now, when you source
a ROS 2 setup.bash
file, it modifies your current shell’s environment variables. To illustrate how overlaying a workspace works, we will look at the default action_tutorials_py
package (installed via the package manager) and overlay it with a source installation.
Step 1: Inspect the Package Manager Installation
We will now use the ROS 2 CLI (ros2 pkg prefix
) to infer the location of the package.
ros2 pkg prefix action_tutorials_py
#/opt/ros/jazzy
Step 2: Overlay the Default ROS 2 Workspace
To overlay the default ROS 2 workspace we need to perform the following three steps:
- Download the
action_tutorials_py
package - Build the workspace containing it
- Source the workspace setup.bash file
git clone https://github.com/ros2/demos src/demos --depth=1 -b jazzy
# Cloning into 'src/demos'...
colcon build --packages-select action_tutorials_py
# - action_tutorials_interfaces
source install/setup.bash
ros2 pkg prefix action_tutorials_py
# /home/ros_user/ros2_ws/install/action_tutorials_py
Automating Environment Sourcing
To avoid having to manually source your environment every time, you can add the appropriate command to your shell’s initialization file. This ensures that every new terminal session is ready for ROS 2 development.
For bash users:
cat << EOF >> ~/.bashrc
source /opt/ros/${ROS_DISTRO}/setup.bash
source /home/ros_user/ros2_ws/install/setup.bash # enter the path to your ROS 2 WS here
EOF
source ~/.bashrc
For zsh users:
cat << EOF >> ~/.zshrc
source /opt/ros/${ROS_DISTRO}/setup.zsh
source /home/ros_user/ros2_ws/install/setup.zsh # enter the path to your ROS 2 WS here
EOF
source ~/.zshrc
Summary
Properly sourcing your ROS 2 environment is a fundamental step that ensures all the necessary tools, libraries, and paths are correctly configured in your terminal session. Without sourcing, even a perfectly installed ROS 2 setup will fail to function as expected. In this tutorial, we walked through:
- Launching a development container with an overridden entrypoint
- Demonstrating the impact of not sourcing the setup scripts
- Understanding the role of setup files in environment configuration
- Overlaying custom ROS 2 workspaces to enable development on top of existing packages
- Using your system environent file to automate the sourcing
Frequently Asked Questions (FAQ)
What does sourcing a ROS 2 setup file actually do?
Sourcing a setup file modifies your current shell environment by updating paths such as PATH
, PYTHONPATH
, LD_LIBRARY_PATH
, and AMENT_PREFIX_PATH
. This allows your terminal to locate and execute ROS 2 commands and load the required libraries.
Why does ros2
return “command not found” even though I’ve installed ROS 2?
This typically means you haven’t sourced the ROS 2 setup file for your distribution. Without sourcing, your shell doesn’t know where to find the ros2
executable or any associated tools.
Can I source multiple setup files?
Yes, it’s common to source the ROS 2 base setup file (e.g., from /opt/ros/jazzy/
) and then source your custom workspace (e.g., ~/ros2_ws/install/setup.bash
). The second source overlays your workspace on top of the base environment.
Do I need to source every time I open a new terminal?
By default, yes. However, you can automate this by adding the source
command to your .bashrc
or .zshrc
file as shown above.
What is overlaying a workspace in ROS 2?
Overlaying allows you to build and run packages from a local workspace on top of an existing ROS 2 installation. This is helpful for customizing or extending existing packages without altering the base distribution.