You are on page 1of 15

Third International Conference on Production Research –

Americas’ Region 2006 (ICPR-AM06)


IFPR – ABEPRO - PUCPR - PPGEPS

LAUS METHOD FOR ROBOT KINEMATICS MODELING

Luís Paulo Laus


UTFPR - Department of Mechanical Engineering (DAMEC)
Av. 7 de Setembro, 3165 - Curitiba, PR, Brazil - 80.230-901
laus@cefetpr.br

Alfranci Freitas Santo


UTFPR – freitas@cefetpr.br

Luiz Carlos de Abreu Rodrigues


UTFPR – lcar@cefetpr.br

João Antonio Palma Setti


UTFPR – setti@cefetpr.br

Leandro Magatão
UTFPR – magatao@cefetpr.br

Abstract: Robots' kinematic models are the base for the study of robotics and the
construction of the dynamic models used for robots’ control and simulation. Lack of a
well established procedure for obtaining the kinematic model may lead to a trial and
error process, resulting in waste of time and effort. With a didactic perspective in mind,
a simple and intuitive modeling method is presented. This method facilitates learning
and reduces the occurrence of mistakes in the construction of the forward kinematic
model. The presented method, in opposition to the available ones, does not require that
the robot be in any special pose. Any pose can be used, what is also an important
practical advantage.

Keywords: robotics, robotic manipulator, robot kinematics, kinematic modeling,


kinematic modeling method.
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

1 Introduction
Kinematics describes – in robotics – the relations among the movements of joints and
links of a robot. The joint variables express the position of joints. These positions are
given as an angular measure for revolute joints and as a linear measure for prismatic
joints. Through kinematics, a mapping among joint variables and the position and
orientation is generated for each robot link. The mappings are static, with no concerns
about speed (Craig, 1986). Position and orientation of robot’s links are defined
attaching a coordinates system – also called frame – to each link. Therefore, the
problem evolves to describing the relative position and orientation of the frames.

This problem is solved using homogeneous transformations matrices, as indicated by


Craig (1986). These matrices have many useful properties being the concatenation the
most important one. Concatenation allows describing the position and orientation of
any segment, specially the last one where the tool is attached to, in respect to any
coordinated system of interest. Usually, the coordinated system of interest is attached
to the robot unmovable link (the base).

The most convenient places to locate the frames on a link are the joints, making one of
the coordinated axes to match the joint axis. Since an internal link has two joints, it is
possible to choose the “closer joint” or the “distant joint”, when the base of the robot is
taken as a reference. Craig (1986) prefers the closer joint but many authors, Gonzalez
et al. (1987), Niku (2001), Paul (1981), Sciavicco & Siciliano (1996) and Stone (1987),
prefer the distant joint.

2 The Modified Denavit-Hartenberg Notation (MDH)


The original notation proposed by Denavit & Hartenberg (1955) describes a link by
attaching a frame on the distant joint. Later on, Craig (1986) began to use the closer
joint. However the choosing seems to be arbitrary. There is a possibility that this
modification leads to a simpler inverse kinematic. Moreover, it was observed that
models that use closer joints are easier to calibrate (Laus, 1998). So, the used notation
in this work is called “Modified Denavit-Hartenberg Notation (MDH)”.

In order to reduce the number of parameters, Denavit & Hartenberg (1955) have
restricted the relative position and orientation of two adjacent frames making one of the
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

axes (the X axis) falls on the mutual perspective of the joint axes (Z axes) of the same
link. Consequently, one degree of freedom of orientation and one of positioning are
eliminated. By abuse of notation, the coordinated systems axes are named by the
versor parallel to the axis.
In order to construct the forward kinematic model, steps i to iv were established by
Craig (1986):
i. starting by the robot’s base, all links are numbered. Robot’s base receives
number zero and the end-effector (also named as tool) receives number N ;
ii. joint’s axes are numbered from 1 to N , according to links’ numbers. That is,
the joint that is closer to the base receives number 1 and the last joint
receives number N ;
iii. axis Zˆ i of each frame must match the joint axis;

