Assignment #2 Solution
Mitsubishi RM-101 Kinematics

DH Parameters

Here is a sketch of the Mitsubishi in the ZERO position (all joint theta's = 0).

There are a couple of possible variations of this position. I chose it so that positive rotations around the horizontal joint axes raised the link (instead of lowering it). Note that all the X axes are parallel. From this sketch, we can get the DH parameters as follows:

Linkangle - thetaoffset - dlength - atwist - alpha
1variabled1090
2variable0a20
3variable0a30
4variable0090
5variabled500

From these parameters, we can get the following A matrices:

The link constants are (all in mm): d1 = 214, a2 = 200, a3 = 150, and d5 = 85.

Forward Kinematics

Multiplying the A-matrices results in the following elements in T5:

For all joint angles set to 0, this gives the following transform to the end effector. Compare this with the figure above - it gives the direction of the axes of frame 5 and the location of the origin with respect to frame 0.

Furthermore, the following (laborious!) checks can be made for the elements of T5:

Other computational checks should be made as well. These are discussed below when the forward kinematics is implemented in a MATLAB routine.

Inverse Kinematics

Starting with

the result of the matrix multiplication is

From the (3,3) and (3,4) elements we get

from which we get

The best solution to use involves px and py, unless these are both zero. Then we could use ax and ay. If these are both zero, then the pose in T5 is on the Z0 axis, with the hand pointing straight up. In this case, set theta_1 = 0. The second solutions (180 degrees away) can be used if the joint limits are exceeded by the first solution.

From the (1,3) and (2,3) elements we get

from which (since theta_1 is known)

Now, comparing the (1,4) and (2,4) elements and using the dummy variables

we have the system of equations

If we square both equations and add them, and use the trig identity for cos((A+B)-A) = cos(B), we get

Now we are stuck because we cannot find an independent expression for S3. We are forced to use

For the Mitsubishi, the elbow angle must always be negative, so we can always take the negative square root here. If C3 is larger than 1 (note that the square root function would fail), it indicates that the desired position is out of reach (t1 and/or t2, that depend on px and py, are too big).

Now we can return to the system of equations above. If we expand the terms in C23 and S23 we will get the following

These can be solved using Cramer's rule to get expressions for S2 and C2. We then use these with the atan2 function to get

Now that we know theta_2 and theta_3 we can use a previous result

The last joint angle is obtained from the (3,1) and (3,2) elements

so that

This completes the inverse kinematics. Along the way we should be checking for illegal operations (for example, square root of a negative number), or for angles that exceed the joint limits.

It is interesting to note that we obtained all the relations required for this solution from the first matrix multiplication above. This is not generally the case - we got lucky!

Implementation using MATLAB

Here are a number of MATLAB scripts that implement the above algorithms:

mitsudh.m
sets up the Mitsubishi DH parameters in an array; also sets up the M vector. These are used with the Toolbox routine ikine().
mitsufk.m
implements the forward kinematics
mitsuik.m
implements the inverse kinematics
mitjoint.m
generates a set of legal joint angles at random.
mittest.m
a script file for testing all the above routines. The script first creates a set of joint angles at random. It then evaluates the forward kinematics (computes the T5 matrix) using mitsufk.m and the Toolbox routine fkine(). Flop counts are reported for both functions. The script then calls the direct inverse kinematics routine mitsuik.m. To run the Toolbox routine ikine() a first guess is generated automatically by modifying the original joint vector by a random amount. The size of the modification can be set by editting the script file. Flop counts are reported for both mitsuik and ikine. If all goes well, the inverse kinematic solutions should compute the same joint vector as we started with.
ikine.m
modified version of Toolbox ikine() function (see discussion below)

Here is a (slightly edited) diary file of some MATLAB operations involving the above routines:

>mitsudh
>dh
dh =
    1.5708         0         0  214.0000         0
         0  200.0000         0         0         0
         0  150.0000         0         0         0
    1.5708         0         0         0         0
         0         0         0   85.0000         0
Note that the last column is necessary for ikine() - it identifies all joints as revolute.
>M'
ans =
     1     1     1     0     1     1
This selection vector tells ikine() that the Mitsubishi does not have yaw capability (rotation around the X axis of the end effector).
>mittest
Starting joint angles (degrees):
  -64.3013   50.4792  -68.3258   72.6446  175.4369

-----  FORWARD  KINEMATICS  -----
direct solution using mitsufk:
T5 =
   -0.3209    0.8783    0.3543  147.2246
    0.4833    0.4736   -0.7363 -305.9273
   -0.8145   -0.0650   -0.5765  273.3094
         0         0         0    1.0000
flops =         58

indirect solution using fkine:
T5 =
   -0.3209    0.8783    0.3543  147.2246
    0.4833    0.4736   -0.7363 -305.9273
   -0.8145   -0.0650   -0.5765  273.3094
         0         0         0    1.0000
flops =        690
These results are identical. Notice the difference in flop count. fkine() wastes a lot of time regenerating the A matrices from scratch and multiplying them out each time it is called. The symbolic solution is more than 10 times faster.

Continuing on with mittest:

-----  INVERSE  KINEMATICS  -----
direct solution using mitsuik:
flops =         65
solution:
  -64.3013   50.4792  -68.3258   72.6446  175.4369

numerical solution using Toolbox:
original guess:
  -61.6261   52.4876  -66.2201   71.5652  173.4223
ikine iterations =   104
flops =     556455
solution using ikine:
  -64.3013   50.4799  -68.3292   72.6520  175.4351
maxerror =
    0.0075
The solution found with mitsuik is exactly the same as the original vector used to generate T5. The first guess for the iterative solution implemented in ikine() is very close (within 3 degrees for each joint) to the original vector. The convergence tolerance in ikine() was changed from the value 1e-12 used in the original script to a value set by the user (more on this below). Even so, it took over 100 iterations, and more than half a million flops to produce the solution compared to 65 for the direct solution in mitsuik!

Some comments on ikine()

I experimented a bit (using mittest) with the Toolbox routine ikine(). This implements an iterative procedure, starting with a first guess at the joint angles, to compute a set of joint angles that will produce the desired T5 matrix. I made a couple of alterations: the convergence tolerance (originally 1e-12) was made an input argument (see variable tol), and the routine prints out the number of iterations required. The tolerance of 1e-12 seemed to be excessively tight, so I used values in the range 1e-4 to 1e-6. This seemed to result in much speedier exit from the program, and still gave solutions accurate to 4 or 5 significant figures.

The performance of ikine() was, to say the least, unpredictable! It sometimes found the solution in as few as 3 or 4 iterations, while at other times it exceeded the maximum limit of 1000 iterations without converging. Tightening the convergence tolerance generally caused it to take longer to converge, as expected. Of more interest was the effect of the first guess. As mentioned above, this first guess vector was obtained from the known solution and a randomly generated perturbation. The amplitude of this perturbation is set in mittest. The question was how close the first guess has to be to the actual solution. I tried amplitudes corresponding to 3, 6, 12, and 60 degrees. Unfortunately, my study was inconclusive. We would expect ikine() to take longer to converge if the first guess was farther away from the solution. There was some evidence of this in the runs I did (50 in total), but because the first guesses were not identical for each run, it is hard to make a firm conclusion. I did find that if the first guess was very far away, the solution would sometimes converge to values more than a full revolution away (note that any joint angle can be incremented by 2*pi and still satisfy T5).

In all these runs, ikine() averaged over 5000 flops per iteration. In each iteration, it must evaluate the forward kinematics, the manipulator Jacobian, and its inverse - this is a lot of work! This can be compared to the constant 65 flops required by the direct solution implemented in mitsuik.

Furthermore, ikine() is incapable of detecting illegal joint positions, since it knows nothing about the joint limits.


Questions?

Send a message to roger.toogood@ualberta.ca

Return to Assignments List