Skip to content

Commit f8c16a3

Browse files
author
Davide Faconti
committed
docs
1 parent d7a906e commit f8c16a3

22 files changed

+757
-301
lines changed

docs/02_BT_description.md renamed to docs/BT_basics.md

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,8 @@ which child should be ticked next or will return a result itself.
3535

3636
__ControlNodes__ are nodes which can have 1 to N children. Once a tick
3737
is received, this tick may be propagated to one or more of the children.
38-
It must be noted that children are always __ordered__, but it is up to the
39-
type of control node to decide if they are ticked in the given order.
4038

41-
__DecoratorNodes__ can have only a single child. Their function is either
42-
to transform the result they receive from the child, to terminate the child,
43-
or repeat processing of the child, depending on the type of decorator.
39+
__DecoratorNodes__ can have only a single child.
4440

4541
__ActionNodes__ are leaves and do not have children. The user should implement
4642
their own ActionNodes that perform the actual task.
@@ -51,15 +47,15 @@ alter the state of the system.
5147

5248
![UML hierarchy](images/TypeHierarchy.png)
5349

54-
!!! warning
55-
Actions and Conditions differ only in terms of __semantic__, the C++
56-
framework can not enforce it unfortunately.
50+
!!! note
51+
Actions and Conditions differ only in terms of __semantic__.
52+
From an implementation point of view they are the same.
5753

5854
## Learn by example
5955

60-
To better understand how a BehaviorTree works let's focus on some practical
56+
To better understand how a BehaviorTrees work let's focus on some practical
6157
examples. For the sake of simplicity we will not take into account what happens
62-
when an action return RUNNING.
58+
when an action returns RUNNING.
6359

6460
We will assume that each Action is executed atomically and synchronously.
6561
In future sections we will more thoughtfully analyze asynchronous actions.
@@ -80,22 +76,43 @@ A Sequence works as described next:
8076
- If a child returns FAILURE, then no more children are ticked and the Sequence returns FAILURE.
8177
- If all the children return SUCCESS, then the Fallback returns SUCCESS too.
8278

83-
In this particular case, if the action __GrabBeer__ failed, the door of the fridge would
84-
remain opened, since the last action __CloseDoor__ is skipped.
79+
??? warning "Exercise: find the bug! Expand to read the answer."
80+
If the action __GrabBeer__ fails, the door of the
81+
fridge would remain opened, since the last action __CloseDoor__ is skipped.
8582

86-
Let's take into accound another example:
8783

88-
![Simple Sequence: Enter Room](images/Sequence2.png)
84+
### Decorators
8985

90-
In this case __Negation__ is a [DecoratorNode](DecoratorNode.md) that inverts
91-
the result returned by its child.
86+
The goal of a [DecoratorNode](DecoratorNode.md) is either to transform the result it received
87+
from the child, to terminate the child,
88+
or repeat ticking of the child, depending on the type of Decorator.
9289

93-
This means that a Negation followed by the ConditionNode called
94-
__DoorOpen__ is equialent to "is the door closed?".
90+
You can create your own Decorators too.
9591

96-
As a result, the branch on the right side means:
92+
![Simple Decorator: Enter Room](images/DecoratorEnterRoom.png)
9793

98-
"If the door is closed, then open it".
94+
The node __Negation__ is a Decorator that inverts
95+
the result returned by its child; Negation followed by the node called
96+
__DoorOpen__ is therefore equivalent to
97+
98+
"Is the door closed?".
99+
100+
The node __Retry__ will repeat ticking the child up to N times (3 in this case)
101+
if the child returns FAILURE.
102+
103+
__Apparently__, the branch on the right side means:
104+
105+
If the door is closed, then try to open it.
106+
Try up to 3 times, otherwise give up and return FAILURE.
107+
108+
109+
__But__ there is an error. Can you find it?
110+
111+
??? warning "Exercise: find the bug! Expand to read the answer."
112+
If __DoorOpen__ returns FAILURE, we have the desired behaviour.
113+
But if it returns SUCCESS, the left branch fails and the entire Sequence
114+
is interrupted.
115+
99116

100117
### Fallback
101118

@@ -111,22 +128,33 @@ In short, it ticks the children in order, as usual from left to right and:
111128

112129
In the next example, you can see how Sequence and Fallbacks can be combined:
113130

114-
"Try to open the door,
115-
otherwise unlock it with a key (if you have it),
116-
otherwise smash it.
117-
If any of these actions succeeded, then enter the room".
118131

119132
![FallbackNodes](images/FallbackBasic.png)
120133

134+
135+
>In the door open?
136+
>
137+
> I not, try to open the door.
138+
>
139+
> Otherwise, if you have a key, unlock and open the door.
140+
>
141+
> Otherwise, smash the door.
142+
>
143+
>If any of these actions succeeded, then enter the room.
144+
121145
### "Fetch me a beer" revisited
122146

123-
We can now improve the previous example, which attempted to
124-
grab a beer from the fridge but left the door open if the beer was not there.
147+
We can now improve the "Fetch Me a Beer" example, which leaves the door open
148+
if the beer was not there.
149+
150+
We use the color "green" to represent nodes which will return
151+
SUCCESS and "red" for those which return FAILURE. Black nodes are never executed.
152+
153+
![FetchBeer failure](images/FetchBeerFails.png)
125154

126-
In the next picture we use the color green to represent nodes which will return
127-
SUCCESS and red for those which return FAILURE.
128155

129-
The action __GrabBeer__ will always fail.
156+
Let's create an alternative tree that closes the door even when __GrabBeer__
157+
returns FAILURE.
130158

131159

132160
![FetchBeer failure](images/FetchBeer.png)
@@ -138,7 +166,7 @@ Both the trees will close the door of the fridge, eventually, but:
138166
- the tree on the __right__ side will return SUCCESS if the beer was there,
139167
FAILURE otherwise.
140168

141-
We can easily double-check what happen if __GrabBeer__ returns SUCCESS.
169+
We can easily double-check that everything works as usual if __GrabBeer__ returns SUCCESS.
142170

143171
![FetchBeer success](images/FetchBeer2.png)
144172

docs/BlackBoard.md

Whitespace-only changes.

docs/ControlNodes.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# ControlNodes
2+
3+
ControlNodes can have multiple children. Children are always __ordered__
4+
and it is up to the ControlNode itself to decide if and when a child should
5+
be ticked.
6+
7+
## SequenceNode
8+
9+
The SequenceNode is used to execute the children in a sequence.
10+
11+
It ticks its children __as long as__ they returns SUCCESS.
12+
13+
- Before ticking the first child, Sequence becomes __RUNNING__.
14+
- If a child return __SUCCESS__, it ticks the next child.
15+
- If the __last__ child returns __SUCCESS__ too, all the children are halted and
16+
the Sequence returns __SUCCESS__.
17+
- If a child returns __RUNNING__, Sequence suspends and returns __RUNNING__.
18+
- If a child returns __FAILURE__, Sequence stops and returns __FAILURE__.
19+
20+
21+
22+
23+
24+
25+
26+

docs/DecoratorNodes.md

Whitespace-only changes.

docs/getting_started.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

docs/images/DecoratorEnterRoom.png

8.13 KB
Loading

docs/images/FallbackBasic.png

-5.86 KB
Loading

docs/images/FetchBeer.png

-9.28 KB
Loading

docs/images/FetchBeer2.png

-7.41 KB
Loading

docs/images/FetchBeerFails.png

1.49 KB
Loading

0 commit comments

Comments
 (0)