At the moment, when you use tf2::convert() with two types which are not from geometry_msgs package (i.e. tf2::Vector3 and Eigen::Vector3d) linking errors can occur. See #430 for details.
This PR changes all overloads of fromMsg() and toMsg() to be template specialisations so that the correct overload is found by tf2::convert() independ of the header include order.
A Python script creates mappings between non-msgs types with forward declarations, an example of its output can be found here. The script runs with Python 2 and 3.
These mappings are picked up by tf2::convert() with some SFINAE magic, if no mapping is found a nice error message is shown:
In file included from /ws_moveit/src/geometry2/tf2/include/tf2/convert.h:36:0,
from /ws_moveit/src/geometry2/tf2/test/three_way_convert.cpp:31:
/ws_moveit/src/geometry2/tf2/include/tf2/impl/convert.h: In instantiation of ‘void tf2::impl::convertViaMessage(const A&, B&, typename std::enable_if<tf2::impl::has_no_common_msgs<A, B>::value, void*>::type) [with A = Bar::Vec3; B = Baz::Vec3; typename std::enable_if<tf2::impl::has_no_common_msgs<A, B>::value, void*>::type = void*]’:
/ws_moveit/src/geometry2/tf2/include/tf2/impl/convert.h:151:20: required from ‘static void tf2::impl::Converter<IS_MESSAGE_A, IS_MESSAGE_B>::convert(const A&, B&) [with A = Bar::Vec3; B = Baz::Vec3; bool IS_MESSAGE_A = false; bool IS_MESSAGE_B = false]’
/ws_moveit/src/geometry2/tf2/include/tf2/convert.h:51:113: required from ‘void tf2::convert(const A&, B&) [with A = Bar::Vec3; B = Baz::Vec3]’
/ws_moveit/src/geometry2/tf2/test/three_way_convert.cpp:213:22: required from here
/ws_moveit/src/geometry2/tf2/include/tf2/impl/convert.h:110:3: error: static assertion failed: Please add a tf2::BidirectionalTypeMap or tf2::UnidirectionalTypeMap specialisation for types A and B.
static_assert(! has_no_common_msgs<A, B>::value,
A typemap looks like
template<>
struct BidirectionalTypeMap<Foo::Vec3, Bar::Vec3> {
using type = geometry_msgs::Vector3;
};
template<>
struct UnidirectionalTypeMap<Foo::Vec3, Baz::Vec3> {
using type = geometry_msgs::Vector3;
};
Caveats
The signature of toMsg is changed, this will break user code.
The generated TypeMaps will be included in <tf2/convert.h>, so tf2::Vector3, KDL::Frame and friends will always be forwad defined when including <tf2/convert.h>. So maybe the TypeMaps should be split into separate headers.
Things to be done
[x] Doxygen
[ ] Further tests for three way conversions
[x] Commit history cleanup
[ ] Adapt wiki (e.g. new fromMsg/toMsg signature, how to extend three way converting)
Overview
At the moment, when you use
tf2::convert()
with two types which are not from geometry_msgs package (i.e.tf2::Vector3
andEigen::Vector3d
) linking errors can occur. See #430 for details.This PR changes all overloads of
fromMsg()
andtoMsg()
to be template specialisations so that the correct overload is found bytf2::convert()
independ of the header include order.A Python script creates mappings between non-msgs types with forward declarations, an example of its output can be found here. The script runs with Python 2 and 3. These mappings are picked up by
tf2::convert()
with some SFINAE magic, if no mapping is found a nice error message is shown:A typemap looks like
Caveats
The signature of
toMsg
is changed, this will break user code. The generated TypeMaps will be included in<tf2/convert.h>
, sotf2::Vector3
,KDL::Frame
and friends will always be forwad defined when including<tf2/convert.h>
. So maybe the TypeMaps should be split into separate headers.Things to be done
fromMsg
/toMsg
signature, how to extend three way converting)Related PRs/Issues
430
431
ros-planning/moveit#1785 ros-planning/moveit#1794