Free demoJob-oriented courses at Debugshala, Old Palasia, Indore. Freshers, non-IT and year-gap welcome.Book a free demo +91-8982385539

Install ROS 2 Jazzy on Ubuntu 24.04 and Set Up a Workspace

Lesson 2 of 5 · 11 min · Updated 12 Nov 2026

Install ROS 2 Jazzy on Ubuntu 24.04 step by step, pick the right 2026 distro, then build a colcon workspace and understand underlays, overlays and rosdep.

Think of a cloud kitchen in Vijay Nagar that runs on a big shared pantry. Rice, spices and oil come from the central store, already stocked and labelled. Nobody in the kitchen grinds their own garam masala.

Each chef also has a small counter of their own. On it sit the few things they are working on today: a new chutney, a tweaked marinade. If a chef's counter has a jar labelled "green chutney", that is the one they use, even though the pantry stocks a different green chutney too.

Installing ROS 2 sets up the pantry. Creating a workspace gives you your own counter. Most beginner confusion comes from not knowing which shelf a package was picked from.

What does installing ROS 2 actually set up?

Map the kitchen onto your computer. The central pantry is the binary installation under /opt/ros/jazzy, called the underlay. Your counter is a workspace such as ~/ros2_ws, called the overlay.

Reading the labels to decide which jar to use is what the setup.bash scripts do when you source them: they put each layer on your search paths, with the overlay checked first.

A ROS 2 installation is a set of prebuilt packages and tools placed under /opt/ros/<distro>, and a ROS 2 workspace is a directory of your own packages that the colcon build tool compiles into an overlay you activate by sourcing its setup script.

This lesson is the practical layer under ROS 2 basics: a working machine, a workspace you understand, and habits that prevent "package not found" errors.

Which ROS 2 distro should you install in 2026?

ROS 2 ships a new distribution every May. Even-year releases are long-term support (LTS), with five years of updates; odd-year releases last about eighteen months. As of November 2026 the official distribution list shows four supported releases.

Distro Released End of life Main Ubuntu Paired Gazebo
Humble Hawksbill (LTS) May 2022 May 2027 22.04 Jammy Fortress
Jazzy Jalisco (LTS) May 2024 May 2029 24.04 Noble Harmonic
Kilted Kaiju May 2025 December 2026 24.04 Noble Ionic
Lyrical Luth (LTS) 22 May 2026 May 2031 26.04 Resolute Jetty

How to choose:

  1. On Ubuntu 24.04, install Jazzy. It is the best-documented LTS, and this series targets it, including the Gazebo and Nav2 lessons.
  2. On a fresh Ubuntu 26.04 machine, install Lyrical. The steps below are identical with jazzy replaced by lyrical; just check your packages have Lyrical releases.
  3. Skip Kilted for new work. It ends in December 2026.
  4. Keep Humble only if an existing robot requires it.

Jazzy's packages are built for Ubuntu 24.04, and Lyrical supports 24.04 only from source. Pick Ubuntu first, and the distro follows.

Quick check

You are setting up a new Ubuntu 24.04 laptop for a ROS 2 course in November 2026. Which distro fits best?

How to install ROS 2 Jazzy on Ubuntu 24.04

These steps follow the official deb-package instructions for Jazzy. Run them in order in a terminal.

  1. Check the locale. ROS 2 needs UTF-8; minimal images often lack it.
  2. Add the ROS 2 apt source. The ros2-apt-source package installs the signing key and repository entry.
  3. Install the development tools. ros-dev-tools brings colcon, rosdep and vcstool.
  4. Install ROS 2. ros-jazzy-desktop includes RViz and demos; ros-jazzy-ros-base suits a headless robot.
Terminal
# 1. UTF-8 locale
locale                                   # look for UTF-8
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

# 2. Universe + the ROS 2 apt source
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F'"' '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"
sudo dpkg -i /tmp/ros2-apt-source.deb

# 3. Build tools
sudo apt update && sudo apt install ros-dev-tools

# 4. ROS 2 itself
sudo apt upgrade
sudo apt install ros-jazzy-desktop        # or ros-jazzy-ros-base on a robot

One Ubuntu 24.04 trap: if /etc/apt/sources.list.d/ubuntu.sources lacks the noble-updates and noble-backports suites, ros-dev-tools can fail with dependency conflicts. Add them, upgrade, and retry.

Verify the install with talker and listener

Open two terminals. Sourcing is per terminal, so do it in both.

Terminal
# Terminal 1
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_cpp talker

# Terminal 2
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_py listener

If the listener prints I heard: [Hello World: 1] and counts up, both client libraries and the default Fast DDS middleware work. Add the source line to ~/.bashrc so new terminals get it automatically.

Initialise rosdep once

rosdep reads the dependencies listed in each package and installs the matching Ubuntu packages. It needs a one-time set-up after installation.

Terminal
sudo rosdep init
rosdep update

What is a ROS 2 workspace?

A workspace is just a directory. You put package source code in its src folder, and colcon creates three folders beside it when you build.

