ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

ros1_bridge generating custom messages but when running, throws error "No template specialization for the pair"

asked 2018-07-20 11:46:05 -0600

Rob V gravatar image

updated 2018-07-24 10:08:26 -0600

I have successfully ran ros1_bridge's dynamic_bridge and passed messages between ROS and ROS2, but cannot quite figure out how to implement custom message definitions. I am using 64-bit Ubuntu 16.04 LTS, ROS Kinetic, and ROS2 Ardent.

Below is my general file structure:

------[workspace built from [this]( tutorial, with ardent branch's ros2.repos file]
------[other ros2 stuff I'm doing that will later utilize the ros1_bridge]

To specify, I've named the package and message file the same for each workspace, and the message file itself is a simple definition with a couple of float64[] list variables (I copied the exact contents so it matches).

My process to build all of this is as follows (each build is done in a separate terminal):

**Process for building ros1_bridge_ws_overlay/catkin_ws_overlay:
  $ source /opt/ros/kinetic/setup.bash
  $ cd <path_to_folder>/ros1_bridge_overlay/catkin_ws_overlay/
  $ catkin_make

The output for catkin_make clearly generates my custom message and link's my executable.

**Process for building ros1_bridge_ws_overlay/ros2_ws_overlay:
  $ source /opt/ros/ardent/setup.bash
  $ cd <path_to_folder>/ros1_bridge_overlay/ros2_ws_overlay/
  $ ament build

Again, the output clearly generates my custom messages (I can see them in install/include/my_interfaces/msg/) and links my executable.

Now that I've generated my custom messages, I go to my ros2_ws and delete the folder ros2_ws/build/ros1_bridge. Then, to rebuild the ros1_bridge, I do as follows:

**Process for rebuilding ros1_bridge:
  $ source <path_to_folder>/ros1_bridge_overlay/catkin_ws_overlay/devel/setup.bash
  $ source <path_to_folder>/ros1_bridge_overlay/ros2_ws_overlay/install/local_setup.bash
  $ cd <path_to_folder>/ros2_ws
  $ src/ament/ament_tools/scripts/ build --build-tests --symlink-install

From this, I see important output such as:

[  2%] Generating generated/get_factory.cpp, generated/get_mappings.cpp, generated/nav_msgs_factories.cpp, generated/actionlib_msgs_factories.cpp, generated/logging_demo_factories.cpp, generated/trajectory_msgs_factories.cpp, generated/test_msgs_factories.cpp, generated/tf2_msgs_factories.cpp, generated/stereo_msgs_factories.cpp, generated/lifecycle_msgs_factories.cpp, generated/visualization_msgs_factories.cpp, generated/geometry_msgs_factories.cpp, generated/shape_msgs_factories.cpp, generated/std_msgs_factories.cpp, generated/rcl_interfaces_factories.cpp, generated/std_srvs_factories.cpp, generated/diagnostic_msgs_factories.cpp, generated/builtin_interfaces_factories.cpp, generated/sensor_msgs_factories.cpp, generated/example_interfaces_factories.cpp, generated/pendulum_msgs_factories.cpp, generated/composition_factories.cpp, generated/my_interfaces_factories.cpp


[ 84%] Building CXX object CMakeFiles/ros1_bridge.dir/generated/my_interfaces_factories.cpp.o

At this point, I would guess that my custom message is being processed and built properly. Then, I run all the executables necessary to bring up the bridge (again, all of these are in separate terminals), as so:

**Process for starting roscore:
  $ source /opt/ros/kinetic/setup.bash
  $ source <path_to_folder>/ros1_bridge_overlay/catkin_ws_overlay/devel/setup.bash
  $ roscore

**Process for starting dynamic_bridge:
  $ source /opt/ros/kinetic/setup.bash
  $ source <path_to_folder>/ros1_bridge_overlay/catkin_ws_overlay/devel/setup.bash
  $ source /opt/ros/ardent/setup.bash
  $ source <path_to_folder>/ros2_ws/install/local_setup.bash
  $ source <path_to_folder>/ros1_bridge_overlay/ros2_ws_overlay/install/local_setup.bash
  $ ros2 run ros1_bridge dynamic_bridge

**Process for starting ROS publisher:
  $ source /opt/ros/kinetic/setup.bash
  $ source <path_to_folder>/ros1_bridge_overlay/catkin_ws_overlay/devel/setup.bash
  $ rosrun my_interfaces test_publisher // How ...
edit retag flag offensive close merge delete


Did you run the bridge with --print-pairs to see which message types from your custom package are included? The content of the generated file generated/my_interfaces_factories.cpp would reveal similar information.

Dirk Thomas gravatar image Dirk Thomas  ( 2018-07-20 18:39:03 -0600 )edit

I tried --print-pairs and generated/my_interfaces_factories.cpp was not included in the list...

Rob V gravatar image Rob V  ( 2018-07-21 09:31:02 -0600 )edit

Can you share the content of the generated file generated/my_interfaces_factories.cpp.

Dirk Thomas gravatar image Dirk Thomas  ( 2018-07-21 16:28:36 -0600 )edit

Sorry for the delay, I was away from my machine for a little bit - see the edit above for the contents of the file. Thanks again!

Rob V gravatar image Rob V  ( 2018-07-23 07:33:45 -0600 )edit

The source code doesn't contain any mapping. Please post the exact content of your message files from the ROS 1 as well as 2 workspaces.

Dirk Thomas gravatar image Dirk Thomas  ( 2018-07-23 09:51:03 -0600 )edit

See the next edit for the message contents.

Rob V gravatar image Rob V  ( 2018-07-23 11:46:03 -0600 )edit

Please try to edit the source code of the ros1_bridge before building it by adding print statements for the various variables in this section

Dirk Thomas gravatar image Dirk Thomas  ( 2018-07-23 11:54:43 -0600 )edit

Make sure that your message appears in ros1_msgs as well as ros2_msgs and that the packages are correlated in package_pairs and the messages in message_pairs.

Dirk Thomas gravatar image Dirk Thomas  ( 2018-07-23 11:55:34 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2018-07-25 19:57:19 -0600

Rob V gravatar image

updated 2018-07-25 20:02:23 -0600

Short answer: Packages that you want to be linked by ros1_bridge (without a mapping rule) cannot end in "_interfaces", and that's possibly the only sequence of character's that it can't end with.

Longer answer: The answer to the original problem, basically, is that I used a sequence of characters as my suffix that produces unexpected results. I named my package my_interfaces. However, in of ros1_bridge, in the function determine_package_pairs (found here), you'll see these variables:

ros1_suffix = '_msgs'
ros2_suffixes = ['_msgs', '_interfaces']

The logic following says that to compare a ROS1 package's name and a ROS2 package's name, you first have to remove possible suffixes. So, when given "my_interfaces", it modifies it to say that the new ROS1 package name is "my_interfaces", but the ROS2 package name is only "my" now. Since those aren't equivalent anymore, it stops processing these packages as possible linkages between the bridge. My solution was to simply rename the package to be anything BUT something that ends in "_interfaces"... I'm not really sure as to why this was implemented without first checking that they're equivalent, it caused me a LOT of frustration XD

However, I have not yet solved the follow up issue in my third edit. If someone can point out what the issue there is, that'd be much appreciated! I'll update this answer if I find a solution.

edit flag offensive delete link more


"I'm not really sure as to why this was implemented without first checking that they're equivalent, it caused me a LOT of frustration XD"

This is related with the ROS1/ROS2 package naming conventions/best practices.

  • In ROS 1 the convention/best practice is to use the "_msgs" postfix in interface packages.
  • In ROS 2 the convention/best practice is to use the "_interfaces" instead of "_msgs" postfix in interface packages BUT in practice both post-fixes are used.

ROS2 Package Naming Best practices

Spyros Kou gravatar image Spyros Kou  ( 2023-06-13 08:27:53 -0600 )edit

Question Tools



Asked: 2018-07-20 11:37:09 -0600

Seen: 1,476 times

Last updated: Jul 25 '18