Part II — Behaviour-based robotics · Chapter 8

Behavior trees

~28 min read3 interactive widgets4 plates

In this chapter

  1. What a behavior tree is
  2. Anatomy: root, control nodes, execution nodes
  3. Execution: the tick and the three return values
  4. Control nodes: sequence and fallback
  5. A BT for the subsumption architecture
  6. The variant with explicit conditions
  7. BTs in Lua, and in this course
  8. Check your understanding

Bibliographic support

1. What a behavior tree is

Three statements open the deck, and the third is the ambitious one:

Key idea — why this chapter closes Part II

Chapter 6 gave two complaints about finite state automata: they are not easy to extend (the whole automaton must be redefined) and they are not modular. Behavior trees are the answer to both, while keeping the property that made FSAs attractive — a clean separation between the model you specify and the general code that executes it. And because BTs subsume the subsumption architecture too (section 5), a single formalism covers both of the arbitration mechanisms you have studied.

The introductory example in the slides is a high-level BT carrying out a task consisting of first finding, then picking and finally placing a ball — a sequence of three sub-tasks, which is exactly what the sequence control node expresses.

2. Anatomy: root, control nodes, execution nodes

Definition

A BT is a tree structure that contains one root node, control nodes, and execution nodes (actions or conditions).

The structural rules:

Execution nodes are the leaves and come in two kinds — actions and conditions — whose semantics are given in section 3. The book that supports these slides (Colledanchise & Ögren, 2018) organises the control nodes into four categories — Sequence, Fallback, Parallel and Decorator — and the execution nodes into the two categories just named; the course slides, following Kuckling et al. (2018), present six different types of control nodes. The two you must be able to execute by hand, and the two the lectures develop, are the Fallback and the Sequence.

ANATOMY OF A BEHAVIOR TREE ROOT the only node without a parent; it generates the tick → SEQUENCE a CONTROL node: at least one child, distributes the tick and combines returns find ball pick ball place ball EXECUTION nodes (leaves): ACTIONS here, CONDITIONS elsewhere tick Read left to right: the ball must be found before it can be picked, and picked before it can be placed. A sequence encodes exactly that dependency, and nothing else.
Plate 8.1 — The find-pick-place example from the slides. The tree is the specification; the tick engine that walks it is general code, reusable across every BT you will ever write.

3. Execution: the tick and the three return values

Execution is controlled by a tick generated by the root and propagated through the tree. When ticked by its parent, a node is activated. After execution, it returns one of three possible values:

success   |   failure   |   running
Node kindReturns successReturns failureReturns running
Conditionif its condition is fulfilledotherwise
Actionif its action is completedif its action cannot be completedif its action is still in progress
Controldistributes the tick to its children; its return value depends on those returned by the children

Condition nodes that are ticked observe the world state. Note that they do not act: this is the formal separation between "checking" and "doing" that the FSA of Chapter 6 blurred into its transition table.

For the exam — the reactivity mechanism

The slides spell out how a BT stays reactive: "In the basic implementation, the execution process traverses down from the root of the tree every single step, testing each node down the tree to see which is active, rechecking any nodes along the way, until it reaches the currently active node to tick it again."

Every tick re-evaluates all the conditions on the path. That is why a running pick ball action is abandoned the instant a higher-priority condition becomes true — no explicit interrupt, no transition to write. Compare the FSA, where you would have had to add an edge from every state to the emergency state by hand.

4. Control nodes: sequence and fallback

Terminology — memorise this equivalence

Selector node ≡ Fallback node. The slides state it twice, because the literature uses both names for the same thing. The course figures label it ?; the sequence node is labelled .

Sequence  Fallback / Selector  ?
Ticks childrenleft to rightleft to right
Stops and returns failureas soon as a child returns failureonly if all children return failure
Stops and returns successonly if all children return successas soon as a child returns success
Returns runningif a child returns runningif a child returns running
Reads as"do this and then this and then this""try this, or else this, or else this"
Encodesa dependency between sub-tasksa priority ordering between alternatives
THE TWO CONTROL NODES YOU MUST BE ABLE TO EXECUTE BY HAND → SEQUENCE A B C success FAILURE never ticked the SEQUENCE returns FAILURE one broken link breaks the chain "A and then B and then C" ? FALLBACK A B C failure SUCCESS never ticked the FALLBACK returns SUCCESS the first one that works, wins "A or else B or else C"
Plate 8.2 — Sequence and fallback are duals: swap the roles of success and failure and one becomes the other. Left to right ordering means dependency in a sequence, and priority in a fallback.

