planners/ik_mpep/IK_Jacobian.cpp

Go to the documentation of this file.
00001 //=================================
00002 // IK_Jacobian.cpp
00003 // Implementation file for planner
00004 //=================================
00005 
00006 #include "synchronization/semaphore.h"
00007 #include "Kinematics\DH_Link.h"
00008 #include "Kinematics\Jacobian.h"
00009 #include "assert.h"
00010 #include <math/matrix4x4.h>
00011 #include <math/Matrixmxn.h>
00012 #include <math/vector4.h>
00013 #include "CollisionDetectors\CD_Swiftpp.h"
00014 #include "IK_Jacobian.h"
00015 
00016 #if 1
00017         #define LogMatrix(a, b, c) 
00018         #define LogVector(a, b, c)
00019         #define LogMessage(a, b)
00020 #endif
00021 
00022 static const int FRAMEDOF = 6;
00023 static const int SAMPLING_PERIOD = 1;
00024 
00025 static const double INFINITY = LONG_MAX; 
00026 static const double DEFAULT_OBS_TOL = 0.01;     
00027         // distance tolerance to obstacles
00028 static const double DEFAULT_PATH_TOL = 0.5;
00029         // tolerance of deviation of end-effector from given path
00030 static const double DEFAULT_ANG_TOL = 2;
00031         // tolerance of deviation of end-effector orienation
00032 static const double DEFAULT_VEL = 1; 
00033         // default end effector velocity in any direction
00034 static const double DEFAULT_OBS_GAIN = 0.1;
00035         // default obstacle point velocity ratio to inverse distance away from obstacle
00036 static const double DEFAULT_REL_IMP = 1;  
00037         // relative importance of obstacle avoidance to following end-effector path
00038         // 1 = equal importance, < 1 = less important than following path
00039 static const double MAX_OBS_VEL = 0.5;         // maximum obstacle point velocity
00040 static const double MAX_JOINT_VEL = (M_PI/10.);       // maximum joint velocity (degrees)
00041 static const double CALCULATION_FREQ = 100;     // per second
00042 static const double UNITY_GAIN_DISTANCE = 0.5;    // arbitrary
00043 static const double SOI_GAIN_DISTANCE   = 1.5;    // distance where the obstacle no longer matters
00044 static const double DEFAULT_HOMO_GAIN = 0.25;
00045 
00046 //Construction
00047 IK_Jacobian::IK_Jacobian()
00048 {
00049         if (collisionDetector != NULL)
00050         {
00051                 m_nDof = collisionDetector->DOF();
00052         }
00053         else
00054         {
00055                 m_nDof = FRAMEDOF;
00056         }
00057 
00058         //The following parameter could be set by users
00059     m_nObsPoint = 2;
00060     m_dObsTol = DEFAULT_OBS_TOL;
00061     m_dObsDistGain = DEFAULT_OBS_GAIN;
00062     m_dHomoGain = DEFAULT_HOMO_GAIN;
00063     m_dPathTol = DEFAULT_PATH_TOL;
00064     m_dAngTol = DEFAULT_ANG_TOL;
00065 
00066     path.Clear();
00067         m_vClosestPoints.clear(); 
00068 }
00069 
00070 //Deconstruction
00071 IK_Jacobian::~IK_Jacobian()
00072 {
00073         path.Clear();
00074         m_vClosestPoints.clear(); 
00075     //m_links.clear();  
00076 }
00077 
00078 //------------------------------------------------------------------
00079 //SetCollisionDetector
00080 //
00081 //This function is derived from its base class, and update collision detector in planner.
00082 //
00083 //------------------------------------------------------------------
00084 void IK_Jacobian::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00085 {
00086     this->collisionDetector = collisionDetector;
00087         m_nDof = collisionDetector->DOF();
00088     m_pRobot = dynamic_cast<R_OpenChain*>(collisionDetector->GetRobot(0));
00089         m_nToolFrame = m_pRobot->GetToolFrame(0);
00090         m_frEndEffector = Matrix4x4::Identity();
00091         if (m_nToolFrame != -1)
00092         {
00093                 FrameManager* frameManager = collisionDetector->GetFrameManager();
00094                 m_frEndEffector = *(frameManager->GetFrameRef(m_nToolFrame));
00095         }
00096 }
00097 
00098 //------------------------------------------------------------------
00099 //ComputeEndEffVel
00100 //
00101 //This function is used to compute the end-effector velocity along the given trajectory.
00102 //
00103 //Input Parameter:
00104 //      frStart: start point. 
00105 //      frEnd  : end point. 
00106 //
00107 //Ouput Parameter:
00108 //      N.A.
00109 //
00110 //Return Value:
00111 //      end-effector velocity. The dimension of the velocity depends on whether we 
00112 //        position or orientation. If both are considered, the dimension=6, otherwise 3.
00113 //      
00114 //------------------------------------------------------------------
00115 VectorN IK_Jacobian::ComputeEndEffVel(Frame &frStart, Frame &frEnd)
00116 {
00117         VectorN returnMe;
00118 
00119         if (m_bOrientation && m_bPosition)
00120                 returnMe.SetLength(6);
00121         else if (m_bOrientation || m_bPosition)
00122                 returnMe.SetLength(3);
00123         else
00124         {
00125                 assert(false);
00126                 return returnMe;
00127         }
00128 
00129         int index = 0;
00130         if (m_bPosition)
00131         {       
00132                 returnMe[index++] = frEnd(0, 3) - frStart(0, 3);
00133                 returnMe[index++] = frEnd(1, 3) - frStart(1, 3);
00134                 returnMe[index++] = frEnd(2, 3) - frStart(2, 3);
00135         }
00136 
00137     //Compute angular velocity
00138     //Angular velocity = (angle rotated)*(Unit vector of rotation axis)
00139         if (m_bOrientation)
00140         {
00141                 //compute equivalent rotation matrix, w.r.t fixed coordinate
00142                 Frame rotated = frEnd * frStart.Inverse();
00143         
00144         //compute axis and angle rotated.
00145                 double temp = rotated.values[0][0] + rotated.values[1][1] + rotated.values[2][2] - 1;
00146                 assert(fabs(temp) <= (2+ROUNDING_ERROR));
00147                 if (temp>2.0)
00148                         temp = 2.0;
00149                 else if (temp<-2.0)
00150                         temp = -2.0;
00151 
00152                 double angle = acos(temp/2.);
00153                 Vector4 axis;
00154                 axis[0] = rotated.values[2][1] - rotated.values[1][2];
00155                 axis[1] = rotated.values[0][2] - rotated.values[2][0];
00156                 axis[2] = rotated.values[1][0] - rotated.values[0][1];
00157 
00158                 if (sin(angle) != 0)
00159                         axis /= (2*sin(angle));
00160 
00161                 axis *= angle;
00162 
00163                 returnMe[index++] = axis[0];
00164                 returnMe[index++] = axis[1];
00165                 returnMe[index++] = axis[2];
00166         }
00167 
00168         return returnMe;        
00169 }
00170 
00171 //------------------------------------------------------------------
00172 //ComputeHomogeneousTerm
00173 //
00174 //This function is used to compute homogeneous solution.
00175 //  \sum_{i=1}^{M}\alpha_i[J_o(I-J^{+}_eJ_e)]^{+}(\dot{x}_o-J_oJ^{+}_e\dot{x}_e)
00176 //where $M$ is number of obstacles points to be considered,
00177 //      $J_o$       : Jacobian matrix of $i^th$ obstacle point;
00178 //      $J_e$       : End-effector Jacobian matrix;
00179 //      $J^{+}_e$   : pseudo-inverse of $J_e$;
00180 //      $\dot{x}_o$ : Velocity to escape from $i^th$ obstacle point;
00181 //      $\dot{x}_e$ : End-effector velocity;
00182 //
00183 //Input Parameter:
00184 //      jacobian  : Jacobian class, by which the Jacobian matrices of obstacle points will be computed. 
00185 //      mJEnd     : End-effector Jacobian Matrix. ($J_e$ in above equation)
00186 //      mJEndInv  : pseudo-inverse of End-effector Jacobian Matrix. ($J^{+}_e$ in above equation)
00187 //      vEndEffVel: End-effector velocity. ($\dot{x}_e$ in above equation)
00188 //
00189 //Ouput Parameter:
00190 //      N.A.
00191 //
00192 //Return Value:
00193 //      joint velocity component of the homogeneous solution.
00194 //      
00195 //------------------------------------------------------------------
00196 VectorN IK_Jacobian::ComputeHomogeneousTerm(CJacobian &jacobian, Matrixmxn &mJEnd, Matrixmxn &mJEndInv, VectorN &vEndEffVel)
00197 {
00198     assert(m_vClosestPoints.size() == m_nObsPoint);
00199 
00200         VectorN vHomogeneousSolns;
00201         VectorN vSingleTerm(vHomogeneousSolns);
00202 
00203         vHomogeneousSolns.SetLength(m_nDof);
00204     for (int j = 0; j < m_nObsPoint; j++)
00205     {
00206                 //Get frame of obstacle point with respect to previous link;
00207                 int robFrame;
00208                 Frame worldTObsFrame;     // frame of joing $robFrame$ w.r.t universe frame
00209                 Frame frObsPtsInLink;     // frame of obstacle-point w.r.t joint $robFrame$
00210         Frame frObsPtsInLinkWorld;// frame of obstacle-point w.r.t universe frame
00211                 VectorN vObsPtsInLink(0, 0, 0); // The position of closest point in joint
00212 
00213         //Determine the joint where current obstacle point lies.
00214         robFrame = m_vClosestPoints[j].robFrame;
00215 
00216         //Compute the universe frame of the obstacle-point in joint;
00217         //  entry: vObsPtsInLink[] w.r.t joint $robFrame$
00218         //  exit : vObsPtsInLink[] w.r.t universe frame
00219                 worldTObsFrame = jacobian.GetJointWorldFrame(robFrame-1);       
00220         vObsPtsInLink[0] = m_vClosestPoints[j].rob_pts[0];  // point on robot arm closest to obstacle wrt link
00221         vObsPtsInLink[1] = m_vClosestPoints[j].rob_pts[1];
00222         vObsPtsInLink[2] = m_vClosestPoints[j].rob_pts[2]; 
00223                 Vector4 vTranslate(vObsPtsInLink[0], vObsPtsInLink[1], vObsPtsInLink[2]);
00224                 frObsPtsInLink.Translate(vTranslate);           
00225         frObsPtsInLinkWorld = worldTObsFrame * frObsPtsInLink;
00226                 vTranslate = frObsPtsInLinkWorld.GetTranslationVector();
00227                 vObsPtsInLink[0] = vTranslate[0];
00228                 vObsPtsInLink[1] = vTranslate[1];
00229                 vObsPtsInLink[2] = vTranslate[2];
00230 
00231                 // The position of closest point in obstacle, it's wrt frame 0, universe frame
00232         VectorN vObsPtWorld(m_vClosestPoints[j].obs_pts[0],m_vClosestPoints[j].obs_pts[1], m_vClosestPoints[j].obs_pts[2]);
00233                 //Set the normalized escape velocity
00234                 VectorN vObsEscapeVel = vObsPtsInLink - vObsPtWorld;
00235                 vObsEscapeVel /= vObsEscapeVel.Magnitude();
00236 
00237                 //Compute Jacobian matrix with respect to obstacle point
00238         //Set jacobian to be interested in obstacle point;
00239                 Matrixmxn mJObs, mJObsInv;              //Jacobian and its inverse of Obstacle point;
00240                 if (robFrame == m_nDof)
00241                 {
00242                         frObsPtsInLink = Matrix4x4::Identity();
00243                         frObsPtsInLink.Translate(jacobian.GetJointFrame(robFrame-1).GetTranslationVector());
00244                         jacobian.SetInterestPoint(robFrame-2, frObsPtsInLink, true, false);
00245                 }
00246                 else
00247                 {
00248                         jacobian.SetInterestPoint(robFrame-1, frObsPtsInLink, true, false);
00249                 }
00250                 mJObs = *(jacobian.GetMatrix());
00251                 mJObs.Inverse(mJObsInv);
00252                 LogMatrix("ikJacobian.log", mJObs, "Jacobian Matrix for Obstale point: ");
00253                 LogMatrix("ikJacobian.log", mJObsInv, "Inverse of Jobs: ");
00254 
00255                 Matrixmxn mTemp(m_nDof, m_nDof);   //Identity
00256                 Matrixmxn mTemp2(mTemp);           //Identity
00257                 Matrixmxn mTemp3(mTemp);           //Identity           
00258                 Matrixmxn mTemp4(mTemp);           //Identity
00259 
00260                 mTemp -= mJEndInv * mJEnd;         //$I - J^{+}_e J_e$
00261                 LogMatrix("ikJacobian.log", mTemp, "Temp: I-Je^+ Je");
00262                 mTemp2 -= mJObsInv * mJObs;         //$I - J^{+}_o J_o$
00263                 LogMatrix("ikJacobian.log", mTemp2, "Temp2: I-Jo^+ Jo");
00264                 mTemp3 = mJObs * mTemp;             //$J_o (I - J^{+}_e J_e)$
00265                 LogMatrix("ikJacobian.log", mTemp3, "Temp3: Jo (I-Je^+ Je)");
00266                 mTemp3 = mTemp3.Inverse();          //$[J_o (I - J^{+}_e J_e)]^{+}$
00267                 LogMatrix("ikJacobian.log", mTemp3, "Inverse of Temp3:");
00268                 mTemp4 = mJObs * mJEndInv;          //J_o J^{+}_e
00269                 LogMatrix("ikJacobian.log", mTemp3, "Temp4: Jo Je^+");
00270 
00271                 double solnGain; //applied to every term of homogeneous solution
00272                 double velcGain; //used to determine escape velocity, $x_o$
00273         if (m_vClosestPoints[j].distance < UNITY_GAIN_DISTANCE)
00274         { 
00275             solnGain = m_dHomoGain;
00276         }
00277         else if (m_vClosestPoints[j].distance > SOI_GAIN_DISTANCE)
00278         {
00279             solnGain = 0;
00280         }
00281         else
00282         {
00283             solnGain = m_dHomoGain*m_vClosestPoints[m_nObsPoint-1-j].distance/m_dTotalObsDist;
00284         }
00285 
00286         if ((m_dObsDistGain/(m_vClosestPoints[j].distance)) > MAX_OBS_VEL)
00287         {
00288             velcGain = MAX_OBS_VEL;
00289         }
00290         else
00291         {
00292             velcGain = m_dObsDistGain / (m_vClosestPoints[j].distance);
00293         }
00294 
00295                 mTemp3 *= solnGain;    //$\alpha_i[J_o(I-J^{+}_eJ_e)]^{+}$
00296                 VectorN vTemp = vObsEscapeVel * velcGain; //$\dot{x}_o$ is related to distance 
00297                 vTemp -= mTemp4 * vEndEffVel;  //$\dot{x}_o-J_oJ^{+}_e\dot{x}_e$
00298                 vSingleTerm = mTemp3 * vTemp;  //$\alpha_i[J_o(I-J^{+}_eJ_e)]^{+}(\dot{x}_o-J_oJ^{+}_e\dot{x}_e)$
00299                 
00300                 vHomogeneousSolns += vSingleTerm; //Sum them up
00301 
00302                 LogVector("ikJacobian.log", vSingleTerm, "Single Term:");
00303     }   // got all homogeneous solutions
00304 
00305     return vHomogeneousSolns;
00306 }
00307 
00308 bool IK_Jacobian::Plan()
00309 {
00310         // Start the timer
00311         StartTimer();
00312 
00313     // check to see that SWIFTpp is the collision detector used
00314     const CD_Swiftpp* pSwiftpp = dynamic_cast< const CD_Swiftpp* >( collisionDetector );
00315     if (pSwiftpp == NULL)
00316     {
00317         return false;
00318     }
00319 
00320     // quick checks
00321         if ( collisionDetector->IsInterfering( GetStartConfig() ) )
00322         {
00323                 // there is a collision with the start configuration...report failure
00324         //MessageBox(NULL, "Collision detected while planning.","IK_Jacobian Planner Error", MB_OK);
00325                 return false;
00326         }
00327 
00328     Configuration   currentConfig, nextConfig, jointVelocity;
00329     currentConfig.SetNumDOF(m_nDof);
00330     nextConfig.SetNumDOF(m_nDof);
00331     jointVelocity.SetNumDOF(m_nDof);
00332     jointVelocity *= 0;     //Clear
00333     currentConfig = GetStartConfig();
00334     
00335     path.Clear();
00336     path.AppendPoint(currentConfig);
00337 
00338         //Initialize Jacobian, obstacle point and end-effector will share a Jacobian matrix.
00339         CJacobian jacobian(*m_pRobot);
00340         jacobian.SetConfiguration(currentConfig);
00341 
00342         bool abort = false;
00343     for (int iViaPts = 0; iViaPts < (poses.size()-1); iViaPts++)
00344     {
00345                 //Compute endeffector Linear & Angular velocity;
00346                 VectorN vEndEffVel;
00347                 //Since the start configuration has been applied to jacobian, we get pose under startconfig.
00348                 Frame frCurrentEndEff = jacobian.GetJointWorldFrame(m_nDof-1)*m_frEndEffector;
00349 
00350                 double dist = Distance(frCurrentEndEff, poses[iViaPts]);
00351                 if (dist > m_dPathTol)
00352                 {
00353                         LogMessage("ikJacobian.log", "Aborting.... Motion too large!");
00354                         abort = true;
00355                         break;
00356                 }
00357                 if (m_bOrientation)
00358                 {
00359                         double x1, y1, z1, yaw1, roll1, pitch1;
00360                         double x2, y2, z2, yaw2, roll2, pitch2;
00361                         GetRotAngles(frCurrentEndEff, x1, y1, z1, roll1, pitch1, yaw1);
00362                         GetRotAngles(poses[iViaPts], x2, y2, z2, roll2, pitch2, yaw2);
00363                         if ( (fabs(roll1-roll2)>m_dAngTol) || (fabs(pitch1-pitch2)>m_dAngTol) || (fabs(yaw1-yaw2)>m_dAngTol) )
00364                         {
00365                                 LogMessage("ikJacobian.log", "Aborting.... Motion too large!");
00366                                 abort = true;
00367                                 break;
00368                         }
00369                 }
00370 
00371         //nothing but logging
00372                 Matrix4x4 logmat;
00373                 Matrixmxn logmatmn;
00374                 logmat = poses[iViaPts];
00375                 logmatmn = logmat;
00376                 LogMatrix("ikJacobian.log", logmatmn , "Expected pose in Trajectory:");
00377                 logmat = frCurrentEndEff;
00378                 logmatmn = logmat;
00379                 LogMatrix("ikJacobian.log", logmatmn, "Actually Pose got:");
00380                 logmat = jacobian.GetJointWorldFrame(m_nDof-1)*m_frEndEffector;
00381                 logmatmn = logmat;
00382                 LogMatrix("ikJacobian.log", logmatmn, "End-effecot Frame:");
00383 
00384         //Compute next end-effector velocity
00385                 vEndEffVel = ComputeEndEffVel(frCurrentEndEff, poses[iViaPts+1]);
00386                 LogVector("ikJacobian.log", vEndEffVel, "Endeffector Velocity");
00387 
00388         //Compute end-effector Jacobian matrix, and its inverse
00389                 jacobian.SetInterestPoint(m_nDof-1, m_frEndEffector, m_bPosition, m_bOrientation);
00390                 jacobian.GetJointVelocity(jointVelocity, vEndEffVel);
00391                 Matrixmxn mJEnd, mJEndInv;
00392                 mJEnd = *(jacobian.GetMatrix());
00393                 mJEnd.Inverse(mJEndInv);
00394                 LogMatrix("ikJacobian.log", mJEnd, "Jacobian matrix of end-effector:");
00395                 LogMatrix("ikJacobian.log", mJEndInv, "Jacobian matrix Inverse:");
00396 
00397                 //============= Begin of obstacles =====================
00398         // Getting the homogeneous solutions for the obstacles (Jo's)
00399         // check for the closest points between robot/obstacles
00400         if (GetClosestValues(currentConfig) != false)
00401                 {
00402                         LogMessage("ikJacobian.log", "Aborting.... Colliding when getting collision points!");
00403                         abort = true;
00404             break;
00405                 }
00406 
00407         double obsDirMag = 0;
00408         // if closest distance is critical, abort
00409         if (m_vClosestPoints[0].distance <= m_dObsTol)
00410         {                
00411             //MessageBox(NULL, "Collision detected while planning", "IK_Jacobian Planner Error", MB_OK);
00412                         LogMessage("ikJacobian.log", "Aborting.... Colliding, too close to obstacles!");
00413             abort = true;
00414             break;
00415         }            
00416         //** no obstacle scenario handled by infinite distance
00417         else
00418         {
00419             //Compute homogeneous solution
00420                         VectorN vHomogeneousSolns;
00421                         vHomogeneousSolns = ComputeHomogeneousTerm(jacobian, mJEnd, mJEndInv, vEndEffVel);
00422                         LogVector("ikJacobian.log", vHomogeneousSolns, "Homogeneous Term:");
00423                         
00424             //Compute general solution
00425                         jointVelocity += vHomogeneousSolns;
00426         } // obstacles exist
00427                 //============= End of obstacles =====================
00428 
00429                 //Convert to degree representation;
00430         CheckJointVelocities(jointVelocity);
00431                 for (int i=0; i<m_nDof; i++)
00432                 {
00433                         double dValue = jointVelocity[i];
00434                         jointVelocity[i] = Rad2Deg(dValue);
00435                 }
00436                 LogVector("ikJacobian.log", jointVelocity, "Joint Velocity");        
00437                 
00438         // calculate where the new velocity takes us after time interval
00439                 nextConfig = currentConfig + jointVelocity;
00440         CheckJointLimits(nextConfig);
00441                 LogVector("ikJacobian.log", nextConfig, "Next Configuration");
00442                        
00443         // got next configuration, now need to see if it's valid               
00444         //if (collisionDetector->IsInterferingLinear(currentConfig, nextConfig ) == false)
00445                 if (collisionDetector->IsInterfering(nextConfig) == false)
00446         {        
00447             // there's no point adding it if it's the same
00448             if (currentConfig != nextConfig)        
00449             {
00450                 currentConfig = nextConfig;
00451                 path.AppendPoint(currentConfig);
00452                 // GetEndEffVector(currentConfig, vCurPt);
00453             }
00454             jacobian.SetConfiguration(currentConfig);
00455         }
00456         else        // interfering
00457         {
00458             //MessageBox(NULL, "Obstacle in path could not be avoided","IK_Jacobian Planner Error", MB_OK);
00459                         LogMessage("ikJacobian.log", "Aborting.... Colliding when checking next configuration!");
00460             abort = true;
00461                         break;
00462         }            
00463 
00464         if (HasTimeLimitExpired() != false)
00465         {            
00466             //MessageBox(NULL, "Time's up!", "Plan() fail - Time's Up!", MB_OK);
00467                         LogMessage("ikJacobian.log", "Aborting.... Time up!");
00468             abort = true;
00469                         break;
00470         }
00471     }
00472 
00473     //semaphore.Unlock();
00474         if (abort)
00475         {
00476                 LogMessage("ikJacobian.log", "### Planning Failure");
00477         }
00478         else
00479         {
00480                 LogMessage("ikJacobian.log", "### Planning Success");
00481         }
00482     return (abort == false);
00483 }
00484 
00485 
00486 void IK_Jacobian::InitNewSearch()
00487 {
00488 }
00489     
00490 void IK_Jacobian::SetObstacleTolerance(double tol)
00491 {
00492     m_dObsTol = tol;
00493     ((CD_Swiftpp*) collisionDetector)->SetObstacleTolerance(tol);
00494 }
00495 
00496 
00497 //------------------------------------------------------------------
00498 //GetClosestValues
00499 //
00500 //This function is used to finds the closest $m_nObsPoint number$ of points and their distances.
00501 //
00502 //Input Parameter:
00503 //      config: Given a configuration.
00504 //
00505 //Ouput Parameter:
00506 //      N.A.
00507 //
00508 //Return Value:
00509 //      true if collision detected; false otherwise.
00510 //
00511 //Note:
00512 //      Refer to SWIFT++ for more parameter information.
00513 //      
00514 //------------------------------------------------------------------
00515 bool IK_Jacobian::GetClosestValues(const Configuration& config)
00516 {    
00517     double  *query_d, *query_npts;
00518     int     iLink1, iLink2, query_np, *query_oids, *query_num_contacts, 
00519             index = -1;
00520 
00521     m_vClosestPoints.clear();
00522     closeValues init;
00523     init.distance = INFINITY;
00524     m_vClosestPoints.push_back(init);
00525 
00526     bool collision = ((CD_Swiftpp*) collisionDetector)->QueryContactDetermination( config, 
00527         true, INFINITY, query_np, &query_oids, &query_num_contacts, &query_d, &query_npts);
00528 
00529     if (collision != false) 
00530         {
00531                 return true;
00532         }
00533 
00534     int j, k, min;    // temp variables for indexing
00535 
00536     //** start here: figure out what to do with no obstacles because query_np may not be 0 without obstacles
00537     //** also check why query is reported for b/t robot links
00538 
00539     for (int i = 0; i < query_np; i++)
00540     {
00541         index += query_num_contacts[i];
00542         if (m_vClosestPoints.size() >= m_nObsPoint)
00543         {
00544             if (query_d[index] > m_vClosestPoints[m_nObsPoint-1].distance)  
00545                         {
00546                                 continue;
00547                         }
00548             // if the shortest distances is not short enough to replace any current distances
00549         }
00550 
00551         // make sure links are valid:
00552         iLink1 = ((CD_Swiftpp*) collisionDetector)->GetRobotLinkBaseFrame(query_oids[2*i]);
00553         iLink2 = ((CD_Swiftpp*) collisionDetector)->GetRobotLinkBaseFrame(query_oids[2*i+1]);
00554         if ((iLink1 == -1) || (iLink2 == -1))  
00555                 {
00556                         return false;
00557                 }
00558         if (((iLink1 == 0)^(iLink2 == 0)) == false)  //between obstacles or between robot joints
00559                 {
00560                         continue;
00561                 }
00562 
00563         // testing begins here:
00564         min = min(query_num_contacts[i], m_nObsPoint);
00565         k = 0;
00566         for (j = 0; j < min; j++)
00567         {
00568             while (k < m_nObsPoint)
00569             {
00570                 if(m_vClosestPoints[k].distance > query_d[index-j]) // need insertion
00571                 {
00572                     closeValues newEntry;
00573                     newEntry.distance = query_d[index-j];
00574                     if (iLink1 == 0)
00575                     {
00576                         newEntry.obs_pts[0] = query_npts[6*index];
00577                         newEntry.obs_pts[1] = query_npts[6*index+1];
00578                         newEntry.obs_pts[2] = query_npts[6*index+2];
00579                         newEntry.robFrame = iLink2;
00580                         newEntry.rob_pts[0] = query_npts[6*index+3];
00581                         newEntry.rob_pts[1] = query_npts[6*index+4];
00582                         newEntry.rob_pts[2] = query_npts[6*index+5];
00583                     }
00584                     else // iLink2 == 0
00585                     {
00586                         newEntry.obs_pts[0] = query_npts[6*index+3];
00587                         newEntry.obs_pts[1] = query_npts[6*index+4];
00588                         newEntry.obs_pts[2] = query_npts[6*index+5];
00589                         newEntry.robFrame = iLink1;
00590                         newEntry.rob_pts[0] = query_npts[6*index];
00591                         newEntry.rob_pts[1] = query_npts[6*index+1];
00592                         newEntry.rob_pts[2] = query_npts[6*index+2];
00593                     }
00594                     m_vClosestPoints.insert(m_vClosestPoints.begin()+k, newEntry);                    
00595                     k++;
00596                     break;
00597                 }
00598                 else if(&m_vClosestPoints[k] == m_vClosestPoints.end())  // at the end
00599                 {
00600                     closeValues newEntry;
00601                     newEntry.distance = query_d[index-j];
00602                     if (iLink1 == 0)
00603                     {
00604                         newEntry.obs_pts[0] = query_npts[6*index];
00605                         newEntry.obs_pts[1] = query_npts[6*index+1];
00606                         newEntry.obs_pts[2] = query_npts[6*index+2];
00607                         newEntry.robFrame = iLink2;
00608                         newEntry.rob_pts[0] = query_npts[6*index+3];
00609                         newEntry.rob_pts[1] = query_npts[6*index+4];
00610                         newEntry.rob_pts[2] = query_npts[6*index+5];
00611                     }
00612                     else // iLink2 == 0
00613                     {
00614                         newEntry.obs_pts[0] = query_npts[6*index+3];
00615                         newEntry.obs_pts[1] = query_npts[6*index+4];
00616                         newEntry.obs_pts[2] = query_npts[6*index+5];
00617                         newEntry.robFrame = iLink1;
00618                         newEntry.rob_pts[0] = query_npts[6*index];
00619                         newEntry.rob_pts[1] = query_npts[6*index+1];
00620                         newEntry.rob_pts[2] = query_npts[6*index+2];
00621                     }
00622                     m_vClosestPoints.push_back(newEntry);
00623                     k++;
00624                     break;
00625                 }
00626                 k++;
00627             }
00628             if (k >= m_nObsPoint) {break;}
00629         }
00630     }
00631     if ((m_vClosestPoints[0].distance == INFINITY)||(query_np==0))    // no obstacles
00632     {   // setting everything to infinity essentially makes it useless
00633         closeValues defaults;
00634         defaults.distance = INFINITY;
00635         defaults.robFrame = 1;
00636         defaults.obs_pts[0] = INFINITY;
00637         defaults.obs_pts[1] = INFINITY;
00638         defaults.obs_pts[2] = INFINITY;
00639         defaults.rob_pts[0] = 1;
00640         defaults.rob_pts[1] = 0;
00641         defaults.rob_pts[2] = 0;
00642 
00643         m_vClosestPoints.clear();
00644         for (i = 0; i < m_nObsPoint; i++)
00645         {
00646             m_vClosestPoints.push_back(defaults);
00647         }
00648              
00649     }
00650     else if (query_np > 0)  
00651     {
00652         m_vClosestPoints.erase(m_vClosestPoints.begin() + m_nObsPoint, m_vClosestPoints.end());
00653         m_dTotalObsDist = 0;
00654         for (i = 0; i < m_vClosestPoints.size(); i++)
00655         {
00656             m_dTotalObsDist += m_vClosestPoints[i].distance;
00657         }
00658     }
00659     else                        // negative should never happen, so return as a collision
00660     {
00661         return true;
00662     }
00663 
00664     return false;
00665 }
00666 
00667 void IK_Jacobian::CheckJointLimits(Configuration& config)
00668 {
00669         for (int i = 0; i<m_nDof; i++)
00670         {
00671                 if ( config[i] < collisionDetector->JointMin(i) )
00672                 {
00673                         config[i] = collisionDetector->JointMin(i);
00674                 }
00675                 else if ( config[i] > collisionDetector->JointMax(i) )
00676                 {
00677                         config[i] = collisionDetector->JointMax(i);
00678                 }
00679         }
00680 }
00681 
00682 void IK_Jacobian::CheckJointVelocities(Configuration& config)
00683 {
00684     for (int i = 0; i < m_nDof; i++)
00685     {
00686         if (config[i] < -MAX_JOINT_VEL)
00687         {
00688             config[i] = -MAX_JOINT_VEL;
00689         }
00690         else if (config[i] > MAX_JOINT_VEL)
00691         {
00692             config[i] = MAX_JOINT_VEL;
00693         }
00694         
00695     }
00696 }
00697 
00698 /*
00699 Matrix4x4 IK_Jacobian::GetToolFrame( const Configuration& config ) const
00700 {
00701 
00702         if ( (collisionDetector == NULL) || (m_nToolFrame == -1) )
00703         {
00704                 return IK_InvKinBase::GetToolFrame(config);
00705         }
00706 
00707         Frame toolFrame = Matrix4x4();
00708 
00709         if ( collisionDetector != NULL )
00710         {
00711                 FrameManager* frameManager = collisionDetector->GetFrameManager();
00712                 collisionDetector->SetConfiguration( config );
00713                 toolFrame = *(frameManager->GetFrameRef(m_nToolFrame));
00714                 toolFrame = frameManager->GetTransformRelative(collisionDetector->DOF(), 0) * toolFrame;
00715         }
00716         return toolFrame;
00717 }
00718 */
00719 
00720 void IK_Jacobian::SetTrajectory(std::vector<Frame> &traj)
00721 {
00722         poses.clear();
00723         for (int i=0; i<traj.size(); i++)
00724         {
00725                 poses.push_back(traj[i]);
00726 
00727                 char szMsg[100];
00728                 Matrixmxn matLog = traj[i];
00729                 sprintf(szMsg, "%d(th) pose:\n", i);
00730                 LogMatrix("ikJacobian.log", matLog, szMsg);
00731         }
00732 
00733 }
00734 
00735 
00736 double IK_Jacobian::Distance(Frame &frame1, Frame &frame2)
00737 {
00738         Vector4 vec1 = frame1.GetTranslationVector();
00739         Vector4 vec2 = frame2.GetTranslationVector();
00740         vec1 -= vec2;
00741         return vec1.Magnitude();
00742 }
00743 

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