Writing a ParallelNode
Overview
This tutorial demonstrates the careBT ParallelNode
. Therefore the SimpleParallel
node
is implemented which has three child nodes of the same type (AddTwoNumbersMultiTickAction
). With
the input parameters, the amount of ticks can be specified that the children take to complete. As the
success_threshold
is set to two, the SimpleParallel
node succeeds in case that two nodes complete
with SUCCESS
or FIXED
, or fails in case one child node completes with FAILURE
or
ABORTED
. By ‘playing around’ with the input parameters different situation can be provoked.
Create the SimpleParallel node
Create a file named parallel.py
with following content.
Or use the provided file: parallel.py
1from carebt import ParallelNode
2from carebt.examples.longrun_actions import AddTwoNumbersMultiTickActionWithTimeout
3
4
5class SimpleParallel(ParallelNode):
6 """The `SimpleParallel` example node.
7
8 The `SimpleParallel` node has three child nodes of the same type
9 (`AddTwoNumbersMultiTickActionWithTimeout`). With the three input parameters it can be
10 controlled how many tick each of the nodes take to complete. The
11 `success_threshold` of the `SimpleParallel` node is set to two. That means,
12 that the whole node succeeds as soon as two nodes have completed with
13 `SUCCESS` or `FIXED` or fails as soon as one of the child nodes complete
14 with `FAILURE` or `ABORTED`.
15
16 Input Parameters
17 ----------------
18 ?ticks1 : int
19 The ticks for the first child
20 ?ticks2 : int
21 The ticks for the second child
22 ?ticks3 : int
23 The ticks for the third child
24
25 """
26
27 def __init__(self, bt_runner):
28 super().__init__(bt_runner, 2, '?ticks1 ?ticks2 ?ticks3')
29
30 def on_init(self) -> None:
31 self.add_child(AddTwoNumbersMultiTickActionWithTimeout, '?ticks1 1 1 => ?c1')
32 self.add_child(AddTwoNumbersMultiTickActionWithTimeout, '?ticks2 2 2 => ?c2')
33 self.add_child(AddTwoNumbersMultiTickActionWithTimeout, '?ticks3 3 3 => ?c3')
The code explained
The AddTwoNumbersMultiTickAction
node was already introduced in
Writing long running ActionNodes and is just reused
in this example.
The constructor (__init__
) of the SimpleParallel
needs to call the constructor (super().__init__
)
of the ParallelNode
and passes the bt_runner, the success_threshold and the signature as arguments. The
success_threshold is set to two, and the signature defines three input parameter.
def __init__(self, bt_runner):
super().__init__(bt_runner, 2, '?ticks1 ?ticks2 ?ticks3')
In the on_init
function the three child nodes are added.
def on_init(self) -> None:
self.add_child(AddTwoNumbersMultiTickActionWithTimeout, '?ticks1 1 1 => ?c1')
self.add_child(AddTwoNumbersMultiTickActionWithTimeout, '?ticks2 2 2 => ?c2')
self.add_child(AddTwoNumbersMultiTickActionWithTimeout, '?ticks3 3 3 => ?c3')
Run the example
Start the Python interpreter and run the SimpleParallel
node:
>>> import carebt
>>> from carebt.examples.parallel import SimpleParallel
>>> bt_runner = carebt.BehaviorTreeRunner()
>>> bt_runner.run(SimpleParallel, '2 4 6')
AddTwoNumbersMultiTickAction: (tick_count = 1/2)
AddTwoNumbersMultiTickAction: (tick_count = 1/4)
AddTwoNumbersMultiTickAction: (tick_count = 1/6)
AddTwoNumbersMultiTickAction: DONE 1 + 1 = 2
AddTwoNumbersMultiTickAction: (tick_count = 2/4)
AddTwoNumbersMultiTickAction: (tick_count = 2/6)
AddTwoNumbersMultiTickAction: (tick_count = 3/4)
AddTwoNumbersMultiTickAction: (tick_count = 3/6)
AddTwoNumbersMultiTickAction: DONE 2 + 2 = 4
AddTwoNumbersMultiTickAction: (tick_count = 4/6)
AddTwoNumbersMultiTickAction: on_abort
>>> bt_runner.run(SimpleParallel, '6 4 2')
AddTwoNumbersMultiTickAction: (tick_count = 1/6)
AddTwoNumbersMultiTickAction: (tick_count = 1/4)
AddTwoNumbersMultiTickAction: (tick_count = 1/2)
AddTwoNumbersMultiTickAction: (tick_count = 2/6)
AddTwoNumbersMultiTickAction: (tick_count = 2/4)
AddTwoNumbersMultiTickAction: DONE 3 + 3 = 6
AddTwoNumbersMultiTickAction: (tick_count = 3/6)
AddTwoNumbersMultiTickAction: (tick_count = 3/4)
AddTwoNumbersMultiTickAction: (tick_count = 4/6)
AddTwoNumbersMultiTickAction: DONE 2 + 2 = 4
AddTwoNumbersMultiTickAction: on_abort
In the first execution the first two nodes complete after two resp. four ticks and thus, the
SimpleParallel
node also completes. The third node is aborted. In the second execution
the third and second node complete after two resp. four ticks. Again, the SimpleParallel
node completes as two nodes succedded, and as a consequence the first node is aborted. When aborting
a node the on_abort
function of this node is called, this is why the message ‘AddTwoNumbersMultiTickAction:
on_abort’ is printed on standard output (see implementation of AddTwoNumbersMultiTickAction
).