adplanner.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Maxim Likhachev
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  * 
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the University of Pennsylvania nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  * 
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 #include <iostream>
00030 using namespace std;
00031 
00032 #include "../../sbpl/headers.h"
00033 
00034 
00035 
00036 
00037 //-----------------------------------------------------------------------------------------------------
00038 
00039 ADPlanner::ADPlanner(DiscreteSpaceInformation* environment, bool bForwardSearch)
00040 {
00041     environment_ = environment;
00042     
00043         bforwardsearch = bForwardSearch;
00044 
00045         bsearchuntilfirstsolution = false;
00046     finitial_eps = AD_DEFAULT_INITIAL_EPS;
00047     searchexpands = 0;
00048     MaxMemoryCounter = 0;
00049     
00050 #ifndef ROS
00051   const char* debug = "debug.txt";
00052 #endif
00053   fDeb = SBPL_FOPEN(debug, "w");
00054   if(fDeb == NULL){
00055     SBPL_ERROR("ERROR: could not open planner debug file\n");
00056     throw new SBPL_Exception();
00057   }
00058     SBPL_PRINTF("debug on\n");    
00059 
00060     pSearchStateSpace_ = new ADSearchStateSpace_t;
00061     
00062     
00063     //create the AD planner
00064     if(CreateSearchStateSpace(pSearchStateSpace_) != 1)
00065         {
00066             SBPL_ERROR("ERROR: failed to create statespace\n");
00067             return;
00068         }
00069     
00070     //set the start and goal states
00071     if(InitializeSearchStateSpace(pSearchStateSpace_) != 1)
00072         {
00073             SBPL_ERROR("ERROR: failed to create statespace\n");
00074             return;
00075         }    
00076 
00077     finitial_eps_planning_time = -1.0;
00078     final_eps_planning_time = -1.0;
00079     num_of_expands_initial_solution = 0;
00080     final_eps = -1.0;
00081 }
00082 
00083 ADPlanner::~ADPlanner()
00084 {
00085 
00086     //delete the statespace
00087     DeleteSearchStateSpace(pSearchStateSpace_);
00088     delete pSearchStateSpace_;
00089 
00090     SBPL_FCLOSE(fDeb);
00091 }
00092 
00093 
00094 void ADPlanner::Initialize_searchinfo(CMDPSTATE* state, ADSearchStateSpace_t* pSearchStateSpace)
00095 {
00096 
00097         ADState* searchstateinfo = (ADState*)state->PlannerSpecificData;
00098 
00099         searchstateinfo->MDPstate = state;
00100         InitializeSearchStateInfo(searchstateinfo, pSearchStateSpace); 
00101 }
00102 
00103 
00104 CMDPSTATE* ADPlanner::CreateState(int stateID, ADSearchStateSpace_t* pSearchStateSpace)
00105 {       
00106         CMDPSTATE* state = NULL;
00107 
00108 #if DEBUG
00109         if(environment_->StateID2IndexMapping[stateID][ADMDP_STATEID2IND] != -1)
00110         {
00111                 SBPL_ERROR("ERROR in CreateState: state already created\n");
00112                 throw new SBPL_Exception();
00113         }
00114 #endif
00115 
00116         //adds to the tail a state
00117         state = pSearchStateSpace->searchMDP.AddState(stateID);
00118 
00119         //remember the index of the state
00120         environment_->StateID2IndexMapping[stateID][ADMDP_STATEID2IND] = pSearchStateSpace->searchMDP.StateArray.size()-1;
00121 
00122 #if DEBUG
00123         if(state != pSearchStateSpace->searchMDP.StateArray[environment_->StateID2IndexMapping[stateID][ADMDP_STATEID2IND]])
00124         {
00125                 SBPL_ERROR("ERROR in CreateState: invalid state index\n");
00126                 throw new SBPL_Exception();
00127         }
00128 #endif
00129 
00130 
00131         //create search specific info
00132         state->PlannerSpecificData = (ADState*)malloc(sizeof(ADState)); 
00133         Initialize_searchinfo(state, pSearchStateSpace);
00134         MaxMemoryCounter += sizeof(ADState);
00135 
00136         return state;
00137 
00138 }
00139 
00140 
00141 CMDPSTATE* ADPlanner::GetState(int stateID, ADSearchStateSpace_t* pSearchStateSpace)
00142 {       
00143 
00144         if(stateID >= (int)environment_->StateID2IndexMapping.size())
00145         {
00146                 SBPL_ERROR("ERROR int GetState: stateID is invalid\n");
00147                 throw new SBPL_Exception();
00148         }
00149 
00150         if(environment_->StateID2IndexMapping[stateID][ADMDP_STATEID2IND] == -1)
00151                 return CreateState(stateID, pSearchStateSpace);
00152         else
00153                 return pSearchStateSpace->searchMDP.StateArray[environment_->StateID2IndexMapping[stateID][ADMDP_STATEID2IND]];
00154 
00155 }
00156 
00157 
00158 
00159 //-----------------------------------------------------------------------------------------------------
00160 
00161 
00162 CKey ADPlanner::ComputeKey(ADState* state)
00163 {
00164         CKey key;
00165 
00166         if(state->v >= state->g)
00167         {
00168                 key.key[0] = state->g + (int)(pSearchStateSpace_->eps*state->h);
00169                 key.key[1] = 1;
00170         }
00171         else
00172         {
00173                 key.key[0] = state->v + state->h;
00174                 key.key[1] = 0;
00175         }
00176 
00177         return key;
00178 }
00179 
00180 
00181 int ADPlanner::ComputeHeuristic(CMDPSTATE* MDPstate, ADSearchStateSpace_t* pSearchStateSpace)
00182 {
00183         //compute heuristic for search
00184         if(bforwardsearch)
00185         {
00186 
00187 #if MEM_CHECK == 1
00188                 //int WasEn = DisableMemCheck();
00189 #endif
00190 
00191                 //forward search: heur = distance from state to searchgoal which is Goal ADState
00192                 int retv =  environment_->GetGoalHeuristic(MDPstate->StateID);
00193 
00194 #if MEM_CHECK == 1
00195                 //if (WasEn)
00196                 //      EnableMemCheck();
00197 #endif
00198 
00199                 return retv;
00200         }
00201         else
00202         {       
00203                 //backward search: heur = distance from searchgoal to state
00204                 return environment_->GetStartHeuristic(MDPstate->StateID);
00205         }
00206 
00207 }
00208 
00209 
00210 //initialization of a state
00211 void ADPlanner::InitializeSearchStateInfo(ADState* state, ADSearchStateSpace_t* pSearchStateSpace)
00212 {
00213         state->g = INFINITECOST;
00214         state->v = INFINITECOST;
00215         state->iterationclosed = 0;
00216         state->callnumberaccessed = pSearchStateSpace->callnumber;
00217         state->bestnextstate = NULL;
00218         state->costtobestnextstate = INFINITECOST;
00219         state->heapindex = 0;
00220         state->listelem[AD_INCONS_LIST_ID] = NULL;
00221         state->numofexpands = 0;
00222         state->bestpredstate = NULL;
00223 
00224         //compute heuristics
00225 #if USE_HEUR
00226         if(pSearchStateSpace->searchgoalstate != NULL)
00227                 state->h = ComputeHeuristic(state->MDPstate, pSearchStateSpace); 
00228         else 
00229                 state->h = 0;
00230 #else
00231         state->h = 0;
00232 #endif
00233 
00234 
00235 }
00236 
00237 
00238 
00239 //re-initialization of a state
00240 void ADPlanner::ReInitializeSearchStateInfo(ADState* state, ADSearchStateSpace_t* pSearchStateSpace)
00241 {
00242         state->g = INFINITECOST;
00243         state->v = INFINITECOST;
00244         state->iterationclosed = 0;
00245         state->callnumberaccessed = pSearchStateSpace->callnumber;
00246         state->bestnextstate = NULL;
00247         state->costtobestnextstate = INFINITECOST;
00248         state->heapindex = 0;
00249         state->listelem[AD_INCONS_LIST_ID] = NULL;
00250         state->numofexpands = 0;
00251         state->bestpredstate = NULL;
00252 
00253         //compute heuristics
00254 #if USE_HEUR
00255 
00256         if(pSearchStateSpace->searchgoalstate != NULL)
00257         {
00258                 state->h = ComputeHeuristic(state->MDPstate, pSearchStateSpace); 
00259         }
00260         else 
00261                 state->h = 0;
00262 
00263 #else
00264 
00265         state->h = 0;
00266 
00267 #endif
00268 
00269 
00270 }
00271 
00272 
00273 
00274 void ADPlanner::DeleteSearchStateData(ADState* state)
00275 {
00276         //no memory was allocated
00277         MaxMemoryCounter = 0;
00278         return;
00279 }
00280 
00281 
00282 void ADPlanner::UpdateSetMembership(ADState* state)
00283 {
00284         CKey key;
00285 
00286     if(state->v != state->g)
00287     {
00288         if(state->iterationclosed != pSearchStateSpace_->searchiteration)
00289         {
00290                         key = ComputeKey(state);
00291             if(state->heapindex == 0)
00292                         {
00293                                 //need to remove it because it can happen when updating edge costs and state is in incons
00294                                 if(state->listelem[AD_INCONS_LIST_ID] != NULL)
00295                                         pSearchStateSpace_->inconslist->remove(state, AD_INCONS_LIST_ID); 
00296 
00297                 pSearchStateSpace_->heap->insertheap(state, key);
00298 
00299                         }
00300             else
00301                                 pSearchStateSpace_->heap->updateheap(state, key);
00302         }
00303                 else if(state->listelem[AD_INCONS_LIST_ID] == NULL)
00304                 {
00305                         pSearchStateSpace_->inconslist->insert(state, AD_INCONS_LIST_ID);
00306                 }
00307     }
00308     else
00309     {
00310         if(state->heapindex != 0)
00311             pSearchStateSpace_->heap->deleteheap(state);
00312         else if(state->listelem[AD_INCONS_LIST_ID] != NULL)
00313                         pSearchStateSpace_->inconslist->remove(state, AD_INCONS_LIST_ID);
00314     }
00315 }
00316 
00317 
00318 void ADPlanner::Recomputegval(ADState* state)
00319 {
00320     vector<int> searchpredsIDV; //these are predecessors if search is done forward and successors otherwise
00321     vector<int> costV;
00322         CKey key;
00323         ADState *searchpredstate;
00324 
00325         if(bforwardsearch)
00326             environment_->GetPreds(state->MDPstate->StateID, &searchpredsIDV, &costV);
00327         else
00328                 environment_->GetSuccs(state->MDPstate->StateID, &searchpredsIDV, &costV);
00329 
00330         //iterate through predecessors of s and pick the best
00331         state->g = INFINITECOST;
00332         for(int pind = 0; pind < (int)searchpredsIDV.size(); pind++)
00333         {
00334                 if(environment_->StateID2IndexMapping[searchpredsIDV[pind]][ADMDP_STATEID2IND] == -1)
00335                         continue; //skip the states that do not exist - they can not be used to improve g-value anyway
00336 
00337                 CMDPSTATE* predMDPState = GetState(searchpredsIDV[pind], pSearchStateSpace_);
00338                 int cost = costV[pind];
00339                 searchpredstate = (ADState*)(predMDPState->PlannerSpecificData);
00340         
00341                 //see if it can be used to improve
00342                 if(searchpredstate->callnumberaccessed == pSearchStateSpace_->callnumber && state->g > searchpredstate->v + cost)
00343                 {
00344                         if(bforwardsearch)
00345                         {
00346                                 state->g = searchpredstate->v + cost;
00347                                 state->bestpredstate = predMDPState;
00348                         }
00349                         else
00350                         {
00351                                 state->g = searchpredstate->v + cost;
00352                                 state->bestnextstate = predMDPState;
00353                                 state->costtobestnextstate = cost;
00354                         }
00355                 }               
00356         } //over preds
00357 }
00358 
00359 
00360 
00361 //used for backward search
00362 void ADPlanner::UpdatePredsofOverconsState(ADState* state, ADSearchStateSpace_t* pSearchStateSpace)
00363 {
00364     vector<int> PredIDV;
00365     vector<int> CostV;
00366         CKey key;
00367         ADState *predstate;
00368 
00369     environment_->GetPreds(state->MDPstate->StateID, &PredIDV, &CostV);
00370 
00371         //iterate through predecessors of s
00372         for(int pind = 0; pind < (int)PredIDV.size(); pind++)
00373         {
00374                 CMDPSTATE* PredMDPState = GetState(PredIDV[pind], pSearchStateSpace);
00375                 predstate = (ADState*)(PredMDPState->PlannerSpecificData);
00376                 if(predstate->callnumberaccessed != pSearchStateSpace->callnumber)
00377                         ReInitializeSearchStateInfo(predstate, pSearchStateSpace);
00378 
00379                 //see if we can improve the value of predstate
00380                 if(predstate->g > state->v + CostV[pind])
00381                 {
00382 
00383 #if DEBUG
00384                         if(predstate->MDPstate->StateID == 679256)
00385                         {
00386                                 SBPL_FPRINTF(fDeb, "updating pred %d of overcons exp\n", predstate->MDPstate->StateID);
00387                                 PrintSearchState(predstate, fDeb);
00388                                 SBPL_FPRINTF(fDeb, "\n");
00389                         }
00390 #endif
00391 
00392 
00393                         predstate->g = state->v + CostV[pind];
00394                         predstate->bestnextstate = state->MDPstate;
00395                         predstate->costtobestnextstate = CostV[pind];
00396 
00397                         //update set membership
00398                         UpdateSetMembership(predstate);
00399 
00400 #if DEBUG
00401                         if(predstate->MDPstate->StateID == 679256)
00402                         {
00403                                 SBPL_FPRINTF(fDeb, "updated pred %d of overcons exp\n", predstate->MDPstate->StateID);
00404                                 PrintSearchState(predstate, fDeb);
00405                                 SBPL_FPRINTF(fDeb, "\n");
00406                         }
00407 #endif
00408 
00409                 }
00410         } //for predecessors
00411 
00412 }
00413 
00414 //used for forward search
00415 void ADPlanner::UpdateSuccsofOverconsState(ADState* state, ADSearchStateSpace_t* pSearchStateSpace)
00416 {
00417     vector<int> SuccIDV;
00418     vector<int> CostV;
00419         CKey key;
00420         ADState *succstate;
00421 
00422     environment_->GetSuccs(state->MDPstate->StateID, &SuccIDV, &CostV);
00423 
00424         //iterate through predecessors of s
00425         for(int sind = 0; sind < (int)SuccIDV.size(); sind++)
00426         {
00427                 CMDPSTATE* SuccMDPState = GetState(SuccIDV[sind], pSearchStateSpace);
00428                 int cost = CostV[sind];
00429 
00430                 succstate = (ADState*)(SuccMDPState->PlannerSpecificData);
00431                 if(succstate->callnumberaccessed != pSearchStateSpace->callnumber)
00432                         ReInitializeSearchStateInfo(succstate, pSearchStateSpace);
00433 
00434                 //see if we can improve the value of succstate
00435                 //taking into account the cost of action
00436                 if(succstate->g > state->v + cost)
00437                 {
00438                         succstate->g = state->v + cost;
00439                         succstate->bestpredstate = state->MDPstate; 
00440 
00441                         //update set membership
00442                         UpdateSetMembership(succstate);
00443 
00444                 } //check for cost improvement 
00445 
00446         } //for actions
00447 }
00448 
00449 
00450 
00451 //used for backward search
00452 void ADPlanner::UpdatePredsofUnderconsState(ADState* state, ADSearchStateSpace_t* pSearchStateSpace)
00453 {
00454     vector<int> PredIDV;
00455     vector<int> CostV;
00456         CKey key;
00457         ADState *predstate;
00458 
00459     environment_->GetPreds(state->MDPstate->StateID, &PredIDV, &CostV);
00460 
00461         //iterate through predecessors of s
00462         for(int pind = 0; pind < (int)PredIDV.size(); pind++)
00463         {
00464 
00465                 CMDPSTATE* PredMDPState = GetState(PredIDV[pind], pSearchStateSpace);
00466                 predstate = (ADState*)(PredMDPState->PlannerSpecificData);
00467                 if(predstate->callnumberaccessed != pSearchStateSpace->callnumber)
00468                         ReInitializeSearchStateInfo(predstate, pSearchStateSpace);
00469 
00470                 if(predstate->bestnextstate == state->MDPstate)
00471         {                                 
00472                         Recomputegval(predstate);
00473                         UpdateSetMembership(predstate);
00474 
00475 #if DEBUG
00476                         if(predstate->MDPstate->StateID == 679256)
00477                         {
00478                                 SBPL_FPRINTF(fDeb, "updated pred %d of undercons exp\n", predstate->MDPstate->StateID);
00479                                 PrintSearchState(predstate, fDeb);
00480                                 SBPL_FPRINTF(fDeb, "\n");
00481                         }
00482 #endif
00483 
00484                 }               
00485         } //for predecessors
00486 
00487 }
00488 
00489 
00490 
00491 //used for forward search
00492 void ADPlanner::UpdateSuccsofUnderconsState(ADState* state, ADSearchStateSpace_t* pSearchStateSpace)
00493 {
00494     vector<int> SuccIDV;
00495     vector<int> CostV;
00496         CKey key;
00497         ADState *succstate;
00498 
00499     environment_->GetSuccs(state->MDPstate->StateID, &SuccIDV, &CostV);
00500 
00501         //iterate through predecessors of s
00502         for(int sind = 0; sind < (int)SuccIDV.size(); sind++)
00503         {
00504                 CMDPSTATE* SuccMDPState = GetState(SuccIDV[sind], pSearchStateSpace);
00505                 succstate = (ADState*)(SuccMDPState->PlannerSpecificData);
00506 
00507                 if(succstate->callnumberaccessed != pSearchStateSpace->callnumber)
00508                         ReInitializeSearchStateInfo(succstate, pSearchStateSpace);
00509 
00510                 if(succstate->bestpredstate == state->MDPstate)
00511         {                                 
00512                         Recomputegval(succstate);
00513                         UpdateSetMembership(succstate);
00514                 }               
00515 
00516         } //for actions
00517 }
00518 
00519 
00520 
00521 int ADPlanner::GetGVal(int StateID, ADSearchStateSpace_t* pSearchStateSpace)
00522 {
00523          CMDPSTATE* cmdp_state = GetState(StateID, pSearchStateSpace);
00524          ADState* state = (ADState*)cmdp_state->PlannerSpecificData;
00525          return state->g;
00526 }
00527 
00528 //returns 1 if the solution is found, 0 if the solution does not exist and 2 if it ran out of time
00529 int ADPlanner::ComputePath(ADSearchStateSpace_t* pSearchStateSpace, double MaxNumofSecs)
00530 {
00531         int expands;
00532         ADState *state, *searchgoalstate;
00533         CKey key, minkey;
00534         CKey goalkey;
00535 
00536         expands = 0;
00537 
00538         if(pSearchStateSpace->searchgoalstate == NULL)
00539         {
00540                 SBPL_ERROR("ERROR searching: no goal state is set\n");
00541                 throw new SBPL_Exception();
00542         }
00543 
00544         //goal state
00545         searchgoalstate = (ADState*)(pSearchStateSpace->searchgoalstate->PlannerSpecificData);
00546         if(searchgoalstate->callnumberaccessed != pSearchStateSpace->callnumber)
00547                 ReInitializeSearchStateInfo(searchgoalstate, pSearchStateSpace);
00548 
00549         //set goal key
00550         goalkey = ComputeKey(searchgoalstate);
00551 
00552         //expand states until done
00553         minkey = pSearchStateSpace->heap->getminkeyheap();
00554         CKey oldkey = minkey;
00555         while(!pSearchStateSpace->heap->emptyheap() && minkey.key[0] < INFINITECOST && (goalkey > minkey || searchgoalstate->g > searchgoalstate->v) &&
00556                 (clock()-TimeStarted) < MaxNumofSecs*(double)CLOCKS_PER_SEC) 
00557     {
00558 
00559                 //get the state         
00560                 state = (ADState*)pSearchStateSpace->heap->deleteminheap();
00561 
00562 
00563 #if DEBUG
00564                 CKey debkey = ComputeKey(state);
00565                 //SBPL_FPRINTF(fDeb, "expanding state(%d): g=%u v=%u h=%d key=[%d %d] iterc=%d callnuma=%d expands=%d (g(goal)=%u)\n",
00566                 //      state->MDPstate->StateID, state->g, state->v, state->h, (int)debkey[0], (int)debkey[1],  
00567                 //      state->iterationclosed, state->callnumberaccessed, state->numofexpands, searchgoalstate->g);
00568                 if(state->MDPstate->StateID == 679256)
00569                 {
00570                         SBPL_FPRINTF(fDeb, "expanding state %d with key=[%d %d]:\n", state->MDPstate->StateID, (int)debkey[0], (int)debkey[1]);
00571                         PrintSearchState(state, fDeb);
00572                         environment_->PrintState(state->MDPstate->StateID, true, fDeb);
00573                 }
00574                 //SBPL_FFLUSH(fDeb);
00575                 if(state->listelem[AD_INCONS_LIST_ID] != NULL)
00576                 {
00577                         SBPL_ERROR("ERROR: expanding state from INCONS list\n");
00578                         throw new SBPL_Exception();
00579                 }
00580 #endif
00581 
00582 
00583 #if DEBUG
00584                 if(minkey.key[0] < oldkey.key[0] && fabs(this->finitial_eps - 1.0) < ERR_EPS)
00585                 {
00586                         SBPL_PRINTF("WARN in search: the sequence of keys decreases in an optimal search\n");
00587                         //throw new SBPL_Exception();
00588                 }
00589                 oldkey = minkey;
00590 #endif
00591 
00592 
00593                 if(state->v == state->g)
00594                 {
00595                         SBPL_ERROR("ERROR: consistent state is being expanded\n");
00596                         throw new SBPL_Exception();
00597                 }
00598 
00599                 //new expand      
00600                 expands++;
00601                 state->numofexpands++;
00602 
00603                 if(state->v > state->g)
00604                 {
00605                         //overconsistent expansion
00606 
00607                         //recompute state value      
00608                         state->v = state->g;
00609                         state->iterationclosed = pSearchStateSpace->searchiteration;
00610 
00611                         if(!bforwardsearch)
00612                         {
00613                                 UpdatePredsofOverconsState(state, pSearchStateSpace);
00614                         }
00615                         else
00616                         {
00617                                 UpdateSuccsofOverconsState(state, pSearchStateSpace);
00618                         }
00619                 }
00620                 else
00621                 {
00622                         //underconsistent expansion
00623 
00624                         //force the state to be overconsistent
00625                         state->v = INFINITECOST;
00626         
00627                         //update state membership
00628                         UpdateSetMembership(state);
00629 
00630 
00631                         if(!bforwardsearch)
00632                         {
00633                                 UpdatePredsofUnderconsState(state, pSearchStateSpace);
00634                         }
00635                         else
00636                                 UpdateSuccsofUnderconsState(state, pSearchStateSpace);
00637 
00638                 }
00639       
00640 
00641                 //recompute minkey
00642                 minkey = pSearchStateSpace->heap->getminkeyheap();
00643 
00644                 //recompute goalkey if necessary
00645                 goalkey = ComputeKey(searchgoalstate);
00646 
00647                 if(expands%100000 == 0 && expands > 0)
00648                 {
00649                         SBPL_PRINTF("expands so far=%u\n", expands);
00650                 }
00651 
00652         }
00653 
00654         int retv = 1;
00655         if(searchgoalstate->g == INFINITECOST && pSearchStateSpace->heap->emptyheap())
00656         {
00657                 SBPL_PRINTF("solution does not exist: search exited because heap is empty\n");
00658 
00659 #if DEBUG
00660                 SBPL_FPRINTF(fDeb, "solution does not exist: search exited because heap is empty\n");
00661 #endif
00662 
00663                 retv = 0;
00664         }
00665         else if(!pSearchStateSpace->heap->emptyheap() && (goalkey > minkey || searchgoalstate->g > searchgoalstate->v))
00666         {
00667                 SBPL_PRINTF("search exited because it ran out of time\n");
00668 #if DEBUG
00669                 SBPL_FPRINTF(fDeb, "search exited because it ran out of time\n");
00670 #endif
00671                 retv = 2;
00672         }
00673         else if(searchgoalstate->g == INFINITECOST && !pSearchStateSpace->heap->emptyheap())
00674         {
00675                 SBPL_PRINTF("solution does not exist: search exited because all candidates for expansion have infinite heuristics\n");
00676 #if DEBUG
00677                 SBPL_FPRINTF(fDeb, "solution does not exist: search exited because all candidates for expansion have infinite heuristics\n");
00678 #endif
00679                 retv = 0;
00680         }
00681         else
00682         {
00683                 SBPL_PRINTF("search exited with a solution for eps=%.3f\n", pSearchStateSpace->eps);
00684 #if DEBUG
00685                 SBPL_FPRINTF(fDeb, "search exited with a solution for eps=%.3f\n", pSearchStateSpace->eps);
00686 #endif
00687                 retv = 1;
00688         }
00689 
00690         //SBPL_FPRINTF(fDeb, "expanded=%d\n", expands);
00691 
00692         searchexpands += expands;
00693 
00694         return retv;            
00695 }
00696 
00697 
00698 void ADPlanner::BuildNewOPENList(ADSearchStateSpace_t* pSearchStateSpace)
00699 {
00700         ADState *state;
00701         CKey key;
00702         CHeap* pheap = pSearchStateSpace->heap;
00703         CList* pinconslist = pSearchStateSpace->inconslist; 
00704                 
00705         //move incons into open
00706         while(pinconslist->firstelement != NULL)
00707           {
00708             state = (ADState*)pinconslist->firstelement->liststate;
00709             
00710             //compute f-value
00711                 key = ComputeKey(state);
00712             
00713             //insert into OPEN
00714         if(state->heapindex == 0)
00715             pheap->insertheap(state, key);
00716         else
00717             pheap->updateheap(state, key); //should never happen, but sometimes it does - somewhere there is a bug TODO
00718             //remove from INCONS
00719             pinconslist->remove(state, AD_INCONS_LIST_ID);
00720           }
00721 
00722         pSearchStateSpace->bRebuildOpenList = false;
00723 
00724 }
00725 
00726 
00727 void ADPlanner::Reevaluatefvals(ADSearchStateSpace_t* pSearchStateSpace)
00728 {
00729         CKey key;
00730         int i;
00731         CHeap* pheap = pSearchStateSpace->heap;
00732         
00733 #if DEBUG
00734         SBPL_FPRINTF(fDeb, "re-computing heap priorities\n");
00735 #endif
00736 
00737         //recompute priorities for states in OPEN and reorder it
00738         for (i = 1; i <= pheap->currentsize; ++i)
00739           {
00740                 ADState* state = (ADState*)pheap->heap[i].heapstate;
00741                 pheap->heap[i].key = ComputeKey(state);
00742           }
00743         pheap->makeheap();
00744 
00745         pSearchStateSpace->bReevaluatefvals = false;
00746 }
00747 
00748 
00749 
00750 
00751 //creates (allocates memory) search state space
00752 //does not initialize search statespace
00753 int ADPlanner::CreateSearchStateSpace(ADSearchStateSpace_t* pSearchStateSpace)
00754 {
00755 
00756         //create a heap
00757         pSearchStateSpace->heap = new CHeap;
00758         pSearchStateSpace->inconslist = new CList;
00759         MaxMemoryCounter += sizeof(CHeap);
00760         MaxMemoryCounter += sizeof(CList);
00761 
00762         pSearchStateSpace->searchgoalstate = NULL;
00763         pSearchStateSpace->searchstartstate = NULL;
00764 
00765         searchexpands = 0;
00766 
00767 
00768     pSearchStateSpace->bReinitializeSearchStateSpace = false;
00769         
00770         return 1;
00771 }
00772 
00773 //deallocates memory used by SearchStateSpace
00774 void ADPlanner::DeleteSearchStateSpace(ADSearchStateSpace_t* pSearchStateSpace)
00775 {
00776         if(pSearchStateSpace->heap != NULL)
00777         {
00778                 pSearchStateSpace->heap->makeemptyheap();
00779                 delete pSearchStateSpace->heap;
00780                 pSearchStateSpace->heap = NULL;
00781         }
00782 
00783         if(pSearchStateSpace->inconslist != NULL)
00784         {
00785                 pSearchStateSpace->inconslist->makeemptylist(AD_INCONS_LIST_ID);
00786                 delete pSearchStateSpace->inconslist;
00787                 pSearchStateSpace->inconslist = NULL;
00788         }
00789 
00790         //delete the states themselves
00791         int iend = (int)pSearchStateSpace->searchMDP.StateArray.size();
00792         for(int i=0; i < iend; i++)
00793         {
00794                 CMDPSTATE* state = pSearchStateSpace->searchMDP.StateArray[i];
00795                 DeleteSearchStateData((ADState*)state->PlannerSpecificData);
00796                 free(state->PlannerSpecificData); // allocated with malloc() on line 199 of revision 19485
00797                 state->PlannerSpecificData = NULL;
00798         }
00799         pSearchStateSpace->searchMDP.Delete();
00800         environment_->StateID2IndexMapping.clear();
00801 }
00802 
00803 
00804 
00805 //reset properly search state space
00806 //needs to be done before deleting states
00807 int ADPlanner::ResetSearchStateSpace(ADSearchStateSpace_t* pSearchStateSpace)
00808 {
00809         pSearchStateSpace->heap->makeemptyheap();
00810         pSearchStateSpace->inconslist->makeemptylist(AD_INCONS_LIST_ID);
00811 
00812         return 1;
00813 }
00814 
00815 //initialization before each search
00816 void ADPlanner::ReInitializeSearchStateSpace(ADSearchStateSpace_t* pSearchStateSpace)
00817 {
00818         CKey key;
00819 
00820         //increase callnumber
00821         pSearchStateSpace->callnumber++;
00822 
00823         //reset iteration
00824         pSearchStateSpace->searchiteration = 0;
00825 
00826 
00827 #if DEBUG
00828     SBPL_FPRINTF(fDeb, "reinitializing search state-space (new call number=%d search iter=%d)\n", 
00829             pSearchStateSpace->callnumber,pSearchStateSpace->searchiteration );
00830 #endif
00831 
00832 
00833 
00834         pSearchStateSpace->heap->makeemptyheap();
00835         pSearchStateSpace->inconslist->makeemptylist(AD_INCONS_LIST_ID);
00836 
00837     //reset 
00838         pSearchStateSpace->eps = this->finitial_eps;
00839     pSearchStateSpace->eps_satisfied = INFINITECOST;
00840 
00841         //initialize start state
00842         ADState* startstateinfo = (ADState*)(pSearchStateSpace->searchstartstate->PlannerSpecificData);
00843         if(startstateinfo->callnumberaccessed != pSearchStateSpace->callnumber)
00844                 ReInitializeSearchStateInfo(startstateinfo, pSearchStateSpace);
00845 
00846         startstateinfo->g = 0;
00847 
00848         //insert start state into the heap
00849         key = ComputeKey(startstateinfo);
00850         pSearchStateSpace->heap->insertheap(startstateinfo, key);
00851 
00852     pSearchStateSpace->bReinitializeSearchStateSpace = false;
00853         pSearchStateSpace->bReevaluatefvals = false;
00854         pSearchStateSpace->bRebuildOpenList = false;
00855 }
00856 
00857 //very first initialization
00858 int ADPlanner::InitializeSearchStateSpace(ADSearchStateSpace_t* pSearchStateSpace)
00859 {
00860 
00861         if(pSearchStateSpace->heap->currentsize != 0 || 
00862                 pSearchStateSpace->inconslist->currentsize != 0)
00863         {
00864                 SBPL_ERROR("ERROR in InitializeSearchStateSpace: heap or list is not empty\n");
00865                 throw new SBPL_Exception();
00866         }
00867 
00868         pSearchStateSpace->eps = this->finitial_eps;
00869     pSearchStateSpace->eps_satisfied = INFINITECOST;
00870         pSearchStateSpace->searchiteration = 0;
00871         pSearchStateSpace->callnumber = 0;
00872         pSearchStateSpace->bReevaluatefvals = false;
00873         pSearchStateSpace->bRebuildOpenList = false;
00874 
00875 
00876         //create and set the search start state
00877         pSearchStateSpace->searchgoalstate = NULL;
00878         //pSearchStateSpace->searchstartstate = GetState(SearchStartStateID, pSearchStateSpace);
00879     pSearchStateSpace->searchstartstate = NULL;
00880         
00881 
00882     pSearchStateSpace->bReinitializeSearchStateSpace = true;
00883 
00884         return 1;
00885 
00886 }
00887 
00888 
00889 int ADPlanner::SetSearchGoalState(int SearchGoalStateID, ADSearchStateSpace_t* pSearchStateSpace)
00890 {
00891 
00892         if(pSearchStateSpace->searchgoalstate == NULL || 
00893                 pSearchStateSpace->searchgoalstate->StateID != SearchGoalStateID)
00894         {
00895                 pSearchStateSpace->searchgoalstate = GetState(SearchGoalStateID, pSearchStateSpace);
00896 
00897                 //current solution may be invalid
00898                 pSearchStateSpace->eps_satisfied = INFINITECOST;
00899                 pSearchStateSpace_->eps = this->finitial_eps;           
00900 
00901                 //recompute heuristic for the heap if heuristics is used
00902 #if USE_HEUR
00903                 int i;
00904                 //TODO - should get rid of and instead use iteration to re-compute h-values online as needed
00905                 for(i = 0; i < (int)pSearchStateSpace->searchMDP.StateArray.size(); i++)
00906                 {
00907                         CMDPSTATE* MDPstate = pSearchStateSpace->searchMDP.StateArray[i];
00908                         ADState* state = (ADState*)MDPstate->PlannerSpecificData;
00909                         state->h = ComputeHeuristic(MDPstate, pSearchStateSpace);
00910                 }
00911 #if DEBUG
00912                 SBPL_PRINTF("re-evaluated heuristic values for %d states\n", i);
00913 #endif
00914                 
00915                 pSearchStateSpace->bReevaluatefvals = true;
00916 #endif
00917         }
00918 
00919 
00920         return 1;
00921 
00922 }
00923 
00924 
00925 int ADPlanner::SetSearchStartState(int SearchStartStateID, ADSearchStateSpace_t* pSearchStateSpace)
00926 {
00927         CMDPSTATE* MDPstate = GetState(SearchStartStateID, pSearchStateSpace); 
00928 
00929         if(MDPstate !=  pSearchStateSpace->searchstartstate)
00930         {       
00931                 pSearchStateSpace->searchstartstate = MDPstate;
00932                 pSearchStateSpace->bReinitializeSearchStateSpace = true;
00933                 pSearchStateSpace->bRebuildOpenList = true;
00934         }
00935 
00936         return 1;
00937 
00938 }
00939 
00940 
00941 
00942 int ADPlanner::ReconstructPath(ADSearchStateSpace_t* pSearchStateSpace)
00943 {       
00944 
00945         //nothing to do, if search is backward
00946         if(bforwardsearch)
00947         {
00948 
00949                 CMDPSTATE* MDPstate = pSearchStateSpace->searchgoalstate;
00950                 CMDPSTATE* PredMDPstate;
00951                 ADState *predstateinfo, *stateinfo;
00952                         
00953                 int steps = 0;
00954                 const int max_steps = 100000;
00955                 while(MDPstate != pSearchStateSpace->searchstartstate && steps < max_steps)
00956                 {
00957                         steps++;
00958 
00959                         stateinfo = (ADState*)MDPstate->PlannerSpecificData;
00960 
00961                         if(stateinfo->g == INFINITECOST)
00962                         {       
00963                                 //SBPL_ERROR("ERROR in ReconstructPath: g of the state on the path is INFINITE\n");
00964                                 //throw new SBPL_Exception();
00965                                 return -1;
00966                         }
00967 
00968                         if(stateinfo->bestpredstate == NULL)
00969                         {
00970                                 SBPL_ERROR("ERROR in ReconstructPath: bestpred is NULL\n");
00971                                 throw new SBPL_Exception();
00972                         }
00973 
00974                         //get the parent state
00975                         PredMDPstate = stateinfo->bestpredstate;
00976                         predstateinfo = (ADState*)PredMDPstate->PlannerSpecificData;
00977 
00978                         //set its best next info
00979                         predstateinfo->bestnextstate = MDPstate;
00980 
00981                         //check the decrease of g-values along the path
00982                         if(predstateinfo->v >= stateinfo->g)
00983                         {
00984                                 SBPL_ERROR("ERROR in ReconstructPath: g-values are non-decreasing\n");
00985                                 throw new SBPL_Exception();
00986                         }
00987 
00988                         //transition back
00989                         MDPstate = PredMDPstate;
00990                 }
00991 
00992                 if(MDPstate != pSearchStateSpace->searchstartstate){
00993                         SBPL_ERROR("ERROR: Failed to reconstruct path (compute bestnextstate pointers): steps processed=%d\n", steps);
00994                         return 0;
00995                 }
00996         }
00997 
00998         return 1;
00999 }
01000 
01001 
01002 void ADPlanner::PrintSearchState(ADState* searchstateinfo, FILE* fOut)
01003 {
01004 
01005         CKey key = ComputeKey(searchstateinfo);
01006         SBPL_FPRINTF(fOut, "g=%d v=%d h = %d heapindex=%d inconslist=%d key=[%d %d] iterc=%d callnuma=%d expands=%d (current callnum=%d iter=%d)", 
01007                         searchstateinfo->g, searchstateinfo->v, searchstateinfo->h, searchstateinfo->heapindex, (searchstateinfo->listelem[AD_INCONS_LIST_ID] != NULL),
01008                         (int)key[0], (int)key[1], searchstateinfo->iterationclosed, searchstateinfo->callnumberaccessed, searchstateinfo->numofexpands,
01009                                 this->pSearchStateSpace_->callnumber, this->pSearchStateSpace_->searchiteration);
01010 
01011 }
01012 
01013 void ADPlanner::PrintSearchPath(ADSearchStateSpace_t* pSearchStateSpace, FILE* fOut)
01014 {
01015   ADState* searchstateinfo;
01016   CMDPSTATE* state = pSearchStateSpace->searchgoalstate;
01017   CMDPSTATE* nextstate = NULL;
01018 
01019   if(fOut == NULL)
01020     fOut = stdout;
01021 
01022   int PathCost = ((ADState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g;
01023 
01024   SBPL_FPRINTF(fOut, "Printing a path from state %d to the search start state %d\n", 
01025           state->StateID, pSearchStateSpace->searchstartstate->StateID);
01026   SBPL_FPRINTF(fOut, "Path cost = %d:\n", PathCost);
01027                                 
01028   environment_->PrintState(state->StateID, true, fOut);
01029 
01030   int costFromStart = 0;
01031   int steps = 0;
01032   const int max_steps = 100000;
01033   while(state->StateID != pSearchStateSpace->searchstartstate->StateID && steps < max_steps)
01034     {
01035       steps++;
01036 
01037       SBPL_FPRINTF(fOut, "state %d ", state->StateID);
01038 
01039       if(state->PlannerSpecificData == NULL)
01040         {
01041           SBPL_FPRINTF(fOut, "path does not exist since search data does not exist\n");
01042           break;
01043         }
01044 
01045       searchstateinfo = (ADState*)state->PlannerSpecificData;
01046 
01047       if(bforwardsearch)
01048         nextstate = searchstateinfo->bestpredstate;
01049       else
01050         nextstate = searchstateinfo->bestnextstate;
01051 
01052       if(nextstate == NULL)
01053         {
01054           SBPL_FPRINTF(fOut, "path does not exist since nextstate == NULL\n");
01055           break;
01056         }
01057       if(searchstateinfo->g == INFINITECOST)
01058         {
01059           SBPL_FPRINTF(fOut, "path does not exist since state->g == NULL\n");
01060           break;
01061         }
01062 
01063       int costToGoal = PathCost - costFromStart;
01064       if(!bforwardsearch)
01065         {
01066           //otherwise this cost is not even set
01067           costFromStart += searchstateinfo->costtobestnextstate;
01068         }
01069 
01070 
01071 #if DEBUG
01072       if(searchstateinfo->g > searchstateinfo->v){
01073         SBPL_FPRINTF(fOut, "ERROR: underconsistent state %d is encountered\n", state->StateID);
01074         throw new SBPL_Exception();
01075       }
01076 
01077       if(!bforwardsearch) //otherwise this cost is not even set
01078         {
01079           if(nextstate->PlannerSpecificData != NULL && searchstateinfo->g < searchstateinfo->costtobestnextstate + ((ADState*)(nextstate->PlannerSpecificData))->g)
01080             {
01081               SBPL_FPRINTF(fOut, "ERROR: g(source) < c(source,target) + g(target)\n");
01082               throw new SBPL_Exception();
01083             }
01084         }
01085 
01086 #endif
01087 
01088       //PrintSearchState(searchstateinfo, fOut);        
01089       SBPL_FPRINTF(fOut, "-->state %d ctg = %d  ", 
01090               nextstate->StateID, costToGoal);
01091 
01092       state = nextstate;
01093 
01094       environment_->PrintState(state->StateID, true, fOut);
01095 
01096     }
01097 
01098   if(state->StateID != pSearchStateSpace->searchstartstate->StateID){
01099     SBPL_ERROR("ERROR: Failed to printsearchpath, max_steps reached\n");
01100     return;
01101   }
01102 
01103 }
01104 
01105 int ADPlanner::getHeurValue(ADSearchStateSpace_t* pSearchStateSpace, int StateID)
01106 {
01107         CMDPSTATE* MDPstate = GetState(StateID, pSearchStateSpace);
01108         ADState* searchstateinfo = (ADState*)MDPstate->PlannerSpecificData;
01109         return searchstateinfo->h;
01110 }
01111 
01112 
01113 vector<int> ADPlanner::GetSearchPath(ADSearchStateSpace_t* pSearchStateSpace, int& solcost)
01114 {
01115   vector<int> SuccIDV;
01116   vector<int> CostV;
01117   vector<int> wholePathIds;
01118   ADState* searchstateinfo;
01119   CMDPSTATE* state = NULL; 
01120   CMDPSTATE* goalstate = NULL;
01121   CMDPSTATE* startstate=NULL;
01122 
01123   if(bforwardsearch)
01124     {
01125       startstate = pSearchStateSpace->searchstartstate;
01126       goalstate = pSearchStateSpace->searchgoalstate;
01127       
01128       //reconstruct the path by setting bestnextstate pointers appropriately
01129       if(ReconstructPath(pSearchStateSpace) != 1){
01130         solcost = INFINITECOST;
01131         return wholePathIds;
01132       }
01133     }
01134   else
01135     {
01136       startstate = pSearchStateSpace->searchgoalstate;
01137       goalstate = pSearchStateSpace->searchstartstate;
01138     }
01139 
01140 
01141 #if DEBUG
01142   //PrintSearchPath(pSearchStateSpace, fDeb);
01143 #endif
01144 
01145 
01146   state = startstate;
01147 
01148   wholePathIds.push_back(state->StateID);
01149   solcost = 0;
01150 
01151   FILE* fOut = stdout;
01152   if(fOut == NULL){
01153     SBPL_ERROR("ERROR: could not open file\n");
01154     throw new SBPL_Exception();
01155   }
01156   int steps = 0;
01157   const int max_steps = 100000;
01158   while(state->StateID != goalstate->StateID && steps < max_steps)
01159     {
01160       steps++;
01161 
01162       if(state->PlannerSpecificData == NULL)
01163         {
01164           SBPL_FPRINTF(fOut, "path does not exist since search data does not exist\n");
01165           break;
01166         }
01167 
01168       searchstateinfo = (ADState*)state->PlannerSpecificData;
01169 
01170       if(searchstateinfo->bestnextstate == NULL)
01171         {
01172           SBPL_FPRINTF(fOut, "path does not exist since bestnextstate == NULL\n");
01173           break;
01174         }
01175       if(searchstateinfo->g == INFINITECOST)
01176         {
01177           SBPL_FPRINTF(fOut, "path does not exist since bestnextstate == NULL\n");
01178           break;
01179         }
01180 
01181       environment_->GetSuccs(state->StateID, &SuccIDV, &CostV);
01182       int actioncost = INFINITECOST;
01183       for(int i = 0; i < (int)SuccIDV.size(); i++)
01184         {   
01185     if(SuccIDV.at(i) == searchstateinfo->bestnextstate->StateID && CostV.at(i)<actioncost)
01186             actioncost = CostV.at(i);
01187 
01188         }
01189       solcost += actioncost;
01190 
01191       if(searchstateinfo->v < searchstateinfo->g)
01192         {
01193           SBPL_ERROR("ERROR: underconsistent state on the path\n");
01194           PrintSearchState(searchstateinfo, stdout);
01195           //SBPL_FPRINTF(fDeb, "ERROR: underconsistent state on the path\n");
01196           //PrintSearchState(searchstateinfo, fDeb);
01197           throw new SBPL_Exception();
01198         }
01199 
01200       //SBPL_FPRINTF(fDeb, "actioncost=%d between states %d and %d\n", 
01201       //        actioncost, state->StateID, searchstateinfo->bestnextstate->StateID);
01202       //environment_->PrintState(state->StateID, false, fDeb);
01203       //environment_->PrintState(searchstateinfo->bestnextstate->StateID, false, fDeb);
01204 
01205 
01206       state = searchstateinfo->bestnextstate;
01207 
01208       wholePathIds.push_back(state->StateID);
01209     }
01210 
01211   if(state->StateID != goalstate->StateID){
01212     SBPL_ERROR("ERROR: Failed to getsearchpath, steps processed=%d\n", steps);
01213     wholePathIds.clear();
01214     solcost = INFINITECOST;
01215     return wholePathIds;
01216   }
01217 
01218   //PrintSearchPath(pSearchStateSpace, stdout); 
01219         
01220   return wholePathIds;
01221 }
01222 
01223 
01224 
01225 bool ADPlanner::Search(ADSearchStateSpace_t* pSearchStateSpace, vector<int>& pathIds, int & PathCost, bool bFirstSolution, bool bOptimalSolution, double MaxNumofSecs)
01226 {
01227         CKey key;
01228         TimeStarted = clock();
01229     searchexpands = 0;
01230 
01231 #if DEBUG
01232         SBPL_FPRINTF(fDeb, "new search call (call number=%d)\n", pSearchStateSpace->callnumber);
01233 #endif
01234 
01235     if(pSearchStateSpace->bReinitializeSearchStateSpace == true){
01236         //re-initialize state space 
01237         ReInitializeSearchStateSpace(pSearchStateSpace);
01238     }
01239 
01240 
01241         if(bOptimalSolution)
01242         {
01243                 pSearchStateSpace->eps = 1;
01244                 MaxNumofSecs = INFINITECOST;
01245         }
01246         else if(bFirstSolution)
01247         {
01248                 MaxNumofSecs = INFINITECOST;
01249         }
01250 
01251         //ensure heuristics are up-to-date
01252         environment_->EnsureHeuristicsUpdated((bforwardsearch==true));
01253 
01254         //the main loop of AD*
01255         int prevexpands = 0;
01256   clock_t loop_time;
01257         while(pSearchStateSpace->eps_satisfied > AD_FINAL_EPS && 
01258                 (clock()- TimeStarted) < MaxNumofSecs*(double)CLOCKS_PER_SEC)
01259         {
01260     loop_time = clock();
01261                 //it will be a new search iteration
01262                 if(pSearchStateSpace->searchiteration == 0) pSearchStateSpace->searchiteration++;
01263 
01264                 //decrease eps for all subsequent iterations
01265                 if(fabs(pSearchStateSpace->eps_satisfied - pSearchStateSpace->eps) < ERR_EPS && !bFirstSolution)
01266                 {
01267                         pSearchStateSpace->eps = pSearchStateSpace->eps - AD_DECREASE_EPS;
01268                         if(pSearchStateSpace->eps < AD_FINAL_EPS)
01269                                 pSearchStateSpace->eps = AD_FINAL_EPS;
01270 
01271 
01272                         pSearchStateSpace->bReevaluatefvals = true;
01273                         pSearchStateSpace->bRebuildOpenList = true;
01274 
01275                         pSearchStateSpace->searchiteration++;
01276                 }
01277 
01278                 //build a new open list by merging it with incons one
01279                 if(pSearchStateSpace->bRebuildOpenList)
01280                         BuildNewOPENList(pSearchStateSpace);
01281                 
01282                 //re-compute f-values if necessary and reorder the heap
01283                 if(pSearchStateSpace->bReevaluatefvals)
01284                         Reevaluatefvals(pSearchStateSpace);
01285 
01286 
01287                 //improve or compute path
01288                 if(ComputePath(pSearchStateSpace, MaxNumofSecs) == 1){
01289             pSearchStateSpace->eps_satisfied = pSearchStateSpace->eps;
01290         }
01291 
01292                 //print the solution cost and eps bound
01293                 SBPL_PRINTF("eps=%f expands=%d g(sstart)=%d\n", pSearchStateSpace->eps_satisfied, searchexpands - prevexpands,
01294                                                         ((ADState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g);
01295 
01296     if(pSearchStateSpace->eps_satisfied == finitial_eps && pSearchStateSpace->eps == finitial_eps)
01297     {
01298       finitial_eps_planning_time = double(clock()-loop_time)/CLOCKS_PER_SEC;
01299       num_of_expands_initial_solution = searchexpands - prevexpands;
01300     }
01301 
01302 #if DEBUG
01303         SBPL_FPRINTF(fDeb, "eps=%f eps_sat=%f expands=%d g(sstart)=%d\n", pSearchStateSpace->eps, pSearchStateSpace->eps_satisfied, searchexpands - prevexpands,
01304                                                         ((ADState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g);
01305 #endif
01306                 prevexpands = searchexpands;
01307 
01308 
01309                 //if just the first solution then we are done
01310                 if(bFirstSolution)
01311                         break;
01312 
01313                 //no solution exists
01314                 if(((ADState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g == INFINITECOST)
01315                         break;
01316 
01317         }
01318 
01319 
01320 #if DEBUG
01321         SBPL_FFLUSH(fDeb);
01322 #endif
01323 
01324         PathCost = ((ADState*)pSearchStateSpace->searchgoalstate->PlannerSpecificData)->g;
01325         MaxMemoryCounter += environment_->StateID2IndexMapping.size()*sizeof(int);
01326         
01327         SBPL_PRINTF("MaxMemoryCounter = %d\n", MaxMemoryCounter);
01328 
01329         int solcost = INFINITECOST;
01330     bool ret = false;
01331         if(PathCost == INFINITECOST || pSearchStateSpace_->eps_satisfied == INFINITECOST)
01332         {
01333                 SBPL_PRINTF("could not find a solution\n");
01334                 ret = false;
01335         }
01336         else
01337         {
01338                 SBPL_PRINTF("solution is found\n");
01339 
01340         pathIds = GetSearchPath(pSearchStateSpace, solcost);
01341         ret = true;
01342         }
01343 
01344         SBPL_PRINTF("total expands this call = %d, planning time = %.3f secs, solution cost=%d\n", 
01345            searchexpands, (clock()-TimeStarted)/((double)CLOCKS_PER_SEC), solcost);
01346   final_eps_planning_time = (clock()-TimeStarted)/((double)CLOCKS_PER_SEC);
01347   final_eps = pSearchStateSpace->eps_satisfied;
01348     
01349 
01350     //SBPL_FPRINTF(fStat, "%d %d\n", searchexpands, solcost);
01351 
01352         return ret;
01353 
01354 }
01355 
01356 void ADPlanner::Update_SearchSuccs_of_ChangedEdges(vector<int> const * statesIDV)
01357 {
01358         SBPL_PRINTF("updating %d affected states\n", (unsigned int)statesIDV->size());
01359 
01360         if(statesIDV->size() > environment_->StateID2IndexMapping.size()/10)
01361         {
01362                 SBPL_PRINTF("skipping affected states and instead restarting planner from scratch\n");
01363                 pSearchStateSpace_->bReinitializeSearchStateSpace = true;
01364         }
01365 
01366         //it will be a new search iteration
01367         pSearchStateSpace_->searchiteration++;
01368 
01369         //will need to rebuild open list
01370         pSearchStateSpace_->bRebuildOpenList = true;
01371 
01372 
01373         int numofstatesaffected = 0;
01374         for(int pind = 0; pind < (int)statesIDV->size(); pind++)
01375         {
01376                 int stateID = statesIDV->at(pind);
01377 
01378                 //first check that the state exists (to avoid creation of additional states)
01379                 if(environment_->StateID2IndexMapping[stateID][ADMDP_STATEID2IND] == -1)
01380                         continue;
01381 
01382                 //now get the state
01383                 CMDPSTATE* state = GetState(stateID, pSearchStateSpace_);
01384                 ADState* searchstateinfo = (ADState*)state->PlannerSpecificData;
01385 
01386                 //now check that the state is not start state and was created after last search reset
01387                 if(stateID != pSearchStateSpace_->searchstartstate->StateID && searchstateinfo->callnumberaccessed == pSearchStateSpace_->callnumber)
01388                 {
01389 
01390 #if DEBUG
01391                         SBPL_FPRINTF(fDeb, "updating affected state %d:\n", stateID);
01392                         PrintSearchState(searchstateinfo, fDeb);
01393                         SBPL_FPRINTF(fDeb, "\n");
01394 #endif
01395 
01396                         //now we really do need to update it
01397                         Recomputegval(searchstateinfo);
01398                         UpdateSetMembership(searchstateinfo);
01399                         numofstatesaffected++;
01400 
01401 #if DEBUG
01402                         SBPL_FPRINTF(fDeb, "the state %d after update\n", stateID);
01403                         PrintSearchState(searchstateinfo, fDeb);
01404                         SBPL_FPRINTF(fDeb, "\n");
01405 #endif
01406 
01407 
01408                 }
01409         }
01410 
01411         //TODO - check. I believe that there are cases when number of states generated is drastically smaller than the number of states really affected, which is a bug!
01412         SBPL_PRINTF("%d states really affected (%d states generated total so far)\n", numofstatesaffected, (int)environment_->StateID2IndexMapping.size());
01413 
01414         //reset eps for which we know a path was computed
01415         if(numofstatesaffected > 0)
01416         {
01417                 //make sure eps is reset appropriately
01418                 pSearchStateSpace_->eps = this->finitial_eps;
01419 
01420                 //reset the satisfied eps
01421             pSearchStateSpace_->eps_satisfied = INFINITECOST;
01422         }
01423 
01424 }
01425 
01426 
01427 //-----------------------------Interface function-----------------------------------------------------
01428 //returns 1 if found a solution, and 0 otherwise
01429 int ADPlanner::replan(double allocated_time_secs, vector<int>* solution_stateIDs_V)
01430 {
01431         int solcost;
01432 
01433         return replan(allocated_time_secs, solution_stateIDs_V, &solcost);
01434         
01435 }
01436 
01437 
01438 
01439 //returns 1 if found a solution, and 0 otherwise
01440 int ADPlanner::replan(double allocated_time_secs, vector<int>* solution_stateIDs_V, int* psolcost)
01441 {
01442     vector<int> pathIds; 
01443     int PathCost = 0;
01444     bool bFound = false;
01445         *psolcost = 0;
01446         bool bOptimalSolution = false;
01447 
01448         SBPL_PRINTF("planner: replan called (bFirstSol=%d, bOptSol=%d)\n", bsearchuntilfirstsolution, bOptimalSolution);
01449 
01450     //plan for the first solution only
01451     if((bFound = Search(pSearchStateSpace_, pathIds, PathCost, bsearchuntilfirstsolution, bOptimalSolution, allocated_time_secs)) == false) 
01452     {
01453         SBPL_PRINTF("failed to find a solution\n");
01454     }
01455 
01456     //copy the solution
01457     *solution_stateIDs_V = pathIds;
01458         *psolcost = PathCost;
01459 
01460         return (int)bFound;
01461 
01462 }
01463 
01464 int ADPlanner::set_goal(int goal_stateID)
01465 {
01466 
01467         SBPL_PRINTF("planner: setting goal to %d\n", goal_stateID);
01468         environment_->PrintState(goal_stateID, true, stdout);
01469 
01470         //it will be a new search iteration
01471         pSearchStateSpace_->searchiteration++;
01472         pSearchStateSpace_->bRebuildOpenList = true; //is not really necessary for search goal changes
01473 
01474         if(bforwardsearch)
01475         {
01476                 if(SetSearchGoalState(goal_stateID, pSearchStateSpace_) != 1)
01477                         {
01478                                 SBPL_ERROR("ERROR: failed to set search goal state\n");
01479                                 return 0;
01480                         }
01481         }
01482         else
01483         {
01484                 if(SetSearchStartState(goal_stateID, pSearchStateSpace_) != 1)
01485                         {
01486                                 SBPL_ERROR("ERROR: failed to set search start state\n");
01487                                 return 0;
01488                         }
01489         }
01490 
01491     return 1;
01492 }
01493 
01494 
01495 int ADPlanner::set_start(int start_stateID)
01496 {
01497 
01498         SBPL_PRINTF("planner: setting start to %d\n", start_stateID);
01499         environment_->PrintState(start_stateID, true, stdout);
01500 
01501         //it will be a new search iteration
01502         pSearchStateSpace_->searchiteration++;
01503         pSearchStateSpace_->bRebuildOpenList = true;
01504 
01505 
01506         if(bforwardsearch)
01507         {
01508                 if(SetSearchStartState(start_stateID, pSearchStateSpace_) != 1)
01509                         {
01510                                 SBPL_ERROR("ERROR: failed to set search start state\n");
01511                                 return 0;
01512                         }
01513         }
01514         else
01515         {
01516                 if(SetSearchGoalState(start_stateID, pSearchStateSpace_) != 1)
01517                         {
01518                                 SBPL_ERROR("ERROR: failed to set search goal state\n");
01519                                 return 0;
01520                         }
01521         }
01522 
01523     return 1;
01524 
01525 }
01526 
01527 
01528 void ADPlanner::update_succs_of_changededges(vector<int>* succstatesIDV)
01529 {
01530         SBPL_PRINTF("UpdateSuccs called on %d succs\n", (unsigned int)succstatesIDV->size());
01531 
01532         Update_SearchSuccs_of_ChangedEdges(succstatesIDV);
01533 }
01534 
01535 void ADPlanner::update_preds_of_changededges(vector<int>* predstatesIDV)
01536 {
01537         SBPL_PRINTF("UpdatePreds called on %d preds\n", (unsigned int)predstatesIDV->size());
01538 
01539         Update_SearchSuccs_of_ChangedEdges(predstatesIDV);
01540 }
01541 
01542 
01543 int ADPlanner::force_planning_from_scratch()
01544 {
01545         SBPL_PRINTF("planner: forceplanfromscratch set\n");
01546 
01547     pSearchStateSpace_->bReinitializeSearchStateSpace = true;
01548 
01549     return 1;
01550 }
01551 
01552 
01553 int ADPlanner::set_search_mode(bool bSearchUntilFirstSolution)
01554 {
01555         SBPL_PRINTF("planner: search mode set to %d\n", bSearchUntilFirstSolution);
01556 
01557         bsearchuntilfirstsolution = bSearchUntilFirstSolution;
01558 
01559         return 1;
01560 }
01561 
01562 
01563 void ADPlanner::costs_changed(StateChangeQuery const & stateChange)
01564 {
01565   if(pSearchStateSpace_->bReinitializeSearchStateSpace == true || pSearchStateSpace_->searchiteration == 0)
01566           return; //no processing if no search efforts anyway
01567 
01568   if (bforwardsearch)
01569     Update_SearchSuccs_of_ChangedEdges(stateChange.getSuccessors());
01570   else
01571     Update_SearchSuccs_of_ChangedEdges(stateChange.getPredecessors());
01572 }
01573 
01574 
01575 //---------------------------------------------------------------------------------------------------------
01576 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


sbpl
Author(s): Maxim Likhachev/maximl@seas.upenn.edu
autogenerated on Fri Jan 18 2013 13:41:52