iv. axis Xˆ i −1 of frame i − 1 is perpendicularly positioned to axis Zˆ i and Zˆ i +1 .

The MDH notation is usually described by a geometric interpretation of each parameter


(Craig, 1986; Gonzalez et al., 1987; Niku, 2001; Paul, 1981; Sciavicco & Siciliano,
1996; Stone, 1987).

The homogeneous transformation matrix that relates two adjacent frames is a function
of three parameters and one joint variable:
• a i −1 is the distance from Zˆ i −1 to Zˆ i measured along Xˆ i −1 and it is called link

length (of link i − 1 );


• α i −1 is the angle between Zˆ i −1 and Zˆ i measured about Xˆ i −1 and it is called

link twist (of link i − 1 );


• di is the distance from Xˆ i −1 to Xˆ i measured along Zˆ i and it is called joint
off-set (of joint i );
• θi is the angle between Xˆ i −1 and Xˆ i measured about Zˆ i and it is called
joint angle (of joint i ).

The Fig. 1 illustrates these geometric relations. Note that two parameters ( a i −1 and

α i −1 ) are link specific characteristics while d i and θ i depend on the relationship of two
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

consecutive links. The joint variable will be d i if the joint is for prismatic type and θ i if
the joint is a revolute one.
In order to reach the frame i from frame i − 1 it is necessary:
• translate along Xˆ i −1 by a distance α i −1 ;

• rotate about Xˆ i −1 by an angle α i −1 ;

• translate along Zˆ i by a distance d i ;

• rotate about Zˆ i by an angle θ i .

Axis i Axis i + 1

Link i
Axis i − 1

Link i − 1
Yˆi +1
Zˆ i +1
Xˆ i +1
αi

Zˆ i di
Zˆ i −1 Xˆ i
Yˆi
ai

i −1
Xˆ i −1 θi

a i −1
α i −1
Zˆ i

Figure 1: Parameters associated to frames.

Considering moving axes (the movement is executed in respect to the result of the
preceding moment and not in respect to fixed axes), the homogenous transformation,
which describes the frame i in respect to frame i − 1 , can be defined by equation (1)
(Craing, 1986):
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

i −1
iT = Transl(a i −1, 0, 0).RotX(α i −1 ). Transl(d i ).RotZ(0, 0,θ i ) =
⎡ cθi − sθi 0 a i −1 ⎤
⎢c α s θ c α c θ − s α ⎥
i −1 − d i s α i −1 ⎥
(1)
= ⎢ i −1 i i −1 i
⎢s α i −1 s θ i s α i −1 c θ i c α i −1 d i c α i −1 ⎥
⎢ ⎥
⎣ 0 0 0 1 ⎦

where c is the co-sine function and s is the sine function. The equation (1) can be
viewed as a function of a i −1 , α i −1 , d i and θ i .

i −1
To build up and simplify the matrices iT given by equation (1), it is interesting to use
a Computer Algebra System. One of these software successfully used by the authors is
the MuPAD (2003).

3 The Laus Method for Forward Kinematics Modeling


The proposed approach is intended to be very intuitive, when compared to other
approaches in the literature (Craig, 1986; Gonzalez et al., 1987; Niku, 2001; Paul,
1981; Sciavicco & Siciliano, 1996; Sheth & Uicker, 1972; Stone, 1987). The Laus
Method does not demand the search for angles and lengths that describe the relative
position and orientation of frames. Instead, it attempts to describe the movements that
should be made to force one frame i − 1 to match to the next frame i . The proposed
method enables the use of any arbitrary pose1 which is a very practical advantage over
the traditional approaches that demands the use of the zero pose2.

The goal of this method is to obtain the set of all four parameters that are necessary for
the determination of the forward kinematic model of any industrial robot. The steps of
the proposed method are:

i. Choose a reference pose (a position specific position for all joint axes). It is
convenient to have a drawing of the robot in this pose. Although any sketch may
do, some of them are not easy to work with, as indicated in Fig. 2.a. It is
advisable to use orthogonal projections, as presented in Fig. 2.b. Notice that

