On the Implementation of Behavior Trees in Robotics
Michele Colledanchise and Lorenzo Natale
Abstract There is a growing interest in Behavior Trees
(BTs) as a tool to describe and implement robot behaviors. BTs
were devised in the video game industry and their adoption
in robotics resulted in the development of ad-hoc libraries
to design and execute BTs that fit complex robotics software
architectures.
While there is broad consensus on how BTs work, some
characteristics rely on the implementation choices done in the
specific software library used.
In this letter, we outline practical aspects in the adoption
of BTs and the solutions devised by the robotics community
to fully exploit the advantages of BTs in real robots. We also
overview the solutions proposed in open-source libraries used in
robotics, we show how BTs fit in a robotic software architecture,
and we present a use case example.
I. INTRODUCTION
BTs are a graphical mathematical model for reactive and
fault-tolerant task executions. They were first introduced
in the computer game industry [1] to control non-player
characters (NPCs) and is now an established tool that appears
in textbooks [2]–[4] and generic game-coding software such
as Pygame, Craft AI, and Unreal Engine. BTs are appreciated
because they are highly modular, flexible, and reusable.
BTs are either created by human experts [5]–[10] or au-
tomatically designed using algorithms [11]–[13] maximizing
given objective functions. The use of BTs in robotics spans
from manipulation [5], [14]–[16] to non-expert program-
ming [8]–[10]. Other works include task planning [17],
human-robot interaction [18]–[20], learning [21]–[23], multi-
robot systems [24]–[27], and system analysis [28], [29]. The
Boston Dynamics’ Spot SDK uses BTs to model the robot’s
mission [30]; the Navigation Stack of ROS2 and the one of
NVIDIA SDK encode robot behaviors as BTs [31].
Despite the similarity in the deliberation capabilities of
NPCs and robots, NPCs are virtual agents that act in a virtual,
usually known, environment; whereas robots are physical
agents that act in an unknown environment. This required
robotics researchers and developers to modify BTs to ac-
commodate the robotic applications’ requirements and better
integrate them into existing robot software architectures.
Consider the BT shown in Figure 1. The BT encodes the
robot’s behavior that has to find an object, approach it, grasp
it, and then go to a destination. The implementation and
execution of this BT assume the following:
Node Templates: The BT has the actions Goto Object
and Goto Destination. This implies the existence of an
The authors are with the Humanoids Sensing and Perception
Lab, Istituto Italiano di Tecnologia. Genoa, Italy. e-mail:
?
Object
Detected
Detect
Object
?
Object
Grasped
?
Close to
Object
Goto
Object
Move Arm
In Pregrasp
Grasp
Object
Goto
Destination
Fig. 1. BT for a fetch task.
action template Goto <argument> that can be refined
by setting the value of the argument.
Communication mechanism between nodes: the action
“Detect Object” computes the 6D pose of the object,
such pose gets then used by other nodes like “Goto
Object” and “Grasp Object”.
Asynchronous action execution: The BT activates ac-
tions by sending ticks to them, as we describe below.
The action “Goto Object”, in turn, controls the robot by
sending commands to navigate to a given location. The
two control loops, the one of the BT’s tick traversal
and the one of the action execution, may run asyn-
chronously.
Preemption: To support reactivity and safety, the BT
may require the running nodes’ interruption.
Hence, the simple BT above requires a design and exe-
cution engine that handles: parametrization, infra-node com-
munication, asynchronous execution, and safe interruptions.
To the best of our knowledge, while there exists surveys on
BTs in robotics and a comparison of software libraries [32],
[33], the literature lacks a study on the implementation
details of BTs in robotics. Our intention is to help readers
understand the implementation aspects of BTs with their
implications in the execution of robot behaviors and suggest
practical solutions to integrate BTs in a robotics software
architecture.
In this letter, we outline the current solutions adopted by
the robotics community. After describing the background
on BTs (Section II), we focus our attention on compo-
sition nodes and their stateful counterpart (Section III),
node parametrization and message passing (Section IV),
asynchronous action execution and the importance of pre-
emptable actions (Section V). We then outline how the most
popular open-source libraries reflect these characteristics
(Section VI), we show how BTs fit a robotic architecture
(Section VII), and finally we present a systematic example
(Section VIII).
arXiv:2106.15227v1 [cs.RO] 29 Jun 2021
II. BEHAVIOR TREES
In this section, we present the classical formulation of BTs.
A detailed description of BTs is available in the literature [4].
A. Classical Formulation of Behavior Trees
A BT is a directed rooted tree where the internal nodes
represent behavior compositions and leaf nodes represent
actuation or sensing operations. We follow the canonical
nomenclature for root, parent, and child nodes.
The children of a BT node are placed below it and they
are executed from left to right. The execution of a BT begins
from the root node. It sends ticks, which are activation
signals, with a given frequency to its children. A node in
the tree is executed if and only if it receives ticks. When
the node no longer receives ticks, its execution stops. The
child returns to the parent a status that can be either Success,
Running, or Failure according to the logic of the node. Below
we present the most common BT nodes and their logic.
In the classical representation, there are four composition
nodes (Fallback, Sequence, Parallel, and Decorator) and two
execution nodes (Action and Condition).
Sequence: When a Sequence node receives ticks, it routes
them to its children from left to right. It returns Failure
or Running whenever a child returns respectively Failure
or Running. It returns Success whenever all the children
return Success. When child i returns Running or Failure, the
Sequence node stops sending ticks to the next child (if any)
but keeps ticking all the children up to child i. The Sequence
node is graphically represented as
, and its pseudocode
is described in Algorithm 1.
Algorithm 1: Pseudocode of a Sequence operator
with N children
Function Tick()
for i 1 to N do
childStatus child(i).Tick()
if childStatus = Running then
return Running
else if childStatus = Failure then
return Failure
return Success
Fallback: When a Fallback node receives ticks, it routes
them to its children from left to right. It returns a status
of Success or Running whenever a child returns Success
or Running respectively. It returns Failure whenever all the
children return Failure. When child i returns Running or
Success, the Fallback node stops sending ticks to the next
child (if any) but keeps ticking all the children up to the
child i. The Fallback node is graphically represented as
?
and its pseudocode is described in Algorithm 2.
Parallel: When the Parallel node receives ticks, it routes
them to all its children. It returns Success if a number M of
children return Success, it returns Failure if more than N M
children return Failure, and it returns Running otherwise.
The Parallel node is graphically represented as
and its
pseudocode is described in Algorithm 3.
Algorithm 2: Pseudocode of a Fallback operator with
N children
Function Tick()
for i 1 to N do
childStatus child(i).Tick()
if childStatus = Running then
return Running
else if childStatus = Success then
return Success
return Failure
Algorithm 3: Pseudocode of a Parallel operator with
N children
Function Tick()
forall i 1 to N do
childStatus[i] child(i).Tick()
if Σ
i:childStatus[i]=Success
= M then
return Success
else if Σ
i:childStatus[i]=F ailure
> N M then
return Failure
else
return Running
Decorator: A Decorator node represents a particular con-
trol flow node with only one child. When a Decorator node
receives ticks, it routes them to its only child and it returns
a status according to custom-made policy. BT designers use
decorator nodes to introduce additional semantic or to change
the return status of a node. Examples of decorators found
in the literature are: the Inverter, which changes the return
status from Success to Failure and vice-versa, the Retry,
which re-sends ticks to a failed child while returning Running
to its parent, and Timeline, which sends ticks only for a
limited time. It is represented as a rhombus.
Action: An action performs some operations as long as
it receives ticks. It returns Success whenever the opera-
tions are completed and Failure if the operations cannot be
completed. It returns Running otherwise. When a running
Action no longer receives ticks, it aborts its execution. An
Action node is graphically represented by a rectangle and its
pseudocode is described in Algorithm 4. The function call
DoAPieceOfComputation() may be executed in the BT itself
or may represent a call to a service running on a separate
component on the same or a remote machine. In these
latter cases, a middleware usually handles the communication
between the BT and the component.
Condition: Whenever a Condition node receives ticks, it
checks if a proposition is satisfied or not. It returns Success or
Failure accordingly. A Condition is graphically represented
by an ellipse and its pseudocode is described in Algorithm 5.
B. Classical BTs semantic and other architectures
In the literature there is evidence that BTs generalize
successful control architectures such as the Subsumption
architecture, Teleo-reactive Paradigm, Decision Tree and
Finite State Machines (FSM) [4].
Algorithm 4: Pseudocode of a BT Action
Function Tick()
DoAPieceOfComputation()
if action-succeeded then
return Success
else if action-failed then
return Failure
else
return Running
Algorithm 5: Pseudocode of a BT Condition
Function Tick()
if condition-true then
return Success
else
return Failure
From a theoretical standpoint, every execution described
by a BT can be characterized by a FSM and vice-versa.
However, due to the number of transitions, using a FSM as a
control architecture leads to complex structures, as described
in the literature [4]. Despite BTs generalize different control
architectures, there are a few disadvantages on using the
vanilla version of BTs, they comprises:
Complexity of the BT engine. The BT engine’s imple-
mentation can become complex using single-threaded
sequential programming as the actions may be executed
asynchronously, as described in Section V.
Checking all the conditions may be expensive. A BT
needs to check several conditions to realize a task exe-
cution. In some applications, checks are too expensive
or even unfeasible. In vanilla BTs implementations,
presents more costs than advantages. For that, BTs have
been extended with memory nodes, as described in
Section III.
Sometimes a sequential (non reactive) execution is just
fine. In applications where the robot operates in a very
structured environment that are predictable in space
and time, BTs do not have advantages over simpler
architectures.
BT tools are less mature. Although there is software for
developing BTs, it is still far behind the amount and
maturity of the software available developed for, e.g.,
FSMs. The BT community extended the BT’s semantic
by introducing node parameters and infra-node message
passing as described in Section IV.
These disadvantages pushed the community to propose the
extensions described in this letter.
III. COMPOSITION NODES WITH MEMORY
In this section, we describe the development of compo-
sition nodes with memory. We provide their definition and
pseudocode. They are also known as stateful nodes [7].
To provide for the reactivity in the BT’s execution, the
Sequence and Fallback nodes keep sending ticks to the
children to the left of a running child, to verify whether
to re-execute a previous child and preempt the one that is
currently running. However, there are cases in which the user
knows that a child, once executed, does not need to be re-
evaluated (e.g., under the closed world assumption, there are
no unexpected changes in the environment). To avoid the
unnecessary re-execution of some nodes, and save compu-
tational resources, the BT community proposed composition
nodes with memory [2]. A composition node with memory
remembers the children that have been executed, preventing
their useless re-evaluation.
There exist different policies to reset the memory. We
describe the most common policy, which consists of resetting
the memory when the node returns either Success or Failure,
so that at the next activation, all children are re-considered
for execution. Nodes with memory are graphically repre-
sented with the symbol as superscript. Their execution
can be obtained by employing standard (memoryless) con-
trol flow nodes and adding auxiliary conditions and shared
memory [4], as in Figure 2.
Sequence with memory: The state of this node contains
the index of the current child. The node routes ticks to
the current child. It returns Failure or Running whenever
the current child returns Failure or Running, respectively.
It returns Success when all the children returned Success.
The node resets the index when a child returns Failure or
when all the children returned Success. A Sequence node
with memory is graphically represented as
and its
pseudocode is described in Algorithm 6.
Algorithm 6: Pseudocode of a Sequence operator
with memory with N children
Function Main
Reset()
Function Reset()
i 1
Function Tick()
childStatus child(i).Tick()
if childStatus = Running then
return Running
else if childStatus = Failure then
Reset()
return Failure
else
if i < N then
i i + 1
else
Reset()
return Success
Fallback with memory: A Fallback node with memory is
graphically represented as
?
and its behavior is similar to
the one of the Sequence node with memory, with the return
status Failure in place of Success and vice-versa.
Parallel with memory: When it receives ticks, it routes
them to all the currently running children, stored in the
memory. It returns Success if M children return Success,
it returns Failure if more than N M children return
Failure, and it returns Running otherwise. The Parallel node
with memory is graphically represented as
and its
pseudocode is described in Algorithm 7.
Algorithm 7: Pseudocode of a Parallel operator with
memory with N children
Function Main
Reset()
Function Reset()
forall i 1 to N do
childDone[i]False
Function Tick()
forall i 1 to N do
if childDone[i]=False then
childStatus[i] child(i).Tick()
if childStatus[i]!=Running then
childDone[i]True
if Σ
i:childStatus[i]=Success
= M then
Reset()
return Success
else if Σ
i:childStatus[i]=F ailure
> N M then
Reset()
return Failure
else
return Running
Some BT implementations, do not include the Running
return status [2]. Instead, they let each Action run until it
returns either Failure or Success. We denote these BTs as
non-reactive since they do not activate actions other than
those currently active and cannot react to changes. This is
a relevant limitation of non-reactive BTs, which was noted
by the authors of such libraries [2]. A non-reactive BT can
be seen as a BT with only memory nodes. As reactivity is
one of the key strengths of BTs, non-reactive BTs are rarely
used in the literature.
Action 1 Action 2
(a) Sequence composi-
tion with memory.
?
Reset
Conditions
Reset
Conditions
? ?
Action 1
Done
Action 1
Action 2
Done
Action 2
(b) BT that emulates the execution
of the Sequence composition with
memory using classical nodes.
Fig. 2. Relation between memory and memory-less BT nodes.
IV. NODE PARAMETERS
In this section, we describe the development of nodes
with parameters. In the example presented in Section I, we
saw how some BTs require an implementation that allows
node parametrization in terms of arguments passing and
communication mechanisms between nodes. Node param-
eters make BTs more flexible and reusable. In particular,
the designer gains the ability to parametrize a particular
task. Such parameters can either be explicit in the form of
arguments passed to the node (at design time) or implicit in
the form of a message passed to the node (at run time).
Explicit arguments: Leaf nodes describe a specific robot
skill that may run differently according to the situation (e.g.,
the action Grasp that can be performed with the left hand
or the right hand, the condition Is robot in <room>, etc.).
This supports the reuse of nodes similar to functions in
computer languages or, more properly in our view, object-
oriented programming. We can consider a leaf node as an
object class with an internal state, in which member variables
are assigned to the values of the argument passed from the
constructor (we believe this analogy is more appropriate
because a node is activated several times when it receives
a tick from the BT engine and it has, therefore, an internal
state that is updated every time the node receives a tick).
Some BT designers apply the argument assignments to an
entire subtree with an exposed parameter interface [34], [35].
For subtrees, the interface inherits the parameter interface
from its children. Such inheritance must avoid argument
clash. From an object-oriented programming perspective, this
is directly analogous to multiple inheritances. We can either
implement the argument passing with the BT description sent
to the engine or by defining a “configuration object” and
which is passed by the BT engine to the subtree [36].
Implicit infra-node message passing: The communication
between BTs leaf nodes traditionally relies on a blackboard,
a centralized shared memory of which all interested parties
have access. Some designers found the use of blackboards
inconvenient for large BTs because it jeopardizes subtree
reuse. Two encapsulated subtrees may both use the same
fields of the blackboard several layers down in their hi-
erarchy, and could overwrite each other in a way that is
difficult to trace [16]. Moreover, some BT designers found it
difficult to track the data stored in the blackboard [34]. Some
BT implementations attempts to tame these problems by
defining the scope of some entries in blackboards [16], [37].
Another use of blackboards is for a BT to store the results
of expensive computation, which takes place concurrently
within the BT or in another branch of the BT composed with
the parallel node to access the most recent result quickly.
For example, an object detection algorithm may store all
the objects detected in the current camera image in the
blackboard. At the same time, a condition node checks
whether a particular object visible or not. Other solutions to
the infra-node message passing rely on a middleware where
the nodes share information using multi-variate dictionaries
accessible via network APIs, as ROS Parameter Server [38].
V. ASYNCHRONOUS ACTION EXECUTION
In this section, we describe the asynchronous action exe-
cution and the action’s halting procedure, crucial aspects to
preempt and switch between actions.
A BT orchestrates action and condition nodes by sending
ticks to them and elaborating their return statuses. Action
nodes control the robot, for example, by sending commands
to the motors to perform a specific arm movement or to
navigate to a given location. In a typical robot architecture,
the actions are executed by independent components running
on a distributed system. Therefore, the actions’ execution
gets delegated to different executables that communicate via
a middleware (e.g., ROS).
An action node should return its status in a reasonably
short time when ticked, so that tick propagation can proceed
to guarantee reactivity. The propagation of the tick is block-
ing, and the time taken by nodes to return their status affects
the step length of a safeguarding BT [4]. Thus, some BT
designers split actions into several small steps; the action’s
execution starts when it receives its first tick, and it proceeds
for another step only when the next tick is received. At the
end of each step, a running action yields control back to the
BT. This describes a synchronous execution. However, with
this solution, the tick frequency affects the speed at which
an action progresses in time. Hence a designer must ensure
sufficiently high tick frequency.
Other BT implementations execute actions asynchronously
with respect to the ticks. The action execution starts in a
separated thread when it receives its first tick. Consequent
ticks check if the action is still running or if the node has
returned a Success or Failure status via an additional function
call to get the node status. This solution results more intuitive
in robotics applications because the designer of the leaf node
has to write the code in a single block (without splitting it
into several steps) and define only the conditions to return
success or failure (see for example Algorithm 8). However,
the designer must ensure that an action’s execution is halted
safely whenever it no longer receives ticks.
Halting procedure: Whenever the BT stops sending ticks
to a running node to execute another one, this must suspend
its execution. To ensure a stable switch, the designer can
either ensure that when the action returns its status, the robot
lies in a stable state (in a synchronous execution setting) or
explicitly define a specific function that ensures a safe halting
routine (in an asynchronous execution setting), bringing the
robot to a stable state (e.g., a bipedal robot places both feet
on the ground when the action Walk aborts). Such a function
gets called whenever a BT no longer ticks a running node.
Looking back at the BT semantic presented in this letter,
Algorithm 4 performs a step of computation at each tick,
and the function Tick() runs in the same thread of the BT
execution. Hence, the algorithm implements a synchronous
execution of the actions. Algorithm 8 shows an implemen-
tation example of an asynchronous action. The function
Tick() runs in a separate thread of the BT execution. The
function initializes the status as Running, then it executes the
code of the action, which will eventually change the status to
Success or Failure. The action implements also the function
Status() that returns its internal status without executing
the node. Some BT implementations [39] of asynchronous
nodes include the return status Idle to indicate that the node
was never executed or that the parent node read the return
status Success or Failure.
With asynchronous actions, the BT implementation needs
to ensure that the thread executing the function Tick()
gets aborted correctly whenever the BT no longer sends
ticks to a running node. The implementation of composition
nodes must also be adapted accordingly, calling the function
Tick() of a child only when the latter is not running and
the function Halt() of a node that is no longer receiving
ticks.
Algorithm 8: Pseudocode of an Asynchronous BT
Action
Function Tick()
current-status Running
Action Implementation
Function Halt()
Safe Abort Routine
Function Status()
return current-status
A controversial aspect concerns the blocking nature of the
function Halt(), i.e. if the flow control must be passed to
the BT only after the function Halt() terminates. Given
the nature of the activities performed by Halt() existing
libraries implement it in a blocking fashion [36], [39].
Other solutions do not include the function Halt();
instead, they implement the action’s abortion procedures
as separate actions to keep the BT semantic as simple as
possible [9], [37], [40]. This, however, may negatively impact
the modularity and reusability of nodes within the BT.
Coroutines: The library BehaviorTree.CPP [39] intro-
duced CoroActionNodes to execute actions. Instead of ex-
ecuting the function Tick() in a separate thread ex-
plicitly, it uses coroutines, a control structure where the
flow control gets cooperatively passed between the two
different routines (i.e., the tick traversal and the action
node execution) until either the parent node no longer
ticks the action or the action terminates its execution. With
CoroActionNodes, the designer explicitly calls the function
setStatusRunningAndYield(), whenever the BT can
suspend the action execution and pass the flow control back
to the parent node. CoroActionNodes also implement the
function Halt() to safely abort the execution. The use
of coroutines for implementing BT actions results conve-
niently from a design and implementation point of view:
We can implement actions as a single block of code (as for
asynchronous actions) and explicitly define when the action
execution can be suspended (as for synchronous actions).
Unfortunately, it is a feature we found only in the library
BehaviorTree.CPP.
VI. AVAILABLE OPEN-SOURCE LIBRARIES
The literature presents a complete review of BTs li-
braries [33], in contrast, in this section, we discuss how the
most used libraries implement the features described above.
1
Table I synthesizes a comparison of the six most used
open-source libraries. Most of the the libraries support
memory nodes; in some cases, they consider memory nodes
as “standard” nodes [9], [39], and in other cases they
are the only ones supported. The blackboard represent the
common implementation of infra-nodes message passing.
The asynchronous action execution, which is fundamental
for BT implementation in robotics, appears to be surprisingly
missing in some of them. Moreover, a few of libraries allow
the creation of BTs using a GUI in a drag-and-drop fashion
and provide traces of execution for debugging purposes.
We now describe in detail the three most used libraries.
BehaviorTree.CPP (BT.cpp) [39]: It is a C++ library that
allows both the definition of classical composition nodes and
memory counterparts. A user can define an interface for the
leaf nodes in terms of input and output ports. With input
ports, a designer can define arguments, as strings that can
be parsed by the node, or keys to the blackboard’s entry.
An output port points to the blackboard’s entry, whose value
can be set inside the node. The library provides two ways of
implementing asynchronous action by either executing the
function Tick() in a separate thread or using coroutines
that uses only one thread. Users can also define the BT by
manually editing an eXtensible Markup Language (XML)
file or through a GUI, available on a separate repository.
py trees [37]: It is a Python library that, to date, does not
contain the sequence node but only its memory counterpart
but it contains the fallback node. The library does not
allow argument passing to the node, and it implements only
synchronous actions. The user must define the read/write
access permission to keys on a blackboard for each leaf
node. The library provides run-time BT visualization in the
following formats Unicode and Graphviz DOT.
CoSTAR [9]: It is an end-user interface for authoring
robot task plans that includes a BT-based user interface. It
is implemented as a C++ library. It allows the definition of
classical composition nodes with memory only. The user can
design the BT using a GUI. The library allows arguments to
leaf nodes and it contains a blackboard.
Name Rea Mem Args BB Asyn GUI
BT.cpp [39] 3 3 3 3 3 3
py trees [37] 7 3 7 3 7 7
CoSTAR [9] 7 3 3 3 7 3
BrainTree [40] 3 3 3 3 7 7
go-behave [36] 7 3 3 3 7 7
ActionFW [38] 3 3 7 7 3 7
TABLE I. Comparison in terms of Reactiveness, Memory nodes,
Arguments, BlackBoard, Asynchronous nodes, and GUI.
1
We searched for the most active and documented BT repositories that
are relevant for robotic applications.
VII. BEHAVIOR TREES IN A ROBOTIC SOFTWARE
ARCHITECTURE
In this section, we suggest where BTs fit inside a robotic
software architecture and we provide a use case example.
We also provide a simplified example, available online.
2
A. Abstraction Layers
The robotic software is often partitioned into different
layers of abstractions, each addressing different concerns;
the layers’ separation allows level-specific efficient solu-
tions [41]. The number and separation of the layers are the
subjects of controversial discussions; in this letter, we use the
abstraction layers defined by the RobMoSys Robotic Soft-
ware Component
3
, which we used in different projects.
4,5
Following the abstraction above, we categorize the robotic
software in:
Mission Layer: The layer where we design the higher-
level goal for the robot to achieve (e.g., serve a customer).
It may employ symbolic task planners, constraint solvers,
and analysis tools to define a goal. It can be implemented
as an algorithm [42], [43] or a human interface [8]–[10] that
synthesizes a BT.
Task Layer: The layer where we design how the robot
accomplishes a goal, disregarding the implementation details.
In our context, it describes the BT.
Skill Layer: The layer where we design the basic ca-
pabilities (skills) of a robot (e.g., grasp an object, go to
a given location in the map, etc.). A skill describes the
implementation of a leaf node of a BT. Each skill is
implemented by orchestrating a set of services from the
Service Layer, orchestration involves retrieving or setting
parameters, starting, and stopping services. A state machine
well describes these operations. Concerning the BT engine,
a skill can run in two ways:
- In the same executable, where the designer writes the
source code of the skill inside a leaf node in the BT engine.
- In a separate executable, where the source code of the
skill is written in a separate component that exposes the
interface for calling the functions Tick() and (possibly) the
Halt(). A leaf node of the BT engine forwards the calls
of the functions Tick() and Halt() to the correspond-
ing component, using inter-process communication facilities
made available by the Operating System or a middleware
(e.g., through shared memory or the network).
Service Layer: The layer that contains entities that serve
as the access point for the skills to command the robot. It
describes the server side of a service for basic capabilities
(e.g., getting the battery level, moving the base, etc.).
The other RobMoSys abstraction layers are: Function,
Operating System, and Hardware. They represent software
components that the robotic designer rarely develops, and
therefore they fall beyond the scope of this letter.
2
github.com/hsp-iit/behavior-stack-example
3
robmosys.eu/wiki/start
4
carve-robmosys.github.io
5
scope-robmosys.github.io
VIII. USE CASE EXAMPLE
In this section, we provide a use case example to show
how to build a full working robot behavior execution. An R1
robot has to fetch an empty bottle from a customer’s hand
and then bring it to a counter. The robot has to move the
arm in a pre-grasp position and then close the hand to fetch
the object. The BT in Figure 3(a) encodes such behavior. A
video of the execution is available online.
6
In the example, we manually designed the BT using
a GUI
7
(Mission Layer) and execute it via the Behav-
iorTree.CPP engine [39] (Task Layer). We run the skills in
a separate executable than the one of the BT (Skill Layer).
We use pre-existing navigation and manipulation servers to
interact with the robot’s hardware (Service Layer).
We implement the skills as external executables as either
YARP RFModule
8
[44] or State Charts (SCs) defined via the
SCXML formalism and executed via the QtSCXML engine
9
.
In either case, the skill exposes the interface to start or
abort the skill execution. Each state in a SC contains C++11
source code. The SC may contain two states representing a
succeeded and failed execution respectively.
10
We found it
convenient to use SCs for actions from a reusable perspec-
tive. Still, any other modeling framework for skills can fit
our purpose, provided that it can handle the requests from
the BT in terms of execution and abortion. The executable
of a SC skill has two threads: one that handles the requests
from the leaf node and executes the SC engine.
We implemented the action nodes a Coroutines (see Sec-
tion V), these actions forward the start and stop (for actions
only) via the YARP middleware, respectively, when they
receive the first tick and when they receive a halt. The details
of the corresponding skill’s executable are passed to the leaf
node as an argument. Whenever a leaf node receives a tick,
it sends the request to the corresponding external executable
to start the skill; when the leaf node receives a halt, it sends
the request to the corresponding external executable to stop
the skill. We implemented actions as CoroActionNodes (see
Section V). The leaf node has parameters to set the name
of the corresponding skill and communicate with each other
by using a blackboard (see Section IV). We chose to not
use nodes with memory, as any sequence of actions can be
modeled as a SC inside a single BT action (see Figure 3(b))
We describe the skills interfaces using the YARP Thrift
IDL [44] and implemented them as the following Remote
Procedure Calls (RPCs): start() that starts the execution
of the skill and returns a boolean that describes if the skill
was performed correctly or not; stop() that aborts the
execution of the skill and returns void.
6
The link will be available at the publication stage. Please watch the
attached video.
7
github.com/BehaviorTree/Groot
8
The RFModule in YARP is an abstraction for components, it implements
basic functions for handling the lifecycle of a modules, its parameters and
it be extended with functions that are specific to each component.
9
doc.qt.io/qt-5/qtscxml-overview.html
10
Actions may not have a termination condition. E.g. move forwards.
(a) BT. (b) Skill “Fetch” implemented as SC.
bool st art (){
bool h as _g ra sped = ma ni pu la tion_ cl ie nt . has _o bj ec t ( h and );
ret urn has _graspe d ;}
(c) Function start() of the skill “Object Grasped” implemented as
RFModule.
Fig. 3. BT and skills of the use case.
A. Skills Implementation Examples
We developed the following skills:
Object Grasped that sends requests to a robot interface
to check if the robot is holding an object. The Skill
has one argument, hand, that represents which hand to
check. Figure 3(c) shows a portion of its implementation
as YARP RFModule.
Close to Pose that sends requests to a localization server
to check if the robot is close to a given pose. The skill
has two arguments position and threshold.
Goto Pose whose function start() sends requests to
a navigation server (on the Service Layer) to compute
a path and follow it with the robot’s base. The function
returns False if the navigation server cannot find a
path to the destination. It returns True if the robot
reaches the pose. The function stop() aborts the
navigation when the BT switches execution from the
Goto action nodes to other nodes.
Fetch whose function start() starts a SC (see Fig-
ure 3(b)). The SC sends requests to a manipulation
server (on the Service Layer) to move the arm in a
pre-grasp position and then to close the hand. This
function returns False if the SC goes in the failure
state, it returns True if it goes in the success state. The
stop() triggers the transition stop in the SC, making
the arm move to a home position if nothing is grasped.
To summarize the example above uses: no memory nodes,
as the linear sequence of actions are encoded as SC; action
execution with Coroutines; external executables that forward
commands to the robot; infranode message passing imple-
mented as a blackboard; and nodes with parameters.
IX. CONCLUDING REMARKS
In this letter, we outlined the practical aspects of BTs
in robotics and outlined state-of-the-art solutions to date.
The analysis highlighted that a designer, to take advantage
of BTs fully, relies on a execution engine with specific
characteristics. Some of these characteristics are still debated,
and different existing libraries implement different solutions,
such as handling a safe preemption, the asynchronous action
execution, and the shared memory. We also showed BTs
fit in generic robotic software architectures and presented
a practical use case example. We believe that this letter
provides useful information for both the BT designers that
want to fully understand the characteristics and limitations of
a particular BT execution engine and the software developers
that want to implement their own BT execution engine.
REFERENCES
[1] D. Isla, “Handling Complexity in the Halo 2 AI,” in Game Developers
Conference, 2005.
[2] I. Millington and J. Funge, Artificial intelligence for games. CRC
Press, 2009.
[3] S. Rabin, Game AI Pro. CRC Press, 2014, ch. 6. The Behavior Tree
Starter Kit.
[4] M. Colledanchise and P.
¨
Ogren, Behavior Trees in Robotics and AI:
An Introduction, ser. Chapman and Hall/CRC Artificial Intelligence
and Robotics Series. Taylor & Francis Group, 2018.
[5] F. Rovida, B. Grossmann, and V. Kr
¨
uger, “Extended behavior trees
for quick definition of flexible robotic tasks, in 2017 IEEE/RSJ
International Conference on Intelligent Robots and Systems (IROS).
IEEE, 2017, pp. 6793–6800.
[6] K. R. Guerin, C. Lea, C. Paxton, and G. D. Hager, A framework for
end-user instruction of a robot assistant for manufacturing, in IEEE
International Conference on Robotics and Automation (ICRA), 2015.
[7] A. Kl
¨
ockner, “Behavior trees with stateful tasks, in Advances in
Aerospace Guidance, Navigation and Control. Springer, 2015, pp.
509–519.
[8] E. Coronado, F. Mastrogiovanni, and G. Venture, “Development of
intelligent behaviors for social robots via user-friendly and modular
programming tools, in 2018 IEEE Workshop on Advanced Robotics
and its Social Impacts (ARSO). IEEE, 2018, pp. 62–68.
[9] C. Paxton, A. Hundt, F. Jonathan, K. Guerin, and G. D. Hager, “Costar:
Instructing collaborative robots with behavior trees and vision, in
2017 IEEE International Conference on Robotics and Automation
(ICRA). IEEE, 2017, pp. 564–571.
[10] D. Shepherd, P. Francis, D. Weintrop, D. Franklin, B. Li, and A. Afzal,
“[engineering paper] an ide for easy programming of simple robotics
tasks,” in 2018 IEEE 18th International Working Conference on Source
Code Analysis and Manipulation (SCAM). IEEE, 2018, pp. 209–214.
[11] L. Pena, S. Ossowski, J. M. Pena, and S. M. Lucas, “Learning and
Evolving Combat Game Controllers, in Computational Intelligence
and Games (CIG), 2012 IEEE Conference on, pp. 195–202.
[12] E. Safronov, M. Colledanchise, and L. Natale, “Task Planning with
Belief Behavior Trees, in 2020 IEEE/RSJ International Conference
on Intelligent Robots and Systems (IROS), 2020.
[13] M. Iovino, J. Styrud, P. Falco, and C. Smith, “Learning behavior
trees with genetic programming in unpredictable environments, arXiv
preprint arXiv:2011.03252, 2020.
[14] D. Zhang and B. Hannaford, “Ikbt: solving symbolic inverse kine-
matics with behavior tree, Journal of Artificial Intelligence Research,
vol. 65, pp. 457–486, 2019.
[15] A. Csiszar, M. Hoppe, S. A. Khader, and A. Verl, “Behavior trees for
task-level programming of industrial robots, in Tagungsband des 2.
Kongresses Montage Handhabung Industrieroboter. Springer, 2017,
pp. 175–186.
[16] M. Tenorth, “Controlling process of robots having a behavior tree
architecture, Mar. 21 2019, uS Patent App. 16/081,763.
[17] X. Neufeld, S. Mostaghim, and S. Brand, A hybrid approach to
planning and execution in dynamic environments through hierarchical
task networks and behavior trees, in Fourteenth Artificial Intelligence
and Interactive Digital Entertainment Conference, 2018.
[18] M. Kim, M. Arduengo, N. Walker, Y. Jiang, J. W. Hart, P. Stone, and
L. Sentis, An architecture for person-following using active target
search, arXiv preprint, 2018.
[19] N. Axelsson and G. Skantze, “Modelling adaptive presentations in
human-robot interaction using behaviour trees, in Proceedings of the
20th Annual SIGdial Meeting on Discourse and Dialogue, 2019.
[20] A. Ghadirzadeh, X. Chen, W. Yin, Z. Yi, M. Bj
¨
orkman, and D. Kragic,
“Human-centered collaborative robots with deep reinforcement learn-
ing, arXiv preprint, 2020.
[21] C. I. Sprague and P.
¨
Ogren, Adding neural network controllers
to behavior trees without destroying performance guarantees, arXiv
preprint arXiv:1809.10283, 2018.
[22] B. Banerjee, Autonomous acquisition of behavior trees for robot
control, in 2018 IEEE/RSJ International Conference on Intelligent
Robots and Systems (IROS). IEEE, 2018, pp. 3460–3467.
[23] E. Scheide, G. Best, and G. A. Hollinger, “Learning behavior trees for
robotic task planning by monte carlo search over a formal grammar.
[24] O. Biggar and M. Zamani, A framework for formal verification
of behavior trees with linear temporal logic, IEEE Robotics and
Automation Letters, vol. 5, no. 2, pp. 2341–2348, 2020.
[25] T. G. Tadewos, L. Shamgah, and A. Karimoddini, “On-the-fly de-
centralized tasking of autonomous vehicles, in 2019 IEEE 58th
Conference on Decision and Control (CDC). IEEE, 2019, pp. 2770–
2775.
[26] J. Kuckling, A. Ligot, D. Bozhinoski, and M. Birattari, “Behavior
trees as a control architecture in the automatic modular design of
robot swarms, in International Conference on Swarm Intelligence.
Springer, 2018, pp. 30–43.
[27]
¨
O.
¨
Ozkahraman and P.
¨
Ogren, “Combining control barrier functions
and behavior trees for multi-agent underwater coverage missions,
arXiv preprint, 2020.
[28] P. de la Cruz, J. Piater, and M. Saveriano, “Reconfigurable behavior
trees: towards an executive framework meeting high-level decision
making and control layer features, arXiv preprint, 2020.
[29] P.
¨
Ogren, “Convergence analysis of hybrid control systems in the form
of backward chained behavior trees, IEEE Robotics and Automation
Letters, vol. 5, no. 4, pp. 6073–6080, 2020.
[30] “BostonDynamics Spot SDK, 2020. [Online]. Available:
bostondynamics.com/spot2
0
[31] S. Macenski, F. Mart
´
ın, R. White, and J. Gin
´
es Clavero, “The marathon
2: A navigation system, in 2020 IEEE/RSJ International Conference
on Intelligent Robots and Systems (IROS), 2020.
[32] M. Iovino, E. Scukins, J. Styrud, P.
¨
Ogren, and C. Smith, A survey
of behavior trees in robotics and ai, arXiv preprint, 2020.
[33] R. Ghzouli, T. Berger, E. B. Johnsen, S. Dragule, and A. Wasowski,
“Behavior trees in action: A study of robotics applications, arXiv
preprint arXiv:2010.06256, 2020.
[34] A. Shoulson, F. M. Garcia, M. Jones, R. Mead, and N. I. Badler,
“Parameterizing Behavior Trees, in Motion in Games. Springer,
2011.
[35] E. Safronov, M. Vilzmann, D. Tsetserukou, and K. Kondak, Asyn-
chronous behavior trees with memory aimed at aerial vehicles with
redundancy in flight controller, arXiv preprint, 2019.
[36] “gobehave repository. [Online]. Available: github.com/askft/
go-behave2
[37] “py trees. [Online]. Available: github.com/splintered-reality/py trees
[38] “action-fw repository. BitBucket. [Online]. Available: bitbucket.
org/brainific/action-fw
[39] D. Faconti and M. Colledanchise, “BehaviorTree.CPP.” [Online].
Available: github.com/BehaviorTree/BehaviorTree.CPP
[40] “braintree repository. [Online]. Available: github.com/arvidsson/
BrainTree
[41] A. Ahmad and M. A. Babar, “Software architectures for robotic sys-
tems: A systematic mapping study, Journal of Systems and Software,
vol. 122, pp. 16–39, 2016.
[42] M. Colledanchise, D. Almeida, and P.
¨
Ogren, “Towards blended reac-
tive planning and acting using behavior trees, in 2019 International
Conference on Robotics and Automation (ICRA). IEEE, 2019, pp.
8839–8845.
[43] T. G. Tadewos, L. Shamgah, and A. Karimoddini, Automatic safe
behaviour tree synthesis for autonomous agents, in 2019 IEEE 58th
Conference on Decision and Control (CDC). IEEE, 2019, pp. 2776–
2781.
[44] F. Paul, C. Elena, D. Daniele, P. Ali, M. Giorgio, and N. Lorenzo, A
middle way for robotics middleware, 2014.