Writing a FallbackNode
Overview
This tutorial demonstrates the careBT FallbackNode
. Therefore the SimpleFallback
node
is implemented which has three child nodes of the same type (AddTwoNumbersActionWithFailures
).
By ‘playing around’ with the input parameters, the ‘RESULT_TOO_LARGE’ contingency can be provoked
in each of the three children. This allows to observe the functionality of the FallbackNode
.
Create the SimpleFallback node
Create a file named fallback.py
with following content.
Or use the provided file: fallback.py
1from carebt import FallbackNode
2from carebt.examples.sequence_with_contingencies import AddTwoNumbersActionWithFailures
3
4
5class SimpleFallback(FallbackNode):
6 """The `SimpleFallback` example node.
7
8 The `SimpleFallback` has three input parameters and contains three child
9 nodes of the same type (`AddTwoNumbersActionWithFailures`). Each of the child
10 nodes has the first input parameter fixed and the second one is taken from the
11 input of the `SimpleFallback`. This structure allows to provoke a failure in
12 each of the child nodes, for example, by setting the input (*?b1 ?b2 ?b3*) to
13 a number that the sum of this value and the fixed one is greater than ten.
14
15
16 Input Parameters
17 ----------------
18 ?b1 : int
19 The first value
20 ?b2 : int
21 The second value
22 ?b3 : int
23 The second value
24
25 """
26
27 def __init__(self, bt_runner):
28 super().__init__(bt_runner, '?b1 ?b2 ?b3')
29
30 def on_init(self) -> None:
31 self.append_child(AddTwoNumbersActionWithFailures, '1 ?b1 => ?c1')
32 self.append_child(AddTwoNumbersActionWithFailures, '2 ?b2 => ?c2')
33 self.append_child(AddTwoNumbersActionWithFailures, '3 ?b3 => ?c3')
The code explained
The AddTwoNumbersActionWithFailures
node was already introduced in
Understanding contingency-handlers and is just reused
in this example.
The constructor (__init__
) of the SimpleFallback
needs to call the constructor (super().__init__
)
of the FallbackNode
and passes the bt_runner and the signature as arguments. The signature defines three
input parameter called ?b1 ?b2 ?b3.
def __init__(self, bt_runner):
super().__init__(bt_runner, '?b1 ?b2 ?b3')
In the on_init
function the three child nodes are added.
def on_init(self) -> None:
self.append_child(AddTwoNumbersActionWithFailures, '1 ?b1 => ?c1')
self.append_child(AddTwoNumbersActionWithFailures, '2 ?b2 => ?c2')
self.append_child(AddTwoNumbersActionWithFailures, '3 ?b3 => ?c3')
Run the example
Start the Python interpreter and run the SimpleFallback
node:
>>> import carebt
>>> from carebt.examples.fallback import SimpleFallback
>>> bt_runner = carebt.BehaviorTreeRunner()
>>> bt_runner.run(SimpleFallback, '1 2 3')
AddTwoNumbersActionWithFailures: calculating: 1 + 1 = 2
>>> bt_runner.run(SimpleFallback, '10 2 3')
AddTwoNumbersActionWithFailures: calculating: 1 + 10 = 11 -> RESULT_TOO_LARGE
AddTwoNumbersActionWithFailures: calculating: 2 + 2 = 4
>>> bt_runner.run(SimpleFallback, '10 20 3')
AddTwoNumbersActionWithFailures: calculating: 1 + 10 = 11 -> RESULT_TOO_LARGE
AddTwoNumbersActionWithFailures: calculating: 2 + 20 = 22 -> RESULT_TOO_LARGE
AddTwoNumbersActionWithFailures: calculating: 3 + 3 = 6
>>> bt_runner.run(SimpleFallback, '10 20 30')
AddTwoNumbersActionWithFailures: calculating: 1 + 10 = 11 -> RESULT_TOO_LARGE
AddTwoNumbersActionWithFailures: calculating: 2 + 20 = 22 -> RESULT_TOO_LARGE
AddTwoNumbersActionWithFailures: calculating: 3 + 30 = 33 -> RESULT_TOO_LARGE
2021-11-30 20:55:46 WARN ---------------------------------------------------
2021-11-30 20:55:46 WARN bt execution finished
2021-11-30 20:55:46 WARN status: NodeStatus.FAILURE
2021-11-30 20:55:46 WARN contingency-message: RESULT_TOO_LARGE
2021-11-30 20:55:46 WARN ---------------------------------------------------
In the first execution of the SimpleFallback
node the first child already completes
with SUCCESS
and thus the whole SimpleFallback
node completes with SUCCESS
. In the
second execution the first child fails (with RESULT_TOO_LARGE
) and thus the second one
is executed, which succeeds. Thus also the whole SimpleFallback
node completes with SUCCESS
.
In the third execution all three children fail and as a consequence the whole SimpleFallback
node fails with the contingency-message RESULT_TOO_LARGE
.