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 "planners/closedchain/PL_PRM_Closedchain.h"
00011 #include "PL_RGD_Constraint.h"
00012 #include <gl/gl.h>
00013 #include <opengl/gl_sphere.h>
00014 #include <opengl/gl_group.h>
00015
00016 #define MAX_ITERATION 30
00017 #define MAX_RETRY 30
00018 #define MAX_RETRY2 30
00019 #define DEF_NEIGHBOR (2)
00020 #define DEF_DIST_TOLERANCE (3)
00021 #define DEF_ERR_TOLERANCE (1e-1)
00022
00023
00024 #define RGD_SPHERE_CX 15
00025 #define RGD_SPHERE_CY 0
00026 #define RGD_SPHERE_CZ 5
00027 #define RGD_SPHERE_RADIUS 12
00028 #define SHPERE_ORIENTATION
00029
00030 double (PL_RGD_PRM::*costFunc)(const Configuration &p1, const Frame &pose) const = &PL_RGD_PRM::Error1;
00031
00032 PL_RGD_PRM::PL_RGD_PRM()
00033 {
00034 edgePath.init(G);
00035 edgeFrag = new Fragment;
00036
00037
00038 planner = new LocalPlannerClosed;
00039 pCollisionDetector = NULL;
00040 useJacobian = false;
00041 useGoalPose = false;
00042 typeOfConstraint = CONSTRAINT_COLSURE;
00043 }
00044
00045 PL_RGD_PRM::~PL_RGD_PRM()
00046 {
00047 if(pCollisionDetector)
00048 {
00049 delete pCollisionDetector;
00050 }
00051 delete planner;
00052
00053 edgeFrag->clear();
00054 delete edgeFrag;
00055 }
00056
00057 void PL_RGD_PRM::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00058 {
00059
00060 PL_PRM::SetCollisionDetector( collisionDetector );
00061
00062 if (pCollisionDetector != NULL)
00063 delete pCollisionDetector;
00064
00065 pCollisionDetector = new CD_Swiftpp( *(collisionDetector->GetUniverse()) );
00066 planner->SetCollisionDetector(pCollisionDetector);
00067 pCollisionDetector->DeactivateFrames(1, pCollisionDetector->DOF());
00068 }
00069
00070 bool PL_RGD_PRM::Plan ()
00071 {
00072 srand( (unsigned)time( NULL ) );
00073
00074 StartTimer();
00075 if (typeOfConstraint == CONSTRAINT_PLANAR)
00076 {
00077 UpdatePlanarConstraint();
00078 }
00079 else if (typeOfConstraint == CONSTRAINT_ORIENTATION)
00080 {
00081 UpdateOrientConstraint();
00082 }
00083 else if (typeOfConstraint == CONSTRAINT_SPHERE)
00084 {
00085 UpdateShpereConstraint();
00086 }
00087
00088 if (useJacobian)
00089 {
00090 planner->SetTimeLimitInSeconds(100);
00091 Configuration q1 = GetStartConfig();
00092 Configuration q2 = GetGoalConfig();
00093 planner->SetStartConfig(q1);
00094 planner->SetGoalConfig(q2);
00095
00096 double dObstacleTol = 0.01;
00097 double dHomogain = 2.0;
00098 double dPathTol = 0.5;
00099 int nObstacleNum = 2;
00100
00101 planner->SetObstacleTolerance(dObstacleTol);
00102 planner->SetNumObstaclePt(nObstacleNum);
00103 planner->SetHomogeneousGain(dHomogain);
00104 planner->SetPathTolerence(dPathTol);
00105 planner->SetOrientation(false);
00106 planner->SetPosition(true);
00107
00108
00109 bool result = planner->Plan();
00110
00111 PA_Points *plannerPath = (PA_Points *)planner->GetPath();
00112 path = *plannerPath;
00113
00114
00115
00116 return result;
00117 }
00118 else if (useGoalPose)
00119 {
00120 Configuration conf;
00121 Frame goalPose = GetToolFrame( GetGoalConfig() );
00122 bool Result = false;
00123 double oldTimeLimit = GetTimeLimitInSeconds();
00124 double timeLimit = 100;
00125
00126 while (Result == false)
00127 {
00128 Result = GenerateRandomConfigForPose(conf, goalPose);
00129 if (Result)
00130 {
00131 timeLimit = GetTimeElapsedInSeconds() + 20;
00132 oldTimeLimit = GetTimeLimitInSeconds();
00133 if (timeLimit > oldTimeLimit)
00134 timeLimit = oldTimeLimit;
00135 SetTimeLimitInSeconds( timeLimit );
00136 PL_PRM::SetGoalConfig(conf);
00137 Result = Plan_As_Usual();
00138 if (GetTimeLimitInSeconds() != timeLimit)
00139 break;
00140 else
00141 SetTimeLimitInSeconds( oldTimeLimit );
00142 }
00143 if (Result)
00144 return true;
00145 if ( HasTimeLimitExpired() )
00146 {
00147 return false;
00148 }
00149 }
00150 return false;
00151
00152
00153 }
00154 else
00155 {
00156 return Plan_As_Usual();
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 }
00196
00197
00198
00199
00200 Frame PL_RGD_PRM::GetToolFrame( const Configuration& config ) const
00201 {
00202 Frame toolFrame = Matrix4x4();
00203 if ( collisionDetector != NULL )
00204 {
00205 FrameManager* frameManager = collisionDetector->GetFrameManager();
00206 collisionDetector->SetConfiguration( config );
00207 R_OpenChain * robot = (R_OpenChain *)collisionDetector->GetRobot(0);
00208 int toolFrameID = robot->GetToolFrame(0);
00209 if (toolFrameID == -1)
00210 {
00211 toolFrameID = collisionDetector->JointFrameNum(collisionDetector->DOF()-1);
00212 toolFrame = frameManager->GetWorldFrame( toolFrameID );
00213 }
00214 else
00215 {
00216 toolFrame = *(frameManager->GetFrameRef(toolFrameID));
00217 toolFrame = frameManager->GetTransformRelative(collisionDetector->DOF(), 0) * toolFrame;
00218 }
00219 }
00220 return toolFrame;
00221 }
00222
00223 bool PL_RGD_PRM::Plan_As_Usual ()
00224 {
00225 PRM_StateMachineType currentState = lastPlanningState;
00226
00227
00228
00229 if ( lastPlanningState == PRM_FAILURE )
00230 {
00231 currentState = PRM_START;
00232 }
00233
00234
00235
00236
00237
00238 Semaphore semaphore( guid );
00239 if( this->m_UseSemaphores == true )
00240 {
00241 semaphore.Lock();
00242 }
00243
00244
00245
00246 if ( (currentState != PRM_DONE ) && (currentState != PRM_FAILURE) )
00247 {
00248 if ( startNode == goalNode )
00249 {
00250
00251 currentState = PRM_DONE;
00252
00253
00254 path.Clear();
00255 path.AppendPoint( GetStartConfig() );
00256 }
00257 else if ( (PL_PRM::IsInterfering(startNode)) || (PL_PRM::IsInterfering(goalNode)) )
00258 {
00259
00260
00261 currentState = PRM_FAILURE;
00262 }
00263 }
00264 if( this->m_UseSemaphores == true )
00265 {
00266 semaphore.Unlock();
00267 }
00268
00269
00270 diagonal_squared = GetCspaceRange();
00271
00272
00273 while (( currentState != PRM_DONE ) && ( currentState != PRM_FAILURE ))
00274
00275 {
00276 SuccessResultType success;
00277
00278 if( this->m_UseSemaphores == true )
00279 {
00280 semaphore.Lock();
00281 }
00282
00283 switch ( currentState )
00284 {
00285 case PRM_BUILD_INIT_ROADMAP :
00286 success = BuildInitRoadMap();
00287 break;
00288 case PRM_FIND_PATH :
00289 success = FindPath();
00290 break;
00291 case PRM_VERIFY_PATH :
00292 success = VerifyPath();
00293 break;
00294 case PRM_TRANSLATE_PATH :
00295 success = TranslatePath();
00296 break;
00297 case PRM_ENHANCE_ROADMAP :
00298 success = EnhanceRoadMap();
00299 break;
00300 default :
00301
00302
00303 success = PASS;
00304 }
00305
00306
00307
00308 if ( success == TIMER_EXPIRED )
00309 {
00310
00311 break;
00312 }
00313
00314
00315 switch ( currentState )
00316 {
00317 case PRM_START :
00318
00319 currentState = PRM_BUILD_INIT_ROADMAP;
00320 break;
00321 case PRM_BUILD_INIT_ROADMAP :
00322
00323 currentState = PRM_FIND_PATH;
00324 break;
00325 case PRM_FIND_PATH :
00326 if ( success == PASS )
00327 {
00328
00329 currentState = PRM_VERIFY_PATH;
00330 }
00331 else
00332 {
00333
00334 currentState = PRM_ENHANCE_ROADMAP;
00335
00336
00337 }
00338 break;
00339 case PRM_VERIFY_PATH :
00340 if ( success == PASS )
00341 {
00342
00343
00344 currentState = PRM_TRANSLATE_PATH;
00345 }
00346 else
00347 {
00348
00349
00350 currentState = PRM_FIND_PATH;
00351 }
00352 break;
00353 case PRM_TRANSLATE_PATH :
00354
00355 currentState = PRM_DONE;
00356 break;
00357 case PRM_ENHANCE_ROADMAP :
00358
00359 currentState = PRM_FIND_PATH;
00360 break;
00361 default :
00362
00363 ASSERT( FALSE );
00364 }
00365
00366
00367 if( this->m_UseSemaphores == true )
00368 {
00369 semaphore.Unlock();
00370 }
00371 }
00372
00373
00374
00375 lastPlanningState = currentState;
00376
00377
00378 if ( currentState == PRM_DONE )
00379 {
00380
00381
00382
00383 if( this->m_UseSemaphores == true )
00384 {
00385 semaphore.Unlock();
00386 }
00387
00388 return true;
00389 }
00390 else
00391 {
00392
00393 graphPath.clear();
00394
00395
00396 path.Clear();
00397 path.AppendPoint( GetStartConfig() );
00398
00399
00400 if( this->m_UseSemaphores == true )
00401 {
00402 semaphore.Unlock();
00403 }
00404
00405 return false;
00406 }
00407 }
00408
00409 bool PL_RGD_PRM::GetSatisfactoryConfiguration(Configuration &conf, Frame &pose)
00410 {
00411 int i,j;
00412 Configuration q;
00413 q = conf;
00414 i = 0; j = 0;
00415 int MAX_I = MAX_ITERATION * MAX_RETRY;
00416 int MAX_J = MAX_RETRY*2;
00417 double err_q = (this->*costFunc)(q, pose);
00418 while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00419 {
00420 i++; j++;
00421 double deviation = DEF_NEIGHBOR;
00422 if (err_q < 1)
00423 deviation *= err_q;
00424 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00425 if ((this->*costFunc)(q_next, pose) < err_q)
00426 {
00427 j = 0;
00428 q = q_next;
00429 err_q = (this->*costFunc)(q, pose);
00430 }
00431 if ( HasTimeLimitExpired() )
00432 {
00433 return false;
00434 }
00435 }
00436
00437 char msg[200];
00438 sprintf(msg, "I=%d, J=%d \t %f", i, j, err_q);
00439
00440 conf = q;
00441 return (err_q <= DEF_ERR_TOLERANCE);
00442 }
00443
00444 bool PL_RGD_PRM::GetSatisfiedConfiguration(Configuration &conf)
00445 {
00446 UpdatePlanarConstraint();
00447 UpdateOrientConstraint();
00448 UpdateShpereConstraint();
00449
00450 int i,j;
00451 Configuration q;
00452 q = conf;
00453 i = 0; j = 0;
00454 int MAX_I = MAX_ITERATION * MAX_RETRY;
00455 int MAX_J = MAX_RETRY;
00456 double err_q = Error(q);
00457 while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00458 {
00459 i++; j++;
00460 double deviation = DEF_NEIGHBOR;
00461 if (err_q < 1)
00462 deviation *= err_q;
00463 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00464 if (Error(q_next) < err_q)
00465 {
00466 j = 0;
00467 q = q_next;
00468 err_q = Error(q);
00469 }
00470 }
00471
00472 conf = q;
00473 return (err_q <= DEF_ERR_TOLERANCE);
00474 }
00475
00476 bool PL_RGD_PRM::GenerateRandomConfigForPose (Configuration &conf, Frame &endEffPose)
00477 {
00478 conf = PL_PRM::GenerateRandomConfig();
00479 costFunc = &PL_RGD_PRM::Error1;
00480
00481 bool Result = GetSatisfactoryConfiguration(conf, endEffPose);
00482 if (Result)
00483 {
00484 Result = !IsInterfering(conf);
00485 }
00486 return Result;
00487 }
00488
00489 Configuration PL_RGD_PRM::GenerateRandomConfig ()
00490 {
00491 Configuration conf;
00492 Frame endEffPose;
00493 conf = PL_PRM::GenerateRandomConfig();
00494 if (typeOfConstraint == CONSTRAINT_PLANAR)
00495 {
00496 endEffPose = planeDesired;
00497 costFunc = &PL_RGD_PRM::Error3;
00498 }
00499 else if (typeOfConstraint == CONSTRAINT_ORIENTATION)
00500 {
00501 endEffPose = orientDesired;
00502 costFunc = &PL_RGD_PRM::Error4;
00503 }
00504 else if (typeOfConstraint == CONSTRAINT_SPHERE)
00505 {
00506 costFunc = &PL_RGD_PRM::Error5;
00507 }
00508 else if (typeOfConstraint == CONSTRAINT_OTHER)
00509 {
00510
00511 endEffPose = orientDesired;
00512 costFunc = &PL_RGD_PRM::Error6;
00513 }
00514 else
00515 {
00516 costFunc = &PL_RGD_PRM::Error2;
00517 }
00518
00519 GetSatisfactoryConfiguration(conf, endEffPose);
00520
00521 return conf;
00522 }
00523
00524 Configuration PL_RGD_PRM::GenerateRandomConfig ( const Configuration& seed, const double& std_dev )
00525 {
00526 Configuration conf;
00527 Frame endEffPose;
00528 conf = PL_PRM::GenerateRandomConfig(seed, std_dev);
00529 if (typeOfConstraint == CONSTRAINT_PLANAR)
00530 {
00531 endEffPose = planeDesired;
00532 costFunc = &PL_RGD_PRM::Error3;
00533 }
00534 else if (typeOfConstraint == CONSTRAINT_ORIENTATION)
00535 {
00536 endEffPose = orientDesired;
00537 costFunc = &PL_RGD_PRM::Error4;
00538 }
00539 else if (typeOfConstraint == CONSTRAINT_SPHERE)
00540 {
00541 costFunc = &PL_RGD_PRM::Error5;
00542 }
00543 else
00544 {
00545 costFunc = &PL_RGD_PRM::Error2;
00546 }
00547
00548 GetSatisfactoryConfiguration(conf, endEffPose);
00549 return conf;
00550 }
00551
00552 void PL_RGD_PRM::ConnectEdgesFull( const node& newnode, const double& radius_squared )
00553 {
00554
00555 assert( connectIDp != NULL );
00556
00557
00558 Configuration nodeconfig = G.inf(newnode);
00559
00560 node n1;
00561
00562
00563 node_pq<double> neighbours(G);
00564 forall_nodes( n1, G)
00565 {
00566 if ( newnode != n1)
00567 {
00568 double edgelength_squared = Distance( nodeconfig, G.inf(n1) );
00569
00570 if ( edgelength_squared <= radius_squared )
00571 {
00572
00573 neighbours.insert( n1, edgelength_squared );
00574 }
00575 }
00576 }
00577
00578
00579 (*connectIDp)[newnode] = NIL_ID;
00580
00581
00582 list<int> connectIDs;
00583
00584
00585
00586 while ( !neighbours.empty() )
00587 {
00588
00589 node neighbour = neighbours.find_min();
00590 double dist_sq = neighbours.inf( neighbour );
00591 neighbours.del( neighbour );
00592
00593
00594
00595
00596 if ( ((*connectIDp)[neighbour] == NIL_ID) ||
00597 ( ((*connectIDp)[neighbour] != (*connectIDp)[newnode]) &&
00598 ( !NodeInConnectionList(neighbour, connectIDs) ) )
00599 )
00600 {
00601 edgeFrag->clear();
00602
00603 if ( !IsInterfering( nodeconfig, G.inf(neighbour) ) )
00604 {
00605 double edgelength = sqrt( dist_sq );
00606 edge newedge = G.new_edge( newnode, neighbour, edgelength );
00607 edgeChecked[newedge] = TRUE;
00608 edgePath[newedge] = *edgeFrag;
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 if ( (*connectIDp)[neighbour] != NIL_ID )
00621
00622 {
00623 if ( (*connectIDp)[newnode] == NIL_ID )
00624 {
00625
00626 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
00627 }
00628 else if ( (*connectIDp)[neighbour] < (*connectIDp)[newnode] )
00629 {
00630
00631
00632
00633
00634 connectIDs.push( (*connectIDp)[newnode] );
00635
00636
00637 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
00638 }
00639 else
00640 {
00641
00642
00643
00644 connectIDs.push( (*connectIDp)[neighbour] );
00645
00646
00647 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
00648 }
00649 }
00650 else
00651
00652 {
00653 if ( (*connectIDp)[newnode] != NIL_ID )
00654 {
00655
00656 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
00657 }
00658 else
00659 {
00660
00661
00662 (*connectIDp)[newnode] = baseConnectID;
00663 (*connectIDp)[neighbour] = baseConnectID;
00664
00665
00666 baseConnectID++;
00667 }
00668 }
00669
00670 }
00671 else
00672 {
00673 edgeFrag->clear();
00674
00675
00676 if ( useMidPts )
00677 {
00678 Configuration midpt = GetMidPoint( nodeconfig, G.inf(neighbour) );
00679 config_seeds.append( midpt );
00680 }
00681 }
00682
00683 }
00684
00685 }
00686
00687
00688
00689 if ( ((*connectIDp)[newnode] != NIL_ID) && ( !connectIDs.empty() ) )
00690 {
00691
00692
00693 int newID = (*connectIDp)[newnode];
00694
00695 forall_nodes( n1, G )
00696 {
00697 if ( ((*connectIDp)[n1] != newID ) && (NodeInConnectionList( n1, connectIDs )) )
00698 {
00699 (*connectIDp)[n1] = newID;
00700 }
00701 }
00702 }
00703
00704 return;
00705 }
00706
00707 bool PL_RGD_PRM::MakeItSatisfied(Configuration &conf)
00708 {
00709 int i,j;
00710 Configuration q;
00711 q = conf;
00712 i = 0; j = 0;
00713 int MAX_I = MAX_ITERATION * MAX_RETRY;
00714 int MAX_J = MAX_RETRY;
00715 double err_q = Error(q);
00716 while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00717 {
00718 i++; j++;
00719 double deviation = DEF_NEIGHBOR;
00720 if (err_q < 1)
00721 deviation *= err_q;
00722 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00723 if (Error(q_next) < err_q)
00724 {
00725 j = 0;
00726 q = q_next;
00727 err_q = Error(q);
00728 }
00729 if ( HasTimeLimitExpired() )
00730 {
00731 return false;
00732 }
00733 }
00734
00735 conf = q;
00736 return (err_q <= DEF_ERR_TOLERANCE);
00737 }
00738
00739 bool PL_RGD_PRM::IsSatisfied(const Configuration &conf) const
00740 {
00741 return (Error(conf) <= DEF_ERR_TOLERANCE);
00742 }
00743
00744 bool PL_RGD_PRM::IsInterfering ( const Configuration& q1, const Configuration& q2 )
00745 {
00746 int i, j, k;
00747 i = 0; j = 0; k = 0;
00748 Configuration q_last = q1;
00749
00750 edgeFrag->append(q1);
00751 int MAX_I = MAX_ITERATION * MAX_RETRY * MAX_RETRY2;
00752 int MAX_J = MAX_RETRY;
00753 int MAX_K = MAX_RETRY2;
00754 double distToLast = sqrt(Distance(q_last, q2));
00755 bool result = false;
00756 while ((i<MAX_I) && (j<MAX_J) && (k<MAX_K) && (distToLast>DEF_DIST_TOLERANCE))
00757 {
00758 i++; j++;
00759
00760 Configuration q_mid = q_last*(1-(DEF_DIST_TOLERANCE/distToLast)) + q2*(DEF_DIST_TOLERANCE/distToLast);
00761 if (MakeItSatisfied(q_mid))
00762 {
00763 j = 0; k++;
00764 if (PL_PRM::IsInterfering(q_mid))
00765 {
00766 result = true;
00767 break;
00768 }
00769 if (Distance(q_mid, q2) < distToLast*distToLast)
00770 {
00771 k = 0;
00772 edgeFrag->append(q_mid);
00773 q_last = q_mid;
00774 distToLast = sqrt(Distance(q_last, q2));
00775 }
00776 }
00777 if ( HasTimeLimitExpired() )
00778 {
00779 result = true;
00780 break;
00781 }
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 if ((!result) && (distToLast<=DEF_DIST_TOLERANCE))
00793 {
00794 edgeFrag->append(q2);
00795 return false;
00796 }
00797 else
00798 {
00799 edgeFrag->clear();
00800 return true;
00801 }
00802 }
00803
00804 bool PL_RGD_PRM::IsInterfering ( const Configuration& c1 )
00805 {
00806 if (!IsSatisfied(c1))
00807 return true;
00808 if (PL_PRM::IsInterfering(c1))
00809 return true;
00810 return false;
00811 }
00812
00813
00814 void PL_RGD_PRM::UpdatePlanarConstraint()
00815 {
00816 planeDesired = GetToolFrame( GetStartConfig() );
00817 }
00818
00819 void PL_RGD_PRM::UpdateOrientConstraint()
00820 {
00821
00822
00823
00824
00825 if (typeOfConstraint == CONSTRAINT_OTHER)
00826 {
00827 orientDesired = Matrix4x4::Identity();
00828 orientDesired.Rotate2(Vector4(0, 1, 0), 90);
00829 }
00830 else
00831 {
00832 orientDesired = Matrix4x4::Identity();
00833 orientDesired.Rotate2(Vector4(1, 0, 0), 90);
00834
00835
00836
00837
00838
00839 }
00840 }
00841
00842 void PL_RGD_PRM::UpdateShpereConstraint()
00843 {
00844 return;
00845 }
00846
00847
00848 double PL_RGD_PRM::Error1(const Configuration &p1, const Frame &pose) const
00849 {
00850 double distance;
00851
00852 Frame toolFrame = GetToolFrame( p1 );
00853
00854 if (typeOfConstraint == CONSTRAINT_ORIENTATION)
00855 {
00856 Vector4 offset = pose.GetTranslationVector() - toolFrame.GetTranslationVector();
00857 distance = offset.Magnitude();
00858
00859
00860
00861
00862 Vector4 PZ(0, 0, 1);
00863
00864
00865
00866
00867 Vector4 Paz = toolFrame * PZ;
00868
00869
00870
00871 Vector4 Pbz = pose * PZ;
00872
00873
00874
00875
00876 Vector4 dz = Paz - Pbz;
00877
00878
00879
00880
00881 distance += dz.Magnitude();
00882 }
00883 else if (typeOfConstraint == CONSTRAINT_SPHERE)
00884 {
00885 Vector4 offset = pose.GetTranslationVector() - toolFrame.GetTranslationVector();
00886 distance = offset.Magnitude();
00887
00888 Vector4 center(RGD_SPHERE_CX, RGD_SPHERE_CY, RGD_SPHERE_CZ);
00889
00890 Vector4 pos1 = pose.GetTranslationVector();
00891 Vector4 desiredZ = center;
00892 desiredZ -= pos1;
00893 desiredZ.Normalize();
00894
00895
00896
00897 Vector4 pos2 = toolFrame.GetTranslationVector();
00898 Vector4 currentZ;
00899 currentZ[0] = toolFrame(0, 2);
00900 currentZ[1] = toolFrame(1, 2);
00901 currentZ[2] = toolFrame(2, 2);
00902
00903
00904 desiredZ -= currentZ;
00905 distance += desiredZ.Magnitude();
00906 }
00907 else
00908 {
00909 Vector4 offset = pose.GetTranslationVector() - toolFrame.GetTranslationVector();
00910 distance = offset.Magnitude();
00911 }
00912
00913 return distance;
00914 }
00915
00916
00917 double PL_RGD_PRM::Error2(const Configuration &p1, const Frame &pose) const
00918 {
00919
00920
00921 Frame toolFrame = GetToolFrame( p1 );
00922 Vector4 offset = toolFrame.GetTranslationVector();
00923 offset[2] = 0;
00924 return offset.Magnitude();
00925 }
00926
00927
00928 double PL_RGD_PRM::Error3(const Configuration &p1, const Frame &pose) const
00929 {
00930
00931 Frame toolFrame = GetToolFrame( p1 );
00932 return fabs(toolFrame(1, 3)-pose(1, 3));
00933 }
00934
00935
00936
00937 double PL_RGD_PRM::Error4(const Configuration &p1, const Frame &pose) const
00938 {
00939
00940
00941
00942 Frame toolFrame = GetToolFrame( p1 );
00943 Vector4 desiredZ, currentZ;
00944 desiredZ = orientDesired*Vector4(0, 0, 1);
00945 currentZ[0] = toolFrame(0, 2);
00946 currentZ[1] = toolFrame(1, 2);
00947 currentZ[2] = toolFrame(2, 2);
00948 double anglecos = currentZ.Dot(desiredZ);
00949 if (anglecos > 1)
00950 anglecos = 1;
00951 else if (anglecos < -1)
00952 anglecos = -1;
00953
00954 return fabs(acos(anglecos));
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 }
00967
00968
00969 double PL_RGD_PRM::Error5(const Configuration &p1, const Frame &pose) const
00970 {
00971 Vector4 center(RGD_SPHERE_CX, RGD_SPHERE_CY, RGD_SPHERE_CZ);
00972
00973 Frame toolFrame = GetToolFrame(p1);
00974 Vector4 pos1 = toolFrame.GetTranslationVector();
00975
00976 #ifdef SHPERE_ORIENTATION //sphere constraint with constraint
00977 Vector4 desiredZ = center;
00978 desiredZ -= pos1;
00979 desiredZ.Normalize();
00980 desiredZ *= -(RGD_SPHERE_RADIUS-1);
00981 desiredZ += center;
00982
00983 Vector4 pos2 = toolFrame.GetTranslationVector();
00984 Vector4 currentZ;
00985 currentZ[0] = toolFrame(0, 2);
00986 currentZ[1] = toolFrame(1, 2);
00987 currentZ[2] = toolFrame(2, 2);
00988 currentZ += pos2;
00989
00990 desiredZ -= currentZ;
00991 return desiredZ.Magnitude();
00992
00993 #else //Without orientation
00994 pos1 -= center;
00995 return sqrt((pos1.Magnitude() - radius)*(pos1.Magnitude() - radius));
00996 #endif
00997 }
00998
00999 double PL_RGD_PRM::Error6(const Configuration &p1, const Frame &pose) const
01000 {
01001
01002 return Error4(p1, pose);
01003 }
01004
01005 double PL_RGD_PRM::Error(const Configuration &p1) const
01006 {
01007 Frame toolFrame = GetToolFrame( p1 );
01008
01009 if (typeOfConstraint == CONSTRAINT_PLANAR)
01010 {
01011 return Error3(p1, planeDesired);
01012 }
01013 else if (typeOfConstraint == CONSTRAINT_ORIENTATION)
01014 {
01015 return Error4(p1, orientDesired);
01016 }
01017 else if (typeOfConstraint == CONSTRAINT_SPHERE)
01018 {
01019 return Error5(p1, toolFrame);
01020 }
01021 else if (typeOfConstraint == CONSTRAINT_OTHER)
01022 {
01023 return Error6(p1, toolFrame);
01024 }
01025 else
01026 {
01027 return Error2(p1, toolFrame);
01028 }
01029 }
01030
01031 void PL_RGD_PRM::GetRotAngles( const Matrix4x4& frame, double& roll, double& pitch, double& yaw ) const
01032 {
01033
01034 double alpha, beta, gamma;
01035
01036
01037 beta = atan2( -frame(2,0) , sqrt( Sqr(frame(0,0)) + Sqr(frame(1,0)) ) );
01038 double cB = cos ( beta );
01039
01040
01041 if ( cB == 0.0 )
01042 {
01043 alpha = 0;
01044 if ( beta > 0 )
01045 {
01046 gamma = atan2( frame(0,1) , frame(1,1) );
01047 }
01048 else
01049 {
01050 gamma = -atan2( frame(0,1), frame(1,1) );
01051 }
01052 }
01053 else
01054 {
01055 alpha = atan2( frame(1,0) / cB , frame(0,0) / cB );
01056 gamma = atan2( frame(2,1) / cB , frame(2,2) / cB );
01057 }
01058
01059
01060
01061 yaw = Rad2Deg( alpha );
01062 pitch = Rad2Deg( beta );
01063 roll = Rad2Deg( gamma );
01064 }
01065
01066 SuccessResultType PL_RGD_PRM::TranslatePath()
01067 {
01068
01069 path.Clear();
01070
01071
01072 if ( graphPath.empty() )
01073 {
01074
01075 path.AppendPoint( GetStartConfig() );
01076
01077
01078 return FAIL;
01079 }
01080
01081
01082
01083
01084 node n1;
01085 node n2;
01086 forall( n1, graphPath )
01087 {
01088 Configuration conf = G.inf(n1);
01089 path.AppendPoint( conf );
01090 n2 = graphPath.succ(n1);
01091 if (n2 == NULL)
01092 continue;
01093
01094 edge e;
01095 forall_inout_edges(e, n1)
01096
01097
01098 {
01099 if (G.opposite(n1, e) == n2)
01100 {
01101 int nStep = 0;
01102 int dir = -1;
01103 Fragment& frag = edgePath[e];
01104 int nFirst = frag.size();
01105 if (conf == frag[frag[0]])
01106 {
01107 nFirst = 0;
01108 dir = 1;
01109 }
01110 for (int i=1; i<(frag.size()-1); i++)
01111 {
01112 nStep += dir;
01113 list_item it = frag[nFirst+nStep];
01114 conf = frag[it];
01115
01116 path.AppendPoint( conf );
01117 }
01118 break;
01119 }
01120 }
01121 }
01122
01123
01124 return PASS;
01125 }
01126
01127
01128
01129 typedef struct
01130 {
01131 Configuration conf;
01132 PA_Points edge;
01133 } VertexInfoInTree;
01134
01135 #define ERR_FAIL 0xff
01136 #define ERR_SUCCESS 0x00
01137 #define ERR_TIMEOUT 0x10
01138 #define ERR_ILLPARAMETER 0x20
01139
01140
01141 PL_RGD_RRT::PL_RGD_RRT()
01142 {
01143 m_rootVert = NULL;
01144 m_goalVert = NULL;
01145 }
01146
01147 PL_RGD_RRT::~PL_RGD_RRT()
01148 {
01149 if ( m_rootVert != NULL )
01150 ClearTree();
01151 }
01152
01153 bool PL_RGD_RRT::DrawExplicit () const
01154 {
01155 double Xcor, Ycor, Zcor;
01156
01157 Semaphore semaphore( guid );
01158 semaphore.Lock();
01159
01160
01161 glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
01162 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
01163 BOOL lightingState = glIsEnabled( GL_LIGHTING );
01164 glDisable( GL_LIGHTING );
01165 glShadeModel( GL_SMOOTH );
01166 glPointSize(5.0f);
01167
01168 if (m_vertices.size() )
01169 {
01170 int i;
01171
01172
01173 glBegin(GL_POINTS);
01174 for(i = 0; i<m_vertices.size(); i++)
01175 {
01176 vertex vert;
01177 VertexInfoInTree *info;
01178 vert = m_vertices[i];
01179 info = (VertexInfoInTree *)((dynamic_trees &)m_trajTree).vertex_inf(vert);
01180
01181 Configuration conf = info->conf;
01182 Xcor = conf[0];
01183 Ycor = conf[1];
01184 Zcor = conf[2];
01185
01186 if ((i==0) || (i==(m_vertices.size()-1)))
01187 glColor3f(0.0f,0.0f,1.0f);
01188 else
01189 glColor3f(1.0f,1.0f,0.0f);
01190 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
01191 }
01192 glEnd();
01193
01194 glBegin(GL_LINES);
01195 for(i = 1; i<m_vertices.size(); i++)
01196 {
01197 vertex vert, parentVert;
01198 VertexInfoInTree *info, *parentInfo;
01199
01200 vert = m_vertices[i];
01201 parentVert = ((dynamic_trees &)m_trajTree).parent(vert);
01202 info = (VertexInfoInTree *)((dynamic_trees &)m_trajTree).vertex_inf(vert);
01203 parentInfo = (VertexInfoInTree *)((dynamic_trees &)m_trajTree).vertex_inf(parentVert);
01204
01205 Configuration conf = info->conf;
01206 Configuration parentConf = parentInfo->conf;
01207
01208 Xcor = conf[0];
01209 Ycor = conf[1];
01210 Zcor = conf[2];
01211 glColor3f(1.0f,0.5f,0.0f);
01212 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
01213
01214 Xcor = parentConf[0];
01215 Ycor = parentConf[1];
01216 Zcor = parentConf[2];
01217 glColor3f(1.0f,0.0f,0.0f);
01218 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
01219 }
01220 glEnd();
01221 }
01222
01223
01224 if( lightingState != FALSE )
01225 {
01226 glEnable( GL_LIGHTING );
01227 }
01228
01229 semaphore.Unlock();
01230
01231
01232
01233 return true;
01234 }
01235
01236 bool PL_RGD_RRT::Plan ()
01237 {
01238 srand( (unsigned)time( NULL ) );
01239
01240 path.Clear();
01241
01242
01243 StartTimer();
01244
01245 Configuration startConf = GetStartConfig();
01246 CreateTree(startConf);
01247
01248 int result = ERR_FAIL;
01249 bool pathFound = false;
01250 m_goalVert = NULL;
01251
01252 int repeatNum = 0;
01253 while ((!pathFound) && (result != ERR_TIMEOUT))
01254 {
01255 PA_Points localPath;
01256 Configuration randConf = PL_RGD_PRM::GenerateRandomConfig();
01257 vertex fromVert = FindClosestInTree(randConf);
01258 Configuration fromConf = GetConfigurationFromTree(fromVert);
01259 Configuration toConf;
01260
01261 result = Extend(fromConf, toConf, randConf, localPath);
01262 if (result == ERR_SUCCESS)
01263 {
01264 fromVert = AddNodeInTree(fromVert, toConf, localPath);
01265
01266 if (ConnectToGoal() == ERR_SUCCESS)
01267 {
01268 pathFound = true;
01269 }
01270 }
01271
01272
01273
01274
01275 if ( HasTimeLimitExpired() )
01276 {
01277 break;
01278 }
01279
01280 }
01281
01282
01283 if (pathFound)
01284 {
01285 assert(m_goalVert != NULL);
01286 RetrievePath(m_goalVert);
01287 return true;
01288 }
01289
01290 return false;
01291 }
01292
01293 #define LEN_STEP_SIZE 10
01294 #define MAX_CONF_RETRY 10
01295 int PL_RGD_RRT::Extend(Configuration &fromConf, Configuration &toConf, Configuration dirConf, PA_Points &localPath)
01296 {
01297 std::vector<Frame> edgeTraj;
01298 localPath.Clear();
01299
01300 double pathLen = 0;
01301 bool trajExtracted = true;
01302
01303
01304 double dist = Distance(fromConf, dirConf);
01305 if (dist > LEN_STEP_SIZE)
01306 toConf = fromConf * (1-LEN_STEP_SIZE/dist) + dirConf * (LEN_STEP_SIZE/dist);
01307 else
01308 toConf = dirConf;
01309
01310 bool result = false;
01311 int retry = 0;
01312 while ( (!result) && (retry < MAX_CONF_RETRY) )
01313 {
01314 result = GetSatisfiedConfiguration( toConf );
01315 retry ++;
01316 }
01317
01318 if (!result)
01319 {
01320 return ERR_FAIL;
01321 }
01322 if ( IsInterfering(fromConf, toConf) == false)
01323 {
01324 for (int i=0; i<edgeFrag->size(); i++)
01325 {
01326 list_item itt = edgeFrag->get_item(i);
01327 Configuration conf = edgeFrag->contents(itt);
01328 localPath.AppendPoint(conf);
01329 }
01330 edgeFrag->clear();
01331
01332 return ERR_SUCCESS;
01333 }
01334
01335 return ERR_FAIL;
01336 }
01337
01338
01339 int PL_RGD_RRT::ConnectToGoal()
01340 {
01341 Configuration goalConf = GetGoalConfig();
01342 Frame goalPose = GetToolFrame(goalConf);
01343 bool result = true;
01344 if (useGoalPose)
01345 {
01346 result = false;
01347 int retry = 0;
01348 while ( (!result) && (retry++<MAX_CONF_RETRY) && (!HasTimeLimitExpired()))
01349 {
01350 result = GenerateRandomConfigForPose(goalConf, goalPose);
01351 }
01352 }
01353
01354 vertex fromVert = NULL;
01355 if (result)
01356 {
01357 fromVert = FindClosestInTree(goalConf);
01358 }
01359 if (fromVert == NULL)
01360 {
01361 result = false;
01362 }
01363
01364 if (result)
01365 {
01366 Configuration fromConf = GetConfigurationFromTree(fromVert);
01367 if (!IsInterfering(fromConf, goalConf))
01368 {
01369 PA_Points localPath;
01370 for (int i=0; i<edgeFrag->size(); i++)
01371 {
01372 list_item itt = edgeFrag->get_item(i);
01373 Configuration conf = edgeFrag->contents(itt);
01374 localPath.AppendPoint( conf );
01375 }
01376 edgeFrag->clear();
01377 m_goalVert = AddNodeInTree(fromVert, goalConf, localPath);
01378 return ERR_SUCCESS;
01379 }
01380 }
01381 return ERR_FAIL;
01382 }
01383
01384 bool PL_RGD_RRT::CreateTree(Configuration &conf)
01385 {
01386 if (m_rootVert != NULL)
01387 {
01388 ClearTree();
01389 }
01390
01391 VertexInfoInTree *newNode = new VertexInfoInTree;
01392 newNode->conf = conf;
01393
01394 Semaphore semaphore( guid );
01395 semaphore.Lock();
01396 m_rootVert = m_trajTree.make(newNode);
01397 m_vertices.push_back(m_rootVert);
01398 semaphore.Unlock();
01399
01400 return true;
01401 }
01402
01403 void PL_RGD_RRT::ClearTree()
01404 {
01405 Semaphore semaphore( guid );
01406 semaphore.Lock();
01407 for (int i=0; i<m_vertices.size(); i++)
01408 {
01409 VertexInfoInTree *info;
01410 info = (VertexInfoInTree *)m_trajTree.vertex_inf(m_vertices[i]);
01411 delete info;
01412 }
01413
01414 m_trajTree.clear();
01415 m_vertices.clear();
01416 m_rootVert = NULL;
01417 semaphore.Unlock();
01418 }
01419
01420 vertex PL_RGD_RRT::AddNodeInTree(vertex parentVertex, Configuration &childConf, PA_Points &localPath)
01421 {
01422 VertexInfoInTree *newNode = new VertexInfoInTree;
01423 newNode->conf = childConf;
01424 CopyPath(newNode->edge, localPath);
01425
01426 Semaphore semaphore( guid );
01427 semaphore.Lock();
01428 vertex newVert = m_trajTree.make(newNode);
01429 m_vertices.push_back(newVert);
01430 m_trajTree.link(newVert, parentVertex, 1);
01431 semaphore.Unlock();
01432
01433 return newVert;
01434 }
01435
01436 vertex PL_RGD_RRT::FindClosestInTree(Configuration &conf)
01437 {
01438 if (m_vertices.size() == 0)
01439 return NULL;
01440
01441 VertexInfoInTree *info;
01442 double minDist, currDist;
01443 int minIndex=0;
01444
01445 info = (VertexInfoInTree *)m_trajTree.vertex_inf(m_vertices[0]);
01446 minDist = Distance(info->conf, conf);
01447 minIndex = 0;
01448
01449 for (int i=1; i<m_vertices.size(); i++)
01450 {
01451 info = (VertexInfoInTree *)m_trajTree.vertex_inf(m_vertices[i]);
01452 currDist = Distance(info->conf, conf);
01453 if (currDist < minDist)
01454 {
01455 minDist = currDist;
01456 minIndex = i;
01457 }
01458 }
01459
01460 return m_vertices[minIndex];
01461 }
01462
01463 Configuration& PL_RGD_RRT::GetConfigurationFromTree(vertex vert)
01464 {
01465 VertexInfoInTree *info;
01466 info = (VertexInfoInTree *)m_trajTree.vertex_inf(vert);
01467 return info->conf;
01468 }
01469
01470 double PL_RGD_RRT::Distance(const Configuration &conf1, const Configuration &conf2)
01471 {
01472 double dist = 0;
01473 VectorN jointDiff = collisionDetector->JointDisplacement(conf1, conf2);
01474 for(int i = 0; i < jointDiff.Length(); i++)
01475 {
01476 dist += (jointDiff[i])*(jointDiff[i]);
01477 }
01478 return sqrt(dist);
01479 }
01480
01481 PA_Points& PL_RGD_RRT::GetPathFromTree(vertex vert)
01482 {
01483 VertexInfoInTree *info;
01484 info = (VertexInfoInTree *)m_trajTree.vertex_inf(vert);
01485 return info->edge;
01486 }
01487
01488 void PL_RGD_RRT::RetrievePath(vertex &goalVert)
01489 {
01490 vertex currVert = goalVert;
01491 while (currVert != NULL)
01492 {
01493 InsertPath(path, GetPathFromTree(currVert));
01494 currVert = m_trajTree.parent(currVert);
01495 }
01496 }
01497
01498 void PL_RGD_RRT::AppendPath(PA_Points &collect, PA_Points &local)
01499 {
01500 for (int i=0; i<local.Size(); i++)
01501 {
01502 collect.AppendPoint(local[i]);
01503 }
01504 }
01505
01506 void PL_RGD_RRT::AppendPath(PA_Points &collect, PA_Points *local)
01507 {
01508 for (int i=0; i<local->Size(); i++)
01509 {
01510 collect.AppendPoint(local->GetPoint(i));
01511 }
01512 }
01513
01514 void PL_RGD_RRT::InsertPath(PA_Points &target, PA_Points &source)
01515 {
01516 int nLen = source.Size()-1;
01517 if ( target.Size() != 0 )
01518 {
01519 nLen = nLen - 1;
01520 }
01521 for( int i = nLen; i >= 0; i-- )
01522 {
01523 target.AppendPointToBeginning( source[ i ] ) ;
01524 }
01525 }
01526
01528 PL_RGD_Constraint::PL_RGD_Constraint()
01529 {
01530 m_strategy = STRATEGY_RRT;
01531 }
01532
01533 void PL_RGD_Constraint::SetStrategy(int strategy)
01534 {
01535 if (m_strategy != strategy)
01536 {
01537 path.Clear();
01538 if (m_strategy == STRATEGY_RRT)
01539 {
01540 this->ClearTree();
01541 }
01542 else
01543 {
01544 this->ClearGraph();
01545 }
01546 }
01547 m_strategy = strategy;
01548 }
01549
01550 int PL_RGD_Constraint::GetStrategy()
01551 {
01552 return m_strategy;
01553 }
01554
01555 bool PL_RGD_Constraint::DrawExplicit () const
01556 {
01557 if (m_strategy == STRATEGY_RRT)
01558 return PL_RGD_RRT::DrawExplicit();
01559 else
01560 return PL_RGD_PRM::DrawExplicit();
01561 }
01562
01563 bool PL_RGD_Constraint::Plan ()
01564 {
01565 if (m_strategy == STRATEGY_RRT)
01566 return PL_RGD_RRT::Plan();
01567 else
01568 return PL_RGD_PRM::Plan();
01569 }
01570