@@ -10,71 +10,76 @@ our coordinating component interacts with the rest of the system.
10
10
For instance, in a service-oriented architecture, the leaves would contain
11
11
the "client" code that triggers an action.
12
12
13
- All the other nodes of the tree, those which are not leaves, control the
13
+ The other nodes of the tree, those which are not leaves, control the
14
14
"flow of execution".
15
15
16
16
To better understand how this flow takes place , imagine a signal, that we will further
17
17
call "__ tick__ " that is executed at the __ root__ of the tree and propagates through
18
- the branches until it reaches a leave .
18
+ the branches until it reaches one or multiple leaves .
19
19
20
20
The result of a tick can be either:
21
21
22
22
- __ SUCCESS__
23
23
- __ FAILURE__
24
24
- __ RUNNING__
25
25
26
+
26
27
The first two, as their names suggest, inform their parent that their operation
27
28
was a success or a failure.
28
- The latter usually means that the execution of the TreeNode is not completed
29
- and it needs more time to return a valid result.
29
+
30
+ RUNNING is returned by asynchronous nodes when their execution is not completed
31
+ and they needs more time to return a valid result.
32
+
33
+ This C++ library provides also the status __ IDLE__ ; it means that the node is ready to
34
+ start.
30
35
31
36
The result of a node is propagated back to the parent, that will decide
32
- which child should be ticked next or will return a result itself .
37
+ which child should be ticked next or will return a result to its own parent .
33
38
34
39
## Types of nodes
35
40
36
41
__ ControlNodes__ are nodes which can have 1 to N children. Once a tick
37
42
is received, this tick may be propagated to one or more of the children.
38
43
39
- __ DecoratorNodes__ can have only a single child.
44
+ __ DecoratorNodes__ is similar to the ControlNode, but it can have only a single child.
40
45
41
46
__ ActionNodes__ are leaves and do not have children. The user should implement
42
- their own ActionNodes that perform the actual task.
47
+ their own ActionNodes to perform the actual task.
43
48
44
- __ ConditionNodes__ are equivalent to ActionNodes, with the exeption that
45
- they are alwais aotmic ( they should not return RUNNING) and they should not
49
+ __ ConditionNodes__ are equivalent to ActionNodes, but
50
+ they are always atomic, i.e. they must not return RUNNING. They should not
46
51
alter the state of the system.
47
52
48
53
![ UML hierarchy] ( images/TypeHierarchy.png )
49
54
50
- !!! note
51
- Actions and Conditions differ only in terms of __ semantic__ .
52
- From an implementation point of view they are the same.
53
55
54
56
## Learn by example
55
57
56
- To better understand how a BehaviorTrees work let's focus on some practical
58
+ To better understand how a BehaviorTrees work, let's focus on some practical
57
59
examples. For the sake of simplicity we will not take into account what happens
58
60
when an action returns RUNNING.
59
61
60
62
We will assume that each Action is executed atomically and synchronously.
61
- In future sections we will more thoughtfully analyze asynchronous actions.
63
+
62
64
63
65
### Sequence
64
66
65
67
Let's illustrate how a BT works using the most basic and frequently used
66
68
ControlNode: the [ SequenceNode] ( SequenceNode.md ) .
67
69
70
+ The children of a ControlNode are always __ ordered__ ; it is up to the ControlNode
71
+ to consider this order or not.
72
+
73
+ In the graphical representation, the order of execution is __ from left to right__ .
74
+
68
75
![ Simple Sequence: fridge] ( images/SequenceBasic.png )
69
76
70
- It is important to notice that the children of a ControlNode are __ ordered__ .
71
- In this case the order of execution is __ from left to right__ .
72
77
73
- A Sequence works as described next :
78
+ In short :
74
79
75
80
- If a child returns SUCCESS, tick the next one.
76
81
- If a child returns FAILURE, then no more children are ticked and the Sequence returns FAILURE.
77
- - If all the children return SUCCESS, then the Fallback returns SUCCESS too.
82
+ - If all the children return SUCCESS, then the Sequence returns SUCCESS too.
78
83
79
84
??? warning "Exercise: find the bug! Expand to read the answer."
80
85
If the action __ GrabBeer__ fails, the door of the
@@ -87,7 +92,7 @@ The goal of a [DecoratorNode](DecoratorNode.md) is either to transform the resul
87
92
from the child, to terminate the child,
88
93
or repeat ticking of the child, depending on the type of Decorator.
89
94
90
- You can create your own Decorators too .
95
+ You can create your own Decorators.
91
96
92
97
![ Simple Decorator: Enter Room] ( images/DecoratorEnterRoom.png )
93
98
@@ -116,18 +121,17 @@ __But__ there is an error. Can you find it?
116
121
117
122
### Fallback
118
123
119
- [ FallbackNodes] ( FallbackNode.md ) , known also as __ "Selector"__ in the literature ,
120
- Is a node that is used to express, as the name suggests, fallback strategies,
121
- ie. what to do if a child return FAILURE.
124
+ [ FallbackNodes] ( FallbackNode.md ) , known also as __ "Selector"__ ,
125
+ are nodes that can express, as the name suggests, fallback strategies,
126
+ ie. what to do next if a child returns FAILURE.
122
127
123
- In short, it ticks the children in order, as usual from left to right and:
128
+ In short, it ticks the children in order and:
124
129
125
130
- If a child returns FAILURE, tick the next one.
126
131
- If a child returns SUCCESS, then no more children are ticked and the Fallback returns SUCCESS.
127
132
- If all the children return FAILURE, then the Fallback returns FAILURE too.
128
133
129
134
In the next example, you can see how Sequence and Fallbacks can be combined:
130
-
131
135
132
136
![ FallbackNodes] ( images/FallbackBasic.png )
133
137
@@ -162,11 +166,11 @@ returns FAILURE.
162
166
Both the trees will close the door of the fridge, eventually, but:
163
167
164
168
- the tree on the __ left__ side will always return SUCCESS if we managed to
165
- open and clode the fridge.
169
+ open and close the fridge.
166
170
- the tree on the __ right__ side will return SUCCESS if the beer was there,
167
171
FAILURE otherwise.
168
172
169
- We can easily double-check that everything works as usual if __ GrabBeer__ returns SUCCESS.
173
+ Everything works as expected if __ GrabBeer__ returns SUCCESS.
170
174
171
175
![ FetchBeer success] ( images/FetchBeer2.png )
172
176
0 commit comments