Widget — Tick the tree

The "pick a ball" tree from the lectures. Set the world state, then tick. Watch the traversal start again from the root every single step and recheck the nodes along the way.

World:

5. A BT for the subsumption architecture

This is the section that makes good on the claim "BTs subsume the subsumption architecture". The recipe, verbatim:

The construction

Given a subsumption architecture, we can create an equivalent BT by arranging the controllers as actions under a Fallback composition, from highest to lowest priority, from left to right.

Furthermore, we let the return status of the actions be Failure if they do not need to execute, and Running if they do. They never return Success.

Each behavior contains both its activation conditions and the execution code.

Take a moment on the middle clause, because it is the clever part. A fallback ticks its children left to right and stops at the first one that does not fail. If a behaviour returns failure exactly when it has nothing to say, then the fallback automatically slides down the priority list until it finds a behaviour that wants to act — and that behaviour returns running, which stops the traversal and gives it the actuators. "Never return success" guarantees the tree never terminates: a robot controller is not a task that completes.

The worked example maps the three-level stack of Chapter 6 onto three children:

Subsumption levelPosition under the fallback
Level 2 — Obstacle avoidanceleftmost (highest priority)
Level 1 — Phototaxismiddle
Level 0 — Random walkrightmost (lowest priority)
SUBSUMPTION STACK → EQUIVALENT BEHAVIOR TREE the stack of Chapter 6 L2 obstacle avoidance L1 phototaxis L0 random walk priority equivalent ? obstacle avoidance phototaxis random walk highest priority LEFT  →  lowest priority RIGHT RETURN STATUS CONVENTION that makes the fallback behave like a subsumption stack: FAILURE → the behaviour does not need to execute, so the fallback moves to the next child RUNNING → the behaviour needs to execute, so the fallback stops here and this behaviour has control SUCCESS → never returned; a robot controller does not terminate
Plate 8.3 — The equivalence. The suppression and inhibition nodes of Plate 6.2 have been replaced by a single fallback and a return-value convention — and the crucial property (at most one level drives the actuators) is now enforced by the tree semantics rather than by wiring.

Widget — The two architectures, same world

Set the world and compare which behaviour takes control in the subsumption stack and in the equivalent BT. They agree, always — that is what "subsumes" means.

World:

6. The variant with explicit conditions

The deck then presents a variant of the same design:

Structurally, each behaviour becomes a sequence of (condition, behaviour), and those sequences become the children of the fallback:

THE VARIANT — CONDITIONS PULLED OUT OF THE BEHAVIOURS ? random walk obstacle avoid. COND obstacle avoidance phototaxis CONDITION phototaxis PROS: favours modularity and reuse — previously coded behaviours can be composed unchanged CONS: code might be redundant, and care must be taken about coherence between condition and behaviour
Plate 8.4 — The variant. In the version of section 5 each behaviour contained both its activation conditions and its execution code; here the condition is lifted into the tree, so the behaviour becomes reusable — at the price of possible redundancy and of a coherence obligation the formalism cannot check for you.
ProsCons
Favours modularity and reuseCode might be redundant, and care must be taken about coherence between condition and behaviour
Careful

The coherence problem is real and subtle. If the obstacle-avoidance condition triggers at 20 cm but the obstacle-avoidance behaviour was written assuming it is invoked at 10 cm, the tree is perfectly well formed and the robot misbehaves. In the section 5 design this could not happen, because the behaviour owned its own activation condition. Modularity has a price, and the exam likes you to be able to name it.

Widget — Two designs, side by side

Choose which design you are reasoning about, then read what changes when you want to reuse phototaxis in a second robot with different sensors.

7. BTs in Lua, and in this course

The deck points to a practical implementation: "A nice implementation of BTs in Lua (suitable to be used with ARGoS) is provided by Michael Allwright"github.com/allsey87/luabt.

-- the subsumption-equivalent tree of section 5, as a BT specification
-- FAILURE = "I do not need to execute"; RUNNING = "I am taking control"

local tree = {
  type = "fallback",                  -- the "?" node: try each child in priority order
  children = {
    { type = "action", fn = obstacle_avoidance },   -- highest priority, leftmost
    { type = "action", fn = phototaxis },
    { type = "action", fn = random_walk }           -- lowest priority, rightmost
  }
}

function obstacle_avoidance()
  local d = nearest_obstacle()
  if d > THRESHOLD then return "failure" end        -- nothing to do: let the next child try
  drive_away_from(d)
  return "running"                                  -- taking control; never returns success
