planners/closedchain/PL_PRM_ClosedChain.cpp

Go to the documentation of this file.
00001 
00002 #include "math/vector4.h"
00003 #include "math/matrixmxn.h"
00004 #include "synchronization/semaphore.h"
00005 #include "robots/R_OpenChain.h"
00006 #include "CollisionDetectors/CD_Swiftpp.h"
00007 #include <assert.h>
00008 #include "planners/inversekin/Redundant.h"
00009 #include "planners/ik_mpep/IK_Jacobian.h"
00010 #include "PL_PRM_ClosedChain.h"
00011 #include <gl/gl.h>
00012 #include <opengl/gl_sphere.h>
00013 #include <opengl/gl_group.h>
00014 
00015 #define MAX_ITERATION        30
00016 #define MAX_RETRY            30
00017 #define MAX_RETRY2           30
00018 #define DEF_NEIGHBOR         (2)
00019 #define DEF_ERR_TOLERANCE    (1e-3)       //For End-effector
00020 #define DEF_RESOLUTION       (15)         //Distance between two closed configuration
00021 
00022 
00023 PL_PRM_ClosedBase::PL_PRM_ClosedBase()
00024 {
00025         edgePath.init(G);
00026         edgeFrag = new Fragment;
00027 }       
00028 
00029 PL_PRM_ClosedBase::~PL_PRM_ClosedBase()
00030 {
00031         edgeFrag->clear();
00032         delete edgeFrag;
00033 }
00034 
00035 bool PL_PRM_ClosedBase::Plan ()
00036 {
00037         return PL_PRM::Plan();
00038 }
00039 
00040 //****************************************************************************
00041 //             Function to Get Tool Frame: End-effector Frame.
00042 //****************************************************************************
00043 Frame PL_PRM_ClosedBase::GetToolFrame( const Configuration& config ) const
00044 {
00045         Frame toolFrame = Matrix4x4();
00046         if ( collisionDetector != NULL )
00047         {
00048                 FrameManager* frameManager = collisionDetector->GetFrameManager();
00049                 collisionDetector->SetConfiguration( config );
00050                 R_OpenChain * robot = (R_OpenChain *)collisionDetector->GetRobot(0);
00051                 int toolFrameID = robot->GetToolFrame(0);
00052                 if (toolFrameID == -1)
00053                 {
00054                         toolFrameID = collisionDetector->JointFrameNum(collisionDetector->DOF()-1);
00055                         toolFrame = frameManager->GetWorldFrame( toolFrameID );
00056                 }
00057                 else
00058                 {
00059                         toolFrame = *(frameManager->GetFrameRef(toolFrameID));
00060                         toolFrame = frameManager->GetTransformRelative(collisionDetector->DOF(), 0) * toolFrame;
00061                 }
00062         }
00063         return toolFrame;
00064 }
00065 
00066 Configuration PL_PRM_ClosedBase::GenerateRandomConfig ()
00067 {
00068         Configuration conf;
00069         conf = PL_PRM::GenerateRandomConfig();
00070         MakeItClosed(conf);
00071         return conf;
00072 }
00073 
00074 Configuration PL_PRM_ClosedBase::GenerateRandomConfig ( const Configuration& seed, const double& std_dev )
00075 {
00076         Configuration conf;
00077         conf = PL_PRM::GenerateRandomConfig(seed, std_dev);
00078         MakeItClosed(conf);
00079         return conf;
00080 }
00081 
00082 void PL_PRM_ClosedBase::ConnectEdgesFull( const node& newnode, const double& radius_squared )
00083 {
00084         // verify connectIDp is valid.
00085         assert( connectIDp != NULL );
00086 
00087         // Save calculation time by determining configuration of the node once intstead of in each iteration
00088         Configuration nodeconfig = G.inf(newnode);
00089 
00090         node n1;
00091 
00092         // create a list of neighbour nodes to connect to within the given radius.
00093         node_pq<double> neighbours(G);
00094         forall_nodes( n1, G)
00095         {
00096                 if ( newnode != n1)
00097                 {
00098                         double edgelength_squared = Distance( nodeconfig, G.inf(n1) );  // returns the squared distance
00099                         // Check if the two nodes are within radius
00100                         if (  edgelength_squared <= radius_squared )  // can compare squares since a^2<b^2 if |a|<|b|
00101                         {
00102                                 // node is within radius, add it as a neighbour with its distance as its priority.
00103                                 neighbours.insert( n1, edgelength_squared );
00104                         }
00105                 }
00106         }
00107 
00108         // New node is currently not connected to anyone, assign it the NIL_ID.
00109         (*connectIDp)[newnode] = NIL_ID;
00110 
00111         // Create a running list of graph connected components new node is attached to.
00112         list<int> connectIDs;
00113 
00114         // While the list of neighbour is not empty, connect the node to the closests nodes, not already graph
00115         // connected to.
00116         while ( !neighbours.empty() )
00117         {
00118                 // get closest neighbour and remove it from the list
00119                 node neighbour = neighbours.find_min();
00120                 double dist_sq = neighbours.inf( neighbour );
00121                 neighbours.del( neighbour );
00122 
00123                 // connect the neighbour to the new node if it is not already graph connected.
00124                 // A node is graph connected if its current connectID is in the running list of
00125                 // connected graph components or has the same connectID as the new node.
00126                 if ( ((*connectIDp)[neighbour] == NIL_ID) ||
00127                          ( ((*connectIDp)[neighbour] != (*connectIDp)[newnode]) &&
00128                            ( !NodeInConnectionList(neighbour, connectIDs) ) )
00129                    )
00130                 {
00131                         edgeFrag->clear();
00132                         // nodes are not aleady connected.  Connect them now if there is a collision free path.
00133                         if ( !IsInterfering( nodeconfig, G.inf(neighbour) ) )
00134                         {
00135                                 double edgelength = sqrt( dist_sq );
00136                                 edge newedge = G.new_edge( newnode, neighbour, edgelength );
00137                                 edgeChecked[newedge] = TRUE;
00138                                 edgePath[newedge] = *edgeFrag;
00139 
00140                                 //LogMessage("closedchain.log", "Configurations checked in fragment");
00141                                 //for (int testj=0; testj<edgePath[newedge].size(); testj++)
00142                                 //{
00143                                 //      Fragment& E= edgePath[newedge];
00144                                 //      list_item itt = E.get_item(testj);
00145                                 //      Configuration conf = (E[itt]);
00146                                 //      LogVector("closedchain.log", conf, "Conf: ");
00147                                 //}
00148 
00149                                 // update the connectionIDs to show these two nodes are now graph connected.
00150                                 if ( (*connectIDp)[neighbour] != NIL_ID )
00151                                 // neighbour node has been previously connected to a graph component.
00152                                 {
00153                                         if ( (*connectIDp)[newnode] == NIL_ID )
00154                                         {
00155                                                 // node has not been previously connected, assign it the connect ID of its new neighbour.
00156                                                 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
00157                                         }
00158                                         else if ( (*connectIDp)[neighbour] < (*connectIDp)[newnode] )
00159                                         {
00160                                                 // the neighbour node has the smaller ID.  Select this as the new ID for the two
00161                                                 // newly connected graph components (one from the new neighbour, one from the new node).
00162 
00163                                                 // save the old connectionID into the running list to be updated later.
00164                                                 connectIDs.push( (*connectIDp)[newnode] );
00165 
00166                                                 // assign the lower connection ID to the new node.
00167                                                 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
00168                                         }
00169                                         else
00170                                         {
00171                                                 // the new node has the smaller ID.  Select this as the new ID for the two components.
00172 
00173                                                 // save the old connectionID into the running list to be updated later.
00174                                                 connectIDs.push( (*connectIDp)[neighbour] );
00175 
00176                                                 // assign the lower connection ID to the neighbour.
00177                                                 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
00178                                         }
00179                                 }  // end if neighbour != NIL_ID
00180                                 else
00181                                 // neighbour has not been previously connected.
00182                                 {
00183                                         if ( (*connectIDp)[newnode] != NIL_ID )
00184                                         {
00185                                                 // new node has been previously connected, assign the neighbour its ID.
00186                                                 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
00187                                         }
00188                                         else
00189                                         {
00190                                                 // both nodes have not been previously connected.  Create a new graph connected
00191                                                 // component by assigning these two nodes the baseConnectID.
00192                                                 (*connectIDp)[newnode] = baseConnectID;
00193                                                 (*connectIDp)[neighbour] = baseConnectID;
00194 
00195                                                 // Update the base connect ID to ensure a new unique ID is available for next new node.
00196                                                 baseConnectID++;
00197                                         }
00198                                 }  // end update connectIDs.
00199 
00200                         } // end if interfering
00201                         else
00202                         {
00203                                 edgeFrag->clear();
00204                                 // nodes have a collision path.  Use the midpoint between these two nodes as a seed for enhancing.
00205                                 // Add the midpoint of this potential edge as a seed, if requested
00206                                 if ( useMidPts )
00207                                 {
00208                                         Configuration midpt = GetMidPoint( nodeconfig, G.inf(neighbour) );
00209                                         config_seeds.append( midpt );
00210                                 }
00211                         }  // end if interfering else.
00212 
00213                 }       // end if not already graph connected.
00214 
00215         } // end while !neighbours.empty().
00216 
00217         // Search the entire graph, if required, updating connectIDs to reflect how new node has graph connected
00218         // different components of the graph.
00219         if ( ((*connectIDp)[newnode] != NIL_ID) && ( !connectIDs.empty() ) )
00220         {
00221                 // new node is connected to more than one graph connected component.  Update the connect IDs of
00222                 // affected nodes.
00223                 int newID = (*connectIDp)[newnode];
00224 
00225                 forall_nodes( n1, G )
00226                 {
00227                         if ( ((*connectIDp)[n1] != newID ) && (NodeInConnectionList( n1, connectIDs )) )
00228                         {
00229                                 (*connectIDp)[n1] = newID;
00230                         }
00231                 }
00232         }  // end update connectIDs of entire graph
00233 
00234         return;
00235 }
00236 
00237 bool PL_PRM_ClosedBase::IsClosed(const Configuration &conf) const
00238 {
00239         return (Error(conf) <= DEF_ERR_TOLERANCE);
00240 }
00241 
00242 bool PL_PRM_ClosedBase::IsInterfering ( const Configuration& c1 )
00243 {
00244         if (!IsClosed(c1)) 
00245                 return true;
00246         if (PL_PRM::IsInterfering(c1))
00247                 return true;
00248         return false;
00249 }
00250 
00251 //Distance between a configuration to a closure constraint
00252 double PL_PRM_ClosedBase::Error(const Configuration &p1) const
00253 {
00254         Frame toolFrame = GetToolFrame( p1 );
00255         Vector4 offset = toolFrame.GetTranslationVector();
00256         offset[2] = 0;
00257         return offset.Magnitude();
00258 }
00259 
00260 SuccessResultType PL_PRM_ClosedBase::TranslatePath()
00261 {
00262         // Clear any current path.
00263         path.Clear();
00264 
00265         // Check if a graph path is available.
00266         if ( graphPath.empty() )
00267         {
00268                 // Path is empty.  Set start as the beginning of the path, and return.
00269                 path.AppendPoint( GetStartConfig() );
00270 
00271                 // no path exists.
00272                 return FAIL;
00273         }
00274 
00275         // If still in the function, there is a graphPath.
00276         // Go through all nodes stored in graphPath and assign the configuration they correspond to the
00277         // actual path.
00278         node n1;
00279         node n2;
00280         forall( n1, graphPath )
00281         {
00282                 Configuration conf = G.inf(n1);
00283                 path.AppendPoint( conf );
00284                 n2 = graphPath.succ(n1);
00285                 if (n2 == NULL)
00286                         continue;
00287 
00288                 edge e;
00289                 forall_inout_edges(e, n1)
00290                 //edge e = G.first_in_edge(n1);
00291                 //while(e)
00292                 {
00293                         if (G.opposite(n1, e) == n2)
00294                         {
00295                                 int nStep = 0;
00296                                 int dir = -1;
00297                                 Fragment& frag = edgePath[e];
00298                                 int nFirst = frag.size();
00299                                 if (conf == frag[frag[0]]) //?
00300                                 {
00301                                         nFirst = 0;
00302                                         dir = 1;
00303                                 }
00304                                 for (int i=1; i<(frag.size()-1); i++)
00305                                 {
00306                                         nStep += dir;
00307                                         list_item it = frag[nFirst+nStep];
00308                                         conf = frag[it];
00309                                         //->get_item(i);//((*frag)[nFirst+dir]);
00310                                         path.AppendPoint( conf );
00311                                 }
00312                                 break;
00313                         }
00314                 }
00315         }
00316 
00317         // Path has been translated and is ready to be animated.
00318         return PASS;
00319 }
00320 
00321 //===========================================================================================
00322 PL_PRM_ClosedLocalJacobian::PL_PRM_ClosedLocalJacobian()
00323 {
00324         planner = new LocalPlannerClosed;
00325         pCollisionDetector = NULL;
00326 }
00327 
00328 PL_PRM_ClosedLocalJacobian::~PL_PRM_ClosedLocalJacobian()
00329 {
00330         if(pCollisionDetector)
00331         {
00332                 delete pCollisionDetector;
00333         }
00334         delete planner;
00335 }
00336 
00337 void PL_PRM_ClosedLocalJacobian::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00338 {
00339         // Call Parent's Collision Detector and assign the collision detector
00340         PL_PRM_ClosedBase::SetCollisionDetector( collisionDetector );
00341 
00342         if (pCollisionDetector != NULL)
00343                 delete pCollisionDetector;
00344 
00345         pCollisionDetector = new CD_Swiftpp( *(collisionDetector->GetUniverse()) );
00346         planner->SetCollisionDetector(pCollisionDetector);
00347         pCollisionDetector->DeactivateFrames(1, pCollisionDetector->DOF());
00348 }
00349 
00350 bool PL_PRM_ClosedLocalJacobian::Plan ()
00351 {
00352         PlannerBase::StartTimer() ;
00353         path.Clear() ;
00354         
00355         planner->SetTimeLimitInSeconds(GetTimeLimitInSeconds());
00356         Configuration q1 = GetStartConfig();
00357         Configuration q2 = GetGoalConfig();
00358         planner->SetStartConfig(q1);
00359         planner->SetGoalConfig(q2);
00360 
00361         double dObstacleTol = 0.01;
00362         double dHomogain = 2.0;
00363         double dPathTol = 0.5;
00364         int nObstacleNum = 2;
00365 
00366         planner->SetObstacleTolerance(dObstacleTol);
00367         planner->SetNumObstaclePt(nObstacleNum);
00368         planner->SetHomogeneousGain(dHomogain);
00369         planner->SetPathTolerence(dPathTol);
00370         planner->SetOrientation(false);
00371         planner->SetPosition(true);
00372 
00373         //if (planner->Plan())
00374         bool result = planner->Plan();
00375 
00376         PA_Points *plannerPath = (PA_Points *)planner->GetPath();
00377         path = *plannerPath;
00378 
00379         //To take a look at where planner fail to go on,
00380         //the path will be returned no matter the planing is success or not.
00381         return result;
00382 }
00383 
00384 bool PL_PRM_ClosedLocalJacobian::MakeItClosed(Configuration &conf)
00385 {
00386         return true;
00387 }
00388 
00389 bool PL_PRM_ClosedLocalJacobian::IsInterfering ( const Configuration& q1, const Configuration& q2 )
00390 {
00391         return false;
00392 }
00393 
00394 //===========================================================================================
00395 PL_PRM_ClosedJacobian::PL_PRM_ClosedJacobian()
00396 {
00397         m_pRobot = NULL;
00398         jacobian = NULL;
00399 }
00400 
00401 PL_PRM_ClosedJacobian::~PL_PRM_ClosedJacobian()
00402 {
00403         if (jacobian != NULL)
00404                 delete jacobian;
00405 }
00406 
00407 void PL_PRM_ClosedJacobian::SetCollisionDetector (CD_BasicStyle* collisionDetector)
00408 {
00409         PL_PRM_ClosedBase::SetCollisionDetector(collisionDetector);
00410 
00411         collisionDetector->DeactivateFrames(1, collisionDetector->DOF());
00412         this->collisionDetector = collisionDetector;
00413         m_nDof = collisionDetector->DOF();
00414         m_pRobot = dynamic_cast<R_OpenChain*>(collisionDetector->GetRobot(0));
00415         m_nToolFrame = m_pRobot->GetToolFrame(0);
00416         m_frEndEffector = Matrix4x4::Identity();
00417         if (m_nToolFrame != -1)
00418         {
00419                 FrameManager* frameManager = collisionDetector->GetFrameManager();
00420                 m_frEndEffector = *(frameManager->GetFrameRef(m_nToolFrame));
00421         }
00422         if (jacobian != NULL)
00423         {
00424                 delete jacobian;
00425         }
00426         jacobian = new CJacobian(*m_pRobot);
00427 }
00428 
00429 bool PL_PRM_ClosedJacobian::MakeItClosed(Configuration &conf)
00430 {
00431         while (true)
00432         {
00433                 Frame currentFrame = GetToolFrame(conf);
00434                 Vector4 offset = currentFrame.GetTranslationVector();
00435                 offset[2] = 0;
00436                 
00437                 double dDistance = offset.Magnitude();
00438                 if (dDistance < DEF_ERR_TOLERANCE)
00439                         break;
00440 
00441                 Matrixmxn mJEnd, mJEndInv;
00442                 jacobian->SetConfiguration(conf);
00443                 jacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, false);
00444                 mJEnd = *(jacobian->GetMatrix());
00445                 mJEnd.Inverse(mJEndInv);
00446 
00447                 VectorN endEffOffset(-offset[0], -offset[1], -offset[2]); 
00448                 Configuration jointOffset;
00449                 jointOffset = mJEndInv * endEffOffset *  Rad2Deg(1);
00450                 conf += jointOffset;
00451         }
00452 
00453         return true;
00454 }
00455 
00456 bool PL_PRM_ClosedJacobian::IsInterfering ( const Configuration& q1, const Configuration& q2 )
00457 {
00458         if (PL_PRM::IsInterfering(q1) || PL_PRM::IsInterfering(q2))
00459                 return true;
00460 
00461         Configuration fromConf = q1;
00462         Configuration dirVel = q2 - q1;
00463         double distChanged1 = 360*q1.DOF(); //distance to goal;
00464         Configuration nextConf = fromConf;
00465         double dDistanceToEnd = dirVel.Magnitude();
00466         Configuration lastConf = q1;
00467 
00468         bool bBadConfig = false;
00469         Matrixmxn mJEnd, mJEndInv;
00470         Matrixmxn mTemp(m_nDof, m_nDof); 
00471         Matrixmxn matrixIdentity(m_nDof, m_nDof);
00472 
00473         edgeFrag->append(fromConf);
00474         jacobian->SetConfiguration(fromConf);
00475         while((bBadConfig == false) && (dDistanceToEnd > DEF_RESOLUTION))
00476         {
00477                 jacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, false);
00478                 mJEnd = *(jacobian->GetMatrix());
00479                 mJEnd.Inverse(mJEndInv);
00480                 mTemp = matrixIdentity;
00481                 mTemp -= mJEndInv * mJEnd;
00482                 dirVel = mTemp * dirVel;
00483                 dirVel *= (DEF_RESOLUTION / dirVel.Magnitude());
00484                 nextConf = nextConf + dirVel;
00485                 MakeItClosed(nextConf);
00486                 //LogConfiguration("JacobianError.log", nextConf);
00487                 if (PL_PRM::IsInterfering(nextConf, lastConf))
00488                 {
00489                         bBadConfig = true;
00490                 }
00491                 else
00492                 {
00493                         //distChanged2 = dirVel.Magnitude();
00494                         dirVel = q2 - nextConf;
00495                         dDistanceToEnd = dirVel.Magnitude();
00496                 }
00497 
00498                 if (bBadConfig)
00499                 {
00500                         edgeFrag->clear();
00501                         break;
00502                 }
00503                 else
00504                 {
00505                         edgeFrag->append(nextConf);
00506                         jacobian->SetConfiguration(nextConf);
00507                 }
00508                 lastConf = nextConf;
00509         }
00510 
00511         if (!bBadConfig)
00512         {
00513                 edgeFrag->append(q2);
00514         }
00515 
00516         return bBadConfig;
00517 }
00518 
00519 //===========================================================================================
00520 PL_PRM_ClosedRGD::PL_PRM_ClosedRGD()
00521 {
00522 }
00523 
00524 PL_PRM_ClosedRGD::~PL_PRM_ClosedRGD()
00525 {
00526 }
00527 
00528 bool PL_PRM_ClosedRGD::MakeItClosed(Configuration &conf)
00529 {
00530         int i,j;
00531         Configuration q;
00532         q = conf;
00533         i = 0; j = 0;
00534         int MAX_I = MAX_ITERATION * MAX_RETRY;
00535         int MAX_J = MAX_RETRY;
00536         double err_q = Error(q);
00537         while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00538         {
00539                 i++;   j++;
00540                 double deviation = DEF_NEIGHBOR;
00541                 if (err_q < 1)
00542                         deviation *= err_q;
00543                 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00544                 if (Error(q_next) < err_q)
00545                 {
00546                         j = 0; 
00547                         q = q_next;
00548                         err_q = Error(q);
00549                 }
00550                 //if ( HasTimeLimitExpired() )
00551                 //{
00552                 //      return false;
00553                 //}
00554         }
00555 
00556         conf = q;
00557         return (err_q <= DEF_ERR_TOLERANCE);
00558 }
00559 
00560 bool PL_PRM_ClosedRGD::IsInterfering ( const Configuration& q1, const Configuration& q2 )
00561 {
00562         if (PL_PRM::IsInterfering(q1) || PL_PRM::IsInterfering(q2))
00563                 return true;
00564 
00565         int i, j, k;
00566         i = 0;  j = 0;  k = 0;
00567         Configuration q_last = q1;
00568         //Configuration q_end = q2;
00569         edgeFrag->append(q1);
00570         int MAX_I = MAX_ITERATION * MAX_RETRY * MAX_RETRY2;
00571         int MAX_J = MAX_RETRY;
00572         int MAX_K = MAX_RETRY2;
00573         double distToLast = sqrt(Distance(q_last, q2));
00574         bool bBadConfig = false;
00575         while ((i<MAX_I) && (j<MAX_J) && (k<MAX_K) && (distToLast>DEF_RESOLUTION))
00576         {
00577                 i++;  j++;
00578                 //Configuration q_mid = PL_PRM::GenerateRandomConfig(q_last, DEF_NEIGHBOR*0.2);
00579                 Configuration q_mid = q_last*(1-(DEF_RESOLUTION/distToLast)) + q2*(DEF_RESOLUTION/distToLast);
00580                 if (MakeItClosed(q_mid))  //if (Error(q_mid)<DEF_ERR_TOLERANCE)
00581                 {
00582                         j = 0; k++;
00583                         if (PL_PRM::IsInterfering(q_mid, q_last))
00584                         {
00585                                 bBadConfig = true;
00586                                 break;
00587                         }
00588                         if (Distance(q_mid, q2) < distToLast*distToLast) //return value of Distance is squared!!
00589                         {
00590                                 k = 0;
00591                                 edgeFrag->append(q_mid);
00592                                 q_last = q_mid;
00593                                 distToLast = sqrt(Distance(q_last, q2));
00594                         }
00595                 }
00596                 //if ( HasTimeLimitExpired() )
00597                 //{
00598                 //      result = true;
00599                 //      break;
00600                 //}
00601         }
00602 
00603         //LogMessage("closedchain.log", "Configurations added into fragment");
00604         //for (int testj=0; testj<edgeFrag->size(); testj++)
00605         //{
00606         //      list_item itt = edgeFrag->get_item(testj);
00607         //      Configuration conf = edgeFrag->contents(itt);
00608         //      LogVector("closedchain.log", conf, "Conf: ");
00609         //}
00610 
00611         if (distToLast > DEF_RESOLUTION)
00612                 bBadConfig = true;
00613         if (!bBadConfig)
00614         {
00615                 if (PL_PRM::IsInterfering(q_last, q2)==false)
00616                         edgeFrag->append(q2);
00617                 else
00618                         bBadConfig = true;
00619         }
00620         if (bBadConfig)
00621         {
00622                 edgeFrag->clear();
00623         }
00624         return bBadConfig;
00625 }
00626 
00627 //===========================================================================================
00628 PL_PRM_ClosedAPDecomp::PL_PRM_ClosedAPDecomp()
00629 {
00630 }
00631 
00632 PL_PRM_ClosedAPDecomp::~PL_PRM_ClosedAPDecomp()
00633 {
00634 }
00635 
00636 void PL_PRM_ClosedAPDecomp::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00637 {
00638         PL_PRM_ClosedBase::SetCollisionDetector(collisionDetector);
00639         
00640         //null is a valid collision detector to set this to
00641         if( this->collisionDetector != NULL )
00642         {
00643                 FrameManager *frameManager=this->collisionDetector->GetFrameManager();
00644                 redundant.SetFrameManager(frameManager);
00645                 redundant.SetCollisionDetector(this->collisionDetector);
00646 
00647                 int nDOF = collisionDetector->DOF();
00648 
00649                 redundant.SetActiveBaseFrame(0);
00650                 redundant.SetActiveFirstJoint(0);
00651                 redundant.SetActiveLastJoint(nDOF-3);
00652 
00653                 redundant.SetPassiveBaseFrame(0);
00654                 redundant.SetPassiveFirstJoint(nDOF-2);
00655                 redundant.SetPassiveLastJoint(nDOF-1);
00656         }
00657 }
00658 
00659 bool PL_PRM_ClosedAPDecomp::MakeItClosed(Configuration &conf)
00660 {
00661         Configuration activeConf=conf;
00662         Configuration biasConf=conf;
00663         Frame frEndEffector = GetToolFrame(conf);
00664         frEndEffector(0,3)= 0;
00665         frEndEffector(1,3)= 0;
00666         redundant.GetConfigurationByActive(conf, activeConf, biasConf, frEndEffector);
00667         //redundant.GetConfigurationByActive(conf, activeConf, frEndEffector);
00668         return IsClosed(conf);
00669 }
00670 
00671 bool PL_PRM_ClosedAPDecomp::IsInterfering ( const Configuration& c1, const Configuration& c2 )
00672 {
00673         if (PL_PRM::IsInterfering(c1) || PL_PRM::IsInterfering(c2))
00674                 return true;
00675 
00676         Configuration q_last = c1;
00677         double dDistance = sqrt(Distance(c1, c2));
00678         int nStepNum = (dDistance/DEF_RESOLUTION)+1;
00679         if (nStepNum == 0)
00680                 return true;
00681 
00682         edgeFrag->append(c1);
00683         bool bBadConfig = false;
00684         for (int i=1; i<=nStepNum; i++)
00685         {
00686                 Configuration q_mid = c1*(1-((double)i/(double)nStepNum)) + c2*((double)i/(double)nStepNum);
00687                 //LogConfiguration("APDError.log", q_mid);
00688                 if (MakeItClosed(q_mid))
00689                 {
00690                         if (PL_PRM::IsInterfering(q_mid, q_last))
00691                         {
00692                                 bBadConfig = true;
00693                                 break;
00694                         }
00695                         edgeFrag->append(q_mid);
00696                         q_last = q_mid;
00697                 }
00698                 else
00699                 {
00700                         bBadConfig = true;
00701                         break;
00702                 }
00703         }
00704 
00705         //if (!result) 
00706         //{
00707         //      edgeFrag->append(c2);
00708         //      return false;
00709         //}
00710         if (bBadConfig) //colliding!!!
00711         {
00712                 edgeFrag->clear();
00713         }
00714         return bBadConfig;
00715 }
00716 
00717 //===========================================================================================
00718 double LocalPlannerClosed::Distance(Configuration &conf1, Configuration &conf2)
00719 {
00720         // Get the differences between each of the joints
00721         VectorN jointDiff;
00722         jointDiff = collisionDetector->JointDisplacement( conf1, conf2 );
00723 
00724         // Square and sum each of the joint differences
00725         double distance = 0;
00726         for( int i = 0; i < jointDiff.Length(); i++ )
00727         {
00728                 distance += Sqr(jointDiff[i] );
00729         }
00730 
00731         // Return the squared euclidean distance
00732         return sqrt(distance);
00733 }
00734 
00735 bool LocalPlannerClosed::Plan()
00736 {
00737     // check to see that SWIFTpp is the collision detector used
00738     const CD_Swiftpp* pSwiftpp = dynamic_cast< const CD_Swiftpp* >( collisionDetector );
00739     if (pSwiftpp == NULL)
00740     {
00741         return false;
00742     }
00743 
00744     // quick checks
00745         if ( collisionDetector->IsInterfering( GetStartConfig() ) )
00746         {
00747                 // there is a collision with the start configuration...report failure
00748         //MessageBox(NULL, "Collision detected while planning.","IK_Jacobian Planner Error", MB_OK);
00749                 return false;
00750         }
00751 
00752         // Start the timer
00753         StartTimer();
00754 
00755         // Establish the semaphore
00756         //Semaphore semaphore( guid );
00757         //semaphore.Lock();
00758 
00759     Configuration   currentConfig, goalConfig, nextConfig, jointVelocity;
00760     currentConfig.SetNumDOF(m_nDof);
00761     nextConfig.SetNumDOF(m_nDof);
00762     jointVelocity.SetNumDOF(m_nDof);
00763     for (int i = 0; i < m_nDof; i++)
00764     {
00765         jointVelocity[i] = 0;
00766     }
00767     currentConfig = GetStartConfig();
00768         goalConfig = GetGoalConfig();
00769     
00770     path.Clear();
00771     path.AppendPoint(currentConfig);
00772 
00773         //Initialize Jacobian, obstacle point and end-effector will share a Jacobian matrix.
00774         CJacobian jacobian(*m_pRobot);
00775         jacobian.SetConfiguration(currentConfig);
00776         //Frame frEndEffector = jacobian.GetJointFrame(m_nDof+1);
00777 
00778         bool abort = false;
00779 
00780         VectorN vEndEffVel(0, 0, 0);
00781     //for (int iViaPts = 0; iViaPts < (poses.size()-1); iViaPts++);
00782         double dist = Distance(currentConfig, goalConfig);
00783         while (dist > DEF_RESOLUTION )
00784     {
00785                 jacobian.SetInterestPoint(m_nDof-1, m_frEndEffector, m_bPosition, m_bOrientation);
00786                 //jacobian.GetJointVelocity(jointVelocity, vEndEffVel);
00787 
00788                 Matrixmxn mJEnd, mJEndInv;
00789                 mJEnd = *(jacobian.GetMatrix());
00790                 mJEnd.Inverse(mJEndInv);
00791 
00792                 Matrixmxn mTemp(m_nDof, m_nDof); 
00793                 mTemp -= mJEndInv * mJEnd;
00794 
00795                 //jointVelocity = currentConfig*(1-(DEF_RESOLUTION/dist)) + goalConfig*(DEF_RESOLUTION/dist);
00796                 jointVelocity = (goalConfig-currentConfig);
00797                 if (dist > DEF_RESOLUTION)
00798                         jointVelocity *= (DEF_RESOLUTION/dist);
00799                 for (int i=0; i<m_nDof; i++)
00800                 {
00801                         double dValue = jointVelocity[i];
00802                         jointVelocity[i] = Deg2Rad(dValue);
00803                 }
00804                 jointVelocity = mTemp * jointVelocity;
00805 
00806                 //============= Begin of obstacles =====================
00807         // Getting the homogeneous solutions for the obstacles (Jo's)
00808         // check for the closest points between robot/obstacles
00809         if (GetClosestValues(currentConfig) != false)
00810                 {
00811                         //LogMessage("Aborting.... Colliding when getting collision points!");
00812                         abort = true;
00813             break;
00814                 }
00815 
00816         double obsDirMag = 0;
00817         // if closest distance is critical, abort
00818         if (m_vClosestPoints[0].distance <= m_dObsTol)
00819         {                
00820             //MessageBox(NULL, "Collision detected while planning", "IK_Jacobian Planner Error", MB_OK);
00821                         //LogMessage("Aborting.... Colliding, too close to obstacles!");
00822             abort = true;
00823             break;
00824         }            
00825         //** no obstacle scenario handled by infinite distance
00826         else
00827         {
00828                         VectorN vHomogeneousSolns;
00829                         vHomogeneousSolns = ComputeHomogeneousTerm(jacobian, mJEnd, mJEndInv, vEndEffVel);
00830 
00831                         //LogVector(vHomogeneousSolns, "Homogeneous Term:");
00832                         
00833                         jointVelocity += vHomogeneousSolns;
00834         } // obstacles exist
00835 
00836                 //============= End of obstacles =====================
00837 
00838                 //Convert to degree representation;
00839         CheckJointVelocities(jointVelocity);
00840                 for (i=0; i<m_nDof; i++)
00841                 {
00842                         double dValue = jointVelocity[i];
00843                         jointVelocity[i] = Rad2Deg(dValue);
00844                 }
00845 
00846                 //LogVector(jointVelocity, "Joint Velocity");
00847         
00848                 // calculate where the new velocity takes us after time interval
00849                 nextConfig = currentConfig + jointVelocity;
00850         CheckJointLimits(nextConfig);
00851 
00852         // got next configuration, now need to see if it's valid               
00853         //if (collisionDetector->IsInterferingLinear(currentConfig, nextConfig ) == false)
00854                 if (collisionDetector->IsInterfering(nextConfig ) == false)
00855         {        
00856             // there's no point adding it if it's the same
00857             if (currentConfig != nextConfig)        
00858             {
00859                 currentConfig = nextConfig;
00860                 path.AppendPoint(currentConfig);
00861                                 dist = Distance(currentConfig, goalConfig);
00862                // GetEndEffVector(currentConfig, vCurPt);
00863             }
00864             jacobian.SetConfiguration(currentConfig);
00865         }
00866         else        // interfering
00867         {
00868             //MessageBox(NULL, "Obstacle in path could not be avoided","IK_Jacobian Planner Error", MB_OK);
00869                         //LogMessage("Aborting.... Colliding when checking next configuration!");
00870             abort = true;
00871                         break;
00872         }            
00873             //semaphore.Unlock();
00874             //semaphore.Lock();
00875 
00876         if (HasTimeLimitExpired() != false)
00877         {            
00878             //MessageBox(NULL, "Time's up!", "Plan() fail - Time's Up!", MB_OK);
00879                         //LogMessage("Aborting.... Time up!");
00880             abort = true;
00881                         break;
00882         }
00883     }
00884 
00885     //semaphore.Unlock();
00886         if (abort)
00887         {
00888                 //LogMessage("### Planning Failure");
00889         }
00890         else
00891         {
00892         if (collisionDetector->IsInterferingLinear(currentConfig, goalConfig ) == false)
00893                 {
00894             path.AppendPoint(goalConfig);
00895                 }
00896                 //LogMessage("### Planning Success");
00897         }
00898     return (abort == false);
00899 }
00900 
00901 //===========================================================================================
00902 
00903 PL_PRM_ClosedChain::PL_PRM_ClosedChain()
00904 {
00905         m_nAlgorithm = ALG_CLOSEDCHAIN_RGD;
00906 }
00907 
00908 PL_PRM_ClosedChain::~PL_PRM_ClosedChain()
00909 {
00910 }
00911 
00912 bool PL_PRM_ClosedChain::Plan ()
00913 {
00914         if (m_nAlgorithm == ALG_CLOSEDCHAIN_LOCAL)
00915                 return PL_PRM_ClosedLocalJacobian::Plan();
00916         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_JACOBIAN)
00917                 return PL_PRM_ClosedJacobian::Plan();
00918         else
00919                 return PL_PRM_ClosedBase::Plan();
00920 }
00921 
00922 bool PL_PRM_ClosedChain::MakeItClosed(Configuration &conf)
00923 {
00924         if (m_nAlgorithm == ALG_CLOSEDCHAIN_RGD)
00925                 return PL_PRM_ClosedRGD::MakeItClosed(conf);
00926         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_APD)
00927                 return PL_PRM_ClosedAPDecomp::MakeItClosed(conf);
00928         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_JACOBIAN)
00929                 return PL_PRM_ClosedJacobian::MakeItClosed(conf);
00930         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_LOCAL)
00931                 return PL_PRM_ClosedLocalJacobian::MakeItClosed(conf);
00932         else
00933                 return true;
00934 }
00935 
00936 bool PL_PRM_ClosedChain::IsInterfering ( const Configuration& c1, const Configuration& c2 )
00937 {
00938         if (m_nAlgorithm == ALG_CLOSEDCHAIN_RGD)
00939                 return PL_PRM_ClosedRGD::IsInterfering(c1, c2);
00940         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_APD)
00941                 return PL_PRM_ClosedAPDecomp::IsInterfering(c1, c2);
00942         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_JACOBIAN)
00943                 return PL_PRM_ClosedJacobian::IsInterfering(c1, c2);
00944         else if (m_nAlgorithm == ALG_CLOSEDCHAIN_LOCAL)
00945                 return PL_PRM_ClosedLocalJacobian::IsInterfering(c1, c2);
00946         else
00947                 return true;
00948 }
00949 
00950 void PL_PRM_ClosedChain::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00951 {
00952         PL_PRM_ClosedBase::SetCollisionDetector( collisionDetector );
00953 
00954         if( this->collisionDetector == NULL )
00955                 return;
00956 
00957         //Create a SWIFTpp collistion detector for Jacobian-based local planner
00958         if (pCollisionDetector != NULL)
00959                 delete pCollisionDetector;
00960         pCollisionDetector = new CD_Swiftpp( *(collisionDetector->GetUniverse()) );
00961         planner->SetCollisionDetector(pCollisionDetector);
00962         pCollisionDetector->DeactivateFrames(1, pCollisionDetector->DOF());
00963 
00964         //Create jocobian for Jacobian computation
00965         collisionDetector->DeactivateFrames(1, collisionDetector->DOF());
00966         this->collisionDetector = collisionDetector;
00967         m_nDof = collisionDetector->DOF();
00968         m_pRobot = dynamic_cast<R_OpenChain*>(collisionDetector->GetRobot(0));
00969         m_nToolFrame = m_pRobot->GetToolFrame(0);
00970         m_frEndEffector = Matrix4x4::Identity();
00971         if (m_nToolFrame != -1)
00972         {
00973                 FrameManager* frameManager = collisionDetector->GetFrameManager();
00974                 m_frEndEffector = *(frameManager->GetFrameRef(m_nToolFrame));
00975         }
00976         if (jacobian != NULL)
00977         {
00978                 delete jacobian;
00979         }
00980         jacobian = new CJacobian(*m_pRobot);
00981 
00982         //Setups for Active Passive Link decomposition method.
00983         FrameManager *frameManager=this->collisionDetector->GetFrameManager();
00984         redundant.SetFrameManager(frameManager);
00985         redundant.SetCollisionDetector(this->collisionDetector);
00986         int nDOF = collisionDetector->DOF();
00987 
00988         redundant.SetActiveBaseFrame(0);
00989         redundant.SetActiveFirstJoint(0);
00990         redundant.SetActiveLastJoint(nDOF-3);
00991 
00992         redundant.SetPassiveBaseFrame(0);
00993         redundant.SetPassiveFirstJoint(nDOF-2);
00994         redundant.SetPassiveLastJoint(nDOF-1);
00995 
00996 }

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