behaviortree和Groot

Behavior Tree

官方文档:https://www.behaviortree.dev/docs/Intro

BehaviorTree.CPP

https://github.com/BehaviorTree/BehaviorTree.CPP

BehaviorTree官方文档:

https://www.behaviortree.dev/bt_basics/

 Behavior Tree 原理 

 分四种节点

行为树(Behavior Tree)具有如下的特性:

它只有4大类型的Node:
* Composite Node  组合节点
* Decorator Node   修饰节点
* Condition Node   条件节点(叶节点)
* Action Node    动作节点(叶节点)

任何Node被执行后,必须向其Parent Node报告执行结果:成功 / 失败。
这简单的成功 / 失败汇报原则被很巧妙地用于控制整棵树的决策方向。

一、组合节点 Composite Node

先看Composite Node,其实它按复合性质还可以细分为3种:

1. Selector Node

(选择节点,顺序执行,满足任意子节点true)

当执行本类型Node时,它将从begin到end迭代执行自己的Child Node:
如遇到一个Child Node执行后返回True,那停止迭代,
本Node向自己的Parent Node也返回True;否则所有Child Node都返回False,
那本Node向自己的Parent Node返回False。

2. Sequence Node

(顺序执行节点,全部子节点都必须true,否则false)
当执行本类型Node时,它将从begin到end迭代执行自己的Child Node:
如遇到一个Child Node执行后返回False,那停止迭代,
本Node向自己的Parent Node也返回False;否则所有Child Node都返回True,
那本Node向自己的Parent Node返回True。

3. Parallel Node

(并发执行节点)
并发执行它的所有Child Node。
而向Parent Node返回的值和Parallel Node所采取的具体策略相关:
Parallel Selector Node: 一False则返回False,全True才返回True。
Parallel Sequence Node: 一True则返回True,全False才返回False。
Parallel Hybird Node: 指定数量的Child Node返回True或False后才决定结果。

Parallel Node提供了并发,提高性能。
不需要像Selector/Sequence那样预判哪个Child Node应摆前,哪个应摆后,
常见情况是:
(1)用于并行多棵Action子树。
(2)在Parallel Node下挂一棵子树,并挂上多个Condition Node,
以提供实时性和性能。
Parallel Node增加性能和方便性的同时,也增加实现和维护复杂度。

PS:上面的Selector/Sequence准确来说是Liner Selector/Liner Sequence。
AI术语中称为strictly-order:按既定先后顺序迭代。

Selector和Sequence可以进一步提供非线性迭代的加权随机变种。
Weight Random Selector提供每次执行不同的First True Child Node的可能。
Weight Random Sequence则提供每次不同的迭代顺序。
AI术语中称为partial-order,能使AI避免总出现可预期的结果。

二、修饰节点 Decorator Node

再看Decorator Node,它的功能正如它的字面意思:它将它的Child Node执行

后返回的结果值做额外处理后,再返回给它的Parent Node。

比如

Decorator Not

Decorator FailUtil

Decorator Counter

Decorator Time

Decorator Log

Decorator Ani

Decorator Nothing

三、条件节点(叶节点) Condition Node

Condition Node,它仅当满足Condition时返回True。

四、动作节点(叶节点)Action Node

Action Node,它完成具体的一次(或一个step)的行为,视需求返回值。
而当行为需要分step/Node间进行时,可引入Blackboard进行简单数据交互。

小结

整棵行为树中,只有Condition Node和Action Node才能成为Leaf Node,而也
只有Leaf Node才是需要特别定制的Node;Composite Node和Decorator Node均
用于控制行为树中的决策走向。

每个节点都应该有以下三种状态:
Running,
Success,
Failed

Running状态用于表明该节点的结果不能立刻获知,比如游戏中的角色进行“向目标移动”

这个动作,很显然这个动作不能在这一帧中立刻完成,当行为树运行到此节点时,并不能

获知是success或者failed,于是返回running,表示该节点正在运行中,并记录此节点

的位置,下一帧运行到此节点的父节点时,则从此节点继续运行,跳过之前的节点。

==================================================================================

行为树架构图

行为树 结构图如下,一棵倒置的树

 


行为树采用节点描述行为逻辑,主要节点类型有:
组合节点:选择节点、顺序节点、随机选择节点、随机顺序节点、随机权重节点、并行节点、并行执行所有节点、if 判断并行节点、if 判断顺序节点

