00001 #include "synchronization/semaphore.h"
00002 #include "Planners/fortest/PL_ForTest.h"
00003 #include "planners/ik_mpep/SMGraph.h"
00004 #include "math/matrixmxn.h"
00005 #include "math/vector4.h"
00006 #include <assert.h>
00007 #include <gl\gl.h>
00008
00009 #define DEF_STEP_AHEAD 2
00010 #define MAX_SMG_EXTEND_RETRY 10
00011 #define DEF_SMG_STEPSIZE 5
00012 #define DEF_ERROR_TOLERANCE 0.01
00013
00014 PL_ForTest::PL_ForTest()
00015 {
00016 m_pJacobian = NULL;
00017 m_nStepAhead = DEF_STEP_AHEAD;
00018 m_bUseJacobianSMGExploration = false;
00019 m_bUseBacktracking = true;
00020 m_pLocalPlanner = new Jacobian_TrajPlanner;
00021 m_nSMGStepSize = DEF_SMG_STEPSIZE;
00022 m_bUseObstacleAvoidLP = true;
00023 m_nSMGNodes = m_nSMGraphs = 0;
00024 smgNodeNum = 50;
00025 }
00026
00027 PL_ForTest::~PL_ForTest()
00028 {
00029 if (m_pJacobian != NULL)
00030 delete m_pJacobian;
00031 if (m_pLocalPlanner != NULL)
00032 {
00033 delete m_pLocalPlanner;
00034 }
00035 }
00036
00037 bool PL_ForTest::DrawExplicit () const
00038 {
00039 return PL_MPEP::DrawExplicit();
00040 }
00041
00042 void PL_ForTest::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00043 {
00044 PL_MPEP::SetCollisionDetector(collisionDetector);
00045 m_pLocalPlanner->SetCollisionDetector(collisionDetector);
00046
00047 collisionDetector->DeactivateFrames(1, collisionDetector->DOF());
00048 this->collisionDetector = collisionDetector;
00049 m_nDof = collisionDetector->DOF();
00050 m_pRobot = dynamic_cast<R_OpenChain*>(collisionDetector->GetRobot(0));
00051 m_nToolFrame = m_pRobot->GetToolFrame(0);
00052 m_frEndEffector = Matrix4x4::Identity();
00053 if (m_nToolFrame != -1)
00054 {
00055 FrameManager* frameManager = collisionDetector->GetFrameManager();
00056 m_frEndEffector = *(frameManager->GetFrameRef(m_nToolFrame));
00057 }
00058 if (m_pJacobian != NULL)
00059 {
00060 delete m_pJacobian;
00061 m_pJacobian = new CJacobian(*m_pRobot);
00062 }
00063 }
00064
00065
00066 bool PL_ForTest::Plan ()
00067 {
00068
00069
00070
00071
00072 if (m_pJacobian == NULL)
00073 m_pJacobian = new CJacobian(*m_pRobot);
00074
00075 Configuration startConfig = GetStartConfig();
00076 m_pJacobian->SetConfiguration(startConfig);
00077 m_pJacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, false);
00078
00079
00080 srand( (unsigned)time( NULL ) );
00081
00082 path.Clear();
00083
00084 int result=ERROR_OK;
00085
00086
00087 usingStartConfig = true;
00088 usingGoalConfig = false;
00089 if (collisionDetector->IsInterfering(startConfig))
00090 {
00091 return false;
00092 }
00093
00094 StartTimer();
00095
00096 if ((result=InitializeTree())!=ERROR_OK)
00097 {
00098 return false;
00099 }
00100
00101 int nStepAhead = m_nStepAhead;
00102 if (m_nStepAhead >= poses.size())
00103 nStepAhead = poses.size()-1;
00104
00105 PA_Points foundPath;
00106 PA_Points bufferPath;
00107 Configuration start = startConfig;
00108 int nStartIndex = 0;
00109 int nEndIndex = nStartIndex + nStepAhead;
00110 int nCurrentIndex = 0;
00111 vertex extendedVert = vertices[0];
00112
00113 while (nEndIndex < poses.size())
00114 {
00115 bool bFound;
00116 if (m_bUseObstacleAvoidLP)
00117 bFound = FindLocalPath2(start, nStartIndex, nEndIndex, foundPath);
00118 else
00119 bFound = FindLocalPath(start, nStartIndex, nEndIndex, foundPath);
00120 if (bFound)
00121 {
00122 for (int i=0; i<foundPath.Size(); i++)
00123 bufferPath.AppendPoint(foundPath[i]);
00124
00125 Pose_Node newNode;
00126 newNode.conf = bufferPath[0];
00127 bufferPath.DeleteFirstPoint();
00128 newNode.poses = nCurrentIndex + 1;
00129 newNode.graph = NULL;
00130 extendedVert = ConnectNode(tree, vertices, extendedVert, newNode);
00131 nStartIndex = nEndIndex;
00132 nEndIndex++;
00133 nCurrentIndex++;
00134 start = foundPath[foundPath.Size()-1];
00135 foundPath.Clear();
00136
00137 }
00138 else
00139 {
00140 nStartIndex = nCurrentIndex;
00141 nEndIndex = nStartIndex + nStepAhead;
00142 bufferPath.Clear();
00143
00144
00145
00146 do {
00147 result = Establish_Self_Motion_Graph(tree, extendedVert);
00148 if (HasTimeLimitExpired())
00149 break;
00150 } while ((result!=ERROR_OK) && (result!=ERROR_SMGRAPH_FULL));
00151
00152 if (result==ERROR_OK)
00153 {
00154 Pose_Node *node=(Pose_Node *)tree.vertex_inf(extendedVert);
00155 start = node->conf;
00156 }
00157 }
00158
00159 while (result==ERROR_SMGRAPH_FULL)
00160 {
00161 vertex backtrackVertex;
00162 backtrackVertex = tree.parent(extendedVert);
00163
00164
00165 do
00166 {
00167 vertex prevVertex = tree.parent(extendedVert);
00168 RemoveNode(extendedVert);
00169 extendedVert = prevVertex;
00170 } while(extendedVert != backtrackVertex );
00171
00172 Pose_Node *node=(Pose_Node *)tree.vertex_inf(extendedVert);
00173 nCurrentIndex = node->poses;
00174 nStartIndex = nCurrentIndex;
00175 nEndIndex = nStartIndex + nStepAhead;
00176
00177
00178 do {
00179 result = Establish_Self_Motion_Graph(tree, extendedVert);
00180 if (HasTimeLimitExpired())
00181 break;
00182 } while ((result!=ERROR_OK) && (result!=ERROR_SMGRAPH_FULL));
00183
00184 if (result==ERROR_OK)
00185 {
00186 Pose_Node *node=(Pose_Node *)tree.vertex_inf(extendedVert);
00187 start = node->conf;
00188 }
00189 }
00190
00191 if (HasTimeLimitExpired())
00192 {
00193 result = ERROR_PLANNING_TIMEOUT;
00194 break;
00195 }
00196 }
00197
00198 if (result == ERROR_OK)
00199 {
00200 for (int i=0; i<bufferPath.Size(); i++)
00201 {
00202 Pose_Node newNode;
00203 newNode.conf = bufferPath[i];
00204 newNode.poses = nCurrentIndex + 1;
00205 nCurrentIndex ++;
00206 newNode.graph = NULL;
00207 extendedVert = ConnectNode(tree, vertices, extendedVert, newNode);
00208 }
00209 }
00210 bufferPath.Clear();
00211
00212
00213 goalPoseVertex = extendedVert;
00214 RetrievePathFromTree();
00215
00216 LogStatistics();
00217 if (result == ERROR_OK)
00218 return true;
00219 else
00220 return false;
00221 }
00222
00223
00224 int PL_ForTest::Establish_Self_Motion_Graph(dynamic_trees &tr, vertex extended)
00225 {
00226 int result;
00227 Pose_Node *node = (Pose_Node *)tr.vertex_inf(extended);
00228 if (node->graph==NULL)
00229 {
00230
00231
00232
00233 node->graph = new SMGraph(node->conf);
00234 m_nSMGraphs ++;
00235 }
00236
00237
00238
00239 if ((m_bUseBacktracking) && (node->graph->Node_Num()>smgNodeNum) && (node->poses > 0))
00240 {
00241 result = ERROR_SMGRAPH_FULL;
00242 }
00243 else
00244 {
00245 Configuration *nextConf;
00246 if (m_bUseJacobianSMGExploration)
00247 result = Extend_Node_Self_Motion_Graph_Jacobian(extended, &nextConf);
00248 else
00249 result = Extend_Node_Self_Motion_Graph(extended, &nextConf);
00250 if (result==ERROR_OK)
00251 {
00252
00253
00254 node->conf = *nextConf;
00255 m_nSMGNodes ++;
00256 }
00257 }
00258
00259 return result;
00260 }
00261
00262
00263 int PL_ForTest::Extend_Node_Self_Motion_Graph(vertex g_vertex, Configuration **nextConf)
00264 {
00265 void* nodeInGraph=NULL;
00266 Pose_Node *node = (Pose_Node*) tree.vertex_inf(g_vertex);
00267 SMGraph *g = node->graph;
00268 (*nextConf)=NULL;
00269
00270
00271
00272
00273
00274 Configuration randConf, activeConf, newConf;
00275 Configuration *nearConf;
00276 bool bFind = false;
00277
00278
00279
00280 for (int i=0; i<randomRetry; i++)
00281 {
00282 GetRandomConfiguration(randConf);
00283
00284
00285 nodeInGraph = GetNearestNodeInGraph(g, &randConf);
00286 nearConf = g->GetConfiguration(nodeInGraph);
00287
00288 if (!GetConfigurationByDirection(activeConf, *(nearConf), randConf))
00289 continue;
00290
00291
00292
00293 if (!redundant.GetConfigurationByActive(newConf, activeConf, *nearConf,
00294 poses[node->poses], distTolerance))
00295
00296
00297 continue;
00298
00299 if (collisionDetector->IsInterfering(newConf))
00300 continue;
00301
00302 if (collisionDetector->IsInterferingLinear(newConf, *nearConf))
00303 continue;
00304
00305 bFind = true;
00306 break;
00307 }
00308
00309 if (!bFind)
00310 return ERROR_GET_COLLISION_FREE_FAILURE;
00311
00312 nodeInGraph = g->AddConnection(nodeInGraph, newConf);
00313 (*nextConf) = g->GetConfiguration(nodeInGraph);
00314 return ERROR_OK;
00315 }
00316
00317 bool PL_ForTest::IsJointWithinLimits(Configuration& config)
00318 {
00319 bool bResult = true;
00320 for (int i = 0; i<m_nDof; i++)
00321 {
00322 if ( config[i] < collisionDetector->JointMin(i) )
00323 {
00324 bResult = false;
00325 }
00326 else if ( config[i] > collisionDetector->JointMax(i) )
00327 {
00328 bResult = false;
00329 }
00330 }
00331 return bResult;
00332 }
00333
00334 int PL_ForTest::Extend_Node_Self_Motion_Graph_Jacobian(vertex g_vertex, Configuration **nextConf)
00335 {
00336 void* nodeInGraph=NULL;
00337 Pose_Node *node = (Pose_Node*) tree.vertex_inf(g_vertex);
00338 SMGraph *g = node->graph;
00339 (*nextConf)=NULL;
00340
00341
00342
00343
00344
00345 Configuration randConf, activeConf, newConf;
00346 Configuration *nearConf;
00347 bool bFind = false;
00348
00349 Matrixmxn mJEnd, mJEndInv;
00350 Matrixmxn mTemp(m_nDof, m_nDof);
00351 Matrixmxn matrixIdentity(m_nDof, m_nDof);
00352
00353
00354
00355 for (int i=0; i<randomRetry; i++)
00356 {
00357
00358 GetRandomConfiguration(randConf);
00359
00360
00361 nodeInGraph = GetNearestNodeInGraph(g, &randConf);
00362 nearConf = g->GetConfiguration(nodeInGraph);
00363 Configuration dirVel = randConf - (*nearConf);
00364
00365 mJEnd = *(m_pJacobian->GetMatrix());
00366 mJEnd.Inverse(mJEndInv);
00367 mTemp = matrixIdentity;
00368 mTemp -= mJEndInv * mJEnd;
00369 dirVel = mTemp * dirVel;
00370 dirVel *= (m_nSMGStepSize/ dirVel.Magnitude());
00371 newConf = *nearConf + dirVel;
00372 if (!IsJointWithinLimits(newConf))
00373 continue;
00374 if (collisionDetector->IsInterfering(newConf))
00375 continue;
00376
00377 AdjustConfiguration(newConf, node->poses);
00378 if (collisionDetector->IsInterferingLinear(newConf, *nearConf))
00379 continue;
00380
00381 bFind = true;
00382 break;
00383 }
00384
00385
00386 if (!bFind)
00387 {
00388
00389 return ERROR_GET_COLLISION_FREE_FAILURE;
00390 }
00391
00392
00393 nodeInGraph = g->AddConnection(nodeInGraph, newConf);
00394 (*nextConf) = g->GetConfiguration(nodeInGraph);
00395
00396
00397
00398 Frame currentFrame = GetToolFrame(**nextConf);
00399 Frame desiredFrame = poses[node->poses];
00400 Vector4 vec1 = currentFrame.GetTranslationVector();
00401 Vector4 vec2 = desiredFrame.GetTranslationVector();
00402 vec2 -= vec1;
00403 double dDistance = vec2.Magnitude();
00404
00405
00406 return ERROR_OK;
00407 }
00408
00409 bool PL_ForTest::AdjustConfiguration(Configuration &config, int nPose)
00410 {
00411 Frame desiredFrame = poses[nPose];
00412 Vector4 desiredPos = desiredFrame.GetTranslationVector();
00413
00414
00415
00416
00417 int logRetry=0;
00418 while (true)
00419 {
00420 Frame currentFrame = GetToolFrame(config);
00421 Vector4 currentPos = currentFrame.GetTranslationVector();
00422
00423
00424
00425
00426 Vector4 offset = desiredPos - currentPos;
00427 double dDistance = offset.Magnitude();
00428 if (dDistance < DEF_ERROR_TOLERANCE)
00429 break;
00430
00431 logRetry++;
00432
00433 Matrixmxn mJEnd, mJEndInv;
00434 m_pJacobian->SetConfiguration(config);
00435 m_pJacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, false);
00436 mJEnd = *(m_pJacobian->GetMatrix());
00437 mJEnd.Inverse(mJEndInv);
00438
00439
00440
00441 VectorN endEffOffset(offset[0], offset[1], offset[2]);
00442 Configuration jointOffset;
00443 jointOffset = mJEndInv * endEffOffset * Rad2Deg(1);
00444 config += jointOffset;
00445 }
00446
00447 return true;
00448 }
00449
00450 VectorN PL_ForTest::ComputeDeltaEndEff(Frame &fromPose, Frame &toPose)
00451 {
00452 VectorN returnMe;
00453
00454
00455 returnMe.SetLength(3);
00456
00457 int index = 0;
00458 returnMe[index++] = toPose(0, 3) - fromPose(0, 3);
00459 returnMe[index++] = toPose(1, 3) - fromPose(1, 3);
00460 returnMe[index++] = toPose(2, 3) - fromPose(2, 3);
00461
00462 return returnMe;
00463 }
00464
00465
00466
00467
00468
00469
00470 bool PL_ForTest::FindLocalPath(Configuration &start, int nStart, int nEnd, PA_Points &localPath)
00471 {
00472 Matrixmxn mJEnd, mJEndInv;
00473 bool bValid = true;
00474 VectorN deltaEndEff;
00475 Configuration deltaConf;
00476 Configuration nextConf = start;
00477
00478 for(int i=nStart; i<nEnd; i++)
00479 {
00480 m_pJacobian->SetConfiguration(nextConf);
00481 m_pJacobian->SetInterestPoint(m_nDof-1, m_frEndEffector, true, false);
00482 mJEnd = *(m_pJacobian->GetMatrix());
00483 mJEnd.Inverse(mJEndInv);
00484
00485 Frame currentPose = GetToolFrame(nextConf);
00486
00487 deltaEndEff = ComputeDeltaEndEff(currentPose, poses[i+1]);
00488 deltaConf = mJEndInv * deltaEndEff;
00489 deltaConf *= Rad2Deg(1);
00490
00491
00492
00493
00494
00495 Configuration newConf;
00496 newConf = nextConf + deltaConf;
00497 if (!IsJointWithinLimits(newConf))
00498 {
00499 localPath.Clear();
00500 bValid = false;
00501 break;
00502 }
00503 AdjustConfiguration(newConf, i+1);
00504 if (collisionDetector->IsInterferingLinear(newConf, nextConf))
00505 {
00506 localPath.Clear();
00507 bValid = false;
00508 break;
00509 }
00510 else
00511 {
00512 nextConf = newConf;
00513 localPath.AppendPoint(nextConf);
00514 }
00515 }
00516
00517 return bValid;
00518 }
00519
00520
00521 bool PL_ForTest::FindLocalPath2(Configuration &start, int nStart, int nEnd, PA_Points &localPath)
00522 {
00523 std::vector<Frame> piece;
00524 for (int i=nStart; i<=nEnd; i++)
00525 piece.push_back(poses[i]);
00526
00527 m_pLocalPlanner->SetStartConfig(start);
00528 m_pLocalPlanner->SetTrajectory(piece);
00529 m_pLocalPlanner->SetUsingOrientation(false);
00530 m_pLocalPlanner->SetUseGoalConfig(false);
00531 if (m_pLocalPlanner->Plan())
00532 {
00533 PA_Points *foundPath = (PA_Points *)m_pLocalPlanner->GetPath();
00534 for (int k=1; k<foundPath->Size(); k++)
00535 localPath.AppendPoint((*foundPath)[k]);
00536 return true;
00537 }
00538 return false;
00539 }
00540
00541 void PL_ForTest::RemoveNode(vertex failVert)
00542 {
00543
00544 assert(failVert != NULL);
00545
00546 Semaphore semaphore( guid );
00547 semaphore.Lock();
00548
00549 tree.cut(failVert);
00550 Pose_Node *node=(Pose_Node *)tree.vertex_inf(failVert);
00551 if (node->graph != NULL)
00552 {
00553 node->graph->Clear();
00554 delete node->graph;
00555 node->graph = NULL;
00556 }
00557
00558 semaphore.Unlock();
00559 }
00560
00561 void PL_ForTest::ResetStatistics()
00562 {
00563 m_nSMGNodes = 0;
00564 m_nSMGraphs = 0;
00565 }
00566
00567 void PL_ForTest::LogStatistics()
00568 {
00569 int nNodes = vertices.size();
00570 int nPathLen = path.Size();
00571 Log("ForTest.log", "SMGNodes: %d, SMGraphs: %d, TreeNodes: %d, PathLen: %d",
00572 m_nSMGNodes, m_nSMGraphs, nNodes, nPathLen);
00573 }