How to easily contribute to ROS2 documentation

How to easily contribute to ROS2 documentation

What we are going to learn

  1. How to find issues to work on
  2. How to clone tutorial packages into a rosject
  3. How to create pull requests

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/56492ac1/
  2. The Construct: https://app.theconstructsim.com/
  3. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days Humble (Python): https://app.theconstructsim.com/Course/132
    2. ROS2 Basics in 5 Days Humble (C++): https://app.theconstructsim.com/Course/133
  4. https://navigation.ros.org/plugin_tutorials/docs/writing_new_nav2planner_plugin.html

Overview

ROS2 is an open-source software framework for robotics that provides libraries and tools to help developers create robot applications.

Documentation is an essential part of any software project, and ROS2 welcomes contributions from anyone who wants to improve it.

In this video, we will show you how to find issues to work on, clone tutorial packages into a rosject, and create pull requests. By the end of this video, you will be able to make your first contribution to ROS2 documentation and become part of the ROS2 community.

ROS Inside!

ROS Inside

ROS Inside

Before anything else, if you want to use the logo above on your own robot or computer, feel free to download it 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 have already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/56492ac1/.

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 – Part 3 – 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.

 

Starting the simulation

After having opened the rosject, let’s start a simulation following the ROS Nav2 documentation to move the robot around. For that, let’s open a terminal by clicking the Open a new terminal button.

Open a new Terminal

Open a new Terminal

 

Let’s run the following commands in the first terminal in order to launch the simulation:

source ~/ros2_ws/install/setup.bash

export GAZEBO_MODEL_PATH=/home/user/ros2_ws/src/neobotix_ros2/neo_simulation2/models:/home/user/ros2_ws/src:/home/user/ros2_ws/src/neobotix_ros2

ros2 launch neo_simulation2 simulation_basics.launch.py

 

Now, in a second terminal, let’s launch the Localization Server using the following command:

ros2 launch localization_server localization.launch.py

 

Then, in a third terminal, let’s launch the Path Planner using the following command:

ros2 launch path_planner_server pathplanner.launch.py

 

If everything went ok, you should have something like we have in the image below, where we have a simulation (on the left side), and the RViz (Robot Visualization) window (on the right side)

Neo robot simulation - setting a pose goal on Nav2

Neo robot simulation – setting a pose goal on Nav2

 

If we just try to set a 2D Pose Goal for the robot to move around, by clicking on 2D Pose Goal on RViz, and then set the goal as we can see in the blue arrow in the image above, the robot should move without any problems (because the rosject is fixed).

Reproducing a problem found in the nav2 documentation

In order to move a robot around in ROS 2, we use the Nav2 package. There is a nav2 documentation in the following link, that we are interested in, for the purpose of this video:

https://navigation.ros.org/plugin_tutorials/docs/writing_new_nav2planner_plugin.html

At the end of the page on the link aforementioned, you will find a code that contains the “planner_server” term.

When this post was created, the code was indented more or less like what we see below (planner_server and ros__parameters have the same indentation):

How to easily contribute to ROS2 documentation - Indentation

How to easily contribute to ROS2 documentation – Indentation

 

The instructions in the linked aforementioned say that we could paste that content in the nav2_params.yaml file.  .

If you want to find that file on the rosject, you first have to open the Code Editor:

Open the IDE - Code Editor

Open the IDE – Code Editor


The nav2 tutorial mentions nav2_params.yaml, but in the specific rosject shared at the beginning of this post, the file used is planner_server.yaml

Once the Code Editor is open, you can find the nav2_params.yaml file at the following path: ~/ros2_ws/src/neobotix_ros2/path_planner_server/config/planner_server.yaml.

nav2_params.yaml - How to easily contribute to ROS2 documentation

nav2_params.yaml – How to easily contribute to ROS2 documentation

 

You don’t have to, but if you replace the first 10 lines of planner_server.yaml with the non-indented code that was provided on the nav2 tutorial when this post was created, you would replace the first 10 lines with the following content:

planner_server:
ros__parameters:
  plugins: ["GridBased"]
  use_sim_time: True
  GridBased:
    plugin: "nav2_straightline_planner/StraightLine"
    interpolation_resolution: 0.1

 

If you had pasted the content above (as I said earlier, you don’t have to), you would have to kill the programs launched in the 3 terminals by pressing CTRL+C,

After that, you would have to recompile the ros2_ws using the following commands on the first terminal:

 

cd ~/ros2_ws

colcon build

 

After that, you could try to launch the simulation just like we did earlier:

In the first terminal, the simulation would be launched:

source ~/ros2_ws/install/setup.bash

export GAZEBO_MODEL_PATH=/home/user/ros2_ws/src/neobotix_ros2/neo_simulation2/models:/home/user/ros2_ws/src:/home/user/ros2_ws/src/neobotix_ros2

ros2 launch neo_simulation2 simulation_basics.launch.py

 

In the second terminal, the Localization Server would be launched:

ros2 launch localization_server localization.launch.py

 

Then, in a third terminal, the Path Planner would be launched:

ros2 launch path_planner_server pathplanner.launch.py

 

But, when launching the Path Planner, you would have the following error:

[planner_server-3] [ERROR] [1678443929.379055702] [rcl]: Failed to parse global arguments
[planner_server-3] terminate called after throwing an instance of 'rclcpp::exceptions::RCLInvalidROSArgsError
[planner_server-3]   what():  failed to initialize rcl: Couldn't parse params file: 
'--params-file /home/user/ros2_ws/install/path_planner_server/share/path_planner_server/config/planner_server.yaml'. 
Error: Cannot have a value before ros__parameters at line 12, 
at /tmp/binarydeb/ros-galactic-rcl-yaml-param-parser-3.1.3/src/parse.c:793,
at /tmp/binarydeb/ros-galactic-rcl-3.1.3/src/rcl/arguments.c:406

 