ROS 2 workspace diagram showing the underlay at /opt/ros/jazzy and the overlay workspace ros2_ws with src, build, install and log folders, sourced in order so the overlay is searched first

Sourcing stacks the layers. The last workspace you source is searched first, so its packages win.

  • src holds your packages. It is the only folder you edit and put in Git.
  • build holds intermediate files. Safe to delete.
  • install holds built packages and the setup.bash you source.
  • log records every build.

The official tutorial recommends sourcing the overlay in a fresh terminal, after the underlay, rather than in the terminal where you just built.

Simulate how an overlay shadows a package

Sourcing sets environment variables such as AMENT_PREFIX_PATH, a list of install folders. When ROS looks for a package, it walks that list from the front and takes the first match. This toy model shows why your modified turtlesim wins over the stock one.

Python
underlay = {"/opt/ros/jazzy": {"rclpy": "7.1", "turtlesim": "1.8", "geometry_msgs": "5.3"}}
overlay = {"/home/you/ros2_ws/install": {"turtlesim": "1.8-mine", "my_robot": "0.1"}}

def source(prefix_path, workspace):
    # setup.bash prepends the new workspace, so it is searched first
    return list(workspace) + prefix_path

def find_package(prefix_path, layers, name):
    for prefix in prefix_path:
        if name in layers[prefix]:
            return prefix, layers[prefix][name]
    return None, "package not found"

layers = {**underlay, **overlay}
path = source([], underlay)
print("only underlay sourced:", find_package(path, layers, "turtlesim"))
print("  my_robot ->", find_package(path, layers, "my_robot"))
path = source(path, overlay)
print("overlay sourced too:  ", find_package(path, layers, "turtlesim"))
print("  my_robot ->", find_package(path, layers, "my_robot"))
print("  rclpy    ->", find_package(path, layers, "rclpy"))
print("AMENT_PREFIX_PATH =", ":".join(path))

Before the overlay is sourced, my_robot simply does not exist for ROS, which is the classic error new users meet. After sourcing, the overlay's turtlesim shadows the stock one, while rclpy still comes from the underlay because the overlay does not contain it.

Quick check

You built a package, but ros2 run says "Package not found". What is the most likely cause?

How to create and build your first workspace

  1. Make the folders and clone a known-good package (ros_tutorials, which contains turtlesim) into src, using your distro's branch.
  2. Run rosdep from the workspace root to install anything the packages need.
  3. Build with colcon from the workspace root, never from inside src.
  4. Open a new terminal, source the underlay, then source the overlay, and run a node.
Terminal
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/ros/ros_tutorials.git -b jazzy

cd ~/ros2_ws
rosdep install -i --from-path src --rosdistro jazzy -y
colcon build --symlink-install

# New terminal
source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/setup.bash
ros2 run turtlesim turtlesim_node

--symlink-install links Python and launch files instead of copying them, so Python edits need no rebuild. --packages-select my_robot builds one package, and --packages-up-to my_robot adds its dependencies.

Your own packages go into the same src folder. ROS 2 basics shows ros2 pkg create and the setup.py entry points; the next lesson, describing a robot with URDF, adds a robot description package to this workspace.

How does colcon decide the build order?

A workspace often holds packages that depend on each other: a message package, a driver that uses those messages, a bringup package that launches the driver. colcon reads every package.xml and builds dependencies first.

colcon build order diagram: package.xml dependencies form a graph where my_interfaces and my_description build first, then my_driver and my_controller in parallel, then my_bringup last

colcon builds packages with no unbuilt dependencies first, and packages on the same level in parallel.

Read dependencies out of package.xml

Each package declares what it needs with tags such as <depend>, <build_depend> and <exec_depend>. Here is a realistic package.xml for a small driver package.

xml
<?xml version="1.0"?>
<package format="3">
  <name>my_driver</name>
  <version>0.1.0</version>
  <description>Serial bridge between ROS 2 and the robot's motor board</description>
  <maintainer email="you@example.com">You</maintainer>
  <license>Apache-2.0</license>
  <depend>rclpy</depend>
  <depend>geometry_msgs</depend>
  <depend>my_interfaces</depend>
  <exec_depend>python3-serial</exec_depend>
  <test_depend>python3-pytest</test_depend>
  <export>
    <build_type>ament_python</build_type>
  </export>
</package>

rosdep and colcon treat these names differently. Names of ROS packages in your workspace, such as my_interfaces, become build-order edges. Everything else is a rosdep key that maps to a system package, so python3-serial becomes the Ubuntu package that provides pyserial.

Python
import xml.etree.ElementTree as ET

package_xml = """<package format="3"><name>my_driver</name>
  <depend>rclpy</depend><depend>geometry_msgs</depend><depend>my_interfaces</depend>
  <exec_depend>python3-serial</exec_depend><test_depend>python3-pytest</test_depend>
  <export><build_type>ament_python</build_type></export></package>"""

root = ET.fromstring(package_xml)
workspace_packages = {"my_interfaces", "my_description", "my_bringup"}
installed = {"rclpy", "geometry_msgs", "python3-pytest"}       # already on this machine

