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_PRM_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
00021 double (PL_PRM_ClosedChain::*costFunc)(const Configuration &p1, const Frame &pose) const = &PL_PRM_ClosedChain::Error1;
00022
00023 PL_PRM_ClosedChain::PL_PRM_ClosedChain()
00024 {
00025 edgePath.init(G);
00026 edgeFrag = new Fragment;
00027
00028
00029 planner = new LocalPlannerClosed;
00030 pCollisionDetector = NULL;
00031 useJacobian = false;
00032 usePlanarConstraint = false;
00033 useOrientConstraint = false;
00034 useGoalPose = false;
00035 }
00036
00037 PL_PRM_ClosedChain::~PL_PRM_ClosedChain()
00038 {
00039 if(pCollisionDetector)
00040 {
00041 delete pCollisionDetector;
00042 }
00043 delete planner;
00044
00045 edgeFrag->clear();
00046 delete edgeFrag;
00047 }
00048
00049 void PL_PRM_ClosedChain::SetCollisionDetector(CD_BasicStyle* collisionDetector)
00050 {
00051
00052 PL_PRM::SetCollisionDetector( collisionDetector );
00053
00054 if (pCollisionDetector != NULL)
00055 delete pCollisionDetector;
00056
00057 pCollisionDetector = new CD_Swiftpp( *(collisionDetector->GetUniverse()) );
00058 planner->SetCollisionDetector(pCollisionDetector);
00059 pCollisionDetector->DeactivateFrames(1, pCollisionDetector->DOF());
00060 }
00061
00062 bool PL_PRM_ClosedChain::Plan ()
00063 {
00064 srand( (unsigned)time( NULL ) );
00065
00066 StartTimer();
00067 if (usePlanarConstraint)
00068 {
00069 UpdatePlanarConstraint();
00070 }
00071 else if (useOrientConstraint)
00072 {
00073 UpdateOrientConstraint();
00074 }
00075
00076 if (useJacobian)
00077 {
00078 planner->SetTimeLimitInSeconds(100);
00079 Configuration q1 = GetStartConfig();
00080 Configuration q2 = GetGoalConfig();
00081 planner->SetStartConfig(q1);
00082 planner->SetGoalConfig(q2);
00083
00084 double dObstacleTol = 0.01;
00085 double dHomogain = 2.0;
00086 double dPathTol = 0.5;
00087 int nObstacleNum = 2;
00088
00089 planner->SetObstacleTolerance(dObstacleTol);
00090 planner->SetNumObstaclePt(nObstacleNum);
00091 planner->SetHomogeneousGain(dHomogain);
00092 planner->SetPathTolerence(dPathTol);
00093 planner->SetOrientation(false);
00094 planner->SetPosition(true);
00095
00096
00097 bool result = planner->Plan();
00098
00099 PA_Points *plannerPath = (PA_Points *)planner->GetPath();
00100 path = *plannerPath;
00101
00102
00103
00104 return result;
00105 }
00106 else if (useGoalPose)
00107 {
00108 Configuration conf;
00109 Frame goalPose = GetToolFrame( GetGoalConfig() );
00110 bool Result = false;
00111 double oldTimeLimit = GetTimeLimitInSeconds();
00112 double timeLimit = 100;
00113
00114 while (Result == false)
00115 {
00116 Result = GenerateRandomConfigForPose(conf, goalPose);
00117 if (Result)
00118 {
00119 timeLimit = GetTimeElapsedInSeconds() + 20;
00120 oldTimeLimit = GetTimeLimitInSeconds();
00121 if (timeLimit > oldTimeLimit)
00122 timeLimit = oldTimeLimit;
00123 SetTimeLimitInSeconds( timeLimit );
00124 PL_PRM::SetGoalConfig(conf);
00125 Result = Plan_As_Usual();
00126 if (GetTimeLimitInSeconds() != timeLimit)
00127 break;
00128 else
00129 SetTimeLimitInSeconds( oldTimeLimit );
00130 }
00131 if (Result)
00132 return true;
00133 if ( HasTimeLimitExpired() )
00134 {
00135 return false;
00136 }
00137 }
00138 return false;
00139
00140
00141 }
00142 else
00143 {
00144 return Plan_As_Usual();
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
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 Frame PL_PRM_ClosedChain::GetToolFrame( const Configuration& config ) const
00189 {
00190 Frame toolFrame = Matrix4x4();
00191 if ( collisionDetector != NULL )
00192 {
00193 FrameManager* frameManager = collisionDetector->GetFrameManager();
00194 collisionDetector->SetConfiguration( config );
00195 R_OpenChain * robot = (R_OpenChain *)collisionDetector->GetRobot(0);
00196 int toolFrameID = robot->GetToolFrame(0);
00197 if (toolFrameID == -1)
00198 {
00199 toolFrameID = collisionDetector->JointFrameNum(collisionDetector->DOF()-1);
00200 toolFrame = frameManager->GetWorldFrame( toolFrameID );
00201 }
00202 else
00203 {
00204 toolFrame = *(frameManager->GetFrameRef(toolFrameID));
00205 toolFrame = frameManager->GetTransformRelative(collisionDetector->DOF(), 0) * toolFrame;
00206 }
00207 }
00208 return toolFrame;
00209 }
00210
00211 bool PL_PRM_ClosedChain::Plan_As_Usual ()
00212 {
00213 PRM_StateMachineType currentState = lastPlanningState;
00214
00215
00216
00217 if ( lastPlanningState == PRM_FAILURE )
00218 {
00219 currentState = PRM_START;
00220 }
00221
00222
00223
00224
00225
00226 Semaphore semaphore( guid );
00227 if( this->m_UseSemaphores == true )
00228 {
00229 semaphore.Lock();
00230 }
00231
00232
00233
00234 if ( (currentState != PRM_DONE ) && (currentState != PRM_FAILURE) )
00235 {
00236 if ( startNode == goalNode )
00237 {
00238
00239 currentState = PRM_DONE;
00240
00241
00242 path.Clear();
00243 path.AppendPoint( GetStartConfig() );
00244 }
00245 else if ( (PL_PRM::IsInterfering(startNode)) || (PL_PRM::IsInterfering(goalNode)) )
00246 {
00247
00248
00249 currentState = PRM_FAILURE;
00250 }
00251 }
00252 if( this->m_UseSemaphores == true )
00253 {
00254 semaphore.Unlock();
00255 }
00256
00257
00258 diagonal_squared = GetCspaceRange();
00259
00260
00261 while (( currentState != PRM_DONE ) && ( currentState != PRM_FAILURE ))
00262
00263 {
00264 SuccessResultType success;
00265
00266 if( this->m_UseSemaphores == true )
00267 {
00268 semaphore.Lock();
00269 }
00270
00271 switch ( currentState )
00272 {
00273 case PRM_BUILD_INIT_ROADMAP :
00274 success = BuildInitRoadMap();
00275 break;
00276 case PRM_FIND_PATH :
00277 success = FindPath();
00278 break;
00279 case PRM_VERIFY_PATH :
00280 success = VerifyPath();
00281 break;
00282 case PRM_TRANSLATE_PATH :
00283 success = TranslatePath();
00284 break;
00285 case PRM_ENHANCE_ROADMAP :
00286 success = EnhanceRoadMap();
00287 break;
00288 default :
00289
00290
00291 success = PASS;
00292 }
00293
00294
00295
00296 if ( success == TIMER_EXPIRED )
00297 {
00298
00299 break;
00300 }
00301
00302
00303 switch ( currentState )
00304 {
00305 case PRM_START :
00306
00307 currentState = PRM_BUILD_INIT_ROADMAP;
00308 break;
00309 case PRM_BUILD_INIT_ROADMAP :
00310
00311 currentState = PRM_FIND_PATH;
00312 break;
00313 case PRM_FIND_PATH :
00314 if ( success == PASS )
00315 {
00316
00317 currentState = PRM_VERIFY_PATH;
00318 }
00319 else
00320 {
00321
00322 currentState = PRM_ENHANCE_ROADMAP;
00323
00324
00325 }
00326 break;
00327 case PRM_VERIFY_PATH :
00328 if ( success == PASS )
00329 {
00330
00331
00332 currentState = PRM_TRANSLATE_PATH;
00333 }
00334 else
00335 {
00336
00337
00338 currentState = PRM_FIND_PATH;
00339 }
00340 break;
00341 case PRM_TRANSLATE_PATH :
00342
00343 currentState = PRM_DONE;
00344 break;
00345 case PRM_ENHANCE_ROADMAP :
00346
00347 currentState = PRM_FIND_PATH;
00348 break;
00349 default :
00350
00351 ASSERT( FALSE );
00352 }
00353
00354
00355 if( this->m_UseSemaphores == true )
00356 {
00357 semaphore.Unlock();
00358 }
00359 }
00360
00361
00362
00363 lastPlanningState = currentState;
00364
00365
00366 if ( currentState == PRM_DONE )
00367 {
00368
00369
00370
00371 if( this->m_UseSemaphores == true )
00372 {
00373 semaphore.Unlock();
00374 }
00375
00376 return true;
00377 }
00378 else
00379 {
00380
00381 graphPath.clear();
00382
00383
00384 path.Clear();
00385 path.AppendPoint( GetStartConfig() );
00386
00387
00388 if( this->m_UseSemaphores == true )
00389 {
00390 semaphore.Unlock();
00391 }
00392
00393 return false;
00394 }
00395 }
00396
00397 bool PL_PRM_ClosedChain::GetSatisfactoryConfiguration(Configuration &conf, Frame &pose) const
00398 {
00399 int i,j;
00400 Configuration q;
00401 q = conf;
00402 i = 0; j = 0;
00403 int MAX_I = MAX_ITERATION * MAX_RETRY;
00404 int MAX_J = MAX_RETRY;
00405 double err_q = (this->*costFunc)(q, pose);
00406 while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00407 {
00408 i++; j++;
00409 double deviation = DEF_NEIGHBOR;
00410 if (err_q < 1)
00411 deviation *= err_q;
00412 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00413 if ((this->*costFunc)(q_next, pose) < err_q)
00414 {
00415 j = 0;
00416 q = q_next;
00417 err_q = (this->*costFunc)(q, pose);
00418 }
00419 if ( HasTimeLimitExpired() )
00420 {
00421 return false;
00422 }
00423 }
00424
00425 conf = q;
00426 return (err_q <= DEF_ERR_TOLERANCE);
00427 }
00428
00429 bool PL_PRM_ClosedChain::GetClosedConfiguration(Configuration &conf)
00430 {
00431 UpdatePlanarConstraint();
00432 UpdateOrientConstraint();
00433
00434 int i,j;
00435 Configuration q;
00436 q = conf;
00437 i = 0; j = 0;
00438 int MAX_I = MAX_ITERATION * MAX_RETRY;
00439 int MAX_J = MAX_RETRY;
00440 double err_q = Error(q);
00441 while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00442 {
00443 i++; j++;
00444 double deviation = DEF_NEIGHBOR;
00445 if (err_q < 1)
00446 deviation *= err_q;
00447 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00448 if (Error(q_next) < err_q)
00449 {
00450 j = 0;
00451 q = q_next;
00452 err_q = Error(q);
00453 }
00454 }
00455
00456 conf = q;
00457 return (err_q <= DEF_ERR_TOLERANCE);
00458 }
00459
00460 bool PL_PRM_ClosedChain::GenerateRandomConfigForPose (Configuration &conf, Frame &endEffPose)
00461 {
00462 conf = PL_PRM::GenerateRandomConfig();
00463 costFunc = &PL_PRM_ClosedChain::Error1;
00464
00465 bool Result = GetSatisfactoryConfiguration(conf, endEffPose);
00466 if (Result)
00467 {
00468 Result = !IsInterfering(conf);
00469 }
00470 return Result;
00471 }
00472
00473 Configuration PL_PRM_ClosedChain::GenerateRandomConfig () const
00474 {
00475 Configuration conf;
00476 Frame endEffPose;
00477 conf = PL_PRM::GenerateRandomConfig();
00478 if (usePlanarConstraint)
00479 {
00480 endEffPose = planeDesired;
00481 costFunc = &PL_PRM_ClosedChain::Error3;
00482 }
00483 else if (useOrientConstraint)
00484 {
00485 endEffPose = orientDesired;
00486 costFunc = &PL_PRM_ClosedChain::Error4;
00487 }
00488 else
00489 {
00490 costFunc = &PL_PRM_ClosedChain::Error2;
00491 }
00492
00493 GetSatisfactoryConfiguration(conf, endEffPose);
00494
00495 return conf;
00496 }
00497
00498 Configuration PL_PRM_ClosedChain::GenerateRandomConfig ( const Configuration& seed, const double& std_dev ) const
00499 {
00500 Configuration conf;
00501 Frame endEffPose;
00502 conf = PL_PRM::GenerateRandomConfig(seed, std_dev);
00503 if (usePlanarConstraint)
00504 {
00505 endEffPose = planeDesired;
00506 costFunc = &PL_PRM_ClosedChain::Error3;
00507 }
00508 else if (useOrientConstraint)
00509 {
00510 endEffPose = orientDesired;
00511 costFunc = &PL_PRM_ClosedChain::Error4;
00512 }
00513 else
00514 {
00515 costFunc = &PL_PRM_ClosedChain::Error2;
00516 }
00517
00518 GetSatisfactoryConfiguration(conf, endEffPose);
00519 return conf;
00520 }
00521
00522 void PL_PRM_ClosedChain::ConnectEdgesFull( const node& newnode, const double& radius_squared )
00523 {
00524
00525 assert( connectIDp != NULL );
00526
00527
00528 Configuration nodeconfig = G.inf(newnode);
00529
00530 node n1;
00531
00532
00533 node_pq<double> neighbours(G);
00534 forall_nodes( n1, G)
00535 {
00536 if ( newnode != n1)
00537 {
00538 double edgelength_squared = Distance( nodeconfig, G.inf(n1) );
00539
00540 if ( edgelength_squared <= radius_squared )
00541 {
00542
00543 neighbours.insert( n1, edgelength_squared );
00544 }
00545 }
00546 }
00547
00548
00549 (*connectIDp)[newnode] = NIL_ID;
00550
00551
00552 list<int> connectIDs;
00553
00554
00555
00556 while ( !neighbours.empty() )
00557 {
00558
00559 node neighbour = neighbours.find_min();
00560 double dist_sq = neighbours.inf( neighbour );
00561 neighbours.del( neighbour );
00562
00563
00564
00565
00566 if ( ((*connectIDp)[neighbour] == NIL_ID) ||
00567 ( ((*connectIDp)[neighbour] != (*connectIDp)[newnode]) &&
00568 ( !NodeInConnectionList(neighbour, connectIDs) ) )
00569 )
00570 {
00571 edgeFrag->clear();
00572
00573 if ( !IsInterfering( nodeconfig, G.inf(neighbour) ) )
00574 {
00575 double edgelength = sqrt( dist_sq );
00576 edge newedge = G.new_edge( newnode, neighbour, edgelength );
00577 edgeChecked[newedge] = TRUE;
00578 edgePath[newedge] = *edgeFrag;
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 if ( (*connectIDp)[neighbour] != NIL_ID )
00591
00592 {
00593 if ( (*connectIDp)[newnode] == NIL_ID )
00594 {
00595
00596 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
00597 }
00598 else if ( (*connectIDp)[neighbour] < (*connectIDp)[newnode] )
00599 {
00600
00601
00602
00603
00604 connectIDs.push( (*connectIDp)[newnode] );
00605
00606
00607 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
00608 }
00609 else
00610 {
00611
00612
00613
00614 connectIDs.push( (*connectIDp)[neighbour] );
00615
00616
00617 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
00618 }
00619 }
00620 else
00621
00622 {
00623 if ( (*connectIDp)[newnode] != NIL_ID )
00624 {
00625
00626 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
00627 }
00628 else
00629 {
00630
00631
00632 (*connectIDp)[newnode] = baseConnectID;
00633 (*connectIDp)[neighbour] = baseConnectID;
00634
00635
00636 baseConnectID++;
00637 }
00638 }
00639
00640 }
00641 else
00642 {
00643 edgeFrag->clear();
00644
00645
00646 if ( useMidPts )
00647 {
00648 Configuration midpt = GetMidPoint( nodeconfig, G.inf(neighbour) );
00649 config_seeds.append( midpt );
00650 }
00651 }
00652
00653 }
00654
00655 }
00656
00657
00658
00659 if ( ((*connectIDp)[newnode] != NIL_ID) && ( !connectIDs.empty() ) )
00660 {
00661
00662
00663 int newID = (*connectIDp)[newnode];
00664
00665 forall_nodes( n1, G )
00666 {
00667 if ( ((*connectIDp)[n1] != newID ) && (NodeInConnectionList( n1, connectIDs )) )
00668 {
00669 (*connectIDp)[n1] = newID;
00670 }
00671 }
00672 }
00673
00674 return;
00675 }
00676
00677 bool PL_PRM_ClosedChain::MakeItClosed(Configuration &conf) const
00678 {
00679 int i,j;
00680 Configuration q;
00681 q = conf;
00682 i = 0; j = 0;
00683 int MAX_I = MAX_ITERATION * MAX_RETRY;
00684 int MAX_J = MAX_RETRY;
00685 double err_q = Error(q);
00686 while ((i<MAX_I) && (j<MAX_J) && (err_q>DEF_ERR_TOLERANCE))
00687 {
00688 i++; j++;
00689 double deviation = DEF_NEIGHBOR;
00690 if (err_q < 1)
00691 deviation *= err_q;
00692 Configuration q_next = PL_PRM::GenerateRandomConfig(q, deviation);
00693 if (Error(q_next) < err_q)
00694 {
00695 j = 0;
00696 q = q_next;
00697 err_q = Error(q);
00698 }
00699 if ( HasTimeLimitExpired() )
00700 {
00701 return false;
00702 }
00703 }
00704
00705 conf = q;
00706 return (err_q <= DEF_ERR_TOLERANCE);
00707 }
00708
00709 bool PL_PRM_ClosedChain::IsClosed(const Configuration &conf) const
00710 {
00711 return (Error(conf) <= DEF_ERR_TOLERANCE);
00712 }
00713
00714 bool PL_PRM_ClosedChain::IsInterfering ( const Configuration& q1, const Configuration& q2 ) const
00715 {
00716 int i, j, k;
00717 i = 0; j = 0; k = 0;
00718 Configuration q_last = q1;
00719
00720 edgeFrag->append(q1);
00721 int MAX_I = MAX_ITERATION * MAX_RETRY * MAX_RETRY2;
00722 int MAX_J = MAX_RETRY;
00723 int MAX_K = MAX_RETRY2;
00724 double distToLast = sqrt(Distance(q_last, q2));
00725 bool result = false;
00726 while ((i<MAX_I) && (j<MAX_J) && (k<MAX_K) && (distToLast>DEF_DIST_TOLERANCE))
00727 {
00728 i++; j++;
00729
00730 Configuration q_mid = q_last*(1-(DEF_DIST_TOLERANCE/distToLast)) + q2*(DEF_DIST_TOLERANCE/distToLast);
00731 if (MakeItClosed(q_mid))
00732 {
00733 j = 0; k++;
00734 if (PL_PRM::IsInterfering(q_mid))
00735 {
00736 result = true;
00737 break;
00738 }
00739 if (Distance(q_mid, q2) < distToLast*distToLast)
00740 {
00741 k = 0;
00742 edgeFrag->append(q_mid);
00743 q_last = q_mid;
00744 distToLast = sqrt(Distance(q_last, q2));
00745 }
00746 }
00747 if ( HasTimeLimitExpired() )
00748 {
00749 result = true;
00750 break;
00751 }
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 if ((!result) && (distToLast<=DEF_DIST_TOLERANCE))
00763 {
00764 edgeFrag->append(q2);
00765 return false;
00766 }
00767 else
00768 {
00769 edgeFrag->clear();
00770 return true;
00771 }
00772 }
00773
00774 bool PL_PRM_ClosedChain::IsInterfering ( const Configuration& c1 ) const
00775 {
00776 if (!IsClosed(c1))
00777 return true;
00778 if (PL_PRM::IsInterfering(c1))
00779 return true;
00780 return false;
00781 }
00782
00783
00784 void PL_PRM_ClosedChain::UpdatePlanarConstraint()
00785 {
00786 planeDesired = GetToolFrame( GetStartConfig() );
00787 }
00788
00789 void PL_PRM_ClosedChain::UpdateOrientConstraint()
00790 {
00791
00792 orientDesired = Matrix4x4::Identity();
00793 orientDesired.Rotate(Vector4(1, 0, 0), -90);
00794
00795
00796 }
00797
00798
00799 double PL_PRM_ClosedChain::Error1(const Configuration &p1, const Frame &pose) const
00800 {
00801 double distance;
00802
00803 Frame toolFrame = GetToolFrame( p1 );
00804 if (!useOrientConstraint)
00805 {
00806 Vector4 offset = pose.GetTranslationVector() - toolFrame.GetTranslationVector();
00807 distance = offset.Magnitude();
00808 }
00809 else
00810 {
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00823 Vector4 PX(1, 0, 0);
00824 Vector4 PY(0, 1, 0);
00825 Vector4 PZ(0, 0, 1);
00826
00827 Vector4 Pax = toolFrame * PX;
00828 Vector4 Pay = toolFrame * PY;
00829 Vector4 Paz = toolFrame * PZ;
00830
00831 Vector4 Pbx = pose * PX;
00832 Vector4 Pby = pose * PY;
00833 Vector4 Pbz = pose * PZ;
00834
00835
00836 Vector4 dx = Pax - Pbx;
00837 Vector4 dy = Pay - Pby;
00838 Vector4 dz = Paz - Pbz;
00839
00840
00841 double distance_sq = dx.MagSquared() + dy.MagSquared() + dz.MagSquared();
00842 distance = sqrt(distance_sq);
00843
00844 }
00845
00846 return distance;
00847 }
00848
00849
00850 double PL_PRM_ClosedChain::Error2(const Configuration &p1, const Frame &pose) const
00851 {
00852 Frame toolFrame = GetToolFrame( p1 );
00853 Vector4 offset = toolFrame.GetTranslationVector();
00854 offset[2] = 0;
00855 return offset.Magnitude();
00856 }
00857
00858
00859 double PL_PRM_ClosedChain::Error3(const Configuration &p1, const Frame &pose) const
00860 {
00861 Frame toolFrame = GetToolFrame( p1 );
00862
00863 #if 0 //plannar constraint
00864 return fabs(toolFrame(1, 3)-pose(1, 3));
00865
00866 #ifdef ABCD //sphere constraint without constraint
00867 double cx, cy, cz, radius;
00868 cx=15; cy=0; cz=5;
00869 radius = 12;
00870 Vector4 center(cx, cy, cz);
00871 Vector4 pos1 = toolFrame.GetTranslationVector();
00872 pos1 -= center;
00873 return sqrt((pos1.Magnitude() - radius)*(pos1.Magnitude() - radius));
00874 #endif
00875
00876 #else //ifdef ABCD
00877 double cx, cy, cz, radius;
00878 cx=15; cy=0; cz=5;
00879 radius = 12;
00880 Vector4 center(cx, cy, cz);
00881
00882 Vector4 pos1 = pose.GetTranslationVector();
00883 Vector4 desiredZ = center;
00884 desiredZ -= pos1;
00885 desiredZ.Normalize();
00886 desiredZ *= -(radius-1);
00887 desiredZ += center;
00888
00889 Vector4 pos2 = toolFrame.GetTranslationVector();
00890 Vector4 currentZ;
00891 currentZ[0] = toolFrame(0, 2);
00892 currentZ[1] = toolFrame(1, 2);
00893 currentZ[2] = toolFrame(2, 2);
00894 currentZ += pos2;
00895
00896 desiredZ -= currentZ;
00897 return desiredZ.Magnitude();
00898 #endif
00899 }
00900
00901
00902 double PL_PRM_ClosedChain::Error4(const Configuration &p1, const Frame &pose) const
00903 {
00904 Frame toolFrame = GetToolFrame( p1 );
00905 double yaw1, pitch1, roll1;
00906 double yaw2, pitch2, roll2;
00907 GetRotAngles(toolFrame, roll1, pitch1, yaw1);
00908 GetRotAngles(pose, roll2, pitch2, yaw2);
00909 return ((roll1-roll2)*(roll1-roll2) + (yaw1-yaw2)*(yaw1-yaw2)
00910 );
00911 }
00912
00913 double PL_PRM_ClosedChain::Error(const Configuration &p1) const
00914 {
00915 Frame toolFrame = GetToolFrame( p1 );
00916
00917 if (usePlanarConstraint)
00918 {
00919
00920
00921 return Error3(p1, toolFrame);
00922 }
00923 else if (useOrientConstraint)
00924 {
00925 double yaw1, pitch1, roll1;
00926 double yaw2, pitch2, roll2;
00927 GetRotAngles(toolFrame, roll1, pitch1, yaw1);
00928 GetRotAngles(orientDesired, roll2, pitch2, yaw2);
00929
00930 return ((roll1-roll2)*(roll1-roll2) + (yaw1-yaw2)*(yaw1-yaw2)
00931 );
00932 }
00933 else
00934 {
00935
00936 Vector4 offset = toolFrame.GetTranslationVector();
00937 offset[2] = 0;
00938 return offset.Magnitude();
00939 }
00940 }
00941
00942 void PL_PRM_ClosedChain::GetRotAngles( const Matrix4x4& frame, double& roll, double& pitch, double& yaw ) const
00943 {
00944
00945 double alpha, beta, gamma;
00946
00947
00948 beta = atan2( -frame(2,0) , sqrt( Sqr(frame(0,0)) + Sqr(frame(1,0)) ) );
00949 double cB = cos ( beta );
00950
00951
00952 if ( cB == 0.0 )
00953 {
00954 alpha = 0;
00955 if ( beta > 0 )
00956 {
00957 gamma = atan2( frame(0,1) , frame(1,1) );
00958 }
00959 else
00960 {
00961 gamma = -atan2( frame(0,1), frame(1,1) );
00962 }
00963 }
00964 else
00965 {
00966 alpha = atan2( frame(1,0) / cB , frame(0,0) / cB );
00967 gamma = atan2( frame(2,1) / cB , frame(2,2) / cB );
00968 }
00969
00970
00971
00972 yaw = Rad2Deg( alpha );
00973 pitch = Rad2Deg( beta );
00974 roll = Rad2Deg( gamma );
00975 }
00976
00977 SuccessResultType PL_PRM_ClosedChain::TranslatePath()
00978 {
00979
00980 path.Clear();
00981
00982
00983 if ( graphPath.empty() )
00984 {
00985
00986 path.AppendPoint( GetStartConfig() );
00987
00988
00989 return FAIL;
00990 }
00991
00992
00993
00994
00995 node n1;
00996 node n2;
00997 forall( n1, graphPath )
00998 {
00999 Configuration conf = G.inf(n1);
01000 path.AppendPoint( conf );
01001 n2 = graphPath.succ(n1);
01002 if (n2 == NULL)
01003 continue;
01004
01005 edge e;
01006 forall_inout_edges(e, n1)
01007
01008
01009 {
01010 if (G.opposite(n1, e) == n2)
01011 {
01012 int nStep = 0;
01013 int dir = -1;
01014 Fragment& frag = edgePath[e];
01015 int nFirst = frag.size();
01016 if (conf == frag[frag[0]])
01017 {
01018 nFirst = 0;
01019 dir = 1;
01020 }
01021 for (int i=1; i<(frag.size()-1); i++)
01022 {
01023 nStep += dir;
01024 list_item it = frag[nFirst+nStep];
01025 conf = frag[it];
01026
01027 path.AppendPoint( conf );
01028 }
01029 break;
01030 }
01031 }
01032 }
01033
01034
01035 return PASS;
01036 }
01037
01038 double LocalPlannerClosed::Distance(Configuration &conf1, Configuration &conf2)
01039 {
01040
01041 VectorN jointDiff;
01042 jointDiff = collisionDetector->JointDisplacement( conf1, conf2 );
01043
01044
01045 double distance = 0;
01046 for( int i = 0; i < jointDiff.Length(); i++ )
01047 {
01048 distance += Sqr(jointDiff[i] );
01049 }
01050
01051
01052 return sqrt(distance);
01053 }
01054
01055 bool LocalPlannerClosed::Plan()
01056 {
01057
01058 const CD_Swiftpp* pSwiftpp = dynamic_cast< const CD_Swiftpp* >( collisionDetector );
01059 if (pSwiftpp == NULL)
01060 {
01061 return false;
01062 }
01063
01064
01065 if ( collisionDetector->IsInterfering( GetStartConfig() ) )
01066 {
01067
01068
01069 return false;
01070 }
01071
01072
01073 StartTimer();
01074
01075
01076
01077
01078
01079 Configuration currentConfig, goalConfig, nextConfig, jointVelocity;
01080 currentConfig.SetNumDOF(m_nDof);
01081 nextConfig.SetNumDOF(m_nDof);
01082 jointVelocity.SetNumDOF(m_nDof);
01083 for (int i = 0; i < m_nDof; i++)
01084 {
01085 jointVelocity[i] = 0;
01086 }
01087 currentConfig = GetStartConfig();
01088 goalConfig = GetGoalConfig();
01089
01090 path.Clear();
01091 path.AppendPoint(currentConfig);
01092
01093
01094 CJacobian jacobian(*m_pRobot);
01095 jacobian.SetConfiguration(currentConfig);
01096
01097
01098 bool abort = false;
01099
01100 VectorN vEndEffVel(0, 0, 0);
01101
01102 double dist = Distance(currentConfig, goalConfig);
01103 while (dist > DEF_DIST_TOLERANCE )
01104 {
01105 jacobian.SetInterestPoint(m_nDof-1, m_frEndEffector, m_bPosition, m_bOrientation);
01106
01107
01108 Matrixmxn mJEnd, mJEndInv;
01109 mJEnd = *(jacobian.GetMatrix());
01110 mJEnd.Inverse(mJEndInv);
01111
01112 Matrixmxn mTemp(m_nDof, m_nDof);
01113 mTemp -= mJEndInv * mJEnd;
01114
01115
01116 jointVelocity = (goalConfig-currentConfig);
01117 if (dist > DEF_DIST_TOLERANCE)
01118 jointVelocity *= (DEF_DIST_TOLERANCE/dist);
01119 for (int i=0; i<m_nDof; i++)
01120 {
01121 double dValue = jointVelocity[i];
01122 jointVelocity[i] = Deg2Rad(dValue);
01123 }
01124 jointVelocity = mTemp * jointVelocity;
01125
01126
01127
01128
01129 if (GetClosestValues(currentConfig) != false)
01130 {
01131
01132 abort = true;
01133 break;
01134 }
01135
01136 double obsDirMag = 0;
01137
01138 if (m_vClosestPoints[0].distance <= m_dObsTol)
01139 {
01140
01141
01142 abort = true;
01143 break;
01144 }
01145
01146 else
01147 {
01148 VectorN vHomogeneousSolns;
01149 vHomogeneousSolns = ComputeHomogeneousTerm(jacobian, mJEnd, mJEndInv, vEndEffVel);
01150
01151
01152
01153 jointVelocity += vHomogeneousSolns;
01154 }
01155
01156
01157
01158
01159 CheckJointVelocities(jointVelocity);
01160 for (i=0; i<m_nDof; i++)
01161 {
01162 double dValue = jointVelocity[i];
01163 jointVelocity[i] = Rad2Deg(dValue);
01164 }
01165
01166
01167
01168
01169 nextConfig = currentConfig + jointVelocity;
01170 CheckJointLimits(nextConfig);
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181 if (collisionDetector->IsInterfering(nextConfig ) == false)
01182 {
01183
01184 if (currentConfig != nextConfig)
01185 {
01186 currentConfig = nextConfig;
01187 path.AppendPoint(currentConfig);
01188 dist = Distance(currentConfig, goalConfig);
01189
01190 }
01191 jacobian.SetConfiguration(currentConfig);
01192 }
01193 else
01194 {
01195
01196
01197 abort = true;
01198 break;
01199 }
01200
01201
01202
01203 if (HasTimeLimitExpired() != false)
01204 {
01205
01206
01207 abort = true;
01208 break;
01209 }
01210 }
01211
01212
01213 if (abort)
01214 {
01215
01216 }
01217 else
01218 {
01219 if (collisionDetector->IsInterferingLinear(currentConfig, goalConfig ) == false)
01220 {
01221 path.AppendPoint(goalConfig);
01222 }
01223
01224 }
01225 return (abort == false);
01226 }
01227
01228
01229