The error message shows that there is a problem when trying to parse the file. The problem is mainly an indentation problem.

Now, since the problem was found in the nav2 tutorial itself, how to contribute to this fix get resolved?

Contributing to the documentation – Creating a Pull Request

At the top of the https://navigation.ros.org/plugin_tutorials/docs/writing_new_nav2planner_plugin.html page, we have an Edit button.

Edit documentation - How to easily contribute to ROS2 documentation

Edit documentation – How to easily contribute to ROS2 documentation

 

By  clicking on that button, we will be sent to the ROS Navigation repository available at https://github.com/ros-planning/navigation.ros.org

The correct path for the file that generates the Nav2 Planner Plugin is https://github.com/ros-planning/navigation.ros.org/blob/master/plugin_tutorials/docs/writing_new_nav2planner_plugin.rst

By opening this last link, you will see at the top right corner a button that allows you to edit that file. You just have to click that link.

You can then make your changes, and create a commit. After that, you can just create a Pull Request:

Pull Request - fix nav2 documentation

Pull Request – fix nav2 documentation

 

And that is it.

The repository maintainers will review your changes, and if everything is ok, they will approve it. If not ok, they will suggest some changes. If they suggest changes, you just make the changes as requested.

Congratulations. You just learned how to contribute to the ROS Documentation.

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:

Get ROS2 Industrial Ready- Hands-On Training by The Construct cover.png

Get ROS2 Industrial Ready- Hands-On Training by The Construct cover.png

How to release a ROS 2 binary package – Part 3

How to release a ROS 2 binary package – Part 3

What we are going to learn

  1. How to generate a changelog file
  2. How to bump the package version
  3. How to run a first-time release using bloom

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/5562c7f1/
  2. The Construct: https://app.theconstructsim.com/
  3. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days Humble (Python): https://app.theconstructsim.com/Course/132
    2. ROS2 Basics in 5 Days Humble (C++): https://app.theconstructsim.com/Course/133

Overview

This is the third part of a video that shows how to release a ROS2 package to the ROS build farm using bloom. Be sure to check the first and second parts if you haven’t yet:

Here we will explain how to generate a changelog file, bump the package version, and run a first-time release using bloom.

Acknowledgment

This video is based-off on ROS2’s official documentation, check it out at the link below:

ROS Inside!

ROS Inside

ROS Inside

Before anything else, if you want to use the logo above on your own robot or computer, feel free to download it 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 have already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/5562c7f1/.

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 – Part 3 – 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.

 

What is bloom?

Bloom is a build automation tool that will guide you through all necessary steps in the process of compiling the source code in the ROS build farms, packaging the code into binaries, and uploading them to the Debian archive. This way any users can easily install and uninstall it using the Debian package tools.

What is a build farm?

A build farm is a collection of one or more servers, which has been set up to compile computer programs remotely.

Assumptions

In order to follow this tutorial, we assume you have:

 

Recap from part 1: Install the tools required on your machine

After having opened the rosject, let’s start running some commands in the terminal. For that, let’s open a terminal by clicking the Open a new terminal button.

Open a new Terminal

Open a new Terminal

Once inside the terminal, let’s run the commands below, use apt to install bloom together with the python3-catkin-pkg modules if you haven’t done so already.

sudo apt update
sudo apt install python3-bloom python3-catkin-pkg

New addition step: Since we are using a version of bloom older than 0.6.8 we need to use the v4 index URL for releasing:

export ROSDISTRO_INDEX_URL='https://raw.githubusercontent.com/ros/rosdistro/master/index-v4.yaml'

Recap from part 2: Incorporate feedback

If you followed the second part of this video, you created a pull request to add a ros/rosdistro source entry. Remember that you have to make the changes requested by the reviewer to get your pull request merged. This part assumes that your pull request has been successfully merged to the ros/rosdistro repository.

Important: The issues created in part 1 and part 2 must be shown as completed.

 

Verify your repository is up to date and your code builds

This might seem like an obvious one, but it’s easy to overlook. Ensure you have committed your changes and pushed the last commit to your remote.

Additionally, confirm your new code builds and executes right before making it available to the build farm.

cd ~/ros2_ws/src

git clone https://github.com/rfzeg/wall_follower_ros2
cd ~/ros2_ws

colcon build; source install/setup.bash

IMPORTANT!!!

Here we cloned the https://github.com/rfzeg/wall_follower_ros2 package. You cannot release the same package from the same URL because it has been already released by ROS, which means some parts of this tutorial may not work 100% if you close the same repository.

To make sure it works, you have to close your own repository instead of the one above. Please use the same repository you used in the previous posts of this series, for example.

Starting the simulation

After having opened the rosject and making sure the workspace builds with no problems, let’s start a simulation using the same terminal that you have already opened previously.

Let’s run the following commands in order to launch the simulation:

source ~/ros2_ws/install/setup.bash

source /usr/share/gazebo-11/setup.bash

ros2 launch wall_follower_ros2_tests miniworld.launch.py

 

Now, in a second terminal, let’s make sure our wall follower is working properly:

ros2 run wall_follower_ros2 wall_follower_ros2 --ros-args -r scan:=/lidar_1/out

 

If everything went well, you should see the robot moving around, and when it gets close to the wall, it turns and keep moving:

Wall follower using ROS 2

Wall follower using ROS 2

It is always a good idea to verify if there are new changes since the last commit. Let’s try that in the same second terminal. For that, first press CTRL+C to kill the current process, and then run the commands below:

cd ~/ros2_ws/src/wall_follower_ros2
git status

 

When you have added all of the changes to a commit, the Git status command line will inform you ‘nothing to commit, working tree clean‘ :

On branch master 
Your branch is up to date with 'origin/master'. 

nothing to commit, working tree clean

 

Generating the Changelog

