How to Create a ROS 2 Package – Lyrical

In this tutorial, we will create a ROS 2 package. The official instructions for creating a package are here, but I will walk you through the entire process, step by step.

Follow along with me click by click, keystroke by keystroke.

Prerequisites

What is a Package?

In ROS 2, a package is a folder that contains files related to a specific functionality or a component of a robotic system.

This folder includes things like:

  • The actual code that makes the package do what it’s supposed to do.
  • Files that help define how the code should be started and set up.
  • Any special message types or configurations the package needs to work properly.

ROS 2 packages are designed to perform specific jobs. For example, consider a robot that needs to determine its position and orientation within a given environment. 

In ROS 2, you could create a package called “localization” to handle this specific task.

The “localization” package would contain:

  • The code that processes data from the robot’s sensors (e.g., cameras or LIDAR) and uses algorithms to estimate the robot’s position and orientation.
  • A file, known as a README file, that explains the purpose of the package and how to install the code.
  • Any custom message the package needs to share localization data with other parts of the robot’s software, such as the estimated position and orientation.

By organizing the localization functionality into its own ROS 2 package, you can focus on developing and refining the algorithms and code specific to localization without worrying about other aspects of the robot’s software. 

This modular approach makes it easier to maintain, debug, and improve the localization capabilities of your robot, and allows you to reuse the package across different projects or robots that require similar localization features.

For a real-world robotics project, you will combine multiple packages together to create a complete robotic application that performs various tasks and functions. 

Create the Package

Let’s create our first ROS 2 package.

Open a terminal window.

Type the following commands

cd ~/ros2_ws/src

Best practice is to create your ROS 2 packages inside the src directory.

Now let’s run the ros2 command for creating our first package.

ros2 pkg create --build-type ament_cmake --license Apache-2.0 ros2_fundamentals_examples

This command creates a new ROS 2 package named ros2_fundamentals_examples. We could have called our package any name, but I chose to call it ros2_fundamentals_examples.

  • –build-type ament_cmake specifies that the package should use the ament_cmake build system, which is the recommended build system for ROS 2 packages written in C++. Think of it as a set of instructions and tools that help you put together all the pieces of your ROS 2 package, making sure everything is properly compiled, linked, and ready to run.
  • –license Apache-2.0 sets the license for the package to Apache License 2.0, which is a license that has minimal restrictions on how others can use, modify, and distribute the software.

Now let’s build our new package. First navigate to the root of the workspace.

cd ~/ros2_ws
colcon build 
1-colcon-build

Let’s see if our new package is recognized by ROS 2.

Either open a new terminal window or source the bashrc file like this:

source ~/.bashrc
ros2 pkg list

You can see the newly created package right there at the top.

2-ros2-fundamental-package

Add the “build” Alias to the Bashrc File

Now open a terminal window, and type this:

echo "alias build='cd ~/ros2_ws && colcon build'" >> ~/.bashrc && source ~/.bashrc

This single command adds the alias called “build” to your .bashrc file. Anytime you want to build all the packages in your ros2 workspace, all you have to do now is type:

build
3-build-alias

To build a specific package, you would type:

colcon build --packages-select ros2_fundamentals_examples

Press Enter to execute the command and build the selected package.

7-build-specific-package

Install Useful Packages (Optional but Recommended)

Let’s install some useful external packages that will help us along the way. 

If you don’t have Terminator, install it now. Terminator lets you have multiple terminal windows open within a single interface.

Type the following command:

sudo apt-get update -y && sudo apt-get upgrade -y && sudo apt-get install terminator -y

To open terminator, you can either click the ring in the bottom left of your Desktop (i.e. “Show Apps” button) and search for “terminator,” or you can type terminator in a regular terminal window.

8-show-apps
9-terminator

You can right-click to split the terminal into different panels.

Let’s install some useful ROS 2 packages. You don’t need to worry about what these packages do for now. 

You already set up the ROS 2 software repository back when you installed ROS 2, so you do not need to do that part again. Open a terminal window, and type the following:

sudo apt update
sudo apt-get install -y ros-${ROS_DISTRO}-ros-gz ros-${ROS_DISTRO}-gz-ros2-control ros-${ROS_DISTRO}-gz-ros2-control-demos ros-${ROS_DISTRO}-joint-state-publisher-gui ros-${ROS_DISTRO}-moveit ros-${ROS_DISTRO}-xacro ros-${ROS_DISTRO}-ros2-control ros-${ROS_DISTRO}-ros2-controllers libserial-dev python3-pip

That’s it! Keep building!

How to Create a Workspace in ROS 2 Lyrical

In this tutorial, we will create a ROS 2 workspace.

In ROS 2, a workspace is a folder that is the central location for organizing and developing your robot software. It contains all the code, data files, and configuration scripts related to your specific robot project. 

The official instructions for creating a workspace are here, but I will walk you through the entire process, step by step.

Let’s get started!

Prerequisites

Directions

Open a terminal, and type the following command to create your workspace. We can name our workspace anything, but I will name it ros2_ws to stand for ROS 2 workspace.

mkdir -p ~/ros2_ws/src

The src folder that is inside your ROS 2 workspace is where all your code will go for your robot.

Move to the root of your new workspace using this command:

cd ~/ros2_ws/

We don’t have any code inside our workspace source folder yet, but when we do, we will need to run the command below to build the workspace. 

colcon build

This colcon build command needs to be run in the root of your workspace whenever you make additions or changes to the code for the robot.

‘colcon build’ takes all the different pieces of your robot’s software and puts them together. This makes the software ready for the robot to use.

Go ahead and run the colcon build command now.

colcon build

Now type this command:

dir

Here is what you should see:

1-colcon-build

There are three folders. These folders are automatically created when you run the colcon build command in your ROS 2 workspace:

  • build: This is where ROS 2 temporarily stores files while it’s putting your code together.
  • install: This is where the finished, ready-to-use parts of your robot’s software are placed.
  • log: This folder keeps track of what happened when you built your code, which is helpful for finding and fixing problems.

Now we need to run the following command to make sure our workspace can be found any time we open a new terminal window.

echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc

Remember that ~/.bashrc file is a script that runs whenever a new terminal session is started.

You can see that we have a new entry in the bashrc file right at the bottom.

gedit ~/.bashrc
2-new-entry-bashrc

That’s it! You have now created a ROS 2 workspace. I’ll see you in the next tutorial. Keep building!

How to Install ROS 2 Lyrical

In this tutorial, we will install ROS 2 Lyrical Luth.

By the end of this tutorial, you will be running your first ROS 2 programs.

You Will Need

In order to complete this tutorial, you will need:

  • A computer or virtual machine running Ubuntu 26.04. If you followed my previous tutorial, you already have that setup.

Set the Locale

The official steps for installing ROS are at this link at ROS.org, but let’s go through this entire process together.

Follow along with me click by click, keystroke by keystroke.

We will begin by installing ROS 2 Lyrical via Debian Packages. Debian packages are software files used to install programs and applications on Ubuntu.

Open a new terminal window.

Type this command inside a terminal window.

locale

A locale is a set of variables that define the language, country, and character encoding settings. These settings are used by applications to determine how to display text, dates, times, and other information.

Now type the following command:

sudo apt update && sudo apt install locales

“sudo apt update” updates the package index list. This list is a database of all the software packages available for your version of Ubuntu.

“sudo apt install locales” installs the locales package, which provides support for different languages and regions.

Now type the following commands into the terminal window to generate locale definition files. After each command, press Enter on your keyboard:

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

In this case, these commands are generating locale definition files for the English (United States) locale and the English (United States) UTF-8 locale. The UTF-8 locale is a special locale that supports the UTF-8 character encoding, which is the standard encoding for most languages.

Now we need to verify the settings by typing:

locale

Here is what you should see:

1-locale

Enable the Required Repositories