1
Robot configuration or the position and orientation of all links that, together, determine
exactly how the robot is in a given time.
2
Configuration that the robot poses when all joint variables are null.
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

attention must be given to the relations among joints and frames, but the robot’s
shape and look are of no use during the modeling procedure. Therefore, it may
also be worthwhile to use simplified sketches that only represent joints and
links, as shown in Fig. 2.c. Moreover, it is not necessary that the chosen pose
be actually achievable, meaning that it is possible to choose a pose out of the
joint variable’s limits.

(a) (b) (c)

Figure 2: Example of RV-M1 robot; a) perspective; b) orthogonal projections; c) simplified sketch.

ii. Treat the joint variables as ordinary parameters. Later on (step x), these
“parameters” will be transformed in initial values for the joint variables, or the
needed values for joint variables, in order to reach the reference pose.

iii. Axes and frames will be numbered, starting at the base of the robot. Thereafter,
base’s frame will receive number 0, while first joint’s axes (and frame) will
receive number 1, and the end-effector’s axes will receive number N . Observe
that this numeration schema implies in movement subordination. Remember
that the smallest number corresponds to the axis that stands still while the other
axis moves. This is of particular significance when two axes cross.

iv. Set the axes Zˆ i (i = 1, 2, 3,K,N ) matching the axes of the revolute joint or
parallel to the axes of prismatic joints. Attention must be given to the desired
orientation of the joint variables, while setting the direction of any axis Zˆ i . For

the prismatic joints, Zˆ i points to the same direction of the growing of the joint
variable. For the revolute joint, use the “right hand rule” where the thumb is
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

aligned with the joint axis (and Zˆ i ) and the other fingers give the growing

direction of the joint variable. Fig. 3 presents all axes Zˆ i .

Zˆ 5

Zˆ 2 Zˆ 3 Zˆ 4
Zˆ1

Figure 3: Set of axes Zˆ i .

v. Set all axes Xˆ i (i = 1, 2, 3,K,N − 1) in such a way that any axis Xˆ i must fall in

mutual perpendicular of both axes Zˆ i and Zˆ i +1 . The direction of any axis Xˆ i is

from Zˆ i to Zˆ i +1 . This is also true when Zˆ i and Zˆ i +1 are parallel. If Zˆ i and Zˆ i +1

are not parallel, while intersecting or not each other, the direction of Xˆ i will be

given by Xˆ i //( Zˆ i × Zˆ i +1 ) . Usually, this procedure is a good hint for the frame
origin determination, but the only purpose of this step is to set the directions of
all axes Xˆ i . All frame origins are set in step x. Fig. 4 presents all axes Xˆ i (as

well as Zˆ i previously defined).

Xˆ 1 Xˆ 2 Xˆ 3 Zˆ 5

Zˆ 2 Zˆ1 Zˆ 3 Zˆ 4 Xˆ 4 Xˆ 5

Figure 4: Set of axes Xˆ i and Zˆ i .


Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

vi. The direction of axis Xˆ N (associated to the last link and the end-effector) may

be arbitrarily defined, since there is no axis Zˆ N +1 . But a good hint is to make

Xˆ N with the same direction of Xˆ N −1 .

vii. Set the origins for all frames, starting by the end-effector and working down
towards the base. Try to align axes Xˆ i or Zˆ i with any axes of frames {i + 1} or

{i − 1} . It is important to attempt align axes Xˆ i or Zˆ i with any axis of frames

{i + 1} or {i − 1} , because this will make inverse kinematics easier, since some


of the parameters (lengths) will be set to zero. It is a little bit better to align the
axes of frame {i } to some axes of frame {i + 1} because the null parameters
will sooner appear in table of step ix, simplifying the inverse kinematic. Fig. 5
show how the frames are set with the fixed origins.

Xˆ 1 Xˆ 2 Xˆ 3 Zˆ
4

