We present here the concept of frames and their operations. Frames are the geometrical foundation of robotic arms, and understanding how to handle them is an important step toward solving kinematic models. The framework we present has general validity, regardless of the robotic structure we need to solve.

## Reference Frames

**frame**is essentially a coordinate system with a specific position and orientation (see Figure 2-1). When describing the position of a generic point in space, we always need to do that relative to a specific frame. In other words, a point has different coordinates according to what frame we are using as reference.

When working with robots, we can immediately identify a few fundamental reference frames.

The **global coordinate system** (or world coordinate system) defines the origin and orientation of our world. When your space includes several machines and robots, it is always important to define a unique global reference system, so that everyone understands the same global coordinates.

**local coordinate system**(or machine coordinate system). That is convenient when programming individual robots: other machines will not see this system and will not understand coordinates specified in this frame. Of course, if you work with only one robot, then you can let the global and local coordinate systems coincide.

For example, the three robots in Figure 2-2 are all placed at the origin *O* = [0 0 0] of their local (purple) reference frames. But their positions in the global (red) frame are , , and , meaning that they are all spaced two meters apart from each other along the global X axis. We will explain later how to move from one frame to another.

**tool coordinate system**, whose origin is located at the TCP of the robot (shown in yellow in Figure 2-3). In this case, we have no tool attached to the robot, so the tool coordinate system is based at the mounting point on the sixth axis.

Finally, the most meaningful frame for the operator is the **workpiece coordinate system** (shown in blue in Figure 2-3). This frame is what the robot’s operator sees and considers as the origin of its workspace: all the programmed points and movements refer to this system. It is often also called product coordinate system, and there are actually several of them in a normal working cell, because the robot performs tasks on a multitude of products, each of them having its own unique origin and orientation.

We now need to understand how to move from one frame to another one and how to transform coordinate points across different frames.

## Frame Operations

*F*

_{1}, the other based in frame

*F*

_{2}, and they are both looking at the same point in space. The first observer will measure the point with coordinates

*P*

_{1}and the second with coordinates

*P*

_{2}(see Figure 2-4).

In the previous section, we learned that robotic applications express their target positions in several different coordinate systems. Therefore, a typical requirement is how do we find the position of that point from the perspective of frame *F*_{2} if we already know its position in frame *F*_{1}?

In order to find a way to convert from *P*_{1} to *P*_{2}, we need to know how the two original frames *F*_{1} and *F*_{2} are related to each other. This is where frame operations come into play.

## Frame Translations

Let’s start with translations, considering the example in Figure 2-6. We are based in frame *F*_{1} and observe the blue point. Its position from this perspective is . Let’s use some numeric values to make the understanding easier. Assume .

*F*

_{2}, which is translated by an

**offset**. The same blue point seen from this perspective has a different position, which we call . Make sure you understand the meaning of this operation here: the physical point in space (the blue point) is absolutely the same, regardless of the observation frame, and has not moved. However, our observation base has moved, so the point’s coordinates in our new frame (

*P*

_{2}) are different than those in the old frame (

*P*

_{1}).

Translation is a linear operation and the formula is very simple: *P*_{2} = ∆ + *P*_{1}.

Keep in mind that we are now basing our observation point in frame *F*_{2}, so *the value of the offset* ∆ *is also measured from the F*_{2} *frame’s perspective*. In other words, the offset ∆ expresses how the old frame *F*_{1} is seen from the new frame *F*_{2}. To continue our numerical example, let’s use , i.e., a negative offset along the Y axis.

*Intuitively, you can think as starting from the origin of F*_{2}, *first moving back to the origin of F*_{1}, *and then from there to P*_{1}*.*

Numerically, if the original point was and the translation offset is , then we can calculate the new point coordinates as , which can be easily verified in Figure 2-6.

## Frame Rotations

*R*, which is built according to the axis around which the frame rotates, and the angle of rotation

*θ*:

*θ*, the rotation matrix assumes the following form:

Note that we have cosines on the diagonal and sines outside of it. That is not a coincidence, because the rotation matrix reduces to the identity matrix when the angle of rotation is zero: the cosines on the diagonal are equal to 1, and the rest is 0. In other words, no rotation occurs, and clearly the final position is the same as where we started.

**right-hand rule**: if we align our right thumb along the axis of rotation, the movement of the other fingers closing on the hand’s palm shows the positive direction of rotation (see Figure 2-8).

*P*

_{1}with coordinates in frame

*F*

_{1}. We then rotate the frame around the vertical Z axis by an angle of 90 degrees.

Note that the rotation angle expresses how the old frame is seen from the new frame. Just like we defined the offset in case of translations, *we express the rotation angle in the new frame coordinates*. Therefore, in this case, we actually have *θ* = − 90.

*P*

_{1}, we find the new

*P*

_{2}:

If you look at the blue point from the perspective of the green rotated frame in Figure 2-9, you can verify that the calculated values are correct. For example, the position along the Y axis is now negative.

## Properties of a Rotation Matrix

A generic rotation matrix has some nice properties that are worth exploring here before we move on with frame operations.

**orthogonal matrix**. We do not need to understand all the details of orthogonal matrices, but we can list here some important results:

Given an orthogonal matrix

*R*, its transpose is equal to its inverse:

The determinant of an orthogonal matrix is always ±1.

The product of two rotation matrices is still a rotation matrix. This property is very helpful when dealing with multiple rotations as we will see in the next section. For example, if we want to rotate around the X and Y axes, we simply multiply the two matrices

*R*_{X}and*R*_{Y}to find the matrix for the entire rotation:

Products between rotation matrices are

*associative*, so you can simplify your calculations grouping them as it fits best:

However, the product is

*not**commutative*! This is a very important property, and it physically means that rotating around Z first and then X is not the same as rotating around X first and then Z:

The rule is simple: adding a new rotation requires *pre-multiplying* the existing matrix by the new rotation matrix.

## Composing Rotations: Euler Angles

So far, we have looked at rotations around a single axis. If we want to describe a more general rotation in space, we need to combine individual rotations into a multi-axis one.

Mathematically, the combination of two consecutive rotations can simply be expressed by the product of the two rotation matrices. In the most general case, a frame can be rotated in space around three axes, so we use the product between three individual matrices.

*R*as the product of the three individual rotations around the X-Y-Z axes by the angles A-B-C, respectively:

That means, we first rotate of an angle A around the X axis, then by an angle B around Y, and finally by an angle C around Z. The angles [A, B, C] are called **Euler angles**.

If you think about it, we could have selected a different order or even different combinations of rotation axes: *X-Z-Y*, or *Z-X-Z*, or many others. Those are all different valid ways of expressing a generic rotation in space. They all represent the same rotation but using different values because of the different reference system.

The particular choice we made is probably the simplest to understand, especially for operators in factories who have to program the target poses for the robot: they see the fixed base coordinate system X-Y-Z and understand A-B-C rotations to be around those axes.

The angles A-B-C in the particular notation we chose (around the base *X-Y-Z* axes) are called improper Euler angles, also known as Cardan or RPY angles (from the roll-pitch-yaw angles used in aerospace).

What is important to understand is that no matter what notation we choose, *Euler angles* *can always represent any rotation in space with only three values*. That is a major advantage in terms of convenience.

Equivalently, given any rotation matrix, we can always decompose it in three Euler angles.

From a computational point of view, composing a generic rotation matrix given three Euler angles is a very straightforward multiplication as we saw in Equation (2-14). However, decomposing the matrix into individual Euler angles is not always so easy. We will see in the next section how to do that.

## Decomposing a Rotation Matrix

Imagine we have a rotation matrix, which describes a specific rotation in space. We now want to find out the corresponding Euler angles required to achieve that rotation. This operation is calling decomposition of the matrix and is used often in the control software of a robot.

A typical application is finding the wrist axes of a six-axes robot when solving its inverse kinematic function.

Keep in mind that the result of the decomposition depends on the specific notation of angles we choose. In this paragraph, we continue with the choice of A-B-C Euler angles around the base X-Y-Z axes. The wrist joints of a six-axes robot rotate around a different set of axes (X-Y-X), so the choice of notation will be different in that case. The underlying concept is identical in all cases.

*R*

_{X}(

*A*) (a rotation of an angle A around the X axis), then pre-multiply by

*R*

_{Y}(

*B*), and finally by

*R*

_{Z}(

*C*):

The matrix looks complicated, and to simplify the notation, we expressed individual sines and cosines elements with more compact symbols. For example, *s*_{y} is the sine of the rotation angle around the Y axis: that is, the sine of B, in our case.

To directly address each element of the matrix, we use the symbol *R*_{ij}, where *i* and *j* are the row and column of the element.

Extracting the A-B-C angles from the rotation matrix works by small individual steps.

*R*

_{31}= −

*s*

_{y}. That is, the sine of B is already given, so we can quickly derive B. From a programming point of view, instead of taking the arcsine of that value, it is numerically more stable to use the arctangent function, which works well even for values of B close to zero.

Note that we can choose two different values for the cosine of B, either positive or negative. This choice will give two possible results for the final tuple A-B-C. In other words, we can reach the same global rotation with different individual rotations around the base axes. Euler angles are not unique!

Notice again how the final values of both A and C are affected by the choice of sign we initially made for B.

The practical way to solve this system is fixing an arbitrary value for one of the two angles (e.g., A = 0) and then derive the other one.

