00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030 using namespace std;
00031
00032 #include <sbpl/headers.h>
00033 #include <sbpl_dynamic_planner/intervalPlanner.h>
00034
00035
00036
00037
00038 IntervalPlanner::IntervalPlanner(DiscreteSpaceTimeIntervalInformation* environment){
00039 numOptStates = 0;
00040 numSubOptStates = 0;
00041 totalNumOptStates = 0;
00042 totalNumSubOptStates = 0;
00043
00044 IntervalPlanner_FINAL_EPS = 1.0;
00045 bforwardsearch = true;
00046
00047 environment_ = environment;
00048
00049 bsearchuntilfirstsolution = false;
00050 finitial_eps = IntervalPlanner_DEFAULT_INITIAL_EPS;
00051 decrease_eps = IntervalPlanner_DECREASE_EPS;
00052 searchexpands = 0;
00053 MaxMemoryCounter = 0;
00054
00055 fDeb = SBPL_FOPEN("debug.txt", "w");
00056
00057 pSearchStateSpace_ = new IntervalPlannerSearchStateSpace_t;
00058
00059
00060 if(CreateSearchStateSpace(pSearchStateSpace_) != 1){
00061 SBPL_ERROR("ERROR: failed to create statespace\n");
00062 return;
00063 }
00064
00065
00066 if(InitializeSearchStateSpace(pSearchStateSpace_) != 1){
00067 SBPL_ERROR("ERROR: failed to create statespace\n");
00068 return;
00069 }
00070 }
00071
00072 IntervalPlanner::~IntervalPlanner(){
00073 if(pSearchStateSpace_ != NULL){
00074
00075 DeleteSearchStateSpace(pSearchStateSpace_);
00076 delete pSearchStateSpace_;
00077 }
00078 SBPL_FCLOSE(fDeb);
00079 }
00080
00081
00082 void IntervalPlanner::Initialize_searchinfo(CMDPSTATE* state, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00083 IntervalPlannerState* searchstateinfo = (IntervalPlannerState*)state->PlannerSpecificData;
00084
00085 searchstateinfo->MDPstate = state;
00086 InitializeSearchStateInfo(searchstateinfo, pSearchStateSpace);
00087 }
00088
00089
00090 CMDPSTATE* IntervalPlanner::CreateState(int stateID, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00091 CMDPSTATE* state = NULL;
00092
00093 #if DEBUG
00094 if(environment_->StateID2IndexMapping[stateID][ARAMDP_STATEID2IND] != -1){
00095 SBPL_ERROR("ERROR in CreateState: state already created\n");
00096 throw new SBPL_Exception();
00097 }
00098 #endif
00099
00100
00101 state = pSearchStateSpace->searchMDP.AddState(stateID);
00102
00103
00104 environment_->StateID2IndexMapping[stateID][ARAMDP_STATEID2IND] = pSearchStateSpace->searchMDP.StateArray.size()-1;
00105
00106 #if DEBUG
00107 if(state != pSearchStateSpace->searchMDP.StateArray[environment_->StateID2IndexMapping[stateID][ARAMDP_STATEID2IND]]){
00108 SBPL_ERROR("ERROR in CreateState: invalid state index\n");
00109 throw new SBPL_Exception();
00110 }
00111 #endif
00112
00113
00114 state->PlannerSpecificData = (IntervalPlannerState*)malloc(sizeof(IntervalPlannerState));
00115 Initialize_searchinfo(state, pSearchStateSpace);
00116 MaxMemoryCounter += sizeof(IntervalPlannerState);
00117
00118 return state;
00119 }
00120
00121 CMDPSTATE* IntervalPlanner::GetState(int stateID, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00122 if(stateID >= (int)environment_->StateID2IndexMapping.size()){
00123 SBPL_ERROR("ERROR int GetState: stateID %d is invalid\n", stateID);
00124 throw new SBPL_Exception();
00125 }
00126
00127 if(environment_->StateID2IndexMapping[stateID][ARAMDP_STATEID2IND] == -1)
00128 return CreateState(stateID, pSearchStateSpace);
00129 else
00130 return pSearchStateSpace->searchMDP.StateArray[environment_->StateID2IndexMapping[stateID][ARAMDP_STATEID2IND]];
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 int IntervalPlanner::ComputeHeuristic(CMDPSTATE* MDPstate, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00141
00142
00143 if(bforwardsearch){
00144
00145 #if MEM_CHECK == 1
00146
00147 #endif
00148
00149
00150 int retv = environment_->GetGoalHeuristic(MDPstate->StateID);
00151
00152 #if MEM_CHECK == 1
00153
00154
00155 #endif
00156
00157 return retv;
00158 }
00159 else{
00160
00161 return environment_->GetStartHeuristic(MDPstate->StateID);
00162 }
00163 }
00164
00165
00166
00167 void IntervalPlanner::InitializeSearchStateInfo(IntervalPlannerState* state, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00168 state->g = INFINITECOST;
00169 state->temp_g = INFINITECOST;
00170 state->v = INFINITECOST;
00171 state->iterationclosed = 0;
00172 state->callnumberaccessed = pSearchStateSpace->callnumber;
00173 state->bestnextstate = NULL;
00174 state->costtobestnextstate = INFINITECOST;
00175 state->heapindex = 0;
00176 state->listelem[IntervalPlanner_INCONS_LIST_ID] = 0;
00177 state->numofexpands = 0;
00178
00179 state->bestpredstate = NULL;
00180 state->temp_bestpredstate = NULL;
00181
00182
00183 #if USE_HEUR
00184 if(pSearchStateSpace->searchgoalstate != NULL)
00185 state->h = ComputeHeuristic(state->MDPstate, pSearchStateSpace);
00186 else
00187 state->h = 0;
00188 #else
00189 state->h = 0;
00190 #endif
00191 }
00192
00193
00194
00195
00196 void IntervalPlanner::ReInitializeSearchStateInfo(IntervalPlannerState* state, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00197 state->g = INFINITECOST;
00198 state->temp_g = INFINITECOST;
00199 state->v = INFINITECOST;
00200 state->iterationclosed = 0;
00201 state->callnumberaccessed = pSearchStateSpace->callnumber;
00202 state->bestnextstate = NULL;
00203 state->costtobestnextstate = INFINITECOST;
00204 state->heapindex = 0;
00205 state->listelem[IntervalPlanner_INCONS_LIST_ID] = 0;
00206 state->numofexpands = 0;
00207
00208 state->bestpredstate = NULL;
00209 state->temp_bestpredstate = NULL;
00210
00211
00212 #if USE_HEUR
00213 if(pSearchStateSpace->searchgoalstate != NULL){
00214 state->h = ComputeHeuristic(state->MDPstate, pSearchStateSpace);
00215 }
00216 else
00217 state->h = 0;
00218 #else
00219 state->h = 0;
00220 #endif
00221
00222
00223 }
00224
00225
00226
00227 void IntervalPlanner::DeleteSearchStateData(IntervalPlannerState* state){
00228
00229 MaxMemoryCounter = 0;
00230 return;
00231 }
00232
00233
00234
00235
00236 void IntervalPlanner::UpdatePreds(IntervalPlannerState* state, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00237 vector<int> PredIDV;
00238 vector<int> CostV;
00239 CKey key;
00240 IntervalPlannerState *predstate;
00241
00242 environment_->GetPreds(state->MDPstate->StateID, &PredIDV, &CostV);
00243
00244
00245 for(int pind = 0; pind < (int)PredIDV.size(); pind++){
00246 CMDPSTATE* PredMDPState = GetState(PredIDV[pind], pSearchStateSpace);
00247 predstate = (IntervalPlannerState*)(PredMDPState->PlannerSpecificData);
00248 if(predstate->callnumberaccessed != pSearchStateSpace->callnumber)
00249 ReInitializeSearchStateInfo(predstate, pSearchStateSpace);
00250
00251
00252 if(predstate->g > state->v + CostV[pind]){
00253 predstate->g = state->v + CostV[pind];
00254 predstate->bestnextstate = state->MDPstate;
00255 predstate->costtobestnextstate = CostV[pind];
00256
00257
00258 if(predstate->iterationclosed != pSearchStateSpace->searchiteration){
00259 key.key[0] = predstate->g + (int)(pSearchStateSpace->eps*predstate->h);
00260
00261 if(predstate->heapindex != 0)
00262 pSearchStateSpace->heap->updateheap(predstate,key);
00263 else
00264 pSearchStateSpace->heap->insertheap(predstate,key);
00265 }
00266
00267 else if(predstate->listelem[IntervalPlanner_INCONS_LIST_ID] == NULL){
00268 pSearchStateSpace->inconslist->insert(predstate, IntervalPlanner_INCONS_LIST_ID);
00269 }
00270 }
00271 }
00272 }
00273
00274
00275 void IntervalPlanner::UpdateSuccs(IntervalPlannerState* state, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00276 vector<int> SuccIDV;
00277 vector<int> CostV;
00278 vector<bool> OptV;
00279 CKey key;
00280 IntervalPlannerState *succstate;
00281
00282 if(state->opt)
00283 numOptStates++;
00284 else
00285 numSubOptStates++;
00286
00287 environment_->GetSuccs(state->MDPstate->StateID, &SuccIDV, &CostV, &OptV, pSearchStateSpace->eps==1.0);
00288
00289
00290 for(int sind = 0; sind < (int)SuccIDV.size(); sind++){
00291 CMDPSTATE* SuccMDPState = GetState(SuccIDV[sind], pSearchStateSpace);
00292 int cost = CostV[sind];
00293
00294 succstate = (IntervalPlannerState*)(SuccMDPState->PlannerSpecificData);
00295 if(succstate->callnumberaccessed != pSearchStateSpace->callnumber)
00296 ReInitializeSearchStateInfo(succstate, pSearchStateSpace);
00297
00298
00299
00300
00301 if(succstate->temp_g > state->v + cost){
00302 succstate->temp_g = state->v + cost;
00303 succstate->temp_bestpredstate = state->MDPstate;
00304
00305
00306 if(succstate->iterationclosed != pSearchStateSpace->searchiteration){
00307
00308 succstate->g = state->v + cost;
00309 succstate->bestpredstate = state->MDPstate;
00310
00311 succstate->opt = OptV[sind];
00312
00313 environment_->Relax(succstate->MDPstate->StateID);
00314
00315 if(OptV[sind])
00316 key.key[0] = (int)(pSearchStateSpace->eps*(succstate->g + succstate->h));
00317 else
00318 key.key[0] = succstate->g + (int)(pSearchStateSpace->eps*succstate->h);
00319
00320
00321
00322 if(succstate->heapindex != 0)
00323 pSearchStateSpace->heap->updateheap(succstate,key);
00324 else
00325 pSearchStateSpace->heap->insertheap(succstate,key);
00326 }
00327
00328 else if(succstate->listelem[IntervalPlanner_INCONS_LIST_ID] == NULL)
00329 pSearchStateSpace->inconslist->insert(succstate, IntervalPlanner_INCONS_LIST_ID);
00330 }
00331
00332 }
00333 }
00334
00335
00336 int IntervalPlanner::GetGVal(int StateID, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00337 CMDPSTATE* cmdp_state = GetState(StateID, pSearchStateSpace);
00338 IntervalPlannerState* state = (IntervalPlannerState*)cmdp_state->PlannerSpecificData;
00339 return state->g;
00340 }
00341
00342
00343 int IntervalPlanner::ImprovePath(IntervalPlannerSearchStateSpace_t* pSearchStateSpace, double MaxNumofSecs){
00344 int expands;
00345 IntervalPlannerState *state, *searchgoalstate;
00346 CKey key, minkey;
00347 CKey goalkey;
00348
00349 expands = 0;
00350
00351
00352 if(pSearchStateSpace->searchgoalstate == NULL){
00353 SBPL_ERROR("ERROR searching: no goal state is set\n");
00354 throw new SBPL_Exception();
00355 }
00356
00357
00358 searchgoalstate = (IntervalPlannerState*)(pSearchStateSpace->searchgoalstate->PlannerSpecificData);
00359 if(searchgoalstate->callnumberaccessed != pSearchStateSpace->callnumber)
00360 ReInitializeSearchStateInfo(searchgoalstate, pSearchStateSpace);
00361
00362
00363 goalkey.key[0] = searchgoalstate->g;
00364
00365
00366
00367 minkey = pSearchStateSpace->heap->getminkeyheap();
00368 CKey oldkey = minkey;
00369 while(!pSearchStateSpace->heap->emptyheap() && minkey.key[0] < INFINITECOST && goalkey > minkey &&
00370 (clock()-TimeStarted) < MaxNumofSecs*(double)CLOCKS_PER_SEC){
00371
00372
00373 state = (IntervalPlannerState*)pSearchStateSpace->heap->deleteminheap();
00374
00375
00376 #if DEBUG
00377
00378
00379
00380 SBPL_FPRINTF(fDeb, "expanding: ");
00381 PrintSearchState(state, fDeb);
00382 if(state->listelem[IntervalPlanner_INCONS_LIST_ID] != NULL){
00383 SBPL_FPRINTF(fDeb, "ERROR: expanding a state from inconslist\n");
00384 SBPL_ERROR("ERROR: expanding a state from inconslist\n");
00385 throw new SBPL_Exception();
00386 }
00387 fflush(fDeb);
00388 #endif
00389
00390 #if DEBUG
00391 if(minkey.key[0] < oldkey.key[0] && fabs(this->finitial_eps - 1.0) < ERR_EPS){
00392
00393
00394 }
00395 oldkey = minkey;
00396 #endif
00397
00398 if(state->v == state->temp_g){
00399 SBPL_ERROR("ERROR: consistent state is being expanded (v=%d, temp_g=%d g=%d)\n",state->v,state->temp_g,state->g);
00400 #if DEBUG
00401 SBPL_FPRINTF(fDeb, "ERROR: consistent state is being expanded\n");
00402 throw new SBPL_Exception();
00403 #endif
00404 }
00405
00406
00407 state->v = state->g;
00408 state->temp_g = state->v;
00409 state->iterationclosed = pSearchStateSpace->searchiteration;
00410
00411
00412 expands++;
00413 state->numofexpands++;
00414
00415
00416 if(bforwardsearch == false)
00417 UpdatePreds(state, pSearchStateSpace);
00418 else
00419 UpdateSuccs(state, pSearchStateSpace);
00420
00421
00422 minkey = pSearchStateSpace->heap->getminkeyheap();
00423
00424
00425 if(goalkey.key[0] != (int)searchgoalstate->g){
00426
00427
00428 goalkey.key[0] = searchgoalstate->g;
00429
00430 }
00431
00432 if(expands%100000 == 0 && expands > 0){
00433 SBPL_PRINTF("expands so far=%u\n", expands);
00434 }
00435
00436 }
00437
00438 int retv = 1;
00439 if(searchgoalstate->g == INFINITECOST && pSearchStateSpace->heap->emptyheap()){
00440 SBPL_PRINTF("solution does not exist: search exited because heap is empty\n");
00441 retv = 0;
00442 }
00443 else if(!pSearchStateSpace->heap->emptyheap() && goalkey > minkey){
00444 SBPL_PRINTF("search exited because it ran out of time\n");
00445 retv = 2;
00446 }
00447 else if(searchgoalstate->g == INFINITECOST && !pSearchStateSpace->heap->emptyheap()){
00448 SBPL_PRINTF("solution does not exist: search exited because all candidates for expansion have infinite heuristics\n");
00449 retv = 0;
00450 }
00451 else{
00452 SBPL_PRINTF("search exited with a solution for eps=%.3f\n", pSearchStateSpace->eps);
00453 retv = 1;
00454 }
00455
00456
00457
00458 searchexpands += expands;
00459
00460 return retv;
00461 }
00462
00463
00464 void IntervalPlanner::BuildNewOPENList(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00465 IntervalPlannerState *state;
00466 CKey key;
00467 CHeap* pheap = pSearchStateSpace->heap;
00468 CList* pinconslist = pSearchStateSpace->inconslist;
00469
00470
00471 while(pinconslist->firstelement != NULL){
00472 state = (IntervalPlannerState*)pinconslist->firstelement->liststate;
00473
00474 state->g = state->temp_g;
00475 state->bestpredstate = state->temp_bestpredstate;
00476 environment_->Relax(state->MDPstate->StateID);
00477
00478
00479 if(state->opt)
00480 key.key[0] = (int)(pSearchStateSpace->eps*(state->g + state->h));
00481 else
00482 key.key[0] = state->g + (int)(pSearchStateSpace->eps*state->h);
00483
00484
00485
00486 pheap->insertheap(state, key);
00487
00488 pinconslist->remove(state, IntervalPlanner_INCONS_LIST_ID);
00489 }
00490 }
00491
00492
00493 void IntervalPlanner::Reevaluatefvals(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00494 CKey key;
00495 int i;
00496 CHeap* pheap = pSearchStateSpace->heap;
00497
00498
00499 for (i = 1; i <= pheap->currentsize; ++i){
00500 IntervalPlannerState* state = (IntervalPlannerState*)pheap->heap[i].heapstate;
00501 if(state->opt)
00502 pheap->heap[i].key.key[0] = (int)(pSearchStateSpace->eps*(state->g + state->h));
00503 else
00504 pheap->heap[i].key.key[0] = state->g + (int)(pSearchStateSpace->eps*state->h);
00505 }
00506 pheap->makeheap();
00507
00508 pSearchStateSpace->bReevaluatefvals = false;
00509 }
00510
00511
00512
00513
00514
00515
00516 int IntervalPlanner::CreateSearchStateSpace(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00517
00518 pSearchStateSpace->heap = new CHeap;
00519 pSearchStateSpace->inconslist = new CList;
00520 MaxMemoryCounter += sizeof(CHeap);
00521 MaxMemoryCounter += sizeof(CList);
00522
00523 pSearchStateSpace->searchgoalstate = NULL;
00524 pSearchStateSpace->searchstartstate = NULL;
00525
00526 searchexpands = 0;
00527
00528
00529 pSearchStateSpace->bReinitializeSearchStateSpace = false;
00530
00531 return 1;
00532 }
00533
00534
00535 void IntervalPlanner::DeleteSearchStateSpace(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00536 if(pSearchStateSpace->heap != NULL){
00537 pSearchStateSpace->heap->makeemptyheap();
00538 delete pSearchStateSpace->heap;
00539 pSearchStateSpace->heap = NULL;
00540 }
00541
00542 if(pSearchStateSpace->inconslist != NULL){
00543 pSearchStateSpace->inconslist->makeemptylist(IntervalPlanner_INCONS_LIST_ID);
00544 delete pSearchStateSpace->inconslist;
00545 pSearchStateSpace->inconslist = NULL;
00546 }
00547
00548
00549 int iend = (int)pSearchStateSpace->searchMDP.StateArray.size();
00550 for(int i=0; i < iend; i++){
00551 CMDPSTATE* state = pSearchStateSpace->searchMDP.StateArray[i];
00552 if(state != NULL && state->PlannerSpecificData != NULL){
00553 DeleteSearchStateData((IntervalPlannerState*)state->PlannerSpecificData);
00554 free((IntervalPlannerState*)state->PlannerSpecificData);
00555 state->PlannerSpecificData = NULL;
00556 }
00557 }
00558 pSearchStateSpace->searchMDP.Delete();
00559 }
00560
00561
00562
00563
00564
00565 int IntervalPlanner::ResetSearchStateSpace(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00566 pSearchStateSpace->heap->makeemptyheap();
00567 pSearchStateSpace->inconslist->makeemptylist(IntervalPlanner_INCONS_LIST_ID);
00568
00569 return 1;
00570 }
00571
00572
00573 void IntervalPlanner::ReInitializeSearchStateSpace(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00574 CKey key;
00575
00576
00577 pSearchStateSpace->callnumber++;
00578
00579
00580 pSearchStateSpace->searchiteration = 0;
00581 pSearchStateSpace->bNewSearchIteration = true;
00582
00583 #if DEBUG
00584 SBPL_FPRINTF(fDeb, "reinitializing search state-space (new call number=%d search iter=%d)\n",
00585 pSearchStateSpace->callnumber,pSearchStateSpace->searchiteration );
00586 #endif
00587
00588 pSearchStateSpace->heap->makeemptyheap();
00589 pSearchStateSpace->inconslist->makeemptylist(IntervalPlanner_INCONS_LIST_ID);
00590
00591
00592 pSearchStateSpace->eps = this->finitial_eps;
00593 pSearchStateSpace->eps_satisfied = INFINITECOST;
00594
00595
00596 IntervalPlannerState* startstateinfo = (IntervalPlannerState*)(pSearchStateSpace->searchstartstate->PlannerSpecificData);
00597 if(startstateinfo->callnumberaccessed != pSearchStateSpace->callnumber)
00598 ReInitializeSearchStateInfo(startstateinfo, pSearchStateSpace);
00599
00600 startstateinfo->g = 0;
00601 startstateinfo->temp_g = 0;
00602 startstateinfo->opt = true;
00603
00604
00605 key.key[0] = (long int)(pSearchStateSpace->eps*startstateinfo->h);
00606
00607 pSearchStateSpace->heap->insertheap(startstateinfo, key);
00608
00609 pSearchStateSpace->bReinitializeSearchStateSpace = false;
00610 pSearchStateSpace->bReevaluatefvals = false;
00611 }
00612
00613
00614 int IntervalPlanner::InitializeSearchStateSpace(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00615 if(pSearchStateSpace->heap->currentsize != 0 ||
00616 pSearchStateSpace->inconslist->currentsize != 0){
00617 SBPL_ERROR("ERROR in InitializeSearchStateSpace: heap or list is not empty\n");
00618 throw new SBPL_Exception();
00619 }
00620
00621 pSearchStateSpace->eps = this->finitial_eps;
00622 pSearchStateSpace->eps_satisfied = INFINITECOST;
00623 pSearchStateSpace->searchiteration = 0;
00624 pSearchStateSpace->bNewSearchIteration = true;
00625 pSearchStateSpace->callnumber = 0;
00626 pSearchStateSpace->bReevaluatefvals = false;
00627
00628
00629 pSearchStateSpace->searchgoalstate = NULL;
00630
00631 pSearchStateSpace->searchstartstate = NULL;
00632
00633 pSearchStateSpace->bReinitializeSearchStateSpace = true;
00634
00635 return 1;
00636 }
00637
00638
00639 int IntervalPlanner::SetSearchGoalState(int SearchGoalStateID, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00640 if(pSearchStateSpace->searchgoalstate == NULL ||
00641 pSearchStateSpace->searchgoalstate->StateID != SearchGoalStateID){
00642 pSearchStateSpace->searchgoalstate = GetState(SearchGoalStateID, pSearchStateSpace);
00643
00644
00645 pSearchStateSpace->eps_satisfied = INFINITECOST;
00646 pSearchStateSpace->bNewSearchIteration = true;
00647 pSearchStateSpace_->eps = this->finitial_eps;
00648
00649
00650
00651 #if USE_HEUR
00652 for(int i = 0; i < (int)pSearchStateSpace->searchMDP.StateArray.size(); i++){
00653 CMDPSTATE* MDPstate = pSearchStateSpace->searchMDP.StateArray[i];
00654 IntervalPlannerState* state = (IntervalPlannerState*)MDPstate->PlannerSpecificData;
00655 state->h = ComputeHeuristic(MDPstate, pSearchStateSpace);
00656 }
00657
00658 pSearchStateSpace->bReevaluatefvals = true;
00659 #endif
00660 }
00661
00662 return 1;
00663 }
00664
00665
00666 int IntervalPlanner::SetSearchStartState(int SearchStartStateID, IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00667 CMDPSTATE* MDPstate = GetState(SearchStartStateID, pSearchStateSpace);
00668
00669 if(MDPstate != pSearchStateSpace->searchstartstate){
00670 pSearchStateSpace->searchstartstate = MDPstate;
00671 pSearchStateSpace->bReinitializeSearchStateSpace = true;
00672 }
00673
00674 return 1;
00675 }
00676
00677
00678
00679 int IntervalPlanner::ReconstructPath(IntervalPlannerSearchStateSpace_t* pSearchStateSpace){
00680 if(bforwardsearch){
00681 CMDPSTATE* MDPstate = pSearchStateSpace->searchgoalstate;
00682 CMDPSTATE* PredMDPstate;
00683 IntervalPlannerState *predstateinfo, *stateinfo;
00684
00685
00686
00687 #if DEBUG
00688 SBPL_FPRINTF(fDeb, "reconstructing a path:\n");
00689 #endif
00690
00691 while(MDPstate != pSearchStateSpace->searchstartstate){
00692 stateinfo = (IntervalPlannerState*)MDPstate->PlannerSpecificData;
00693
00694 #if DEBUG
00695 PrintSearchState(stateinfo, fDeb);
00696 #endif
00697 if(stateinfo->g == INFINITECOST){
00698
00699
00700 return -1;
00701 }
00702
00703 if(stateinfo->bestpredstate == NULL){
00704 SBPL_ERROR("ERROR in ReconstructPath: bestpred is NULL\n");
00705 throw new SBPL_Exception();
00706 }
00707
00708
00709 PredMDPstate = stateinfo->bestpredstate;
00710 predstateinfo = (IntervalPlannerState*)PredMDPstate->PlannerSpecificData;
00711
00712
00713 predstateinfo->bestnextstate = MDPstate;
00714
00715
00716 if(predstateinfo->v >= stateinfo->g){
00717 SBPL_ERROR("ERROR in ReconstructPath: g-values are non-decreasing\n");
00718 PrintSearchState(predstateinfo, fDeb);
00719 throw new SBPL_Exception();
00720 }
00721
00722
00723 MDPstate = PredMDPstate;
00724 }
00725 }
00726
00727 return 1;
00728 }
00729
00730
00731
00732 void IntervalPlanner::PrintSearchPath(IntervalPlannerSearchStateSpace_t* pSearchStateSpace, FILE* fOut){
00733 IntervalPlannerState* searchstateinfo;
00734 CMDPSTATE* state;
00735 int goalID;
00736 int PathCost;
00737
00738 if(bforwardsearch){
00739 state = pSearchStateSpace->searchstartstate;
00740 goalID = pSearchStateSpace->searchgoalstate->StateID;
00741 }
00742 else{
00743 state = pSearchStateSpace->searchgoalstate;
00744 goalID = pSearchStateSpace->searchstartstate->StateID;
00745 }
00746 if(fOut == NULL)
00747 fOut = stdout;
00748
00749 PathCost = ((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g;
00750
00751 SBPL_FPRINTF(fOut, "Printing a path from state %d to the goal state %d\n",
00752 state->StateID, pSearchStateSpace->searchgoalstate->StateID);
00753 SBPL_FPRINTF(fOut, "Path cost = %d:\n", PathCost);
00754
00755 environment_->PrintState(state->StateID, false, fOut);
00756
00757 int costFromStart = 0;
00758 while(state->StateID != goalID){
00759 SBPL_FPRINTF(fOut, "state %d ", state->StateID);
00760
00761 if(state->PlannerSpecificData == NULL){
00762 SBPL_FPRINTF(fOut, "path does not exist since search data does not exist\n");
00763 break;
00764 }
00765
00766 searchstateinfo = (IntervalPlannerState*)state->PlannerSpecificData;
00767
00768 if(searchstateinfo->bestnextstate == NULL){
00769 SBPL_FPRINTF(fOut, "path does not exist since bestnextstate == NULL\n");
00770 break;
00771 }
00772 if(searchstateinfo->g == INFINITECOST){
00773 SBPL_FPRINTF(fOut, "path does not exist since bestnextstate == NULL\n");
00774 break;
00775 }
00776
00777 int costToGoal = PathCost - costFromStart;
00778 int transcost = searchstateinfo->g - ((IntervalPlannerState*)(searchstateinfo->bestnextstate->PlannerSpecificData))->v;
00779 if(bforwardsearch)
00780 transcost = -transcost;
00781
00782 costFromStart += transcost;
00783
00784 SBPL_FPRINTF(fOut, "g=%d-->state %d, h = %d ctg = %d ", searchstateinfo->g,
00785 searchstateinfo->bestnextstate->StateID, searchstateinfo->h, costToGoal);
00786
00787 state = searchstateinfo->bestnextstate;
00788
00789 environment_->PrintState(state->StateID, false, fOut);
00790 }
00791 }
00792
00793 void IntervalPlanner::PrintSearchState(IntervalPlannerState* state, FILE* fOut){
00794 SBPL_FPRINTF(fOut, "state %d: h=%d g=%u v=%u iterc=%d callnuma=%d expands=%d heapind=%d inconslist=%d\n",
00795 state->MDPstate->StateID, state->h, state->g, state->v,
00796 state->iterationclosed, state->callnumberaccessed, state->numofexpands, state->heapindex, state->listelem[IntervalPlanner_INCONS_LIST_ID]?1:0);
00797 environment_->PrintState(state->MDPstate->StateID, true, fOut);
00798 }
00799
00800
00801
00802 int IntervalPlanner::getHeurValue(IntervalPlannerSearchStateSpace_t* pSearchStateSpace, int StateID){
00803 CMDPSTATE* MDPstate = GetState(StateID, pSearchStateSpace);
00804 IntervalPlannerState* searchstateinfo = (IntervalPlannerState*)MDPstate->PlannerSpecificData;
00805 return searchstateinfo->h;
00806 }
00807
00808
00809 vector<int> IntervalPlanner::GetSearchPath(IntervalPlannerSearchStateSpace_t* pSearchStateSpace, int& solcost){
00810 vector<int> SuccIDV;
00811 vector<int> CostV;
00812 vector<bool> OptV;
00813 vector<int> wholePathIds;
00814 IntervalPlannerState* searchstateinfo;
00815 CMDPSTATE* state = NULL;
00816 CMDPSTATE* goalstate = NULL;
00817 CMDPSTATE* startstate=NULL;
00818
00819 if(bforwardsearch){
00820 startstate = pSearchStateSpace->searchstartstate;
00821 goalstate = pSearchStateSpace->searchgoalstate;
00822
00823
00824 ReconstructPath(pSearchStateSpace);
00825 }
00826 else{
00827 startstate = pSearchStateSpace->searchgoalstate;
00828 goalstate = pSearchStateSpace->searchstartstate;
00829 }
00830
00831 state = startstate;
00832
00833 wholePathIds.push_back(state->StateID);
00834 solcost = 0;
00835
00836 FILE* fOut = stdout;
00837 while(state->StateID != goalstate->StateID){
00838 if(state->PlannerSpecificData == NULL){
00839 SBPL_FPRINTF(fOut, "path does not exist since search data does not exist\n");
00840 break;
00841 }
00842
00843 searchstateinfo = (IntervalPlannerState*)state->PlannerSpecificData;
00844
00845 if(searchstateinfo->bestnextstate == NULL){
00846 SBPL_FPRINTF(fOut, "path does not exist since bestnextstate == NULL\n");
00847 break;
00848 }
00849 if(searchstateinfo->g == INFINITECOST){
00850 SBPL_FPRINTF(fOut, "path does not exist since bestnextstate == NULL\n");
00851 break;
00852 }
00853
00854 environment_->GetSuccs(state->StateID, &SuccIDV, &CostV, &OptV, false);
00855 int actioncost = INFINITECOST;
00856 for(int i = 0; i < (int)SuccIDV.size(); i++){
00857 if(SuccIDV.at(i) == searchstateinfo->bestnextstate->StateID && CostV.at(i)<actioncost)
00858 actioncost = CostV.at(i);
00859 }
00860 if(actioncost == INFINITECOST)
00861 SBPL_PRINTF("WARNING: actioncost = %d (%d)\n", actioncost,state->StateID);
00862
00863 solcost += actioncost;
00864
00865
00866
00867
00868
00869
00870
00871 #if DEBUG
00872 IntervalPlannerState* nextstateinfo = (IntervalPlannerState*)(searchstateinfo->bestnextstate->PlannerSpecificData);
00873 if(actioncost != abs((int)(searchstateinfo->g - nextstateinfo->g)) && pSearchStateSpace->eps_satisfied <= 1.001){
00874 SBPL_FPRINTF(fDeb, "ERROR: actioncost=%d is not matching the difference in g-values of %d\n",
00875 actioncost, abs((int)(searchstateinfo->g - nextstateinfo->g)));
00876 SBPL_ERROR("ERROR: actioncost=%d is not matching the difference in g-values of %d\n",
00877 actioncost,abs((int)(searchstateinfo->g - nextstateinfo->g)));
00878 PrintSearchState(searchstateinfo, fDeb);
00879 PrintSearchState(nextstateinfo, fDeb);
00880 }
00881 #endif
00882
00883 state = searchstateinfo->bestnextstate;
00884
00885 wholePathIds.push_back(state->StateID);
00886 }
00887
00888 return wholePathIds;
00889 }
00890
00891
00892
00893 bool IntervalPlanner::Search(IntervalPlannerSearchStateSpace_t* pSearchStateSpace, vector<int>& pathIds, int & PathCost, bool bFirstSolution, bool bOptimalSolution, double MaxNumofSecs){
00894 CKey key;
00895 TimeStarted = clock();
00896 searchexpands = 0;
00897
00898 #if DEBUG
00899 SBPL_FPRINTF(fDeb, "new search call (call number=%d)\n", pSearchStateSpace->callnumber);
00900 #endif
00901
00902 if(pSearchStateSpace->bReinitializeSearchStateSpace == true){
00903
00904 ReInitializeSearchStateSpace(pSearchStateSpace);
00905 }
00906
00907 if(bOptimalSolution){
00908 pSearchStateSpace->eps = 1;
00909 MaxNumofSecs = INFINITECOST;
00910 }
00911 else if(bFirstSolution){
00912 MaxNumofSecs = INFINITECOST;
00913 }
00914
00915 epsV.clear();
00916 expandsV.clear();
00917 solcostV.clear();
00918 searchTimeV.clear();
00919
00920
00921 int prevexpands = 0;
00922 clock_t loop_time;
00923 while(pSearchStateSpace->eps_satisfied > IntervalPlanner_FINAL_EPS &&
00924 (clock()- TimeStarted) < MaxNumofSecs*(double)CLOCKS_PER_SEC){
00925 loop_time = clock();
00926
00927 if(fabs(pSearchStateSpace->eps_satisfied - pSearchStateSpace->eps) < ERR_EPS && !bFirstSolution){
00928 pSearchStateSpace->eps = pSearchStateSpace->eps - decrease_eps;
00929 if(pSearchStateSpace->eps < IntervalPlanner_FINAL_EPS)
00930 pSearchStateSpace->eps = IntervalPlanner_FINAL_EPS;
00931
00932
00933 pSearchStateSpace->bReevaluatefvals = true;
00934
00935
00936 pSearchStateSpace->bNewSearchIteration = true;
00937
00938
00939 BuildNewOPENList(pSearchStateSpace);
00940 }
00941
00942 if(pSearchStateSpace->bNewSearchIteration){
00943 pSearchStateSpace->searchiteration++;
00944 pSearchStateSpace->bNewSearchIteration = false;
00945 }
00946
00947
00948 if(pSearchStateSpace->bReevaluatefvals)
00949 Reevaluatefvals(pSearchStateSpace);
00950
00951
00952 if(ImprovePath(pSearchStateSpace, MaxNumofSecs) == 1){
00953 pSearchStateSpace->eps_satisfied = pSearchStateSpace->eps;
00954 epsV.push_back(pSearchStateSpace->eps);
00955 expandsV.push_back(searchexpands-prevexpands);
00956 solcostV.push_back(((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g);
00957 searchTimeV.push_back(double(clock()-loop_time)/CLOCKS_PER_SEC);
00958 }
00959
00960
00961 SBPL_PRINTF("eps=%f expands=%d(opt=%d, sub=%d) g(searchgoal)=%d time=%.3f\n", pSearchStateSpace->eps_satisfied, searchexpands - prevexpands,numOptStates,numSubOptStates,
00962 ((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g,double(clock()-loop_time)/CLOCKS_PER_SEC);
00963 totalNumOptStates += numOptStates;
00964 totalNumSubOptStates += numSubOptStates;
00965 numOptStates = 0;
00966 numSubOptStates = 0;
00967
00968 #if DEBUG
00969 SBPL_FPRINTF(fDeb, "eps=%f expands=%d g(searchgoal)=%d time=%.3f\n", pSearchStateSpace->eps_satisfied, searchexpands - prevexpands,
00970 ((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g,double(clock()-loop_time)/CLOCKS_PER_SEC);
00971 PrintSearchState((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData, fDeb);
00972 #endif
00973 prevexpands = searchexpands;
00974
00975
00976 if(bFirstSolution)
00977 break;
00978
00979
00980 if(((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g == INFINITECOST)
00981 break;
00982 }
00983
00984 #if DEBUG
00985 fflush(fDeb);
00986 #endif
00987
00988 PathCost = ((IntervalPlannerState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g;
00989 MaxMemoryCounter += environment_->StateID2IndexMapping.size()*sizeof(int);
00990
00991 SBPL_PRINTF("MaxMemoryCounter = %d\n", MaxMemoryCounter);
00992
00993 int solcost = INFINITECOST;
00994 bool ret = false;
00995 if(PathCost == INFINITECOST){
00996 SBPL_PRINTF("could not find a solution\n");
00997 ret = false;
00998 }
00999 else{
01000 SBPL_PRINTF("solution is found\n");
01001 pathIds = GetSearchPath(pSearchStateSpace, solcost);
01002 ret = true;
01003 }
01004
01005 solfound = ret;
01006 searchtime = (clock()-TimeStarted)/((double)CLOCKS_PER_SEC);
01007 finalsolcost = solcost;
01008 SBPL_PRINTF("total expands this call = %d(opt=%d, sub=%d), planning time = %.3f secs, solution cost=%d\n",
01009 searchexpands, totalNumOptStates, totalNumSubOptStates, searchtime, solcost);
01010 totalNumOptStates = 0;
01011 totalNumSubOptStates = 0;
01012
01013
01014
01015 return ret;
01016 }
01017
01018
01019
01020
01021 int IntervalPlanner::replan(double allocated_time_secs, vector<int>* solution_stateIDs_V){
01022 int solcost;
01023 return replan(allocated_time_secs, solution_stateIDs_V, &solcost);
01024 }
01025
01026
01027 int IntervalPlanner::replan(double allocated_time_secs, vector<int>* solution_stateIDs_V, int* psolcost){
01028 vector<int> pathIds;
01029 bool bFound = false;
01030 int PathCost;
01031 bool bFirstSolution = this->bsearchuntilfirstsolution;
01032 bool bOptimalSolution = false;
01033 *psolcost = 0;
01034
01035 SBPL_PRINTF("planner: replan called (bFirstSol=%d, bOptSol=%d)\n", bFirstSolution, bOptimalSolution);
01036
01037
01038 if((bFound = Search(pSearchStateSpace_, pathIds, PathCost, bFirstSolution, bOptimalSolution, allocated_time_secs)) == false){
01039 SBPL_PRINTF("failed to find a solution\n");
01040 }
01041
01042
01043 *solution_stateIDs_V = pathIds;
01044 *psolcost = PathCost;
01045
01046
01047
01048 return (int)bFound;
01049 }
01050
01051
01052 int IntervalPlanner::set_goal(int goal_stateID){
01053 SBPL_PRINTF("planner: setting goal to %d\n", goal_stateID);
01054 environment_->PrintState(goal_stateID, true, stdout);
01055
01056 if(bforwardsearch){
01057 if(SetSearchGoalState(goal_stateID, pSearchStateSpace_) != 1){
01058 SBPL_ERROR("ERROR: failed to set search goal state\n");
01059 return 0;
01060 }
01061 }
01062 else{
01063 if(SetSearchStartState(goal_stateID, pSearchStateSpace_) != 1){
01064 SBPL_ERROR("ERROR: failed to set search start state\n");
01065 return 0;
01066 }
01067 }
01068 return 1;
01069 }
01070
01071
01072 int IntervalPlanner::set_start(int start_stateID){
01073 SBPL_PRINTF("planner: setting start to %d\n", start_stateID);
01074 environment_->PrintState(start_stateID, true, stdout);
01075
01076 if(bforwardsearch){
01077 if(SetSearchStartState(start_stateID, pSearchStateSpace_) != 1){
01078 SBPL_ERROR("ERROR: failed to set search start state\n");
01079 return 0;
01080 }
01081 }
01082 else{
01083 if(SetSearchGoalState(start_stateID, pSearchStateSpace_) != 1){
01084 SBPL_ERROR("ERROR: failed to set search goal state\n");
01085 return 0;
01086 }
01087 }
01088 return 1;
01089 }
01090
01091
01092
01093 void IntervalPlanner::costs_changed(StateChangeQuery const & stateChange){
01094 pSearchStateSpace_->bReinitializeSearchStateSpace = true;
01095 }
01096
01097 void IntervalPlanner::costs_changed(){
01098 pSearchStateSpace_->bReinitializeSearchStateSpace = true;
01099 }
01100
01101
01102
01103 int IntervalPlanner::force_planning_from_scratch(){
01104 SBPL_PRINTF("planner: forceplanfromscratch set\n");
01105 pSearchStateSpace_->bReinitializeSearchStateSpace = true;
01106 return 1;
01107 }
01108
01109
01110 int IntervalPlanner::set_search_mode(bool bSearchUntilFirstSolution){
01111 SBPL_PRINTF("planner: search mode set to %d\n", bSearchUntilFirstSolution);
01112 bsearchuntilfirstsolution = bSearchUntilFirstSolution;
01113 return 1;
01114 }
01115
01116
01117 void IntervalPlanner::print_searchpath(FILE* fOut){
01118 PrintSearchPath(pSearchStateSpace_, fOut);
01119 }
01120
01121
01122
01123
01124
01125 void IntervalPlanner::getSearchStats(bool* solutionFound, vector<int>* numExpands, vector<int>* solutionCost, vector<double>* searchTime, vector<double>* searchEps){
01126 *solutionFound = solfound;
01127 for(int i=0; i<epsV.size(); i++){
01128 searchEps->push_back(epsV[i]);
01129 numExpands->push_back(expandsV[i]);
01130 solutionCost->push_back(solcostV[i]);
01131 searchTime->push_back(searchTimeV[i]);
01132 }
01133 }
01134