修饰节点:修饰节点取反、修饰节点重复、修饰节点_返回 Fail、修饰节点_返回 Success、修饰节点_直到 Fail、修饰节点_直到 Success

行为树入门:https://zhuanlan.zhihu.com/p/463182588

 https://robohub.org/introduction-to-behavior-trees/

组合节点与叶节点区分

一棵行为树表示一个AI逻辑。执行这个 AI 逻辑,需要从根节点开始深度优先遍历执行节点,执行过程中,节点根据自身的类型确定执行逻辑或调用子节点,节点将执行结果反馈给父节点。

从结构上节点可分为:组合节点、叶节点 。
组合节点就是拥有子节点的节点。
叶节点 就是不能添加子节点的节点。

其中叶节点 :条件节点、行为节点。其他为组合节点

如下图一个行为树示例图:

行为树节点顺序如下,
节点1 为根节点, 节点2、节点5为中间节点,节点3、4、6、7,为子节点
节点 1、2、5为组合节点,节点3、4、6、7为叶节点

 


节点执行结果

执行结果可分为三种:Fail、Success、Running。
Fail : 节点执行失败(如:条件节点判定为 false、执行节点失败、没有符合执行的节点等)
Success:节点执行成功(如:条件节点判定为 true、执行节点成功等)
Running:节点执行中(如:正在跑向目标、正在吃饭、动画播放中等)

叶节点

叶节点类型分为两种:条件节点和行为节点

条件叶节点

条件节点(Condition)即是条件判定,例如:“是否饿了?”、“是否有饭?”、“是否有作业”等。
如果条件测试结果为真,向父节点返回 Success,否则返回 Fail。
条件节点为叶子节点

行为叶节点

行为节点(Action)用来执行实际的工作,如:做饭、吃饭、打球、写作业等。
行为节点有些可能一帧就可以执行完成,有些可能需要多帧才能完成。
行为节点执行过程中失败,向父节点返回 Fail,
执行完毕(成功)向父节点返回 Success,
正在执行中向父节点返回 Running。

 

组合节点

组合节点用来控制树的遍历方式,每种组合节点的遍历方式都不相同。下面是各个组合节点的执行逻辑

1.选择节点

选择节点:依次从头顺次遍历执行所有子节点
当前执行节点返回 Success,退出停止,向父节点
返回 Success

当前执行节点返回 Fail,退出当前节点
继续执行下一个节点

当前执行节点返回 Running, 记录当前节点,向父节
点返回 Running,下次执行直接从该节点开始

如果所有节点都返回Fail,执行完所有节点后
向父节点返回 Fail

2.顺序节点

顺序节点:依次执行子节点
当前执行节点返回 Success,就继续执行后续节点

当前执行节点返回 Fail,退出停止,向父节点
返回 Fail,下次执行直接从第一个节点开始

当前执行节点返回 Running, 记录当前节点,向父节
点返回 Running,下次执行直接从该节点开始

如果所有节点都返回 Success,向父节点返回 Success

3.随机选择节点

随机选择节点:(参考选择节点)
每次随机一个未执行的节点,总随机次数为子节点个数

当前执行节点返回 Success,退出停止
向父节点返回 Success

当前执行节点返回 Fail,退出当前节点
继续随机一个未执行的节点开始执行

当前执行节点返回 Running, 记录当前节点
向父节点返回 Running,下次执行直接从该节点开始

如果所有节点都返回Fail,执行完所有节点后
向父节点返回 Fail

4.随机顺序节点

随机顺序节点:(参考顺序节点)
每次随机一个未执行的节点,总随机次数为子节点个数

当前执行节点返回 Success,继续随机一个未执行的节点

当前执行节点返回 Fail,退出停止
向父节点返回 Fail

当前执行节点返回 Running, 记录当前节点
向父节点返回 Running,下次执行直接从该节点开始

如果所有节点都返回 Success
向父节点返回 Success

5.随机权重节点

随机权重节点:(参考随机选择节点)
每次根据节点权重随机一个未执行的节点
总随机次数为子节点个数

当前执行节点返回 Success,退出停止
向父节点返回 Success

当前执行节点返回 Fail,退出当前节点
继续随机一个未执行的节点开始执行

