Behaviour Tree for memory constrained devices. icpmoles.tngl.io/orchard

Files
README.md

Orchard #

Documentation Homepage

PDF Documentation

Repository

Behavior trees for microcontrollers and embedded systems, in plain C.

A behavior tree describes what a device should do as a tree of small decisions: check this, then do that, otherwise fall back to something else. Orchard runs these trees on anything from a Cortex-M0+ under Zephyr to a Linux or QNX system. You write the leaves in C (a condition that reads a button, an action that drives an LED) and describe how they fit together in a tree file. Change the file and reload it, and the device behaves differently, without rebuilding the firmware.

{
  "root": {
    "type": "reactive_fallback",
    "children": [
      { "type": "reactive_sequence", "children": [
        { "type": "condition", "name": "button", "arg": 0 },
        { "type": "action", "name": "led_on", "arg": 1 }
      ]},
      { "type": "action", "name": "led_off", "arg": 1 }
    ]
  }
}

Properties #

  • No heap. Nodes live in a pool that the application allocates, 28 bytes each on 32-bit targets (32 with the 64-bit clock). RAM use is the pool, one 40-byte tree structure and, only while loading, the file buffer.
  • Small, portable core. C99, depending only on the freestanding headers and <string.h>. The OS is reached through two functions, a monotonic clock and a file read, and both are optional. From C++, orchard.hpp checks trees at compile time.
  • Errors at load time, not at run time. Unknown node types, unknown leaf names and malformed trees are rejected with a line, a column and a message. Leaf names are resolved to function pointers once, so a tick never compares strings.
  • JSON or C. Load trees from a file at run time, or build fixed ones in C with the same checks, and leave the JSON parser out of the image.
  • Bounded stack. Parsing recursion is capped at 24 levels of nesting, ticking recursion is the depth of the tree.
  • Observable. Every node keeps the status of its last tick. Print it as text or, on Zephyr, read it live from a host over MCUmgr (SMP).
  • Platforms. Zephyr, as a module using the native kernel and file system APIs, and POSIX.1-2008, tested on Linux and on QNX SDP 8.0.

Getting started #

Background #

Orchard's sequence, fallback and their reactive variants follow the definitions in the book.

License #

MIT, see LICENSE.

Credits #

Favicon from Mona Font (OFL)