I'm trying to adapt a lot of code that already has data structures defined to ROS, so I decided to try using roscpp message adaptation since it seems like it could help make the transition easier. But I cant get even the demo code to run.
I've been following this tutorial: " http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes#Example:_Adapting_a_custom_Vector3 " in Ubuntu 18.04 with ROS Melodic but it doesn't compile. I copied and pasted the tutorial code, and the things added are:
The include ros/static_assert.h and include geometry_msgs/Vector3.h, to fix dependency issues of the original code
The include ros/ros.h and the main function to test the code
This is the code:
#include <ros/message_traits.h>
#include <ros/serialization.h>
#include "ros/static_assert.h"
#include <ros/ros.h>
#include <geometry_msgs/Vector3.h>
struct MyVector3
{
double x;
double y;
double z;
};
// compile-time assert that sizeof(MyVector3) == serializationLength(x) + serializationLength(y) + serializationLength(z)
ROS_STATIC_ASSERT(sizeof(MyVector3) == 24);
namespace ros
{
namespace message_traits
{
// This type is fixed-size (24-bytes)
template<> struct IsFixedSize<MyVector3> : public TrueType {};
// This type is memcpyable
template<> struct IsSimple<MyVector3> : public TrueType {};
template<>
struct MD5Sum<MyVector3>
{
static const char* value()
{
// Ensure that if the definition of geometry_msgs/Vector3 changes we have a compile error here.
ROS_STATIC_ASSERT(MD5Sum<geometry_msgs::Vector3>::static_value1 == 0x4a842b65f413084dULL);
ROS_STATIC_ASSERT(MD5Sum<geometry_msgs::Vector3>::static_value2 == 0xc2b10fb484ea7f17ULL);
return MD5Sum<geometry_msgs::Vector3>::value();
}
static const char* value(const MyVector3& m)
{
return MD5Sum<geometry_msgs::Vector3>::value(m);
}
};
template<>
struct DataType<MyVector3>
{
static const char* value()
{
return DataType<geometry_msgs::Vector3>::value();
}
static const char* value(const MyVector3& m)
{
return DataType<geometry_msgs::Vector3>::value(m);
}
};
template<>
struct Definition<MyVector3>
{
static const char* value()
{
return Definition<geometry_msgs::Vector3>::value();
}
static const char* value(const MyVector3& m)
{
return Definition<geometry_msgs::Vector3>::value(m);
}
};
} // namespace message_traits
namespace serialization
{
template<>
struct Serializer<MyVector3>
{
template<typename Stream, typename T>
inline static void allInOne(Stream& stream, T t)
{
stream.next(t.x);
stream.next(t.y);
stream.next(t.z);
}
ROS_DECLARE_ALLINONE_SERIALIZER;
};
} // namespace serialization
} // namespace ros
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<geometry_msgs::Vector3>("chatter", 1000);
ros::Rate loop_rate(10);
MyVector3 Variance;
Variance.x = 1.0;
Variance.y = 2.0;
int count = 0;
while (ros::ok())
{
chatter_pub.publish(Variance);
ros::spinOnce();
loop_rate.sleep();
++count;
}
return 0;
}
It gives the following error:
/home/user/catkin_ws/src/message_tests/src/message_tests2.cpp: In static member function ‘static const char* ros::message_traits::MD5Sum<MyVector3>::value(const MyVector3&)’:
/home/user/catkin_ws/src/message_tests/src/message_tests2.cpp:37:63: error: no matching function for call to ‘ros::message_traits::MD5Sum<geometry_msgs::Vector3_<std::allocator<void> > >::value(const MyVector3&)’
return MD5Sum<geometry_msgs::Vector3>::value(m);
^
In file included from /home/user/catkin_ws/src/message_tests/src/message_tests2.cpp:4:0:
/opt/ros/melodic/include/geometry_msgs/Vector3.h:125:22: note: candidate: static const char* ros::message_traits::MD5Sum<geometry_msgs::Vector3_<ContainerAllocator> >::value() [with ContainerAllocator = std::allocator<void>]
static const char* value()
^~~~~
/opt/ros/melodic/include/geometry_msgs/Vector3.h:125:22: note: candidate expects 0 arguments, 1 provided
/opt/ros/melodic/include/geometry_msgs/Vector3.h:130:22: note: candidate: static const char* ros::message_traits::MD5Sum<geometry_msgs::Vector3_<ContainerAllocator> >::value(const geometry_msgs::Vector3_<ContainerAllocator>&) [with ContainerAllocator = std::allocator<void>]
static const char* value(const ::geometry_msgs::Vector3_<ContainerAllocator>&) { return value(); }
^~~~~
/opt/ros/melodic/include/geometry_msgs/Vector3.h:130:22: note: no known conversion for argument 1 from ‘const MyVector3’ to ‘const geometry_msgs::Vector3_<std::allocator<void> >&’
/home/user/catkin_ws/src/message_tests/src/message_tests2.cpp: In static member function ‘static const char* ros::message_traits::DataType<MyVector3>::value(const MyVector3&)’:
/home/user/catkin_ws/src/message_tests/src/message_tests2.cpp:51:65: error: no matching function for call to ‘ros::message_traits::DataType<geometry_msgs::Vector3_<std::allocator<void> > >::value(const MyVector3&)’
return DataType<geometry_msgs::Vector3>::value(m);
^
In file included from /home/user/catkin_ws/src/message_tests/src/message_tests2.cpp:4:0:
/opt/ros/melodic/include/geometry_msgs/Vector3.h:138:22: note: candidate: static const char* ros::message_traits::DataType<geometry_msgs::Vector3_<ContainerAllocator> >::value() [with ContainerAllocator = std::allocator<void>]
static const char* value()
^~~~~
/opt/ros/melodic/include/geometry_msgs/Vector3.h:138:22: note: candidate expects 0 arguments, 1 provided
/opt/ros/melodic/include/geometry_msgs/Vector3.h:143:22: note: candidate: static const char* ros::message_traits::DataType<geometry_msgs::Vector3_<ContainerAllocator> >::value(const geometry_msgs::Vector3_<ContainerAllocator>&) [with ContainerAllocator = std::allocator<void>]
static const char* value(const ::geometry_msgs::Vector3_<ContainerAllocator>&) { return value(); }
^~~~~
/opt/ros/melodic/include/geometry_msgs/Vector3.h:143:22: note: no known conversion for argument 1 from ‘const MyVector3’ to ‘const geometry_msgs::Vector3_<std::allocator<void> >&’
/home/user/catkin_ws/src/message_tests/src/message_tests2.cpp: In static member function ‘static const char* ros::message_traits::Definition<MyVector3>::value(const MyVector3&)’:
/home/user/catkin_ws/src/message_tests/src/message_tests2.cpp:65:67: error: no matching function for call to ‘ros::message_traits::Definition<geometry_msgs::Vector3_<std::allocator<void> > >::value(const MyVector3&)’
return Definition<geometry_msgs::Vector3>::value(m);
^
In file included from /home/user/catkin_ws/src/message_tests/src/message_tests2.cpp:4:0:
/opt/ros/melodic/include/geometry_msgs/Vector3.h:149:22: note: candidate: static const char* ros::message_traits::Definition<geometry_msgs::Vector3_<ContainerAllocator> >::value() [with ContainerAllocator = std::allocator<void>]
static const char* value()
^~~~~
/opt/ros/melodic/include/geometry_msgs/Vector3.h:149:22: note: candidate expects 0 arguments, 1 provided
/opt/ros/melodic/include/geometry_msgs/Vector3.h:164:22: note: candidate: static const char* ros::message_traits::Definition<geometry_msgs::Vector3_<ContainerAllocator> >::value(const geometry_msgs::Vector3_<ContainerAllocator>&) [with ContainerAllocator = std::allocator<void>]
static const char* value(const ::geometry_msgs::Vector3_<ContainerAllocator>&) { return value(); }
^~~~~
/opt/ros/melodic/include/geometry_msgs/Vector3.h:164:22: note: no known conversion for argument 1 from ‘const MyVector3’ to ‘const geometry_msgs::Vector3_<std::allocator<void> >&’
My CMakeFile is as follows:
cmake_minimum_required(VERSION 2.8.3)
project(message_tests)
find_package(catkin REQUIRED COMPONENTS
std_msgs
roscpp
geometry_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES message_tests
# CATKIN_DEPENDS geometry2d std_msgs
# DEPENDS system_lib
)
include_directories(
# include
${catkin_INCLUDE_DIRS}
include/${PROJECT_NAME}
)
add_executable(message_tests2 src/message_tests2.cpp)
target_link_libraries(message_tests2 ${catkin_LIBRARIES})
The problem originates in this lines:
static const char* value(const MyVector3& m)
{
return MD5Sum<geometry_msgs::Vector3>::value(m);
}
static const char* value(const MyVector3& m)
{
return DataType<geometry_msgs::Vector3>::value(m);
}
static const char* value(const MyVector3& m)
{
return Definition<geometry_msgs::Vector3>::value(m);
}
The code seems to expect a 'const geometry_msgs::Vector3_std::allocator<void >&' but the value m is a 'const MyVector3& '. If I change geometry_msgs::Vector3 to MyVector3 the function calls itself and I get a segmentation fault.
I dont know enough about templates to find the problem. The only other example I found was this: ROS Answers - custom-classes-in-message-files. Which also has the same issue. I tried compiling using C++11 and C++03 as well as C++14 but unfourtanately I have made no progress.
Any help would be greatly appreciated.
Originally posted by NINMort on ROS Answers with karma: 3 on 2020-02-04
Post score: 0