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
4648namespace 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 */
5860template <class T >
5961void 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 */
6793template <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 */
74103template <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 */
81113template <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 */
129143template <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 */
138162template <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 */
148196template <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 */
168209inline
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 */
185228inline
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