11---
22title : 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
44hide_table_of_contents : false
55sidebar_position : 7
66---
77
8- # Migrating from version 3.X to 4.X
8+ # Migrating from version 3.8 to 4.X
99
1010You will find that most of the changes in version 4.X
1111are incremental and back compatible with your previous code.
@@ -15,14 +15,14 @@ that you should be aware of, when migrating.
1515
1616::: note
1717In 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 )!
1919
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!
2121:::
2222
2323## Class renaming
2424
25- The name of the following classes / XML tags changed.
25+ The names of the following classes / XML tags changed.
2626
2727| Name in 3.8+ | Name in 4.x | Where |
2828| -------------| ---------| ---------|
@@ -31,7 +31,7 @@ The name of the following classes / XML tags changed.
3131| AsyncActionNode | ThreadedAction | C++ |
3232| Optional | Expected | C++ |
3333
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 :
3535
3636``` cpp
3737namespace BT
@@ -42,10 +42,6 @@ namespace BT
4242}
4343```
4444
45- ::: info
46- These changes can be disabled while compiling BT.CPP with the CMake option __ USE_V3_COMPATIBLE_NAMES__ .
47- :::
48-
4945## XML
5046
5147You should add the attribute ` BTCPP_format ` to the \< root\> tag of your XML:
6056<root BTCPP_format =" 4" >
6157```
6258
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!
6560
6661## 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".
7165
7266| Name in 3.8+ | Name in 4.x |
7367| -------------| ---------|
7468| ` <SubTree> ` | Deprecated |
7569| ` <SubTreePlus> ` | ` <SubTree> ` |
7670
77- ## SetBlackboard and BlackboardPrecondition
71+ ## SetBlackboard and BlackboardCheck
7872
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.
8174
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** :
8378
8479``` xml
8580<SetBlackboard output_key =" port_A" value =" 42" />
@@ -94,26 +89,80 @@ New code in **4.X**:
9489
9590``` xml
9691<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)
100115```
101116
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**.
103119
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 :
105121
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.
109158
110159# Asychronous Control Nodes
111160
112161A serious problem was detected by a user
113162[ here] ( https://github.com/BehaviorTree/BehaviorTree.CPP/issues/395 ) :
114163
115164> If a ** ControlNode** or ** DecoratorNode** has synchronous children only,
116- it is impossible to interrupt it .
165+ it is impossible to interrupt them .
117166
118167Consider this example:
119168
@@ -127,14 +176,13 @@ Consider this example:
127176 <Sequence >
128177</ReactiveSequence >
129178```
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".
132180
133181In other words, when "synch_sequence" starts, it is impossible for ` AbortCondition ` to stop it.
134182
135183To address this issue, we added two new nodes, ` AsyncSequence ` and ` AsyncFallback ` .
136184
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.
139188
140- In this way, we give allow the tree to run the ` ReactiveSequence ` above.
0 commit comments