How to build a local Debian ROS2 package

How to build a local Debian ROS2 package

What we are going to learn

  1. What is a Debian package and what is it used for
  2. How to get the building dependencies
  3. How to initialize rosdep
  4. How to create a Debian installable package
  5. How to install a ROS2 package from a local Debian installable file

List of resources used in this post

  1. The previous part of this series: https://www.theconstruct.ai/how-to-release-a-ros-2-binary-package-part-2-2/
  2. Use the rosject: https://app.theconstructsim.com/l/5142d6f5/
  3. The Construct: https://app.theconstructsim.com/
  4. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days (Python): https://app.theconstructsim.com/#/Course/73
    2. ROS2 Basics in 5 Days (C++): https://app.theconstructsim.com/#/Course/61
    3. ROS2 Navigation (Galactic): https://app.theconstructsim.com/Course/109
    4. ROS2 Navigation training: https://www.theconstruct.ai/ros2-navigation-training/

Overview

ROS2, the improved version of ROS (ROS1), is quickly becoming the standard for developing robotics applications.

In this post, we will take a look at how to build a local Debian package out of a ROS 2 package that you have in your system. Private Debian packages (*.deb files) are easy to share, install, upgrade and uninstall without you having to share any source code.

You can easily install them with sudo dpkg -i pkg-name.deb, for example.

It is highly recommended that you follow the previous posts of this series:

ROS Inside!

ROS Inside

ROS Inside

Before anything else, in case you want to use the logo above on your own robot or computer, feel free to download it for free and attach it to your robot. It is really free. Find it in the link below:

ROS Inside logo

Acknowledgment

This post is based on ROS2’s official documentation, check it out here:

This notebook is based on the official instructions.

Opening the rosject

In order to follow this tutorial, we need to have ROS2 installed in our system, and ideally a ros2_ws (ROS2 Workspace). To make your life easier, we already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/5142d6f5/.

You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).

Learn ROS2 Parameters - Run rosject

Learn ROS2 Topics vs Service vs Action – Run rosject (example of the RUN button)

After pressing the Run button, you should have the rosject loaded. Now, let’s head to the next section to get some real practice.

Compiling the ros2_ws (ROS 2 Workspace)

In the rosject link shared above, we have the ros2_draw_squares package developed by GitHub user samialperen. The package will be used in our example and can be found at https://github.com/samialperen/ros2_move_robot.

Let’s start by compiling the ros2_draw_squares package that is inside the ~/ros2_ws/src folder. In order to do that, we need a terminal. You can open one by clicking the Open a new terminal button.

Open a new Terminal

Open a new Terminal

Once the terminal is open, we can compile the package using the following commands:

cd ~/ros2_ws
colcon build
source install/setup.bash

 

Starting the simulation

Before showing the process of creating the Debian file, let’s see it in action first through a robot simulation.

Let’s start by exporting the GAZEBO_MODEL_PATH variable to the location of the turtlebot3 model files, so that the Gazebo Simulator can show the robot properly:

source install/setup.bash
export GAZEBO_MODEL_PATH=/home/user/ros2_ws/src/turtlebot3_simulations/turtlebot3_gazebo/models:${GAZEBO_MODEL_PATH}
export GAZEBO_RESOURCE_PATH=/home/user/ros2_ws/src/turtlebot3_simulations/turtlebot3_gazebo:${GAZEBO_RESOURCE_PATH}

 

Now let’s set the TURTLEBOT3_MODEL to waffle:

export TURTLEBOT3_MODEL=waffle
ros2 launch turtlebot3_gazebo empty_world.launch.py

You should see the Gazebo simulator pop up with an empty world.

Now, open a second Terminal, and run the service server node using the command below:

ros2 launch ros2_draw_squares move_robot_in_square_service_server.launch.py

 

And from a third terminal, we can run the service move_robot_in_square.

ros2 service call /move_robot_in_square std_srvs/srv/Trigger '{}'

If everything went ok, in the simulation window you should have seen the Turtlebot robot moving in a square-like format.

Turblebot robot moving in a square-like format

Turblebot robot moving in a square-like format

 

Alright, we already saw the package in action. Now let us see the process of converting it into a Debian file.

Feel free to kill the existing simulation by pressing CTRL+C in the three terminals.

What is a Debian package and what is it used for?

.deb file in essence it’s a very simple and easy way of distributing software in Debian-based Linux distributions. You can think of it as a file similar to a .tar file which is a format used to store multiple files in one single file. Using a Debian package we can install a ROS2 package in our environment without having to have the source files.