Zˆ 2 Zˆ1 Zˆ 3 Zˆ 5 Xˆ 4 Xˆ 5

Zˆ 0
Yˆ0
Xˆ 0

Figure 5: Set of origins and base frame.

viii. Locate frame {0} – that is, the BASE frame. Basically, there are two options:

• To make the frame {0} = {1} . In this case a 0 , α 0 , d 1 , and θ1 will be null; or

• To make Xˆ 0 ⊥ Zˆ1 and locate the other axes of frame {0 } arbitrarily.

In the example, Mitsubishi (1994) uses a base frame on the mounting surface with axis
Zˆ 0 pointing up and axis Xˆ 0 being perpendicular to the paper plane, as shown in Fig. 5.
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

ix. Build up a table with N rows, one row for each joint. The parameters
associated to each frame (link) will be recorded in a row of this table. Thus, four
columns are needed to register: a i −1 - the length of link (i − 1) ; α i −1 - the twist of

link (i − 1) ; d i - the offset of joint i ; and θ i - the angle of joint i . Consider the
joint variable as a regular parameter (with a defined numerical value). Begin
with the first line ( i = 1, associated to the frame {0} and the homogeneous

transformation from the frame {0} to {1} ). Determine the necessary movements

(lengths and angles) to set the frame {i − 1} to coincide with frame {i } . In order
to accomplish this, it is necessary to:

• Rotate the frame {i − 1} about axis Xˆ i −1 by an angle of α i −1 until axis Zˆ i −1

becomes parallel to axis Zˆ i of the frame {i } . Displace the new obtained

frame along axis Xˆ i −1 until axis Zˆ i −1 matches to axis Zˆ i of frame {i } . The

displaced distance is called a i −1 .

• Rotate the new frame about its own axis Zˆ i (the same of the frame {i } ) by

an angle of θ i until its axis Xˆ i −1 becomes parallel to axis Xˆ i of frame {i } .

Displace the new obtained frame along Zˆ i by a distance of d i until axis

Xˆ i −1 matches to axis Xˆ i of the frame {i } .

Never change the order of the above rules: always rotate and displace over axis Xˆ i −1

and then over axis Zˆ i .

In the example, in order to make frame {0} match frame {0} , it is necessary to rotate

by + 180 0 about Xˆ 0 . Then the new frame must be rotate by − 90 0 about Zˆ1 in order to

make Xˆ 0 parallel to Xˆ 1 . Then the new frame must be translated by a distance d 1

( 300 mm according to Mitsubishi (1994)) in order to make Xˆ 0 coincide with Xˆ 1 . Note

that d i for the first row ( i = 1) of Table 1 is negative because the displacement must be

done in opposite direction of the axis Zˆ1 . It is better to consider d 1 = 300 mm (positive)
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

and use a negative symbol ( − d 1 ) into the table than to use a negative displacement
because people tend to forget that the displacement is negative.
In order to make frame {1} match frame {2} , it is only necessary to rotate by − 90 0

about Xˆ 1 . In order to make frame {2} match frame {3} , it is only necessary to displace

frame {2} by a distance of a 2 along Xˆ 2 . In order to make frame {3} match frame { 4} ,

it is necessary to displace frame {3} by a distance of a 3 along Xˆ 3 . Then the new

frame is rotated about axis Zˆ 4 by − 90 0 , matching to frame { 4} . In order to reach

frame {5} departing from frame { 4} , it is enough to rotate frame { 4} about Xˆ 4 by

+ 900 . Care should be taken when registering the values on the table, since there are
two angles and two lengths. They must be set according to the reference axis. Table 1
shows all the rows ( i = 1,K5 ) for the example robot.

Table 1: Parameters and joint variable at reference pose.

i i −1
iT
α i −1 a i −1 θi di

1 0
T
1 180 0 0 − 90 0 −d1
1
2 2T − 90 0 0 0 0
3 2
3T 0 a2 0 0
4 3
4T 0 a3 − 90 0 0
4
5 5T + 90 0 0 0 0

