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.