So for instance the example project contains the following files and directories:
-ros2_draw_squares
 |-package.xml
 |-launch
 | |-call_move_robot_in_square_service_server.launch.py
 | |-move_robot_in_square_service_server.launch.py
 |-include
 | |-ros2_draw_squares
 | | |-move_robot.hpp
 |-README.md
 |-src
 | |-move_robot.cpp
 | |-move_robot_in_square_service_server.cpp
 | |-move_robot_in_square_service_client.cpp
 | |-move_robot_node.cpp
 |-CMakeLists.txt
The Debian file will consist of only one single file.

Deb files also hold metadata about the software they provide. By the use of metadata, Debian packaging handles the installation, removal, and dependencies of packages.

In the context of robotics, Debian files provide a convenient way to deploy and remotely manage robotic software on real robots. This includes installing, updating, and removing packages through an SSH (Secure Shell) connection, for example.

Get the building dependencies

After having stopped everything by pressing CTRL+C in the three terminals, the next thing we need to do is to actually install the building tools needed by running the following commands in the first terminal:
sudo apt update
sudo apt install python3-bloom python3-rosdep fakeroot dh-make

This will install the tools python3-bloom python3-rosdep, fakeroot, and dh-make packages.

Since this can take a while to install, you just have to wait a bit for it to finish.

Check the ROS2 package dependencies

All of the dependencies of the package should be properly declared in the package.xml file of the ROS 2 package.

Still in the first terminal, let’s see the dependencies that we have for our package:

cat ~/ros2_ws/src/ros2_draw_squares/package.xml

We just have to make sure all package dependencies are listed using the correct dependency tag. If when creating your own package you are not sure what kind of dependency a package is, you can use <depend> tag to specify that the dependency is a build, export, and execution one.

Initialize rosdep

Let’s initialize rosdep. That can still be done in the first terminal:

sudo rosdep init

You might see the following error if rosdep has already been initialized in the past:

ERROR: default sources list file already exists:
        /etc/ros/rosdep/sources.list.d/20-default.list
Please delete if you wish to re-initialize

Create a Debian installable package

cd ~/ros2_ws/src/ros2_draw_squares

After that, let’s use the bloom-generate command:

bloom-generate rosdebian

The expected output is something similar to the following:

bloom-generate rosdebian output

bloom-generate rosdebian output

 

If for whatever reason you get an error message like the one below:

Could not resolve rosdep key

Could not resolve rosdep key

This means that rosdep could not find that particular package dependency. Verify if the package must be indexed in the rosdistro by creating a PR.

After successfully running the above command, you should get a directory named debian in the current directory, which contains the compiled files and rules required to create the Debian file. The “ls” command output should be like this:

 CMakeLists.txt  README.md  debian  include  launch  package.xml  src

 

Use the following command to create a Debian package:

fakeroot debian/rules binary

We should see something similar to the following animation:

fakeroot expected output

fakeroot expected output

After a while, the command should finish with no errors.

The command we just executed should have created a .deb file in the directory that is one level above. We can check it with:

cd ..

ls

Which should show us the following:

Debian file created

Debian file created

Install a ROS2 package from a local Debian installable file

Alright, our Debian file has been successfully generated.

Let us install this Debian package on our own machine by using the package management program called dpkg:

sudo dpkg --install ros-galactic-ros2-draw-squares_0.0.0-0focal_amd64.deb

This will install the Debian package (including unpacking and configuring) onto the file system of the hard disk.

 

dpkg install output

dpkg install output

After having installed the Debian package, it is ready to be used in our environment. Let’s find out where the package got installed. To do so we first need to get the package name:

dpkg --info ros-galactic-ros2-draw-squares_0.0.0-0focal_amd64.deb

 

Once we have the name, we can display where the files in the deb package got installed to:

dpkg -L ros-galactic-ros2-draw-squares

 

We can see that this package is now installed in the same location where the main ROS 2 installation is located.

Finally, in case you want to uninstall this package, we can easily do it also with dpkg:

sudo dpkg -P ros-galactic-ros2-draw-squares

 

And if you want to take it further from here, you can even create your own apt repository to host your private ROS2 .deb packages, but that’s a story for another time.

 

Congratulations on reaching the end of this tutorial. We hope this post was really helpful to you.

If you want a live version of this post with more details, please check the video in the next section.

Youtube video

So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.

Keep pushing your ROS Learning.

Related Courses & Training

If you want to learn more about ROS and ROS2, we recommend the following courses:

[ROS2 Q&A] How to spawn robot from sam_bot nav2 tutorial #237

[ROS2 Q&A] How to spawn robot from sam_bot nav2 tutorial #237

What we are going to learn

  1. How to create a ROS 2 package
  2. How to load a URDF robot for the Gazebo simulator

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/50fbfe47/
  2. The Construct: https://app.theconstructsim.com/
  3. Nav2 documentation: https://navigation.ros.org/setup_guides/index.html
  4. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days (Python): https://app.theconstructsim.com/#/Course/73
    2. ROS2 Basics in 5 Days (C++): https://app.theconstructsim.com/#/Course/61
    3. ROS2 Navigation (Galactic): https://app.theconstructsim.com/Course/109
    4. ROS2 Navigation training: https://www.theconstruct.ai/ros2-navigation-training/

Overview

This post answers the following question posted at ROS answers:

ROS Inside!

ROS inside

ROS inside

Before anything else, in case you want to use the logo above on your own robot or computer, feel free to download it for free and attach it to your robot. It is really free. Find it in the link below:

ROS Inside logo

Opening the rosject

In order to follow this tutorial, we need to have ROS2 installed in our system, and ideally a ros2_ws (ROS2 Workspace). To make your life easier, we already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/50fbfe47/.

You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).

Learn ROS2 Parameters - Run rosject

Learn ROS2 Topics vs Service vs Action – Run rosject (example of the RUN button)

After pressing the Run button, you should have the rosject loaded. Now, let’s head to the next section to get some real practice.

Opening the Code Editor

Now that the rosject is open, let’s open the Code Editor by clicking on the second link:

Open the IDE - Code Editor

Open the IDE – Code Editor

 

Once the Code Editor is open, you should be able to see that we have a ros2_ws folder (ROS2 workspace)

The sam_bot_description.urdf file

Now that you have the Code Editor open, let’s have a look at the file that contains the robot description. The file is inside the ros2_ws folder. The full path is:

/home/user/ros2_ws/src/sam_bot_description/src/description/sam_bot_description.urdf

 

In case you want to see the content using the terminal, you can open it by clicking the Open a new terminal button.

Open a new Terminal

Open a new Terminal

Once inside the terminal, just type the command below (although it is better to see the file using the Code Editor):

cat /home/user/ros2_ws/src/sam_bot_description/src/description/sam_bot_description.urdf

 

Starting the simulation

As we saw in the overview, the question asked in ROS Answers was saying that the robot wheels were not working. That happened probably because the person forgot to add something to the URDF file.

To better understand the URDF file, you can refer to the Nav 2 Documentation: https://navigation.ros.org/setup_guides/urdf/setup_urdf.html and https://navigation.ros.org/setup_guides/odom/setup_odom.html

Now, go to the terminal you have open and run the following command to run the simulation:

ros2 launch  sam_bot_description display.launch.py

 

If everything went well, you should have Gazebo as well as RViz open, like in the image below (If the Graphical Tools don’t open automatically, just click click the 4th and 5th buttons on the bottom left bar to Open Gazebo and Open the Graphical Tools):

 

You can also see the Gazebo simulation by clicking the 4th icon named Open Gazebo. There you will see that the wheels are in place.

Well, that is pretty much it.

We hope this post was really helpful to you. If you want a live version of this post with more details, please check the video in the next section.

Youtube video

So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.

Keep pushing your ROS Learning.

Related Courses & Training

If you want to learn more about ROS and ROS2, we recommend the following courses:

[ROS2 Q&A] How to setup identical robots for multi-robot navigation #236

[ROS2 Q&A] How to setup identical robots for multi-robot navigation #236

What we are going to learn

  1. How to create a launch file that launches several robots
  2. How to modify the robot state publisher to add a frame prefix
  3. How to pass a variable to a xacro file

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/50f92c5f/
  2. The Construct: https://app.theconstructsim.com/
  3. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days (Python): https://app.theconstructsim.com/#/Course/73
    2. ROS2 Basics in 5 Days (C++): https://app.theconstructsim.com/#/Course/61
    3. ROS2 Navigation (Galactic): https://app.theconstructsim.com/Course/109
    4. ROS2 Navigation training: https://www.theconstruct.ai/ros2-navigation-training/

Overview

In this post, we will learn to make navigation in ROS 2 work with 2 identical robots using ROS Navigation 2.

This post answers the following question on ROS answers: https://answers.ros.org/question/405822/multi-robot-tf-with-namespaces-for-tf-or-with-frame_prefix-what-is-the-right-way-to-do-it-ros2/

ROS Inside!

ROS inside

ROS inside

Before anything else, in case you want to use the logo above on your own robot, feel free to download it for free and attach it to your robot. It is really free. Find it in the link below:

ROS Inside logo

Opening the rosject

In order to have navigation in ROS2 working with two robots, we need to have ROS2 installed in our system, and ideally a ros2_ws (ROS2 Workspace). To make your life easier, we already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/50f92c5f/.