end

Behavior trees reappear twice more in the course, and it is worth flagging both now:

For the exam

A very likely question is: compare FSMs, the subsumption architecture and behavior trees as coordination mechanisms. The skeleton of a good answer: all three are arbitration (competitive) mechanisms. FSMs allow formal analysis and separate model from execution, but are not modular and not easy to extend. The subsumption architecture gives incremental design and graceful degradation, but its priority hierarchy is fixed and expressed in wiring. BTs are modular and reactive, they re-evaluate conditions at every tick, and they subsume both of the previous models — a fallback with children ordered by priority reproduces subsumption exactly, given the failure/running convention.

Check your understanding

What is a behavior tree, and what does it subsume?

A BT is a way to structure the switching between different tasks. BTs are a very efficient way of creating control software for a robot that is modular and reactive, and they subsume several previous models, such as FSMs and the subsumption architecture.

Give the structural definition of a BT.

A tree structure containing one root node, control nodes, and execution nodes (actions or conditions). The root is the node without parents; all other nodes have exactly one parent; control nodes have at least one child. Standard parent/child terminology is used for connected nodes.

What are the three return values, and what does each node kind mean by them?

Success, failure, running. A condition node observes the world state and returns success if its condition is fulfilled, failure otherwise. An action node returns success if its action is completed, failure if it cannot be completed, and running if it is still in progress. A control node distributes the tick to its children and its return value depends on those returned by the children.

How does the tick work, and why does that make BTs reactive?

The tick is generated by the root and propagated through the tree; a node ticked by its parent is activated. In the basic implementation, the execution process traverses down from the root every single step, testing each node to see which is active and rechecking any nodes along the way, until it reaches the currently active node and ticks it again. Because every condition on the path is re-evaluated at every tick, a running action is abandoned as soon as a higher-priority condition becomes true — no explicit interrupt is needed.

Contrast the sequence and the fallback node.

Both tick their children left to right. A sequence () returns failure as soon as a child fails and success only if all children succeed — it encodes a dependency: "do A and then B and then C". A fallback (?), also called a selector, returns success as soon as a child succeeds and failure only if all children fail — it encodes a priority ordering: "try A, or else B, or else C". Both return running if a child returns running.

How do you build a BT equivalent to a given subsumption architecture?

Arrange the controllers as actions under a Fallback composition, from highest to lowest priority, from left to right. Let the return status of the actions be Failure if they do not need to execute and Running if they do; they never return Success. Each behavior contains both its activation conditions and the execution code.

Why must the actions never return success in that construction?

Because a fallback returns success as soon as one child succeeds, which would terminate the composition. A robot controller is not a task that completes: it must keep running. Returning only failure ("I have nothing to do, try the next child") or running ("I am taking control") makes the fallback slide down the priority list every tick and stop at the highest-priority behaviour that wants to act.

Write the BT for phototaxis with obstacle avoidance given in the lectures.

A single fallback node with three action children, left to right: Obstacle avoidance (level 2, highest priority), Phototaxis (level 1), Random walk (level 0, lowest priority).

Describe the variant with explicit conditions, and give its pros and cons.

Behavior nodes are run only if the condition is satisfied: each behaviour becomes a sequence of (condition, behaviour), and these sequences are the children of the fallback. This lets us compose previously coded behaviors by adding suitable execution conditions. Pros: favours modularity and reuse. Cons: code might be redundant, and care must be taken about coherence between condition and behaviour.

Compare FSMs, subsumption and BTs as arbitration mechanisms.

All three are competitive (arbitration) schemes. FSMs: powerful for composing simple behaviours, allow formal analysis, and separate model from execution — but are not modular and not easy to extend, since the whole automaton must be redefined. Subsumption: incremental design, graceful degradation (partition at any level and the layers below still work), at most one level drives the actuators — but the priority hierarchy is fixed and encoded in suppression/inhibition wiring. BTs: modular and reactive, conditions rechecked at every tick, and they subsume both of the other models.

Where else do behavior trees appear in this course?

In automatic design (Chapter 11): the Kuckling, Ligot, Bozhinoski and Birattari paper cited in this deck is about behavior trees as a control architecture in the automatic modular design of robot swarms, where the tree is produced by an optimisation algorithm. And in experimental evaluation (Chapter 15), where two of the compared controllers are the same subsumption controller implemented with two different BTs, and the Wilcoxon test returns p = 0.661 — no evidence that they differ.