//----------------------------------------------------------------------------------------------- private static void ParseMethodsFromNode(XmlNode compoundTaskNode, CompoundTask task, Domain domain) { XmlNodeList methodList = compoundTaskNode.ChildNodes; foreach (XmlNode methodNode in methodList) { Method methodToAdd = new Method(); XmlNodeList methodDataMembers = methodNode.ChildNodes; foreach (XmlNode methodDataMember in methodDataMembers) { string dataType = methodDataMember.Name; switch (dataType) { case "Precondition": { ParsePreconditionForMethod(methodDataMember, methodToAdd); break; } case "Subtasks": { ParseSubtasksForMethod(methodDataMember, methodToAdd, domain); break; } } } task.RegisterMethod(methodToAdd); } }
//From the failed task, get a node in hierarchy with a valid method in current state public static CompoundTask GetValidNode(PrimitiveTask failedTask, State state) { CompoundTask parent = new CompoundTask(); Task current = failedTask; //Get parent of task, until a parent with a valid method is found, or the root of hierarchy is reached while (current.parent != null) { parent = current.parent; foreach (Method method in parent.methods) { if (RuleMatcher.MatchCondition(method.preconditions, state, method.logicalOperator)) { return(parent); } } current = parent; } return(parent); }
public void UpwardUnifyTest1() { var up = new CompoundTask("up", 1); up.AddMethod(1, new object[] { "xyz" }, new LocalVariableName[0], null, 0, null, 1); var down = new CompoundTask("down", 1); // ReSharper disable once InconsistentNaming var X = new LocalVariableName("X", 0); down.AddMethod(1, new object[] { X }, new[] { X }, TestUtils.Sequence(new object[] { toString, X }, new[] { "matched" }), 0, null, 1); var test = new CompoundTask("test", 0); // ReSharper disable once InconsistentNaming var Y = new LocalVariableName("Y", 0); test.AddMethod(1, new object[0], new [] { Y }, TestUtils.Sequence(new object[] { up, Y }, new object[] { down, Y }), 0, null, 1); Assert.AreEqual("Xyz matched", new Call(test, new object[0], null).Expand()); }
public PrimitiveTask(string n, CompoundTask p) { name = n; arguments = new List <Term>(); arguments.Capacity = 3; preconditions = new List <Atom>(); effects = new List <Atom>(); cuncurrentTasks = new List <CuncurrentTask> (); cost = 1; loop = false; logicalOperator = LogicalOperator.AND; actionType = ActionTypes.MOVEMENT; groundData = new GroundData(); groundData.animationState = ""; groundData.name = ""; parent = p; }
public PlannerState(CompoundTask currentTask, Stack <PrimitiveTask> finalPlan, Stack <Task> tasksToProcess, Method currentMethod) { this.currentTask = currentTask; this.finalPlan = new Stack <PrimitiveTask>(); this.tasksToProcess = new Stack <Task>(); this.currentMethod = currentMethod; Stack <PrimitiveTask> temp = new Stack <PrimitiveTask>(); // Create shallow copy of finalPlan for (int i = 0; i < finalPlan.Count; i++) { temp.Push(finalPlan.Pop()); } for (int i = 0; i < temp.Count; i++) { PrimitiveTask t = temp.Pop(); this.finalPlan.Push(t); finalPlan.Push(t); } // Create shallow copy of tasksToProcess Stack <Task> temp2 = new Stack <Task>(); for (int i = 0; i < tasksToProcess.Count; i++) { temp2.Push(tasksToProcess.Pop()); } for (int i = 0; i < temp2.Count; i++) { Task t = temp2.Pop(); this.tasksToProcess.Push(t); tasksToProcess.Push(t); } }
public Method(string n, CompoundTask p) { name = n; preconditions = new List <Atom> (); subtasks = new List <Task> (); preference = "none"; logicalOperator = LogicalOperator.AND; parent = p; cost = -1.0f; }
void removeMethod(object data) { ArrayList list = (ArrayList)data; CompoundTask comp = (CompoundTask)list [0]; Method method = (Method)list [1]; comp.removeMethod(method); }
/// <summary> /// 直前のCompoundTaskの状態まで遡れるように、現在のPlannerStateを記録 /// </summary> private void RecordDecompositionOfTask(CompoundTask nextCompoundTask) { var copyOfPlannerState = new PlannerState( plannerState.WorkingWS.Clone(), new List <TaskBase>(plannerState.FinalPlanList), new List <TaskBase>(plannerState.TaskListToProcess), plannerState.NextMethodNumber); copyOfPlannerState.TaskListToProcess.Add(nextCompoundTask); plannerStateHistory.Add(copyOfPlannerState); }
public void MatchingNoVariablesTest() { var t = new CompoundTask("test", 1); t.Flags |= CompoundTask.TaskFlags.Fallible; t.AddMethod(1, new object[] { 1 }, new LocalVariableName[0], new EmitStep(new [] { "1", "matched" }, null), 0, null, 1); t.AddMethod(1, new object[] { 2 }, new LocalVariableName[0], new EmitStep(new [] { "2", "matched" }, null), 0, null, 1); Assert.AreEqual("1 matched", new Call(t, new object[] { 1 }, null).Expand()); Assert.AreEqual("2 matched", new Call(t, new object[] { 2 }, null).Expand()); Assert.AreEqual(null, new Call(t, new object[] { 3 }, null).Expand()); }
protected override void Context() { _executionContext = A.Fake <IExecutionContext>(); _buildingBlockTask = A.Fake <IBuildingBlockTask>(); _applicationController = A.Fake <IApplicationController>(); _compound = new Compound().WithId("Drug").WithName("Drug"); _buildingBlockRepository = A.Fake <IBuildingBlockRepository>(); _dialogCreator = A.Fake <IDialogCreator>(); sut = new CompoundTask(_executionContext, _buildingBlockTask, _applicationController, _buildingBlockRepository, _dialogCreator); A.CallTo(() => _buildingBlockTask.SaveAsTemplate(A <ICache <IPKSimBuildingBlock, IReadOnlyList <IPKSimBuildingBlock> > > ._, TemplateDatabaseType.User)) .Invokes(x => _cache = x.GetArgument <ICache <IPKSimBuildingBlock, IReadOnlyList <IPKSimBuildingBlock> > >(0)); }
public void DownwardUnifyTest1() { var t = new CompoundTask("test", 1); // ReSharper disable once InconsistentNaming var X = new LocalVariableName("X", 0); var locals = new[] { X }; t.AddMethod(1, new object[] { X }, locals, TestUtils.Sequence(new object[] { toString, X }, new[] { "matched" }), 0, null, 1); Assert.AreEqual("1 matched", new Call(t, new object[] { 1 }, null).Expand()); Assert.AreEqual("2 matched", new Call(t, new object[] { 2 }, null).Expand()); }
//----------------------------------------------------------------------------------------------- private static void ParseCompoundTaskMethods(XmlDocument xmlData, Domain domain) { XmlNodeList compoundTaskList = xmlData.GetElementsByTagName("CompoundTask"); foreach (XmlNode compoundTaskNode in compoundTaskList) { string taskName = ""; if (!TryLoadRequiredAttributeFromXmlNode(compoundTaskNode, "name", ref taskName)) { throw new ArgumentNullException("CompoundTask missing name!"); } CompoundTask task = domain.GetTaskByName(taskName) as CompoundTask; ParseMethodsFromNode(compoundTaskNode, task, domain); } }
//----------------------------------------------------------------------------------------------- private static void ParseCompoundTasks(XmlDocument xmlData, Domain domain) { XmlNodeList compoundTaskList = xmlData.GetElementsByTagName("CompoundTask"); foreach (XmlNode compoundTaskNode in compoundTaskList) { string taskName = ""; if (!TryLoadRequiredAttributeFromXmlNode(compoundTaskNode, "name", ref taskName)) { throw new ArgumentNullException("CompoundTask missing name!"); } CompoundTask task = new CompoundTask(taskName); domain.TryRegisterTask(taskName, task); } }
/// <summary> /// CompoundTaskが保有しているMethodの中から、現在のWorldStateに合致するMethodを返す。 /// なければ、nullを返す。 /// </summary> private Method FindSatisfiedMethod(CompoundTask currentCompoundTask, PlannerState plannerState) { var methodsWorldState = plannerState.WorkingWS.Clone(); var methods = currentCompoundTask.Methods; while (plannerState.NextMethodNumber < methods.Count) { var method = methods[plannerState.NextMethodNumber]; plannerState.NextMethodNumber++; if (method.CheckPreCondition(methodsWorldState)) { return(method); } } return(null); }
public SerializedTask(CompoundTask t, SerializedTask p) { type = "Compound"; parent = p; name = t.name; methods = new List <SerializedMethod> (); foreach (Method m in t.methods) { methods.Add(new SerializedMethod(m, this)); } cost = 0; effects = null; preconditions = null; cuncurrentTasks = null; }
public Task DeSerialize(CompoundTask p) { if (type == "Compound") { CompoundTask cp = new CompoundTask(name, p); foreach (SerializedMethod sm in methods) { Method m = sm.DeSerialize(cp); cp.addMethod(m); } return(cp); } else { PrimitiveTask tp = new PrimitiveTask(name, p); tp.cost = cost; tp.effects = effects; tp.cuncurrentTasks = cuncurrentTasks; tp.preconditions = preconditions; arguments.Capacity = 3; tp.arguments = arguments; tp.actionType = actionType; tp.groundData = groundData; tp.loop = loop; tp.logicalOperator = logicalOperator; return(tp); } }
//Check if node in hierarchy is forefather of this task public bool IsMyForeFather(CompoundTask node) { CompoundTask currentParent = new CompoundTask(); Task currentTask = this; while (currentTask.parent != null) { currentParent = currentTask.parent; if (currentParent.Equals(node)) { return(true); } currentTask = currentParent; } return(false); }
public Method DeSerialize(CompoundTask p) { Method m = new Method(name, null); m = new Method(name, p); m.preference = preference; m.logicalOperator = logicalOperator; m.preconditions = preconditions; foreach (SerializedTask st in subtasks) { m.subtasks.Add(st.DeSerialize(p)); } return(m); }
Vector2 calcLastHeight(Task task, Vector2 pos) { if (task.GetType() == typeof(CompoundTask)) { Vector2 lastPos = pos; CompoundTask cp = (CompoundTask)task; foreach (Method m in cp.methods) { foreach (Task t in m.subtasks) { lastPos = calcLastHeight(t, new Vector2(lastPos.x + 30, lastPos.y + 60)); } } return(lastPos); } return(pos); }
public static void ShowWindow(HTNAgent a, CompoundTask g) { goal = g; agent = a; persIndex = 0; varIndex = 0; actionIndex = 0; if (agent.serializedGoal.name.Length > 0) { goal = (CompoundTask)agent.serializedGoal.DeSerialize(null); } EditorWindow window = EditorWindow.GetWindow(typeof(HTNEditorWindow)); window.maxSize = new Vector2(700, 700); window.minSize = new Vector2(700, 700); window.position = new Rect(200, 200, 700, 700); }
//Least cost plan found choosing this method public float leastCost() { float c = 0.0f; foreach (Task subtask in subtasks) { if (subtask.GetType() == typeof(CompoundTask)) { CompoundTask ct = (CompoundTask)subtask; float leastCost = Mathf.Infinity; foreach (Method m in ct.methods) { float currentCost = m.Cost; if (currentCost < Mathf.Infinity) { leastCost = currentCost; } } return(leastCost); } else if (subtask.GetType() == typeof(PrimitiveTask)) { PrimitiveTask pt = (PrimitiveTask)subtask; c += pt.cost; } } return(c); }
public CompoundTask(string n, CompoundTask p) { name = n; methods = new List <Method> (); parent = p; }
public CompoundTask(CompoundTask p) { name = "New Compound"; methods = new List <Method> (); parent = p; }
public void InstantiateVariables(Task task, List <Term> variables) { if (task.GetType() == typeof(PrimitiveTask)) { PrimitiveTask pt = (PrimitiveTask)task; foreach (Term variable in variables) { int index = pt.arguments.FindIndex((Term arg) => arg.key == variable.key); if (index >= 0) { pt.arguments[index] = variable; } foreach (Atom pre in pt.preconditions) { index = pre.terms.FindIndex((Term arg) => arg.key == variable.key); if (index >= 0) { pre.terms[index] = variable; } } foreach (Atom eff in pt.effects) { index = eff.terms.FindIndex((Term arg) => arg.key == variable.key); if (index >= 0) { eff.terms[index] = variable; } } } } else if (task.GetType() == typeof(CompoundTask)) { CompoundTask ct = (CompoundTask)task; foreach (Method m in ct.methods) { foreach (Atom pre in m.preconditions) { foreach (Term variable in variables) { int index = pre.terms.FindIndex((Term arg) => arg.key == variable.key); if (index >= 0) { pre.terms[index] = variable; } } } foreach (Task subTask in m.subtasks) { InstantiateVariables(subTask, variables); } } } }
// Use this for initialization void Start() { compileExpressionParser(); //Knowledge update rate KnowledgeUpdateWindow.LoadFromFile(); //Get goal goal = (CompoundTask)serializedGoal.DeSerialize(null); //Initialize knowledge foreach (SerializedFact fact in serializedKnowledge) { Atom newFact = new Atom(fact.name, fact.sign); foreach (string objName in fact.values) { newFact.addTerm(new Term(GameObject.Find(objName))); } state.addFact(newFact); } //Initialize variables foreach (SerializedVariable var in serializedDomainVariables) { if (var.key != "" && var.value != "") { domainVariables [serializedDomainVariables.IndexOf(var)].value = GameObject.Find(var.value); } } //Instantiate variables InstantiateVariables(goal, domainVariables); //Add sensor if (sensor == 0) { sensorySystem = new CameraSensor(this); } else if (sensor == 1) { sensorySystem = new RadiusSensor(this, radiusLength); } try { definitions = FactDefinitionsContainer.Load(FactsDefinitionWindow.definitionsPath).list; } catch (Exception e) { Debug.Log(e.Message); } //Agent FSM FSM = new AgentStateMachine(AgentState.IDLE, this); //Action manager actionManager = new ActionManager(this); //Coordination communicationSystem = new CommunicationSystem(this); groupMembers = new List <HTNAgent> (); //Personalities knownPersonalities = PersonalitiesContainer.Load(PersonalityEditorWindow.path).list; }
public void Update() { if (current == AgentState.IDLE) { //Transizione a PLANNING: se l'agente ha un task obiettivo non completato, o non esiste una condizione obiettivo, ma il manager delle azioni è comunque in stato STOP if (agent.goal.methods.Count > 0 && !agent.goal.completed && (Time.frameCount % 60 == 0 || Time.frameCount == 1)) { current = AgentState.PLANNING; } //Transizione a EXECUTING: se il manager delle azioni è in stato EXECUTE else if (agent.actionManager.state == ManagerState.EXECUTE) { current = AgentState.EXECUTING; } else if (agent.actionManager.state == ManagerState.PAUSE) { PrimitiveTask currentTask = (PrimitiveTask)agent.actionManager.currentAction; foreach (CuncurrentTask cuncurrent in currentTask.cuncurrentTasks) { if (!currentTask.CheckCuncurrency(cuncurrent, agent)) { return; } } agent.actionManager.Resume(); } } else if (current == AgentState.PLANNING) { /*In this state, agent plans to goal * Transition to EXECUTING : if agent has a plan towards goal (not empty actions list) * Transizion to IDLE: agent has no plan towards goal (empty actions list)*/ //Generate or fix plan List <Task> tasks = new List <Task>(); //If manager has stopped with INVALID state, fix plan and get a new plan if (agent.actionManager.state == ManagerState.INVALID) { //Climb the hierarchy and get the first valid node CompoundTask validNode = Planner.GetValidNode((PrimitiveTask)agent.actionManager.currentAction, agent.state); tasks.Add(validNode); //Generate first segment of fixed plan, planning from the node found List <PrimitiveTask> firstSegment = Planner.GeneratePlan(tasks, agent); if (firstSegment.Count > 0) { //Get second segment from the current plan, deleting tasks who have node found as father or forefather List <PrimitiveTask> secondSegment = new List <PrimitiveTask>(); foreach (PrimitiveTask task in agent.plan) { if (!task.IsMyForeFather(validNode) && !task.completed) { secondSegment.Add(task); } } //Fix the plan concatenating first segment with second segment agent.plan = firstSegment.Concat(secondSegment).ToList <PrimitiveTask>(); } //No plan.. else { agent.plan = new List <PrimitiveTask>(); //If agent is a member of a group, notify it to the leader, who will stop execution of global plan agent.communicationSystem.sendMessage(new Message(agent.leader, MessageContent.ORDER_FAILURE)); } } //Otherwise generate plan else { tasks.Add(agent.goal); agent.plan = Planner.GeneratePlan(tasks, agent); } if (agent.plan != null) { foreach (IGroundAction action in agent.plan) { agent.actionManager.ScheduleAction(action); } agent.actionManager.NextAction(); current = AgentState.EXECUTING; agent.actionManager.state = ManagerState.EXECUTE; } else { agent.actionManager.state = ManagerState.STOP; current = AgentState.IDLE; } } else if (current == AgentState.EXECUTING) { //Dentro lo stato: esecuzione azione corrente del piano //Transizione a IDLE : se il piano è completato con successo, oppure il manager delle azioni è andato in pausa //Transizione a PLANNING : se il piano non è valido (precondizioni azione non valide) agent.actionManager.RunCurrentAction(); if (agent.actionManager.state == ManagerState.EMPTY) { current = AgentState.IDLE; agent.actionManager.state = ManagerState.STOP; agent.goal.completed = true; } else if (agent.actionManager.state == ManagerState.INVALID) { current = AgentState.PLANNING; } else if (agent.actionManager.state == ManagerState.PAUSE) { current = AgentState.IDLE; } } }
static List <PrimitiveTask> SHOPNoBack(List <Task> tasks, List <PrimitiveTask> plan, string personality, State state, HTNAgent agent) { Task task = tasks [0]; if (task.GetType() == typeof(PrimitiveTask)) { PrimitiveTask pt = (PrimitiveTask)task; PrimitiveTask groundAction = InstantiateAction(pt, state, agent); if (groundAction != null) { plan.Add(groundAction); tasks.Remove(pt); if (tasks.Count > 0) { return(SHOPNoBack(tasks, plan, personality, pt.apply(state), agent)); } } else { return(null); } } else if (task.GetType() == typeof(CompoundTask)) { CompoundTask ct = (CompoundTask)task; List <Method> orderdedMethods = new List <Method>(); switch (agent.methodsOrdering) { case MethodsOrdering.NONE: orderdedMethods = ct.methods; break; case MethodsOrdering.PREF: orderdedMethods = ct.methods.OrderBy(m => m.preference != personality).ToList(); break; case MethodsOrdering.COSTANDPREF: orderdedMethods = ct.methods.OrderBy(m => m.leastCost()).ThenBy(m => m.preference != personality).ToList(); break; } foreach (Method m in orderdedMethods) { if (RuleMatcher.MatchCondition(m.preconditions, state, m.logicalOperator)) { List <Task> tempTasks = new List <Task>(tasks); tempTasks.Remove(task); int j = 0; foreach (Task subtask in m.subtasks) { tempTasks.Insert(0 + j, subtask); j++; } List <PrimitiveTask> tempPlan = SHOPNoBack(tempTasks, plan, personality, state, agent); if (tempPlan != null) { plan.Concat(tempPlan); break; } else { return(null); } } } } return(plan); }
// Start is called before the first frame update void Start() { lvlMgr = FindObjectOfType <LevelManager>(); player = FindObjectOfType <Self>(); agent = GetComponent <NavMeshAgent>(); /* Build a HTN */ // var root = new CompoundTask(); // htn = new HTNPlanner(root); // var ApproachCrate = new ApproachObject("crate"); // var PickUpCrate = new ObstaclePickUp("crate"); // var ApproachPlayer = new ApproachPlayer(); // var ThrowObstacle = new ThrowObstacle(); // var ApproachRock = new ApproachObject("rock"); // var PickUpRock = new ObstaclePickUp("rock"); // var ApproachRandom = new ApproachRandom(); // var getCrate = new CompoundTask(); // getCrate.AddMethod(new List<Task>() { ApproachCrate, PickUpCrate}); // var getRock = new CompoundTask(); // getRock.AddMethod(new List<Task>() { ApproachRock, PickUpRock }); // root.AddMethod(new List<Task>() { getCrate, ApproachPlayer, ThrowObstacle, ApproachRandom }); // root.AddMethod(new List<Task>() { getRock, ApproachPlayer, ThrowObstacle, ApproachRandom }); var root = new CompoundTask(); htn = new HTNPlanner(root); var ApproachCrate = new ApproachObject("crate"); var PickUpCrate = new ObstaclePickUp("crate"); var ApproachPlayer = new ApproachPlayer(); var ThrowObstacle = new ThrowObstacle(); var ApproachRock = new ApproachObject("rock"); var PickUpRock = new ObstaclePickUp("rock"); var ApproachRandom = new ApproachRandom(); var attackUsingCrate = new CompoundTask(); attackUsingCrate.AddMethod(new List <Task>() { ApproachCrate, PickUpCrate, ApproachPlayer, ThrowObstacle }); attackUsingCrate.AddMethod(new List <Task>() { ApproachPlayer, ThrowObstacle }); var attackUsingRock = new CompoundTask(); attackUsingRock.AddMethod(new List <Task>() { ApproachRock, PickUpRock, ApproachPlayer, ThrowObstacle }); attackUsingRock.AddMethod(new List <Task>() { ApproachPlayer, ThrowObstacle }); var move = new CompoundTask(); move.AddMethod(new List <Task>() { ApproachRandom }); move.AddMethod(new List <Task>() { ApproachPlayer }); root.AddMethod(new List <Task>() { attackUsingCrate }); root.AddMethod(new List <Task>() { attackUsingRock }); root.AddMethod(new List <Task>() { move }); }
void SimpleForwardPlanner() { Plan.Clear(); // we clear the plan before we start populating it Stack <Task> tasks = new Stack <Task> (); tasks.Push(new CaveMonsterCompoundTask()); // HTN ROOT while (tasks.Count > 0) { Task task = tasks.Pop(); if (task.isCompound()) { // then we can safely cast it CompoundTask compoundTask = (CompoundTask)task; // not all compound tasks need to find a task if (compoundTask.NeedsToFindTask()) { CompoundTask method = compoundTask.FindTask(); // if we found a task if (method != null) { // CODE TO SAVE STATE HERE NOT NEEDED BECAUSE OF PRE CONDITIONS // we push the subtasks into our tasks stack foreach (Task t in method.GetSubtasks()) { tasks.Push(t); } } else { // if method == null // CODE TO RESTORE STATE HERE } } // if don't need to find task, then we just add all subtasks of the compoundtask to tasks else { foreach (Task t in compoundTask.GetSubtasks()) { tasks.Push(t); } } } // ELSE task is primitive else { // can safely cast PrimitiveTask primitiveTask = (PrimitiveTask)task; if (primitiveTask.ValidPreconditions()) { // Also need to Update State but we will do that when we execute the primitive task, not here Plan.Add(primitiveTask); } else { // if preconditions were false // CODE TO RESTORE STATE HERE } } } hasPlan = true; Plan.Reverse(); // because we built it bottom up }
public void plan(GameController.WorldState currentWorldState) { finalPlan = new Stack <PrimitiveTask>(); Stack <PlannerState> decompHistory = new Stack <PlannerState>(); GameController.WorldState WorkingWS = currentWorldState.Copy(); tasksToProcess.Push(new PlayGame()); while (tasksToProcess.Count > 0) { Task CurrentTask = tasksToProcess.Pop(); if (CurrentTask.GetType().IsSubclassOf(typeof(CompoundTask))) { CompoundTask CurrentCompoundTask = (CompoundTask)CurrentTask; Method SatisfiedMethod = CurrentCompoundTask.FindSatisfiedMethod(WorkingWS); if (SatisfiedMethod != null) { //PlannerState currentState = new PlannerState(CurrentCompoundTask, finalPlan, tasksToProcess, SatisfiedMethod); // decompHistory.Push(currentState); SatisfiedMethod.subTasks.Reverse(); foreach (Task t in SatisfiedMethod.subTasks) { tasksToProcess.Push(t); } SatisfiedMethod.subTasks.Reverse(); } else if (decompHistory.Count > 0) { //RestoreToLastDecomposedTask(): PlannerState lastState = decompHistory.Pop(); CompoundTask lastCompoundTask = lastState.currentTask; finalPlan = lastState.finalPlan; tasksToProcess = lastState.tasksToProcess; // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method. lastCompoundTask.InvalidateMethod(lastState.currentMethod); tasksToProcess.Push(lastCompoundTask); } } else//Primitive Task { PrimitiveTask CurrentPrimitiveTask = (PrimitiveTask)CurrentTask; if (CurrentPrimitiveTask.PrimitiveConditionsMet(WorkingWS)) { // CurrentPrimitiveTask.ApplyEffects(this, WorkingWS); // Add this PrimitiveTask to the bottom of the finalPlan Stack <PrimitiveTask> temp = new Stack <PrimitiveTask>(); for (int i = 0; i < finalPlan.Count; i++) { PrimitiveTask nextTask = finalPlan.Pop(); temp.Push(nextTask); } temp.Push(CurrentPrimitiveTask); finalPlan = new Stack <PrimitiveTask>(); for (int i = 0; i < temp.Count; i++) { PrimitiveTask nextTask = temp.Pop(); finalPlan.Push(nextTask); } } else if (decompHistory.Count > 0) { //RestoreToLastDecomposedTask(); PlannerState lastState = decompHistory.Pop(); CompoundTask lastCompoundTask = lastState.currentTask; finalPlan = lastState.finalPlan; tasksToProcess = lastState.tasksToProcess; // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method. lastCompoundTask.InvalidateMethod(lastState.currentMethod); tasksToProcess.Push(lastCompoundTask); } } } }