Docs menu
Rigid Body Transforms, Visually
A visual guide to rotation matrices, homogeneous coordinates and changing reference frames — the maths behind how the car's sensors, chassis and map relate in ROS 2.
Every sensor on the car reports what it sees in its own coordinate frame. The lidar says “obstacle 2 m ahead of me”, but the planner thinks in the map frame, and the steering thinks in the chassis frame. Rigid body transforms are the maths that moves a point from one frame to another without losing what it means. This guide builds the idea up in four steps, exactly the way the quiz notes do, then lands it on the car.
Rotation is a matrix
Rotating a 2D vector v = (a, b) counterclockwise by an angle θ is a linear map, so it can be written as a matrix multiplication:
The same matrix works for every vector, and that is the point: one small object, R(θ), captures “rotate by θ” for the whole plane. Matrices also chain — rotating twice is one multiplication, not two geometric constructions.
Translation is not
Now try to write “shift every point by t = (3, 2)” the same way. Is there a 2×2 matrix A with
A · (a, b) = (a + 3, b + 2) for every (a, b) in R²?
Translation slides the whole plane by the same amount. In particular it moves the origin — and that is exactly what a matrix can never do.
The answer is no. Every matrix multiplication fixes the origin: A·0 = 0, always. But our shift sends 0 → (3, 2). So L(x) = x + t is not a linear map, and no 2×2 matrix represents it. Rotation alone will never be enough to describe a sensor that is mounted somewhere on the car — we also need “somewhere”, which is a translation.
Homogeneous coordinates: the trick
The way out is to give every point a third coordinate. Embed the plane inside 3D space as the slice z = 1:
(a, b) → (a, b, 1)
Points of the plane live one unit up, on the slice z = 1. The extra coordinate is not decoration — it is what makes translation writable as a matrix.
In these homogeneous coordinates, the stubborn translation from before becomes an ordinary 3×3 matrix:
Multiply it out: the third coordinate contributes the +3 and +2, and the bottom row keeps the result on the z = 1 slice. The translation we proved was impossible in 2D is a single matrix in 3D.
One matrix does both
Rotation and translation now share one container. A 2D rigid body transform — a rotation R plus a translation t, with no scaling, shearing or bending — is
2×2 rotation block R2×1 translation column t
Read the multiplication the way the notes do: the top row is a₁₁x + a₁₂y + a₁₃ — the rotation acting on (x, y), plus the x-shift. Same for the second row. The last row just says 1 = 1, keeping us on the slice. “Rigid” means the block R is a pure rotation: lengths and angles survive, so the shape of the world is preserved — which is exactly what you want when the world is a racetrack.
Changing frames
Frames are where this pays off. A point P does not move — but its coordinates depend on which frame you read them in. If frame B is frame A rotated by θ (about the same origin), then
[P]B = R(θ)T · [P]A
Same point, two readings. The dashed lines are perpendicular projections: dropping P onto each frame's axes gives that frame's coordinates for it.
Note the transpose: rotating the vector by θ uses R(θ), but rotating the frame by θ transforms the coordinates by R(θ)ᵀ = R(−θ). The notes write the same multiplication as
[P]B′ = [cos θ −sin θ ; sin θ cos θ] · (p_x, p_y)
with the convention that the new frame is rotated clockwise by θ. Both are right; they just disagree on which way θ points. Mixing up the two conventions is the single most common source of sign errors, so always state yours.
When the frames also have offset origins, the full transform combines both pieces: rotate into the new orientation, then account for the translation of the origin — or, in homogeneous coordinates, multiply by one 3×3 matrix.
Worked example: from a lidar hit to the map
This is the pipeline the car runs on every lidar scan. The lidar detects an obstacle at p_laser = (2.0, 0.5) in the laser frame. The laser is mounted 0.3 m ahead of the chassis origin (base_link), unrotated. The car itself is at t = (1, 2) in the map, heading θ = 30°. Where is the obstacle in the map?
The obstacle is fixed in the world. What changes hands between nodes on the car is its coordinates — first in the laser frame, then base_link, then the map.
Step 1 — laser to base_link. The frames are aligned, so this is a pure translation:
p_base = p_laser + (0.3, 0) = (2.3, 0.5)
Step 2 — base_link to map. Rotate by the heading, then add the position:
p_map = R(30°) · (2.3, 0.5) + (1, 2)
So the obstacle sits at about (2.74, 3.58) in the map. In ROS 2 you never write this arithmetic yourself: the transform tree carries one transform per frame pair (a 3D translation plus rotation), and tf2 composes the chain map → base_link → laser for you. But tf2 only composes matrices — everything it does is the maths on this page.
Try it, then keep going
You do not have to take the static diagrams on faith:
- 3D Rigid Body Transform visualizer — our own interactive tool. Set a yaw, pitch, roll and translation, and watch the homogeneous transform act on a frame you can orbit. This is the same matrix as above, one dimension up.
- Vector Operations visualizer — if the matrix multiplication itself is the shaky part, warm up here first.
Both are linked from the Learning hub.
Supplemental resources
Not required for onboarding — pick whichever matches the gap you hit:
- RoboRacer Coursekit, Lecture 3: Rigid Body Transformation — the official course lecture for exactly this topic, including how frames and transforms appear in ROS.
- 3Blue1Brown: Essence of Linear Algebra — chapters 3 (linear transformations) and 13 (change of basis) are the visual intuition behind the Rotation and Changing frames sections above.
- Modern Robotics (Lynch & Park, Northwestern) — the free textbook and video series when you want the full 3D treatment with screw theory; where the 3×3 here grows into the 4×4 used on the real stack.
- ROS 2 Humble: Introducing tf2 — the practical half: the transform tree that carries this maths on our car, which runs ROS 2 Humble.