planners/inversekin/Passive.cpp

Go to the documentation of this file.
00001 
00003 //
00004 //Contents: Class CPassive
00005 // 
00006 //Relations:
00007 //      CJoints --> CActive  ---o CRedundant
00008 //            |---> CPassive -|
00009 //
00010 //      Class CActive/CPassive is derived from class CJoints
00011 //      Class CRedundant constains entities of CActive and CPassive
00012 //
00013 //CPassive is used to do closed-form inverse kinematics. 
00014 //The typical calling sequence is:
00015 //      1.CPassive::CPassive(...)
00016 //      2.CPassive::SetFrameManager(...)
00017 //        CPassive::SetRobot(...)
00018 //        CPassive::SetFirstJoint(...)
00019 //        CPassive::SetLastJoint(...)
00020 //      3.CPassive::SetFirstFrame(...)
00021 //        CPassive::SetEndEffectFrame(...)
00022 //      4.CPassive::SetDesireEndEffect(...)
00023 //      5.CPassive::GetConfiguration(...)
00024 //
00025 //Revision History:
00026 //       Date     Author    Description
00027 //      ---------------------------------------------------------
00028 //     Mar-2003:  Z.Yao     First version implemented
00029 //                          In this version, only two joints are
00030 //                          allowed in a passive chain, and only
00031 //                          position is considerred.
00032 //                          
00033 //Others:
00034 //     a.[Mar-2003]
00036 
00037 #include <math.h>
00038 #include "math\math2.h"
00039 #include "math\vector4.h"
00040 #include "Passive.h"
00041 #include "debug/debug.h"
00042 //------------------------------------------------------------------
00043 //
00044 //Construction and Deconstruction function
00045 //
00046 //------------------------------------------------------------------
00047 CPassive::CPassive():CJoints()
00048 {
00049         solution = new Configuration[MAX_SOLUTION];
00050 }
00051 
00052 CPassive::CPassive(FrameManager* frameManager)
00053                 :CJoints(frameManager)
00054 {
00055         solution = new Configuration[MAX_SOLUTION];
00056 }
00057 
00058 CPassive::~CPassive()
00059 {
00060         delete[] solution;
00061 }
00062 
00063 //------------------------------------------------------------------
00064 //
00065 //Set the robot in the environment
00066 //As default, it set robot's end-effector as that of passive chain.
00067 //
00068 //------------------------------------------------------------------
00069 void CPassive::SetRobot(R_OpenChain *robot)
00070 {
00071         CJoints::SetRobot(robot);
00072         Frame *frame = frameManager->GetFrameRef(robot->GetToolFrame(0));
00073         if (frame != NULL)
00074                 effectFrame.SetValues(*(frame));
00075         else
00076                 effectFrame.SetValues(Frame::Identity());
00077 }
00078 
00079 //------------------------------------------------------------------
00080 //
00081 //Set the last joint in the passive joint chain
00082 //
00083 //------------------------------------------------------------------
00084 void CPassive::SetLastJoint(unsigned int joint)
00085 {
00086         CJoints::SetLastJoint(joint);
00087         for (int i=0; i<MAX_SOLUTION; i++)
00088         {
00089                 solution[i].SetNumDOF(jointNum);
00090         }
00091         solutionNum = 0;
00092 }
00093 
00094 //------------------------------------------------------------------
00095 //This function is used to set end-effector pose with respect to wrist.
00096 //
00097 //Input Parameter:
00098 //      frame: end-effector frame r.w.t wrist
00099 //
00100 //Ouput Parameter:
00101 //      N.A
00102 //
00103 //Return Value:
00104 //      N.A
00105 //------------------------------------------------------------------
00106 void CPassive::SetEndEffectFrame(Frame &frame)
00107 {
00108         effectFrame.SetValues(frame);
00109         //this->effectFrameIndex=frame;
00110 }
00111 
00112 //------------------------------------------------------------------
00113 //This function is used to set desired end-effector pose 
00114 //with respect to universe frame.
00115 //
00116 //Input Parameter:
00117 //      frame: end-effector frame r.w.t universe frame
00118 //
00119 //Ouput Parameter:
00120 //      N.A
00121 //
00122 //Return Value:
00123 //      N.A
00124 //------------------------------------------------------------------
00125 void CPassive::SetDesireEndEffect(Frame &frame)
00126 {
00127         desireEffect.SetValues(frame);
00128 }
00129 
00130 //------------------------------------------------------------------
00131 //This function is used to set a base frame of passive chain.
00132 //And the base frame is r.w.t universe frame.
00133 //
00134 //Input Parameter:
00135 //      frame: base frame w.r.t universe frame
00136 //
00137 //Ouput Parameter:
00138 //      N.A
00139 //
00140 //Return Value:
00141 //      N.A
00142 //------------------------------------------------------------------
00143 void CPassive::SetFirstFrame(Frame &frame)
00144 {
00145         firstFrame.SetValues(frame);
00146 }
00147 
00148 //------------------------------------------------------------------
00149 //This function is used to get passive joint variables randomly.
00150 //
00151 //Input Parameter:
00152 //      N.A
00153 //
00154 //Ouput Parameter:
00155 //      conf: A random configuration
00156 //
00157 //Return Value:
00158 //      true, if success; 
00159 //      false, otherwise;
00160 //------------------------------------------------------------------
00161 bool CPassive::GetRandomConfiguration(Configuration &conf)
00162 {
00163         conf.SetLength(jointNum);
00164         if (jointNum==0)
00165                 return true;
00166 
00167         for( int i = 0; i < jointNum; i++ )
00168         {
00169                 double max = links[firstJoint+i]->JointMax() ;
00170                 double min = links[firstJoint+i]->JointMin() ;
00171                 double random = 2*( double( rand() ) / RAND_MAX ) - 1; //this is a random number between [-1..1]
00172                 double jointvalue = ( max - min ) * random;
00173 
00174                 // Create a uniform distribution by having the random number go over the limits have wrapping the C-space;
00175                 if ( jointvalue < min )
00176                 {
00177                         jointvalue += (max - min);
00178                 }
00179                 else if ( jointvalue > max )
00180                 {
00181                         jointvalue -= (max - min);
00182                 }
00183 
00184                 conf[ i ] = jointvalue;
00185         }
00186 
00187         return true;
00188 }
00189 
00190 //------------------------------------------------------------------
00191 //This function is used to get passive joint variables randomly.
00192 //
00193 //Input Parameter:
00194 //      N.A
00195 //
00196 //Ouput Parameter:
00197 //      conf: A random configuration
00198 //
00199 //Return Value:
00200 //      true, if success; 
00201 //      false, otherwise;
00202 //------------------------------------------------------------------
00203 bool CPassive::GetConfiguration(Configuration &conf)
00204 {
00205         conf.SetLength(jointNum);
00206         if (jointNum==0)
00207                 return true;
00208 
00209         if (!Inverse())
00210                 return false;
00211 
00212         int random = solutionNum*rand() / (RAND_MAX+2);
00213 
00214         for (int i=0; i<jointNum; i++)
00215                 conf[i] = (solution[random])[i];
00216         return true;
00217 }
00218 
00219 //------------------------------------------------------------------
00220 //This function is used to get passive joint variables
00221 //in a neighbour area of current configuration, and satisfying
00222 //end-effector pose set by function SetDesiredEndEffector(...). 
00223 //
00224 //Input Parameter:
00225 //      current: Given bias configuration
00226 //      dist: Deviation allowed for each joint variables
00227 //
00228 //Ouput Parameter:
00229 //      conf: Satisfactory configuration
00230 //
00231 //Return Value:
00232 //      true, if success; 
00233 //      false, otherwise;
00234 //------------------------------------------------------------------
00235 bool CPassive::GetConfiguration(Configuration &conf, Configuration &current, double dist)
00236 {
00237         conf.SetLength(jointNum);
00238         if (jointNum==0)
00239                 return true;
00240 
00241         bool bFind;
00242         int i, j;
00243         if (!Inverse())
00244         {
00245                 return false;
00246         }
00247 
00248         //for (i=0; i<solutionNum; i++)
00249         //      for (j=0; j<jointNum; j++)
00250         //              solution[i][j] = Rad2Deg(solution[i][j]);
00251         //Now above conversion is done in Inverse()!!
00252 
00253         for (i=0; i<solutionNum; i++)
00254         {
00255                 bFind = true;
00256 
00257                 for (j=0; j<jointNum; j++)
00258                 {
00259                         if (Distance(links[firstJoint+j],solution[i][j], current[j])>dist)
00260                         {
00261                                 bFind = false;
00262                                 break;
00263                         }
00264                 }
00265                 if (bFind)
00266                 {
00267                         for (j=0; j<jointNum; j++)
00268                                 conf[j] = (solution[i])[j];
00269                         break;
00270                 }
00271         }
00272         return bFind;
00273 }
00274 
00275 //------------------------------------------------------------------
00276 //This function is used to get passive joint variables
00277 //that is closest to current configuration, and satisfying
00278 //end-effector pose set by function SetDesiredEndEffector(...). 
00279 //
00280 //Input Parameter:
00281 //      current: Given bias configuration
00282 //
00283 //Ouput Parameter:
00284 //      conf: Closest satisfactory configuration
00285 //
00286 //Return Value:
00287 //      true, if success; 
00288 //      false, otherwise;
00289 //------------------------------------------------------------------
00290 bool CPassive::GetConfiguration(Configuration &conf, Configuration &current)
00291 {
00292         conf.SetLength(jointNum);
00293         if (jointNum==0)
00294                 return true;
00295 
00296         int i, j;
00297         if (!Inverse())
00298         {
00299                 return false;
00300         }
00301 
00302         //for (i=0; i<solutionNum; i++)
00303         //      for (j=0; j<jointNum; j++)
00304         //              solution[i][j] = Rad2Deg(solution[i][j]);
00305         //Now above conversion is done in Inverse()!!
00306 
00307         int minDist = 0;
00308         int minSolution = 0;
00309         for (j=0; j<jointNum; j++)
00310         {
00311                 double dist = Distance(links[firstJoint+j], solution[0][j], current[j]);
00312                 minDist += dist*dist;
00313         }
00314 
00315         for (i=1; i<solutionNum; i++)
00316         {
00317                 double currDist=0;
00318                 for (j=0; j<jointNum; j++)
00319                 {
00320                         double dist = Distance(links[firstJoint+j], solution[i][j], current[j]);
00321                         currDist += dist*dist;
00322                 }
00323 
00324                 if (currDist < minDist)
00325                 {
00326                         minDist = currDist;
00327                         minSolution = i;
00328                 }
00329         }
00330 
00331         for (j=0; j<jointNum; j++)
00332         {
00333                 conf[j] = (solution[minSolution])[j];
00334         }
00335 
00336         return true;
00337 }
00338 
00339 //------------------------------------------------------------------
00340 //This function is a private function to solve the case where 
00341 //there is only one joint in passive chain.
00342 //
00343 //Input Parameter:
00344 //      type: Joint type: Revolute or Prismatic
00345 //
00346 //Ouput Parameter:
00347 //      N.A
00348 //
00349 //Return Value:
00350 //      true, if success; 
00351 //      false, otherwise;
00352 //------------------------------------------------------------------
00353 bool CPassive::ResolveJoints(DH_Parameter type)
00354 {
00355         return false;
00356 }
00357 
00358 //------------------------------------------------------------------
00359 //This function is a private function to solve the case where 
00360 //there are two joints in passive chain.
00361 //
00362 //Input Parameter:
00363 //      type1/type2: Joint type: Revolute or Prismatic
00364 //
00365 //Ouput Parameter:
00366 //      N.A
00367 //
00368 //Return Value:
00369 //      true, if success; 
00370 //      false, otherwise;
00371 //------------------------------------------------------------------
00372 bool CPassive::ResolveJoints(DH_Parameter type1, DH_Parameter type2)
00373 {
00374         double a1, alpha1, d1, theta1;
00375         double a2, alpha2, d2, theta2;
00376 
00377         DH_Link *link1 = (DH_Link *) links[firstJoint];
00378         DH_Link *link2 = (DH_Link *) links[firstJoint+1];
00379 
00380         a1 = link1->GetA();
00381         a2 = link2->GetA();
00382 
00383         d1 = link1->GetD();
00384         d2 = link2->GetD();
00385 
00386         alpha1 = link1->GetAlpha();
00387         alpha2 = link2->GetAlpha();
00388 
00389         theta1 = link1->GetTheta();
00390         theta2 = link2->GetTheta();
00391 
00392         double x, y, z;
00393         double Xe, Ye, Ze;
00394         double Xo, Yo, Zo;
00395 
00396         //Xe, Ye, Ze, End Effect Position with respect to frame {0}
00397         Xe = desireEffect(0, 3);
00398         Ye = desireEffect(1, 3);
00399         Ze = desireEffect(2, 3);
00400 
00401         //x, y, z, End Effect Position with respect to last frame
00402         x = effectFrame(0, 3);
00403         y = effectFrame(1, 3);
00404         z = effectFrame(2, 3);
00405 
00406         Vector4 firstPos(a1, -sin(alpha1)*d1, cos(alpha1)*d1);
00407         Vector4 firstPos0= firstFrame * firstPos;
00408         Xo = firstPos0[0];
00409         Yo = firstPos0[1];
00410         Zo = firstPos0[2];
00411         //Xo = firstFrame(0, 3);
00412         //Yo = firstFrmae(1, 3);
00413         //Zo = firstFrame(2, 3);
00414 
00415         double a, b, c, d;
00416 
00417         double solu[2];
00418         int num;
00419 
00420         solutionNum = 0;
00421 
00422         //------------Both are Revolute------------
00423         if ((type1==DH_THETA)&& (type2==DH_THETA))
00424         {
00425                 a = (Xe-Xo)*(Xe-Xo)+(Ye-Yo)*(Ye-Yo)-a1*a1-a2*a2;
00426                 b = -2*a1*a2;
00427 
00428                 double cos2, sin2;
00429                 cos2 = a/b;
00430                 if (fabs(cos2)>1)
00431                 {
00432                         if (IsZero(fabs(cos2)-1))
00433                         {
00434                                 cos2 = cos2/fabs(cos2);
00435                                 sin2 = 0;
00436                         }
00437                         else
00438                         {
00439                                 return false;
00440                         }
00441                 }
00442                 else
00443                 {
00444                         sin2 = sqrt(1-cos2*cos2);
00445                 }
00446 
00447                 sin2 = sqrt(1-cos2*cos2);
00448 
00449                 solution[0][1] = M_PI-atan2(sin2, cos2);
00450                 solution[1][1] = atan2(sin2, cos2)-M_PI;
00451 
00452                 solutionNum = 2;
00453 
00454                 Vector4 end2First(Xe, Ye, Ze);
00455                 Vector4 end2First0 = firstFrame.Inverse() * end2First;
00456                 Xo = end2First0[0];
00457                 Yo = end2First0[1];
00458                 Zo = end2First0[2];
00459 
00460                 for (int i=0; i<2; i++)
00461                 {
00462                         cos2 = cos(solution[i][1]);
00463                         sin2 = sin(solution[i][1]);
00464 
00465                         a = cos(alpha1)*Yo+sin(alpha1)*Zo;
00466                         b = Xo-a1;
00467                         c = sin2*x - cos2*y;
00468                         d = a2 + cos2*x - sin2*y;
00469 
00470                         Solution(a, b, c, d, solu[0]);
00471                         solution[i][0] = solu[0];
00472                 }
00473 
00474                 /*
00475                 ----------------------------------------
00476                 +cos(theta1)*()
00477                 -sin(theta1)*(Xo-a1)
00478                 +sin(theta2)*(-x)
00479                 +cos(theta2)*(y)
00480                 =0
00481                 ----------------------------------------   
00482                 +sin(theta1)*(cos(alpha1)*Yo+sin(alpha1)*Zo)
00483                 +cos(theta1)*(Xo-a1)
00484                 +cos(theta2)*(-x)
00485                 +sin(theta2)*(y)
00486                 =a2
00487                 ----------------------------------------
00488                 */
00489                 /*
00490                     //Get theta2
00491                     a = y*sin(alpha2);
00492                     b = x*sin(alpha2);
00493                     c = -d1-sin(alpha1)*Ye+cos(alpha1)*Ze-cos(alpha2)*z-cos(alpha2)*d2;
00494                  
00495                     Solution(a, b, c, solu, num);
00496                     if (num==1)
00497                     {
00498                       solutionNum = 1;
00499                       solution[0][1] = solu[0];
00500                     }
00501                     else if (num==2)
00502                     {
00503                       solutionNum = 2;
00504                       solution[0][1] = solu[0];
00505                       solution[1][1] = solu[1];
00506                     }
00507                     else
00508                     {
00509                       return false;
00510                     }
00511                  
00512                     //Get theta1
00513                     for (int i=0; i<solutionNum; i++)
00514                     {
00515                       theta2 = solution[i][1];
00516                  
00517                                   a=(Xe-a1);
00518                                   b=(cos(alpha1)*Ye+sin(alpha1)*Ze);
00519                                   c=-(-sin(theta2)*cos(alpha2)*x
00520                           -cos(theta2)*cos(alpha2)*y
00521                           +sin(alpha2)*z
00522                           +sin(alpha2)*d2
00523                          );
00524                                   d=-(-cos(theta2)*x+sin(theta2)*y-a2);
00525                  
00526                       Solution(a, b, c, d, solu[0]);
00527                       solution[i][0] = solu[0];
00528                     }
00529                 */
00530         }
00531 
00532         //------------Both are Prismatic------------
00533         else if((type1==DH_D)&& (type2==DH_D))
00534         {
00535                 a = cos(theta1)*(Xe-a1)
00536                     +sin(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00537                     -cos(theta2)*x+sin(theta2)*y-a2;
00538 
00539                 if (!IsZero(a))
00540                         return false;
00541 
00542                 //Get D2
00543                 a=sin(alpha2);
00544                 b=-(-sin(theta1)*(Xe-a1)
00545                     +cos(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00546                     -sin(theta2)*cos(alpha2)*x
00547                     -cos(theta2)*cos(alpha2)*y+sin(alpha2)*z
00548                    );
00549                 //if (a==0)
00550                 if (!IsZero(a))
00551                         return false;
00552                 solution[0][1]=d2=b/a;
00553 
00554                 //Get D1
00555                 solution[0][0]=(-sin(theta2)*sin(alpha2)*x
00556                                 -cos(theta2)*sin(alpha2)*y
00557                                 -sin(alpha1)*Ye
00558                                 +cos(alpha1)*Ze
00559                                 -cos(alpha2)*z
00560                                 -cos(alpha2)*d2
00561                                );
00562 
00563                 solutionNum = 1;
00564         }
00565 
00566         //------------First Revolute, second Prismatic------------
00567         else if((type1==DH_THETA)&& (type2==DH_D))
00568         {
00569                 //Get Theta1
00570                 a=(Xe-a1);
00571                 b=(cos(alpha1)*Ye+sin(alpha1)*Ze);
00572                 c=-(-cos(theta2)*x+sin(theta2)*y-a2);
00573 
00574                 Solution(a, b, c, solu, num);
00575                 if (num==1)
00576                 {
00577                         solutionNum = 1;
00578                         solution[0][0] = solu[0];
00579                 }
00580                 else if (num==2)
00581                 {
00582                         solutionNum = 2;
00583                         solution[0][0] = solu[0];
00584                         solution[1][0] = solu[1];
00585                 }
00586                 else
00587                 {
00588                         return false;
00589                 }
00590 
00591                 //Get D2
00592                 for (int i=0; i<solutionNum; i++)
00593                 {
00594                         theta1 = solution[i][0];
00595 
00596                         a=sin(alpha2);
00597                         b=-(-sin(theta1)*(Xe-a1)
00598                             +cos(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00599                             -sin(theta2)*cos(alpha2)*x
00600                             -cos(theta2)*cos(alpha2)*y
00601                             +sin(alpha2)*z
00602                            );
00603 
00604                         //if (a==0)
00605                         if (!IsZero(a))
00606                         {
00607                                 solutionNum = 0;
00608                                 return false;
00609                         }
00610                         else
00611                         {
00612                                 solution[i][1] = b/a;
00613                         }
00614                 }
00615 
00616         }
00617 
00618         //------------First Prismatic, second Revolute------------
00619         else
00620         {
00621                 //Get Theta2
00622                 a=cos(alpha2)*y;
00623                 b=cos(alpha2)*x;
00624                 c=-sin(theta1)*(Xe-a1)
00625                   +cos(theta1)*(cos(alpha1)*Ye+sin(alpha1)*Ze)
00626                   +sin(alpha2)*z+sin(alpha2)*d2;
00627 
00628                 Solution(a, b, c, solu, num);
00629                 if (num==1)
00630                 {
00631                         solutionNum = 1;
00632                         solution[0][1] = solu[0];
00633                 }
00634                 else if (num==2)
00635                 {
00636                         solutionNum = 2;
00637                         solution[0][1] = solu[0];
00638                         solution[1][1] = solu[1];
00639                 }
00640                 else
00641                 {
00642                         return false;
00643                 }
00644 
00645                 //Get D1
00646                 for (int i=0; i<solutionNum; i++)
00647                 {
00648                         theta2 = solution[i][1];
00649 
00650                         solution[i][0]=(-sin(theta2)*sin(alpha2)*x
00651                                         -cos(theta2)*sin(alpha2)*y
00652                                         -sin(alpha1)*Ye+cos(alpha1)*Ze
00653                                         -cos(alpha2)*z
00654                                         -cos(alpha2)*d2
00655                                        );
00656                 }
00657         }
00658 
00659         return true;
00660 }
00661 
00662 //------------------------------------------------------------------
00663 //This function is a private function to solve the case where 
00664 //there are three joints in passive chain.
00665 //
00666 //Input Parameter:
00667 //      type1/type2/type3: Joint type: Revolute or Prismatic
00668 //
00669 //Ouput Parameter:
00670 //      N.A
00671 //
00672 //Return Value:
00673 //      true, if success; 
00674 //      false, otherwise;
00675 //------------------------------------------------------------------
00676 bool CPassive::ResolveJoints(DH_Parameter type1, DH_Parameter type2, DH_Parameter type3)
00677 {
00678         double a1, alpha1, d1, theta1;
00679         double a2, alpha2, d2, theta2;
00680 
00681         DH_Link *link1 = (DH_Link *) links[firstJoint];
00682         DH_Link *link2 = (DH_Link *) links[firstJoint+1];
00683         DH_Link *link3 = (DH_Link *) links[firstJoint+2];
00684 
00685         a1 = link1->GetA();
00686         a2 = link2->GetA();
00687 
00688         d1 = link1->GetD();
00689         d2 = link2->GetD();
00690 
00691         alpha1 = link1->GetAlpha();
00692         alpha2 = link2->GetAlpha();
00693 
00694         theta1 = link1->GetTheta();
00695         theta2 = link2->GetTheta();
00696 
00697         double x, y, z;
00698         double Xw, Yw, Zw;
00699         double Xo, Yo, Zo;
00700 
00701         Frame desireWrist = desireEffect * effectFrame.Inverse();
00702         Xw = desireWrist(0, 3);
00703         Yw = desireWrist(1, 3);
00704         Zw = desireWrist(2, 3);
00705 
00706         link3->SetJointVariable(0);
00707         Frame wristFrame = link3->GetFrame();
00708         x = wristFrame(0, 3);
00709         y = wristFrame(1, 3);
00710         z = wristFrame(2, 3);
00711 
00712         Vector4 firstPos(a1, -sin(alpha1)*d1, cos(alpha1)*d1);
00713         Vector4 firstPos0= firstFrame * firstPos;
00714         Xo = firstPos0[0];
00715         Yo = firstPos0[1];
00716         Zo = firstPos0[2];
00717         //Xo = firstFrame(0, 3);
00718         //Yo = firstFrmae(1, 3);
00719         //Zo = firstFrame(2, 3);
00720 
00721 #if 0
00722         Log("passive.log", \
00723                 "desireEffect:\n \
00724                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00725                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00726                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00727                 desireEffect(0, 0), desireEffect(0, 1), desireEffect(0, 2), desireEffect(0, 3), \
00728                 desireEffect(1, 0), desireEffect(1, 1), desireEffect(1, 2), desireEffect(1, 3), \
00729                 desireEffect(2, 0), desireEffect(2, 1), desireEffect(2, 2), desireEffect(2, 3) \
00730                 );
00731         Log("passive.log", \
00732                 "desireWrist:\n \
00733                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00734                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00735                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00736                 desireWrist(0, 0), desireWrist(0, 1), desireWrist(0, 2), desireWrist(0, 3), \
00737                 desireWrist(1, 0), desireWrist(1, 1), desireWrist(1, 2), desireWrist(1, 3), \
00738                 desireWrist(2, 0), desireWrist(2, 1), desireWrist(2, 2), desireWrist(2, 3) \
00739                 );
00740         Log("passive.log", \
00741                 "wristFrame:\n \
00742                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00743                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00744                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00745                 wristFrame(0, 0), wristFrame(0, 1), wristFrame(0, 2), wristFrame(0, 3), 
00746                 wristFrame(1, 0), wristFrame(1, 1), wristFrame(1, 2), wristFrame(1, 3), 
00747                 wristFrame(2, 0), wristFrame(2, 1), wristFrame(2, 2), wristFrame(2, 3)
00748                 );
00749         Log("passive.log", \
00750                 "firstFrame:\n \
00751                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00752                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00753                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00754                 firstFrame(0, 0), firstFrame(0, 1), firstFrame(0, 2), firstFrame(0, 3), 
00755                 firstFrame(1, 0), firstFrame(1, 1), firstFrame(1, 2), firstFrame(1, 3), 
00756                 firstFrame(2, 0), firstFrame(2, 1), firstFrame(2, 2), firstFrame(2, 3)
00757                 );
00758 #endif
00759 
00760         double a, b, c, d;
00761         double solu[2];
00762 
00763         solutionNum = 0;
00764 
00765         if ((type1==DH_THETA)&& (type2==DH_THETA) && (type3==DH_THETA))
00766         {
00767                 a = (Xw-Xo)*(Xw-Xo)+(Yw-Yo)*(Yw-Yo)-a1*a1-a2*a2;
00768                 b = -2*a1*a2;
00769 
00770                 double cos2, sin2;
00771                 cos2 = a/b;
00772                 if (fabs(cos2)>1)
00773                 {
00774                         if (IsZero(fabs(cos2)-1))
00775                         {
00776                                 cos2 = cos2/fabs(cos2);
00777                                 sin2 = 0;
00778                         }
00779                         else
00780                         {
00781                                 return false;
00782                         }
00783                 }
00784                 else
00785                 {
00786                         sin2 = sqrt(1-cos2*cos2);
00787                 }
00788 
00789                 solution[0][1] = M_PI-atan2(sin2, cos2);
00790                 solution[1][1] = atan2(sin2, cos2)-M_PI;
00791 
00792                 solutionNum = 2;
00793 
00794                 Vector4 end2First(Xw, Yw, Zw);
00795                 Vector4 end2First0 = firstFrame.Inverse() * end2First;
00796                 Xo = end2First0[0];
00797                 Yo = end2First0[1];
00798                 Zo = end2First0[2];
00799 
00800                 for (int i=0; i<2; i++)
00801                 {
00802                         cos2 = cos(solution[i][1]);
00803                         sin2 = sin(solution[i][1]);
00804 
00805                         a = cos(alpha1)*Yo+sin(alpha1)*Zo;
00806                         b = Xo-a1;
00807                         c = sin2*x - cos2*y;
00808                         d = a2 + cos2*x - sin2*y;
00809 
00810                         Solution(a, b, c, d, solu[0]);
00811                         solution[i][0] = solu[0];
00812 
00813                         //Add wrist joint value
00814                         link1->SetJointVariable(Rad2Deg(solution[i][0]));
00815                         link2->SetJointVariable(Rad2Deg(solution[i][1]));
00816                         link3->SetJointVariable(0);
00817                         Frame currWristFrame = firstFrame*link1->GetFrame()*link2->GetFrame()*link3->GetFrame();
00818                         Frame link3Frame = currWristFrame.Inverse() * desireWrist;
00819 
00820 #if 0
00821                         Log("passive.log", \
00822                                 "currWristFrame:\n \
00823                                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00824                                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00825                                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00826                                 currWristFrame(0, 0), currWristFrame(0, 1), currWristFrame(0, 2), currWristFrame(0, 3), 
00827                                 currWristFrame(1, 0), currWristFrame(1, 1), currWristFrame(1, 2), currWristFrame(1, 3), 
00828                                 currWristFrame(2, 0), currWristFrame(2, 1), currWristFrame(2, 2), currWristFrame(2, 3)
00829                                 );
00830                         Log("passive.log", \
00831                                 "link3Frame:\n \
00832                                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00833                                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n \
00834                                 \t[%3.4f, %3.4f, %3.4f, %3.4f]\n", \
00835                                 link3Frame(0, 0), link3Frame(0, 1), link3Frame(0, 2), link3Frame(0, 3), 
00836                                 link3Frame(1, 0), link3Frame(1, 1), link3Frame(1, 2), link3Frame(1, 3), 
00837                                 link3Frame(2, 0), link3Frame(2, 1), link3Frame(2, 2), link3Frame(2, 3)
00838                                 );
00839 #endif
00840                         
00841                         Solution(link3Frame, solu[0]);
00842                         solution[i][2] = solu[0];
00843 #if 0
00844                         Log("passive.log", "The solution we get is %f\n==========", solu[0]);
00845 #endif
00846                 }
00847 
00848         }
00849         else
00850         {
00851                 //Not support other case yet!
00852                 assert(false);
00853         }
00854         return true;
00855 }
00856 
00857 //------------------------------------------------------------------
00858 //This function is a private function to initiate inverse kinematics
00859 //computation. The calling stack would be:
00860 //   Inverse(...)           -- Dispatcher
00861 //      ResolveJoints(...)      -- Handle kinematics
00862 //         Solution(...)    -- Solve arithematic equation
00863 //
00864 //Input Parameter:
00865 //      N.A
00866 //
00867 //Ouput Parameter:
00868 //      N.A
00869 //
00870 //Return Value:
00871 //      true, if success; 
00872 //      false, otherwise;
00873 //
00874 //Note:
00875 //      The solution is stored in member variable: solutions[]
00876 //------------------------------------------------------------------
00877 bool CPassive::Inverse()
00878 {
00879 
00880         if ((jointNum>3) || (jointNum<=0))
00881         {
00882                 return false;
00883         }
00884 
00885         DH_Parameter type1, type2, type3;
00886 
00887         DH_Link *link1, *link2, *link3;
00888 
00889         link1 = (DH_Link *) links[firstJoint];
00890         type1 = link1->GetJointType();
00891         if ((type1 == DH_ALPHA) || (type1 == DH_A))
00892         {
00893                 return false;
00894         }
00895 
00896         if (jointNum > 1)
00897         {
00898                 link2 = (DH_Link *)links[firstJoint+1];
00899                 type2 = link2->GetJointType();
00900 
00901                 if ((type2 == DH_ALPHA) || (type2 == DH_A))
00902                 {
00903                         return false;
00904                 }
00905         }
00906 
00907         if (jointNum > 2)
00908         {
00909                 link3 = (DH_Link *)links[firstJoint+2];
00910                 type3 = link3->GetJointType();
00911 
00912                 if ((type2 == DH_ALPHA) || (type2 == DH_A))
00913                 {
00914                         return false;
00915                 }
00916         }
00917 
00918         bool bResolved;
00919         if (jointNum==1)
00920         {
00921                 bResolved = ResolveJoints(type1);
00922         }
00923         else if (jointNum==2)
00924         {
00925                 bResolved = ResolveJoints(type1, type2);
00926         }
00927         else if (jointNum==3)
00928         {
00929                 bResolved = ResolveJoints(type1, type2, type3);
00930         }
00931 
00932         if (bResolved)
00933         {
00934                 for (int i=0; i<solutionNum; i++)
00935                 for (int j=0; j<jointNum; j++)
00936                         solution[i][j] = Rad2Deg(solution[i][j]);
00937         }
00938 
00939         return bResolved;
00940 }
00941 
00942 //------------------------------------------------------------------
00943 //This function is a private function to solve the equation:
00944 //  a*cos(theta)+b*sin(theta)=c, where
00945 //      a, b, c, is known, asking for "theta"
00946 //
00947 //Input Parameter:
00948 //      a,b,c:
00949 //
00950 //Ouput Parameter:
00951 //      num: number of solution
00952 //      solution[]: solutions for theta
00953 //
00954 //Return Value:
00955 //      true, if success; 
00956 //      false, otherwise;
00957 //------------------------------------------------------------------
00958 bool __inline CPassive::Solution(double a, double b, double c, double solution[2], int &num)
00959 {
00960         if ((a==0) && (b==0))
00961         {
00962                 num = 0;
00963                 return false;
00964         }
00965 
00966         if ((a*a+b*b)<(c*c))
00967         {
00968                 return false;
00969         }
00970         else if ((a*a+b*b)==(c*c))
00971         {
00972                 num = 1;
00973                 if (c>0)
00974                         solution[0] = atan2(b,a);
00975                 else
00976                         solution[0] = atan2(b,a)+M_PI;
00977         }
00978         else
00979         {
00980                 num = 2;
00981                 solution[0] = atan2(b,a)+atan2(sqrt(a*a+b*b-c*c), c);
00982                 solution[1] = atan2(b,a)-atan2(sqrt(a*a+b*b-c*c), c);
00983         }
00984         return true;
00985 }
00986 
00987 //------------------------------------------------------------------
00988 //This function is a private function to solve the equations:
00989 //  a*cos(theta)-b*sin(theta)=c  && 
00990 //  a*sin(theta)+b*cos(theta)=d, where
00991 //      a, b, c, is known, asking for "theta"
00992 //
00993 //Input Parameter:
00994 //      a,b,c:
00995 //
00996 //Ouput Parameter:
00997 //      solution: solution for theta, there will be only one
00998 //
00999 //Return Value:
01000 //      true, if success; 
01001 //      false, otherwise;
01002 //------------------------------------------------------------------
01003 bool __inline CPassive::Solution(double a, double b, double c, double d, double &solution)
01004 {
01005         if ((a==0) && (b==0))
01006         {
01007                 return false;
01008         }
01009 
01010         solution = atan2(a*d-b*c, a*c+b*d);
01011         return true;
01012 }
01013 
01014 //------------------------------------------------------------------
01015 //This function is a private function to solve the rotation:
01016 //  given a frame, computer the equivalent rotation axis
01017 //  and the angle rotated
01018 //
01019 //Input Parameter:
01020 //      rotated: Frame(orientation) after rotated
01021 //
01022 //Ouput Parameter:
01023 //      solution: solution for theta, there will be only one
01024 //
01025 //Return Value:
01026 //      true, if success; 
01027 //      false, otherwise;
01028 //------------------------------------------------------------------
01029 bool __inline CPassive::Solution(Frame &rotated, double &solution)
01030 {
01031         double temp;
01032         temp = rotated.values[0][0] + rotated.values[1][1] + rotated.values[2][2] - 1;
01033 
01034         assert( fabs(temp) <= (2+ROUNDING_ERROR) );
01035 
01036         solution = acos(temp/2);
01037         if ((rotated.values[1][0] - rotated.values[0][1]) < 0)
01038                 solution = -solution;
01039         return true;
01040 }

Generated on Sat Apr 1 21:30:44 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO