ZERO Notificatons

NO Feedback yet!!

okay

xparo
X.P.A.R.O



project - Behaviour Tree Visualizer



Finite state machines were the standard way to structure robot behaviour for decades, and ROS 1 robots often ran on SMACH. Today Nav2 is built on behaviour trees, and many teams assume trees have replaced state machines. They haven't: each is better at a different kind of problem. This comparison uses one example robot to show where each shines, and where each one hurts.

The same robot, two ways

Our robot fetches a cup from the kitchen and brings it to the table. It has to stop and charge when its battery runs low.

As a state machine, the robot is always in exactly one state, and events move it between states: GoToKitchen, then FindCup, PickCup and GoToTable, with a transition for each "done" event. That is four transitions, and easy to read. Now add the battery. "Battery low" can happen in any of the four working states, so each needs its own transition to Charge: four more. After charging, the robot should carry on where it stopped, so Charge needs a way back to each of the four states, plus a variable that remembers which one: four more again. Twelve transitions, where the task itself needs four. A second interruption that can happen anywhere, such as a person blocking the way, adds eight more.

As a behaviour tree, the battery check is one ReactiveSequence and a Fallback wrapped around the whole task, as built in our introduction. It is the same four extra nodes whether the task has four steps or forty, and the task itself doesn't change.

To be fair to state machines, the twelve transitions are a problem of flat machines. A hierarchical state machine puts the four working states inside a Working superstate, with one transition from Working to Charge, and a "history" feature lets it return to the sub-state it left. Good state machine libraries support both. The difference that remains is how each one gets back on track.

Remembering versus re-checking

A state machine resumes by remembering: it knows it was in PickCup, so it goes back there. A behaviour tree usually starts again from the top and re-checks the world. For that to work, each step checks whether its job is already done before doing it:

<root BTCPP_format="4">
  <BehaviorTree ID="FetchCup">
    <Sequence>
      <Fallback>
        <IsHoldingCup/>
        <Sequence>
          <GoTo name="go_to_kitchen" target="kitchen"/>
          <PickCup/>
        </Sequence>
      </Fallback>
      <GoTo name="go_to_table" target="table"/>
    </Sequence>
  </BehaviorTree>
</root>

We ran this with BehaviorTree.CPP 4.10. When IsHoldingCup failed, the robot went to the kitchen, picked the cup and went to the table. When it succeeded, as it would after a recharge in the middle of the delivery, the tree skipped straight to the table.

Re-checking is more robust: if someone took the cup from the robot while it was charging, the tree notices and fetches another, while a state machine resuming at GoToTable would deliver nothing. It also costs more design effort. Every step needs a condition that can be checked, and some things, such as "have I already announced my arrival?", are hard to observe from sensors.

Side by side

State machineBehaviour tree
Basic ideaOne active state; events trigger transitionsA tree ticked repeatedly; nodes answer SUCCESS, FAILURE or RUNNING
InterruptionsA transition from every state, or a superstateOne reactive node above the task
ReuseStates are tied to their transitions, so moving one means rewiringSubtrees report only success or failure, so they drop into other trees
ResumingRemembers the last stateRe-checks conditions from the top
Debugging"Where am I?" is one state nameThe active path through the tree; needs a viewer such as Groot
Event-driven protocolsNatural: states and messages map one to oneAwkward: events must be turned into conditions that can be polled
Learning curveFamiliar to most engineersReactive nodes, halting and the blackboard take time to learn

When a state machine is the better choice

  • Modes. A robot that is Idle, Manual, Autonomous or Emergency stop is in exactly one mode at a time, and the transitions between modes are a safety question you want to see written down.
  • Protocols. A docking handshake, a charger negotiation or a device driver waiting for specific replies is a sequence of states driven by messages, which is what state machines describe best.
  • Small, stable behaviour. With five states that rarely change, a state machine is shorter and easier for a newcomer to follow.

When a behaviour tree is the better choice

  • Tasks with many ways to fail. Retries, fallbacks and recoveries are where trees shine: Nav2's tree tries a costmap clear, then a spin, a wait and a backup, as our Nav2 walkthrough traces step by step.
  • Reusable skills. "Pick object" or "dock" written once as a subtree can be used in many missions, by different people.
  • Behaviour that changes often. Trees are loaded from XML, so a new mission can be a new file instead of new code.

Using both

Many robots combine them, and that is often the best answer. A small state machine handles the robot's modes, and in Autonomous mode it runs a behaviour tree for the task. Going the other way, the individual actions inside a tree are often small state machines themselves: a BehaviorTree.CPP StatefulActionNode has onStart, onRunning and onHalted callbacks, which are exactly the states of one action.

Libraries for ROS 2

All of these have binary packages for ROS 2 Jazzy:

  • Behaviour trees: BehaviorTree.CPP (C++; version 4.10 in Jazzy), used by Nav2 and edited with Groot; py_trees and py_trees_ros (Python).
  • State machines: SMACH (Python, ported from ROS 1); YASMIN (Python and C++); FlexBE (Python, with a graphical editor and operator control at run time).

Whichever you choose, draw it. A state diagram or a tree diagram that the whole team can read catches more mistakes than any code review. For trees, paste your XML into the Behaviour Tree Visualizer to see it drawn and checked. For the theory, Colledanchise and Ögren's book Behavior Trees in Robotics and AI: An Introduction compares trees with state machines and other architectures in depth.

More guides

Oct. 4, 2026, 9:10 a.m.
Inside Nav2's Behaviour Tree: How navigate_to_pose Works
Read more..
Oct. 4, 2026, 9:11 a.m.
Behaviour Tree Design Patterns: Retry, Recovery, Timeouts and Reactive Sequences
Read more..
Oct. 4, 2026, 9:13 a.m.
The BehaviorTree.CPP XML Format Explained: Nodes, Ports and the Blackboard
Read more..
Oct. 4, 2026, 9:14 a.m.
Behaviour Trees for Robots: A Practical Introduction
Read more..

If you have any query or problem
feel free to contact us
email: [email protected]