for tag in ("depend", "exec_depend", "test_depend"):
    for dep in root.iter(tag):
        name = dep.text
        if name in workspace_packages:
            where = "built from src first (colcon edge)"
        elif name in installed:
            where = "already installed"
        else:
            where = "rosdep will install it"
        print(f"{root.findtext('name')}: {tag:12} {name:15} -> {where}")
print("build type:", root.find("export/build_type").text)

Compute the build order yourself

Python's standard graphlib module does the same topological sort colcon does. Packages that become ready together could be built in parallel.

Python
from graphlib import TopologicalSorter

deps = {                                   # package -> workspace packages it needs
    "my_interfaces": set(),
    "my_driver": {"my_interfaces"},
    "my_description": set(),
    "my_controller": {"my_interfaces"},
    "my_bringup": {"my_driver", "my_description", "my_controller"},
}
ts = TopologicalSorter(deps)
ts.prepare()
wave = 1
while ts.is_active():
    ready = sorted(ts.get_ready())         # everything whose deps are built
    print(f"wave {wave}: build in parallel -> {', '.join(ready)}")
    ts.done(*ready)
    wave += 1

deps["my_interfaces"] = {"my_bringup"}     # a careless circular dependency
try:
    list(TopologicalSorter(deps).static_order())
except Exception as e:
    print("colcon would refuse too:", type(e).__name__)

The last lines show why circular dependencies are fatal: no package in the loop can ever be built first. If colcon reports a cycle, move the shared messages into their own package.

Common ROS 2 installation and workspace mistakes

  • Mixing distros. Sourcing Humble and Jazzy in one terminal, or cloning a humble branch into a Jazzy workspace, gives baffling errors. One distro per machine or container is simplest.
  • Forgetting to re-source after adding a package. New packages appear only after you source install/setup.bash again.
  • A Conda or virtualenv Python on the path. ROS 2 Jazzy's binaries are built against Ubuntu 24.04's system Python. Deactivate Conda before building, or colcon may pick the wrong interpreter.
  • Two laptops controlling each other's robots. In a shared lab, nodes on the same network discover each other. Give each student a different ROS_DOMAIN_ID, for example export ROS_DOMAIN_ID=7.

If loops and conditions in these scripts still feel shaky, the shared for loop and if-else lessons are a quick refresher, and you can warm up your shell and Python logic on Debugshala Test.

Key takeaways

  • Pick Ubuntu first: 24.04 goes with Jazzy, 26.04 with Lyrical. Kilted ends in December 2026.
  • Install with the ros2-apt-source package, then ros-dev-tools and ros-jazzy-desktop.
  • /opt/ros/jazzy is the underlay; your workspace's install folder is an overlay searched first.
  • A workspace is src plus colcon's build, install and log folders; only src goes in Git.
  • rosdep installs system dependencies; colcon builds workspace packages in dependency order.
Take the free ROS 2 quiz10 quick questions with explanations. No sign-up needed, and you can come back to this lesson after.

FAQ

Which version of ROS 2 should a beginner install?

Install ROS 2 Jazzy Jalisco on Ubuntu 24.04. It is a long-term support release maintained until May 2029, and most tutorials, simulators and third-party packages support it. If you are starting on Ubuntu 26.04, install Lyrical Luth, the newest LTS from May 2026, with the same steps.

Can I install ROS 2 on Windows?

Yes. Jazzy publishes Windows binaries, but most learning material, rosdep and many community packages assume Ubuntu. For a course or self-study, running Ubuntu 24.04 inside WSL 2 on Windows is usually smoother, and RViz and Gazebo windows display through WSLg on Windows 11.

What is the difference between ros-jazzy-desktop and ros-jazzy-ros-base?

ros-jazzy-desktop includes the core libraries plus RViz, rqt, demos and tutorials, so it suits a development laptop. ros-jazzy-ros-base contains only the communication libraries, message packages and command-line tools, with no graphical tools, so it suits a Raspberry Pi or other robot computer.

Why do I need to source setup.bash in every terminal?

Sourcing sets environment variables, such as the package search path, only for the current shell session. A new terminal starts without them. Adding the underlay's source line to ~/.bashrc automates the base install, while sourcing the workspace by hand keeps you aware of which overlay is active.

Can I learn ROS 2 with guidance in Indore?

Yes. Debugshala's Old Palasia robotics course with ROS 2 basics introduces nodes and topics after you have worked with Arduino, ESP32, sensors and motors, and pairs them with Raspberry Pi and camera work. Classes are taught in English and Hindi, and a free demo class comes before any payment.

From the team behind this site

Go further with the Robotics Course at Debugshala

These tutorials are written by Debugshala, a training and placement institute at Old Palasia, Indore. The classroom course adds live mentoring, real projects and interview preparation.

  • Offline classes at Old Palasia, Indore
  • Free demo class before you pay
  • Non-IT, fresher and year-gap friendly
  • Placement assistance

700+ students placed · 200+ hiring partners · 4.9★ Google rating

ROS 2 Basics: Nodes, Topics, Services and Launch FilesURDF in ROS 2: Describe a Robot Model with Links and Joints