Using tf/tf2 in ROS
tf and tf2 are ROS packages that handles frame transformation in the time frame. This means, we can get information about “What is the relative pose of Frame B with respect to Frame A at 10 seconds ago.” Frame transformation is extremely important in robotics as a robot itself typically consist of several frames, such the base_link frame of the robot, frames of multiple links (particularly the moving ones) of the robot, and frames of the sensors (camera, LiDAR, etc). The data obtained by a sensor is typically expressed with respect to the sensor’s frame. To conveniently define the motion of the robot, the reference of the acquired data should be transformed from the sensor’s frame to the robot’s frame.
In a mobile robot, the motion of the robot is typically expressed with respect to an odometry frame (a frame indicating where the robot starts) or a map frame. Hence, it is required to evaluate the transformation between the map frame and the odometry frame, and between the map frame and the robot’s frame or a sensor’s frame.
A frame is defined by a Cartesian axes X, Y, and Z with directions following the right-hand rule: X, Y, and Z are along the index finger, the middle finger, and the thumb of your right hand, respectively. The X, Y, and Z axes are indicated by red, green, and blue axes, respectively. The mnemonic for this is RGB, a very familiar term in computer vision.
tf is the earlier generation of frame transformation package in ROS. Since ROS Hydro, tf is “deprecated” in favor of tf2. tf2 is an iteration on tf providing generally the same feature set more efficiently. As well as adding a few new features.
robot_state_publisher
The “robot_state_publisher” node is a node that transforms the joint states (published by the “joint_state_controller” or “joint_state_publisher” node) to the transforms of all the links in the robot. Hence, both the “joint_state_controller” or “joint_state_publisher” node and the “robot_state_publisher” needs to be run when starting a robot (or a robot simulator). This is commonly performed by using a launch file like this:
1 2 3 4 5 |
<launch> <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="joint_state_controller"/> <node pkg="robot_state_publisher" type="state_publisher" name="robot_state_publisher"/> </launch> |
or:
1 2 3 4 |
<launch> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher"/> <node pkg="robot_state_publisher" type="state_publisher" name="robot_state_publisher"/> </launch> |
The “robot_state_publisher” can also be run by using the following CLI command:
1 |
rosrun robot_state_publisher robot_state_publisher |
static_transform_publisher: Create and publish a static transform between a child frame and a parent frame at a certain frequency/period. The static transform is published in “/tf_static” topic.
Using “tf”:
- Using Euler angles: static_transform_publisher x y z yaw pitch roll parent_frame child_frame period_in_ms
- Using quaternions: static_transform_publisher x y z qx qy qz qw parent_frame child_frame period_in_ms
The argument “period_in_ms” above is optional.
static_transform_publisher can also be used in a launch file. It looks like this:
1 2 3 |
<launch> <node pkg="tf" type="static_transform_publisher" name="link1_broadcaster" args="1 0 0 0 0 0 1 link1_parent link1 100" /> </launch> |
or without specifying the frequency it looks like this:
1 2 3 |
<launch> <node pkg="tf" type="static_transform_publisher" name="link1_broadcaster" args="1 0 0 0 0 0 1 link1_parent link1" /> </launch> |
Using “tf2”:
- Using Euler angles: static_transform_publisher x y z yaw pitch roll parent_frame child_frame
- Using quaternions: static_transform_publisher x y z qx qy qz qw parent_frame child_frame
static_transform_publisher can also be used in a launch file. It looks like this:
1 2 3 |
<launch> <node pkg="tf2_ros" type="static_transform_publisher" name="link1_broadcaster" args="1 0 0 0 0 0 1 link1_parent link1" /> </launch> |
You can see that the main difference between using “tf” and “tf2” is basically just the name of the package.
Other tf-related CLI commands
tf_monitor: Print information about the current coordinate transform tree to console (terminal).
tf_echo <source_frame> <target_frame>: Print information about a particular transformation between a source_frame and a target_frame. For example, to echo the transform between /map and /odom:
1 |
rosrun tf tf_echo /map /odom |
rosrun tf view_frames: Create a PDF graph of your current transform tree.
roswtf: tf diagnostic tool.