You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).

Learn ROS2 Parameters - Run rosject

Learn ROS2 Topics vs Service vs Action – Run rosject (example of the RUN button)

After pressing the Run button, you should have the rosject loaded. Now, head to the next section to get some real practice.

Launching the simulation

We already have provided a simulation with two simulated robots. In order to run the simulation, let’s start by opening a terminal:

Open a new Terminal

Open a new Terminal

Once the terminal is open, we can run the simulation with the following command:

ros2 launch barista_gazebo main_two_robots.launch.xml

 

You should have a pop-up with the simulation running. If the simulation fails to load for any reason, just run the same command again. You should have a simulation with two robots, something similar to the following:

How to setup identical robots for multi robot navigation - gazebo simulator

How to setup identical robots for multi-robot navigation – gazebo simulator

 

What we need in order to have multi-robot navigation is:

  • First, have the cmd_vel and scan topics separated into different namespaces
  • Second, have TF Tree separated.

 

After launching the simulation, we can go to a second terminal and list the topics with rostopic list. The list of topics should be like the following:

ros2 topic list

/barista_1/cmd_vel
/barista_1/joint_states
/barista_1/odom
/barista_1/robot_description
/barista_1/scan
/barista_2/cmd_vel
/barista_2/joint_states
/barista_2/odom
/barista_2/robot_description
/barista_2/scan
/clock
/parameter_events
/performance_metrics
/rosout
/tf
/tf_static

 

As we can see, we have two namespaces, named /barista_1/ and /barista_2/

Moving the robots independently

If we want to move the barista_1 robot, for example, we can run the command below:

ros2 run teleop_twist_keyboard teleop_twist_keyboard cmd_vel:=barista_1/cmd_vel

 

The command above launches the script that allows us to move the robot using the keyboard, mapping the cmd_vel topic to barista_1/cmd_vel. That is the topic used to move the robot around.

You can press the “k” key to stop the robot, and other keys to move the robot, as we can see in the instructions:

This node takes keypresses from the keyboard and publishes them
as Twist messages. It works best with a US keyboard layout.
---------------------------
Moving around:
   u    i    o
   j    k    l
   m    ,    .

For Holonomic mode (strafing), hold down the shift key:
---------------------------
   U    I    O
   J    K    L
   M    <    >

t : up (+z)
b : down (-z)

anything else : stop

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%

CTRL-C to quit

 

If instead of the red robot you want to move the blue one, you just run the same command but remapping the cmd_vel topic to barista_2/cmd_vel:

ros2 run teleop_twist_keyboard teleop_twist_keyboard cmd_vel:=barista_1/cmd_vel

 

Separated TF Trees

To see the separated TF Trees, we can run rqt_tf_tree. We can install it for ROS Galactic in a third terminal using the following commands:

sudo apt-get update

sudo apt-get install -y ros-galactic-rqt-tf-tree

 

Once it is installed, you can run it with the command below:

ros2 run rqt_tf_tree rqt_tf_tree

 

A Graphical Window should pop up. If not, you click the fifth icon on the bottom left menu to have it. As you can see below, we have two TF Trees, one for each robot:

 

2 two TF Trees on The Construct - Multi-Robot navigation

2 two TF Trees on The Construct – Multi-Robot navigation

 

How the simulation and the multi-robot navigation were prepared

To better understand the code, let’s open the Code Editor by clicking on the second link:

Open the IDE - Code Editor

Open the IDE – Code Editor

 

You will see that inside the ros2_ws/src folder we have a package named barista_ros2. You can also navigate to that folder using the terminal if you want:

 

cd /home/user/ros2_ws/src

ls

You will find the following folders inside the barista_ros2 package.

barista_description barista_extra_models barista_gazebo blender_files

 

Inside the barista_gazebo package, we have the main_two_robots.launch.xml file used to spawn the two robots. We can check its content using the Code Editor, or using the terminal with the following command:

cat /home/user/ros2_ws/src/barista_ros2/barista_gazebo/launch/main_two_robots.launch.xml

which shows us its content:

<?xml version='1.0' ?>
<launch>
  <arg name="number_of_robots" default="2"/>

  <!-- Launches World now independently form spawning robot -->
  <include file="$(find-pkg-share barista_gazebo)/launch/start_world_standalone.launch.py"/>

  <!-- launches the basic turtlebot3 world with multiple basic baristas -->
  <include file="$(find-pkg-share barista_gazebo)/launch/barista_1.launch.py"/>
  <include file="$(find-pkg-share barista_gazebo)/launch/barista_2.launch.py"/>

</launch>

 

