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
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:
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).
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
Let’s run the following commands in the first terminal in order to launch the simulation:
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
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:
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
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
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
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:
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:
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
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
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:
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:
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:
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).
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:
An existing ROS2 Package, publicly available for everyone to use
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
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:
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:
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
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 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:
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.
Replaces the heading Forthcoming with version (date) (eg. 0.0.1 (2022-01-08)) in CHANGELOG.rst
Commits those changes
Creates a Git tag (eg. 0.0.1) to mark this point in the Git history
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:
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
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.
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
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:
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.
Let’s examine the differential drive section of this plugin file and compare it with the one on the ROS Answers post.
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.
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.
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
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:
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).
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
In order to move the robot around, Open-RMF has a pipeline that goes as follows:
We start with the blueprint of a building
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.
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
Once inside the terminal, let’s run the commands below:
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
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
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 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
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
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
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:
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:
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
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:
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.
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 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:
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.
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "std_msgs/msg/header.hpp"
#include <chrono>
#include <cv_bridge/cv_bridge.h> // cv_bridge converts between ROS 2 image messages and OpenCV image representations.
#include <image_transport/image_transport.hpp> // Using image_transport allows us to publish and subscribe to compressed image streams in ROS2
#include <opencv2/opencv.hpp> // 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->create_publisher<sensor_msgs::msg::Image>("random_image", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&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_->publish(*msg_.get());
RCLCPP_INFO(this->get_logger(), "Image %ld published", count_);
count_++;
}
rclcpp::TimerBase::SharedPtr timer_;
sensor_msgs::msg::Image::SharedPtr msg_;
rclcpp::Publisher<sensor_msgs::msg::Image>::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>();
// 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():
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!
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:
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.