本文主要是介绍行为树(BT)笔记(二):行为树简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
行为树简介
与有限状态机不同,行为树是一个分层节点树,它控制决策流和“任务”的执行,或者我们将进一步称之为“ 动作 ”。
树的叶子是实际命令,即我们的协调组件与系统其余部分交互的位置。
例如,在面向服务的体系结构中,叶子将包含与执行操作的“服务器”通信的“客户端”代码。
在下面的示例中,我们可以看到在序列中执行的两个Actions, DetectObject
以及GraspObject。
树的其他节点,即不是叶子的节点,控制“执行流程”。
为了更好地理解这种控制流是如何发生的,设想一个叫做“ tick ” 的信号; 它在树的根部执行,并通过分支传播,直到它到达一个或多个叶子。
单词tick经常用作动词(勾选/被勾选),这意味着“调用一个tick()名为TreeNode的回调“。
当一个TreeNode被
选中,它会返回一个NodeStatus
:
- SUCCESS
- FAILURE
- RUNNING
- IDLE
前两个正如它们的名字一样,通知它们父母的行动是成功还是失败。
异步节点在执行未完成时返回RUNNING,并且需要更多时间来返回有效结果。
此C ++库还提供IDLE状态; 这意味着节点已准备好启动。
节点的结果将传播回其父节点,该节点将决定下一个应该选中哪个子节点,或者将结果返回给它自己的父节点。
节点的类型
ControlNodes是可以有1到N 个子节点的节点。一旦收到tick,该tick可以传播给一个或多个子节点。
DecoratorNodes类似于ControlNode,但它只能有一个子节点。
ActionNodes是叶子,没有子节点。用户应该实现自己的ActionNodes来执行实际任务。
ConditionNodes等效于ActionNodes,但它们始终是原子的,即它们不能返回RUNNING。它们不应该改变系统的状态。
例子
为了更好地理解BehaviorTrees如何工作,让我们关注一些实际的例子。为简单起见,我们不会考虑操作返回RUNNING时会发生什么。
我们假设每个Action都是原子地和同步地执行的。
第一个ControlNode:序列
让我们来说明BT如何使用最基本和最常用的ControlNode:SequenceNode。
ControlNode的子节点总是有序的 ; 是由ControlNode来考虑这个顺序。
在图形表示中,执行顺序是从左到右。
简而言之:
- 如果子节点返回SUCCESS,请勾选子节点。
- 如果子节点返回FAILURE,则不再勾选子节点并且向Sequence返回FAILURE。
- 如果所有子节点都返回SUCCESS,则Sequence也返回SUCCESS。
存在的bug
如果操作GrabBeer失败,冰箱的门将保持打开状态,因为跳过了最后一个动作CloseFridge。
装饰器
DecoratorNode的目标是转接从子节点接收的结果,终止子节点,或重复tick子节点,具体取决于Decorator的类型。
您可以创建自己的装饰器。
节点Inverter是一个装饰器,它反转其子节点返回的结果; 因此,Inverter后跟着一个称为DoorOpen的节点 相当于
“门关上了吗?”
如果子节点返回FAILURE ,节点Retry将重复给子节点tick N次(在该例子中为3次)。
显而易见的,右侧的分支意味着:
如果门关闭,请尝试打开它。
尝试最多3次,否则放弃并返回FAILURE。
但是...
如果DoorOpen返回FAILURE,我们会有所行动。但是如果它返回SUCCESS,则左分支失败并且整个序列被中断。稍后我们将看到如何改进这棵树。
第二个ControlNode:Fallback
FallbackNodes,也称为“选择器”,是一个节点,顾名思义,它可以表达反馈策略,即如果子节点退出失败,下一步该怎么做。
简而言之,它按顺序给子节点打勾,并且:
- 如果子节点退回FAILURE,请勾选下一个子节点。
- 如果子节点返回SUCCESS,则不再勾选子项,并且Fallback返回SUCCESS。
- 如果所有子节点都返回FAILURE,那么Fallback也会返回FAILURE。
在下一个示例中,您可以看到序列和反馈如何组合:
门开了吗?如果没有,请尝试打开门。门没开,如果您有钥匙,请解锁并打开门。否则,砸门。如果这些操作中的任何一个成功,则进入房间。
重写“给我拿一杯啤酒”
我们现在可以改进“给我拿一杯啤酒”的例子,如果啤酒不在冰箱内保持开门的状态。
我们使用绿色表示返回SUCCESS的节点,使用红色表示返回FAILURE的节点,黑色节点则表示永远不会执行。
让我们创建一个替代树,即使GrabBeer 返回FAILURE 也会关闭门。
这两棵树最终将关闭冰箱的门,但是:
-
如果我们设法打开和关闭冰箱,左侧的树将始终返回SUCCESS。
-
如果啤酒在那里,右侧的树将返回SUCCESS,否则将失败。
如果GrabBeer返回SUCCESS,一切都按预期工作。
这篇关于行为树(BT)笔记(二):行为树简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!