当前执行节点返回 Running, 记录当前节点
向父节点返回 Running
下次执行直接从该节点开始

如果所有节点都返回Fail,执行完所有节点后
向父节点返回 Fail

6.并行节点

并行节点:依次从头顺次遍历执行所有子节点

当前执行节点返回 Fail,退出停止,向父节点
返回 Fail

当前执行节点返回 Success,记录当前节点,继续
执行下一个节点,记录所有返回 Success 的节点

当前执行节点返回 Running, 记录当前节点,继续
执行下一个节点,记录所有返回 Running 的节点

如果没有节点返回 Fail
如果所有节点都返回 Success 向父节点返回 Success
否则向父节点返回 Running

7.并行执行所有节点

并行执行所有节点:依次从头顺次遍历执行所有子节点

当前执行节点返回 Success、 Fail、Running 都继续
执行下一个节点,分别记录返回三种结果的节点个数

执行完所有节点后
如果所有节点都返回 Success 向父节点返回 Success
如果所有节点都返回 Fail 向父节点返回 Fail
否则一定有节点返回了Running 向父节点返回 Running

8.if 判断并行节点

if判断并行节点:
只能有 二或者三个子节点
第一个为判断节点只能返回Success、Fail

如下方配置三个节点
第一个节点返回 Success时,执行 第二个节点
第一个节点返回 Fail 时,执行 第三个节点

或者配置两个节点
第一个节点返回 Success时,执行 第二个节点

因为是并行节点,每次执行都会先执行第一个节点
根据第一个节点返回 (Success 或者 Fail)选择执行第M个节点

执行第一个条件节点,记录返回结果 result
根据配置 判断 执行第 M(二、三) 节点

if N 是空 then
执行 第 M 节点的 Enter
elseif N 不等于 M then
执行 第 N 节点的 OnExit
执行 第 M 节点的 Enter
end
记录当前执行节点:令 N = M
执行 第 N 节点的 Execute 并记录结果 result

9.if 判断顺序节点

if判断顺序节点:
只能有 二或者三个子节点
第一个为判断节点只能返回Success、Fail

配置同上第8条

因为是顺序节点,每次执行时
如果当前有正在执行的第二、第三个节点则
直接执行它的 Execute

如果没有,则执行第一个节点,根据第一个节点返回
根据第一个节点返回 (Success 或者 Fail)选择执行第M个节点

if result == Success then
令 N = nil
return 向父节点返回 Success
elseif result == Fail then
令 N = nil
return 向父节点返回 Fail
else -- result == Running
return 向父节点返回 Running
end

10.修饰节点取反

取反修饰节点 Inverter 对子节点执行结果取反

11.修饰节点重复

修饰节点_重复:
开始执行该节点时,将记录次数清零
顺序执行所有子节点(记为 1 次),不关心节点返回结果
如果 执行次数 < 配置执行次数 向父节点返回 Running
如果 执行次数 >= 配置执行次数 向父节点返回 Success

12.修饰节点_返回 Fail

修饰_返回Fail:
执行节点,无论节点返回 Success、Fail、Running
执行结束后永远向父节点返回 Fail

13.修饰节点_返回 Success

修饰_返回Success:
执行节点,无论节点返回 Success、Fail、Running
执行结束后永远向父节点返回 Success

14.修饰节点_直到 Fail

修饰_直到Fail:
执行节点
如果节点返回结果不是 Fail
向父节点返回 Running

直到节点返回 Fail,向父节点返回 Success

15.修饰节点_直到 Success

修饰_直到Success:
执行节点
如果节点返回结果不是 Success
向父节点返回 Running

直到节点返回 Success,向父节点返回 Success

 

==================================================================================

Groot

官方文档:

github:https://github.com/BehaviorTree/Groot

主页:https://www.behaviortree.dev/groot/

 

说明

BehaviorTree行为树是树状的结构,它的逻辑流程是由xml文件描述的。

用其配套的工具Groot来可视化行为树。

Groot is a Graphical Editor, written in C++ and Qt, to create BehaviorTrees.

It is compliant with the the library BehaviorTree.CPP.

如下图所示:

 

可视化和序列化表达行为树

QT界面显示效果

 

posted @ 2024-09-29 09:19  南水之源  阅读(105)  评论(0编辑  收藏  举报