Skip to content

Commit 00ed4e5

Browse files
committed
[2/7] Complete rework: convert.h
1 parent 130face commit 00ed4e5

File tree

2 files changed

+653
-98
lines changed

2 files changed

+653
-98
lines changed

tf2/include/tf2/convert.h

Lines changed: 118 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -26,85 +26,95 @@
2626
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2727
// POSSIBILITY OF SUCH DAMAGE.
2828

29-
/** \author Tully Foote */
29+
/** \author Tully Foote, Bjarne von Horn */
3030

3131
#ifndef TF2__CONVERT_H_
3232
#define TF2__CONVERT_H_
3333

3434
#include <algorithm>
3535
#include <array>
36+
#include <builtin_interfaces/msg/time.hpp>
37+
#include <geometry_msgs/msg/transform_stamped.hpp>
38+
#include <rosidl_runtime_cpp/traits.hpp>
3639
#include <string>
3740

38-
#include "builtin_interfaces/msg/time.hpp"
39-
#include "geometry_msgs/msg/transform_stamped.hpp"
40-
#include "rosidl_runtime_cpp/traits.hpp"
41-
#include "tf2/exceptions.h"
42-
#include "tf2/impl/convert.h"
43-
#include "tf2/transform_datatypes.h"
44-
#include "tf2/visibility_control.h"
41+
#include "exceptions.h"
42+
#include "impl/convert.h"
43+
#include "impl/stamped_traits.hpp"
44+
#include "time.h"
45+
#include "transform_datatypes.h"
46+
#include "visibility_control.h"
4547

4648
namespace tf2
4749
{
48-
49-
/**\brief The templated function expected to be able to do a transform
50+
/** \brief The templated function expected to be able to do a transform.
5051
*
5152
* This is the method which tf2 will use to try to apply a transform for any given datatype.
52-
* \param data_in[in] The data to be transformed.
53-
* \param data_out[inout] A reference to the output data. Note this can point to data in and the method should be mutation safe.
54-
* \param transform[in] The transform to apply to data_in to fill data_out.
53+
* \param[in] data_in The data to be transformed.
54+
* \param[in,out] data_out A reference to the output data. Note this can point to data in and the method should be mutation safe.
55+
* \param[in] transform The transform to apply to data_in to fill data_out.
56+
* \tparam T The type of the data to be transformed.
5557
*
5658
* This method needs to be implemented by client library developers
5759
*/
5860
template<class T>
5961
void doTransform(
60-
const T & data_in, T & data_out,
61-
const geometry_msgs::msg::TransformStamped & transform);
62+
const T & data_in, T & data_out, const geometry_msgs::msg::TransformStamped & transform)
63+
{
64+
using TransformType = typename impl::DefaultTransformType<T>::type;
65+
TransformType t;
66+
tf2::fromMsg<>(transform.transform, t);
67+
data_out = t * data_in;
68+
}
69+
70+
/** \brief The templated function expected to be able to do a transform.
71+
*
72+
* This is the method which tf2 will use to try to apply a transform for any given datatype.
73+
* Overload for tf2::Stamped\<T\> types, uses doTransform(const T&, T&, const geometry_msgs::msg::TransformStamped&).
74+
* \param[in] data_in The data to be transformed.
75+
* \param[in,out] data_out A reference to the output data. Note this can point to data in and the method should be mutation safe.
76+
* \param[in] transform The transform to apply to data_in to fill data_out.
77+
* \tparam T The type of the data to be transformed.
78+
*/
79+
template<class T>
80+
void doTransform(
81+
tf2::Stamped<T> const & data_in, tf2::Stamped<T> & data_out,
82+
const geometry_msgs::msg::TransformStamped & transform)
83+
{
84+
T tmp;
85+
doTransform(static_cast<const T &>(data_in), tmp, transform);
86+
data_out = tf2::Stamped<T>{tmp, transform.header.stamp, transform.header.frame_id};
87+
}
6288

