Simplified inverse kinematics model for a 5 degree of freedom + gripper robotic arm (2011)

The following describes a simple method (inverse kinematics) of calculating the angles for all joints of a robotic arm to obtain a desired position of the end actuator (gripper). The video bellow shows the algorithm at work.

The picture bellows shows the robot arm used for this example. It has 5 degrees of freedom:

1. Base Rotate

2. Shoulder

3. Elbow

4. Wrist

5. Wrist Rotate

ik_5_degrees.jpg

We will use the following standard coordinate system used in robotics:

ik_coordinate_system.jpg

All degrees of freedom of this type of arm act in the same vertical plane. This vertical plane can rotate around the z axis as seen in the following diagram.

ik_base_rotate.jpg

We can obtain the base rotate angle (A0) as a simple arcTan function of the desired actuator target xT and yT coordinates.

A0 = arctan ( yT / xT )

This is possible with this type of robotic arm because there are no degrees of freedom that go out of the vertical plane.

Once we have calculated A0 we can calculate the value of wT by using the Pythagoras Theorem .

wT = sqrt ( sq ( xT ) + sq ( yT ))

Once we have wT we can do all calculations in the two dimensional plane wz.

Note that wrist rotate angle is not required for the calculation of the remaining angles. The wrist rotate angle will be determined by the particular need to have the gripper rotated in a certain position to grab a particular shaped object. This may or may not be relevant to all applications. If wrist rotate is important then it should be calculated after all other angles have been calculated.

The following diagram shows the robotic arm simplified to 3 degrees of freedom in the wz plane.

ik_3_degrees.jpg

In most applications we will like the gripper to act on a certain fixed angle. For example to pick up a chess piece we will normally want the gripper to act vertically (-90 degrees). In order to have control over the Wrist angle and to keep simplifying the model we will use a discrete set of angles for the last link. In this case we will use 90, 45, 0, -45 or -90 degrees.

ik_gripper_positions.jpg

If we know the target gripper coordinates, wT and zT, and the desired angle for the actuator link (AG = GripperAngle) then we can use simple trigonometry to calculate coordinate w2, z2.

w2 = wT – L3 cos (AG)

z2 = zT – L3 sin (AG)

We now have the simplified 2 Degrees of Freedom problem shown in the following diagram. Where we know the coordinate of the end of Link 2 (w2, z2) and we know the coordinate of the beginning of Link 1 (w0, z0) and we just need to calculate the angles for both links.

ik_2_degrees.jpg

A1, A2 and A3 are the three angles that we need to obtain. We can use the law of cosines to obtain angle A1-A12 as we have the length of the three triangle sides L1, L2 and

L12 (this last one obtained using Pythagoras Theorem).

L12 = sqrt ( sq ( w2 ) + sq ( z2 ))

A12 = arctan (z2 / w2)

If L12 > L1 + L2 then there is no solution as arm can not reach the target.

A1 = arccos ( ( sq ( L1 ) + sq ( L12 ) – sq ( L2)) / (2 * L1 * L12 )) + A12

with A1 calculate w1,z1

w1 = L1 cos (A1)

z1 = L1 sin (A1)

A2 = arctan ( ( z2 – z1 ) / ( w2 – w1 ) ) – A1

with A12 calculate the Angle of Link 3, A3

A3 = AG – A1 – A2

To illustrate the algorithm and to confirm that it works before implementing it on a robot arm I wrote a small program in Processing language: Inverse Kinematics Processing Simulation

Screen Shot 2016-01-31 at 1.25.53 PM.png

Processing is an open source programming language and environment for people who want to create images, animations, and interactions.

Processing.js is the sister project of the Processing visual programming language, designed for the web. Processing.js makes your data visualizations, digital art, interactive animations, educational graphs, video games, etc. work using web standards and without any plug-ins.

Bellow is the processing code:

/*
 * Inverse_Kinematics_1 
 * Programm used to validate an inverse kinematics algorithm for a Robotic Arm
 *
 * Author: Diego Pontones
 * Date: February 17, 2011
 * Copyright: Diego Pontones
 * email:
 */
