|
| 1 | +#include<math.h> |
| 2 | +#include"Solver.h" |
| 3 | +void Solver::Pos_calculation(double length1,double length2,Point Input_Angle) |
| 4 | +{ Angle[0].x=Input_Angle.x*M_PI/180; //给定的两关节角存储在Angle【0】 |
| 5 | + Angle[0].y=Input_Angle.y*M_PI/180; //得到的世界坐标系的点存储在 point_World |
| 6 | + point_World.x=length1*cos(Angle[0].x)+length2*cos(Angle[0].y); |
| 7 | + point_World.y=length1*sin(Angle[0].x)+length2*sin(Angle[0].y); |
| 8 | +} |
| 9 | +void Solver::Neg_calculation(double l1,double l2,Point Input_Point) |
| 10 | +{ point_World.x=Input_Point.x; |
| 11 | + point_World.y=Input_Point.y; |
| 12 | + double x=point_World.x; |
| 13 | + double y=point_World.y; |
| 14 | + double m,delt; |
| 15 | + double result[2][2]={2*M_PI,2*M_PI,2*M_PI,2*M_PI}; //第一个下标0--关节1,1--关节2 |
| 16 | + double is_boor[2]={0,0}; |
| 17 | + double temp[2][4]; //第一个下标0--关节1的临时变量,1--关节2的临时变量 |
| 18 | + int i,j; |
| 19 | + m=(x*x+y*y+l2*l2-l1*l1)/(2*l2); |
| 20 | + delt=pow(y,4)+(x*x-m*m)*y*y; |
| 21 | + if(delt<0) |
| 22 | + number=0; |
| 23 | + else |
| 24 | + { |
| 25 | + temp[1][0]=(m*x+sqrt(delt))/(x*x+y*y); // 此时,若number>=0,则关节角1有两种可能,重根视为2个;可能的关节角为 0,1, |
| 26 | + temp[1][2]=(m*x-sqrt(delt))/(x*x+y*y); // 则temp[0][]依次存储关节1的cos0,sin0,cos1,sin1的计算值,此时可能大于1 |
| 27 | + if(y==0){ // temp[1][]依次存储关节2的 cos0,sin0,cos1,sin1的计算值, |
| 28 | + temp[0][0]=(x-l2*temp[1][0])/l1; |
| 29 | + temp[0][2]=(x-l2*temp[1][2])/l1; |
| 30 | + if (fabs(temp[1][0])<=1){ |
| 31 | + result[1][0]=acos(temp[1][0]); |
| 32 | + result[1][1]=-acos(temp[1][2]); |
| 33 | + } |
| 34 | + if (fabs(temp[0][0])<=1){ |
| 35 | + result[0][0]=-acos(temp[0][0]); |
| 36 | + result[0][1]=acos(temp[0][2]); |
| 37 | + } |
| 38 | + } |
| 39 | + else{ |
| 40 | + temp[1][1]=(m-x*temp[1][0])/y; |
| 41 | + temp[1][3]=(m-x*temp[1][2])/y; |
| 42 | + for(i=0;i<4;i+=2){ |
| 43 | + temp[0][i]=(x-l2*temp[1][i])/l1; |
| 44 | + temp[0][i+1]=(y-l2*temp[1][i+1])/l1; |
| 45 | + } |
| 46 | + for(j=0;j<2;j++){ |
| 47 | + for(i=0;i<4;i+=2){ |
| 48 | + if(fabs(temp[j][i])<=1) // 对函数取反余弦函数 取值范围 0,π 但关节角的活动范围为 负180-180;因此可以根据sin 值的正负确定关节角的 |
| 49 | + if(temp[j][i+1]<0) //正负,result 2依次存储关节角2 的两种可能角度 0,1 ,但是也有可能不存在,此时是默认值 2*M_PI |
| 50 | + result[j][i/2]=-acos(temp[j][i]); //例如 可能角0不存在,则result2【0】= 2*M_PI |
| 51 | + else |
| 52 | + result[j][i/2]=acos(temp[j][i]); |
| 53 | + } |
| 54 | + } |
| 55 | + } |
| 56 | + for(i=0;i<2;i++){ |
| 57 | + if ((fabs(result[0][i])<=M_PI)&&(fabs(result[1][i])<=M_PI)){ |
| 58 | + is_boor[i]=1; // 若 (fabs(result[0][i])<=M_PI)&&(fabs(result[1][i])<=M_PI)为真,说明关节角1,2的可能角i--i |
| 59 | + number++; // 均存在,注:可能会出现一个小于M_PI,一个大于,这样也即是说不能同时存在i-i满足方程 |
| 60 | + } //这样也相对于方程组无界;is_boor[i]=1表示i--i存在 ,即方程组有解,能找到关节角1,2满足方程组 |
| 61 | + result[0][i]= result[0][i]*180/M_PI; |
| 62 | + result[1][i]= result[1][i]*180/M_PI; |
| 63 | + } |
| 64 | + if(number==1){ |
| 65 | + if (is_boor[0]==1){ //若number=1,说明只有一个解,那么 is_boor只有一个为1,将该数据赋值给Angle【0】,Angle【1】为默认值 |
| 66 | + Angle[0].x=result[0][0]; |
| 67 | + Angle[0].y=result[1][0]; |
| 68 | + } |
| 69 | + else{ |
| 70 | + Angle[0].x=result[0][1]; |
| 71 | + Angle[0].y=result[1][1]; |
| 72 | + } |
| 73 | + } |
| 74 | + else |
| 75 | + if (number==2){ |
| 76 | + for(i=0;i<2;i++){ |
| 77 | + Angle[i].x=result[0][i]; //number=2时,两个是解,赋值给Angle【0】【1】 |
| 78 | + Angle[i].y=result[1][i]; |
| 79 | + } |
| 80 | + if((Angle[0].x==Angle[1].x)&&(Angle[0].y==Angle[1].y)) //若两解相同,令number=1; |
| 81 | + number=1; //最终的效果 无解,Angle【0】【1】为默认值 number=0 |
| 82 | + } // 只有一解,Angle【0】为解,Angle【1】为默认值 number=1 |
| 83 | + } // 有两相同解,Angle【0】【1】均为解 number=1 |
| 84 | +} |
0 commit comments