x. Add the joint variable to the tabled “parameters” according to the joint type ( θ i

for revolute joint and d i for prismatic ones). Observe that, in the cases of joint
variables, the values shown in Table 1 become joint variable’s offsets (initial
values). The complete kinematic description of the example robot is shown in
Table 2.

If Xˆ i (with i = 1, 2, 3,K,N ) are all parallel, all the revolute joint variable’s offsets will be
null. In the cases when the joint variable’s offsets are not null (as joint 1 and 4 in the
example), the use of a Matlab toolbox (Corke, 1996; Matlab, 1993) to validate the
robot’s model will not be possible. This can be avoided finding out another reference
pose such as all the Xˆ i being parallel. To find out this pose is a bit tricky procedure
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

because it is hard to imagine all the axes moving at the same time. This approach is
adopted by many authors like Craig (1986), Gonzalez et al. (1987), Niku (2001), Paul
(1981), Sciavicco & Siciliano (1996), and Stone (1987).

Table 2: Complete table, including joint variables.

i i −1
iT
α i −1 a i −1 θi di

1 0
T
1 180 0 0 θ1 − 90 0 −d1

2 1
T
2 − 90 0 0 θ2 0
3 2
T
3 0 a2 θ3 0
4 3
T
4 0 a3 θ 4 − 90 0 0
5 4
T
5 + 90 0 0 θ5 0

In a simpler way, it is possible to consider that the reference pose is not the zero pose
in order to avoid non-nulls initial values. For this approach, in the given example,
θ1 = θ 4 = −90 0 and θ 2 = θ 3 = θ 5 = 0 set the robot just like the reference pose shown in

Fig. 5. In order to find the zero pose, it is enough to turn θ1 and θ 4 by + 90 0 . In the

achieved pose, all Xˆ i are parallel.

If the zero pose is taken as the reference pose, the admissible values for θ1 will be

from − 240 0 to + 60 0 (and not from − 150 0 to + 150 0 ) and for θ 4 will be from − 180 0 to

00 (and not from − 90 0 to + 90 0 ). With this approach, it is possible to use the Matlab
toolbox (Corke, 1996; Matlab, 1993).

Note that the kinematic model stops at the wrist. The wrist can be viewed as: 1) one
point where the last two joints’ axes cross; 2) the origin of the frame that sets the
position and orientation of the last link (but not the tool). To model the position and
orientation of the link instead of the end-effectors brings simpler kinematic equations.
Also, the kinematic equations are independent from the end-effector (type, size, etc.).
Thus, one can change the tool without any need for remodeling.

An analysis of the most frequently made mistake of students points out that care should
be taken in step v. Four possible situations should be considered:
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

• the joint axes ( Zˆ i and Zˆ i +1 ) are parallel: Xˆ i will be in the same plane that

contains Zˆ i and Zˆ i +1 , oriented from Zˆ i to Zˆ i +1 and perpendicular to both of

them (since they are parallel). The origin of the frame {i } will be only known in
the step vii;
• the joint axes coincide: in this case there is quite a bit of freedom in Xˆ i

assigned. The better to do is to set Xˆ i coincident or parallel to Xˆ i +1 . Note that


coincident joint axes occur only when the two type kind of joints, prismatic and
revolute, are involved.
• the joint axes cross in one point: the origin of the frame {i } will be the crossing

point, the Xˆ i will be perpendicular to both Zˆ i and Zˆ i +1 (perpendicular to the


plane that contains those axes) and there is only one option. The direction that
Xˆ i points can be arbitrary, but it is preferable that Xˆ i points to the frame
{i + 2}. Note that the crossing angle is not important;
• the joint axes do not cross but also are not parallel: in this case it will be one,
and only one, line that remains perpendicular to both axes, Xˆ i will lie along this

line oriented from Zˆ i to Zˆ i +1 .

4 Building the Kinematic Model


