Behavior Trees
"Not the hero you deverse,
but (probably) the one you need"
What to expect
An unbiased, hype-free, review of how Behavior Trees differ from State Machines
and how they can help you to design more modular Software Systems.
Which problem are we trying to solve?
- We always start implementing individual robot "skills" and designing the workflow/behavior is an "afterthought".
- Not many guidelines, design patterns related to "Task Planning".
- In terms of Hierarchical State Machines, we have SMACH and FlexBe.
- How do we create reusable, modular and composable software architectures?
"Separation of Concerns" and "Composability" are two core principles
you need to understand to build good robotic systems
Which problem are we trying to solve?
We want to build a high level "Task Planner", AKA "Coordinator / Orchestrator" that executes complex behaviors in a Service Oriented system.
What are "Behavior Trees"?
-
An alternative to Hierarchical State Machines.
-
A Domain Specific Language to describe Behaviors.
- A "grammar" to implement Explicit Task Planners.
- .... not a silver bullet, but an incremental improvement.
HSM
BT
- More intuitive and faster to learn
- Order specified by the transitions
- Might be harder to scale
- Hard to model concurrency
- They invite you to think about failure and fallback strategies
- Order specified by the semantic of the parent node
- More human-readable (with practice)
- Richer and more expressive grammar, easy to extend
What do you mean by
"Domain Specific Language"?
- Specifically designed to describe a particular class of problems more easily.
- We may extend the language as needed.
- The analogy with "functions" is very powerful to understand composability.
bool FetchBeer()
{
if( GoTo("kitchen") &&
OpenFridge() &&
Grasp("beer") &&
CloseFridge() )
{
return true;
}
else{
return false;
}
}
Actions, Control Nodes and Decorators
- We have a "tick" signal that propagates from the root of the tree to its leaves.
- All the nodes: may return SUCCESS, FAILURE or (in some cases) RUNNING.
- Action Nodes are leaves of the tree and they actually "do something". From a practical point of view, they just invoke a user defined callback.
- Control Nodes have 1-to-N children, the order is important. If and when a child is executed is based on the result of the other children.
- Decorator Nodes have 1 child and may modify its returned value and decide if and when the child is called.
Key concepts to keep in mind
- A Parent node can only see its direct child / children.
- There is no difference is a child is a leaf or a sub-branch.
- A node doesn't have any knowledge about its parent.
This makes the composable and intrinsically hierarchical
You need to thing about all the branches :/
There are no beers in the fridge and I don't want to keep the door of the fridge open
About BehaviorTree.CPP
Much more than a C++ implementation
- Focused on concurrent and reactive behaviors, i.e. non-blocking actions may be interrupted under certain circumstances.
- As flexible as a scripting language, since the actual tree is expressed in an XML format that is parsed at run-time.
- As probably one of the most convincing approaches to Dataflow in the field of BTs (borrowed by SMACH)
- Model Driven Development in disguise... but better!
- "Batteries included": logging infrastructure, visual editor, online and offline debugger.
- Middleware agnostic (as it should be)
Groot, an IDE for Behavior Trees
An opinionated implementation
"The endless search for the Saint Grial of Composability"
- Nodes are programmed in C++, trees in XML. This provides flexibility but also strong decoupling between coordination and business logic.
- Dataflow uses Ports instead of Blackboards
- You may define Subtrees and reuse them. Their ports are scoped and you need to "export" them to make them visible.
What we (still) need: good idioms
The NAND gate analogy
The only building block of State Machines are the transitions.
Behavior Trees have more abstractions, but you probably want to have even more (or different one) to make your tree more readable and less verbose.
Summarizing
About Behavior Trees in general
- Both HSM and BT allow the user to create explicit Task Planning nodes
- Their real value is in the decoupling and separation of concerns
- If you are confused about their role, think that they are a Domain Specific Language
- BT have a more powerful and have an extensible grammar.
About BehaviorTree.CPP
- Reactive and Concurrent behaviors are first class citizens.
- Tooling and good documentation makes the life of the user easier.
- Efficient as C++, flexible as a scripting language.
- The concept of "scoped ports" allows full composability.
Explicit Planning is the present, but I hope it is not the future
I hope Symbolic Planning will have it "Deep Neural Networks" moment, but don't keep your breath
Behavior Trees 2021
By Davide Faconti
Behavior Trees 2021
- 697