![](/media/cache/group/Diana_su_nero.jpg.50x50_q85.jpg)
test_IPKF
Dependencies: mbed
Diff: source/kinematic.c
- Revision:
- 0:fb6e494a7656
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/kinematic.c Wed Apr 20 10:03:58 2016 +0000 @@ -0,0 +1,614 @@ +#include "kinematic.h" +#include <stdio.h> + +/** + * @defgroup MACRO_GROUP + * + * @{ + */ + /** + * @brief + * Macro used to build the jacobian + * matrix column by column + */ +#define BUILD_JACOBIAN(J, p, z, i) \ + J->element[0][i]=p.element[0][0];\ + J->element[1][i]=p.element[1][0];\ + J->element[2][i]=p.element[2][0];\ + J->element[3][i]=z.element[0][0];\ + J->element[4][i]=z.element[1][0];\ + J->element[5][i]=z.element[2][0]; + +/** + * @brief + * Macro used to check if the joint angle + * are in the interval between -pi and pi + */ +#define CHECK_ANGLE()\ + while(joint->element[0][0] > PI)\ + joint->element[0][0] = joint->element[0][0] - 2*PI;\ + while(joint->element[0][0] < -PI)\ + joint->element[0][0] = joint->element[0][0] + 2*PI;\ + \ + while(joint->element[1][0] > PI)\ + joint->element[1][0] = joint->element[1][0] - 2*PI;\ + while(joint->element[1][0] < -PI)\ + joint->element[1][0] = joint->element[1][0] + 2*PI;\ + \ + while(joint->element[2][0] > PI)\ + joint->element[2][0] = joint->element[2][0] - 2*PI;\ + while(joint->element[2][0] < -PI)\ + joint->element[2][0] = joint->element[2][0] + 2*PI;\ + \ + while(joint->element[3][0] > PI)\ + joint->element[3][0] = joint->element[3][0] - 2*PI;\ + while(joint->element[3][0] < -PI)\ + joint->element[3][0] = joint->element[3][0] + 2*PI;\ + \ + while(joint->element[4][0] > PI)\ + joint->element[4][0] = joint->element[4][0] - 2*PI;\ + while(joint->element[4][0] < -PI)\ + joint->element[4][0] = joint->element[4][0] + 2*PI;\ + \ + while(joint->element[5][0] > PI)\ + joint->element[5][0] = joint->element[5][0] - 2*PI;\ + while(joint->element[5][0] < -PI)\ + joint->element[5][0] = joint->element[5][0] + 2*PI;\ + /** @} */ + +void DHP_update(DHP* dhp,matrix* joints) +{ + dhp[0].d = l1; + dhp[0].theta = joints->element[0][0]; + dhp[0].a = 0; + dhp[0].alpha = PI/2; + + dhp[1].d = 0; + dhp[1].theta = joints->element[1][0]; + dhp[1].a = l2; + dhp[1].alpha = 0; + + dhp[2].d = 0; + dhp[2].theta = joints->element[2][0]; + dhp[2].a = l3; + dhp[2].alpha = 0; + + dhp[3].d = 0; + dhp[3].theta = joints->element[3][0]; + dhp[3].a= l4; + dhp[3].alpha = -PI/2; + + dhp[4].d = 0; + dhp[4].theta = joints->element[4][0] + PI/2; + dhp[4].a = 0; + dhp[4].alpha = PI/2; + + dhp[5].d = l5; + dhp[5].theta = joints->element[5][0]; + dhp[5].a = 0; + dhp[5].alpha = 0; + + return; +} + +void DH_Transf(DHP* dhp, matrix* T) +{ + + T->element[0][0] = (float)cos(dhp->theta); + T->element[0][1] = (float)(-sin(dhp->theta)*cos(dhp->alpha)); + T->element[0][2] = (float)(sin(dhp->theta)*sin(dhp->alpha)); + T->element[0][3] = (float)(dhp->a * cos(dhp->theta)); + + T->element[1][0] = (float)sin(dhp->theta); + T->element[1][1] = (float)(cos(dhp->theta)*cos(dhp->alpha)); + T->element[1][2] = (float)(-cos(dhp->theta)*sin(dhp->alpha)); + T->element[1][3] = (float)(dhp->a * sin(dhp->theta)); + + T->element[2][0] = 0; + T->element[2][1] = (float)sin(dhp->alpha); + T->element[2][2] = (float)cos(dhp->alpha); + T->element[2][3] = dhp->d; + + T->element[3][0] = 0; + T->element[3][1] = 0; + T->element[3][2] = 0; + T->element[3][3] = 1; + + return; +} + +void DPKF(matrix* joint, matrix* p) +{ + + int val = 0; + matrix T01; + matrix T12; + matrix T23; + matrix T34; + matrix T45; + matrix T56; + matrix T_TCP; + + DHP dhp[6]; + + /**< initialization of matrices */ + InitMatrix(&T01,4,4); + InitMatrix(&T12,4,4); + InitMatrix(&T23,4,4); + InitMatrix(&T34,4,4); + InitMatrix(&T45,4,4); + InitMatrix(&T56,4,4); + InitMatrix(&T_TCP,4,4); + + /**< DHP initialization*/ + DHP_update(dhp, joint); + + /**< Homogeneous transformations */ + DH_Transf(&dhp[0], &T01); + DH_Transf(&dhp[1], &T12); + DH_Transf(&dhp[2], &T23); + DH_Transf(&dhp[3], &T34); + DH_Transf(&dhp[4], &T45); + DH_Transf(&dhp[5], &T56); + + /**< Tool center point transformation*/ + val = MxM(&T01, &T12, &T_TCP); + val += MxM(&T_TCP, &T23, &T_TCP); + val += MxM(&T_TCP, &T34, &T_TCP); + val += MxM(&T_TCP, &T45, &T_TCP); + val += MxM(&T_TCP, &T56, &T_TCP); + + if (val!=0) + { + return; + } + + /**< pose extrapolation*/ + p->element[0][0] = T_TCP.element[0][3]; + p->element[1][0] = T_TCP.element[1][3]; + p->element[2][0] = T_TCP.element[2][3]; + p->element[3][0] = (float)atan2(T_TCP.element[2][1],T_TCP.element[2][2]); + p->element[4][0] = (float)atan2(-T_TCP.element[2][0],sin(p->element[3][0])*T_TCP.element[2][1] + cos(p->element[3][0])*T_TCP.element[2][2]); + p->element[5][0] = (float)atan2(-cos(p->element[3][0])*T_TCP.element[0][1]+ sin(p->element[3][0]) * T_TCP.element[0][2],cos(p->element[3][0]) * T_TCP.element[1][1]- sin(p->element[3][0]) * T_TCP.element[1][2]); + + + /**< matrix delation*/ + DeleteMatrix(&T01); + DeleteMatrix(&T12); + DeleteMatrix(&T23); + DeleteMatrix(&T34); + DeleteMatrix(&T45); + DeleteMatrix(&T56); + DeleteMatrix(&T_TCP); + + return; +} + +void JacobianG(matrix* joint, matrix* Jg, matrix* T_TCP) +{ + int i = 0; + DHP dhp[6]; + + matrix T01; + matrix T12; + matrix T23; + matrix T34; + matrix T45; + matrix T56; + + matrix p0; + matrix p1; + matrix p2; + matrix p3; + matrix p4; + matrix p5; + matrix p_TCP; + + matrix z0; + matrix z1; + matrix z2; + matrix z3; + matrix z4; + matrix z5; + + matrix CrossP; + //p is matrix of RF origin positions + //z is matrix of k axis for each RF + + /*Matrix creation*/ + InitMatrix(&T01,4,4); + InitMatrix(&T12,4,4); + InitMatrix(&T23,4,4); + InitMatrix(&T34,4,4); + InitMatrix(&T45,4,4); + InitMatrix(&T56,4,4); + + InitMatrix(&p0,3,1); + InitMatrix(&p1,3,1); + InitMatrix(&p2,3,1); + InitMatrix(&p3,3,1); + InitMatrix(&p4,3,1); + InitMatrix(&p5,3,1); + InitMatrix(&p_TCP,3,1); + + InitMatrix(&z0,3,1); + InitMatrix(&z1,3,1); + InitMatrix(&z2,3,1); + InitMatrix(&z3,3,1); + InitMatrix(&z4,3,1); + InitMatrix(&z5,3,1); + + InitMatrix(&CrossP,3,1); + + + /**<compute dh_par */ + DHP_update(dhp,joint); + + /**>compute T from dhp*/ + DH_Transf(&dhp[0], &T01); + DH_Transf(&dhp[1], &T12); + DH_Transf(&dhp[2], &T23); + DH_Transf(&dhp[3], &T34); + DH_Transf(&dhp[4], &T45); + DH_Transf(&dhp[5], &T56); + + /* R0 - JOINT 1 + distance between Global RF origin & R0 origin + R0 k axis */ + p0.element[0][0] = 0; + p0.element[1][0] = 0; + p0.element[2][0] = 0; + + z0.element[0][0] = 0; + z0.element[1][0] = 0; + z0.element[2][0] = 1; + + + /* R1 -JOINT 2 + distance between Global RF origin & R1 origin + R1 k axis */ + for(i = 0; i < 3; i++) { + p1.element[i][0] = T01.element[i][3]; + } + // z1 = omo2rot(T02)*[0;0;1]; + for(i = 0; i < 3; i++) { + z1.element[i][0] = T01.element[i][2]; + } + + /* R2 -JOINT 3 + distance between Global RF origin & R2 origin + R2 k axis */ + MxM(&T01, &T12, T_TCP); + for(i = 0; i < 3; i++) { + p2.element[i][0] = T_TCP->element[i][3]; + } + // z2 = omo2rot(T02)*[0;0;1]; + for(i=0; i<3; i++) { + z2.element[i][0] = T_TCP->element[i][2]; + } + + /* R3 -JOINT 4 + distance between Global RF origin & R3 origin + R3 k axis */ + MxM(T_TCP, &T23, T_TCP); + for(i = 0; i < 3; i++) { + p3.element[i][0] = T_TCP->element[i][3]; + } + // z3 = omo2rot(T03)*[0;0;1]; + for(i = 0; i < 3; i++) { + z3.element[i][0] = T_TCP->element[i][2]; + } + + + /* R4 -JOINT 5 + distance between Global RF origin & R4 origin + R4 k axis */ + MxM(T_TCP, &T34, T_TCP); + for(i = 0; i < 3; i++) { + p4.element[i][0] = T_TCP->element[i][3]; + } + // z4 = omo2rot(T03)*[0;0;1]; + for(i = 0; i < 3; i++) { + z4.element[i][0] = T_TCP->element[i][2]; + } + + /* R5 -JOINT 6 + distance between Global RF origin & R5 origin + R5 k axis */ + MxM(T_TCP, &T45, T_TCP); + for(i = 0; i < 3; i++) { + p5.element[i][0] = T_TCP->element[i][3]; + } + // z5 = omo2rot(T03)*[0;0;1]; + for(i = 0; i < 3; i++) { + z5.element[i][0] = T_TCP->element[i][2]; + } + + MxM(T_TCP, &T56, T_TCP); + for(i = 0; i < 3; i++) { + p_TCP.element[i][0] = T_TCP->element[i][3]; + } + + /**compute distance from TCP*/ + + Sub(&p_TCP, &p0, &p0); + Sub(&p_TCP, &p1, &p1); + Sub(&p_TCP, &p2, &p2); + Sub(&p_TCP, &p3, &p3); + Sub(&p_TCP, &p4, &p4); + Sub(&p_TCP, &p5, &p5); + + /**compute jacobian*/ + + CrossProd(&z0, &p0, &CrossP); + + BUILD_JACOBIAN(Jg, CrossP, z0, 0) + + + CrossProd(&z1, &p1, &CrossP); + + BUILD_JACOBIAN(Jg, CrossP, z1, 1) + + + CrossProd(&z2, &p2, &CrossP); + + BUILD_JACOBIAN(Jg, CrossP, z2, 2) + + + CrossProd(&z3, &p3, &CrossP); + + BUILD_JACOBIAN(Jg, CrossP, z3, 3) + + + CrossProd(&z4, &p4, &CrossP); + + BUILD_JACOBIAN(Jg, CrossP, z4, 4) + + + + CrossProd(&z5, &p5, &CrossP); + + BUILD_JACOBIAN(Jg, CrossP, z5, 5) + + + DeleteMatrix(&p0); + DeleteMatrix(&p1); + DeleteMatrix(&p2); + DeleteMatrix(&p3); + DeleteMatrix(&p4); + DeleteMatrix(&p5); + DeleteMatrix(&p_TCP); + + DeleteMatrix(&z0); + DeleteMatrix(&z1); + DeleteMatrix(&z2); + DeleteMatrix(&z3); + DeleteMatrix(&z4); + DeleteMatrix(&z5); + + DeleteMatrix(&T01); + DeleteMatrix(&T12); + DeleteMatrix(&T23); + DeleteMatrix(&T34); + DeleteMatrix(&T45); + DeleteMatrix(&T56); + + DeleteMatrix(&CrossP); + + return; +} + +void JacobianA(matrix* joint, matrix* Ja) +{ + + int i = 0; + int j = 0; + + matrix Jg; + matrix M; + matrix Ttcp; + matrix JgA; + matrix JaA; + + matrix p; + + InitMatrix(&Jg, Ja->row, Ja->col ); + InitMatrix(&M, 3 ,3 ); + InitMatrix(&JgA, 3, 6 ); + InitMatrix(&JaA, 3, 6 ); + InitMatrix(&Ttcp, 4, 4 ); + InitMatrix(&p, 6, 1); + + JacobianG(joint, &Jg, &Ttcp); + + p.element[0][0] = Ttcp.element[0][3]; + p.element[1][0] = Ttcp.element[1][3]; + p.element[2][0] = Ttcp.element[2][3]; + p.element[3][0] = (float)atan2(Ttcp.element[2][1],Ttcp.element[2][2]); + p.element[4][0] = (float)atan2(-Ttcp.element[2][0],sin(p.element[3][0])*Ttcp.element[2][1]+cos(p.element[3][0])*Ttcp.element[2][2]); + p.element[5][0] = (float)atan2(-cos(p.element[3][0])*Ttcp.element[0][1]+ sin(p.element[3][0])*Ttcp.element[0][2],cos(p.element[3][0])*Ttcp.element[1][1]-sin(p.element[3][0])*Ttcp.element[1][2]); + + + // Transformation matrix + M.element[0][0] = (float)(cos(p.element[5][0])/cos(p.element[4][0])); + M.element[0][1] = (float)(sin(p.element[5][0])/cos(p.element[4][0])); + M.element[0][2] = 0; + + M.element[1][0] = (float)-sin(p.element[5][0]); + M.element[1][1] = (float)cos(p.element[5][0]); + M.element[1][2] = 0; + + M.element[2][0] = (float)(cos(p.element[5][0])*sin(p.element[4][0])/cos(p.element[4][0])); + M.element[2][1] = (float)(-sin(p.element[4][0])*sin(p.element[5][0])/cos(p.element[4][0])); + M.element[2][2] = 1; + + + for(i = 0; i < JgA.row; i++) { + for(j = 0; j< JgA.col; j++) { + JgA.element[i][j] = Jg.element[i+3][j]; + } + } + + MxM(&M, &JgA, &JaA); + + + for(i = 0; i < JaA.row; i++) { + for(j = 0; j< JaA.col; j++) { + Ja->element[i][j] = Jg.element[i][j]; + } + } + + for(i = 0; i < JaA.row; i++) { + for(j = 0; j< JaA.col; j++) { + Ja->element[i+3][j] = JaA.element[i][j]; + } + } + + DeleteMatrix(&M); + DeleteMatrix(&Jg); + DeleteMatrix(&JgA); + DeleteMatrix(&JaA); + DeleteMatrix(&Ttcp); + DeleteMatrix(&p); + + return; +} + +int IPKF (matrix* p, matrix* joint) +{ + + float sentinel = 2; + float sum = 0.0; + float error_G = 0.5; + float error_N = (float)0.0001; + float alpha = (float)0.27; //after several trials + int c = 0; + int i = 0; + + + DHP dhp[6]; + + matrix f;//computed position through Direct Kinematics + matrix J; + matrix delta_p; + matrix delta_q; + matrix inv_J; + + + InitMatrix(&f, 6, 1); + InitMatrix(&J, 6, 6); + InitMatrix(&inv_J, 6, 6); + InitMatrix(&delta_q, 6,1); + InitMatrix(&delta_p, 6,1); + + + /*gradient method*/ + while(sentinel >= error_G) { +// + /*compute the direct kinematics*/ + DPKF(joint, &f); + + /*compute dh_par*/ + DHP_update(dhp,joint); + + /*compute jacobian*/ + JacobianA(joint, &J);// to be defined + + /*compute the next value of angle*/ + Traspost(&J, &J); //Transpose of J saved in JT + axM(&J, alpha, &J);// Transpose of J (J) multiplied by alpha and saved in J + + /*subtraction of two pose objects into matrix*/ + Sub(p , &f, &delta_p); + + //alpha*J'*(p-f) + MxM(&J, &delta_p, &delta_q); + + Sum(joint, &delta_q, joint); + + CHECK_ANGLE() + + c = c+1; + + /*if the gradient method does not converge break the cycle*/ + if (c > 1000) { + break; + } + + /* norm of p_minus_f*/ + + for(i=0; i<6; i++) { + sum += (delta_p.element[i][0] * delta_p.element[i][0]); + } + sentinel = (float)sqrt(sum); + sum = 0; + } + +//printf("c = %d\n", c); + + /*Newton method*/ + while (sentinel >= error_N) { + + /*compute the direct kinematics*/ + DPKF(joint,&f); + + /*compute dh_par*/ + DHP_update(dhp,joint); + + /*compute jacobian*/ + JacobianA(joint, &J);// to be defined + + /*compute the next value of angle*/ + + //check if Jacobian is invertible + if(Inv(&J, &inv_J) == 6 ) { + break; + //printf("error due to jacobuan singularities"); + } + + Sub(p, &f, &delta_p); + + MxM(&inv_J, &delta_p, &delta_q); + + //q = q + J \ (p-f); + Sum(joint, &delta_q, joint); + + CHECK_ANGLE(); + + c = c+1; + + /*if the newton method does not converge break the cycle*/ + if (c > 2000) { + break; + } + /* norm of p_minus_f*/ + sum = 0.0; + + for(i=0; i<6; i++) { + sum += delta_p.element[i][0] * delta_p.element[i][0]; + } + sentinel = (float)sqrt(sum); + } + + DeleteMatrix(&f); + DeleteMatrix(&J); + DeleteMatrix(&delta_p); + DeleteMatrix(&delta_q); + DeleteMatrix(&inv_J); + //printf("c = %d\n",c); + if(c >=2000) + { + return 1; + } + else + { + return 0; + } +} + +void Print_DHP(DHP* dhp) +{ + printf("d = %f\n",dhp->d); + printf("theta = %f\n",dhp->theta); + printf("a = %f\n",dhp->a); + printf("alpha = %f\n",dhp->alpha); + printf("\n"); +} + + + +