ROS2 Tutorials #7: How to create a ROS2 Custom Message

ROS2 Tutorials #7: How to create a ROS2 Custom Message

Written by Alberto Ezquerro

07/10/2019

In this episode of ROS2 Tutorials Series, you will learn how to create a simple ROS2 custom message for Topics.

We are going to use a ROS2 (Dashing) installation for this, but you don’t need to install ROS, as we will use the ROS Development Studio (ROSDS), an online platform that provides access to ROS2 and ROS2 computers and other powerful ROS tools within a browser!

Now let’s get to work without further ado!

Step 1: Create a Project (ROSject) on ROSDS

Head to http://rosds.online and create a project with a similar configuration as the one shown below. You can change the details as you like, but please ensure you select “Ubuntu 18.04 + ROS2 Dashing” under “Configuration”.

Create a ROS2 project for Dashing

Once done with that, open your ROSject. This might take a few moments, please be patient.

Step 2: Source the ROS2 workspace

Once the ROSject is open, head to the Tools menu and pick the Shell tool (a terminal) and run the following command to source the workspace:

user:~$ source /opt/ros/dashing/setup.bash
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~$

If you get that ROS_DISTRO warning, just ignore it.

Step 3: Create a ROS2 C++ package in your ROS2 workspace

We are creating a C++ package (ament_cmake) and adding dependencies rclcpp (ROS C++ client) and std_msgs (in-built standard messages type, on which our new message will be based).

