zoukankan      html  css  js  c++  java
  • 行为树简介

    与有限状态机不同,行为树是一个分层节点树, 它控制着决策的流程,以及 "任务"(或 "Action" )的执行。

    树的叶节点是实际的指令,即我们的协同组件与系统其余部分交互的地方。

    例如,在面向服务的体系结构中,叶节点将包含与执行操作的 "服务器" 通信的 "客户端" 代码。

    在下面的例子中,我们可以看到在一个 Sequence 中执行两个 Action,DetectObjectGraspObject

    树的其它节点,不是叶节点,控制 "执行流程"。

    为了更好地理解这个控制流是如何发生的,请设想一个名为 "tick" 的信号。它在树的根部执行,并通过分支传播,直到到达一个或多个叶子节点。

    注意

    单词 tick 经常被用作动词(勾选/被勾选),它的意思是 "调用一个 TreeNode 的回调 tick() "。

    当一个 TreeNode 被勾选,它返回的 NodeStatus 应为下述之一:

    • SUCCESS
    • FAILURE
    • RUNNING

    顾名思义,前两个告诉父节点它们的操作是成功还是失败。

    异步节点的执行未完成并且需要更多时间来返回有效结果时,将返回 RUNNING 。

    异步节点可以停止

    节点的结果将回传给它的父节点,父节点将决定下一步应勾选哪个子节点,或者可以将结果返回给自己的父节点。

    节点类型

    ControlNode 是可以有1到N个子节点的节点。一旦收到 tick,该 tick 可以传播到一个或多个子节点。

    DecoratorNode 与 ControlNode 相似,但只能有一个子节点。

    ActionNode 是叶节点,没有任何子节点。用户应实现自己的 ActionNode 来执行实际任务。

    ConditionNode 与 ActionNode 等价,但它们始终是原子和同步的,即它们不得返回 RUNNING。它们不应改变系统的状态。

    示例

    为了更好地了解行为树的工作原理,让我们关注一些实例。为了简单起见,我们将不考虑 Action 返回 RUNNING 时发生的情况。

    我们将假定每个 Action 都是原子且同步执行的。

    第一个 ControlNode:Sequence

    让我们用最基本和最常用的 ControlNode:SequenceNode,来说明行为树是如何工作的。

    ControlNode 的子节点始终是有序的;在图形表示中,执行顺序是从左到右

    简而言之:

    • 如果一个子节点返回 SUCCESS,则勾选下一个。
    • 如果一个子节点返回 FAILURE,则不再勾选子节点,并且该 Sequence 返回 FAILURE。
    • 如果所有子节点都返回 SUCCESS,则该 Sequence 也返回 SUCCESS。

    您发现错误了吗?

    如果 Action GrabBeer 失败,则由于跳过了最后一个 Action CloseFridge,冰箱的门将保持打开状态。

    Decorators

    根据 DecoratorNode 的类型,该节点的目标可以是:

    • 转换从子节点那里收到的结果,
    • 停止子节点的执行,
    • 根据 Decorator 的类型重复勾选子节点。

    您可以创建自己的 Decorator 来扩展语法。

    节点 Inverter 是一个 Decorator,它对子节点返回的结果进行取反。因此,后面跟有称为 DoorOpen 的节点的 Inverter 等效于

    "Is the door closed?".
    

    如果子节点 OpenDoor 返回 FAILURE,节点 Retry 将对该子节点重复勾选N次(本例中为3次)。

    显然,右侧的分支表示:

    If the door is closed, then try to open it.
    Try up to 3 times, otherwise give up and return FAILURE.
    

    但...

    您发现错误了吗?

    如果 DoorOpen 返回 FAILURE,则我们会执行期望的行为。但是,如果返回 SUCCESS,则左分支失败,整个 Sequence 被中断。

    稍后我们将看到如何改进此树。

    第二个 ControlNode:Fallback

    FallbackNode(也称为 "Selectors" ),顾名思义,是可以表达 Fallback 策略的节点,即,如果一个子节点返回 FAILURE,下一步该怎么做。

    它按顺序勾选子节点,并且:

    • 如果一个子节点返回 FAILURE,则勾选下一个。
    • 如果一个子节点返回 SUCCESS,则不会再勾选任何子节点,并且该 Fallback 返回 SUCCESS。
    • 如果所有子节点都返回 FAILURE,那么该 Fallback 也返回 FAILURE。

    在下一个示例中,您将看到如何组合 Sequence 和 Fallback:

    门开着吗?

    如果没有,请尝试打开门。

    否则,如果您有钥匙,请开锁并打开门。

    否则,砸门。

    如果这些操作中的任何一个成功,请进入房间。

    重新回到 "Fetch me a beer"

    现在,我们可以改进 "Fetch Me a Beer" 示例,如果啤酒不在冰箱内,则该示例将门保持打开状态。

    我们使用 "绿色" 表示返回 SUCCESS 的节点,使用 "红色" 表示返回 FAILURE 的节点。黑色节点表示尚未执行。

    让我们创建一个替代树,即使 GrabBeer 返回 FAILURE 时,它也会关闭门。

    这两棵树最终都会关闭冰箱的门,但是:

    • 不管我们是否真的拿过啤酒,左侧的树都将始终返回 SUCCESS。
    • 如果有啤酒,则右侧的树将返回 SUCCESS,否则将返回 FAILURE。

    如果 GrabBeer 返回 SUCCESS,则一切正常。

  • 相关阅读:
    Hibernate框架—简介
    ooad单例模式-Singleton
    About-JavaOOAD
    win10内置ubuntu,mysql完美清理,并安装
    VUE关于对象动态添加属性无法双向绑定问题
    正则留档
    centos下tomcat中文路径不识别
    web服务器解释html-include
    rose
    聊天框突出箭头
  • 原文地址:https://www.cnblogs.com/xGonZh10n/p/12868391.html
Copyright © 2011-2022 走看看