@ -11,7 +11,6 @@ bool DecomposeGoalTask(GoalDecompositionStack& decompositionStack, GoalTask* goa
int methodIndex , ParameterList & parameters , WorldState & state )
{
GoalDecomposition decomposition ;
// GoalTask* goalTask = currentTask->GetGoal();
decomposition . DecomposedGoalTask = goalTask ;
decomposition . MethodIndex = methodIndex ;
decomposition . Parameters = parameters ;
@ -29,388 +28,389 @@ bool DecomposeGoalTask(GoalDecompositionStack& decompositionStack, GoalTask* goa
}
bool DecomposeCompoundTask ( TaskCallList & compoundDecompositions , CompoundTask * compoundTask ,
TaskArguments & taskArgument s)
const WorldState & state , const ParameterList & parameter s)
{
if ( ! compoundTask - > StateMeetsPreconditions ( taskArgument s) )
if ( ! compoundTask - > StateMeetsPreconditions ( state , parameter s) )
return false ;
return compoundTask - > Decompose ( compoundDecompositions , taskArgument s) ;
return compoundTask - > Decompose ( compoundDecompositions , state , parameter s) ;
}
// TODO: Pool various task lists?
// TODO: Pull more things out into functions, if possible. It's bad that whenever I make a change to
// something I have to change it in two place s
Planner : : Status Planner : : PlanStep ( void )
// When the stack is empty, find a goal task to push onto the task or add tasks as per usual
// If any Decompositions or Preconditions fail, we must fail the entire plan because we have
// no alternate method s
Planner : : Status Planner : : PlanStep_BottomLevel ( void )
{
// When the stack is empty, find a goal task to push onto the task or add tasks as per usual
// If any Decompositions or Preconditions fail, we must fail the entire plan because we have
// no alternate methods
if ( DecompositionStack . empty ( ) )
if ( InitialCallList . empty ( ) )
return Status : : Failed_NoTasks ;
else if ( WorkingCallList . empty ( ) & & FinalCallList . empty ( ) )
{
if ( InitialCallList . empty ( ) )
return Status : : Failed_NoTasks ;
else if ( WorkingCallList . empty ( ) & & FinalCallList . empty ( ) )
{
WorkingCallList = InitialCallList ;
StacklessState = State ;
}
else if ( WorkingCallList . empty ( ) & & ! FinalCallList . empty ( ) )
return Status : : PlanComplete ;
// First time the planner has been stepped
WorkingCallList = InitialCallList ;
StacklessState = State ;
}
else if ( WorkingCallList . empty ( ) & & ! FinalCallList . empty ( ) )
return Status : : PlanComplete ;
TaskCallList compoundDecompositions ;
TaskCallList compoundDecompositions ;
if ( DebugPrint )
{
std : : cout < < " \n PlanStep() \n WorkingCallList.size() = " < < WorkingCallList . size ( ) < < " \n " ;
printTaskCallList ( WorkingCallList ) ;
}
for ( TaskCallListIterator currentTaskCallIter = WorkingCallList . begin ( ) ;
currentTaskCallIter ! = WorkingCallList . end ( ) ;
currentTaskCallIter = WorkingCallList . erase ( currentTaskCallIter ) )
{
TaskCall currentTaskCall = ( * currentTaskCallIter ) ;
Task * currentTask = currentTaskCall . TaskToCall ;
if ( ! currentTask )
continue ;
TaskType currentTaskType = currentTask - > GetType ( ) ;
if ( DebugPrint )
{
std : : cout < < " \n PlanStep() \n WorkingCallList.size() = " < < WorkingCallList . size ( )
< < " \n " ;
printTaskCallList ( WorkingCallList ) ;
}
std : : cout < < " TaskType currentTaskType = " < < ( int ) currentTaskType < < " \n " ;
for ( TaskCallListIterator currentTaskCallIter = WorkingCallList . begin ( ) ;
currentTaskCallIter ! = WorkingCallList . end ( ) ;
currentTaskCallIter = WorkingCallList . erase ( currentTaskCallIter ) )
switch ( currentTaskType )
{
TaskCall currentTaskCall = ( * currentTaskCallIter ) ;
Task * currentTask = currentTaskCall . TaskToCall ;
if ( ! currentTask )
continue ;
TaskType currentTaskType = currentTask - > GetType ( ) ;
// Prepare arguments based on our current working state & parameters
// TODO: I don't like this
TaskArguments taskArguments = { StacklessState , currentTaskCall . Parameters } ;
case TaskType : : Goal :
{
if ( DebugPrint )
std : : cout < < " Goal \n " ;
GoalTask * goalTask = currentTask - > GetGoal ( ) ;
if ( DebugPrint )
std : : cout < < " TaskType currentTaskType = " < < ( int ) currentTaskType < < " \n " ;
if ( ! DecomposeGoalTask ( DecompositionStack , goalTask , 0 , currentTaskCall . Parameters ,
StacklessState ) )
return Status : : Failed_NoPossiblePlan ;
switch ( currentTaskType )
WorkingCallList . erase ( currentTaskCallIter ) ;
return Status : : Running_SuccessfulDecompositionStackPush ;
}
break ;
case TaskType : : Primitive :
{
case TaskType : : Goal :
if ( DebugPrint )
std : : cout < < " Primitive \n " ;
PrimitiveTask * primitiveTask = currentTask - > GetPrimitive ( ) ;
if ( ! primitiveTask - > StateMeetsPreconditions ( StacklessState ,
currentTaskCall . Parameters ) )
return Status : : Failed_NoPossiblePlan ;
// If at top level, apply primitive tasks immediately to the stackless state
primitiveTask - > ApplyStateChange ( StacklessState , currentTaskCall . Parameters ) ;
FinalCallList . push_back ( currentTaskCall ) ;
if ( BreakOnPrimitiveApply )
{
if ( DebugPrint )
std : : cout < < " Goal \n " ;
GoalTask * goalTask = currentTask - > GetGoal ( ) ;
if ( ! DecomposeGoalTask ( DecompositionStack , goalTask , 0 ,
currentTaskCall . Parameters , StacklessState ) )
return Status : : Failed_NoPossiblePlan ;
if ( BreakOnStackPush )
{
WorkingCallList . erase ( currentTaskCallIter ) ;
return Status : : Running_SuccessfulDecomposition ;
}
// TODO: IMPORTANT! This code will collapse horribly if I don't now start
// processing the stack
WorkingCallList . erase ( currentTaskCallIter ) ;
return Status : : Running_SuccessfulDecomposition ;
}
break ;
case TaskType : : Primitive :
{
if ( DebugPrint )
std : : cout < < " Primitive \n " ;
PrimitiveTask * primitiveTask = currentTask - > GetPrimitive ( ) ;
if ( ! primitiveTask - > StateMeetsPreconditions ( taskArguments ) )
return Status : : Failed_NoPossiblePlan ;
// If at top level, apply primitive tasks immediately to the stackless state
primitiveTask - > ApplyStateChange ( taskArguments ) ;
StacklessState = taskArguments . worldState ;
FinalCallList . push_back ( currentTaskCall ) ;
if ( BreakOnPrimitiveApply )
{
WorkingCallList . erase ( currentTaskCallIter ) ;
return Status : : Running_SuccessfulPrimitive ;
}
// Keep processing tasks otherwise
return Status : : Running_SuccessfulPrimitive ;
}
break ;
case TaskType : : Compound :
{
if ( DebugPrint )
std : : cout < < " Compound \n " ;
CompoundTask * compoundTask = currentTask - > GetCompound ( ) ;
if ( ! DecomposeCompoundTask ( compoundDecompositions , compoundTask , taskArguments ) )
return Status : : Failed_NoPossiblePlan ;
// Keep processing tasks otherwise
}
break ;
case TaskType : : Compound :
{
if ( DebugPrint )
std : : cout < < " Compound \n " ;
CompoundTask * compoundTask = currentTask - > GetCompound ( ) ;
currentTaskCallIter = WorkingCallList . erase ( currentTaskCallIter ) ;
// we need to push our decomposition to our call list, but we're iterating on
// it. By pushing our decomposition to compoundDecompositions in
// DecomposeCompoundTask(), we'll then break out of the loop and tack it on there
if ( ! DecomposeCompoundTask ( compoundDecompositions , compoundTask , StacklessState ,
currentTaskCall . Parameters ) )
return Status : : Failed_NoPossiblePlan ;
// we need to push our decomposition to our call list, but we're iterating on
// it. By pushing our decomposition to compoundDecompositions, we break out of
// the loop and tack it on there
}
break ;
default :
return Status : : Failed_BadData ;
currentTaskCallIter = WorkingCallList . erase ( currentTaskCallIter ) ;
}
break ;
default :
return Status : : Failed_BadData ;
}
if ( compoundDecompositions . size ( ) )
if ( compoundDecompositions . size ( ) )
{
if ( DebugPrint )
{
if ( DebugPrint )
{
std : : cout < < " compoundDecompositions.size() = " < < compoundDecompositions . size ( )
< < " \n " ;
}
WorkingCallList . insert ( WorkingCallList . begin ( ) , compoundDecompositions . begin ( ) ,
compoundDecompositions . end ( ) ) ;
// We have to break here because we are adding things to the list we're iterating
// on; We'll process the tasks next Step
// break; // UPDATE: Eventually we'll need a way to start over the loop if the
// caller wants whole plan in one call
if ( DebugPrint )
std : : cout < < " PlanStep Done \n " ;
return Status : : Running_SuccessfulDecomposition ;
std : : cout < < " compoundDecompositions.size() = " < < compoundDecompositions . size ( )
< < " \n " ;
}
WorkingCallList . insert ( WorkingCallList . begin ( ) , compoundDecompositions . begin ( ) ,
compoundDecompositions . end ( ) ) ;
if ( DebugPrint )
std : : cout < < " Loop Done \n " ;
std : : cout < < " PlanStep Done \n " ;
// We have to break here because we are adding things to the list we're iterating
// on; We'll process the tasks next Step
return Status : : Running_SuccessfulDecomposition ;
}
}
else
{
// Remember: If goal fails to decompose and goal is bottom of stack, fail
GoalDecompositionStack : : iterator currentStackFrameIter = DecompositionStack . end ( ) - 1 ;
GoalDecomposition & currentStackFrame = * currentStackFrameIter ;
if ( DebugPrint )
{
std : : cout < < " \n PlanStep() \n currentStackFrame.CallList.size() = "
< < currentStackFrame . CallList . size ( ) < < " \n " ;
printTaskCallList ( currentStackFrame . CallList ) ;
std : : cout < < " Loop Done \n " ;
}
std : : cout < < " Stack Depth: " ;
for ( unsigned int i = 0 ; i < DecompositionStack . size ( ) ; i + + )
std : : cout < < " = " ;
std : : cout < < " \n " ;
return Status : : PlanComplete ;
}
Planner : : Status Planner : : PlanStep_StackFrame ( void )
{
// Remember: If goal fails to decompose and goal is bottom of stack, fail
GoalDecompositionStack : : iterator currentStackFrameIter = DecompositionStack . end ( ) - 1 ;
GoalDecomposition & currentStackFrame = * currentStackFrameIter ;
if ( DebugPrint )
{
std : : cout < < " \n PlanStep() \n currentStackFrame.CallList.size() = "
< < currentStackFrame . CallList . size ( ) < < " \n " ;
printTaskCallList ( currentStackFrame . CallList ) ;
std : : cout < < " Stack Depth: " ;
for ( unsigned int i = 0 ; i < DecompositionStack . size ( ) ; i + + )
std : : cout < < " = " ;
std : : cout < < " \n " ;
{
std : : cout < < " ----Fullstack working lists \n " ;
std : : cout < < " [0] \n " ;
printTaskCallList ( WorkingCallList ) ;
int i = 1 ;
for ( GoalDecomposition & stackFrame : DecompositionStack )
{
std : : cout < < " ----Fullstack working lists \n " ;
std : : cout < < " [0] \n " ;
printTaskCallList ( WorkingCallList ) ;
int i = 1 ;
for ( GoalDecomposition & stackFrame : DecompositionStack )
{
std : : cout < < " [ " < < i + + < < " ] \n " ;
printTaskCallList ( stackFrame . CallList ) ;
}
std : : cout < < " ---- \n " ;
std : : cout < < " [ " < < i + + < < " ] \n " ;
printTaskCallList ( stackFrame . CallList ) ;
}
std : : cout < < " ---- \n " ;
}
}
TaskCallList compoundDecompositions ;
bool methodFailed = false ;
for ( TaskCallListIterator currentTaskCallIter = currentStackFrame . CallList . begin ( ) ;
currentTaskCallIter ! = currentStackFrame . CallList . end ( ) ;
currentTaskCallIter = currentStackFrame . CallList . erase ( currentTaskCallIter ) )
{
TaskCall currentTaskCall = ( * currentTaskCallIter ) ;
Task * currentTask = currentTaskCall . TaskToCall ;
if ( ! currentTask )
continue ;
TaskType currentTaskType = currentTask - > GetType ( ) ;
TaskCallList compoundDecompositions ;
bool methodFailed = false ;
// Prepare arguments based on our current working state & parameters
// TODO: I don't like this
TaskArguments taskArguments = { currentStackFrame . WorkingState ,
currentTaskCall . Parameters } ;
for ( TaskCallListIterator currentTaskCallIter = currentStackFrame . CallList . begin ( ) ;
currentTaskCallIter ! = currentStackFrame . CallList . end ( ) ;
currentTaskCallIter = currentStackFrame . CallList . erase ( currentTaskCallIter ) )
{
TaskCall currentTaskCall = ( * currentTaskCallIter ) ;
Task * currentTask = currentTaskCall . TaskToCall ;
if ( ! currentTask )
continue ;
TaskType currentTaskType = currentTask - > GetType ( ) ;
if ( DebugPrint )
std : : cout < < " TaskType currentTaskType = " < < ( int ) currentTaskType < < " \n " ;
if ( DebugPrint )
std : : cout < < " TaskType currentTaskType = " < < ( int ) currentTaskType < < " \n " ;
switch ( currentTaskType )
switch ( currentTaskType )
{
case TaskType : : Goal :
{
case TaskType : : Goal :
{
if ( DebugPrint )
std : : cout < < " Goal \n " ;
GoalTask * goalTask = currentTask - > GetGoal ( ) ;
if ( DebugPrint )
std : : cout < < " Goal \n " ;
GoalTask * goalTask = currentTask - > GetGoal ( ) ;
// TODO erase ahead of time because fuck
// Strange things are afoot when we push to stack
currentStackFrame . CallList . erase ( currentTaskCallIter ) ;
// TODO erase ahead of time because fuck
// Strange things are afoot when we push to stack
currentStackFrame . CallList . erase ( currentTaskCallIter ) ;
// Perform the decomposition. This function only fails if the method at method
// index doesn't exist. This means that the goal task has no alternative options
if ( ! DecomposeGoalTask ( DecompositionStack , goalTask , 0 ,
currentTaskCall . Parameters ,
currentStackFrame . WorkingState ) )
{
methodFailed = true ;
break ;
}
// This code is wrong. I'm not sure why.
// Pushing to the stack invalidates our currentStackFrame reference; update it
// What the actual fuck (updating the ref doesn't fix the fucking thing)
/*std::cout << "Ref updating from " << ¤tStackFrame << " to "
< < & ( * ( DecompositionStack . end ( ) - 1 ) ) < < " \n " ;
currentStackFrameIter = DecompositionStack . end ( ) - 1 ;
currentStackFrame = * currentStackFrameIter ; */
if ( BreakOnStackPush )
{
// currentStackFrame.CallList.erase(currentTaskCallIter);
return Status : : Running_SuccessfulDecomposition ;
}
// TODO: IMPORTANT! This code will collapse horribly if I don't now start
// processing the stack
// currentStackFrame.CallList.erase(currentTaskCallIter);
return Status : : Running_SuccessfulDecomposition ;
}
break ;
case TaskType : : Primitive :
// Perform the decomposition. This function only fails if the method at method
// index doesn't exist. This means that the goal task has no alternative options
if ( ! DecomposeGoalTask ( DecompositionStack , goalTask , 0 , currentTaskCall . Parameters ,
currentStackFrame . WorkingState ) )
{
if ( DebugPrint )
std : : cout < < " Primitive \n " ;
PrimitiveTask * primitiveTask = currentTask - > GetPrimitive ( ) ;
if ( ! primitiveTask - > StateMeetsPreconditions ( taskArguments ) )
{
methodFailed = true ;
break ;
}
primitiveTask - > ApplyStateChange ( taskArguments ) ;
currentStackFrame . WorkingState = taskArguments . worldState ;
currentStackFrame . FinalCallList . push_back ( currentTaskCall ) ;
if ( BreakOnPrimitiveApply )
{
currentStackFrame . CallList . erase ( currentTaskCallIter ) ;
return Status : : Running_SuccessfulPrimitive ;
}
// Keep processing tasks otherwise
methodFailed = true ;
break ;
}
break ;
case TaskType : : Compound :
{
if ( DebugPrint )
std : : cout < < " Compound \n " ;
CompoundTask * compoundTask = currentTask - > GetCompound ( ) ;
if ( ! DecomposeCompoundTask ( compoundDecompositions , compoundTask , taskArguments ) )
{
methodFailed = true ;
break ;
}
// This code is wrong. I'm not sure why.
// Pushing to the stack invalidates our currentStackFrame reference; update it
// What the actual fuck (updating the ref doesn't fix the fucking thing)
/*std::cout << "Ref updating from " << ¤tStackFrame << " to "
< < & ( * ( DecompositionStack . end ( ) - 1 ) ) < < " \n " ;
currentStackFrameIter = DecompositionStack . end ( ) - 1 ;
currentStackFrame = * currentStackFrameIter ; */
currentTaskCallIter = currentStackFrame . CallList . erase ( currentTaskCallIter ) ;
// we need to push our decomposition to our call list, but we're iterating on
// it. By pushing our decomposition to compoundDecompositions, we break out of
// the loop and tack it on there
}
break ;
default :
return Status : : Failed_BadData ;
return Status : : Running_SuccessfulDecompositionStackPush ;
}
if ( methodFailed )
break ;
case TaskType : : Primitive :
{
if ( DebugPrint )
std : : cout < < " Method failed decomposition \n " ;
// Clear stack frame
currentStackFrame . CallList . clear ( ) ;
currentStackFrame . FinalCallList . clear ( ) ;
// currentStackFrame.Parameters.clear(); // Little weird (implicit assumption that
// GoalTask uses exact parameters)
currentStackFrame . WorkingState = currentStackFrame . InitialState ;
// Try the next method
currentStackFrame . MethodIndex + + ;
if ( ! currentStackFrame . DecomposedGoalTask - > DecomposeMethodAtIndex (
currentStackFrame . CallList , currentStackFrame . MethodIndex ,
currentStackFrame . Parameters ) )
std : : cout < < " Primitive \n " ;
PrimitiveTask * primitiveTask = currentTask - > GetPrimitive ( ) ;
if ( ! primitiveTask - > StateMeetsPreconditions ( currentStackFrame . WorkingState ,
currentTaskCall . Parameters ) )
{
DecompositionStack . pop_back ( ) ;
return Status : : Running_FailedGoalDecomposition ;
methodFailed = true ;
break ;
}
// TODO: make this optional return
return Status : : Running_FailedMethodDecomposition ;
}
primitiveTask - > ApplyStateChange ( currentStackFrame . WorkingState ,
currentTaskCall . Parameters ) ;
if ( compoundDecompositions . size ( ) )
currentStackFrame . FinalCallList . push_back ( currentTaskCall ) ;
if ( BreakOnPrimitiveApply )
{
currentStackFrame . CallList . erase ( currentTaskCallIter ) ;
return Status : : Running_SuccessfulPrimitive ;
}
// Keep processing tasks otherwise
}
break ;
case TaskType : : Compound :
{
if ( DebugPrint )
std : : cout < < " Compound \n " ;
CompoundTask * compoundTask = currentTask - > GetCompound ( ) ;
if ( ! DecomposeCompoundTask ( compoundDecompositions , compoundTask ,
currentStackFrame . WorkingState ,
currentTaskCall . Parameters ) )
{
std : : cout < < " compoundDecompositions.size() = " < < compoundDecompositions . size ( )
< < " \n " ;
std : : cout < < " currentStackFrame.CallList.size() = "
< < currentStackFrame . CallList . size ( ) < < " \n " ;
std : : cout < < " Decomposition: \n " ;
printTaskCallList ( compoundDecompositions ) ;
methodFailed = true ;
break ;
}
currentStackFrame . CallList . insert ( currentStackFrame . CallList . begin ( ) ,
compoundDecompositions . begin ( ) ,
compoundDecompositions . end ( ) ) ;
// We have to break here because we are adding things to the list we're iterating
// on; We'll process the tasks next Step
// break; // UPDATE: TODO: Eventually we'll need a way to start over the loop if the
// caller wants whole plan in one call
if ( DebugPrint )
std : : cout < < " PlanStep Done \n " ;
return Status : : Running_SuccessfulDecomposition ;
}
if ( DebugPrint )
std : : cout < < " Loop Done \n " ;
currentTaskCallIter = currentStackFrame . CallList . erase ( currentTaskCallIter ) ;
// we need to push our decomposition to our call list, but we're iterating on
// it. By pushing our decomposition to compoundDecompositions, we break out of
// the loop and tack it on there
}
break ;
default :
return Status : : Failed_BadData ;
}
// Finished processing this stack frame
if ( currentStackFrame . CallList . empty ( ) & & ! currentStackFrame . FinalCallList . empty ( ) )
if ( methodFailed )
{
bool onlyStackFrame = DecompositionStack . size ( ) = = 1 ;
TaskCallList * parentFinalCallList = nullptr ;
WorldState * parentWorkingState = nullptr ;
// If this is the only frame on the stack, its call list and working state goes to the
// plan, else, the previous stack
if ( onlyStackFrame )
if ( DebugPrint )
std : : cout < < " Method failed decomposition \n " ;
// Clear stack frame
currentStackFrame . CallList . clear ( ) ;
currentStackFrame . FinalCallList . clear ( ) ;
currentStackFrame . WorkingState = currentStackFrame . InitialState ;
// Try the next method
currentStackFrame . MethodIndex + + ;
if ( ! currentStackFrame . DecomposedGoalTask - > DecomposeMethodAtIndex (
currentStackFrame . CallList , currentStackFrame . MethodIndex ,
currentStackFrame . Parameters ) )
{
parentFinalCallList = & FinalCallList ;
parentWorkingState = & StacklessState ;
DecompositionStack . pop_back ( ) ;
return Status : : Running_FailedGoalDecomposition ;
}
else
{
GoalDecomposition & previousStackFrame = * ( currentStackFrameIter - 1 ) ;
parentFinalCallList = & previousStackFrame . FinalCallList ;
parentWorkingState = & previousStackFrame . WorkingState ;
}
// We have failed to decompose the previous method, but successfully got the next
// method. Return to let the Planner know what just happened
return Status : : Running_FailedMethodDecomposition ;
}
if ( compoundDecompositions . size ( ) )
{
if ( DebugPrint )
{
std : : cout < < " Collapsing stack frame. Adding List: \n " ;
printTaskCallList ( currentStackFrame . FinalCallList ) ;
std : : cout < < " To parent: \n " ;
printTaskCallList ( * parentFinalCallList ) ;
std : : cout < < " compoundDecompositions.size() = " < < compoundDecompositions . size ( )
< < " \n " ;
std : : cout < < " currentStackFrame.CallList.size() = "
< < currentStackFrame . CallList . size ( ) < < " \n " ;
std : : cout < < " Decomposition: \n " ;
printTaskCallList ( compoundDecompositions ) ;
}
// Should this be appended?
parentFinalCallList - > insert ( parentFinalCallList - > end ( ) ,
currentStackFrame . FinalCallList . begin ( ) ,
currentStackFrame . FinalCallList . end ( ) ) ;
currentStackFrame . CallList . insert ( currentStackFrame . CallList . begin ( ) ,
compoundDecompositions . begin ( ) ,
compoundDecompositions . end ( ) ) ;
if ( DebugPrint )
std : : cout < < " PlanStep Done \n " ;
* parentWorkingState = currentStackFrame . WorkingState ;
// We have to break here because we are adding things to the list we're iterating
// on; We'll process the tasks next Step
return Status : : Running_SuccessfulDecomposition ;
}
DecompositionStack . pop_back ( ) ;
if ( DebugPrint )
std : : cout < < " Loop Done \n " ;
}
if ( DebugPrint )
std : : cout < < " Frame Done \n " ;
// Finished processing this stack frame
if ( currentStackFrame . CallList . empty ( ) & & ! currentStackFrame . FinalCallList . empty ( ) )
{
bool onlyStackFrame = DecompositionStack . size ( ) = = 1 ;
TaskCallList * parentFinalCallList = nullptr ;
WorldState * parentWorkingState = nullptr ;
if ( BreakOnStackPop )
return Status : : Running_SuccessfulDecomposition ;
// If this is the only frame on the stack, its call list and working state goes to the
// plan, else, the previous stack
if ( onlyStackFrame )
{
parentFinalCallList = & FinalCallList ;
parentWorkingState = & StacklessState ;
}
else
{
GoalDecomposition & previousStackFrame = * ( currentStackFrameIter - 1 ) ;
// TODO: Continue processing the stack
return Status : : Running_SuccessfulDecomposition ;
parentFinalCallList = & previousStackFrame . FinalCallList ;
parentWorkingState = & previousStackFrame . WorkingState ;
}
if ( DebugPrint )
{
std : : cout < < " Collapsing stack frame. Adding List: \n " ;
printTaskCallList ( currentStackFrame . FinalCallList ) ;
std : : cout < < " To parent: \n " ;
printTaskCallList ( * parentFinalCallList ) ;
}
parentFinalCallList - > insert ( parentFinalCallList - > end ( ) ,
currentStackFrame . FinalCallList . begin ( ) ,
currentStackFrame . FinalCallList . end ( ) ) ;
* parentWorkingState = currentStackFrame . WorkingState ;
DecompositionStack . pop_back ( ) ;
if ( DebugPrint )
std : : cout < < " Frame Done \n " ;
return Status : : Running_SuccessfulDecompositionStackPop ;
}
return Status : : PlanComplete ;
}
// TODO: Pool various task lists?
// TODO: Pull more things out into functions, if possible. It's bad that whenever I make a change to
// something I have to change it in two places
Planner : : Status Planner : : PlanStep ( void )
{
Status status = Status : : Failed_NoPossiblePlan ;
// Continue stepping the plan until a non-running state is complete or a status is returned
// which matches the user-specified break conditions
do
{
if ( DecompositionStack . empty ( ) )
status = PlanStep_BottomLevel ( ) ;
else
status = PlanStep_StackFrame ( ) ;
// The user can decided how much planning happens in a single step; conditionally stop
// stepping here based on their settings
if ( ( BreakOnCompoundDecomposition & & status = = Status : : Running_SuccessfulDecomposition ) | |
( BreakOnPrimitiveApply & & status = = Status : : Running_SuccessfulPrimitive ) | |
( BreakOnStackAction & & ( status = = Status : : Running_SuccessfulDecompositionStackPush | |
status = = Status : : Running_SuccessfulDecompositionStackPop | |
status = = Status : : Running_FailedGoalDecomposition ) ) | |
( BreakOnFailedDecomposition & & ( status = = Status : : Running_FailedGoalDecomposition | |
status = = Status : : Running_FailedMethodDecomposition ) ) )
return status ;
} while ( status > = Status : : Running_EnumBegin & & status < = Status : : Running_EnumEnd ) ;
return status ;
}
}