user:~$ mkdir -p ros2_ws/src
user:~$ cd ros2_ws/src
user:~/ros2_ws/src$
user:~/ros2_ws/src$ ros2 pkg create ros2_msg --build-type ament_cmake --dependencies rclcpp std_msgs
going to create a new package
package name: ros2_msg
destination directory: /home/user/ros2_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['user <user@todo.todo>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: ['rclcpp', 'std_msgs']
creating folder ./ros2_msg
creating ./ros2_msg/package.xml
creating source and include folder
creating folder ./ros2_msg/src
creating folder ./ros2_msg/include/ros2_msg
creating ./ros2_msg/CMakeLists.txt
user:~/ros2_ws/src$

Step 3: Create the definition of the ROS2 custom message

user:~/ros2_ws/src$ cd ros2_msg
user:~/ros2_ws/src/ros2_msg$ mkdir -p msg
user:~/ros2_ws/src/ros2_msg$ cd msg/
user:~/ros2_ws/src/ros2_msg/msg$ touch MyMsg.msg

Pick the “IDE” tool from the Tools menu, locate the MyMsg.msg file, and paste in the following code:

int32 day
string month
int32 year

Next, open up the CMakeList.txt file in the IDE and add the required dependencies:

  1. Add these two dependencies under “#find package”, right after the three that are already there:
    • find_package(builtin_interfaces REQUIRED)
      find_package(rosidl_default_generators REQUIRED)

  2. Add the following function to CMakeList.txt.This function tells the ROS system to generate a new message from the specified message definition, using the specified interface.
    • rosidl_generate_interfaces(new_msg
        "msg/MyMsg.msg"
        DEPENDENCIES builtin_interfaces
      )
      

      Add custom function to CMakeLists.txt

Next, open up the package.xml file in the IDE and make the following changes:

  1. Change the package format from “2” to “3”, if not already “3” (in this case it was already 3):
    • Check package format is "3"
  2. Add the dependencies that complement the ones we have in CMakeList.txt:
    • <build_depend>builtin_interfaces</build_depend>
      <build_depend>rosidl_default_generators</build_depend>
      <exec_depend>builtin_interfaces</exec_depend>
      <exec_depend>rosidl_default_runtime</exec_depend>
      
      <member_of_group>rosidl_interface_packages</member_of_group>

      Add dependencies to package.xml

Step 4: Compile the package

Whew, a couple of ingredients had to be added there; now it is time to compile the message and taste the “soup”!

Get back to the terminal and run the following commands:

user:~$ cd ~/ros2_ws
user:~/ros2_ws$ colcon build --symlink-install
Starting >>> ros2_msg
Finished <<< ros2_msg [14.1s]
Summary: 1 package finished [14.3s]
user:~/ros2_ws$ source install/setup.bash
ROS_DISTRO was set to 'dashing' before. Please make sure that the environment does not mix paths from different distributions.
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~/ros2_ws$

Step 5: Find and test the new custom message:

user:~/ros2_ws$ ros2 msg list | grep MyMsg
ros2_msg/msg/MyMsg

user:~/ros2_ws$ ros2 msg show ros2_msg/msg/MyMsg
int32 day
string month
int32 year
user:~/ros2_ws$ ros2 topic pub /test_topic ros2_msg/MyMsg "{day: '7', month: 'October', year: '2019'}"
publisher: beginning loop
publishing #1: ros2_msg.msg.MyMsg(day=7, month='October', year=2019)

publishing #2: ros2_msg.msg.MyMsg(day=7, month='October', year=2019)

publishing #3: ros2_msg.msg.MyMsg(day=7, month='October', year=2019)

Pick another Shell from the Tools menu and check the message being published (PS: you need to source ROS Dashing and the workspace first):

user:~$ source /opt/ros/dashing/setup.bash
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~$ source ros2_ws/install/setup.bash
ROS_DISTRO was set to 'dashing' before. Please make sure that the environment does not mix paths from different distributions.
ROS_DISTRO was set to 'melodic' before. Please make sure that the environment does not mix paths from different distributions.
user:~$ ros2 topic list
/parameter_events
/rosout
/test_topic
user:~$ ros2 topic echo /test_topic
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
day: 7
month: October
year: 2019
---
^Cuser:~$

Great, it ran! We’re done here!!

Extra 1: ROSject link

Get the ROSject containing all code used in the post in the following link: http://www.rosject.io/l/c3f3784/

Extra 2: Video

Prefer to watch a video demonstrating the steps above? We have one for you below!

Related Resources

Feedback

Did you like this post? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.

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

Post edited by Bayode Aderinola

#ROS2 #ROS #ROS2tutorials #Robot

Topics: ROS Q&A
Masterclass 2023 batch2 blog banner

Check Out These Related Posts

5 Comments

  1. Anonymous

    CMake Error at /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
    Could NOT find FastRTPS (missing: FastRTPS_INCLUDE_DIR FastRTPS_LIBRARIES)
    Call Stack (most recent call first):
    /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
    /opt/ros/dashing/share/fastrtps_cmake_module/cmake/Modules/FindFastRTPS.cmake:95 (find_package_handle_standard_args)
    /opt/ros/dashing/share/rosidl_typesupport_fastrtps_c/cmake/rosidl_typesupport_fastrtps_c-extras.cmake:7 (find_package)
    /opt/ros/dashing/share/rosidl_typesupport_fastrtps_c/cmake/rosidl_typesupport_fastrtps_cConfig.cmake:38 (include)
    /opt/ros/dashing/share/rosidl_default_generators/cmake/rosidl_default_generators-extras.cmake:21 (find_package)
    /opt/ros/dashing/share/rosidl_default_generators/cmake/rosidl_default_generatorsConfig.cmake:38 (include)
    CMakeLists.txt:17 (find_package)

    Reply
  2. Miao

    what if I need to include the msg file from another folder in the same package. how to equip the CMakeLists and package.xml?

    Reply
  3. Anonymous

    I tried to include the .msg file from other folder but got:

    CMake Error at /home/miao/ros2_install/ros2-linux/share/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake:93 (message):
    rosidl_generate_interfaces() the passed file ‘msg/JointCommand.msg’ doesn’t
    exist relative to the CMAKE_CURRENT_SOURCE_DIR
    ‘/home/miao/ros2_pendulum_ws/src/ros2_pendulum_pkg/minimal_publisher’
    Call Stack (most recent call first):
    CMakeLists.txt:23 (rosidl_generate_interfaces)

    How should I handle this problem?

    Reply
  4. la

    I have the same question as Miao :

    I tried to include the .msg file from other folder but got:

    CMake Error at /home/miao/ros2_install/ros2-linux/share/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake:93 (message):
    rosidl_generate_interfaces() the passed file ‘msg/JointCommand.msg’ doesn’t
    exist relative to the CMAKE_CURRENT_SOURCE_DIR
    ‘/home/la/dev_ws/src/ros2_pendulum_pkg/minimal_publisher’
    Call Stack (most recent call first):
    CMakeLists.txt:23 (rosidl_generate_interfaces)

    How should I handle this problem?

    Reply
  5. Reshma

    r
    r
    Could build successfuly, but getting
    r Could build it successfully,, but this command is giving following error, ros2 topic pub /test_topic ros2_msg/msg/String “{day: ‘7’, month: ‘October’, year: ‘2019’}”

    >>> [rcutils|error_handling.c:108] rcutils_set_error_state()
    This error state is being overwritten:

    ‘Failed to find library ‘ros2_msg__rosidl_typesupport_fastrtps_c’
    , at /tmp/binarydeb/ros-foxy-rosidl-typesupport-c-1.0.2/src/type_support_dispatch.hpp:73′

    with this new error message:

    ‘Handle’s typesupport identifier (rosidl_typesupport_c) is not supported by this library
    , at /tmp/binarydeb/ros-foxy-rosidl-typesupport-c-1.0.2/src/type_support_dispatch.hpp:116’

    rcutils_reset_error() should be called after error handling to avoid this.
    <<>> [rcutils|error_handling.c:108] rcutils_set_error_state()
    This error state is being overwritten:

    ‘Handle’s typesupport identifier (rosidl_typesupport_c) is not supported by this library
    , at /tmp/binarydeb/ros-foxy-rosidl-typesupport-c-1.0.2/src/type_support_dispatch.hpp:116’

    with this new error message:

    ‘type support not from this implementation, at /tmp/binarydeb/ros-foxy-rmw-fastrtps-cpp-1.3.0/src/publisher.cpp:86’

    rcutils_reset_error() should be called after error handling to avoid this.
    <<<
    Failed to create publisher: type support not from this implementation, at /tmp/binarydeb/ros-foxy-rmw-fastrtps-cpp-1.3.0/src/publisher.cpp:86, at /tmp/binarydeb/ros-foxy-rcl-1.1.13/src/rcl/publisher.c:180

    Reply

Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pin It on Pinterest

Share This