When we analyze its content we see that we first launch the world using the start_world_standalone.launch.py file, then we launch the two baristas.

You can also check the content of barista_1_launch.py with:

cat ~/ros2_ws/src/barista_ros2/barista_gazebo/launch/barista_1.launch.py

 

In that file we have a function named get_robot_info:

def gen_robot_info():

    pose_2 = [1.0, -4.0]

    robot_name = "barista_2"
    x_pos = pose_2[0]
    y_pos = pose_2[1]
    robot = {'name': robot_name, 'x_pose': x_pos,
                    'y_pose': y_pos, 'z_pose': 0.1, 'Y_pose': 0.0}

    return robot

 

That function essentially returns the robot_name, used as the namespace for the robot, and also returns its initial position.

In that barista_1.launch.py we can see that it also includes spawn.launch.py (available at ~/ros2_ws/src/barista_ros2/barista_description/launch/spawn.launch.py)

One of the important functions of spawn.launch.py is the launch_setup function, especially the definition of robot_state_publisher_node and joint_state_publisher_node, where we specify the frame_prefix and the robot_description.

Please, look carefully at that file to better understand it.

Youtube video

So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.

Keep pushing your ROS Learning.

Related Courses & Training

If you want to learn more about ROS and ROS2, we recommend the following courses:

How to use webots with ROS2 – ROS2 Q&A # 235

How to use webots with ROS2 – ROS2 Q&A # 235

What we are going to learn

  1. How to use Webots with ROS2

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/5020588f/
  2. Webots Simulator: https://github.com/cyberbotics/webots
  3. Webots documentation: https://cyberbotics.com/doc/guide/index
  4. The Construct: https://app.theconstructsim.com/
  5. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days (Python): https://app.theconstructsim.com/#/Course/73
    2. ROS2 Basics in 5 Days (C++): https://app.theconstructsim.com/#/Course/61
    3. ROS2 Navigation training: https://www.theconstruct.ai/ros2-navigation-training/

Overview

In this post, we will learn how to use a simulator other than Gazebo in ROS. We are going to use the Webots Simulator, whose code is available at https://github.com/cyberbotics/webots

ROS Inside!

ROS inside

ROS inside

Before anything else, in case you want to use the logo above on your own robot, feel free to download it for free and attach it to your robot. It is really free. Find it in the link below:

ROS Inside logo

Opening the rosject

In order to work with Webots with ROS 2, we need to have ROS2 installed in our system, and ideally a ros2_ws (ROS2 Workspace). To make your life easier, we already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/5020588f/.

You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).

Learn ROS2 Parameters - Run rosject

Learn ROS2 Topics vs Service vs Action – Run rosject (example of the RUN button)

After pressing the Run button, you should have the rosject loaded. Let’s now head to the next section to really get some real practice.

Opening the Code Editor

Let’s start by opening the Code Editor by clicking on the second link:

Open the IDE - Code Editor

Open the IDE – Code Editor

 

Once the Code Editor is open, you should be able to see that we have the webots folder in the root.

That folder contains the Webots version R2022b compiled from source.

If you are really new to Webots, you can follow the complete guide available at https://cyberbotics.com/doc/guide/index.

 

Starting Webots Simulator

In order to start Webots using the command line, let’s start by opening a terminal:

Open a new Terminal

Open a new Terminal

 

Now, to open Webots we only need the two following commands:

cd ~/webots

./webots

 

After a few seconds, you should have a pop-up with a Webots ROS2 Simulation (by default it shows the last simulation we used). If the pop-up doesn’t open, you can have it by clicking on the 4th Icon of the bottom bar.

Webots ROS2 Simulation

Webots ROS2 Simulation

 

Ok, now that you know how to open Webots manually, feel free to close the simulator by pressing CTRL+C on the command line, or manually pressing the Close Webots button available on the top right corner of the simulator.

Launching a Webots world

As you may have noticed, we have a workspace named ros2_ws. That workspace contains ROS2 packages ready for Webots.

Let’s launch a simulation using the following command:

ros2 launch webots_ros2_epuck robot_launch.py

 

That command will basically load the world that we saw in the previous picture.

You can now go to a second terminal and check the topics with:

ros2 topic list

 

If you want to move a robot, you would need external controllers, but that is a topic for another post.

In any case, you can always refer to the official documentation. For External Controllers, the documentation is available at https://cyberbotics.com/doc/guide/running-extern-robot-controllers?tab-os=linux

Another simulation you could launch with Webots is Turtlebot:

ros2 launch webots_ros2_turtlebot robot_launch.py

It may take a while to load because Webots downloads the assets in the background. But after a while, you should have the Turtlebot simulation up and running:

 

Turtlebot robot on Webots Simulator

 

