概念
执行顺序: 从根到叶, 从上到下, 从左到右; 节点执行结果: Fail、Success、Running
分类 | 描述 | 包含 |
---|---|---|
control flow nodes | 也叫组合, 一般是中间节点 , 代表了逻辑 | Sequence, Fallback, Parallel, and Decorator |
execution nodes | 叶子节点, 两类 | Action, Condition |
控制节点, 一般代表树结构中的父节点. 一般来说,常用的控制节点有以下三种:
- 选择 (fallback): 失败了进行下一个节点,所有子节点失败了才返回失败; 只要某个成功了就返回成功
- 序列(Sequence):成功了进行下一个节点,某个节点失败就返回失败,所有子节点成功了才成功;
- 并行(Parallel):同时运行所有子节点,根据子节点成功的比例决定
- 装饰 (Decorator):单个子节点,用户自定义规则修改返回状态;比如invert,max-N-tries; max-T-sec
前提(Precondition),每一个节点,不管是行为节点还是控制节点,都会包含一个前提的部分
整体术语
每个节点需要有进入(Enter),离开(Exit),运行(Execute)等部分,
有行为节点(ActionNode),控制节点(ControlNode),前提(Precondition)等基类,然后,还需要定义行为树的输入(InputParam)和输出(OutputParam),一般来说,我们希望行为树是一个黑盒,也就是说,它仅依赖于预定义的输入。输入可以是黑板(Blackboard),工作池(Working Memory)等等数据结构,输出可以是请求(Request),或者其他自定义的数据结构
blackboard, 指一种设计模式,? 数据结构, 用黑板从各个模块中来收集行为树决策和执行的过程中需要用到的数据,然后提交给行为树使用。值得注意的是,这块黑板对于行为树来说是只读(Readonly)的,行为树不允许修改和添加任何信息到这块黑板上面。因为很难从程序上去限制(就算用const,有时为了方便还能强转成非const),所以限制只能是一种规则,或者说约定。
黑板Blackboard概念的引出是基于在不同Node之间共享数据的考虑. 任何一个系统,都少不了游离于流程之外的全局数据,这些数据需要得到某种封装跟格式化。
BT规则规定,每个BT只能有一个blackboard,BT提供一系列对blackboard以及其中的数据的访问接口
xml 中黑板的entry (key) 用{} 包起来
类型
选择节点 fallback, 也叫selector
遍历方式为从左到右依次执行所有子节点,只要节点返回 Fail,就继续执行后续节点,直到一个节点返回Success或Running为止. 如果有一个节点返回Success或Running则向父节点返回Success或Running。否则向父节点返回 Fail。
Before ticking the first child, the node status becomes RUNNING
This family of nodes are known as “Selector” or “Priority” in other frameworks.Their purpose is to try different strategies, until we find one that “works”.
They share the following rules:
- Before ticking the first child, the node status becomes RUNNING.
- If a child returns FAILURE, the fallback ticks the next child.
- If the last child returns FAILURE too, all the children are halted and the sequence returns FAILURE.
- If a child returns SUCCESS, it stops and returns SUCCESS. All the children are halted.
两种类型Fallback vs FallbackStar
The two versions of Fallback differ in the way they react when a child returns RUNNING:
- FallbackStar will return RUNNING and the next time it is ticked, it will tick the same child where it left off before.
Plain old Fallback will return RUNNING and the index of the next child to execute is reset after each execution.
顺序节点 sequence
从左向右依次执行所有节点,只要节点返回Success,就继续执行后续节点,当一个节点返回Fail或 Running 时,停止执行后续节点。向父节点返回 Fail 或 Running,只有当所有节点都返回 Success 时,才向父节点返回 Success。
Before ticking the first child, the node status becomes RUNNING
三种类型Sequence vs SequenceStar vs ReactiveSequence
They share the following rules:
- Before ticking the first child, the node status becomes RUNNING.
- If a child returns SUCCESS, it ticks the next child.
- If the last child returns SUCCESS too, all the children are halted and the sequence returns SUCCESS.
To understand how the three ControlNodes differ, refer to the following table:
Type of ControlNode | Child returns FAILURE | Child returns RUNNING |
---|---|---|
Sequence | Restart | Tick again |
ReactiveSequence | Restart | Restart |
SequenceStar | Tick again | Tick again |
条件节点 condition
如果条件测试结果为真,向父节点返回 Success,否则返回 Fail。
不能返回RUNING状态
条件节点一般作为叶节点。
没有running 状态
行为节点 action
行为节点(Action)用来执行实际的工作,行为节点执行过程中失败,向父节点返回 Fail,执行完毕向父节点返回 Success,正在执行中时向父节点返回 Running。
并行节点 parallel
并行节点(Parallel)有 N 个节点,每次执行所有节点,直到一个节点返回 Fail 或者全部返回 Success为止,此时并行节点向父节点返回 Fail 或者 Success,并终止执行其他所有节点。否则至少有一个节点处于 Running 状态,则执行完所有节点向父节点返回 Running。与选择节点不同的是并行节点不需要记录返回 Running 结果的节点,每次执行都会从左向右依次执行所有子节点。
修饰节点 Decorator
修饰节点(Decorator)修饰节点不能独立存在,其作用为对子节点进行修饰,以得到我们所希望的结果.
修饰节点有很多种,其中有一些是用于决定是否允许子节点运行的,也叫过滤器,例如 Until Success, Until Fail 等,首先确定需要的结果,循环执行子节点,直到节点返回的结果和需要的结果相同时向父节点返回需要的结果,否则返回 Running。
最好的一个例子是RateDecoratorNode,限定子Node被执行的频率。
类型 | |
---|---|
Inverter | !取反 |
Repeater | |
Return Failure | |
Return Success | |
Unitl Failure | |
Unitl Success | |
InverterNode | |
ForceSuccessNode | If the child returns RUNNING, this node returns RUNNING too. Otherwise, it returns always SUCCESS |
ForceFailureNode | |
RepeatNode | Tick the child up to N times, where N is passed as a Input Port, as long as the child returns SUCCESS.Interrupt the loop if the child returns FAILURE and, in that case, return FAILURE too. 成功了重试 |
RetryNode | Tick the child up to N times, where N is passed as a Input Port, as long as the child returns FAILURE. 失败了重试 |
TimeoutNode |
随机节点 random
ports remapping
blackboard 是一种共享的键值存储
ports 提供了一种机制,允许节点之间交换信息
ports 被连接起来,通过blackboard的同样的关键字
一个节点的所有ports 必须再编译前已知; ports 之间的连接在部署的时候已经完成了。
<root main_tree_to_execute = "MainTree">
<BehaviorTree ID="MainTree">
<Sequence name="main_sequence">
<SetBlackboard output_key="move_goal" value="1;2;3" />
<SubTree ID="MoveRobot" target="move_goal" output="move_result" />
<SaySomething message="{move_result}"/>
</Sequence>
</BehaviorTree>
<BehaviorTree ID="MoveRobot">
<Fallback name="move_robot_main">
<SequenceStar>
<MoveBase goal="{target}"/>
<SetBlackboard output_key="output" value="mission accomplished" />
</SequenceStar>
<ForceFailure>
<SetBlackboard output_key="output" value="mission failed" />
</ForceFailure>
</Fallback>
</BehaviorTree>
</root>
bt wiki
bt demostration video 1
bt demonstration video 2
robmosys
cnurobotic_flexible_be
cnurobotic_flexibla_navi