Let’s add the ROS 2 apt repository to our system. APT stands for “Advanced Package Repository”. This repository provides a convenient way to install and manage ROS 2 packages without having to clone packages to your computer from GitHub and build them from that source code.  

Open a terminal window, and type the following two commands:

sudo apt install software-properties-common
sudo add-apt-repository universe

Press Enter.

The software-properties-common package provides a number of tools for managing software sources on Ubuntu and Debian systems. 

The universe repository is a software repository that contains a wide variety of software packages, including many that are not included in the default Ubuntu and Debian repositories. 

Now we need to tell your computer where to find the ROS 2 software, and we need to add the ROS 2 GPG key. The GPG key makes sure the software packages you are installing are from a trusted source.

Type this command:

sudo apt update && sudo apt install curl -y

That installs curl, a little program that downloads files from the internet.

Now type this command to download the ROS 2 setup file (copy and paste all of this below):

curl -L -o /tmp/ros2-apt-source.deb https://github.com/ros-infrastructure/ros-apt-source/releases/download/1.2.0/ros2-apt-source_1.2.0.resolute_all.deb

What does this do? It downloads one small file and saves it in your /tmp folder. That file contains the address of the ROS 2 software repository and the GPG key that goes with it. The word “resolute” in the file name is the nickname for Ubuntu 26.04, so this is the right file for the version of Ubuntu we are using.

Now install that file by typing:

sudo dpkg -i /tmp/ros2-apt-source.deb

Your computer now knows where to download ROS 2 from, and it trusts the packages it finds there. In older versions of ROS 2, you had to download the key yourself and then type out the repository address by hand. You do not have to do any of that anymore.

Type the following command to install ROS 2 development tools.

sudo apt update && sudo apt install ros-dev-tools

Upgrade the packages on your system to make sure you have the newest versions.

sudo apt upgrade -y

Install ROS 2

Now for the fun part. Here is where we get to install ROS 2 Lyrical. 

Open a terminal window, and type this command:

sudo apt install ros-lyrical-desktop

Set Up the Environment Variables

Once Lyrical has finished installing, you need to set up the important environment variables. Environment variables are settings that tell your computer how to find and use ROS 2 commands and packages.

Open a terminal window, and type this command:

echo "source /opt/ros/lyrical/setup.bash" >> ~/.bashrc

When you run this command, it appends the line source /opt/ros/lyrical/setup.bash to your ~/.bashrc file

What does this do? Each time you open a new terminal window, you are starting what is called a bash session. The bash session needs to know what version of ROS 2 you are using. 

By adding this line (echo “source /opt/ros/lyrical/setup.bash”) to your ~/.bashrc file, you ensure the necessary environment variables and paths for ROS 2 Lyrical are properly set up each time you open a new terminal window, allowing you to use ROS 2 commands and tools without having to manually run the setup.bash script every time.

For the changes to take effect, you now need to open a new terminal window, or you can type this command in the current terminal:

source ~/.bashrc

You can verify that line was added by typing:

sudo apt-get install gedit -y
gedit ~/.bashrc

Close the gedit window.

Check Your ROS 2 Version

Now let’s see what ROS 2 version we are using using:

printenv ROS_DISTRO

You should see “lyrical”.

You can also type:

env | grep ROS

Finally, you can also type:

echo $ROS_DISTRO

Set up the system to manage ROS package dependencies.

sudo rosdep init
rosdep update

One thing worth knowing: if sudo rosdep init has already been run on this machine, running it a second time prints an error saying the default sources list file already exists. That error is harmless. Your rosdep setup is already in place, so just go ahead and run rosdep update.

Install Gazebo and Other Useful Packages

Let’s install some other useful packages like pip (the Python package manager), Gazebo, a simulation software for robotics, and NumPy, a scientific computing library for Python.

sudo apt-get install python3 python3-pip -y
sudo apt-get install ros-${ROS_DISTRO}-ros-gz -y
sudo apt-get install python3-numpy

