We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am trying to use processing to communicate in real time with an arduino which is driving a 3d printer via serial communication. The problem I am having is that some calculations I am doing in processing are giving me the wrong answer. The below code is a simple calculation of the inverse kinematic solution of a 3PUU delta robot. I give it the cartesian coordinates (x, y, and z) and it is supposed to give me L1, L2, and L3 (the height of each carriage on the printer) in order to achieve that position. The L1 it is giving me is correct, but the L2 and L3 are off by 6-7mm which is huge for this application. I thought it might have been a problem with my code, but I used the same formulas in matlab and the answer was correct far past 4 decimal places. Are any of the functions that I am using causing loss of precision or rounding errors maybe? Possibly the sqrt() function or pow(bla, bla) function? Can anyone tell me why my answers are incorrect with this code?
If anyone is curious about the source of the formulas it is here: http://www.ohio.edu/people/williar4/html/pdf/DeltaKin.pdf pages 27 and 28
Code below:
//variables (lengths, etc) (mm)
float sb=432;
float rb=142;
float sp=127;
float lmin=67;
float lmax=479;
float l=264;
float h=44;
float wb=(sqrt(3)/6)*sb;
float ub=(sqrt(3)/3)*sb;
float wp=(sqrt(3)/6)/sp;
float up=(sqrt(3)/3)*sp;
float ox=0;
float oy=0;
float H=686;
//input coordinates (desired position)
float x=0;
float y=0;
float z=-500;
//calculations
float a=wb-up;
float b=(sp/2)-((sqrt(3)/2)*wb);
float c=wp-(.5*wb);
// calculations
float C1=pow(x,2)+pow(y,2)+pow(z,2)+pow(a,2)+(2ya)-pow(l,2);
float C2=pow(x,2)+pow(y,2)+pow(z,2)+pow(b,2)+pow(c,2)+(2xb)+(2yc)-pow(l,2);
float C3=pow(x,2)+pow(y,2)+pow(z,2)+pow(b,2)+pow(c,2)-(2xb)+(2yc)-pow(l,2);
//both solutions for each length (elbow up, and elbow down)
float L11=-z+sqrt(pow(z,2)-C1);
float L12=-z-sqrt(pow(z,2)-C1);
float L21=-z+sqrt(pow(z,2)-C2);
float L22=-z-sqrt(pow(z,2)-C2);
float L31=-z+sqrt(pow(z,2)-C3);
float L32=-z-sqrt(pow(z,2)-C3);
println("elbow up");
println("L1: "+L11);
println("L2: "+L21);
println("L3: "+L31);
println("elbow down");
println("L1: "+L12);
println("L2: "+L22);
println("L3: "+L32);
println("actual answer: 241");
Answers
Surely
pow (n, 2)
is simplyn * n
so why not simply do multiplication rather than power calculations.floats are only accurate to 6-7 significant digits so you could use the double data type and the Math class functions i.e. Math.sqrt (n) which will return a double if n is a double
Quark, thanks for the reply! I thought of using doubles but was getting errors when using them. However adding Math. in front of my math functions fixed the errors! My answers are still off by the same amount, but now I can be sure it is not from rounding errors. I think I am going to compare my answers to the matlab solution and see exactly where it differs when I get a chance. I will post when I find results.
I narrowed down the problem to a typo on line 11... had a / instead of a *. Thanks for your help!