Creating custom message for ros1_bridge, #include <my_msgs/MyCustom.h> fails
ROS: Kinetic, ROS2: Ardent, OS: Ubuntu 16.04
Hello! This question acts as somewhat of a continuation of my previous question. I'm trying to build a custom message to use with ros1_bridge, and in the generated file <path_to_folder>/ros2_ws/build/ros1_bridge/generated/my_msgs_factories.hpp
, the line #include <my_msgs/MyCustom.h>
is failing while trying to build ros1_bridge
. The error message is as follows:
In file included from <path_to_folder>/ros2_ws/build/ros1_bridge/generated/get_factory.cpp:25:0:
<path_to_folder>/ros2_ws/build/ros1_bridge/generated/my_msgs_factories.hpp:6:31: fatal error: my_msgs/MyCustom.h: No such file or directory
compilation terminated.
CMakeFiles/ros1_bridge.dir/build.make:156: recipe for target 'CMakeFiles/ros1_bridge.dir/generated/get_factory.cpp.o' failed
As a sanity check, in /opt/ros/kinetic/include
, I created a folder called my_msgs
and placed MyCustom.h
in it, and then it successfully built. Only at this point is my_msgs
seen in the output of ros2 run ros1_bridge dynamic_bridge --print-pairs
. However, when I run dynamic_bridge
after this (using MyCustom
), I get the following output:
Failed to find library 'my_msgs__rosidl_typesupport_introspection_cpp'
failed to create 1to2 bridge for topic '/test_chatter' with ROS 1 type 'my_msgs/MyCustom' and ROS 2 type 'my_msgs/MyCustom': could not create publisher: type support not from this implementation, at <path_to_folder>/ros2_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_cpp/src/rmw_publisher.cpp:75, at <path_to_folder>/ros2_ws/src/ros2/rcl/rcl/src/rcl/publisher.c:151
The contents of <path_to_folder>/ros2_ws/build/ros1_bridge/generated/my_msgs_factories.hpp
and .cpp
are as follows:
//CONTENTS OF my_msgs_factories.hpp
// generated from ros1_bridge/resource/pkg_factories.hpp.em
#include <ros1_bridge/factory.hpp>
// include ROS 1 messages
#include <my_msgs/MyCustom.h>
// include ROS 2 messages
#include <my_msgs/msg/my_custom.hpp>
namespace ros1_bridge
{
std::shared_ptr<FactoryInterface>
get_factory_my_msgs(const std::string & ros1_type_name, const std::string & ros2_type_name);
std::unique_ptr<ServiceFactoryInterface>
get_service_factory_my_msgs(const std::string & ros_id, const std::string & package_name, const std::string & service_name);
// conversion functions for available interfaces
template<>
void
Factory<
my_msgs::MyCustom,
my_msgs::msg::MyCustom
>::convert_1_to_2(
const my_msgs::MyCustom & ros1_msg,
my_msgs::msg::MyCustom & ros2_msg);
template<>
void
Factory<
my_msgs::MyCustom,
my_msgs::msg::MyCustom
>::convert_2_to_1(
const my_msgs::msg::MyCustom & ros2_msg,
my_msgs::MyCustom & ros1_msg);
} // namespace ros1_bridge
And .cpp
:
// CONTENTS OF my_msgs_factories.cpp
// generated from ros1_bridge/resource/pkg_factories.cpp.em
#include "rclcpp/rclcpp.hpp"
#include "my_msgs_factories.hpp"
// include builtin interfaces
#include <ros1_bridge/convert_builtin_interfaces.hpp>
// include ROS 1 services
// include ROS 2 services
namespace ros1_bridge
{
std::shared_ptr<FactoryInterface>
get_factory_my_msgs(const std::string & ros1_type_name, const std::string & ros2_type_name)
{
// mapping from string to specialized template
if (
(ros1_type_name == my_"msgs/MyCustom" ||
ros1_type_name == "") &&
ros2_type_name == "my_msgs/MyCustom")
{
return std::make_shared<
Factory<
my_msgs::MyCustom,
my_msgs::msg::MyCustom
>
>("my_msgs/MyCustom", ros2_type_name);
}
return std::shared_ptr<FactoryInterface>();
}
// conversion functions for available interfaces
template<>
void
Factory<
my_msgs::MyCustom,
my_msgs::msg::MyCustom
>::convert_1_to_2(
const my_msgs::MyCustom & ros1_msg,
my_msgs::msg::MyCustom & ros2_msg)
{
// convert array field
// ensure array size
// dynamic arrays must be resized
ros2_msg.positions.resize(ros1_msg.positions.size());
// convert primitive array elements
std::copy(
ros1_msg.positions.begin(),
ros1_msg.positions.end(),
ros2_msg.positions.begin());
// convert array field
// ensure array size
// dynamic arrays must be resized
ros2_msg.velocities.resize(ros1_msg.velocities.size());
// convert primitive ...
Did you source your ROS 1 workspace after building it? Please try to include the exact steps you did with which you can reproduce the problem.
See my above edit... Thanks for helping out again!!
Your original post mentioned that the include failed. So you shouldn't be able to build successfully. You might want to revert your manual changes to
/opt/ros/kinetic
to reproduce the original problem.You should only need to source a single ws per ROS version. In ROS 1 your overlay workspace will automatically source the underlay which was used to build that ws. In ROS 2 that works the same when you source the
setup.*
instead of thelocal_setup.*
.Good point... However, when I revert it back, that's the same procedure I follow too. See the above minor edit at EDIT #2. Also, didn't know about that
setup
functionality. Good to know.