6389
/**\brief Get the timestamp from data
6490
* \param[in] t The data input.
6591
* \return The timestamp associated with the data.
6692
*/
6793
template<class T>
68-
tf2::TimePoint getTimestamp(const T & t);
94+
inline tf2::TimePoint getTimestamp(const T & t)
95+
{
96+
return impl::StampedAttributesHelper<T>::getTimestamp(t);
97+
}
6998

7099
/**\brief Get the frame_id from data
71100
* \param[in] t The data input.
72101
* \return The frame_id associated with the data.
73102
*/
74103
template<class T>
75-
std::string getFrameId(const T & t);
104+
inline std::string getFrameId(const T & t)
105+
{
106+
return impl::StampedAttributesHelper<T>::getFrameId(t);
107+
}
76108

77109
/**\brief Get the covariance matrix from data
78110
* \param[in] t The data input.
79111
* \return The covariance matrix associated with the data.
80112
*/
81113
template<class T>
82-
std::array<std::array<double, 6>, 6> getCovarianceMatrix(const T & t);
83-
84-
/**\brief Get the frame_id from data
85-
*
86-
* An implementation for Stamped<P> datatypes.
87-
*
88-
* \param[in] t The data input.
89-
* \return The frame_id associated with the data.
90-
*/
91-
template<class P>
92-
tf2::TimePoint getTimestamp(const tf2::Stamped<P> & t)
93-
{
94-
return t.stamp_;
95-
}
96-
97-
/**\brief Get the frame_id from data
98-
*
99-
* An implementation for Stamped<P> datatypes.
100-
*
101-
* \param[in] t The data input.
102-
* \return The frame_id associated with the data.
103-
*/
104-
template<class P>
105-
std::string getFrameId(const tf2::Stamped<P> & t)
114+
std::array<std::array<double, 6>, 6> getCovarianceMatrix(const T & t)
106115
{
107-
return t.frame_id_;
116+
using traits = impl::StampedMessageTraits<T>;
117+
return covarianceRowMajorToNested(traits::getCovariance(t));
108118
}
109119

110120
/**\brief Get the covariance matrix from data
@@ -120,53 +130,86 @@ std::array<std::array<double, 6>, 6> getCovarianceMatrix(const tf2::WithCovarian
120130
return t.cov_mat_;
121131
}
122132

123-
/**\brief Function that converts from one type to a ROS message type. It has to be
124-
* implemented by each data type in tf2_* (except ROS messages) as it is
125-
* used in the "convert" function.
126-
* \param a an object of whatever type
133+
/**
134+
* \brief Function that converts from one type to a ROS message type.
135+
*
136+
* The implementation of this function should be done in the tf2_* packages
137+
* for each datatypes. Preferably in a specialization of the impl::ConversionImplementation struct.
138+
* \param[in] a an object of whatever type
139+
* \tparam A Non-message Datatype
140+
* \tparam B ROS message Datatype. The default value will be taken from impl::DefaultMessageForDatatype\<A\>::type.
127141
* \return the conversion as a ROS message
128142
*/
129143
template<typename A, typename B>
130-
B toMsg(const A & a);
144+
inline B toMsg(const A & a)
145+
{
146+
B b;
147+
impl::ConversionImplementation<A, B>::toMsg(a, b);
148+
return b;
149+
}
131150