int nLinks = 3;
int nGripperAngles = 5;
int GripperAngle[] = {0, -45, -90, 45, 90};
int linkStrokeW[] = {28, 18, 12};
int linkColor[] = {#00D000, #0000FF, #FF0000};
int l[] = {0, 100, 100, 60};
int h0 = 180; //Arm Origen in Screen Coordinates
int v0 = 360; //Arm Origen in Screen Coordinates
int currGripper = 0;
float[] w = new float[nLinks]; //horizontal coordinate, corresponds to P0, P1, P2 etc
float[] z = new float[nLinks]; //vertical coordinate
float[] a = new float[nLinks]; //angle for the link, reference is previous link
float tw, tz; //target coordinate for the actuator (gripper)
float tw0, tz0; //Previous target coordinate for the actuator (gripper) that was inside the robot reach
float l12;
float a12;
void setup() {
 size(480, 560); //drawing window size
 smooth(); 
 w[0] = 0; // Set Origen
 z[0] = 0; // Set Origen
 tw0=100; // Initiakl Target
 tz0=100;
}
void draw() {
 background(240);
 checkMouseInMenu(mouseX, mouseY);
 drawGripperMenu();
 drawAxes();
 tw = mouseX - h0;
 tz = v0 - mouseY ;
 calcP2();
 if (l12>l[1]+l[2]){
 textAlign(CENTER); 
 fill(#FF0000);
 text("No Solution",240,70);
 text("Move mouse pointer towards the origin.",240,84);
 tw=tw0;
 tz=tz0;
 calcP2();
 }
 calcP1();
 drawLinks();
 tw0=tw;
 tz0=tz;
}
void drawAxes(){
 strokeWeight(1);
 stroke(0);
 line(h0, v0, h0+259,v0);
 line(h0, v0, h0,v0-259);
}
void checkMouseInMenu(float hin, float vin){
 int H = 120;
 if((vin>436) && (vin<454)) { 
 for(int i=0; i<nGripperAngles; i++) { 
 if((hin>H-20) && (hin<H+20)) {
 currGripper=i;
 }
 H=H+44; 
 }
 }
}
void drawGripperMenu() {
 textAlign(CENTER);
 text("Robot Arm Inverse Kinematics Algorithm Simulation",250,34);
 text("www.maquinapensante.com",250,50);
 int H = 60;
 int V = 424;
 fill(0);
 textAlign(LEFT); 
 text("To change gripper angle roll mouse over new value",H,V);
 textAlign(CENTER);
 H = 120;
 V = 450;
 for(int i=0; i<nGripperAngles; i++) { 
 if(i == currGripper) {
 fill(0);
 }else {
 fill(180); 
 }
 text(GripperAngle[i], H, V);
 H = H+44; 
 }
}
void calcP2(){
 w[2]=tw-cos(radians(GripperAngle[currGripper]))*l[3];
 z[2]=tz-sin(radians(GripperAngle[currGripper]))*l[3];
 l12 = sqrt(sq(w[2])+sq(z[2]));
}
void calcP1(){
 a12=atan2(z[2],w[2]);
 a[1]=acos((sq(l[1])+sq(l12)-sq(l[2]))/(2*l[1]*l12))+a12;
 w[1]=cos(a[1])*l[1];
 z[1]=sin(a[1])*l[1];
}
void drawLinks(){
 for(int i=0; i<2; i++) { 
 strokeWeight(linkStrokeW[i]);
 stroke(linkColor[i]);
 line(h0+w[i], v0-z[i],h0+w[i+1], v0-z[i+1]);
 }
 strokeWeight(linkStrokeW[2]);
 stroke(linkColor[2]);
 line(h0+w[2], v0-z[2],h0+ tw,v0- tz);
 fill(0);
 strokeWeight(0);
 stroke(0);
 ellipse(h0+ tw,v0- tz,10,10);
}

As can be seen the algorithm successfully calculates the angles for the joints however the following needs to be considered when implementing it:

  • As mentioned before the wrist rotate angle would have to be calculated if required in order to compensate for base rotation and for wrist (L3) angle.

  • Need to check and limit the angle values so that the arm segments and the gripper do no not hit the surface or other segments.

  • For example for a gripper orientation (AG) of -90 degrees the wrist rotation angle will be a simple function of the base rotate angle (A0).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s