You can list the ros2 topics just as you did for the previous simulation:

ros2 topic list

 

You can even load a Tesla simulation with Webots, in which you have a Tesla in a city:

ros2 launch webots_ros2_turtlebot robot_launch.py
Testa Simulation in Webots

Testa Simulation in Webots

 

Webots guided tour

You can also follow the Webots Guided Tour by clicking Help -> Webots Guided Tour, although most of the tours right now are still for ROS (ROS1).

Congratulations. You have just learned the basics of how to start a Webots simulation using ROS2. We hope this post was really helpful to you. If you want a live version of this post, please check the video in the next section.

Youtube video

So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.

Keep pushing your ROS Learning.

Related Courses & Training

If you want to learn more about ROS and ROS2, we recommend the following courses:

How to create a ros2 C++ Library

How to create a ros2 C++ Library

In this post, you will learn how to create and use your own ros2 C++ library. I’ll show you how to create the library and then use it in a demo package.

Step 1: Fire up a system with ROS2 installation

“Hey, do you mean I have to install ros2 first?” Absolutely not! Just log in to The Construct to get access to virtual machines pre-installed with ROS.

Once logged in, click on My Rosjects, then Create a New Rosject, supply the information as shown in the video and click Create. Then RUN the rosject.

Create a new Rosject

You might also want to try this on a local PC if you have ros2 installed. However, please note that we cannot support local PCs and you will have to fix any errors you run into on your own. The rest of the instruction assumes that you are working on The Construct; please adapt them to your local PC and ros2 installation.

Step 2: Create a new package that contains the library’s source code (logic)

Open Code Editor
Open a web shell

Open a web shell and run the following commands to create the package.

cd ros2_ws/src
source /opt/ros/humble/setup.bash/
ros2 pkg create my_value_converter_library --build-type ament_cmake --license BSD-3-Clause

Now that your package is created, we need to create a header file for the library. Move inside the include/my_value_converter_library directory and create a header file named library_header.h.  

cd ~/ros2_ws/src/my_value_converter_library/include/my_value_converter_library
touch library_header.h

Now head over to the Code Editor to make changes to the header file. Check the image below for how to open the Code Editor.

Open the Code Editor

Locate the header file in the code editor: ros2_ws > src > my_value_converter_library > include > my_value_converter_library > library_header.h and paste in the following code.

#ifndef MAP_VALUE_H
#define MAP_VALUE_H

double map_value(double x, double in_min, double in_max, double out_min, double out_max);

#endif

Next, we create the C++ source code file for the library. In the same web shell:

cd ~/ros2_ws/src/my_value_converter_library/src
touch my_value_converter_library.cpp

Locate the my_value_converter_library.cpp file in the code editor and paste in the following code:

#include "my_value_converter_library/library_header.h"

