{{{#!wiki tip Using ROS 2? Check out the [[https://docs.ros.org/en/rolling/Tutorials/Intermediate/Tf2/Tf2-Main.html|ROS 2 tf2 tutorials]]. }}} ## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = Create Data Conversion Package (Python) ## multi-line description to be displayed in search ## description = This tutorial will teach you how to create the methods required to convert Python datatypes using the tf2 convert methods. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= ## next.1.link= ## what level user is this tutorial for ## level= IntermediateCategory ## keywords = #################################### <> == Background == To use the tf2_ros Python conversion methods you must define functions which will convert to and from a message datatype. Note that all the message datatypes must be `Stamped` which includes the `timestamp` and `frame_id` fields. And because we're not leveraging the C++ compiler template logic we must register the conversion function. == Required Methods for Automatic Conversion == You must define a function which will take a message as an argument and it will return the equivalent datatype wrapped in the `tf2_ros.Stamped` datatype. For example: {{{#!python def from_msg_vector(msg): vector = PyKDL.Vector(msg.point.x, msg.point.y, msg.point.z) return tf2_ros.Stamped(vector, msg.header.stamp, msg.header.frame_id) }}} Then you must register this function as a from_msg converter. {{{#!python tf2_ros.ConvertRegistration().add_from_msg(PyKDL.Vector, from_msg_vector) }}} For the other side you must implement a method that coverts from the custom datatype into a message. {{{#!python def to_msg_vector(vector): msg = PointStamped() msg.header = vector.header msg.point.x = vector[0] msg.point.y = vector[1] msg.point.z = vector[2] return msg }}} And register the conversion in this direction too. {{{#!python tf2_ros.ConvertRegistration().add_to_msg(PyKDL.Vector, to_msg_vector) }}} == Required Methods for Transforming Custom Datatypes == To support transforming custom datatypes you must provide a template specialization of the method doTransform defined in `tf2/convert.h` {{{#!cpp template void doTransform(const T& data_in, T& data_out, const geometry_msgs::TransformStamped& transform); }}} For example [[https://github.com/ros/geometry_experimental/blob/indigo-devel/tf2_kdl/include/tf2_kdl/tf2_kdl.h#L81| in tf2_kdl]] it looks like this: {{{#!cpp template <> inline void doTransform(const tf2::Stamped& t_in, tf2::Stamped& t_out, const geometry_msgs::TransformStamped& transform) { t_out = tf2::Stamped(transformToKDL(transform) * t_in, transform.header.stamp, transform.header.frame_id); } }}} == Use in code == With these methods defined you can use `tf2::convert` to go between a message and any datatype with these methods defined. And using slightly more logic it can actually convert between any two datatypes with a mutual message datatype intermediary. The other place that this can be leveraged is that the tf2_ros API is entirely templated such that you can pass any supported datatype as an input and ask for any datatype with the above conditions as an output and it will work. == Recommendations for Implementers == This approach has been chosen to allow the core package to remain with as few dependencies as necessary. It is recommended to create standalone packages to support these conversions which have the minimum dependencies of the message package, the package with the definition of the datatype, and if necessary the minimum libraries necessary to implement the transform. The convention for these packages is `tf2_MESSAGE_DATATYPE_PACKAGE_NAME` such as [[tf2_kdl]], [[tf2_eigen]], and [[tf2_bullet]]. These are also good example implementation packages for reference. ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## LearningCategory ## PythonCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE