Skip to content

Commit e085949

Browse files
Docs added
1 parent 8ac2ca9 commit e085949

37 files changed

+2071
-359
lines changed

docs/BT_basics.md

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,71 +10,76 @@ our coordinating component interacts with the rest of the system.
1010
For instance, in a service-oriented architecture, the leaves would contain
1111
the "client" code that triggers an action.
1212

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
1414
"flow of execution".
1515

1616
To better understand how this flow takes place , imagine a signal, that we will further
1717
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.
1919

2020
The result of a tick can be either:
2121

2222
- __SUCCESS__
2323
- __FAILURE__
2424
- __RUNNING__
2525

26+
2627
The first two, as their names suggest, inform their parent that their operation
2728
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.
3035

3136
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.
3338

3439
## Types of nodes
3540

3641
__ControlNodes__ are nodes which can have 1 to N children. Once a tick
3742
is received, this tick may be propagated to one or more of the children.
3843

39-
__DecoratorNodes__ can have only a single child.
44+
__DecoratorNodes__ is similar to the ControlNode, but it can have only a single child.
4045

4146
__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.
4348

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
4651
alter the state of the system.
4752

4853
![UML hierarchy](images/TypeHierarchy.png)
4954

50-
!!! note
51-
Actions and Conditions differ only in terms of __semantic__.
52-
From an implementation point of view they are the same.
5355

5456
## Learn by example
5557

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
5759
examples. For the sake of simplicity we will not take into account what happens
5860
when an action returns RUNNING.
5961

6062
We will assume that each Action is executed atomically and synchronously.
61-
In future sections we will more thoughtfully analyze asynchronous actions.
63+
6264

6365
### Sequence
6466

6567
Let's illustrate how a BT works using the most basic and frequently used
6668
ControlNode: the [SequenceNode](SequenceNode.md).
6769

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+
6875
![Simple Sequence: fridge](images/SequenceBasic.png)
6976

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__.
7277

73-
A Sequence works as described next:
78+
In short:
7479

7580
- If a child returns SUCCESS, tick the next one.
7681
- 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.
7883

7984
??? warning "Exercise: find the bug! Expand to read the answer."
8085
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
8792
from the child, to terminate the child,
8893
or repeat ticking of the child, depending on the type of Decorator.
8994

90-
You can create your own Decorators too.
95+
You can create your own Decorators.
9196

9297
![Simple Decorator: Enter Room](images/DecoratorEnterRoom.png)
9398

@@ -116,18 +121,17 @@ __But__ there is an error. Can you find it?
116121

117122
### Fallback
118123

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.
122127

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:
124129

125130
- If a child returns FAILURE, tick the next one.
126131
- If a child returns SUCCESS, then no more children are ticked and the Fallback returns SUCCESS.
127132
- If all the children return FAILURE, then the Fallback returns FAILURE too.
128133

129134
In the next example, you can see how Sequence and Fallbacks can be combined:
130-
131135

132136
![FallbackNodes](images/FallbackBasic.png)
133137

@@ -162,11 +166,11 @@ returns FAILURE.
162166
Both the trees will close the door of the fridge, eventually, but:
163167

164168
- 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.
166170
- the tree on the __right__ side will return SUCCESS if the beer was there,
167171
FAILURE otherwise.
168172

169-
We can easily double-check that everything works as usual if __GrabBeer__ returns SUCCESS.
173+
Everything works as expected if __GrabBeer__ returns SUCCESS.
170174

171175
![FetchBeer success](images/FetchBeer2.png)
172176

docs/ControlNode.md

Lines changed: 0 additions & 26 deletions
This file was deleted.

docs/DecoratorNode.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ A decorator is a node that can have only a single child.
55
It is up to the Decorator to decide if, when and how many times the child should be
66
ticked.
77

8-
## InverterNode
8+
## NegationNode
99

1010
Tick the child once and return SUCCESS if the child failed or FAILURE if
1111
the child succeeded.
@@ -26,7 +26,7 @@ Otherwise, it returns always FAILURE.
2626

2727
## RepeatNode
2828

29-
Tick the child up to N times, where N is passed as a [NodeParameter](NodeParameter.md),
29+
Tick the child up to N times, where N is passed as a [NodeParameter](NodeParameters.md),
3030
as long as the child returns SUCCESS.
3131

3232
Interrupt the loop if the child returns FAILURE and, in that case, return FAILURE too.
@@ -35,19 +35,11 @@ If the child returns RUNNING, this node returns RUNNING too.
3535

3636
## RetryNode
3737

38-
Tick the child up to N times, where N is passed as a [NodeParameter](NodeParameter.md),
38+
Tick the child up to N times, where N is passed as a [NodeParameter](NodeParameters.md),
3939
as long as the child returns FAILURE.
4040

4141
Interrupt the loop if the child returns SUCCESS and, in that case, return SUCCESS too.
4242

