1
1
---
2
2
title : Migration from BT.CPP 3.x
3
- description : How to migrate your code from version 3.X
3
+ description : How to migrate your code from version 3.8
4
4
hide_table_of_contents : false
5
5
sidebar_position : 7
6
6
---
7
7
8
- # Migrating from version 3.X to 4.X
8
+ # Migrating from version 3.8 to 4.X
9
9
10
10
You will find that most of the changes in version 4.X
11
11
are incremental and back compatible with your previous code.
@@ -15,14 +15,14 @@ that you should be aware of, when migrating.
15
15
16
16
::: note
17
17
In the repository you can find a Python script called ** convert_v3_to_v4.py**
18
- that may save you some time (thanks to use https://github.com/SubaruArai )!
18
+ that may save you some time (thanks to user https://github.com/SubaruArai )!
19
19
20
- Try it, but make sure that you double check the result first!
20
+ Try it, but make sure that you double- check the result first!
21
21
:::
22
22
23
23
## Class renaming
24
24
25
- The name of the following classes / XML tags changed.
25
+ The names of the following classes / XML tags changed.
26
26
27
27
| Name in 3.8+ | Name in 4.x | Where |
28
28
| -------------| ---------| ---------|
@@ -31,7 +31,7 @@ The name of the following classes / XML tags changed.
31
31
| AsyncActionNode | ThreadedAction | C++ |
32
32
| Optional | Expected | C++ |
33
33
34
- If you want to quickly fix the compilation of your C++ code, ** even if refactoring is encorauged ** , do :
34
+ If you want to quickly fix the compilation of your C++ code ( ** even if refactoring is encouraged ** ) add :
35
35
36
36
``` cpp
37
37
namespace BT
@@ -42,10 +42,6 @@ namespace BT
42
42
}
43
43
```
44
44
45
- ::: info
46
- These changes can be disabled while compiling BT.CPP with the CMake option __ USE_V3_COMPATIBLE_NAMES__ .
47
- :::
48
-
49
45
## XML
50
46
51
47
You should add the attribute ` BTCPP_format ` to the \< root\> tag of your XML:
60
56
<root BTCPP_format =" 4" >
61
57
```
62
58
63
- This will allow us to be compatible
64
- with both versions 3 and 4 (in future releases, not yet).
59
+ This will allow us to be compatible with both versions 3 and 4... eventually!
65
60
66
61
## SubTree and SubTreePlus
67
-
68
- The deafault ** SubTree** in 3.X has been deprecated and
69
- ** SubtreePlus** is the new default, being easier to use and
70
- more consistent.
62
+
63
+ The default ** SubTree** in 3.X has been deprecated in favor of ** SubtreePlus** .
64
+ Being this the new default, we simply call it "SubTree".
71
65
72
66
| Name in 3.8+ | Name in 4.x |
73
67
| -------------| ---------|
74
68
| ` <SubTree> ` | Deprecated |
75
69
| ` <SubTreePlus> ` | ` <SubTree> ` |
76
70
77
- ## SetBlackboard and BlackboardPrecondition
71
+ ## SetBlackboard and BlackboardCheck
78
72
79
- The new [ scripting language] ( /docs/guides/scripting )
80
- is much simpler and more powerful.
73
+ The new [ scripting language] ( /docs/guides/scripting ) is much simpler and more powerful.
81
74
82
- Old code in ** 3.8+** :
75
+ Check also the introduction to [ Pre and Post Conditions] ( /docs/guides/pre_post_conditions ) .
76
+
77
+ Old code in ** 3.8** :
83
78
84
79
``` xml
85
80
<SetBlackboard output_key =" port_A" value =" 42" />
@@ -94,26 +89,80 @@ New code in **4.X**:
94
89
95
90
``` xml
96
91
<Script code =" port_A:=42; port_B:=69" />
97
- <Precondition if =" port_A==port_B" else =" FAILURE" >
98
- <MyAction />
99
- </Precondition >
92
+ <MyAction _failureIf =" port_A!=port_B" />
93
+ ```
94
+
95
+ ## Ticking in a While Loop
96
+
97
+ A typical execution used to look like this:
98
+
99
+ ``` cpp
100
+ // simplified code, frequently found in BT.CPP 3.8
101
+ while (status != NodeStatus::SUCCESS || status == NodeStatus::FAILURE)
102
+ {
103
+ status tree.tickRoot();
104
+ std::this_thread::sleep_for (sleep_ms);
105
+ }
106
+ ```
107
+
108
+ The "polling" model of Behavior Trees is sometimes criticized. The sleep is necessary to
109
+ avoid "busy loops", but may introduce some latency.
110
+
111
+
112
+ To improve the reactiveness of behavior trees, we introduced the method
113
+ ``` cpp
114
+ Tree::sleep (std::chrono::milliseconds timeout)
100
115
```
101
116
102
- ## Ticking
117
+ This particular implementation of **sleep** can be interrupted if **any** node in the tree invokes the method `TreeNode::emitWakeUpSignal`.
118
+ This allows the loop to re-tick the tree **immediately**.
103
119
104
- The method ` Tree::tickRoot() ` was removed, and we introduced these two new methods instead :
120
+ The method `Tree::tickRoot()` has been removed from the public API and the new recommended approach is :
105
121
106
- - ` Tree::tickOnce() ` works as usual. It should run inside a while-loop.
107
- - ` Tree::tickWhileRunning() ` has its own while-loop, and will continue ticking until either
108
- SUCCESS or FAILURE is received.
122
+ ```cpp
123
+ // Use Tree::sleep and wait for either SUCCESS or FAILURE
124
+ while(!BT::isStatusCompleted(status))
125
+ {
126
+ status = tree.tickOnce();
127
+ tree.sleep(sleep_ms);
128
+ }
129
+ //---- or, even better ------
130
+ status = tree.tickWhileRunning(sleep_ms);
131
+ ```
132
+
133
+ ` Tree::tickWhileRunning ` is the new default and it has its own internal loop;
134
+ the first argument is a timeout of the sleep inside the loop.
135
+
136
+ Alternatively, you may use these methods:
137
+
138
+ - ` Tree::tickExactlyOnce() ` : equivalent to the old behavior in 3.8+
139
+ - ` Tree::tickOnce() ` is roughly equivalent to ` tickWhileRunning(0ms) ` . It may potentially tick more than once.
140
+
141
+
142
+ # ControlNodes and Decorators must support NodeStatus: SKIPPED
143
+
144
+ The purpose of this new status is to be returned when a [ PreCondition] ( /docs/guides/pre_post_conditions ) is not met.
145
+
146
+ When a Node returns ** SKIPPED** , it is notifying to its parent (ControlNode or Decorator) that it hasn't been executed.
147
+
148
+ ::: note
149
+ When you implement your own custom ** Leaf Node** , you shall not return ** SKIPPED** .
150
+ This status is reserved for PreConditions.
151
+
152
+ On the other hand, ** ControlNodes and Decorators** must be modified to support this
153
+ new status.
154
+ :::
155
+
156
+ The usual rule of thumb is that, if a child Node returns ** SKIPPED** ,
157
+ it means that it was not executed, and the ControlNode should move to the next one.
109
158
110
159
# Asychronous Control Nodes
111
160
112
161
A serious problem was detected by a user
113
162
[ here] ( https://github.com/BehaviorTree/BehaviorTree.CPP/issues/395 ) :
114
163
115
164
> If a ** ControlNode** or ** DecoratorNode** has synchronous children only,
116
- it is impossible to interrupt it .
165
+ it is impossible to interrupt them .
117
166
118
167
Consider this example:
119
168
@@ -127,14 +176,13 @@ Consider this example:
127
176
<Sequence >
128
177
</ReactiveSequence >
129
178
```
130
- When a ` Sequence ` (or ` Fallback ` ) has only synchronous children, the entire sequence becomes
131
- "atomic".
179
+ When a ` Sequence ` (or ` Fallback ` ) has only synchronous children, the entire sequence becomes "atomic".
132
180
133
181
In other words, when "synch_sequence" starts, it is impossible for ` AbortCondition ` to stop it.
134
182
135
183
To address this issue, we added two new nodes, ` AsyncSequence ` and ` AsyncFallback ` .
136
184
137
- When ` AsyncSequence ` is used, ** RUNNING** is returned after the execution of each synchronous child,
138
- before moving to the next sibling.
185
+ When ` AsyncSequence ` is used, ** RUNNING** is returned after the execution of ** each** synchronous child, before moving to the next sibling.
186
+
187
+ In the example above, to complete the entire tree successfully we need 3 ticks.
139
188
140
- In this way, we give allow the tree to run the ` ReactiveSequence ` above.
0 commit comments