robotic_manipulators_ik_cpp
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
robotic_manipulators_ik_cpp [2016/08/06 21:20] – created joaomatos | robotic_manipulators_ik_cpp [2016/08/08 19:12] (current) – joaomatos | ||
---|---|---|---|
Line 1: | Line 1: | ||
===== Inverse Kinematics Using Damped Least Squares method in C++ ===== | ===== Inverse Kinematics Using Damped Least Squares method in C++ ===== | ||
+ | |||
+ | **Author:** Joao Matos Email: < | ||
+ | \\ | ||
+ | **Date:** Last modified on 6/8/2016 | ||
+ | \\ | ||
+ | **Keywords: | ||
+ | \\ | ||
+ | |||
+ | This application was made using Visual Studio 2015 and C++. Is necessary to include the Eigen library. To include the Eigen library just go to your solution properties , under C++ general properties , on the additional include directory include the folder where you saved the Eigen file. | ||
+ | |||
+ | [[http:// | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | |||
+ | To run this application just include the source given above or copy and paste the code bellow in your application | ||
+ | |||
+ | |||
+ | {{ :: | ||
+ | |||
+ | ---- | ||
+ | ===== Code with commentaries (copy and paste in your Visual Studio) ===== | ||
+ | |||
+ | < | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | |||
+ | |||
+ | using namespace Eigen; | ||
+ | |||
+ | |||
+ | int main() | ||
+ | { | ||
+ | |||
+ | const float pi = 3.14159265; | ||
+ | const float L1 = -11, L2 = 15, L3 = 10, L4 = -21, L5 = -8; | ||
+ | float th1, th2, th3, th4, th5; | ||
+ | float xt, yt, zt; | ||
+ | int method; | ||
+ | |||
+ | |||
+ | // Ask for the desired position (target position) | ||
+ | std::cout << "Enter the Target x position " << std::endl; | ||
+ | std::cin >> xt; | ||
+ | |||
+ | std::cout << "Enter the Target y position " << std::endl; | ||
+ | std::cin >> yt; | ||
+ | |||
+ | std::cout << "Enter the Target z position " << std::endl; | ||
+ | std::cin >> zt; | ||
+ | |||
+ | // Ask the method to be used | ||
+ | // | ||
+ | //No Orientation control | ||
+ | std::cout << "Enter 1 to run the IK with orientation control " << std::endl; | ||
+ | std::cout << "Enter 2 to run the IK without orientation control " << std::endl; | ||
+ | std::cout << "If you choose orientation Control and get an error " << std::endl; | ||
+ | std::cout << "The desired position cant be reached keeping the end effector in the vertical " << std::endl; | ||
+ | |||
+ | |||
+ | std::cin >> method; | ||
+ | |||
+ | MatrixXf A1(4, 4); | ||
+ | MatrixXf A2(4, 4); | ||
+ | MatrixXf A3(4, 4); | ||
+ | MatrixXf A4(4, 4); | ||
+ | MatrixXf A5(4, 4); | ||
+ | |||
+ | MatrixXf A12(4, 4); | ||
+ | MatrixXf A123(4, 4); | ||
+ | MatrixXf A1234(4, 4); | ||
+ | MatrixXf A12345(4, 4); | ||
+ | |||
+ | MatrixXf Jw(3, 5); | ||
+ | MatrixXf Jv(3, 5); | ||
+ | MatrixXf Jacobian(6, 5); | ||
+ | |||
+ | MatrixXf Oeff(3, 1); | ||
+ | MatrixXf O00(3, 1); | ||
+ | MatrixXf O01(3, 1); | ||
+ | MatrixXf O02(3, 1); | ||
+ | MatrixXf O03(3, 1); | ||
+ | MatrixXf O04(3, 1); | ||
+ | |||
+ | |||
+ | MatrixXf rc1(3, 1); | ||
+ | MatrixXf rc2(3, 1); | ||
+ | MatrixXf rc3(3, 1); | ||
+ | MatrixXf rc4(3, 1); | ||
+ | MatrixXf rc5(3, 1); | ||
+ | |||
+ | MatrixXf jwc1(3, 1); | ||
+ | MatrixXf jwc2(3, 1); | ||
+ | MatrixXf jwc3(3, 1); | ||
+ | MatrixXf jwc4(3, 1); | ||
+ | MatrixXf jwc5(3, 1); | ||
+ | |||
+ | MatrixXf jv1(3, 1); | ||
+ | MatrixXf jv2(3, 1); | ||
+ | MatrixXf jv3(3, 1); | ||
+ | MatrixXf jv4(3, 1); | ||
+ | MatrixXf jv5(3, 1); | ||
+ | |||
+ | MatrixXf thv1, thv2, thv3, thv4, thv5; | ||
+ | MatrixXf gpcmd1(1, 1002), gpcmd2(1, 1002), gpcmd3(1, 1002), gpcmd4(1, 1002), gpcmd5(1, 1002); | ||
+ | |||
+ | MatrixXf dgp1(1, 1002); | ||
+ | MatrixXf dgp2(1, 1002); | ||
+ | MatrixXf dgp3(1, 1002); | ||
+ | MatrixXf dgp4(1, 1002); | ||
+ | MatrixXf dgp5(1, 1002); | ||
+ | |||
+ | |||
+ | // initial angles | ||
+ | th1 = 0; | ||
+ | th2 = 0; | ||
+ | th3 = 0; | ||
+ | th4 = 0; | ||
+ | th5 = 0; | ||
+ | |||
+ | float ev1 = 30; | ||
+ | float ev2 = 30; | ||
+ | float ev3 = 30; | ||
+ | float i = 0; | ||
+ | float k = 0; | ||
+ | |||
+ | float gpi1 = 2292; | ||
+ | float gpi2 = 2086; | ||
+ | float gpi3 = 2007; | ||
+ | float gpi4 = 538; | ||
+ | float gpi5 = 509; | ||
+ | |||
+ | |||
+ | if (method == 1) | ||
+ | { | ||
+ | bool status = true; | ||
+ | while (status) | ||
+ | { | ||
+ | |||
+ | //Error threshold , to stop the iteration and accept a solution | ||
+ | if (ev1 < 1 & ev2 < 1 & ev3 < 1) | ||
+ | { | ||
+ | status = false; | ||
+ | } | ||
+ | |||
+ | //If the solution is not converging , should stop the program | ||
+ | if (i > 1000) | ||
+ | { | ||
+ | status = false; | ||
+ | std:: | ||
+ | std:: | ||
+ | std:: | ||
+ | Sleep(1000000000); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | float a1p11 = cos(th1); | ||
+ | float a1p12 = 0; | ||
+ | float a1p13 = -sin(th1); | ||
+ | float a1p14 = 0; | ||
+ | |||
+ | float a1p21 = sin(th1); | ||
+ | float a1p22 = 0; | ||
+ | float a1p23 = cos(th1); | ||
+ | float a1p24 = 0; | ||
+ | |||
+ | float a1p31 = 0; | ||
+ | float a1p32 = -1; | ||
+ | float a1p33 = 0; | ||
+ | float a1p34 = L1; | ||
+ | |||
+ | float a1p41 = 0; | ||
+ | float a1p42 = 0; | ||
+ | float a1p43 = 0; | ||
+ | float a1p44 = 1; | ||
+ | |||
+ | A1 << a1p11, a1p12, a1p13, a1p14, | ||
+ | a1p21, a1p22, a1p23, a1p24, | ||
+ | a1p31, a1p32, a1p33, a1p34, | ||
+ | a1p41, a1p42, a1p43, a1p44; | ||
+ | |||
+ | |||
+ | // | ||
+ | float a2p11 = cos(th2); | ||
+ | float a2p12 = -sin(th2); | ||
+ | float a2p13 = 0; | ||
+ | float a2p14 = L2*cos(th2); | ||
+ | |||
+ | float a2p21 = sin(th2); | ||
+ | float a2p22 = cos(th2); | ||
+ | float a2p23 = 0; | ||
+ | float a2p24 = L2*sin(th2); | ||
+ | |||
+ | float a2p31 = 0; | ||
+ | float a2p32 = 0; | ||
+ | float a2p33 = 1; | ||
+ | float a2p34 = 0; | ||
+ | |||
+ | float a2p41 = 0; | ||
+ | float a2p42 = 0; | ||
+ | float a2p43 = 0; | ||
+ | float a2p44 = 1; | ||
+ | |||
+ | A2 << a2p11, a2p12, a2p13, a2p14, | ||
+ | a2p21, a2p22, a2p23, a2p24, | ||
+ | a2p31, a2p32, a2p33, a2p34, | ||
+ | a2p41, a2p42, a2p43, a2p44; | ||
+ | |||
+ | |||
+ | |||
+ | // | ||
+ | float a3p11 = cos(th3); | ||
+ | float a3p12 = -sin(th3); | ||
+ | float a3p13 = 0; | ||
+ | float a3p14 = L3*cos(th3); | ||
+ | |||
+ | float a3p21 = sin(th3); | ||
+ | float a3p22 = cos(th3); | ||
+ | float a3p23 = 0; | ||
+ | float a3p24 = L3*sin(th3); | ||
+ | |||
+ | float a3p31 = 0; | ||
+ | float a3p32 = 0; | ||
+ | float a3p33 = 1; | ||
+ | float a3p34 = 0; | ||
+ | |||
+ | float a3p41 = 0; | ||
+ | float a3p42 = 0; | ||
+ | float a3p43 = 0; | ||
+ | float a3p44 = 1; | ||
+ | |||
+ | A3 << a3p11, a3p12, a3p13, a3p14, | ||
+ | a3p21, a3p22, a3p23, a3p24, | ||
+ | a3p31, a3p32, a3p33, a3p34, | ||
+ | a3p41, a3p42, a3p43, a3p44; | ||
+ | |||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | float a4p11 = cos(th4); | ||
+ | float a4p12 = 0; | ||
+ | float a4p13 = sin(th4); | ||
+ | float a4p14 = 0; | ||
+ | |||
+ | float a4p21 = sin(th4); | ||
+ | float a4p22 = 0; | ||
+ | float a4p23 = -cos(th4); | ||
+ | float a4p24 = 0; | ||
+ | |||
+ | float a4p31 = 0; | ||
+ | float a4p32 = 1; | ||
+ | float a4p33 = 0; | ||
+ | float a4p34 = 0; | ||
+ | |||
+ | float a4p41 = 0; | ||
+ | float a4p42 = 0; | ||
+ | float a4p43 = 0; | ||
+ | float a4p44 = 1; | ||
+ | |||
+ | A4 << a4p11, a4p12, a4p13, a4p14, | ||
+ | a4p21, a4p22, a4p23, a4p24, | ||
+ | a4p31, a4p32, a4p33, a4p34, | ||
+ | a4p41, a4p42, a4p43, a4p44; | ||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | float a5p11 = cos(th5); | ||
+ | float a5p12 = -sin(th5); | ||
+ | float a5p13 = 0; | ||
+ | float a5p14 = 0; | ||
+ | |||
+ | float a5p21 = sin(th5); | ||
+ | float a5p22 = cos(th5); | ||
+ | float a5p23 = 0; | ||
+ | float a5p24 = 0; | ||
+ | |||
+ | float a5p31 = 0; | ||
+ | float a5p32 = 0; | ||
+ | float a5p33 = 1; | ||
+ | float a5p34 = L4 + L5; | ||
+ | |||
+ | float a5p41 = 0; | ||
+ | float a5p42 = 0; | ||
+ | float a5p43 = 0; | ||
+ | float a5p44 = 1; | ||
+ | |||
+ | |||
+ | A5 << a5p11, a5p12, a5p13, a5p14, | ||
+ | a5p21, a5p22, a5p23, a5p24, | ||
+ | a5p31, a5p32, a5p33, a5p34, | ||
+ | a5p41, a5p42, a5p43, a5p44; | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | // | ||
+ | //A12 A123 A1234 A12345 | ||
+ | |||
+ | A12 = A1*A2; | ||
+ | A123 = A1*A2*A3; | ||
+ | A1234 = A1*A2*A3*A4; | ||
+ | A12345 = A1*A2*A3*A4*A5; | ||
+ | |||
+ | |||
+ | // | ||
+ | Jw(0, 0) = 0; | ||
+ | Jw(1, 0) = 0; | ||
+ | Jw(2, 0) = 1; | ||
+ | |||
+ | Jw(0, 1) = A1(0, 2); | ||
+ | Jw(1, 1) = A1(1, 2); | ||
+ | Jw(2, 1) = A1(2, 2); | ||
+ | |||
+ | Jw(0, 2) = A12(0, 2); | ||
+ | Jw(1, 2) = A12(1, 2); | ||
+ | Jw(2, 2) = A12(2, 2); | ||
+ | |||
+ | Jw(0, 3) = A123(0, 2); | ||
+ | Jw(1, 3) = A123(1, 2); | ||
+ | Jw(2, 3) = A123(2, 2); | ||
+ | |||
+ | Jw(0, 4) = A1234(0, 2); | ||
+ | Jw(1, 4) = A1234(1, 2); | ||
+ | Jw(2, 4) = A1234(2, 2); | ||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | //First calculate the second element of the cross product | ||
+ | |||
+ | Oeff(0, 0) = A12345(0, 3); | ||
+ | Oeff(1, 0) = A12345(1, 3); | ||
+ | Oeff(2, 0) = A12345(2, 3); | ||
+ | |||
+ | O00(0, 0) = 0; | ||
+ | O00(1, 0) = 0; | ||
+ | O00(2, 0) = 0; | ||
+ | |||
+ | O01(0, 0) = A1(0, 3); | ||
+ | O01(1, 0) = A1(1, 3); | ||
+ | O01(2, 0) = A1(2, 3); | ||
+ | |||
+ | O02(0, 0) = A12(0, 3); | ||
+ | O02(1, 0) = A12(1, 3); | ||
+ | O02(2, 0) = A12(2, 3); | ||
+ | |||
+ | O03(0, 0) = A123(0, 3); | ||
+ | O03(1, 0) = A123(1, 3); | ||
+ | O03(2, 0) = A123(2, 3); | ||
+ | |||
+ | O04(0, 0) = A1234(0, 3); | ||
+ | O04(1, 0) = A1234(1, 3); | ||
+ | O04(2, 0) = A1234(2, 3); | ||
+ | |||
+ | //The second element is the difference between end effector position and frame i-1 position | ||
+ | rc1 = Oeff - O00; | ||
+ | rc2 = Oeff - O01; | ||
+ | rc3 = Oeff - O02; | ||
+ | rc4 = Oeff - O03; | ||
+ | rc5 = Oeff - O04; | ||
+ | |||
+ | |||
+ | |||
+ | // First element of the cross product | ||
+ | // Is the same as the Jw | ||
+ | jwc1(0, 0) = Jw(0, 0); | ||
+ | jwc1(1, 0) = Jw(1, 0); | ||
+ | jwc1(2, 0) = Jw(2, 0); | ||
+ | |||
+ | jwc2(0, 0) = Jw(0, 1); | ||
+ | jwc2(1, 0) = Jw(1, 1); | ||
+ | jwc2(2, 0) = Jw(2, 1); | ||
+ | |||
+ | jwc3(0, 0) = Jw(0, 2); | ||
+ | jwc3(1, 0) = Jw(1, 2); | ||
+ | jwc3(2, 0) = Jw(2, 2); | ||
+ | |||
+ | jwc4(0, 0) = Jw(0, 3); | ||
+ | jwc4(1, 0) = Jw(1, 3); | ||
+ | jwc4(2, 0) = Jw(2, 3); | ||
+ | |||
+ | jwc5(0, 0) = Jw(0, 4); | ||
+ | jwc5(1, 0) = Jw(1, 4); | ||
+ | jwc5(2, 0) = Jw(2, 4); | ||
+ | |||
+ | |||
+ | // | ||
+ | float jwc1vp1 = jwc1(0, 0); | ||
+ | float jwc1vp2 = jwc1(1, 0); | ||
+ | float jwc1vp3 = jwc1(2, 0); | ||
+ | Vector3f jwc1v(jwc1vp1, | ||
+ | |||
+ | float rc1vp1 = rc1(0, 0); | ||
+ | float rc1vp2 = rc1(1, 0); | ||
+ | float rc1vp3 = rc1(2, 0); | ||
+ | Vector3f rc1v(rc1vp1, | ||
+ | |||
+ | float jwc2vp1 = jwc2(0, 0); | ||
+ | float jwc2vp2 = jwc2(1, 0); | ||
+ | float jwc2vp3 = jwc2(2, 0); | ||
+ | Vector3f jwc2v(jwc2vp1, | ||
+ | |||
+ | float rc2vp1 = rc2(0, 0); | ||
+ | float rc2vp2 = rc2(1, 0); | ||
+ | float rc2vp3 = rc2(2, 0); | ||
+ | Vector3f rc2v(rc2vp1, | ||
+ | |||
+ | float jwc3vp1 = jwc3(0, 0); | ||
+ | float jwc3vp2 = jwc3(1, 0); | ||
+ | float jwc3vp3 = jwc3(2, 0); | ||
+ | Vector3f jwc3v(jwc3vp1, | ||
+ | |||
+ | float rc3vp1 = rc3(0, 0); | ||
+ | float rc3vp2 = rc3(1, 0); | ||
+ | float rc3vp3 = rc3(2, 0); | ||
+ | Vector3f rc3v(rc3vp1, | ||
+ | |||
+ | float jwc4vp1 = jwc4(0, 0); | ||
+ | float jwc4vp2 = jwc4(1, 0); | ||
+ | float jwc4vp3 = jwc4(2, 0); | ||
+ | Vector3f jwc4v(jwc4vp1, | ||
+ | |||
+ | float rc4vp1 = rc4(0, 0); | ||
+ | float rc4vp2 = rc4(1, 0); | ||
+ | float rc4vp3 = rc4(2, 0); | ||
+ | Vector3f rc4v(rc4vp1, | ||
+ | |||
+ | float jwc5vp1 = jwc5(0, 0); | ||
+ | float jwc5vp2 = jwc5(1, 0); | ||
+ | float jwc5vp3 = jwc5(2, 0); | ||
+ | Vector3f jwc5v(jwc5vp1, | ||
+ | |||
+ | float rc5vp1 = rc5(0, 0); | ||
+ | float rc5vp2 = rc5(1, 0); | ||
+ | float rc5vp3 = rc5(2, 0); | ||
+ | Vector3f rc5v(rc5vp1, | ||
+ | |||
+ | //Do the cross product | ||
+ | jv1 = jwc1v.cross(rc1v); | ||
+ | jv2 = jwc2v.cross(rc2v); | ||
+ | jv3 = jwc3v.cross(rc3v); | ||
+ | jv4 = jwc4v.cross(rc4v); | ||
+ | jv5 = jwc5v.cross(rc5v); | ||
+ | |||
+ | |||
+ | // FIll Jv with the cross products calculated before | ||
+ | Jv(0, 0) = jv1(0, 0); | ||
+ | Jv(1, 0) = jv1(1, 0); | ||
+ | Jv(2, 0) = jv1(2, 0); | ||
+ | |||
+ | Jv(0, 1) = jv2(0, 0); | ||
+ | Jv(1, 1) = jv2(1, 0); | ||
+ | Jv(2, 1) = jv2(2, 0); | ||
+ | |||
+ | Jv(0, 2) = jv3(0, 0); | ||
+ | Jv(1, 2) = jv3(1, 0); | ||
+ | Jv(2, 2) = jv3(2, 0); | ||
+ | |||
+ | Jv(0, 3) = jv4(0, 0); | ||
+ | Jv(1, 3) = jv4(1, 0); | ||
+ | Jv(2, 3) = jv4(2, 0); | ||
+ | |||
+ | Jv(0, 4) = jv5(0, 0); | ||
+ | Jv(1, 4) = jv5(1, 0); | ||
+ | Jv(2, 4) = jv5(2, 0); | ||
+ | |||
+ | |||
+ | |||
+ | // Fill Jacobian | ||
+ | // Jv is the upper part ( first three rows and n columns (n=number of joints) | ||
+ | // Jw is the lower part ( last three rows and n columns (n=number of joints) | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | |||
+ | //Get end effector position | ||
+ | float x = A12345(0, 3); | ||
+ | float y = A12345(1, 3); | ||
+ | float z = A12345(2, 3); | ||
+ | |||
+ | |||
+ | // | ||
+ | // | ||
+ | MatrixXf evector(6, 1); | ||
+ | evector(0, | ||
+ | evector(1, | ||
+ | evector(2, | ||
+ | evector(3, | ||
+ | evector(4, | ||
+ | evector(5, | ||
+ | |||
+ | // Calculate tranpose of Jacobian | ||
+ | MatrixXf Jt(5, 6); | ||
+ | Jt = Jacobian.transpose(); | ||
+ | // | ||
+ | int lambida = 1; | ||
+ | lambida = lambida*lambida; | ||
+ | |||
+ | // Create identity 6x6 | ||
+ | MatrixXf Id(6, 6); | ||
+ | Id << 1, 0, 0, 0, 0, 0, | ||
+ | 0, 1, 0, 0, 0, 0, | ||
+ | 0, 0, 1, 0, 0, 0, | ||
+ | 0, 0, 0, 1, 0, 0, | ||
+ | 0, 0, 0, 0, 1, 0, | ||
+ | 0, 0, 0, 0, 0, 1; | ||
+ | |||
+ | |||
+ | // | ||
+ | MatrixXf cof1(6, 6); | ||
+ | cof1 = (Jacobian*Jt); | ||
+ | |||
+ | MatrixXf cof2(6, 6); | ||
+ | cof2 = (lambida*Id); | ||
+ | |||
+ | MatrixXf cof(6, 6); | ||
+ | cof = cof1 + cof2; | ||
+ | |||
+ | MatrixXf invcof(6, 6); | ||
+ | invcof = cof.inverse(); | ||
+ | |||
+ | // Create the vector to hold the damped least squares solution | ||
+ | MatrixXf thetavector(5, | ||
+ | |||
+ | //Apply damped least squares equation | ||
+ | thetavector = Jt*invcof*evector; | ||
+ | |||
+ | //Create variables to store the solution of this iteration | ||
+ | float t1, t2, t3, t4, t5; | ||
+ | |||
+ | t1 = thetavector(0, | ||
+ | t2 = thetavector(1, | ||
+ | t3 = thetavector(2, | ||
+ | t4 = thetavector(3, | ||
+ | t5 = thetavector(4, | ||
+ | |||
+ | // | ||
+ | t1 = t1*pi / 180; | ||
+ | t2 = t2*pi / 180; | ||
+ | t3 = t3*pi / 180; | ||
+ | t4 = t4*pi / 180; | ||
+ | t5 = t5*pi / 180; | ||
+ | |||
+ | |||
+ | // Update new angles to be used on the next iteration | ||
+ | th1 = th1 + t1; | ||
+ | th2 = th2 + t2; | ||
+ | th5 = th5 + t5; | ||
+ | th3 = 0; // Physical limitation of DASL arm , is better to not move this joint | ||
+ | //th3 = th3 + t3; WE ARE USING POSITION CONTROL , SO WE | ||
+ | //th4 = th4 + t4; MUST IMPOSE SOME RESTRICTION ON THE ANGLES IN ORDER TO KEEP THE END EFFECTOR VERTICAL | ||
+ | |||
+ | |||
+ | //Angles restrictions | ||
+ | th4 = -th2 - th3; | ||
+ | |||
+ | |||
+ | // Store the command to be send to the dynamixel | ||
+ | // | ||
+ | // | ||
+ | dgp1(0, i) = th1*(1 / 0.088)*(180 / pi); | ||
+ | dgp2(0, i) = th2*(1 / 0.088)*(180 / pi); | ||
+ | dgp3(0, i) = th3*(1 / 0.088)*(180 / pi); | ||
+ | dgp4(0, i) = th4*(1 / 0.29)*(180 / pi); | ||
+ | dgp5(0, i) = th5*(1 / 0.29)*(180 / pi); | ||
+ | |||
+ | |||
+ | //Get errors to compare to a threshold and see if the solution was found | ||
+ | ev1 = evector(0, 0); | ||
+ | ev2 = evector(1, 0); | ||
+ | ev3 = evector(2, 0); | ||
+ | ev1 = abs(ev1); | ||
+ | ev2 = abs(ev2); | ||
+ | ev3 = abs(ev3); | ||
+ | |||
+ | //update counters | ||
+ | k = i; | ||
+ | i = i + 1; | ||
+ | |||
+ | } | ||
+ | |||
+ | //After finding the solution , check what is the final end effector position | ||
+ | float xeff = A12345(0, 3); | ||
+ | float yeff = A12345(1, 3); | ||
+ | float zeff = A12345(2, 3); | ||
+ | |||
+ | //Copy all the commands to be send to the dynamixel | ||
+ | // As the dynamixels start in a initial goal position | ||
+ | // we just need to add / subtract the goals given by each iteration | ||
+ | for (int cc = 0; cc <= k; cc++) | ||
+ | |||
+ | { | ||
+ | gpcmd1(0, | ||
+ | gpcmd2(0, | ||
+ | gpcmd3(0, | ||
+ | gpcmd4(0, | ||
+ | gpcmd5(0, | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | } // end of while loop | ||
+ | |||
+ | |||
+ | |||
+ | if (method == 2) | ||
+ | { | ||
+ | bool status = true; | ||
+ | while (status) | ||
+ | { | ||
+ | |||
+ | //Error threshold , to stop the iteration and accept a solution | ||
+ | if (ev1 < 1 & ev2 < 1 & ev3 < 1) | ||
+ | { | ||
+ | status = false; | ||
+ | } | ||
+ | |||
+ | //If the solution is not converging , should stop the program | ||
+ | if (i > 1000) | ||
+ | { | ||
+ | status = false; | ||
+ | std:: | ||
+ | std:: | ||
+ | std:: | ||
+ | Sleep(1000000000); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | float a1p11 = cos(th1); | ||
+ | float a1p12 = 0; | ||
+ | float a1p13 = -sin(th1); | ||
+ | float a1p14 = 0; | ||
+ | |||
+ | float a1p21 = sin(th1); | ||
+ | float a1p22 = 0; | ||
+ | float a1p23 = cos(th1); | ||
+ | float a1p24 = 0; | ||
+ | |||
+ | float a1p31 = 0; | ||
+ | float a1p32 = -1; | ||
+ | float a1p33 = 0; | ||
+ | float a1p34 = L1; | ||
+ | |||
+ | float a1p41 = 0; | ||
+ | float a1p42 = 0; | ||
+ | float a1p43 = 0; | ||
+ | float a1p44 = 1; | ||
+ | |||
+ | A1 << a1p11, a1p12, a1p13, a1p14, | ||
+ | a1p21, a1p22, a1p23, a1p24, | ||
+ | a1p31, a1p32, a1p33, a1p34, | ||
+ | a1p41, a1p42, a1p43, a1p44; | ||
+ | |||
+ | |||
+ | // | ||
+ | float a2p11 = cos(th2); | ||
+ | float a2p12 = -sin(th2); | ||
+ | float a2p13 = 0; | ||
+ | float a2p14 = L2*cos(th2); | ||
+ | |||
+ | float a2p21 = sin(th2); | ||
+ | float a2p22 = cos(th2); | ||
+ | float a2p23 = 0; | ||
+ | float a2p24 = L2*sin(th2); | ||
+ | |||
+ | float a2p31 = 0; | ||
+ | float a2p32 = 0; | ||
+ | float a2p33 = 1; | ||
+ | float a2p34 = 0; | ||
+ | |||
+ | float a2p41 = 0; | ||
+ | float a2p42 = 0; | ||
+ | float a2p43 = 0; | ||
+ | float a2p44 = 1; | ||
+ | |||
+ | A2 << a2p11, a2p12, a2p13, a2p14, | ||
+ | a2p21, a2p22, a2p23, a2p24, | ||
+ | a2p31, a2p32, a2p33, a2p34, | ||
+ | a2p41, a2p42, a2p43, a2p44; | ||
+ | |||
+ | |||
+ | |||
+ | // | ||
+ | float a3p11 = cos(th3); | ||
+ | float a3p12 = -sin(th3); | ||
+ | float a3p13 = 0; | ||
+ | float a3p14 = L3*cos(th3); | ||
+ | |||
+ | float a3p21 = sin(th3); | ||
+ | float a3p22 = cos(th3); | ||
+ | float a3p23 = 0; | ||
+ | float a3p24 = L3*sin(th3); | ||
+ | |||
+ | float a3p31 = 0; | ||
+ | float a3p32 = 0; | ||
+ | float a3p33 = 1; | ||
+ | float a3p34 = 0; | ||
+ | |||
+ | float a3p41 = 0; | ||
+ | float a3p42 = 0; | ||
+ | float a3p43 = 0; | ||
+ | float a3p44 = 1; | ||
+ | |||
+ | A3 << a3p11, a3p12, a3p13, a3p14, | ||
+ | a3p21, a3p22, a3p23, a3p24, | ||
+ | a3p31, a3p32, a3p33, a3p34, | ||
+ | a3p41, a3p42, a3p43, a3p44; | ||
+ | |||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | float a4p11 = cos(th4); | ||
+ | float a4p12 = 0; | ||
+ | float a4p13 = sin(th4); | ||
+ | float a4p14 = 0; | ||
+ | |||
+ | float a4p21 = sin(th4); | ||
+ | float a4p22 = 0; | ||
+ | float a4p23 = -cos(th4); | ||
+ | float a4p24 = 0; | ||
+ | |||
+ | float a4p31 = 0; | ||
+ | float a4p32 = 1; | ||
+ | float a4p33 = 0; | ||
+ | float a4p34 = 0; | ||
+ | |||
+ | float a4p41 = 0; | ||
+ | float a4p42 = 0; | ||
+ | float a4p43 = 0; | ||
+ | float a4p44 = 1; | ||
+ | |||
+ | A4 << a4p11, a4p12, a4p13, a4p14, | ||
+ | a4p21, a4p22, a4p23, a4p24, | ||
+ | a4p31, a4p32, a4p33, a4p34, | ||
+ | a4p41, a4p42, a4p43, a4p44; | ||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | float a5p11 = cos(th5); | ||
+ | float a5p12 = -sin(th5); | ||
+ | float a5p13 = 0; | ||
+ | float a5p14 = 0; | ||
+ | |||
+ | float a5p21 = sin(th5); | ||
+ | float a5p22 = cos(th5); | ||
+ | float a5p23 = 0; | ||
+ | float a5p24 = 0; | ||
+ | |||
+ | float a5p31 = 0; | ||
+ | float a5p32 = 0; | ||
+ | float a5p33 = 1; | ||
+ | float a5p34 = L4 + L5; | ||
+ | |||
+ | float a5p41 = 0; | ||
+ | float a5p42 = 0; | ||
+ | float a5p43 = 0; | ||
+ | float a5p44 = 1; | ||
+ | |||
+ | |||
+ | A5 << a5p11, a5p12, a5p13, a5p14, | ||
+ | a5p21, a5p22, a5p23, a5p24, | ||
+ | a5p31, a5p32, a5p33, a5p34, | ||
+ | a5p41, a5p42, a5p43, a5p44; | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | // | ||
+ | //A12 A123 A1234 A12345 | ||
+ | |||
+ | A12 = A1*A2; | ||
+ | A123 = A1*A2*A3; | ||
+ | A1234 = A1*A2*A3*A4; | ||
+ | A12345 = A1*A2*A3*A4*A5; | ||
+ | |||
+ | |||
+ | // | ||
+ | Jw(0, 0) = 0; | ||
+ | Jw(1, 0) = 0; | ||
+ | Jw(2, 0) = 1; | ||
+ | |||
+ | Jw(0, 1) = A1(0, 2); | ||
+ | Jw(1, 1) = A1(1, 2); | ||
+ | Jw(2, 1) = A1(2, 2); | ||
+ | |||
+ | Jw(0, 2) = A12(0, 2); | ||
+ | Jw(1, 2) = A12(1, 2); | ||
+ | Jw(2, 2) = A12(2, 2); | ||
+ | |||
+ | Jw(0, 3) = A123(0, 2); | ||
+ | Jw(1, 3) = A123(1, 2); | ||
+ | Jw(2, 3) = A123(2, 2); | ||
+ | |||
+ | Jw(0, 4) = A1234(0, 2); | ||
+ | Jw(1, 4) = A1234(1, 2); | ||
+ | Jw(2, 4) = A1234(2, 2); | ||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | //First calculate the second element of the cross product | ||
+ | |||
+ | Oeff(0, 0) = A12345(0, 3); | ||
+ | Oeff(1, 0) = A12345(1, 3); | ||
+ | Oeff(2, 0) = A12345(2, 3); | ||
+ | |||
+ | O00(0, 0) = 0; | ||
+ | O00(1, 0) = 0; | ||
+ | O00(2, 0) = 0; | ||
+ | |||
+ | O01(0, 0) = A1(0, 3); | ||
+ | O01(1, 0) = A1(1, 3); | ||
+ | O01(2, 0) = A1(2, 3); | ||
+ | |||
+ | O02(0, 0) = A12(0, 3); | ||
+ | O02(1, 0) = A12(1, 3); | ||
+ | O02(2, 0) = A12(2, 3); | ||
+ | |||
+ | O03(0, 0) = A123(0, 3); | ||
+ | O03(1, 0) = A123(1, 3); | ||
+ | O03(2, 0) = A123(2, 3); | ||
+ | |||
+ | O04(0, 0) = A1234(0, 3); | ||
+ | O04(1, 0) = A1234(1, 3); | ||
+ | O04(2, 0) = A1234(2, 3); | ||
+ | |||
+ | //The second element is the difference between end effector position and frame i-1 position | ||
+ | rc1 = Oeff - O00; | ||
+ | rc2 = Oeff - O01; | ||
+ | rc3 = Oeff - O02; | ||
+ | rc4 = Oeff - O03; | ||
+ | rc5 = Oeff - O04; | ||
+ | |||
+ | |||
+ | |||
+ | // First element of the cross product | ||
+ | // Is the same as the Jw | ||
+ | jwc1(0, 0) = Jw(0, 0); | ||
+ | jwc1(1, 0) = Jw(1, 0); | ||
+ | jwc1(2, 0) = Jw(2, 0); | ||
+ | |||
+ | jwc2(0, 0) = Jw(0, 1); | ||
+ | jwc2(1, 0) = Jw(1, 1); | ||
+ | jwc2(2, 0) = Jw(2, 1); | ||
+ | |||
+ | jwc3(0, 0) = Jw(0, 2); | ||
+ | jwc3(1, 0) = Jw(1, 2); | ||
+ | jwc3(2, 0) = Jw(2, 2); | ||
+ | |||
+ | jwc4(0, 0) = Jw(0, 3); | ||
+ | jwc4(1, 0) = Jw(1, 3); | ||
+ | jwc4(2, 0) = Jw(2, 3); | ||
+ | |||
+ | jwc5(0, 0) = Jw(0, 4); | ||
+ | jwc5(1, 0) = Jw(1, 4); | ||
+ | jwc5(2, 0) = Jw(2, 4); | ||
+ | |||
+ | |||
+ | // | ||
+ | float jwc1vp1 = jwc1(0, 0); | ||
+ | float jwc1vp2 = jwc1(1, 0); | ||
+ | float jwc1vp3 = jwc1(2, 0); | ||
+ | Vector3f jwc1v(jwc1vp1, | ||
+ | |||
+ | float rc1vp1 = rc1(0, 0); | ||
+ | float rc1vp2 = rc1(1, 0); | ||
+ | float rc1vp3 = rc1(2, 0); | ||
+ | Vector3f rc1v(rc1vp1, | ||
+ | |||
+ | float jwc2vp1 = jwc2(0, 0); | ||
+ | float jwc2vp2 = jwc2(1, 0); | ||
+ | float jwc2vp3 = jwc2(2, 0); | ||
+ | Vector3f jwc2v(jwc2vp1, | ||
+ | |||
+ | float rc2vp1 = rc2(0, 0); | ||
+ | float rc2vp2 = rc2(1, 0); | ||
+ | float rc2vp3 = rc2(2, 0); | ||
+ | Vector3f rc2v(rc2vp1, | ||
+ | |||
+ | float jwc3vp1 = jwc3(0, 0); | ||
+ | float jwc3vp2 = jwc3(1, 0); | ||
+ | float jwc3vp3 = jwc3(2, 0); | ||
+ | Vector3f jwc3v(jwc3vp1, | ||
+ | |||
+ | float rc3vp1 = rc3(0, 0); | ||
+ | float rc3vp2 = rc3(1, 0); | ||
+ | float rc3vp3 = rc3(2, 0); | ||
+ | Vector3f rc3v(rc3vp1, | ||
+ | |||
+ | float jwc4vp1 = jwc4(0, 0); | ||
+ | float jwc4vp2 = jwc4(1, 0); | ||
+ | float jwc4vp3 = jwc4(2, 0); | ||
+ | Vector3f jwc4v(jwc4vp1, | ||
+ | |||
+ | float rc4vp1 = rc4(0, 0); | ||
+ | float rc4vp2 = rc4(1, 0); | ||
+ | float rc4vp3 = rc4(2, 0); | ||
+ | Vector3f rc4v(rc4vp1, | ||
+ | |||
+ | float jwc5vp1 = jwc5(0, 0); | ||
+ | float jwc5vp2 = jwc5(1, 0); | ||
+ | float jwc5vp3 = jwc5(2, 0); | ||
+ | Vector3f jwc5v(jwc5vp1, | ||
+ | |||
+ | float rc5vp1 = rc5(0, 0); | ||
+ | float rc5vp2 = rc5(1, 0); | ||
+ | float rc5vp3 = rc5(2, 0); | ||
+ | Vector3f rc5v(rc5vp1, | ||
+ | |||
+ | //Do the cross product | ||
+ | jv1 = jwc1v.cross(rc1v); | ||
+ | jv2 = jwc2v.cross(rc2v); | ||
+ | jv3 = jwc3v.cross(rc3v); | ||
+ | jv4 = jwc4v.cross(rc4v); | ||
+ | jv5 = jwc5v.cross(rc5v); | ||
+ | |||
+ | |||
+ | // FIll Jv with the cross products calculated before | ||
+ | Jv(0, 0) = jv1(0, 0); | ||
+ | Jv(1, 0) = jv1(1, 0); | ||
+ | Jv(2, 0) = jv1(2, 0); | ||
+ | |||
+ | Jv(0, 1) = jv2(0, 0); | ||
+ | Jv(1, 1) = jv2(1, 0); | ||
+ | Jv(2, 1) = jv2(2, 0); | ||
+ | |||
+ | Jv(0, 2) = jv3(0, 0); | ||
+ | Jv(1, 2) = jv3(1, 0); | ||
+ | Jv(2, 2) = jv3(2, 0); | ||
+ | |||
+ | Jv(0, 3) = jv4(0, 0); | ||
+ | Jv(1, 3) = jv4(1, 0); | ||
+ | Jv(2, 3) = jv4(2, 0); | ||
+ | |||
+ | Jv(0, 4) = jv5(0, 0); | ||
+ | Jv(1, 4) = jv5(1, 0); | ||
+ | Jv(2, 4) = jv5(2, 0); | ||
+ | |||
+ | |||
+ | |||
+ | // Fill Jacobian | ||
+ | // Jv is the upper part ( first three rows and n columns (n=number of joints) | ||
+ | // Jw is the lower part ( last three rows and n columns (n=number of joints) | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | Jacobian(0, | ||
+ | Jacobian(1, | ||
+ | Jacobian(2, | ||
+ | Jacobian(3, | ||
+ | Jacobian(4, | ||
+ | Jacobian(5, | ||
+ | |||
+ | |||
+ | //Get end effector position | ||
+ | float x = A12345(0, 3); | ||
+ | float y = A12345(1, 3); | ||
+ | float z = A12345(2, 3); | ||
+ | |||
+ | |||
+ | // | ||
+ | // | ||
+ | MatrixXf evector(6, 1); | ||
+ | evector(0, | ||
+ | evector(1, | ||
+ | evector(2, | ||
+ | evector(3, | ||
+ | evector(4, | ||
+ | evector(5, | ||
+ | |||
+ | // Calculate tranpose of Jacobian | ||
+ | MatrixXf Jt(5, 6); | ||
+ | Jt = Jacobian.transpose(); | ||
+ | // | ||
+ | int lambida = 1; | ||
+ | lambida = lambida*lambida; | ||
+ | |||
+ | // Create identity 6x6 | ||
+ | MatrixXf Id(6, 6); | ||
+ | Id << 1, 0, 0, 0, 0, 0, | ||
+ | 0, 1, 0, 0, 0, 0, | ||
+ | 0, 0, 1, 0, 0, 0, | ||
+ | 0, 0, 0, 1, 0, 0, | ||
+ | 0, 0, 0, 0, 1, 0, | ||
+ | 0, 0, 0, 0, 0, 1; | ||
+ | |||
+ | |||
+ | // | ||
+ | MatrixXf cof1(6, 6); | ||
+ | cof1 = (Jacobian*Jt); | ||
+ | |||
+ | MatrixXf cof2(6, 6); | ||
+ | cof2 = (lambida*Id); | ||
+ | |||
+ | MatrixXf cof(6, 6); | ||
+ | cof = cof1 + cof2; | ||
+ | |||
+ | MatrixXf invcof(6, 6); | ||
+ | invcof = cof.inverse(); | ||
+ | |||
+ | // Create the vector to hold the damped least squares solution | ||
+ | MatrixXf thetavector(5, | ||
+ | |||
+ | //Apply damped least squares equation | ||
+ | thetavector = Jt*invcof*evector; | ||
+ | |||
+ | //Create variables to store the solution of this iteration | ||
+ | float t1, t2, t3, t4, t5; | ||
+ | |||
+ | t1 = thetavector(0, | ||
+ | t2 = thetavector(1, | ||
+ | t3 = thetavector(2, | ||
+ | t4 = thetavector(3, | ||
+ | t5 = thetavector(4, | ||
+ | |||
+ | // | ||
+ | t1 = t1*pi / 180; | ||
+ | t2 = t2*pi / 180; | ||
+ | t3 = t3*pi / 180; | ||
+ | t4 = t4*pi / 180; | ||
+ | t5 = t5*pi / 180; | ||
+ | |||
+ | |||
+ | // Update new angles to be used on the next iteration | ||
+ | th1 = th1 + t1; | ||
+ | th2 = th2 + t2; | ||
+ | th3 = 0; // Physical limitation of DASL arm , is better to not move this joint | ||
+ | th4 = th4 + t4; | ||
+ | th5 = th5 + t5; | ||
+ | |||
+ | |||
+ | |||
+ | // Store the command to be send to the dynamixel | ||
+ | // | ||
+ | // | ||
+ | dgp1(0, i) = th1*(1 / 0.088)*(180 / pi); | ||
+ | dgp2(0, i) = th2*(1 / 0.088)*(180 / pi); | ||
+ | dgp3(0, i) = th3*(1 / 0.088)*(180 / pi); | ||
+ | dgp4(0, i) = th4*(1 / 0.29)*(180 / pi); | ||
+ | dgp5(0, i) = th5*(1 / 0.29)*(180 / pi); | ||
+ | |||
+ | |||
+ | //Get errors to compare to a threshold and see if the solution was found | ||
+ | ev1 = evector(0, 0); | ||
+ | ev2 = evector(1, 0); | ||
+ | ev3 = evector(2, 0); | ||
+ | ev1 = abs(ev1); | ||
+ | ev2 = abs(ev2); | ||
+ | ev3 = abs(ev3); | ||
+ | |||
+ | //update counters | ||
+ | k = i; | ||
+ | i = i + 1; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | } // end of while loop | ||
+ | |||
+ | |||
+ | //After finding the solution , check what is the final end effector position | ||
+ | float xeff = A12345(0, 3); | ||
+ | float yeff = A12345(1, 3); | ||
+ | float zeff = A12345(2, 3); | ||
+ | |||
+ | //Copy all the commands to be send to the dynamixel | ||
+ | // As the dynamixels start in a initial goal position | ||
+ | // we just need to add / subtract the goals given by each iteration | ||
+ | for (int cc = 0; cc <= k; cc++) | ||
+ | |||
+ | { | ||
+ | gpcmd1(0, cc) = gpi1 - dgp1(0, cc); | ||
+ | gpcmd2(0, cc) = gpi2 - dgp2(0, cc); | ||
+ | gpcmd3(0, cc) = gpi3 - dgp3(0, cc); | ||
+ | gpcmd4(0, cc) = gpi4 - dgp4(0, cc); | ||
+ | gpcmd5(0, cc) = gpi5 - dgp5(0, cc); | ||
+ | |||
+ | } | ||
+ | |||
+ | //Write results on the CMD | ||
+ | std::cout << " -------------------------" | ||
+ | std::cout << " IK Algorithm found the solution ! " << std::endl; | ||
+ | std::cout << " Took " | ||
+ | std::cout << "Theta 1 :" << th1 * 180 / pi << std::endl; | ||
+ | std::cout << "Theta 2 :" << th2 * 180 / pi << std::endl; | ||
+ | std::cout << "Theta 3 :" << th3 * 180 / pi << std::endl; | ||
+ | std::cout << "Theta 4 :" << th4 * 180 / pi << std::endl; | ||
+ | std::cout << "Theta 5: " << th5 * 180 / pi << std::endl; | ||
+ | |||
+ | std::cout << " The end effector position is " << std::endl; | ||
+ | std::cout << " | ||
+ | std::cout << std::endl; | ||
+ | std::cout << std::endl; | ||
+ | std::cout << " The position entered was " << std::endl; | ||
+ | std::cout << " | ||
+ | std::cout << std::endl; | ||
+ | std::cout << std::endl; | ||
+ | |||
+ | std::cout << " The initial goals are " << std::endl; | ||
+ | std::cout << gpi1 << std::endl; | ||
+ | std::cout << gpi2 << std::endl; | ||
+ | std::cout << gpi3 << std::endl; | ||
+ | std::cout << gpi4 << std::endl; | ||
+ | std::cout << gpi5 << std::endl; | ||
+ | std::cout << std::endl; | ||
+ | |||
+ | |||
+ | std::cout << " The final goals are " << std::endl; | ||
+ | std::cout << gpcmd1(0, k) << std::endl; | ||
+ | std::cout << gpcmd2(0, k) << std::endl; | ||
+ | std::cout << gpcmd3(0, k) << std::endl; | ||
+ | std::cout << gpcmd4(0, k) << std::endl; | ||
+ | std::cout << gpcmd5(0, k) << std::endl; | ||
+ | std::cout << std::endl; | ||
+ | std::cout << "The path vector has " << k << " set of joint angles " << std::endl; | ||
+ | |||
+ | |||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </ |
robotic_manipulators_ik_cpp.1470543645.txt.gz · Last modified: by joaomatos