double map_value(double x, double in_min, double in_max, double out_min, double out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Now we need to edit the CMakeLists.txt file of our package to recognize the source code we have just added. Open the file ros2_ws > src > my_value_converter_library > CMakeLists.txt and add the following lines before the ament_package() call.

# let the compiler search for headers in the include folder
include_directories(include)

# define a library target called my_value_converter_library
add_library(my_value_converter_library src/my_value_converter_library.cpp) 

# this line to exports the library
ament_export_targets(my_value_converter_library HAS_LIBRARY_TARGET)

# install the include/my_cpp_library directory to the install/include/my_cpp_library
install(
  DIRECTORY include/my_value_converter_library
  DESTINATION include
)

install(
  TARGETS my_value_converter_library
  EXPORT my_value_converter_library
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

So much for all the hard work – now is the time to see if it works. Time to compile the code. In the same web shell, run the following commands:

cd ~/ros2_ws
colcon build

Success! We have now created our library. Next, we are going to use it!

PS: if your code did not compile correctly, please go over the instructions and ensure you have created the files in the exact locations specified.

Step 3: Create a new package that uses the library you just created

Create the new package in the open shell. Note that my_value_converter_library is passed as a dependency during the creation of the new package. This will simplify some of the work that needs to be done when modifying the CMakeLists.txt file.

cd ros2_ws/src
ros2 pkg create my_value_converter_node --build-type ament_cmake --license BSD-3-Clause --dependencies rclcpp std_msgs my_value_converter_library

Now verify that the dependencies have been properly added. If the build runs successfully, it is so. If not, please correct the errors before you proceed.

cd ~/ros2_ws
colcon build

If you got to this point, great! Now we will create the C++ source code that will use your library.

cd ~/ros2_ws/src/my_value_converter_node/src
touch my_value_converter_node.cpp

Now locate the my_value_converter_node.cpp file in the code editor and paste in the following source code.

#include <memory>
#include <string>

#include "my_value_converter_library/library_header.h"
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/float32.hpp"

class ConverterNode : public rclcpp::Node {
public:
  explicit ConverterNode() : Node("converter_node") {

    auto callback =
        [this](const std_msgs::msg::Float32::SharedPtr input_msg) -> void {
      RCLCPP_DEBUG(this->get_logger(), "I heard: [%f]", input_msg->data);

      // Use the library
      // Map an value from 0 - 1023 range to -1.0 to +1.0 range
      double new_value = map_value(input_msg->data, 0, 1023, -1.0, 1.0);

      output_msg_ = std::make_unique<std_msgs::msg::Float32>();
      output_msg_->data = new_value;
      RCLCPP_DEBUG(this->get_logger(), "Publishing: '%f'", output_msg_->data);
      pub_->publish(std::move(output_msg_));
    };

    sub_ = create_subscription<std_msgs::msg::Float32>("output_topic", 10,
                                                       callback);
    // Create a publisher
    rclcpp::QoS qos(rclcpp::KeepLast(7));
    pub_ = this->create_publisher<std_msgs::msg::Float32>("input_topic", qos);
  }

private:
  std::unique_ptr<std_msgs::msg::Float32> output_msg_;
  rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtr pub_;
  rclcpp::Subscription<std_msgs::msg::Float32>::SharedPtr sub_;
};

int main(int argc, char *argv[]) {
  rclcpp::init(argc, argv);
  auto node = std::make_shared<ConverterNode>();
  RCLCPP_INFO(node->get_logger(), "My value converter node started.");
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

As you might have expected, we need to modify the CMakeLists.txt file for our new package. Locate the ros2_ws > src > my_value_converter_node > CMakeLists.txt in the code editor and paste in the following code before the ament_package() call.

# define the binary to be built and identify the source files with with which to build it
add_executable(main src/my_value_converter_node.cpp)
# tell CMake that the executable "main" depends on the library "my_value_converter_library"
ament_target_dependencies(main my_value_converter_library rclcpp std_msgs)
# install the executable in the lib folder to make it detectable through setup.bash
install(TARGETS 
  main
  DESTINATION lib/${PROJECT_NAME}/
)

Now build and use your package!

cd ~/ros2_ws
colcon build
source install/setup.bash

ros2 run my_value_converter_node main

Step 4: Check your learning

Do you understand how to create a ros2 C++ library? If you don’t know it yet, please go over the post again, more carefully this time.

(Extra) Step 5: Watch the video to understand how to install a ros2 binary package

Here you go:

Feedback

Did you like this post? Do you have any questions about how to create a ros2 C++ library? Please leave a comment in the comments section below, so we can interact and learn from each other.

If you want to learn about other ROS2 topics, please let us know in the comments area and we will do a video or post about it.

How to release a ROS 2 binary package [Part 2/3]

How to release a ROS 2 binary package [Part 2/3]

What we are going to learn

  • How to create a ros/rosdistro source entry so that your package can be released with ROS. Something like: sudo apt-get install ros-humble-my-package-name

 

List of resources used in this post

  1. Part 1 of this series: https://www.theconstruct.ai/how-to-release-a-ros-2-binary-package-part-1-2
  2. Use the rosject: https://app.theconstructsim.com/l/50995c4e/
  3. The Construct: https://app.theconstructsim.com/
  4. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days (Python): https://app.theconstructsim.com/#/Course/73
    2. ROS2 Basics in 5 Days (C++): https://app.theconstructsim.com/#/Course/61
    3. ROS2 Navigation training: https://www.theconstruct.ai/ros2-navigation-training/

Overview

ROS2, the improved version of ROS (ROS1), is quickly becoming the standard for developing robotics applications.

In this post, we will learn the second part on how to release a ROS2 package as a binary file. Binary files are pre-built executables. They are easier to install because they do not require building from the source code. Binary files are perfect if you want to easily distribute a package to other people.

You can easily install them with apt-get install PKG_NAME, or sudo dpkg -i pkg-name.deb, for example.

It is highly recommended that you follow that Part 1, since it is a requirement for following this post:

Also, the third part of this series can be found in the link below:

ROS Inside!

ROS Inside

ROS Inside

Before anything else, in case you want to use the logo above on your own robot or laptop, feel free to download it for free and attach it to your robot. It is really free. Find it in the link below:

ROS Inside logo

Acknowledgment

This post is based on ROS2’s official documentation, check it out here:

https://docs.ros.org/en/humble/How-To-Guides/Releasing/Releasing-a-Package.html

Opening the rosject

In order to release a ROS 2 binary package, we need to have ROS2 installed in our system, and it is also useful to have some simulations. To make your life easier, we already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/50995c4e/.

You can download the rosject on your own computer if you want to work locally, but just by copying the rosject (clicking the link), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject (below you have a rosject example).

Learn ROS2 Parameters - Run rosject

How to release a ROS 2 binary package – Run rosject (example of the RUN button)

After pressing the Run button, you should have the rosject loaded. Let’s now head to the next section to really get some real practice.

Assumptions

  • Existing ROS2 Package, publicly available for everyone to use
  • Git and GitHub basics
  • You have completed the first part aforementioned:
    • Created a release repository
    • Started a new release team (pull request is pending)
    • Installed the tools required on our machine
    • Created a GIT access token to authenticate

Open a terminal

You will need to clone a repository soon, so, in order to do that, you will need a terminal. If you are new to the platform, you can easily open a terminal by clicking on the first button on the bottom left.

 

Open a new Terminal

Open a new Terminal

 

Create a ros/rosdistro source entry

What is ros/rosdistro? https://github.com/ros/rosdistro is a GitHub repository that maintains information describing ROS packages and repositories. The build process accesses this information to build packages.

The rosdistro repository also stores the rules used by rosdep to install external dependencies.

To see all ROS Packages included in ROS Humble, for example, you can have a look at this file: https://github.com/ros/rosdistro/blob/master/humble/distribution.yaml

Validation process

When you create a ros/rosdistro source entry for a package that you release for the very first time, your repository will be reviewed to check whether it conforms to some basic rules.
Here is an example of some of the validations performed:

 

To add create a ros/rosdistro source entry one can manually open a pull request to the corresponding GitHub repository:

Steps:

  1. Fork the https://github.com/ros/rosdistro repository on GitHub by clicking https://github.com/ros/rosdistro/fork.
  2. Clone the repo fork, so you can edit the contents locally. Something like:
    cd ~/ros2_ws/src
    
    git clone https://github.com/YOUR-USERNAME/rosdistro
    
    cd rosdistro

     

    Add your repository to the repository listing:

    • Open the appropriate directory for the distribution that you would like to add a listing to through the IDE.
    • Inside this directory, edit the distribution.yaml file.
    • Add your repository information with a doc section as shown below.Considerations:
      • You should maintain the alphabetic order of the repositories
      • The repository URL should point to the upstream repository, not the release repository.

Example distro file: humble/distribution.yaml

 

wall_follower_ros2: 
  source:
    type: git 
    url: https://github.com/rfzeg/wall_follower_ros2.git 
    version: master 
  status: maintained

 

Now, go back to the rosdistro root directory and run the following command:

 

rosdistro_reformat file://"$(pwd)"/index.yaml

 

This will make the files comply with rosdistro’s special formatting rules.

 

Check the differences made by the script you just ran:

 

git diff distribution.yaml

 

which should show something like this:

 

git diff

git diff

 

If everything looks good, you are ready to commit your changes:


git commit -m "Add wall_follower_ros2 repo"

 

Push your changes to your remote GitHub repository:


git push origin master

 

Create and Submit a pull request on GitHub to the rosdistro project to add your source entry to the indexer.

To create a new request, go to your repository and click the Contribute -> Open pull request button:

 

Open a Pull Request for rosdistro

Open a Pull Request for rosdistro

 

After that, git a title to the Pull Request. Title example:

Add wall_follower_ros2 repo to humble

Then the body of the Pull Request goes like this:

Adding new repository: https://github.com/rfzeg/wall_follower_ros2.git to humble 
as requested in https://github.com/ros2-gbp/ros2-gbp-github-org/issues/99 
for the purpose of releasing the package wall_follower_ros2

# Checks
[x] All packages have a declared license in the package.xml
[x] This repository a LICENSE file
[x] This package is expected to build on the submitted rosdistro

 

Remember that after submitting your pull request, some changes may be requested, and since the reviews are done asynchronously, it can sometimes take a few days until the review is completed.

Now, if they ask you to modify anything, you just go ahead and do the modifications.

You may now want to go ahead and check how to build a Debian file locally:

Congratulations. We have finished the second part about the release of a ROS2 Binary package. We hope this post was really helpful to you. We soon may have an extra part related to this subject.

Please bear in mind that the third part of this series can be found in the link below:

Youtube video

So this is the post for today. Remember that we have the live version of this post on YouTube. If you liked the content, please consider subscribing to our youtube channel. We are publishing new content ~every day.

Keep pushing your ROS Learning.

Related Courses & Training

If you want to learn more about ROS and ROS2, we recommend the following courses:

Pin It on Pinterest