Frames, Transforms and Arm Kinematics

Rotation matrices and homogeneous transforms, quaternions and Euler angles, forward and inverse kinematics of a two-link arm, Jacobians and singularities.

Frames and poses

Robot software is mostly bookkeeping of where things are. A frame is a coordinate system attached to something (the world, the robot, a camera, a tool), and a pose is the position and orientation of one frame relative to another. Two things are used constantly: transforming a point from one frame to another, and chaining poses (the camera relative to the base, the base relative to the world).

The standard frame tree (REP 105)mapfixed by localizationodomfixed by odometrybase_linkon the robotlasercamera_linkimu_linkjumps on correctionsmooth but driftsfixed mounting transforms →Each arrow is a transform; tf2 chains them so any node can ask where one frame is relative to another at a given time.
The standard mobile-robot frame tree; arms add a frame for each link and a tool frame at the end.
ConventionRule
UnitsMeters and radians (SI): never degrees or millimeters inside the software (REP 103)
AxesRight-handed: x forward, y left, z up; rotation positive counter-clockwise about an axis looking down on it
Naming“Pose of B in A” (TAB) transforms points from B coordinates to A coordinates
Camera framesOptical frames use z forward, x right, y down: a different convention from the robot body, so a fixed rotation links them

Transforms in 2D

In a plane a pose is (x, y, θ). A point (px, py) in the robot’s frame is at, in the world frame:

xw = x + px cos θ − py sin θ    yw = y + px sin θ + py cos θ

Worked example: where is that lidar point?

  • The robot is at (2.0, 1.0) m heading 30° in the world. A lidar is mounted 0.2 m ahead of the robot’s center (no rotation), and sees a point at (3.0, 0.5) m in the lidar frame.
  • In the robot frame: (0.2 + 3.0, 0.0 + 0.5) = (3.2, 0.5) m.
  • In the world frame: xw = 2.0 + 3.2 × cos 30° − 0.5 × sin 30° = 2.0 + 2.771 − 0.250 = 4.521 m; yw = 1.0 + 1.600 + 0.433 = 3.033 m.
  • The inverse (world to robot) rotates by −θ after subtracting the position; the inverse of the robot pose is (-2.232, 0.134, −30°): applying it to the robot’s own pose gives the origin.

Rotations in 3D: matrices, Euler angles, quaternions

In 3D an orientation has three degrees of freedom, and there are several ways to write it. Each has a use:

FormWhat it isGood forWatch out for
Rotation matrix3 × 3, orthogonal, determinant +1Rotating vectors, composing, no ambiguityNine numbers for three degrees of freedom; drifts from orthogonal if multiplied many times
Euler angles (roll, pitch, yaw)Three angles about axes in a stated orderHuman-readable input and displayThe order and axes must be stated (ROS: fixed axes x, y, z = roll, pitch, yaw); gimbal lock near pitch = ±90°
Axis-angle / rotation vectorA unit axis and an angle (or axis × angle)Robot controllers, small rotations, optimizationAngle of 0 has no defined axis
Unit quaternion (x, y, z, w)Four numbers with x² + y² + z² + w² = 1Storing, composing and interpolating (slerp) orientations; ROS messagesq and −q are the same rotation; normalize after many operations

Quaternion for a rotation of angle φ about the unit axis (ax, ay, az): q = (ax sin φ/2, ay sin φ/2, az sin φ/2, cos φ/2)

Worked example: quaternions

  • A 90° turn about z: q = (0, 0, sin 45°, cos 45°) = (0, 0, 0.7071, 0.7071).
  • Rotate the vector (1, 0, 0) with v′ = q v q−1: the result is (0.000, 1.000, 0.000): the x axis turns to the y axis.
  • Compose a 90° roll about x followed by a 90° turn about z: q = qz ⊗ qx = (0.5000, 0.5000, 0.5000, 0.5000), with length 1.0000 (still 1). Order matters: rotations do not commute, and qx ⊗ qz is a different orientation.
  • Gimbal lock: at pitch = ±90° roll and yaw turn about the same line, so only their sum is defined and a small orientation change can swing the Euler angles wildly. Quaternions and rotation matrices have no such problem: keep them internally and convert to Euler angles only for display.
import numpy as np
from scipy.spatial.transform import Rotation as R

r = R.from_euler("xyz", [90, 0, 90], degrees=True)       # roll 90, pitch 0, yaw 90 (extrinsic, ROS order)
r.as_quat()            # (x, y, z, w): the order ROS uses
r.apply([1, 0, 0])     # rotate a vector
(R.from_euler("z", 90, degrees=True) * R.from_euler("x", 90, degrees=True)).as_matrix()   # composition

Homogeneous transforms and chains of frames

A rotation R and a translation p are packed into one 4 × 4 homogeneous transform T = [R p; 0 1], so that a point in homogeneous form (x, y, z, 1) is moved by one matrix multiplication, and a chain of frames is a product of matrices: Tworld←tool = Tworld←base Tbase←arm … Twrist←tool. The inverse is simple: T−1 = [RT −RT p; 0 1].

  • Order matters: matrix products do not commute. Read a chain from the left as “from the world down to the tool”.
  • tf2 does this for you: it multiplies the transforms along the tree between any two frames at a given time (see ROS 2 in Practice).
  • Check by round trips: a point transformed to a frame and back must return unchanged; a transform times its inverse must be the identity.
  • Fixed mounts (the camera on the arm) are measured once by calibration: hand-eye calibration solves A X = X B for the unknown camera-to-gripper transform from several poses.

Forward kinematics

Forward kinematics computes the tool pose from the joint angles. For a planar arm with link lengths L1 and L2 and joint angles θ1 and θ2:

x = L1 cos θ1 + L2 cos(θ1 + θ2)    y = L1 sin θ1 + L2 sin(θ1 + θ2)

With L1 = 0.4 m, L2 = 0.3 m, θ1 = 30° and θ2 = 45°: x = 0.4 cos 30° + 0.3 cos 75° = 0.3464 + 0.0776 = 0.4241 m; y = 0.2000 + 0.2898 = 0.4898 m. Forward kinematics always has exactly one answer.

  • For a general arm describe each joint with four numbers, the Denavit-Hartenberg (DH) parameters (link length a, twist α, offset d, angle θ), and multiply the four-by-four matrices: the URDF or MoveIt does this from the robot description.
  • The zero position of each joint and its direction of positive rotation must match between the model and the real robot; a sign error here is the most common cause of an arm that moves the wrong way.
  • Joint encoders give the angles: the accuracy of the tool position is the sum of the angle errors times the link lengths, plus the errors in the link lengths themselves (calibrate them).

Inverse kinematics

Two solutions to reach one point (inverse kinematics)elbow down: θ₁ = -11.5°, θ₂ = 80.4°elbow up: θ₁ = 55.1°, θ₂ = -80.4°target (0.5, 0.2) mL₁ = 0.4 m, L₂ = 0.3 mcos θ₂ = (x² + y² − L₁² − L₂²) ÷ (2 L₁ L₂)= (0.29 − 0.16 − 0.09) ÷ 0.24 = 0.167
The same target reached with the elbow down and the elbow up: inverse kinematics usually has several solutions.

Inverse kinematics (IK) finds the joint angles that put the tool at a given pose. It is harder: there may be no solution, one, several or infinitely many.

Worked example: reaching a point with two links

  • Target (0.5, 0.2) m, so x² + y² = 0.29. From the law of cosines: cos θ2 = (0.29 − 0.16 − 0.09) ÷ (2 × 0.4 × 0.3) = 0.167, so θ2 = ±80.4°.
  • Elbow down (θ2 positive): θ1 = atan2(y, x) − atan2(L2 sin θ2, L1 + L2 cos θ2) = -11.5°, θ2 = 80.4°. Elbow up: θ1 = 55.1°, θ2 = -80.4°.
  • Check with forward kinematics: the elbow-down angles give (0.5000, 0.2000) m: the target.
  • Reachability: the tool can only reach distances between |L1 − L2| = 0.1 m and L1 + L2 = 0.7 m. A target 0.81 m away is out of reach: |cos θ2| > 1 and the formula has no solution.
  • Closed-form solutions exist for common arms (a six-axis arm with a spherical wrist has up to eight); they are fast and give all the solutions: choose the one nearest the current joints, within limits and clear of obstacles.
  • Numerical IK iterates from a starting guess using the Jacobian (next section) and finds one solution: used for arms without a closed form and for redundant arms (KDL, TRAC-IK, IKFast, MoveIt’s solvers).
  • Always check the result with forward kinematics, the joint limits and collisions.

Worked example: numerical IK converges

Start from θ1 = 0.1 rad and θ2 = 0.8 rad (a good guess, away from the straight-arm singularity) and repeat Δθ = J−1 × (target − current position). The position error after each iteration:

IterationDistance to the target
00.11292643 m
10.04898001 m
20.00249292 m
30.00000780 m
40.00000000 m

The error shrinks very fast (Newton’s method, see Numerical Methods) and the iteration lands on θ1 = -11.5°, θ2 = 80.4°: the elbow-down solution, because that is the one nearest the start. Near a singularity J−1 blows up, so practical solvers use a damped pseudo-inverse.

The Jacobian: velocities, forces and singularities

The Jacobian J relates joint velocities to tool velocity: v = J q̇. For the two-link arm:

J = [ −L1 sin θ1 − L2 sin(θ1+θ2), −L2 sin(θ1+θ2) ; L1 cos θ1 + L2 cos(θ1+θ2), L2 cos(θ1+θ2) ]    det J = L1 L2 sin θ2

Worked example: speed, force and the singularity

  • Tool velocity. At the elbow-down pose above, joints turning at ω1 = 0.5 and ω2 = 0.2 rad/s move the tool at v = (-0.156, 0.272) m/s, a speed of 0.313 m/s.
  • Joint torques for a tool force. The same Jacobian transposed converts a tool force into joint torques: τ = JT F. Holding 10 N downward (F = (0, −10) N) needs τ1 = -5.00 N·m and τ2 = -1.08 N·m (the signs show direction; the sizes are the static torques the motors must supply to hold the load, before adding the arm’s own weight).
  • Singularity. det J = L1 L2 sin θ2 = 0.1183 here (0.1183 from the matrix: the same). When θ2 = 0° or 180° the arm is straight or folded and det J = 0: the tool cannot move along the arm, and the Jacobian cannot be inverted.
θ₂det J = L₁ L₂ sin θ₂Fraction of the best
90°0.1200100 %
45°0.084971 %
10°0.020817 %
1°0.00212 %

Near a singularity the joints must move enormously for a small tool motion. To move the tool at 0.2 m/s perpendicular to the arm needs roughly ω = v ÷ (L1 sin θ2): 0.50 rad/s at θ2 = 90°, but 5.74 rad/s at 5°. Planners avoid the neighbourhood of singularities, and controllers limit joint speed there.

  • Manipulability √det(J JT) measures how far a pose is from a singularity: maximize it when choosing among IK solutions.
  • Damped least squares: q̇ = JT (J JT + λ² I)−1 v stays finite at a singularity at the cost of a small error in the tool motion.
  • Orientation Jacobian: a full arm has a 6 × n Jacobian (three linear and three angular velocities).

Six-axis arms, redundancy and joint limits

TaskDegrees of freedom needed
Position only (x, y, z)3
Position and orientation of a rigid tool6
A planar arm placing a point (x, y)2
A 7-joint arm (one redundant)7: infinitely many solutions for a pose
  • Six joints are enough to reach any position and orientation inside the workspace; the typical industrial arm has six (see Industrial Robotics).
  • A spherical wrist (three joint axes meeting at a point) lets the position and orientation problems separate, giving the closed-form IK.
  • Redundant arms (seven joints, or a mobile manipulator) have extra freedom, used to avoid obstacles, singularities and joint limits (null-space control).
  • Joint limits and self-collision reduce the usable workspace and remove some IK solutions; the planner must check them.
  • Wrist and shoulder singularities appear in every six-axis arm (wrist axes aligned, arm stretched, wrist over the base): programs that pass near them slow down or stop (see the singularity messages in your robot’s manual).
  • Joint space versus Cartesian moves: a joint move goes in a curve in space and never meets a singularity; a straight-line Cartesian move needs IK at every point and can fail.

Kinematics in practice: tf2, MoveIt and calibration

  • Describe the robot once in a URDF with accurate link lengths and joint axes (see Simulation and Digital Twins); robot_state_publisher turns joint states into the frame tree.
  • MoveIt 2 uses the URDF for forward and inverse kinematics, collision checking and motion planning (OMPL, Pilz, STOMP).
  • Calibrate: real link lengths and joint zero offsets differ from the CAD by fractions of a millimeter and a degree; a few millimeters of tool error at a meter’s reach come from 0.2° of joint error (1 m × 0.0035 rad = 3.5 mm). Industrial robots are calibrated at the factory; for others use a measuring arm or a laser tracker.
  • Hand-eye calibration finds the camera pose relative to the gripper or the base, so that an object found in an image can be reached.
  • Test with a pose you can check: command the tool to a point you can measure (a corner of a fixture) and compare.
  • Name every frame clearly and draw the tree: most “wrong place” bugs are a transform applied in the wrong direction or the wrong frame.

Related

FAQ

Should I use Euler angles or quaternions?

Use quaternions (or rotation matrices) in software and for storing and composing orientations; use Euler angles only for people to read and type. Always state the order and the axes.

Why does my inverse kinematics return no solution?

The target is outside the reachable workspace, at a distance the arm cannot reach, an orientation the wrist cannot make, or a pose that violates a joint limit. Check the reach, then the limits.

What is a singularity and why does the arm slow down?

A pose where the Jacobian cannot be inverted: the arm loses the ability to move in some direction, and the joint speeds needed for a small tool motion become huge. Controllers slow or stop there; planners avoid it.

How do I know a transform is in the right direction?

Test it with a point you can place by hand. A transform TAB maps B coordinates into A; if the result is rotated or mirrored the wrong way, you have used the inverse.

References

  • Craig, J. J., Introduction to Robotics: Mechanics and Control; Spong, M. W., Hutchinson, S. and Vidyasagar, M., Robot Modeling and Control.
  • Murray, R. M., Li, Z. and Sastry, S. S., A Mathematical Introduction to Robotic Manipulation; Lynch, K. M. and Park, F. C., Modern Robotics (free online).
  • ROS REP 103 and REP 105; MoveIt 2 and tf2 documentation; Kuipers, J. B., Quaternions and Rotation Sequences.

Last reviewed: October 2026. All values are computed in the page builder; check sign and zero conventions against your own robot.