A note on Gazebo versions. ROS 2 Lyrical pairs with Gazebo Jetty (gz-sim 10). If you are coming from the previous release, that is a step up from gz-sim 8.

You do not need to add the separate Gazebo apt repository: on Lyrical, Gazebo arrives as ROS vendor packages straight from packages.ros.org, and ros-lyrical-desktop already pulls Gazebo Jetty in on its own. The ros-gz package you just installed is the bridge between ROS 2 and Gazebo.

You can check which version you got by typing:

gz sim --versions

On my Ubuntu 26.04 machine, that prints 10.5.0.

Test Your Gazebo Installation

If you want to run an example Gazebo simulation world now, open a new terminal window, and type:

gz sim -v 4 shapes.sdf

Now test your Gazebo installation again by typing the following command:

gz sim

You should see this screen.

4-see-this-screen

Click on the NAO Joint Control simulation, and click Run.

5-nao-simulation

Close the simulation by typing CTRL + C in the terminal window.

Now try the Panda Joint Control World.

gz sim

Click on the Panda Joint Control World simulation, and click Run. It might take up to 60 seconds to load. Just be patient and don’t quit Gazebo if asked.

6-panda-joint-control-world

Close the simulation by typing CTRL + C in the terminal window.

Now run another example:

gz sim shapes.sdf -v 4

Close the simulation by typing CTRL + C in the terminal window.

Now let’s run the same shapes example using a ros2 command (source: official Gazebo ROS 2 GitHub repository):

ros2 launch ros_gz_sim gz_sim.launch.py gz_args:="shapes.sdf"
7-shapes-sdf

Close the simulation by typing CTRL + C in the terminal window.

Test Your ROS 2 Installation

Now that we have tested Gazebo, let’s test our ROS 2 installation by running some sample programs.

Open a terminal window, and type:

ros2 run demo_nodes_cpp talker
9-talker

This command runs a pre-built program called “talker” that comes with ROS 2. The “talker” program publishes messages to the ROS 2 system in string format. 

Open another terminal window, and type:

ros2 run demo_nodes_py listener
10-listener

If your output looks similar to the images above, you have installed ROS 2 successfully. 

To close these programs, press CTRL + C on your keyboard in both terminal windows.

So what did we just do here, and what do these two hello world programs we just ran have to do with real robots?

So imagine you’re building a robot that needs to navigate through a room. The “talker” program is like a sensor on the robot (e.g., a depth camera for example) that constantly sends out information about what it sees. 

The “listener” program, on the other hand, receives the information that was published by the talker program. This listener program, in a real robot, could do something with that data like stop the wheels if an obstacle is detected by the camera.

The talker program is what we call in ROS 2, a publisher. The listener program is called a subscriber. Remember those two terms. Those are the two most important terms in all of ROS 2. 

A ROS 2 publisher sends data, and a subscriber receives data. 

In future tutorials, we will create our own publishers and subscribers for actual robots. 

Publishers and subscribers are the main way programs exchange information with each other inside a robot.

So, again, just remember this…publishers are programs that send data to other programs, and subscribers are programs that receive data from other programs. All these programs are usually written in either Python or C++.

Collectively, publishers and subscribers in ROS 2 are called nodes. You just saw how to run a publisher node named talker and a subscriber node named listener.

The term node is the third most important term in all of ROS 2. So remember it because you will be using that term again and again over the course of your work with ROS 2.

To close out this tutorial, let me show you a cool program that enables you to show multiple terminal windows in a single window.

The program is called terminator.

Open a terminal window, and type:

sudo apt-get install terminator -y

Now type:

terminator

Right-click on the screen, and click “Split Horizontally”.

11-split-horizontally

On the top panel, type:

ros2 run demo_nodes_cpp talker

On the bottom panel, type:

ros2 run demo_nodes_py listener

Now, press Enter in both terminals.

Here is what you should get:

12-terminator

Press CTRL + C in both terminal windows to close everything.

That’s it! Keep building! I’ll see you in the next tutorial.