Go to the documentation of this file.00001 # TF remapper (more efficient and versatile C++ version)
00002
00003 [![License](https:
00004
00005 This package is an alternative to official ROS node [tf/tf_remap](https:
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](
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:
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:
00023 - the remapping logic is available in dynamic library `libtf_remapper_cpp.so`, class [`TfRemapper`](https:
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:
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>