We are now going to generate a Changelog. A changelog is a file that contains a condensed list of all important changes made to a project in a chronologically ordered way. Its purpose is to communicate to other developers what features have been added, improved, or removed over time.

To auto-generate the CHANGELOG.rst files, use the "catkin_generate_changelog --all" command.

Make sure to run this command from inside the home directory where the package files are located:

cd ~/ros2_ws/src/wall_follower_ros2
catkin_generate_changelog --all

 

If everything went well, we expect to have the following output:

Found packages: wall_follower_ros2
Querying all tags and commit information...
Generating changelog files with all versions...
- creating './CHANGELOG.rst'
Done.
Please review the extracted commit messages and consolidate the changelog entries before committing the files!

 

A new CHANGELOG.rst file will be automatically created for every package within the repository. The above command will also populate the file with the contents of your commit messages.

The above command will generate a CHANGELOG.rst file. If we open that file using the Code Editor, or by typing “cat CHANGELOG.rst“, we should see something similar to the following, for instance:

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package wall_follower_ros2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Forthcoming
-----------
* Merge pull request `#1 <https://github.com/rfzeg/wall_follower_ros2/issues/1>`_ from rfzeg/master
  Master to main
* Feat: stop robot when a CTRL+C signal is received
* Fix safety_distance parameter value
* Add parameter to reverse ranges array in case it starts with rays at the left side
* Refactor: rename, reformat and rearrange code
* Add Timer Callback to set movement state, fill vel msg, publish vel msg
* Refactor laser_callback to get the distance reading to the closest object and the ray's position index
* Rename set_drive_state() -> set_drive_logic_state(), RCLCPP_INFO() -> RCLCPP_DEBUG() logs
* Rename set_velocity() -> determine_vel_msg(), rewrite debug logs
* Rename package to 'wall_follower_ros2'. Set version to 0.0.0 in package.xml
* Add info & debug log messages
* Add logical behavoir depending upon 5 zones around the robot, set velocity command
* Add log info & debug statements
* Refactor parameter value retrieval
* Add safety distance parameter
* Add default parameter values
* Add minimal rule based obstacle avoidance node (c++)
* Add initial ROS2 package files, Readme, License & Git configuration
* Contributors: Roberto Zegers, Roberto Zegers R

 

Note: The changelog is basically a list of commits. I you want to compare it with your log messages, have a look at the Git log history using git log –oneline:

git log --oneline

 

So, the changelog is basically a list of commits, but you can definitely remove some of the commits in the changelog if you want, however, you must not remove the  Forthcoming header.

AGAIN!!! Make sure you do not modify the Forthcoming header.

 

In this example I reduced the list of changes to only include the most important things as shown below:

Forthcoming
-----------

* Add initial version with logical behavoir depending upon 5 zones around the robot
* Contributors: Roberto Zegers

 

If you are interested you can consult the following page for additional information: Incorporation of Changelogs into Package Source Tree

Commit

If you have modified the changelog, then you must commit CHANGELOG.rst changes giving it an appropriate commit message such as “Add Changelog”.

git add CHANGELOG.rst
git commit -m "Add Changelog"

 

Bump the package version

Before releasing the package you will also have to increment its version number to a new, unique value because by default its initial version will be “0.0.0″, which is the value defined in the package.xml file of our package.
To confirm that number, you can run the command below:
cat ~/ros2_ws/src/wall_follower_ros2/package.xml | grep version

 

which will output something like this:
 <version>0.0.0</version>

 

Now, in order to automatically bump the package version, we can use the following command, but be aware that the command will ask you for your github credentials. That is why we mentioned previously that you would have to clone your own repository instead of the one we are using in this example (https://github.com/rfzeg/wall_follower_ros2):

cd ~/ros2_ws/src/wall_follower_ros2 

catkin_prepare_release

 

According to the ROS2’s documentation, this command performs the following:

  1. Increases the package version in package.xml. The above command will increment the patch version of the package from its default value of 0.0.0 to 0.0.1.
  2. Replaces the heading Forthcoming with version (date) (eg. 0.0.1 (2022-01-08)) in CHANGELOG.rst
  3. Commits those changes
  4. Creates a Git tag (eg. 0.0.1) to mark this point in the Git history
  5. Pushes the changes and the tag to your remote repository

You can show the changes made to the repository like this:

git diff HEAD^ HEAD

 

If you want to verify the tag that Git just added, run the command below, which will list the available tags in your Git repository:

git tag

 

Sidenote on semantic versioning

A semantic version number has three parts delimited by a dot, for instance:

1.2.5

Where 1 stands for a Major version, 2 represents the Minor version and 5 is the Patch. Let’s understand these labels:

Patch: Patch updates are interchangeable, meaning consumers can upgrade or downgrade freely. Example: Bug fix, performance improvement, or internal tweaks.

Minor: Minor updates are backward compatible, meaning consumers can upgrade freely. For instance new additional API methods, without changing the current methods.

Major: Major updates are non-compatible, meaning consumers can not upgrade without changing the software that uses the API, where applicable. You normally have interface changes breaking backward compatibility, like changes in an API endpoint name or signature, removal of an endpoint, etc.

To increment the major version, for instance in the first major release, run:

catkin_prepare_release --bump major

 

Similarly, the minor version gets incremented when you execute:

catkin_prepare_release --bump minor

 

Run the bloom-release command

Run the following command, the <my_repository> should be replaced with the name of your repository:

bloom-release –new-track –rosdistro humble –track humble <my_repository>

Note that <my_repository> is not an URL, but the repository reference in distribution.yaml.

In this particular example, the command to be executed is:

bloom-release --new-track --rosdistro humble --track humble wall_follower_ros2

 

The above command will create a release for ROS2 Humble. Let’s have a quick breakdown of the flags we used:

  • –new-track is important for a first-time release to create a new track before running bloom. What is a track? Bloom is designed to allow the release of the same package for different ROS distributions and versions in the same release repository. To facilitate this, bloom uses release “tracks” to maintain configurations for different release processes.
  • –rosdistro humble indicates that this release is for the humble distro. Replace as appropriate.
  • –track humble indicates that you want the track name to be humble

 

Note: For later releases, you don’t need the --new-track flag. However, if you want to add a new distribution to an already released package (see documentation) and configure it, you will have to include the --new-track option again.

Once executed, it will look at the distributions.yaml file for your project key. If it doesn’t find it, it’ll look in other distributions. If it finds one, it’ll prompt you to approve it. If not, you will be asked to enter a release repository URL:

Looking for a release of this repository in a different distribution

Looking for a release of this repository in a different distribution

In this particular example, we have to add the following. Note that you should replace this with the name of your repository.

AGAIN!!! Note that you should replace this with the name of your repository.

Our ros2-gbp release repository is at:

https://github.com/ros2-gbp/wall_follower_ros2-release.git

 

What follows are prompts that are meant to configure the new release track.

Configure the new release track

You will be asked to enter some basic information required to configure a new track. In the example shown we should respond to the prompts as follows:

  1. Repository Name: the name of the repository in which the package is: wall_follower_ros2
  2. Upstream Repository URI: Our repository is hosted on GitHub at https://github.com/rfzeg/wall_follower_ros2, but please remember to insert the URL of your own repository
  3. Upstream VCS Type: [Enter]
  4. Version: [Enter]
  5. Release Tag: [Enter]
  6. Upstream Devel Branch: master
  7. ROS Distro: [Enter]
  8. Patches Directory: [Enter]
  9. Release Repository Push URL: [Enter]

The whole process will take a while because it runs quite a few commands, for instance:

==>  git-bloom-release humble

 

==>  bloom-export-upstream

 

==>  git-bloom-import-upstream

 

==>  git-bloom-generate -y rosrelease humble --source upstream -i 1

 

==>  git-bloom-generate -y rosdebian --prefix release/humble humble -i 1--os-name ubuntu

 

It will also check if all dependencies can be satisfied by running rosdep update:

Running rosdep update to release a ros2 binary package

Running rosdep update to release a ros2 binary package

 

You should continue to see lots of dumping messages/logs on the terminal:

==> git-bloom-generate -y rosdebian --prefix release/humble humble -i 1--os-name debian --os-not-required
==> git-bloom-generate -y rosrpm --prefix release/humble humble -i 1 --os-name fedora
==> git-bloom-generate -y rosrpm --prefix release/humble humble -i 1 --os-name rhel
<== Released 'wall_follower_ros2' using release track 'humble' successfully

 

Then you will be asked if you want to push to the release repository. Just type Y and [Enter] to pass this prompt:

Releasing complete, push to release repository?
Continue [Y/n]? Y

 

The script will continue its execution:

==> git push --tags

 

We don’t have documentation information, and that’s okay:

Would you like to add documentation information for this repository? [Y/n]? n

 

You might encounter a prompt message like this one:

Enter an access token prompt

Enter an access token prompt

 

Go to http://github.com/settings/tokens to create a token if you haven’t done it so far.

This token will be saved in the bloom config file in your local machine: ‘/home/user/.config/bloom

Then, finally, you will be asked to confirm the creation of a pull request:

Open a pull request prompt

Open a pull request prompt

 

A few more commands will be run:

==> Pulling latest rosdistro branch

 

==> Writing new distribution file: humble/distribution.yaml

 

==> git add humble/distribution.yaml

 

==> Pushing changes to fork

 

At the very end of the process, you should see a message similar to this:

<== Pull request opened at: https://github.com/ros/rosdistro/pull/xxxxx

In our case, the Pull Request URL was the following:

Note: The release process begins recording logs as soon as you run it. Bloom log files are saved in your local machine to this directory: '/home/user/.bloom_logs'

The pull request page

Click on that link and you will see the current status of your pull request:

ROS ROSDISTRO Pull Request on GitHub

ROS ROSDISTRO Pull Request on GitHub

 

Now you will have to wait for someone from the ROS release team to review/merge the pull request.
This can take some time, so you may have to wait a bit.

If required you will have to update the PR to address the comments. That is all for today’s post.


 

Congratulations. You just learned the third part of how to publish your ROS 2 binary package.

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:

Get ROS2 Industrial Ready- Hands-On Training by The Construct cover.png

Get ROS2 Industrial Ready- Hands-On Training by The Construct cover.png

How to use the Gazebo differential drive plugin in ROS 2

How to use the Gazebo differential drive plugin in ROS 2

In this post, you will learn how to use the Gazebo differential drive plugin in ros 2. This post answers the following question posted on ROS Answers.

Step 1: Copy a sample project with a ROS 2 Gazebo simulation using the differential drive plugin

“Hey, do I have to install ros2 first?” Absolutely not! We will be using The Construct to get access to virtual machines pre-installed with ROS.

Click here to copy the ROS2 TurtleBot3 sandbox project. Once copied, click the red RUN button to launch the project in a virtual machine. Please be patient while the environment loads.

PS: You will need to log in or create an account to copy the packages.


You might also want to try this on a local PC if you have ros2 and some executables 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 post assumes that you are working on The Construct; please adapt them to your local PC and ros2 installation.

Step 2: Find and explore the Gazebo model file containing the differential drive plugin

Now, we will find a Gazebo model file with the differential drive plugin. For this post, we’ll use the turtlebot3_ws/src/turtlebot3_simulations/turtlebot3_gazebo/models/turtlebot3_burger/model.sdf file. Sometimes it’s also defined as a .xacro file.

Head over to the Code Editor to explore this file as well as other files.

Open the Code Editor
Gazebo model file

Let’s examine the differential drive section of this plugin file and compare it with the one on the ROS Answers post.

turtlebot3_ws/src/turtlebot3_simulations/turtlebot3_gazebo/models/turtlebot3_burger/model.sdf

<plugin name="turtlebot3_diff_drive" filename="libgazebo_ros_diff_drive.so">

      <ros>
        <!-- <namespace>/tb3</namespace> -->
      </ros>

      <update_rate>30</update_rate>

      <!-- wheels -->
      <left_joint>wheel_left_joint</left_joint>
      <right_joint>wheel_right_joint</right_joint>

      <!-- kinematics -->
      <wheel_separation>0.160</wheel_separation>
      <wheel_diameter>0.066</wheel_diameter>

      <!-- limits -->
      <max_wheel_torque>20</max_wheel_torque>
      <max_wheel_acceleration>1.0</max_wheel_acceleration>

      <command_topic>cmd_vel</command_topic>

      <!-- output -->
      <publish_odom>true</publish_odom>
      <publish_odom_tf>true</publish_odom_tf>
      <publish_wheel_tf>false</publish_wheel_tf>

      <odometry_topic>odom</odometry_topic>
      <odometry_frame>odom</odometry_frame>
      <robot_base_frame>base_footprint</robot_base_frame>

    </plugin>

On lines 385 and 392, we see entries for the /cmd_vel (<command_topic>cmd_vel</command_topic>) and /odom (<odometry_topic>odom</odometry_topic>) topics respectively. However, these entries are missing in the file on ROS Answers.

Gazebo plugin file: mising command and odometry entries

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro"  name="robot">

   <gazebo>
        <plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
            <!-- Wheel info-->
            <left_joint>left_wheel_joint</left_joint>
            <right_joint>right_wheel_joint</right_joint>
            <wheel_separation>0.35</wheel_separation>
            <wheel_diameter>0.1</wheel_diameter>

            <!-- Limits-->
            <max_wheel_torque>200</max_wheel_torque>
            <max_wheel_acceleration>10.0</max_wheel_acceleration>

            <!-- Output-->
            <odometry_frame>odom</odometry_frame>
            <robot_base_frame>base_link</robot_base_frame>

            <publish_odom>true</publish_odom> 
            <publish_odom_tf>true</publish_odom_tf> 
            <publish_wheel_tf>true</publish_wheel_tf> 

        </plugin>
     </gazebo>

</robot>

Are these lines really necessary for moving the robot and getting its odometry? Let’s find out!

Step 3: Investigate the impacts of the of the command and odometry topic tags

Let’s comment out those tags in the file, and see if we can find the /cmd_vel and /odom topics, and if they work.

turtlebot3_ws/src/turtlebot3_simulations/turtlebot3_gazebo/models/turtlebot3_burger/model.sdf (modified)

<plugin name="turtlebot3_diff_drive" filename="libgazebo_ros_diff_drive.so">

      <ros>
        <!-- <namespace>/tb3</namespace> -->
      </ros>

      <update_rate>30</update_rate>

      <!-- wheels -->
      <left_joint>wheel_left_joint</left_joint>
      <right_joint>wheel_right_joint</right_joint>

      <!-- kinematics -->
      <wheel_separation>0.160</wheel_separation>
      <wheel_diameter>0.066</wheel_diameter>

      <!-- limits -->
      <max_wheel_torque>20</max_wheel_torque>
      <max_wheel_acceleration>1.0</max_wheel_acceleration>

      <!-- <command_topic>cmd_vel</command_topic> -->

      <!-- output -->
      <publish_odom>true</publish_odom>
      <publish_odom_tf>true</publish_odom_tf>
      <publish_wheel_tf>false</publish_wheel_tf>

      <!-- <odometry_topic>odom</odometry_topic> -->
      <odometry_frame>odom</odometry_frame>
      <robot_base_frame>base_footprint</robot_base_frame>

    </plugin>

Now let’s run the package…in Terminal 1

cd
source turtlebot3_ws/install/setup.bash
export TURTLEBOT3_MODEL=burger
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

…check the topics in Terminal 2

ros2 topic list

# output:
/clock
/cmd_vel
/imu
/joint_states
/odom
/parameter_events
/performance_metrics
/robot_description
/rosout
/scan
/tf
/tf_static

Well, the topics are there, but are they working? Let’s publish to the /cmd_vel topic and see if the robot moves. We also echo the /odom in another terminal. Run the following in Terminal 2:

# Try to move the robot with teleop
ros2 run teleop_twist_keyboard teleop_twist_keyboard

Then in Terminal 3:

ros2 topic echo /odom

The robot didn’t move and nothing was echoing from /odom!

Now we need to confirm that it’s not working because of those tags. Let’s modify the launch command in Terminal 1. Press Ctrl + C to stop the simulation and run the following commands instead:

# note that we changed the Turtlebot3 model
export TURTLEBOT3_MODEL=waffle
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

Now try to move the robot again and check the /odom eching…Poof, both working! Why? We modified the model file for “burger”; the one for “waffle” was intact!

Final confirmation: uncomment the lines in turtlebot3_ws/src/turtlebot3_simulations/turtlebot3_gazebo/models/turtlebot3_burger/model.sdf , stop the simulation in Terminal 1 and run the following commands.

# note that we changed the Turtlebot3 model back to burger
export TURTLEBOT3_MODEL=burger
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

Done! Now everything should be working!

So we have confirmed that the command and odometry tags are necessary.

Step 4: Check your learning

Do you understand how to use the Gazebo differential drive plugin in ROS 2? 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 use the Gazebo differential drive plugin in ROS 2

Here you go:

Feedback

Did you like this post? Do you have any questions about how to use the Gazebo differential drive plugin in ROS 2? 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.

Get ROS2 Industrial Ready- Hands-On Training by The Construct cover.png
Get ROS2 Industrial Ready- Hands-On Training by The Construct cover.png
[ROS2 Q&A] Learn how to create map for Robot Fleet Management Open-RMF #238

[ROS2 Q&A] Learn how to create map for Robot Fleet Management Open-RMF #238

What we are going to learn

  1. How to use RMF already installed in a rosject
  2. How to use a map created by SLAM as a base for RMF

List of resources used in this post

  1. Use the rosject: https://app.theconstructsim.com/l/51e404da/
  2. The Construct: https://app.theconstructsim.com/
  3. Open-RMF: https://www.open-rmf.org/
  4. Open-RMF Demos: https://github.com/open-rmf/rmf_demos
  5. ROS2 Courses –▸
    1. ROS2 Basics in 5 Days Humble (Python): https://app.theconstructsim.com/Course/132
    2. ROS2 Basics in 5 Days Humble (C++): https://app.theconstructsim.com/Course/133
    3. Open-RMF / Fleet Management Training: https://www.theconstruct.ai/robot-fleet-management-ros2-open-rmf-training/

Overview

Open-RMF stands for Open Robotics Middleware Framework, and it is a Common Language for Robot Interoperability.

It is a modular software system that enables sharing and interoperability between multiple fleets of robots and physical infrastructure, like doors, elevators, and building management systems.

This post is an introduction to the map you will need in order to use Open-RMF.

ROS Inside!

ROS Inside

ROS Inside

Before anything else, if you want to use the logo above on your own robot or computer, feel free to download it 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 and Open-RMF installed in our system, and ideally a ros2_ws (ROS2 Workspace). To make your life easier, we have already prepared a rosject with a simulation for that: https://app.theconstructsim.com/l/51e404da/.

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 create a map for Robot Fleet Management Open-RMF – 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.

Why do we need a map, after all?

When we use Open-RMF, we want to control a fleet of robots, and since robots move around, we need a way to go through the building, and for that, we need a map.

If we check the rmf_demos repository, it shows an image of a blueprint of a building,

Open-RMF hotel world by Open-Robotics

Open-RMF hotel world by Open-Robotics

 

In order to move the robot around, Open-RMF has a pipeline that goes as follows:

  1. We start with the blueprint of a building
  2. Use the Traffic Editor to paint the walls and the paths that the robot can follow in the building. The robots have autonomous navigation but we still limit the robots to certain areas. If we check the image above, we see two paths, a blue and an orange one. This means that there are two fleets of robots operating in this area. Each fleet can move in one of these paths.
  3.  We start from the blueprint and create a simulation from that blueprint

But we found that most of the time we already have a simulation of a building, for example, and we want to make Open-RMF adapt to our simulation, instead of making our simulation adapt to Open-RMF.

That is what is this post about: How to make your own map to be used by Open-RMF.

Starting the simulation

After having opened the rosject, let’s start a simulation. For that, let’s open a terminal by clicking the Open a new terminal button.

Open a new Terminal

Open a new Terminal

Once inside the terminal, let’s run the commands below:

cd ~/ros2_ws
ros2 launch barista_gazebo  start_world_standalone.launch.py

 

After a few seconds, we should have a simulation open, like in the image below (if for any reason you think the simulation is empty, just zoom out using the mouse to find the simulation):

Starbots Coffee simulation for Open-RMF on The Construct

Starbots Coffee simulation for Open-RMF on The Construct

 

Now that you see the simulation, we basically want to make a map of that building that appears in the simulation.

Normally, everyone who has a Gazebo simulation already has a map of that area to make the robot move around. In this case, the cartographer_slam package has been used to create a map of the environment.

The image below is what we are talking about when we say we already have a  map of the environment:

Starbots Coffee Cartographer Map for Open-RMF

Starbots Coffee Cartographer Map for Open-RMF

 

If you want to see that image of the map, it is available in the following path in the rosject:

  • ~/ros2_ws/src/starbots_rmf/maps/starbots_sim.png

In order to download that file, you can just use the IDE (Code Editor) for that. If you don’t know how to open it, please check the image below:

Open the IDE - Code Editor

Open the IDE – Code EditorAfter opening the Code Editor, just right-click on ~/ros2_ws/src/starbots_rmf/maps/starbots_sim.png, and then click Download.

Bear in mind that the Cartographer Slam package generates PGM files. We used a tool to convert the PGM files to PNG (image format).

Starting the Traffic Editor

Now that the basic introductions have been made, let’s start with the Traffic Editor. For that, you can open a second terminal and type the following command:

traffic-editor

After a few seconds, you should have it open (a new window should pop up).

To create a new map, just click Buidling -> New.

How to create a map for Robot Fleet Management Open-RMF -Building New

How to create a map for Robot Fleet Management Open-RMF -Building New

 

To make things simpler, you can save the map in the same location as the existing maps:

  •  /home/user/ros2_ws/src/starbots_rmf/maps/

You can name the map “test” and click the save button.

Traffic Editor – Creating a new level

Now that we have a blank map of the building in the Traffic Editor, let’s create a new level. Let’s name it L1 (level 1) and let’s select the /home/user/ros2_ws/src/starbots_rmf/maps/starbots_sim.png map that we mentioned earlier. For that, let’s click the Add button, then click Find to select the map, as we can see in the image below:

Open-RMF Traffic Editor - Adding a new level

Open-RMF Traffic Editor – Adding a new level

 

Traffic Editor – Creating a new lane

After the new level has been created, we can now create a new lane that specifies the paths that the robot can move. The robot will be able to move only in those areas. For that, click New Lane, and by clicking in different areas of the map, draw a lane where the robot can move:

Open-RMF Traffic Editor - Adding a new lane

Open-RMF Traffic Editor – Adding a new lane

 

Traffic Editor – Naming the spots

After drawing the lane in the previous image, you see that we have some small circles that form the intersections, and we have them also at the beginning and at the end of the lane we draw.

When we click on any of these spots, we see some properties on the right side. Please click in each circle spot and name them, like start, end, kitchen, etc by entering the name in the name input.

By selecting the green lines, you can also define if the movement is bidirectional or not, for example.

You can have as many lanes as you want, but you have to make sure they are somehow connected if you want the robot to move the whole area.

Now, to make sure your changes will not be lost, just click Building -> Save.

After hitting Save, you should see all the information related to the map at:

  •  /home/user/ros2_ws/src/starbots_rmf/maps/test.building.yaml

Traffic Editor – Compile the workspace

Now that we created our new map, we need to recompile our workspace to make sure Open-RMF will be able to work with it.

For that, we just run the following commands in a third terminal:

cd ~/ros2_ws

then,

colcon build  --cmake-args -DCMAKE_BUILD_TYPE=Release

We expect everything to finish successfully. Among other output messages, the following message is expected:

# ...
Generating Lane Graphs in  Generating Lane Graphs in  /home/user/ros2_ws/build/starbots_rmf/maps/test/nav_graphs/
# ...

 

The thing that most interests us here is the following path:

/home/user/ros2_ws/build/starbots_rmf/maps/test/

If we check the content of that directory, we will find a test.world file (because our Building was called test).

ls /home/user/ros2_ws/build/starbots_rmf/maps/test/

ls  /home/user/ros2_ws/build/starbots_rmf/maps/test/nav_graphs/

 

If we check /home/user/ros2_ws/build/starbots_rmf/maps/test/nav_graphs/, we will find a file named 0.yaml, which is the main element we need to get started with Open-RMF map.

Changing the launch file to open our newly generated map

Using the code editor, please open the following file:

  • /home/user/ros2_ws/src/starbots_rmf/launch/rmf_schedule.launch.xml

Then, change the map_name variable on line 12 to set the value “test”. In the end, the file should look like this:

<?xml version='1.0' ?>

<launch>
  <arg name="failover_mode" default="false"/>
  <!-- set to false if using real robots -->
  <arg name="use_sim_time" default="false"/> 

  <!-- Common launch -->
  <include file="$(find-pkg-share starbots_rmf)/launch/barista_rmf_schedule.launch.xml">
    <arg name="use_sim_time" value="$(var use_sim_time)"/>
    <arg name="failover_mode" value="$(var failover_mode)"/>
    <arg name="map_name" value="test" />
  </include>

</launch>

 

Now let’s create an RViz config file named test.rviz:

cd ~/ros2_ws/src
cp ./starbots_rmf/rviz_config/starbots.rviz ./starbots_rmf/rviz_config/test.rviz

 

Now we can compile the workspace again to have the updates of the XML reflected:

cd ~/ros2_ws
colcon build  --cmake-args -DCMAKE_BUILD_TYPE=Release
source install/setup.bash

 

now we can launch the simulation again in the first terminal (Please remember to terminate the simulation that was launched previously in the first terminal):

ros2 launch starbots_rmf rmf_schedule.launch.xml

 

If everything worked perfectly, you should now see an RViz window with the map ready for Open-RMF to use it. If we had setup our robots correctly, they should appear on top of the map:

How to create map for Robot Fleet Management Open-RMF generated map on RViz

How to create map for Robot Fleet Management Open-RMF generated map on RViz

 

Congratulations. You just learned how to create a map to be used by Open-RMF.

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:


How to integrate OpenCV with a ROS2 C++ node

How to integrate OpenCV with a ROS2 C++ node

In this post, you will learn how to integrate the OpenCV library with a ROS2 C++ node. The example shown builds into a “hello-world” binary for ROS2 integration with OpenCV that publishes an image to the ROS network.

After going through this post, you would be able to use OpenCV to do things related to image processing and computer vision and make the results available to other ROS2 nodes. The example uses ROS2 Humble.

Step 1: Fire up a system with ROS2 installation

“Hey, do 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 image below, 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: Verify that OpenCV is installed

All ROS installs include OpenCV, so verify whether OpenCV has been installed.

Open Code Editor
Open a web shell

Open a web shell and run the following command:

pkg-config --modversion opencv4

You should get a version number similar to this:

4.5.4

If the above output is similar to what you see, you are set and ready, everything should work. Otherwise, please install OpenCV using the following command:

sudo apt install libopencv-dev python3-opencv

Step 3: Create a ROS2 C++ node integrating the OpenCV library

First, we need to create a package. We need the following dependencies for the package:

  • rclcpp – this is the ros2 C++ API we’ll use to create the ros2 node
  • std_msgs – needed for sending message header while sending the image
  • sensor_msgs – needed for sending the image itself
  • cv_bridge – converts from the OpenCV image format to the ros2 image format
  • image_transport – compresses the image for transport within the ros2 network
  • OpenCV – generates the image we want to send

Run the following command in the terminal you used in Step 2, to create the package:

cd ~/ros2_ws/src
ros2 pkg create my_opencv_demo --dependencies rclcpp std_msgs sensor_msgs cv_bridge image_transport OpenCV

Now go to the src folder of the package you just created and create the C++ file that will define the node:

cd ~/ros2_ws/src/my_opencv_demo/src
touch minimal_opencv_ros2_node.cpp

Open the Code Editor, locate the C++ file you just created, and paste the code indicated below. Explanations are given as comments within the code.

Open the Code Editor
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "std_msgs/msg/header.hpp"
#include <chrono&gt;
#include <cv_bridge/cv_bridge.h&gt; // cv_bridge converts between ROS 2 image messages and OpenCV image representations.
#include <image_transport/image_transport.hpp&gt; // Using image_transport allows us to publish and subscribe to compressed image streams in ROS2
#include <opencv2/opencv.hpp&gt; // We include everything about OpenCV as we don't care much about compilation time at the moment.

using namespace std::chrono_literals;

class MinimalImagePublisher : public rclcpp::Node {
public:
  MinimalImagePublisher() : Node("opencv_image_publisher"), count_(0) {
    publisher_ =
        this-&gt;create_publisher<sensor_msgs::msg::Image&gt;("random_image", 10);
    timer_ = this-&gt;create_wall_timer(
        500ms, std::bind(&amp;MinimalImagePublisher::timer_callback, this));
  }

private:
  void timer_callback() {
    // Create a new 640x480 image
    cv::Mat my_image(cv::Size(640, 480), CV_8UC3);

    // Generate an image where each pixel is a random color
    cv::randu(my_image, cv::Scalar(0, 0, 0), cv::Scalar(255, 255, 255));

    // Write message to be sent. Member function toImageMsg() converts a CvImage
    // into a ROS image message
    msg_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", my_image)
               .toImageMsg();

    // Publish the image to the topic defined in the publisher
    publisher_-&gt;publish(*msg_.get());
    RCLCPP_INFO(this-&gt;get_logger(), "Image %ld published", count_);
    count_++;
  }
  rclcpp::TimerBase::SharedPtr timer_;
  sensor_msgs::msg::Image::SharedPtr msg_;
  rclcpp::Publisher<sensor_msgs::msg::Image&gt;::SharedPtr publisher_;
  size_t count_;
};

int main(int argc, char *argv[]) {
  rclcpp::init(argc, argv);
  // create a ros2 node
  auto node = std::make_shared<MinimalImagePublisher&gt;();

  // process ros2 callbacks until receiving a SIGINT (ctrl-c)
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

Finally, edit the package’s CMakeLists.txt (~/ros2_ws/src/my_opencv_demo/CMakeLists.txt) file to recognize the node. Copy the lines of code shown below and paste them before the invocation of ament_package():

add_executable(minimal_opencv_ros2_node src/minimal_opencv_ros2_node.cpp)
ament_target_dependencies(minimal_opencv_ros2_node rclcpp std_msgs sensor_msgs cv_bridge image_transport OpenCV)
​
install(TARGETS
   minimal_opencv_ros2_node
   DESTINATION lib/${PROJECT_NAME}
 )

The CMakeLists.txt file should now look like this:

cmake_minimum_required(VERSION 3.8)
project(my_opencv_demo)

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)
find_package(sensor_msgs REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(image_transport REQUIRED)
find_package(OpenCV REQUIRED)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

add_executable(minimal_opencv_ros2_node src/minimal_opencv_ros2_node.cpp)
ament_target_dependencies(minimal_opencv_ros2_node rclcpp std_msgs sensor_msgs cv_bridge image_transport OpenCV)

install(TARGETS
  minimal_opencv_ros2_node
  DESTINATION lib/${PROJECT_NAME}
)

ament_package()

Congratulations! You have created a ros2 C++ node integrating OpenCV. Now, we need to see if it works!

Step 4: Compile and test ROS2 C++ node integrating the OpenCV library

Generate the ros2 executable by compiling and sourcing the package:

cd ~/ros2_ws
colcon build --packages-select my_opencv_demo
source ~/ros2_ws/install/setup.bash

If you got to this point, great! Now we will run the node:

ros2 run my_opencv_demo minimal_opencv_ros2_node

You should see some output similar to this:

[INFO] [1677071986.446315963] [opencv_image_publisher]: Image 0 published
[INFO] [1677071986.941745471] [opencv_image_publisher]: Image 1 published
[INFO] [1677071987.442009334] [opencv_image_publisher]: Image 2 published
[INFO] [1677071987.941677164] [opencv_image_publisher]: Image 3 published
[INFO] [1677071988.441115565] [opencv_image_publisher]: Image 4 published
[INFO] [1677071988.940492910] [opencv_image_publisher]: Image 5 published
[INFO] [1677071989.441007118] [opencv_image_publisher]: Image 6 published

Now let’s run ros2 topic list to confirm the existence of the image topic. Leave the node running in the current terminal and run the following command in a new terminal:

source ~/ros2_ws/install/setup.bash
ros2 topic list

The output should inclide the /random_image topic:

/parameter_events
/random_image
/rosout

Finally lets us see what the image produced by OpenCV looks like. Run the following in the same terminal where you ran ros2 topic list. If you get the error, (image_view:8839): Gdk-ERROR **: 13:30:34.498: The program 'image_view' received an X Window System error, just run the command again.

ros2 run image_view image_view --ros-args --remap image:=/random_image

You should now see something like this pop up on your screen. Yahoo!

Random image output from the OpenCV node

Great job! You have successfully created a ros2 C++ node integrating OpenCV!

Step 5: Extra: add text to the Image

Copy the lines of code shown below and paste them inside the timer callback function just before writing the message to be sent:

    // Declare the text position
    cv::Point text_position(15, 40);
    
    // Declare the size and color of the font
    int font_size = 1;
    cv::Scalar font_color(255, 255, 255);

    // Declare the font weight
    int font_weight = 2;

    // Put the text in the image
    cv::putText(my_image, "ROS2 + OpenCV", text_position, cv::FONT_HERSHEY_COMPLEX, font_size, font_color, font_weight);

Stop the currently running node, recompile and source the package, and re-run the node. You should now see something like this:

Random image with text from the OpenCV node

Step 6: Check your learning

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

(Extra) Step 7: Watch the video to understand how to integrate the OpenCV library with a ROS2 C++ node

Here you go:

If you want to learn more about ROS 2 and dive deeper into robotics, check out the Robotics Developer Masterclass, where you’ll master robotics development from scratch and get 100% job-ready to work at robotics companies.




Feedback

Did you like this post? Do you have any questions about how to integrate the OpenCV library with a ROS2 C++ node? 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.

Pin It on Pinterest