README.md
Go to the documentation of this file.
00001 # TF remapper (more efficient and versatile C++ version)
00002 
00003 [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![codecov](https://codecov.io/gh/tradr-project/tf_remapper_cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/tradr-project/tf_remapper_cpp)
00004 
00005 This package is an alternative to official ROS node [tf/tf_remap](https://github.com/ros/geometry/blob/melodic-devel/tf/scripts/tf_remap) with the following advantages:
00006 
00007 - Works natively with **TF2**
00008     - that could probably save a few data conversions
00009 - **Performance**: handles tens of TF subscribers with thousands of TF messages/sec with ease
00010     - the official node fully utilizes 2 i7 CPU cores if you have 10 subscribers and publish 2000 TF messages per second ([ros/geometry#175](//github.com/ros/geometry/issues/175))
00011     - this package needs about 0.4 CPU cores for the same
00012 - Can also remap **`/tf_static`**
00013     - the official package can not do that correctly
00014 - Can also **remove frames** (if you pass empty string to `new`)
00015     - this can come handy if you e.g. want to recompute your map in bagfiles using a brand new algorithm
00016 - Can **work in both ways**
00017     - not only taking frames published on `/tf_old` and remapping and publishing them to `/tf`, but it can also watch `/tf`, perform a reverse remapping, and publish new TF messages to `/tf_old`
00018     - this can come handy if you e.g. want to run your robot in a restricted world where it does not know about the other robots (it has its own `/map` frame), and then you have a multirobot coordination algorithm which wants to see the maps of each robot as `/ugv1/map`, `/ugv2/map` and so on, and also wants to publish a `/global_map` frame available to all robots.
00019 - Backwards **compatible with [tf/tf_remap](https://github.com/ros/geometry/blob/melodic-devel/tf/scripts/tf_remap)**
00020     - to use this remapper, just change package name from `tf` to `tf_remapper_cpp` in your launch files
00021     - all the new functionality should not endanger the basic usage, since the package is accompanied by an exhaustive test suite
00022 - [API Documentation](https://tradr-project.github.io/tf_remapper_cpp/md_README.html) and [usage examples](#example-usage-in-launch-files)
00023     - the remapping logic is available in dynamic library `libtf_remapper_cpp.so`, class [`TfRemapper`](https://tradr-project.github.io/tf_remapper_cpp/classtf__remapper__cpp_1_1TfRemapper.html)
00024 
00025 ## Nodes
00026 
00027 ### tf\_remapper\_cpp/tf\_remap
00028 
00029 The node that performs the TF remapping.
00030 
00031 #### Private parameters
00032 
00033 - **`mappings`** (`array of dicts`): The rules for TF frame name remapping, e.g. `[{"old": "b", "new": "d"}]`. Each dict presents one remapping rule. Each dict contains keys `old` and `new`. If either of these keys is missing or its value is empty string, it means the TF frame should be deleted.
00034     - Until [ros_comm#1498](https://github.com/ros/ros_comm/issues/1498) is fixed, you can not pass this parameter from `rosrun` commandline - either set it in a launch file, or use `rosparam set /tf_remapper/mappings '[{"old": "b", "new": "d"}]'` before launching this node.
00035 - **`static_tf`** (`bool`): Whether the remapper acts on static TFs or not. If not set, it is autodetected from `new_tf_topic_name` parameter.
00036     - Static TFs need special handling, so be sure to have this parameter set correctly, otherwise it can cause performance issues (when used with non-static TFs) or incorrect operation (if not used with static TFs).
00037     - Autodetection checks if the `new_tf_topic_name` is `tf_static` or `/tf_static`, and if it is, then `static_tf` is set to `True`, otherwise it is set to `False`.
00038 - **`old_tf_topic_name`** (`string`, default `'/tf_old'`): The topic on which old TFs are subscribed.
00039 - **`new_tf_topic_name`** (`string`, default `'/tf'`): The topic on which remapped TFs are published.
00040 - **`is_bidirectional`** (`bool`, default `False`): If `True`, the remapper will also allow passing TFs published on the "remapped end" to the "old end" via a reverse mapping. 
00041     - Pay special attention if you use any kind of multimaster solution or a custom topic transport. This node needs CallerIDs to be unchanged. If this contract is broken, the node will probably enter an infinite loop reacting to its own published messages.
00042 
00043 #### Subscribed topics
00044 
00045 - **`/tf_old`** (or any other topic set in `old_tf_topic_name`; type `tf2_ros/TFMessage`): The original TF messages that are to be remapped.
00046 - **`/tf`** (or any other topic set in `new_tf_topic_name`; only if `is_bidirectional == True`; type `tf2_ros/TFMessage`): The TF messages with remapped frames. If some node publises to this topic and this remapper is running in bidirectional mode, it sends the newly published transforms back to `/tf_old`.
00047 
00048 #### Published topics
00049 
00050 - **`/tf`** (or any other topic set in `new_tf_topic_name`; type `tf2_ros/
00051 TFMessage`): The TF messages with remapped frames.
00052 - **`/tf_old`** (or any other topic set in `old_tf_topic_name`; only if `is_bidirectional == True`; type `tf2_ros/TFMessage`): The original TF messages. If some node publises to `/tf` and this remapper is running in bidirectional mode, it sends the newly published transforms back to this topic.
00053 
00054 ## Example usage in launch files
00055 
00056 ### simple.launch
00057 
00058     <launch>
00059         <group>
00060             <remap from="tf" to="tf_old" />
00061             <!-- The tf(1) static_transform_publisher does not use /tf_static, but periodically publises to /tf -->
00062             <node name="broadcaster_ab" pkg="tf" type="static_transform_publisher" args="1 2 3 4 5 6 a b 10"/>
00063             <!-- Usually, there would be e.g. a rosbag play instead of the static tf publisher. -->
00064         </group>
00065 
00066         <node name="remapper" pkg="tf_remapper_cpp" type="tf_remap">
00067             <rosparam param="mappings">[{old: b, new: c}]</rosparam>
00068         </node>
00069 
00070         <!-- This node will see transform a->c -->
00071         <node name="my_node" pkg="my_pkg" type="node_type" />
00072     </launch>
00073     
00074 ### static_tf.launch
00075 
00076     <launch>
00077         <group>
00078             <remap from="tf_static" to="tf_static_old" />
00079             <!-- The tf2 static_transform_publisher uses /tf_static -->
00080             <node name="broadcaster_ab" pkg="tf2_ros" type="static_transform_publisher" args="1 2 3 4 5 6 a b"/>
00081             <!-- Usually, there would be e.g. a rosbag play instead of the static tf publisher. -->
00082         </group>
00083 
00084         <node name="remapper" pkg="tf_remapper_cpp" type="tf_remap">
00085             <rosparam param="mappings">[{old: b, new: c}]</rosparam>
00086             <!--<param name="static_tf" value="true" />  - this is not needed, autodetection works in this case -->
00087         </node>
00088 
00089         <!-- This node will see static transform a->c -->
00090         <node name="my_node" pkg="my_pkg" type="node_type" />
00091     </launch>
00092     
00093 ### bidirectional.launch
00094 
00095     <launch>
00096         <group>
00097             <remap from="tf" to="tf_old" />
00098             <!-- The tf(1) static_transform_publisher does not use /tf_static, but periodically publises to /tf -->
00099             <node name="broadcaster_ab" pkg="tf" type="static_transform_publisher" args="1 2 3 4 5 6 a b 10"/>
00100             <!-- Usually, there would be e.g. a rosbag play instead of the static tf publisher. -->
00101             
00102             <!-- This node will see transforms a->b and d->e -->
00103             <node name="my_node2" pkg="my_pkg" type="node_type" />
00104         </group>
00105 
00106         <node name="remapper" pkg="tf_remapper_cpp" type="tf_remap">
00107             <rosparam param="mappings">[{old: b, new: c}, {old: e, new: f}]</rosparam>
00108             <param name="is_bidirectional" value="true" />
00109         </node>
00110 
00111         <!-- This node will see transforms a->c and d->f -->
00112         <node name="my_node" pkg="my_pkg" type="node_type" />
00113         
00114         <node name="broadcaster_df" pkg="tf" type="static_transform_publisher" args="1 2 3 4 5 6 d f 10"/>
00115     </launch>


tf_remapper_cpp
Author(s): Martin Pecka
autogenerated on Tue Mar 19 2019 09:29:23