The physical meaning of a singular rotation matrix is that we can select from an infinite number of possible rotations around the individual axes to reach the final desired orientation. The best solution to select is usually determined by the movement’s actual conditions, as we will see in Chapter 5 when studying path-planning.

Note that we decomposed a rotation matrix into the A-B-C angles of rotations around the X-Y-Z axes of the fixed base frame. In case you want to decompose the same matrix into other Euler angles notations, you proceed in a very similar way, but use a different initial composition of rotation matrices.

## Column Vectors

Understanding the target rotation given a tuple of Euler angles can usually be done intuitively by visualizing the combination of the three individual rotations around the selected reference axes. On the other hand, a rotation matrix looks too abstract to visualize in practice.

That is actually not the case after we present an interesting property here: *the* *column vectors* *of a rotation matrix represent the axes of the old frame (before the rotation) as seen from the new frame (after the rotation)*.

*F*

_{1}is highlighted in red. Its coordinates in the

*F*

_{1}frame are . Now, if we want to find out the coordinates of that same vector as seen from the new frame

*F*

_{2}, we need to pre-multiply that vector by the rotation matrix

*R*. It is easy to see that the result is exactly the first column vector of the rotation matrix itself.

Similarly, we can proceed for the Y and Z axis and find the second and third columns of the matrix.

This property provides a very simple way to build a rotation matrix in practice, if we know the vector axes of a frame with respect to another one. A typical example is when a robot’s operator wants to find out what rotation a workpiece has with respect to the base of the robot: that is, the rotation between the workpiece coordinate system and the local coordinate system, as described in the Reference Frames Section. The operator can position the TCP of the robot on two points along each axis of the workpiece in order to let the system identify the axes vectors and from there immediately build the rotation matrix without any further calculation. The details are explained in Cell Calibration Section in Chapter 10 where we talk about calibrating frames in a working cell.

## Expressing Rotations

So far, we have seen two alternative ways of expressing a general rotation in space: a 3x3 rotation matrix and a three-tuple of Euler angles. We have also seen how to convert back and forth from one representation to the other.

*Simplicity*: Euler angles are very simple to understand because they can represent a generic rotation with only three angles. Rotation matrices are large and complicated: they need nine elements to represent a single rotation, and they are not at all intuitive. Not to mention that they are computationally much more expensive.*Uniqueness*: Euler angles are not uniquely defined as there are 12 different kinds of possible notations. Also, they do not provide unique solutions: many combinations of Euler angles can represent the same rotation in space. In the worst case, an infinite number of solutions are possible, as we have seen when decomposing a rotation matrix around a singularity. All that can be confusing. Rotation matrices, on the other hand, are unique.*Interpolation*: The operation of smoothly moving from one starting point to a final target point is called interpolation. We will describe the details in Chapter 5, but we anticipate here that Euler angles do not interpolate linearly. If our robot starts from a rotation and wants to reach another target rotation, we cannot simply take the Euler angles and linearly move them from start to end, like we would do for positions. The resulting movement could look totally random and wrong to an external observer. Rotation matrices are even worse: there is no practical way to interpolate between two matrices directly.

Actually, there is also other way to express rotations that we have not introduced yet: quaternions. We will present them in Chapter 5. Quaternions are somewhat in between Euler angles and rotation matrices, and they are actually the only choice when it comes to interpolations.

So, the question is which representation do we pick when developing our control software? Well, we need all of them really. Since Euler angles are simpler to understand, we normally use them for the interface to the operator (e.g., for visualization purposes). Internally, we use quaternions for interpolations (e.g., for path-planning operations) and rotation matrices for all frame operations (e.g., for kinematic transformations).

## Combining Translations and Rotations

We have first studied translations of frames and then rotations, and now we need to put them together into one individual operation to derive the most generic transformation of a frame into another.

**homogeneous matrix**: a matrix

*T*, which combines a rotation matrix

*R*and a translation offset Δ into a single transformation. The resulting combination is a 4x4 matrix, filled with zeros under the rotation matrix and with a 1 under the translational offset.

Joining the two operations together means that with a single matrix multiplication, we can perform both translation and rotation of a frame at the same time.

*θ*and then translate along the Y axis by

*δ*

_{Y}, we can use the following matrix:

*It is critical to remember that the order is not commutative: when moving from the old frame to a new one, we first rotate and then translate.*If we would first translate and then rotate, the result would be totally different (see Figure 2-11).

*Also critical is to remember that the values of the offset and rotation angles are to be expressed as seen from the new frame coordinates.*

The homogeneous matrix is a powerful tool to express generic transformation between frames. Actually, as far as industrial robots are concerned, this tool is all we need to derive geometrical models of mechanical structures.

*P*

_{1}in an old frame

*F*

_{1}and

*P*

_{2}in a new frame

*F*

_{2}; we know the value of

*P*

_{1}, and we know the transformation matrix

*T*

_{21}between

*F*

