-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from ptrefall/stateless_planner_v2
Stateless Planner
- Loading branch information
Showing
9 changed files
with
190 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using FluidHTN.Conditions; | ||
using FluidHTN.PrimitiveTasks; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace FluidHTN | ||
{ | ||
public class DefaultPlannerState : IPlannerState | ||
{ | ||
// ========================================================= PROPERTIES | ||
|
||
public ITask CurrentTask { get; set; } | ||
public Queue<ITask> Plan { get; set; } = new Queue<ITask>(); | ||
public TaskStatus LastStatus { get; set; } | ||
|
||
// ========================================================= CALLBACKS | ||
|
||
public Action<Queue<ITask>> OnNewPlan { get; set; } | ||
public Action<Queue<ITask>, ITask, Queue<ITask>> OnReplacePlan { get; set; } | ||
public Action<ITask> OnNewTask { get; set; } | ||
public Action<ITask, ICondition> OnNewTaskConditionFailed { get; set; } | ||
public Action<IPrimitiveTask> OnStopCurrentTask { get; set; } | ||
public Action<IPrimitiveTask> OnCurrentTaskCompletedSuccessfully { get; set; } | ||
public Action<IEffect> OnApplyEffect { get; set; } | ||
public Action<IPrimitiveTask> OnCurrentTaskFailed { get; set; } | ||
public Action<IPrimitiveTask> OnCurrentTaskContinues { get; set; } | ||
public Action<IPrimitiveTask, ICondition> OnCurrentTaskExecutingConditionFailed { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using FluidHTN.Conditions; | ||
using FluidHTN.PrimitiveTasks; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace FluidHTN | ||
{ | ||
public interface IPlannerState | ||
{ | ||
// ========================================================= PROPERTIES | ||
|
||
ITask CurrentTask { get; set; } | ||
Queue<ITask> Plan { get; set; } | ||
TaskStatus LastStatus { get; set; } | ||
|
||
// ========================================================= CALLBACKS | ||
|
||
/// <summary> | ||
/// OnNewPlan(newPlan) is called when we found a new plan, and there is no | ||
/// old plan to replace. | ||
/// </summary> | ||
Action<Queue<ITask>> OnNewPlan { get; set; } | ||
|
||
/// <summary> | ||
/// OnReplacePlan(oldPlan, currentTask, newPlan) is called when we're about to replace the | ||
/// current plan with a new plan. | ||
/// </summary> | ||
Action<Queue<ITask>, ITask, Queue<ITask>> OnReplacePlan { get; set; } | ||
|
||
/// <summary> | ||
/// OnNewTask(task) is called after we popped a new task off the current plan. | ||
/// </summary> | ||
Action<ITask> OnNewTask { get; set; } | ||
|
||
/// <summary> | ||
/// OnNewTaskConditionFailed(task, failedCondition) is called when we failed to | ||
/// validate a condition on a new task. | ||
/// </summary> | ||
Action<ITask, ICondition> OnNewTaskConditionFailed { get; set; } | ||
|
||
/// <summary> | ||
/// OnStopCurrentTask(task) is called when the currently running task was stopped | ||
/// forcefully. | ||
/// </summary> | ||
Action<IPrimitiveTask> OnStopCurrentTask { get; set; } | ||
|
||
/// <summary> | ||
/// OnCurrentTaskCompletedSuccessfully(task) is called when the currently running task | ||
/// completes successfully, and before its effects are applied. | ||
/// </summary> | ||
Action<IPrimitiveTask> OnCurrentTaskCompletedSuccessfully { get; set; } | ||
|
||
/// <summary> | ||
/// OnApplyEffect(effect) is called for each effect of the type PlanAndExecute on a | ||
/// completed task. | ||
/// </summary> | ||
Action<IEffect> OnApplyEffect { get; set; } | ||
|
||
/// <summary> | ||
/// OnCurrentTaskFailed(task) is called when the currently running task fails to complete. | ||
/// </summary> | ||
Action<IPrimitiveTask> OnCurrentTaskFailed { get; set; } | ||
|
||
/// <summary> | ||
/// OnCurrentTaskContinues(task) is called every tick that a currently running task | ||
/// needs to continue. | ||
/// </summary> | ||
Action<IPrimitiveTask> OnCurrentTaskContinues { get; set; } | ||
|
||
/// <summary> | ||
/// OnCurrentTaskExecutingConditionFailed(task, condition) is called if an Executing Condition | ||
/// fails. The Executing Conditions are checked before every call to task.Operator.Update(...). | ||
/// </summary> | ||
Action<IPrimitiveTask, ICondition> OnCurrentTaskExecutingConditionFailed { get; set; } | ||
} | ||
} |
Oops, something went wrong.
607ba05
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit surprising that a PlannerState belongs to Context.
But thinking twice, make planner statless is kind of cool !
607ba05
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for sharing your opinion on this commit fnaith! The reasoning is from the perspective of being able to trigger planning for agents on multiple threads and being guaranteed that the agent's context is respected. This is why it made sense to put PlannerState in the Agent's Context, as the planner's state relates to the plan, current task and current status of planning for "the last agent context is processed". This does of course mean that in a situation where you don't need planning to run in parallel, we spend more memory than is strictly needed. This is where the setter on the PlannerState property can be used in your own Context definition to override, so you could set it to a common PlannerState instance if you so wanted to. I am of course open to making alterations here, so feel free to suggest improvements.
607ba05
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I noticed that you import
System.Threading.Tasks
andSystem.Security.Cryptography.X509Certificates
for multiple threads.It all make scese now, thanks for your explanation.
607ba05
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, those probably shouldn't be in there. Sometimes this auto-import stuff gets overly "excited". Thanks for pointing that out! About 5 years ago TotallyGatsby successfully used the stateless planner branch with Unity DOTS. He has several thousand agents running some basic domains in real-time.
607ba05
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the performance is very promising.
I wish the godot can support hundreds of agent.