The forward kinematic goal is to describe the position and orientation of the end-
effector as a function of the joint variables. This description can be done by coordinated
systems (frames). The main purpose of this description is to obtain the inverse
kinematic: to determine the joint variable set in order to reach a given position and
orientation.

Through equation (1), it is easy to get a description of the robot’s wrist as a function of
the joint variables: apply equation (1) for each row of the Table 2, obtaining N
homogenous transformations; multiply every obtained homogenous transformation.
However, this procedure leads to a description of the wrist, not the end-effector. Hence,
it is necessary to include a constant homogenous transformation NTT to describe the
position and orientation of the end-effector in respect to the wrist.
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

Generally, it is also interesting to include another constant homogenous transformation


S
0T to describe the base frame in respect of a station frame {S } because the base may
not be conveniently located from the user point of view.

The equation (2) calculates the homogenous transformation TST as a function of the
joint variables.

S
TT =S0T 01T 21T 23T KN N−1T N
TT (2)

N −1
where 0
1T to NT are obtained from equation (1) and both TST and NT T are constants.

Since all the details of end-effectors are included in the matrix NTT , it is possible to
derive a forward and inverse kinematic that is generic. In addition, it is possible to
chance the end-effect without the need for any remodeling.

5 Conclusions
The presented method has been tested for more than four years with roughly two
hundred undergraduate students. Comparing to the traditional methods, the students
have reported better understanding than the traditional approaches. The easiness of
using a computer algebra system is also an attractive point. Probably, the most
important feature is the fact that the presented method does not request a priori
knowledge of a specific pose, called zero pose, to be applied. This pose, in with all Xˆ i
axes are parallel to each other, is usually hard to be found.

References
Corke, P. I. A Robotics Toolbox for MATLAB. IEEE Robotics and Automation
Magazine, v. 3(1), pp. 24-32, March 1996.

Craig, J. J. Introduction to robotics : mechanics & control. Reading : Addison Wesley,


1986.
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

Denavit, J.; Hartenberg, R. S. A Kinematic Notation for Lower Pair Mechanisms Based
on Matrices, Transaction of the ASME, Journal of Applied Mechanics, v. 22, pp. 215-
221, 1955.

Gonzalez, R. C.; Fu, K. S.; Lee, C. S. Robotics : control, sensing, vision, and
inteligence. New Yourk : McGraw-Hill, 1987.

Laus, L. P. Identificação da Cinemática de Robôs Industriais. Curitiba, Brasil, 1998.


Dissertação (Mestrado em Ciências : Informática Industrial) Centro Federal de
Educação Tecnológica do Paraná (in Portuguese).

MATLAB, Matlab with Simulink. MATLAB version 4.0, SIMULINK version 1.2c.
Mathematic software for matrices processing and meta language. The MathWorks Inc.
CEFET-PR, August 4th, 1993. IBM-PC.

Mitsubishi Electric Corporation. Industrial micro-robot system : Model RV-M1, BFP-


A5191E-B, Japan, 1994.

MuPAD, MuPAD Light Version 2.5.3. Computer algebra system. Paderborn University,
Alemanha. Licenced to : “Luis Paulo Laus, September 11th, 2003” as a courtesy of
Paderborn University. IBM-PC compatible, Windows.

Niku, S. B. Introduction to robotics : analisys, systems, applications. Upper Saddle


River : Prentice Hall, 2001.

Paul, R. P. Robot manipulator : mathematics, programming and control. Cambridge,


MA : MIT, 1981.

Sciavicco, L.; Siciliano, B. Modeling and control of robot manipulators, New York :
McGraw-Hill, 1996.

Sheth, P. N.; Uicker, J. J. A generalized symbolic notation for mechanisms. ASME


Journal of Engineering for Industry, v. 93, n. 1, pp. 102-112, 1972.
Third International Conference on Production Research –
Americas’ Region 2006 (ICPR-AM06)
IFPR – ABEPRO - PUCPR - PPGEPS

Stone, H. W. Kinematic modeling, identification and control of robotic manipulators.


New York : Kluwer Inc., 1987.

You might also like