_{1}and

*F*

_{2}; the question is how to find

*P*

_{2}.

The answer is *P*_{2} = *T*_{21} *P*_{1}. Just like we used to pre-multiply by a rotation matrix to account for a frame rotation, now we pre-multiply by the entire homogeneous matrix to account for a frame rotation and translation combined.

Moving from the old *F*_{1} to the new *F*_{2}, we first rotate and then translate. The angle and offset values are measured as seen by the new frame *F*_{2}.

*P*

_{2}:

It is easy to verify that if the two frames only have a translation and no rotation in between, the elements along the diagonal of the rotation part will all be 1s and the elements outside the diagonal will be 0s. Then we fall back to a simple linear offset addition for the translational effects.

Similarly, if the translation offset vector is 0, then we only have the rotation elements left.

Just like rotation matrices can be chained multiplied together to express a series of rotations, also homogeneous matrices can build up a chain of multiplication to describe a series of generic frame transformations. We will use this property when solving the direct kinematics of robots. As usual, the resulting product is associative but not commutative.

## Example

Let’s look at a practical example to make things a bit clearer.

The position of the TCP is indicated by the blue dot, and it moves along the black curve when the rotating axis is turning. We now want to derive the actual position of the TCP referenced to the fixed robot base frame as a function of the rotating joint angle.

We start by providing some fixed geometrical parameters: the length of the arm *l* and its height *h*.

*F*

_{1}and the fixed base frame

*F*

_{0}(see Figure 2-14). The position of the TCP as seen from the mobile frame

*F*

_{1}(the robot’s moving link) is actually constant. We call it

*P*

_{1}. The position of the TCP as seen from the fixed frame

*F*

_{0}(the robot’s base) is moving. We call it

*P*

_{0}.

In order to find *P*_{0}, we need to know *P*_{1} and the transformation matrix *T*_{01} that modifies the mobile frame *F*_{1} into the fixed frame *F*_{0}. The solution will then be *P*_{0} = *T*_{01} *P*_{1}.

*P*_{1} is simple: the TCP position in frame *F*_{1} is fixed at [*l*, 0, 0].

*θ*around the Z axis and then a translation along the Z axis by an offset

*h*. Note that both

*θ*and

*h*are positive as seen from the fixed frame

*F*

_{0}. However, while

*h*is always constant, the angle

*θ*can change all the time because it is driven by the rotating joint of the robot.

*P*

_{1}by the matrix

*T*

_{01}to find

*P*

_{0}:

The solution is . These are the coordinates of the TCP as seen by an observer fixed at the base of the robot.

In such a simple example, we could have easily derived the correct answer by mere geometrical considerations. However, solving a full six-axes robot is going to be much harder, and using the homogeneous transformations is certainly more convenient.

If you have understood this example, you are a good half-way through solving the kinematic model for the six-axes robot.

## Inverted Transformation

Once you are able to transform points from one frame to another, you can also quickly learn how to perform the inverse operation. Essentially, instead of finding *P*_{1} = *T*_{10} *P*_{0}, we want to find *P*_{0} = *T*_{01}*P*_{1} = *T*_{10}^{−1} *P*_{1}. We know but we do not know how to compose *T*_{10}^{−1}.

Inverting an individual translation is as easy as simply taking the same offset in the negative direction: ∆ → − ∆.

Inverting an individual rotation is also easy by recalling one of the properties of rotation matrices that we presented earlier in this chapter: inverting a rotation matrix is the equivalent of taking its transpose, which is an elementary operation: *R* → *R*^{−1} = *R*^{T}.

However, when translations and rotations are combined together into a homogeneous matrix, we need to take an extra step: the reason being that the order of rotation and translation is not commutative in a frame transformation, as already stressed earlier.

Intuitively, we can proceed with the following reasoning: A rotation angle is not modified by a translation, but the direction of a translation is modified by a rotation of the frame. Therefore, when doing the operation in reverse, we can safely inverse the rotation matrix, but we cannot simply take the same offset in the negative direction. The correct solution is to take a translation offset along the rotated frame, so −∆ actually becomes −*R*^{T}∆.

*P*

_{1}in

*P*

_{0}by a rotation

*R*and a translation ∆:

*P*

_{1}as a function of

*P*

_{0}and observe the resulting inverted values for rotation and translation (in

**bold**):

## Summary

This was a heavy but fundamental chapter to lay the foundations for robotics control. You have now learned the geometrical tools needed to tackle all kinematic models, including the most generic six-axes manipulator that we are going to study in the next chapters. Make sure you understand well how to combine the translations and rotations of frames into a homogeneous matrix before moving forward.

After all, the whole process of solving robotics kinematics relies on finding the position of a point (the TCP) in different frames created by the mechanical structure of joints and links, where joints introduce angular rotations, while links add offset translations.