Position in the full course
This is the second step of the course.
The full learning order is:
1. ROS 2 node/topic/launch review
2. TF2 frame concept
3. Static sensor frames
4. Dynamic odometry frame
5. URDF + robot_state_publisher
6. SLAM mapping
7. AMCL localization
8. Nav2 path planning
9. RViz goal navigation
10. TF2 debugging in Nav2
In Step 1, you reviewed ROS 2 nodes, topics, messages, and launch files.
In Step 2, you will learn the most important concept before writing TF2 code:
Coordinate frames and TF tree
1. Learning objectives
After this module, you should be able to:
- Explain what a coordinate frame is.
- Explain why a robot needs many coordinate frames.
- Understand the meaning of parent frame and child frame.
- Understand the meaning of a TF tree.
- Explain the difference between fixed and moving frames.
- Use
tf2_echoto check the transform between two frames. - Use
view_framesto generate a TF tree. - Use RViz2 to visualize TF frames.
- Understand the basic Nav2 frame structure:
map β odom β base_link β sensor frames
2. Suggested teaching duration
Suggested duration: 2 hours
| Time | Activity |
| ----------- | ----------------------------------------- |
| 0β15 min | Review ROS 2 publisher/subscriber concept |
| 15β35 min | Explain coordinate frames |
| 35β55 min | Explain TF tree using turtlesim |
| 55β80 min | Run official TF2 turtlesim demo |
| 80β100 min | Use tf2_echo, view_frames, and RViz2 |
| 100β115 min | Connect TF2 to Nav2 |
| 115β120 min | Summary and homework |
3. Why you need TF2
A robot has many parts:
robot body
wheels
LiDAR
camera
IMU
robot arm
gripper
Each part may have its own coordinate frame.
For example:
base_link robot body frame
base_laser LiDAR frame
camera_link camera frame
imu_link IMU frame
The robot must know where each part is located.
For example:
Where is the LiDAR relative to the robot body?
Where is the camera relative to the robot body?
Where is the robot body relative to the odometry frame?
Where is the robot relative to the map?
TF2 helps ROS 2 answer these questions.
A simple explanation is:
TF2 tells the robot the position and orientation relationship between coordinate frames.
4. What is a coordinate frame?
A coordinate frame is a local coordinate system.
It usually has:
x-axis
y-axis
z-axis
origin
orientation
For a mobile robot, a common body frame is base_link.
A simple convention is:
x-axis: forward direction
y-axis: left direction
z-axis: upward direction
For example:
z
β
|
|
o------β x
/
/
y
For a mobile robot:
x forward
y left
z up
So when the robot moves forward, it usually moves in the positive x direction of base_link.
5. Why one robot needs many frames
Imagine your AMR has a LiDAR and a camera.
The robot body frame is:
base_link
The LiDAR frame is:
base_laser
The camera frame is:
camera_link
The LiDAR may be mounted 20 cm in front of the robot center.
The camera may be mounted 30 cm above the robot body.
Therefore, the robot needs to know:
base_link β base_laser
base_link β camera_link
This information is necessary because sensor data is measured in the sensorβs own frame.
For example:
LiDAR data is measured in base_laser frame.
Camera data is measured in camera_link frame.
Robot motion is usually controlled in base_link frame.
Navigation is usually planned in map or odom frame.
TF2 allows ROS 2 to transform data from one frame to another.
6. Parent frame and child frame
A TF relationship usually has two frames:
parent frame
child frame
Example:
base_link β base_laser
This means:
base_link is the parent frame.
base_laser is the child frame.
The transform describes where base_laser is relative to base_link.
Example:
base_laser is 0.20 m in front of base_link.
base_laser is 0.15 m above base_link.
You can write this as:
parent: base_link
child: base_laser
x: 0.20
y: 0.00
z: 0.15
7. What is a TF tree?
A TF tree is a tree structure that connects all coordinate frames.
For a simple AMR, the TF tree may look like this:
map
βββ odom
βββ base_link
βββ base_laser
βββ camera_link
βββ imu_link
This tree tells ROS 2 the relationship between frames.
For example, because the tree connects map to base_laser, ROS 2 can calculate:
Where is the LiDAR in the map?
Even if there is no direct transform:
map β base_laser
ROS 2 can combine transforms:
map β odom
odom β base_link
base_link β base_laser
Therefore:
map β base_laser
can be calculated.
8. Fixed frame and moving frame
There are two important types of frames.
8.1 Fixed frame
A fixed frame does not move relative to its parent.
Example:
base_link β base_laser
The LiDAR is physically mounted on the robot body.
So the relationship between base_link and base_laser is fixed.
Another example:
base_link β camera_link
base_link β imu_link
These are usually static transforms.
8.2 Moving frame
A moving frame changes over time.
Example:
odom β base_link
The robot moves in the odometry frame, so the position of base_link relative to odom changes continuously.
Another example from turtlesim:
world β turtle1
world β turtle2
The turtles move in the world frame, so their transforms change over time.
9. Important Nav2 frames
For Nav2, you should understand these frames first:
map
odom
base_link
sensor frames
9.1 base_link
base_link is attached to the robot body.
It usually represents the main body center of the robot.
For an AMR:
base_link is usually near the center of the chassis.
The robotβs velocity command usually controls the motion of base_link.
9.2 odom
odom is the odometry frame.
It is usually continuous and smooth.
The transform is:
odom β base_link
This transform describes how the robot moves according to odometry.
Odometry may come from:
wheel encoder
IMU
visual odometry
sensor fusion
simulation odometry
9.3 map
map is the global map frame.
It is used for localization and navigation.
The transform is:
map β odom
This transform is usually provided by localization or SLAM.
For example:
AMCL publishes map β odom
SLAM Toolbox may publish map β odom
9.4 Sensor frames
Sensor frames describe where sensors are mounted.
Examples:
base_laser
camera_link
imu_link
Common static transforms are:
base_link β base_laser
base_link β camera_link
base_link β imu_link
10. Nav2 TF tree concept
A common Nav2 TF tree is:
map
βββ odom
βββ base_link
βββ base_laser
βββ camera_link
βββ imu_link
You should understand this carefully.
Meaning of each transform
| Transform | Meaning | Usually published by |
| ------------------------- | ------------------------------------------- | ------------------------------------ |
| map β odom | Global correction from localization or SLAM | AMCL or SLAM |
| odom β base_link | Robot motion from odometry | Odometry node or robot_localization |
| base_link β base_laser | LiDAR mounting position | Static transform or URDF |
| base_link β camera_link | Camera mounting position | Static transform or URDF |
| base_link β imu_link | IMU mounting position | Static transform or URDF |
Important:
In real Nav2, you usually do not manually publish
map β odomif AMCL or SLAM is already running.
11. Practice 1: Install required packages
Open a terminal:
source /opt/ros/jazzy/setup.bash
Install required packages:
sudo apt update
sudo apt install ros-jazzy-turtle-tf2-py ros-jazzy-turtlesim ros-jazzy-tf2-tools ros-jazzy-rviz2
12. Practice 2: Run the TF2 turtlesim demo
Open Terminal 1:
source /opt/ros/jazzy/setup.bash
ros2 launch turtle_tf2_py turtle_tf2_demo.launch.py
You should see two turtles.
Open Terminal 2:
source /opt/ros/jazzy/setup.bash
ros2 run turtlesim turtle_teleop_key
Use the keyboard to move the first turtle.
You should observe:
turtle1 moves by keyboard control.
turtle2 follows turtle1.
Conceptually, this demo has frames like:
world
βββ turtle1
βββ turtle2
The TF2 system knows:
world β turtle1
world β turtle2
Because both turtles are connected to world, TF2 can calculate:
turtle2 β turtle1
This allows turtle2 to know where turtle1 is.
13. Practice 3: List TF topics
Open Terminal 3:
source /opt/ros/jazzy/setup.bash
ros2 topic list
You should see topics similar to:
/tf
/tf_static
Meaning:
/tf contains dynamic transforms.
/tf_static contains static transforms.
Dynamic transforms change over time.
Static transforms usually do not change after being published.
14. Practice 4: Use tf2_echo
Use this command:
ros2 run tf2_ros tf2_echo turtle2 turtle1
This asks:
What is the transform from turtle2 to turtle1?
In other words:
Where is turtle1 relative to turtle2?
You may see output like:
Translation: [x, y, z]
Rotation: in Quaternion [x, y, z, w]
Focus first on translation:
x means forward/backward distance.
y means left/right distance.
z is usually 0 in turtlesim.
Move the turtle and observe how the transform changes.
15. Practice 5: Reverse the frame order
Try:
ros2 run tf2_ros tf2_echo turtle1 turtle2
Compare it with:
ros2 run tf2_ros tf2_echo turtle2 turtle1
These two commands are not the same.
Example:
turtle2 β turtle1
means:
Where is turtle1 relative to turtle2?
But:
turtle1 β turtle2
means:
Where is turtle2 relative to turtle1?
Teaching point:
The order of frames matters.
16. Practice 6: Generate TF tree using view_frames
Run:
ros2 run tf2_tools view_frames
This command listens to TF data and creates a PDF file.
The output file is usually:
frames.pdf
Open the PDF:
xdg-open frames.pdf
You should see a TF tree similar to:
world
βββ turtle1
βββ turtle2
Question:
Which frame is the parent frame?
Which frames are child frames?
Expected answer:
world is the parent frame.
turtle1 and turtle2 are child frames.
17. Practice 7: Visualize TF in RViz2
Open a new terminal:
source /opt/ros/jazzy/setup.bash
rviz2
In RViz2:
1. Set Fixed Frame to world.
2. Click Add.
3. Choose TF.
4. Click OK.
You should see the TF frames.
You can also add Axes display if needed.
Important:
The Fixed Frame tells RViz which frame is used as the reference frame.
For the turtlesim TF2 demo, use:
world
For Nav2, the fixed frame is usually:
map
or sometimes:
odom
depending on the current system.
18. Practice 8: Think like Nav2
Now connect the turtlesim example to Nav2.
In turtlesim:
world
βββ turtle1
βββ turtle2
In Nav2:
map
βββ odom
βββ base_link
βββ base_laser
βββ camera_link
Comparison:
| Turtlesim | Nav2 |
| -------------------------- | -------------------------------- |
| world | map or odom |
| turtle1 | base_link |
| turtle2 | another robot or target frame |
| world β turtle1 | odom β base_link |
| tf2_echo turtle2 turtle1 | checking relative frame position |
The key idea is the same:
TF2 allows one frame to understand where another frame is.
19. Common TF2 misunderstanding
Misunderstanding 1: A frame is the same as a topic
Wrong idea:
base_link is a topic.
Correct idea:
base_link is a coordinate frame.
A topic carries messages.
A frame is a coordinate system.
Misunderstanding 2: TF2 controls the robot
Wrong idea:
TF2 makes the robot move.
Correct idea:
TF2 does not control the robot.
TF2 only describes coordinate relationships.
The robot moves because a controller sends velocity commands, such as:
/cmd_vel
Misunderstanding 3: map, odom, and base_link are interchangeable
Wrong idea:
map, odom, and base_link are almost the same.
Correct idea:
map is the global reference frame.
odom is the local odometry reference frame.
base_link is attached to the robot body.
Misunderstanding 4: The frame order does not matter
Wrong idea:
tf2_echo turtle1 turtle2
is the same as:
tf2_echo turtle2 turtle1
Correct idea:
The order matters.
The transform direction changes.
20. Classroom discussion questions
- Why does a mobile robot need more than one coordinate frame?
- What is the difference between
base_linkandbase_laser? - Why is
odom β base_linka dynamic transform? - Why is
base_link β base_laserusually a static transform? - In Nav2, who usually provides
map β odom? - In Nav2, who usually provides
odom β base_link? - What is the difference between
/tfand/tf_static? - Why does RViz need a Fixed Frame?
21. Practice assignment
Assignment title
Observe and Explain a TF Tree
Task 1: Run the TF2 turtlesim demo
Run:
ros2 launch turtle_tf2_py turtle_tf2_demo.launch.py
Then control the turtle:
ros2 run turtlesim turtle_teleop_key
Task 2: Generate the TF tree
Run:
ros2 run tf2_tools view_frames
Submit a screenshot of the generated TF tree.
Task 3: Use tf2_echo
Run:
ros2 run tf2_ros tf2_echo turtle2 turtle1
Submit a screenshot of the output.
Task 4: Explain the result
Write a short explanation:
The parent frame is:
The child frames are:
The meaning of turtle2 β turtle1 is:
The transform changes when:
Task 5: Connect to Nav2
Draw a simple Nav2 TF tree:
map
βββ odom
βββ base_link
βββ base_laser
βββ camera_link
Then answer:
Which transform is dynamic?
Which transform is static?
Which transform is related to localization?
Which transform is related to odometry?
Which transforms are related to sensor mounting?
22. Mini quiz
- What is a coordinate frame?
- What is a TF tree?
- What is the parent frame in
base_link β base_laser? - What is the child frame in
base_link β base_laser? - Is
base_link β base_laserusually static or dynamic? - Is
odom β base_linkusually static or dynamic? - What does
tf2_echo turtle2 turtle1show? - What does
view_framesgenerate? - What is the usual fixed frame in Nav2 RViz?
- Why is TF2 important for Nav2?
23. Key summary
In this module, you learned that TF2 manages coordinate frame relationships.
A robot needs many frames because different parts of the robot have different coordinate systems.
A TF tree connects these frames.
For turtlesim, the tree is similar to:
world
βββ turtle1
βββ turtle2
For Nav2, the tree is usually similar to:
map
βββ odom
βββ base_link
βββ base_laser
βββ camera_link
βββ imu_link
The most important idea is:
TF2 does not move the robot. TF2 tells the robot where each frame is relative to other frames.
In the next module, you will learn how to publish static sensor frames such as:
base_link β base_laser
base_link β camera_link
base_link β imu_link