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

How to create new tf2::convert specialization?

asked 2018-05-02 13:36:00 -0500

seanarm gravatar image

Before you point me to tutorials, I've seen all the existing ones and have looked at tf2_eigen.h and tf2_bullet.h as examples. I created a new header file in my package, named tf2_range.hpp with contents:

namespace tf2
{
inline
geometry_msgs::PointStamped toMsg(const sensor_msgs::Range& in)
{
    geometry_msgs::PointStamped out;
    out.header.stamp = in.header.stamp;
    out.header.frame_id = in.header.frame_id;
    out.point.y = out.point.z = 0;
    out.point.x = in.range;
    return out;
}

inline
void fromMsg(const sensor_msgs::Range& in, geometry_msgs::PointStamped& out)
{
    out.header.stamp = in.header.stamp;
    out.header.frame_id = in.header.frame_id;
    out.point.y = out.point.z = 0;
    out.point.x = in.range;
}

}

In a cpp file in that package, I include the header and call tf2::convert(range, pointStamped), resulting in the error:

CMakeFiles/sensor_fusion_node.dir/src/sensor_fusion.cpp.o: In function `void tf2::convert<sensor_msgs::Range_<std::allocator<void> >, geometry_msgs::PointStamped_<std::allocator<void> > >(sensor_msgs::Range_<std::allocator<void> > const&, geometry_msgs::PointStamped_<std::allocator<void> >&)':
sensor_fusion.cpp:(.text._ZN3tf27convertIN11sensor_msgs6Range_ISaIvEEEN13geometry_msgs13PointStamped_IS3_EEEEvRKT_RT0_[_ZN3tf27convertIN11sensor_msgs6Range_ISaIvEEEN13geometry_msgs13PointStamped_IS3_EEEEvRKT_RT0_]+0x1f): undefined reference to `void tf2::impl::Converter<true, true>::convert<sensor_msgs::Range_<std::allocator<void> >, geometry_msgs::PointStamped_<std::allocator<void> > >(sensor_msgs::Range_<std::allocator<void> > const&, geometry_msgs::PointStamped_<std::allocator<void> >&)'
collect2: error: ld returned 1 exit status
make[2]: *** [/home/dev/src/rosws/devel/.private/sensor_fusion/lib/sensor_fusion/sensor_fusion_node] Error 1
make[1]: *** [CMakeFiles/sensor_fusion_node.dir/all] Error 2
make: *** [all] Error 2

What's undefined about the way I'm handling this?

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2018-05-02 14:19:22 -0500

seanarm gravatar image

Going to answer my own question here-- tf2 tutorials don't make it abundantly clear that you're not allowed to create a convert() specialization consisting of two ROS messages. Here's the reasoning (from tf2/impl/convert.h):

// The case where both A and B are messages should not happen: if you have two
// messages that are interchangeable, well, that's against the ROS purpose:
// only use one type. Worst comes to worst, specialize the original convert
// function for your types.
// if B == A, the templated version of convert with only one argument will be
// used.
//
//template <>
//template <typename A, typename B>
//inline void Converter<true, true>::convert(const A& a, B& b);

Not sure I agree with the design decision, but it's easy enough to write my own convert function for my specific purpose, so why argue?

edit flag offensive delete link more
1

answered 2018-05-02 15:31:54 -0500

tfoote gravatar image

A Point and a Range message are not isomorphic. This is why they are in different messages. Your converters lose a lot of information going from the Range to a Point. Thus it's not a conversion but a projection. You should not create conversion methods like this that are not isomorphic. If there are two of these defined it's possible for the template logic to traverse through a pair of these and return completely invalid data.

I'd recommend that you write your function as projectRangeToPoint as you're dropping information and casting it down to just a point in 3D. If you were to write the inverse function you would need to add arguments to fill in the rest of the Range fields.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2018-05-02 13:36:00 -0500

Seen: 243 times

Last updated: May 02 '18