4343
If the child returns RUNNING, this node returns RUNNING too.
4444

45-
## RetryNode
46-
47-
Tick the child up to N times, where N is passed as a [NodeParameter](NodeParameter.md),
48-
as long as the child returns FAILURE.
49-
50-
Interrupt the loop if the child returns SUCCESS and, in that case, return SUCCESS too.
51-
52-
If the child returns RUNNING, this node returns RUNNING too.
5345

docs/FallbackNode.md

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,103 @@ This family of nodes are known as "Selector" or, sometimes, "Priority"
44
in other frameworks.
55

66
Its purpose is to try different strategies, until we find one that "works".
7-
Currently, there is only a single type of node called "FallbackNode".
87

8+
Currently the framework provides two kinds of nodes:
99

10-
## FallbackNode
10+
- FallbackNode
11+
- FallbackStarNode
12+
13+
They share the following rules:
1114

12-
The SequenceNode is used to execute the children in a sequence.
15+
- Before ticking the first child, the node status becomes __RUNNING__.
1316

14-
- Before ticking the first child, Fallback becomes __RUNNING__.
1517
- If a child returns __FAILURE__, it ticks the next child.
18+
1619
- If the __last__ child returns __FAILURE__ too, all the children are halted and
17-
the Sequence returns __FAILURE__.
18-
- If a child returns __RUNNING__, Fallback suspends and returns __RUNNING__.
19-
- If a child returns __SUCCESS__, Fallback stops and returns __SUCCESS__.
20+
the sequence returns __FAILURE__.
21+
22+
- If a child returns __SUCCESS__, it stops and returns __SUCCESS__.
23+
All the children are halted.
24+
25+
26+
## FallbackNode
27+
28+
If a child returns __RUNNING__:
29+
30+
- FallbackNode returns __RUNNING__.
31+
- The loop is restarted and all the previous children are ticked again __unless
32+
they are ActionNodes__.
33+
2034

2135
__Example__:
2236

23-
Try different strategies to open the door. Check first if it is open already.
37+
Try different strategies to open the door. Check first if the door is open.
2438

2539
![FallbackNode](images/FallbackSimplified.png)
2640

2741
??? example "See the pseudocode"
2842
``` c++
29-
// At the beginning, start from first child
30-
if( state != RUNNING) {
31-
index = 0;
43+
status = RUNNING;
44+
45+
for (int index=0; index < number_of_children; index++)
46+
{
47+
child_status = child[index]->tick();
48+
49+
if( child_status == RUNNING ) {
50+
// Suspend execution and return RUNNING.
51+
// At the next tick, index will be the same.
52+
return RUNNING;
53+
}
54+
else if( child_status == SUCCESS ) {
55+
// Suspend execution and return SUCCESS.
56+
// index is reset and children are halted.
57+
HaltAllChildren();
58+
return SUCCESS;
59+
}
3260
}
33-
state = RUNNING;
61+
// all the children returned FAILURE. Return FAILURE too.
62+
HaltAllChildren();
63+
return FAILURE;
64+
```
65+
66+
## FallbackStarNode
67+
68+
If a child returns __RUNNING__:
69+
70+
- FallbackStarNode returns __RUNNING__.
71+
- The loop is __not__ restarted and none of the previous children is ticked.
72+
73+
??? example "See the pseudocode"
74+
``` c++
75+
// index is initialized to 0 in the constructor
76+
status = RUNNING;
3477

3578
while( index < number_of_children )
3679
{
37-
child_state = child[index]->tick();
80+
child_status = child[index]->tick();
3881
39-
if( child_state == RUNNING ) {
82+
if( child_status == RUNNING ) {
4083
// Suspend execution and return RUNNING.
4184
// At the next tick, index will be the same.
42-
state = RUNNING;
43-
return state;
85+
return RUNNING;
4486
}
45-
else if( child_state == FAILURE ) {
87+
else if( child_status == FAILURE ) {
4688
// continue the while loop
4789
index++;
4890
}
49-
else if( child_state == SUCCESS ) {
91+
else if( child_status == SUCCESS ) {
5092
// Suspend execution and return SUCCESS.
51-
// index is reset and children are halted.
52-
state = SUCCESS;
93+
// At the next tick, index will be the same.
94+
HaltAllChildren();
5395
index = 0;
54-
HaltAllChildren();
55-
return state;
96+
return SUCCESS;
5697
}
5798
}
58-
// all the children returned failure. Return FAILURE too.
59-
state = FAILURE;
99+
// all the children returned FAILURE. Return FAILURE too.
100+
index = 0;
60101
HaltAllChildren();
61-
return state;
62-
63-
102+
return FAILURE;
103+
```
64104

65105

66106

docs/NodeParameters.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# NodeParameters
2+
3+

0 commit comments

Comments
 (0)