00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "synchronization/semaphore.h"
00012 #include "PL_Astar.h"
00013
00014
00015 #include <LEDA/node_map.h>
00016 #include <LEDA/node_pq.h>
00017
00018 #include "math/math2.h"
00019 #include <iosfwd>
00020 #include <iostream>
00021
00022 using std::endl;
00023
00024
00025
00026 const int DEFAULTNUMSTEPS = 40;
00027 const double DEFAULTWEIGHT = 0.9;
00028 const double COMPTOL = 1e-8;
00029
00030 static const char FILEEXT[] = ".a8";
00031 static const char FILEHEADER[] = "PL_ASTAR";
00032
00033
00034
00035
00036 PL_Astar::PL_Astar()
00037 {
00038
00039 strcpy( fileext, FILEEXT );
00040 strcpy( fileheader, FILEHEADER );
00041
00042
00043 openp = NULL;
00044
00045
00046 ClearGraph();
00047
00048
00049 weight = DEFAULTWEIGHT;
00050
00051
00052 SetDefaultStepSize();
00053
00054 TRACE("PL_Astar Default Constructor completed.\n");
00055
00056 }
00057
00058
00059 PL_Astar::~PL_Astar()
00060 {
00061
00062 if ( openp != NULL )
00063 {
00064 delete openp;
00065 }
00066
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076 void PL_Astar::ClearGraph()
00077 {
00078
00079 PL_GraphBase::ClearGraph();
00080
00081
00082 nodeExpanded.init(G,FALSE);
00083
00084 InitNewSearch();
00085 }
00086
00087
00088
00089
00090
00091
00092
00093 void PL_Astar::InitNewSearch()
00094 {
00095
00096 ClearGraphPath();
00097
00098
00099 pred.init(G,nil);
00100 dist.init(G,0);
00101
00102
00103 if ( openp == NULL )
00104 {
00105 openp = new node_pq<double>(G);
00106 }
00107 openp->clear();
00108
00109
00110 if ( startNode != nil )
00111 {
00112 openp->insert( startNode, 0 );
00113 dist[startNode] = 0;
00114 pred[startNode] = nil;
00115 }
00116
00117
00118 plan_success = TIMER_EXPIRED;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 bool PL_Astar::LoadContents( std::ifstream& infile )
00131 {
00132
00133 bool success = PL_GraphBase::LoadContents( infile );
00134 if ( !success )
00135 {
00136 return false;
00137 }
00138
00139
00140 infile >> stepsize;
00141 infile >> goalOnGrid >> weight;
00142
00143 InvertStepSize();
00144
00145
00146 node n0;
00147 forall_nodes( n0, G )
00148 {
00149 int nodeID;
00150 infile >> nodeID;
00151 infile >> nodeExpanded[n0];
00152 }
00153
00154
00155 InitNewSearch();
00156
00157 return true;
00158
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 bool PL_Astar::SaveContents ( std::ofstream& outfile ) const
00170 {
00171
00172 bool success = PL_GraphBase::SaveContents( outfile );
00173 if ( !success )
00174 {
00175 return false;
00176 }
00177
00178
00179 outfile << stepsize << endl;
00180 outfile << goalOnGrid << " " << weight << endl;
00181
00182
00183 node n1;
00184 forall_nodes( n1, G )
00185 {
00186 outfile << n1->id() << " " << nodeExpanded[n1] << endl;
00187 }
00188
00189
00190
00191 return true;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 bool PL_Astar::Plan ()
00201 {
00202
00203 if ( startNode == goalNode )
00204 {
00205 graphPath.clear();
00206 TranslatePath();
00207 plan_success = PASS;
00208 }
00209
00210
00211 if ( plan_success == PASS )
00212 {
00213 return true;
00214 }
00215 else if ( plan_success == FAIL )
00216 {
00217 return false;
00218 }
00219
00220
00221
00222 StartTimer();
00223
00224
00225 Semaphore semaphore( guid );
00226 semaphore.Lock();
00227
00228
00229 plan_success = FAIL;
00230
00231
00232
00233
00234
00235 while ( !openp->empty() )
00236 {
00237
00238 if ( HasTimeLimitExpired() )
00239 {
00240
00241
00242
00243
00244
00245 plan_success = TIMER_EXPIRED;
00246 break;
00247 }
00248
00249
00250 node n1 = openp->del_min();
00251
00252
00253 if ( n1 == goalNode )
00254
00255 {
00256
00257 graphPath.clear();
00258 graphPath.push( n1 );
00259
00260
00261
00262 while ( n1 != startNode )
00263 {
00264 node n0 = pred[n1];
00265
00266
00267 graphPath.push( n0 );
00268
00269
00270 n1 = n0;
00271 }
00272
00273
00274 delete openp;
00275 openp = NULL;
00276
00277
00278 plan_success = PASS;
00279 break;
00280
00281 }
00282 else
00283 {
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 ExpandNode( n1 );
00295
00296 node n2;
00297 edge e1;
00298
00299
00300 forall_inout_edges(e1, n1)
00301 {
00302
00303
00304
00305
00306 n2 = G.source(e1);
00307 if ( n2 == n1)
00308 {
00309
00310 n2 = G.target(e1);
00311 }
00312
00313
00314 if ( ( pred[n2] == nil ) && ( n2 != startNode ) )
00315 {
00316
00317 pred[n2] = n1;
00318
00319
00320 dist[n2] = dist[n1] + G.inf(e1);
00321
00322
00323 openp->insert( n2, Astar_f(n2, dist[n2]) );
00324 }
00325 else
00326 {
00327
00328 double currcost = dist[n2];
00329 double newcost = dist[n1] + G.inf(e1);
00330
00331
00332 if ( newcost < currcost )
00333 {
00334
00335 pred[n2] = n1;
00336
00337
00338 dist[n2] = newcost;
00339
00340
00341 double priority = Astar_f(n2, dist[n2]);
00342
00343
00344 if ( openp->member(n2) )
00345 {
00346
00347 openp->decrease_p( n2, priority );
00348 }
00349 else
00350 {
00351
00352 openp->insert( n2, priority );
00353 }
00354 }
00355 }
00356 }
00357
00358 }
00359
00360
00361 semaphore.Unlock();
00362 semaphore.Lock();
00363
00364 }
00365
00366
00367
00368
00369
00370 SuccessResultType success = TranslatePath();
00371
00372
00373 semaphore.Unlock();
00374
00375
00376 if ( success == PASS )
00377 {
00378
00379 return true;
00380 }
00381 else
00382 {
00383
00384 return false;
00385 }
00386
00387
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397 void PL_Astar::SetStartConfig( const Configuration& config )
00398 {
00399
00400 if (( startNode != nil ) && ( GetStartConfig() == config ))
00401 {
00402
00403 return;
00404 }
00405
00406
00407 ClearGraph();
00408
00409
00410
00411 PL_GraphBase::SetStartConfig( config );
00412
00413
00414 ASSERT( startNode != nil );
00415
00416
00417 if ( IsInterfering( GetStartConfig() ) )
00418 {
00419
00420 G.del_node( startNode );
00421 startNode = nil;
00422
00423
00424 plan_success = FAIL;
00425 return;
00426 }
00427
00428
00429
00430 PL_GraphBase::SetGoalConfig( GetGoalConfig() );
00431
00432
00433 ASSERT( goalNode != nil );
00434
00435 int gSize = GetGoalConfig().Size();
00436 int cSize = config.Size();
00437 if( ( gSize != cSize ) || ( IsInterfering( GetGoalConfig() ) ) )
00438 {
00439
00440 G.del_node( goalNode );
00441 goalNode = nil;
00442
00443
00444 plan_success = FAIL;
00445 return;
00446 }
00447
00448
00449 if ( GetGoalConfig().Compare( AlignConfig( GetGoalConfig() ) , COMPTOL ) )
00450 {
00451 goalOnGrid = TRUE;
00452 nodeExpanded[ goalNode ] = FALSE;
00453 }
00454 else
00455 {
00456 goalOnGrid = FALSE;
00457 nodeExpanded[ goalNode ] = TRUE;
00458 }
00459
00460
00461 InitNewSearch();
00462
00463
00464 nodeExpanded[ startNode ] = FALSE;
00465
00466 }
00467
00468
00469
00470
00471
00472
00473
00474 void PL_Astar::SetGoalConfig( const Configuration& config )
00475 {
00476
00477 if (( goalNode != nil ) && ( GetGoalConfig() == config ))
00478 {
00479
00480 return;
00481 }
00482
00483
00484 if ( !goalOnGrid )
00485 {
00486 G.del_node( goalNode );
00487 goalNode = nil;
00488 }
00489
00490
00491
00492 int oldNumNodes = NodeCount();
00493 PL_GraphBase::SetGoalConfig( config );
00494
00495
00496
00497 ASSERT( goalNode != nil );
00498
00499
00500 if ( IsInterfering( GetGoalConfig() ) )
00501 {
00502 G.del_node( goalNode );
00503 goalNode = nil;
00504
00505
00506 plan_success = FAIL;
00507 return;
00508 }
00509
00510
00511 if ( GetGoalConfig().Compare( AlignConfig( GetGoalConfig() ) , COMPTOL ) )
00512 {
00513 goalOnGrid = TRUE;
00514
00515 if ( oldNumNodes == NodeCount() )
00516 {
00517
00518 }
00519 else
00520 {
00521 nodeExpanded[ goalNode ] = FALSE;
00522 }
00523 }
00524 else
00525 {
00526 goalOnGrid = FALSE;
00527 nodeExpanded[ goalNode ] = TRUE;
00528
00529
00530
00531 node n;
00532 forall_nodes( n, G )
00533 {
00534 if ( n != goalNode )
00535 {
00536
00537 Configuration testConfig = G.inf(n);
00538 if ( (Distance( testConfig, GetGoalConfig(), invStepSize ) < 1) && (!IsInterfering( testConfig, GetGoalConfig() )) )
00539 {
00540 double dist = sqrt( Distance( testConfig, GetGoalConfig() ) );
00541 edge e1 = G.new_edge( goalNode, n, dist );
00542 }
00543 }
00544 }
00545 }
00546
00547
00548
00549 InitNewSearch();
00550
00551 }
00552
00553
00554
00555
00556
00557
00558
00559 void PL_Astar::SetCollisionDetector (CD_BasicStyle* collisionDetector)
00560 {
00561
00562 PL_GraphBase::SetCollisionDetector( collisionDetector );
00563
00564
00565
00566 if ( stepsize.Length() != collisionDetector->DOF() )
00567 {
00568 SetDefaultStepSize();
00569 }
00570
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580 double PL_Astar::Astar_f( const node& n, const double& currcost ) const
00581 {
00582 return (1-weight)*currcost + weight*sqrt(Distance( n, goalNode ));
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592 void PL_Astar::InvertStepSize()
00593 {
00594
00595 int length = stepsize.Length();
00596 invStepSize.SetLength( length );
00597
00598
00599 for (int i = 0; i < length; i++ )
00600 {
00601 invStepSize[i] = double( 1 / stepsize[i] );
00602 }
00603
00604 }
00605
00606
00607
00608
00609
00610
00611
00612 void PL_Astar::SetStepSize( const VectorN& newstepsize )
00613 {
00614 if ( stepsize == newstepsize )
00615 {
00616 return;
00617 }
00618
00619
00620 stepsize = newstepsize;
00621
00622
00623 InvertStepSize();
00624
00625
00626 ClearGraph();
00627
00628 }
00629
00630
00631
00632
00633
00634
00635 void PL_Astar::SetDefaultStepSize()
00636 {
00637 int dof = 0;
00638
00639 if ( collisionDetector != NULL )
00640 {
00641 dof = collisionDetector->DOF();
00642 }
00643
00644 stepsize.SetLength( dof );
00645
00646 for ( int i = 0; i < dof; i++)
00647 {
00648 stepsize[i] = double( (collisionDetector->JointMax(i) - collisionDetector->JointMin(i)) / DEFAULTNUMSTEPS );
00649 }
00650
00651
00652 InvertStepSize();
00653
00654 }
00655
00656
00657
00658
00659
00660
00661
00662 double PL_Astar::AlignJoint( const int& jointNum, const double& jointValue ) const
00663 {
00664 double start = GetStartConfig()[jointNum];
00665 double step = stepsize[jointNum];
00666
00667 double diff = jointValue - start;
00668
00669 int numofsteps = diff / step;
00670
00671 double align = start + numofsteps*step;
00672
00673
00674 if ( fabs( jointValue - align ) < ( 0.5 * step ) )
00675 {
00676 return align;
00677 }
00678 else if ( diff > 0 )
00679 {
00680 double align2 = align + step;
00681 if ( align2 > collisionDetector->JointMax( jointNum ) )
00682 {
00683 return align;
00684 }
00685 else
00686 {
00687 return align2;
00688 }
00689 }
00690 else
00691 {
00692 double align2 = align - step;
00693 if ( align2 < collisionDetector->JointMin( jointNum ) )
00694 {
00695 return align;
00696 }
00697 else
00698 {
00699 return align2;
00700 }
00701 }
00702
00703 }
00704
00705
00706
00707
00708
00709
00710
00711 Configuration PL_Astar::AlignConfig( const Configuration& config ) const
00712 {
00713 int dof = config.DOF();
00714
00715 Configuration returnMe;
00716 returnMe.SetNumDOF( dof );
00717
00718 for ( int i = 0; i < dof; i++ )
00719 {
00720 returnMe[i] = AlignJoint( i, config[i] );
00721 }
00722
00723 return returnMe;
00724
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 void PL_Astar::ExpandNode( const node& n )
00736 {
00737
00738 if ( nodeExpanded[n] )
00739 {
00740 return;
00741 }
00742
00743 int dof = collisionDetector->DOF();
00744
00745
00746 node_list neighbours;
00747 edge e1;
00748 forall_inout_edges( e1, n)
00749 {
00750 node n1 = G.source(e1);
00751 if ( n1 == n )
00752 {
00753 n1 = G.target(e1);
00754 }
00755
00756 neighbours.append(n1);
00757 }
00758
00759
00760 Configuration currentconfig = G.inf(n);
00761 for( int i = 0; i < dof; i++)
00762 {
00763 BOOL jointWraps = collisionDetector->JointWraps( i );
00764 double jmax = collisionDetector->JointMax( i );
00765 double jmin = collisionDetector->JointMin( i );
00766
00767 for( int j = -1; j < 2; j+=2 )
00768 {
00769 Configuration newconfig = currentconfig;
00770 double newjoint = currentconfig[i] + (j*stepsize[i]);
00771
00772
00773
00774
00775
00776
00777 if ( jointWraps )
00778 {
00779
00780 if ( newjoint > jmax )
00781 {
00782
00783 newjoint = AlignJoint( i, jmin );
00784 }
00785 else if ( newjoint < jmin )
00786 {
00787
00788 newjoint = AlignJoint( i, jmax );
00789 }
00790 }
00791 else
00792 {
00793
00794
00795 if ( ( newjoint > jmax ) || ( newjoint < jmin ) )
00796 {
00797
00798 continue;
00799 }
00800
00801 }
00802
00803
00804
00805
00806 if ( newjoint == currentconfig[i] )
00807 {
00808 continue;
00809 }
00810
00811
00812
00813 newconfig[i] = newjoint;
00814
00815
00816 if ( IsInterfering( newconfig ) )
00817 {
00818 continue;
00819 }
00820
00821
00822 node n1;
00823 bool configFound = FALSE;
00824 forall( n1, neighbours )
00825 {
00826
00827 if ( newconfig.Compare( G.inf(n1) , COMPTOL ) )
00828 {
00829 configFound = TRUE;
00830 break;
00831 }
00832 }
00833 if ( configFound )
00834 {
00835 continue;
00836 }
00837
00838
00839 n1 = FindConfig( newconfig );
00840 if ( n1 == nil )
00841 {
00842
00843 n1 = G.new_node( newconfig );
00844 nodeExpanded[ n1 ] = FALSE;
00845 pred[ n1 ] = nil;
00846 dist[ n1 ] = 0;
00847
00848 }
00849
00850
00851 if ( !IsInterfering( newconfig, currentconfig ) )
00852 {
00853 double dist = sqrt( Distance( newconfig, currentconfig ) );
00854 edge e1 = G.new_edge( n1, n, dist );
00855 }
00856
00857 }
00858 }
00859
00860
00861
00862 if ( ( !goalOnGrid ) &&
00863 ( Distance( currentconfig, GetGoalConfig(), invStepSize ) < 1 ) &&
00864 ( !IsInterfering( currentconfig, GetGoalConfig() ) ) )
00865 {
00866 double dist = sqrt( Distance( GetGoalConfig(), currentconfig ) );
00867 edge e1 = G.new_edge( goalNode, n, dist );
00868 }
00869
00870
00871 nodeExpanded[ n ] = TRUE;
00872
00873 }
00874
00875
00876
00877
00878
00879
00880 void PL_Astar::CopySettings( PlannerBase* original )
00881 {
00882 PL_GraphBase::CopySettings( original );
00883
00884 PL_Astar* originalAstar = dynamic_cast< PL_Astar* >( original );
00885 if( originalAstar == NULL )
00886 {
00887 return;
00888 }
00889 this->stepsize = originalAstar->stepsize;
00890 this->invStepSize = originalAstar->invStepSize;
00891 this->weight = originalAstar->weight;
00892
00893 }