132-
/**\brief Function that converts from a ROS message type to another type. It has to be
133-
* implemented by each data type in tf2_* (except ROS messages) as it is used
134-
* in the "convert" function.
135-
* \param a a ROS message to convert from
136-
* \param b the object to convert to
151+
/**
152+
* \brief Function that converts from one type to a ROS message type.
153+
*
154+
* The implementation of this function should be done in the tf2_* packages
155+
* for each datatypes. Preferably in a specialization of the impl::ConversionImplementation struct.
156+
* \param[in] a an object of whatever type
157+
* \param[out] b ROS message
158+
* \tparam A Non-message Datatype
159+
* \tparam B Type of the ROS Message
160+
* \return Reference to the parameter b
137161
*/
138162
template<typename A, typename B>
139-
void fromMsg(const A &, B & b);
163+
inline B & toMsg(const A & a, B & b)
164+
{
165+
impl::ConversionImplementation<A, B>::toMsg(a, b);
166+
return b;
167+
}
168+
169+
/**
170+
* \brief Function that converts from a ROS message type to another type.
171+
*
172+
* The implementation of this function should be done in the tf2_* packages
173+
* for each datatypes. Preferably in a specialization of the impl::ConversionImplementation struct.
174+
* \param[in] a a ROS message to convert from
175+
* \param[out] b the object to convert to
176+
* \tparam A ROS message type
177+
* \tparam B Arbitrary type
178+
*/
179+
template<typename A, typename B>
180+
inline void fromMsg(const A & a, B & b)
181+
{
182+
impl::ConversionImplementation<B, A>::fromMsg(a, b);
183+
}
140184

141-
/**\brief Function that converts any type to any type (messages or not).
185+
/**
186+
* \brief Function that converts any type to any type (messages or not).
187+
*
142188
* Matching toMsg and from Msg conversion functions need to exist.
143189
* If they don't exist or do not apply (for example, if your two
144190
* classes are ROS messages), just write a specialization of the function.
145-
* \param a an object to convert from
146-
* \param b the object to convert to
191+
* \param[in] a an object to convert from
192+
* \param[in,out] b the object to convert to
193+
* \tparam A Type of the object to convert from
194+
* \tparam B Type of the object to convert to
147195
*/
148196
template<class A, class B>
149-
void convert(const A & a, B & b)
150-
{
151-
impl::Converter<rosidl_generator_traits::is_message<A>::value,
152-
rosidl_generator_traits::is_message<B>::value>::convert(a, b);
153-
}
154-
155-
template<class A>
156-
void convert(const A & a1, A & a2)
197+
inline void convert(const A & a, B & b)
157198
{
158-
if (&a1 != &a2) {
159-
a2 = a1;
160-
}
199+
impl::Converter<
200+
rosidl_generator_traits::is_message<A>::value,
201+
rosidl_generator_traits::is_message<B>::value, A, B>::convert(a, b);
161202
}
162203

163-
/**\brief Function that converts from a row-major representation of a 6x6
204+
/** \brief Function that converts from a row-major representation of a 6x6
164205
* covariance matrix to a nested array representation.
165-
* \param row_major A row-major array of 36 covariance values.
206+
* \param[in] row_major A row-major array of 36 covariance values.
166207
* \return A nested array representation of 6x6 covariance values.
167208
*/
168209
inline
169-
std::array<std::array<double, 6>, 6> covarianceRowMajorToNested(const std::array<double, 36> & row_major)
210+
std::array<std::array<double, 6>, 6> covarianceRowMajorToNested(
211+
const std::array<double,
212+
36> & row_major)
170213
{
171214
std::array<std::array<double, 6>, 6> nested_array;
172215
std::array<double, 36>::const_iterator ss = row_major.begin();
@@ -177,13 +220,15 @@ std::array<std::array<double, 6>, 6> covarianceRowMajorToNested(const std::array
177220
return nested_array;
178221
}
179222

180-
/**\brief Function that converts from a nested array representation of a 6x6
223+
/** \brief Function that converts from a nested array representation of a 6x6
181224
* covariance matrix to a row-major representation.
182-
* \param nested_array A nested array representation of 6x6 covariance values.
225+
* \param[in] nested_array A nested array representation of 6x6 covariance values.
183226
* \return A row-major array of 36 covariance values.
184227
*/
185228
inline
186-
std::array<double, 36> covarianceNestedToRowMajor(const std::array<std::array<double, 6>, 6> & nested_array)
229+
std::array<double, 36> covarianceNestedToRowMajor(
230+
const std::array<std::array<double, 6>,
231+
6> & nested_array)
187232
{
188233
std::array<double, 36> row_major = {};
189234
size_t counter = 0;

0 commit comments

Comments
 (0)