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/ik_mpep/IK_Jacobian.h"
00009 #include "PL_RRT_ClosedChain.h"
00010 #include <gl/gl.h>
00011 #include <opengl/gl_sphere.h>
00012 #include <opengl/gl_group.h>
00013
00014 #define MAX_ITERATION 30
00015 #define MAX_RETRY 30
00016 #define MAX_RETRY2 30
00017 #define DEF_NEIGHBOR (2)
00018 #define DEF_DIST_TOLERANCE (3)
00019 #define DEF_ERR_TOLERANCE (1e-3)
00020 #define DEF_TIME_INTERVAL (1e-1)
00021 #define DEF_INCREMENT (15)
00022 #define MIN_DIST_CHANGE (0.5)
00023
00024 #define LEN_STEP_SIZE 20
00025 #define MAX_CONF_RETRY 10
00026
00027 typedef struct
00028 {
00029 Configuration conf;
00030 PA_Points edge;
00031 } VertexInfoInTree;
00032
00033 #define ERR_FAIL 0xff
00034 #define ERR_SUCCESS 0x00
00035 #define ERR_TIMEOUT 0x10
00036 #define ERR_ILLPARAMETER 0x20
00037
00038
00039 PL_RRT_ClosedChain::PL_RRT_ClosedChain()
00040 {
00041 m_rootVert = NULL;
00042 m_goalVert = NULL;
00043 jacobian = NULL;
00044 m_bUseJacobian = true;
00045
00046 }
00047
00048 PL_RRT_ClosedChain::~PL_RRT_ClosedChain()
00049 {
00050 if (jacobian != NULL)
00051 delete jacobian;
00052 if ( m_rootVert != NULL )
00053 ClearTree();
00054 }
00055
00056 void PL_RRT_ClosedChain::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00057 {
00058 PL_PRM::SetCollisionDetector(collisionDetector);
00059
00060 collisionDetector->DeactivateFrames(1, collisionDetector->DOF());
00061 this->collisionDetector = collisionDetector;
00062 m_nDof = collisionDetector->DOF();
00063 m_pRobot = dynamic_cast<R_OpenChain*>(collisionDetector->GetRobot(0));
00064 m_nToolFrame = m_pRobot->GetToolFrame(0);
00065 m_frEndEffector = Matrix4x4::Identity();
00066 if (m_nToolFrame != -1)
00067 {
00068 FrameManager* frameManager = collisionDetector->GetFrameManager();
00069 m_frEndEffector = *(frameManager->GetFrameRef(m_nToolFrame));
00070 }
00071 if (jacobian != NULL)
00072 {
00073 delete jacobian;
00074 jacobian = new CJacobian(*m_pRobot);
00075 }
00076 }
00077
00078 bool PL_RRT_ClosedChain::DrawExplicit () const
00079 {
00080 double Xcor, Ycor, Zcor;
00081
00082 Semaphore semaphore( guid );
00083 semaphore.Lock();
00084
00085
00086 glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
00087 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00088 BOOL lightingState = glIsEnabled( GL_LIGHTING );
00089 glDisable( GL_LIGHTING );
00090 glShadeModel( GL_SMOOTH );
00091 glPointSize(5.0f);
00092
00093 if (m_vertices.size() )
00094 {
00095 int i;
00096
00097
00098 glBegin(GL_POINTS);
00099 for(i = 0; i<m_vertices.size(); i++)
00100 {
00101 vertex vert;
00102 VertexInfoInTree *info;
00103 vert = m_vertices[i];
00104 info = (VertexInfoInTree *)((dynamic_trees &)m_trajTree).vertex_inf(vert);
00105
00106 Configuration conf = info->conf;
00107 Xcor = conf[0];
00108 Ycor = conf[1];
00109 Zcor = conf[2];
00110
00111 if ((i==0) || (i==(m_vertices.size()-1)))
00112 glColor3f(0.0f,0.0f,1.0f);
00113 else
00114 glColor3f(1.0f,1.0f,0.0f);
00115 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00116 }
00117 glEnd();
00118
00119 glBegin(GL_LINES);
00120 for(i = 1; i<m_vertices.size(); i++)
00121 {
00122 vertex vert, parentVert;
00123 VertexInfoInTree *info, *parentInfo;
00124
00125 vert = m_vertices[i];
00126 parentVert = ((dynamic_trees &)m_trajTree).parent(vert);
00127 info = (VertexInfoInTree *)((dynamic_trees &)m_trajTree).vertex_inf(vert);
00128 parentInfo = (VertexInfoInTree *)((dynamic_trees &)m_trajTree).vertex_inf(parentVert);
00129
00130 Configuration conf = info->conf;
00131 Configuration parentConf = parentInfo->conf;
00132
00133 Xcor = conf[0];
00134 Ycor = conf[1];
00135 Zcor = conf[2];
00136 glColor3f(1.0f,0.5f,0.0f);
00137 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00138
00139 Xcor = parentConf[0];
00140 Ycor = parentConf[1];
00141 Zcor = parentConf[2];
00142 glColor3f(1.0f,0.0f,0.0f);
00143 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00144 }
00145 glEnd();
00146 }
00147
00148
00149 if( lightingState != FALSE )
00150 {
00151 glEnable( GL_LIGHTING );
00152 }
00153
00154 semaphore.Unlock();
00155
00156 Sleep( 50 );
00157
00158 return true;
00159 }
00160
00161 bool PL_RRT_ClosedChain::Plan ()
00162 {
00163 srand( (unsigned)time( NULL ) );
00164
00165 path.Clear();
00166
00167
00168 StartTimer();
00169
00170
00171
00172
00173
00174
00175 Configuration startConf = GetStartConfig();
00176 CreateTree(startConf);
00177
00178 int result = ERR_FAIL;
00179 bool pathFound = false;
00180 m_goalVert = NULL;
00181
00182 if (m_bUseJacobian)
00183 {
00184 if (jacobian == NULL)
00185 jacobian = new CJacobian(*m_pRobot);
00186 }
00187
00188 int repeatNum = 0;
00189 while ((!pathFound) && (result != ERR_TIMEOUT))
00190 {
00191 PA_Points localPath;
00192 Configuration randConf = PL_PRM_ClosedChain::GenerateRandomConfig();
00193 vertex fromVert = FindClosestInTree(randConf);
00194 Configuration fromConf = GetConfigurationFromTree(fromVert);
00195 Configuration toConf;
00196
00197 if (m_bUseJacobian)
00198 result = ExtendJacobian(fromConf, toConf, randConf, localPath);
00199 else
00200 result = Extend(fromConf, toConf, randConf, localPath);
00201
00202 if (result == ERR_SUCCESS)
00203 {
00204 fromVert = AddNodeInTree(fromVert, toConf, localPath);
00205 if (m_bUseJacobian)
00206 {
00207 if (ConnectToGoalJacobian(fromVert) == ERR_SUCCESS)
00208
00209 {
00210 pathFound = true;
00211 }
00212 }
00213 else
00214 {
00215 if (ConnectToGoal() == ERR_SUCCESS)
00216 {
00217 pathFound = true;
00218 }
00219 }
00220 }
00221
00222
00223
00224
00225 if ( HasTimeLimitExpired() )
00226 {
00227 break;
00228 }
00229
00230 }
00231
00232
00233 if (pathFound)
00234 {
00235 assert(m_goalVert != NULL);
00236 RetrievePath(m_goalVert);
00237 return true;
00238 }
00239
00240 return false;
00241 }
00242
00243 int PL_RRT_ClosedChain::Extend(Configuration &fromConf, Configuration &toConf, Configuration dirConf, PA_Points &localPath)
00244 {
00245 std::vector<Frame> edgeTraj;
00246 localPath.Clear();
00247
00248 double pathLen = 0;
00249 bool trajExtracted = true;
00250
00251
00252 double dist = Distance(fromConf, dirConf);
00253 if (dist > LEN_STEP_SIZE)
00254 toConf = fromConf * (1-LEN_STEP_SIZE/dist) + dirConf * (LEN_STEP_SIZE/dist);
00255 else
00256 toConf = dirConf;
00257
00258 bool result = false;
00259 int retry = 0;
00260 while ( (!result) && (retry < MAX_CONF_RETRY) )
00261 {
00262 result = GetClosedConfiguration( toConf );
00263 retry ++;
00264 }
00265
00266 if (!result)
00267 {
00268 return ERR_FAIL;
00269 }
00270 if ( IsInterfering(fromConf, toConf) == false)
00271 {
00272 for (int i=0; i<edgeFrag->size(); i++)
00273 {
00274 list_item itt = edgeFrag->get_item(i);
00275 Configuration conf = edgeFrag->contents(itt);
00276 localPath.AppendPoint(conf);
00277 }
00278 edgeFrag->clear();
00279
00280 return ERR_SUCCESS;
00281 }
00282
00283 return ERR_FAIL;
00284 }
00285
00286 int PL_RRT_ClosedChain::ExtendJacobian(Configuration &fromConf, Configuration &toConf, Configuration dirConf, PA_Points &localPath)
00287 {
00288 std::vector<Frame> edgeTraj;
00289 localPath.Clear();
00290
00291 double pathLen = 0;
00292 bool trajExtracted = true;
00293
00294 Configuration dirVel = dirConf;
00295 dirVel -= fromConf;
00296 toConf = fromConf;
00297
00298
00299 jacobian->SetConfiguration(fromConf);
00300
00301 Matrixmxn mJEnd, mJEndInv;
00302 Matrixmxn mTemp(m_nDof, m_nDof);
00303 Matrixmxn matrixIdentity(m_nDof, m_nDof);
00304 double distTravel=0;
00305 localPath.AppendPoint(fromConf);
00306 bool bCollisionFree = true;
00307 #ifdef _MULTIPLE_STEP
00308 while(distTravel<LEN_STEP_SIZE)
00309 {
00310 jacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, useOrientConstraint);
00311 mJEnd = *(jacobian->GetMatrix());
00312 mJEnd.Inverse(mJEndInv);
00313 mTemp = matrixIdentity;
00314 mTemp -= mJEndInv * mJEnd;
00315 dirVel = mTemp * dirVel;
00316 dirVel *= (DEF_INCREMENT / dirVel.Magnitude());
00317 toConf = toConf + dirVel;
00318 AdjustConfiguration(toConf);
00319 if (collisionDetector->IsInterfering(toConf))
00320 {
00321 bCollisionFree = false;
00322 localPath.Clear();
00323 break;
00324 }
00325 else
00326 {
00327 localPath.AppendPoint(toConf);
00328 jacobian->SetConfiguration(toConf);
00329 distTravel += dirVel.Magnitude();
00330 dirVel = dirConf - toConf;
00331 }
00332 }
00333 #else
00334 mJEnd = *(jacobian->GetMatrix());
00335 mJEnd.Inverse(mJEndInv);
00336 mTemp = matrixIdentity;
00337 mTemp -= mJEndInv * mJEnd;
00338 dirVel = mTemp * dirVel;
00339 dirVel *= (DEF_INCREMENT / dirVel.Magnitude());
00340 toConf = toConf + dirVel;
00341 AdjustConfiguration(toConf);
00342
00343 if (collisionDetector->IsInterfering(toConf, fromConf))
00344 {
00345 bCollisionFree = false;
00346 localPath.Clear();
00347 }
00348 else
00349 {
00350 localPath.AppendPoint(toConf);
00351 }
00352 #endif
00353
00354 if (bCollisionFree)
00355 {
00356 Log("closedchain.log", "The number of intermediate node in an extension: %d", localPath.Size());
00357 return ERR_SUCCESS;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 return ERR_FAIL;
00371 }
00372
00373 bool PL_RRT_ClosedChain::AdjustConfiguration(Configuration &config)
00374 {
00375 if (IsClosed(config))
00376 return true;
00377 else
00378 {
00379 Frame toolFrame = GetToolFrame( config );
00380 Vector4 offset = toolFrame.GetTranslationVector();
00381 offset[2] = 0;
00382 VectorN endEffOffset(-offset[0], -offset[1], -offset[2]);
00383
00384
00385
00386 jacobian->SetConfiguration(config);
00387 jacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, useOrientConstraint);
00388
00389 Matrixmxn mJEnd, mJEndInv;
00390 mJEnd = *(jacobian->GetMatrix());
00391 mJEnd.Inverse(mJEndInv);
00392
00393 Configuration jointOffset;
00394 jointOffset = mJEndInv * endEffOffset * Rad2Deg(1);
00395 config += jointOffset;
00396
00397 }
00398 return true;
00399 }
00400
00401 int PL_RRT_ClosedChain::ConnectToGoal2()
00402 {
00403 Configuration goalConf = GetGoalConfig();
00404 Frame goalPose = GetToolFrame(goalConf);
00405 bool result = true;
00406 if (useGoalPose)
00407 {
00408 result = false;
00409 int retry = 0;
00410 while ( (!result) && (retry++<MAX_CONF_RETRY))
00411 {
00412 result = GenerateRandomConfigForPose(goalConf, goalPose);
00413 }
00414 }
00415
00416 vertex fromVert = NULL;
00417 if (result)
00418 {
00419 fromVert = FindClosestInTree(goalConf);
00420 }
00421 if (fromVert == NULL)
00422 {
00423 result = false;
00424 }
00425
00426 if (result)
00427 {
00428 Configuration fromConf = GetConfigurationFromTree(fromVert);
00429 if (!IsInterfering(fromConf, goalConf))
00430 {
00431 PA_Points localPath;
00432 for (int i=0; i<edgeFrag->size(); i++)
00433 {
00434 list_item itt = edgeFrag->get_item(i);
00435 Configuration conf = edgeFrag->contents(itt);
00436 localPath.AppendPoint( conf );
00437 }
00438 edgeFrag->clear();
00439 m_goalVert = AddNodeInTree(fromVert, goalConf, localPath);
00440 localPath.Clear();
00441 return ERR_SUCCESS;
00442 }
00443 }
00444 return ERR_FAIL;
00445 }
00446
00447
00448 int PL_RRT_ClosedChain::ConnectToGoal()
00449 {
00450 Configuration goalConf = GetGoalConfig();
00451 Frame goalPose = GetToolFrame(goalConf);
00452 bool result = true;
00453 if (useGoalPose)
00454 {
00455 result = false;
00456 int retry = 0;
00457 while ( (!result) && (retry++<MAX_CONF_RETRY))
00458 {
00459 result = GenerateRandomConfigForPose(goalConf, goalPose);
00460 }
00461 }
00462
00463 vertex fromVert = NULL;
00464 if (result)
00465 {
00466 fromVert = FindClosestInTree(goalConf);
00467 }
00468 if (fromVert == NULL)
00469 {
00470 result = false;
00471 }
00472
00473 if (result)
00474 {
00475 Configuration fromConf = GetConfigurationFromTree(fromVert);
00476 if (!IsInterfering(fromConf, goalConf))
00477 {
00478 PA_Points localPath;
00479 for (int i=0; i<edgeFrag->size(); i++)
00480 {
00481 list_item itt = edgeFrag->get_item(i);
00482 Configuration conf = edgeFrag->contents(itt);
00483 localPath.AppendPoint( conf );
00484 }
00485 edgeFrag->clear();
00486 m_goalVert = AddNodeInTree(fromVert, goalConf, localPath);
00487 localPath.Clear();
00488 return ERR_SUCCESS;
00489 }
00490 }
00491 return ERR_FAIL;
00492 }
00493
00494
00495 int PL_RRT_ClosedChain::ConnectToGoal(vertex fromVert)
00496 {
00497 Configuration goalConf = GetGoalConfig();
00498 if (fromVert==NULL)
00499 {
00500 return ERR_FAIL;
00501 }
00502
00503 bool result = true;
00504
00505 Configuration fromConf = GetConfigurationFromTree(fromVert);
00506 if (!IsInterfering(fromConf, goalConf))
00507 {
00508 PA_Points localPath;
00509 for (int i=0; i<edgeFrag->size(); i++)
00510 {
00511 list_item itt = edgeFrag->get_item(i);
00512 Configuration conf = edgeFrag->contents(itt);
00513 localPath.AppendPoint( conf );
00514 }
00515 edgeFrag->clear();
00516 m_goalVert = AddNodeInTree(fromVert, goalConf, localPath);
00517 localPath.Clear();
00518 return ERR_SUCCESS;
00519 }
00520 return ERR_FAIL;
00521 }
00522
00523 int PL_RRT_ClosedChain::ConnectToGoalJacobian(vertex fromVert)
00524 {
00525 Configuration goalConf = GetGoalConfig();
00526 if (fromVert==NULL)
00527 {
00528 return ERR_FAIL;
00529 }
00530
00531 Configuration fromConf = GetConfigurationFromTree(fromVert);
00532 double distChanged1 = 360*goalConf.DOF();
00533
00534 Configuration dirVel = goalConf - fromConf;
00535 Configuration nextConf = fromConf;
00536 double newDistance = 0;
00537 double oldDistance = dirVel.Magnitude();
00538 PA_Points localPath;
00539 localPath.AppendPoint(fromConf);
00540
00541 jacobian->SetConfiguration(fromConf);
00542
00543 Matrixmxn mJEnd, mJEndInv;
00544 Matrixmxn mTemp(m_nDof, m_nDof);
00545 Matrixmxn matrixIdentity(m_nDof, m_nDof);
00546
00547 bool bValid=true;
00548 while((bValid == true) && (oldDistance > DEF_DIST_TOLERANCE))
00549 {
00550 jacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, useOrientConstraint);
00551 mJEnd = *(jacobian->GetMatrix());
00552 mJEnd.Inverse(mJEndInv);
00553 mTemp = matrixIdentity;
00554 mTemp -= mJEndInv * mJEnd;
00555 dirVel = mTemp * dirVel;
00556 if (oldDistance < DEF_INCREMENT)
00557 dirVel *= (oldDistance / dirVel.Magnitude());
00558 else
00559 dirVel *= (DEF_INCREMENT / dirVel.Magnitude());
00560 nextConf = nextConf + dirVel;
00561 AdjustConfiguration(nextConf);
00562 if (collisionDetector->IsInterfering(nextConf))
00563 {
00564 bValid = false;
00565 }
00566 else
00567 {
00568
00569 dirVel = goalConf - nextConf;
00570 newDistance = dirVel.Magnitude();
00571 distChanged1 = oldDistance - newDistance;
00572 oldDistance = newDistance;
00573 if ((newDistance > DEF_DIST_TOLERANCE) && (distChanged1<MIN_DIST_CHANGE))
00574 {
00575 bValid = false;
00576 Log("closedchain.log", "Jacobian local failed with newDistance=%f, and distChanged1=%d", newDistance, distChanged1);
00577 }
00578 }
00579
00580 if (bValid==false)
00581 {
00582 localPath.Clear();
00583 break;
00584 }
00585 else
00586 {
00587 localPath.AppendPoint(nextConf);
00588 jacobian->SetConfiguration(nextConf);
00589 }
00590 }
00591
00592 if (bValid)
00593 {
00594 m_goalVert = AddNodeInTree(fromVert, goalConf, localPath);
00595 Log("closedchain.log", "The number of intermediate node to goal: %d", localPath.Size());
00596 localPath.Clear();
00597 return ERR_SUCCESS;
00598 }
00599
00600 return ERR_FAIL;
00601 }
00602
00603
00604 bool PL_RRT_ClosedChain::CreateTree(Configuration &conf)
00605 {
00606 if (m_rootVert != NULL)
00607 {
00608 ClearTree();
00609 }
00610
00611 VertexInfoInTree *newNode = new VertexInfoInTree;
00612 newNode->conf = conf;
00613
00614 Semaphore semaphore( guid );
00615 semaphore.Lock();
00616 m_rootVert = m_trajTree.make(newNode);
00617 m_vertices.push_back(m_rootVert);
00618 semaphore.Unlock();
00619
00620 return true;
00621 }
00622
00623 void PL_RRT_ClosedChain::ClearTree()
00624 {
00625 Semaphore semaphore( guid );
00626 semaphore.Lock();
00627 for (int i=0; i<m_vertices.size(); i++)
00628 {
00629 VertexInfoInTree *info;
00630 info = (VertexInfoInTree *)m_trajTree.vertex_inf(m_vertices[i]);
00631 delete info;
00632 }
00633
00634 m_trajTree.clear();
00635 m_vertices.clear();
00636 m_rootVert = NULL;
00637 semaphore.Unlock();
00638 }
00639
00640 vertex PL_RRT_ClosedChain::AddNodeInTree(vertex parentVertex, Configuration &childConf, PA_Points &localPath)
00641 {
00642 VertexInfoInTree *newNode = new VertexInfoInTree;
00643 newNode->conf = childConf;
00644 CopyPath(newNode->edge, localPath);
00645
00646 Semaphore semaphore( guid );
00647 semaphore.Lock();
00648 vertex newVert = m_trajTree.make(newNode);
00649 m_vertices.push_back(newVert);
00650 m_trajTree.link(newVert, parentVertex, 1);
00651 semaphore.Unlock();
00652
00653 return newVert;
00654 }
00655
00656 vertex PL_RRT_ClosedChain::FindClosestInTree(Configuration &conf)
00657 {
00658 if (m_vertices.size() == 0)
00659 return NULL;
00660
00661 VertexInfoInTree *info;
00662 double minDist, currDist;
00663 int minIndex=0;
00664
00665 info = (VertexInfoInTree *)m_trajTree.vertex_inf(m_vertices[0]);
00666 minDist = Distance(info->conf, conf);
00667 minIndex = 0;
00668
00669 for (int i=1; i<m_vertices.size(); i++)
00670 {
00671 info = (VertexInfoInTree *)m_trajTree.vertex_inf(m_vertices[i]);
00672 currDist = Distance(info->conf, conf);
00673 if (currDist < minDist)
00674 {
00675 minDist = currDist;
00676 minIndex = i;
00677 }
00678 }
00679
00680 return m_vertices[minIndex];
00681 }
00682
00683 Configuration& PL_RRT_ClosedChain::GetConfigurationFromTree(vertex vert)
00684 {
00685 VertexInfoInTree *info;
00686 info = (VertexInfoInTree *)m_trajTree.vertex_inf(vert);
00687 return info->conf;
00688 }
00689
00690 double PL_RRT_ClosedChain::Distance(const Configuration &conf1, const Configuration &conf2)
00691 {
00692 double dist = 0;
00693 VectorN jointDiff = collisionDetector->JointDisplacement(conf1, conf2);
00694 for(int i = 0; i < jointDiff.Length(); i++)
00695 {
00696 dist += (jointDiff[i])*(jointDiff[i]);
00697 }
00698 return sqrt(dist);
00699 }
00700
00701 PA_Points& PL_RRT_ClosedChain::GetPathFromTree(vertex vert)
00702 {
00703 VertexInfoInTree *info;
00704 info = (VertexInfoInTree *)m_trajTree.vertex_inf(vert);
00705 return info->edge;
00706 }
00707
00708 void PL_RRT_ClosedChain::RetrievePath(vertex &goalVert)
00709 {
00710 vertex currVert = goalVert;
00711 while (currVert != NULL)
00712 {
00713 InsertPath(path, GetPathFromTree(currVert));
00714 currVert = m_trajTree.parent(currVert);
00715 }
00716 }
00717
00718 void PL_RRT_ClosedChain::AppendPath(PA_Points &collect, PA_Points &local)
00719 {
00720 for (int i=0; i<local.Size(); i++)
00721 {
00722 collect.AppendPoint(local[i]);
00723 }
00724 }
00725
00726 void PL_RRT_ClosedChain::AppendPath(PA_Points &collect, PA_Points *local)
00727 {
00728 for (int i=0; i<local->Size(); i++)
00729 {
00730 collect.AppendPoint(local->GetPoint(i));
00731 }
00732 }
00733
00734 void PL_RRT_ClosedChain::InsertPath(PA_Points &target, PA_Points &source)
00735 {
00736 int nLen = source.Size()-1;
00737 if ( target.Size() != 0 )
00738 {
00739 nLen = nLen - 1;
00740 }
00741 for( int i = nLen; i >= 0; i-- )
00742 {
00743 target.AppendPointToBeginning( source[ i ] ) ;
00744 }
00745 }
00746
00747
00748
00749
00750
00751
00752 bool PL_RRT_ClosedChain::TestJacobianConnection(Configuration &testStartConf, Configuration &testGoalConf, PA_Points &localPath)
00753 {
00754 double distChanged1 = 360*testGoalConf.DOF();
00755
00756 Configuration dirVel = testGoalConf - testStartConf;
00757 Configuration nextConf = testStartConf;
00758 double newDistance = 0;
00759 double oldDistance = dirVel.Magnitude();
00760 localPath.AppendPoint(testStartConf);
00761
00762 jacobian->SetConfiguration(testStartConf);
00763
00764 Matrixmxn mJEnd, mJEndInv;
00765 Matrixmxn mTemp(m_nDof, m_nDof);
00766 Matrixmxn matrixIdentity(m_nDof, m_nDof);
00767
00768 bool bValid=true;
00769 while((bValid == true) && (oldDistance > DEF_DIST_TOLERANCE))
00770 {
00771 jacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, useOrientConstraint);
00772 mJEnd = *(jacobian->GetMatrix());
00773 mJEnd.Inverse(mJEndInv);
00774 mTemp = matrixIdentity;
00775 mTemp -= mJEndInv * mJEnd;
00776 dirVel = mTemp * dirVel;
00777 if (oldDistance < DEF_INCREMENT)
00778 dirVel *= (oldDistance / dirVel.Magnitude());
00779 else
00780 dirVel *= (DEF_INCREMENT / dirVel.Magnitude());
00781 nextConf = nextConf + dirVel;
00782 AdjustConfiguration(nextConf);
00783 if (collisionDetector->IsInterfering(nextConf))
00784 {
00785 bValid = false;
00786 }
00787 else
00788 {
00789
00790 dirVel = testGoalConf - nextConf;
00791 newDistance = dirVel.Magnitude();
00792 distChanged1 = oldDistance - newDistance;
00793 oldDistance = newDistance;
00794
00795
00796
00797
00798 }
00799
00800 if (bValid==false)
00801 {
00802 localPath.Clear();
00803 break;
00804 }
00805 else
00806 {
00807 localPath.AppendPoint(nextConf);
00808 jacobian->SetConfiguration(nextConf);
00809 }
00810 }
00811
00812 return (bValid);
00813 }
00814
00815
00816 bool PL_RRT_ClosedChain::TestRGDConnection(Configuration &testStartConf, Configuration &testGoalConf, PA_Points &localPath)
00817 {
00818 int i, j, k;
00819 i = 0; j = 0; k = 0;
00820 Configuration q_last = testStartConf;
00821
00822 localPath.AppendPoint(testStartConf);
00823 int MAX_I = MAX_ITERATION * MAX_RETRY * MAX_RETRY2;
00824 int MAX_J = MAX_RETRY;
00825 int MAX_K = MAX_RETRY2;
00826 double distToLast = sqrt(Distance(q_last, testGoalConf));
00827 bool bValid = true;
00828 while ((i<MAX_I) && (j<MAX_J) && (k<MAX_K) && (distToLast>DEF_DIST_TOLERANCE))
00829 {
00830 i++; j++;
00831
00832 Configuration q_mid = q_last*(1-(DEF_DIST_TOLERANCE/distToLast)) + testGoalConf*(DEF_DIST_TOLERANCE/distToLast);
00833 if (MakeItClosed(q_mid))
00834 {
00835 j = 0; k++;
00836 if (PL_PRM::IsInterfering(q_mid))
00837 {
00838 bValid = false;
00839 break;
00840 }
00841 if (Distance(q_mid, testGoalConf) < distToLast*distToLast)
00842 {
00843 k = 0;
00844 localPath.AppendPoint(q_mid);
00845 q_last = q_mid;
00846 distToLast = sqrt(Distance(q_last, testGoalConf));
00847 }
00848 }
00849 }
00850
00851 if ((bValid) && (distToLast<=DEF_DIST_TOLERANCE))
00852 {
00853 localPath.AppendPoint(testGoalConf);
00854 }
00855 else
00856 {
00857 localPath.Clear();
00858 }
00859
00860 return bValid;
00861 }
00862
00863 void PL_RRT_ClosedChain::CompareJacobianAndRGD()
00864 {
00865 int numTest = 100;
00866 Configuration testStart, testGoal;
00867 if (jacobian==NULL)
00868 jacobian = new CJacobian(*m_pRobot);
00869
00870 Log("CompareJacobianAndRGD.log", "===============Begin===============");
00871 Log("CompareJacobianAndRGD.log", "Jacobian: S/F, Time, Len, Max, Min; RGD: S/F, Time, Len, Max, Min");
00872 for (int i=0; i<numTest; i++)
00873 {
00874 do{
00875 testStart = GenerateRandomConfig(GetStartConfig(), DEF_NEIGHBOR*0.5);
00876 } while(!IsClosed(testStart));
00877 do
00878 {
00879 testGoal = GenerateRandomConfig(GetGoalConfig(), DEF_NEIGHBOR*0.5);
00880 } while(!IsClosed(testGoal));
00881 Log("PathByJacobian.log", "Start Configuration");
00882 LogConfiguration("PathByJacobian.log", testStart);
00883 Log("PathByJacobian.log", "Goal Configuration");
00884 LogConfiguration("PathByJacobian.log", testGoal);
00885
00886 Log("PathByRGD.log", "Start Configuration");
00887 LogConfiguration("PathByRGD.log", testStart);
00888 Log("PathByRGD.log", "Goal Configuration");
00889 LogConfiguration("PathByRGD.log", testGoal);
00890
00891 int nDof = testStart.DOF();
00892 PA_Points foundPath;
00893
00894 bool bJacobian;
00895 double timeForJacobian;
00896 int nPathLenForJacobian;
00897 double dMaxForJacobian, dMinForJacobian;
00898 dMaxForJacobian = dMinForJacobian = 0;
00899
00900 timeForJacobian = GetTimeElapsedInSeconds();
00901 bJacobian = TestJacobianConnection(testStart, testGoal, foundPath);
00902 timeForJacobian = GetTimeElapsedInSeconds() - timeForJacobian;
00903 nPathLenForJacobian = foundPath.Size();
00904 if ((bJacobian) && (nPathLenForJacobian>1))
00905 {
00906 Configuration diff=foundPath[1]-foundPath[0];
00907 double distance = diff.Magnitude();
00908 dMaxForJacobian = dMinForJacobian = distance;
00909 for(int k=2; k<nPathLenForJacobian; k++)
00910 {
00911 diff=foundPath[k]-foundPath[k-1];
00912 distance = diff.Magnitude();
00913 if (distance > dMaxForJacobian)
00914 dMaxForJacobian = distance;
00915 if (distance < dMinForJacobian)
00916 dMinForJacobian = distance;
00917 }
00918
00919 Log("PathByJacobian.log", "Path: %d [out of %d]", i, numTest);
00920 LogPath("PathByJacobian.log", foundPath);
00921 }
00922
00923 foundPath.Clear();
00924
00925 bool bRGD;
00926 double timeForRGD;
00927 int nPathLenForRGD;
00928 double dMaxForRGD, dMinForRGD;
00929 dMaxForRGD = dMinForRGD = 0;
00930 timeForRGD = GetTimeElapsedInSeconds();
00931 bRGD = TestRGDConnection(testStart, testGoal, foundPath);
00932 timeForRGD = GetTimeElapsedInSeconds() - timeForRGD;
00933 nPathLenForRGD = foundPath.Size();
00934
00935 if ((bRGD) && (nPathLenForRGD>1))
00936 {
00937 Configuration diff=foundPath[1]-foundPath[0];
00938 double distance = diff.Magnitude();
00939 dMaxForRGD = dMinForRGD = distance;
00940 for(int k=2; k<nPathLenForRGD; k++)
00941 {
00942 diff=foundPath[k]-foundPath[k-1];
00943 distance = diff.Magnitude();
00944 if (distance > dMaxForRGD)
00945 dMaxForRGD = distance;
00946 if (distance < dMinForRGD)
00947 dMinForRGD = distance;
00948 }
00949
00950 Log("PathByRGD.log", "Path: %d [out of %d]", i, numTest);
00951 LogPath("PathByRGD.log", foundPath);
00952 }
00953
00954 Log("CompareJacobianAndRGD.log", "Jacobian: %d, %.3f, %d, %.3f, %.3f; RGD: %d, %.3f, %d, %.3f, %.3f",
00955 bJacobian, timeForJacobian, nPathLenForJacobian, dMaxForJacobian, dMinForJacobian,
00956 bRGD, timeForRGD, nPathLenForRGD, dMaxForRGD, dMinForRGD);
00957 }
00958
00959 }