-
Notifications
You must be signed in to change notification settings - Fork 5
The Controller
Our behavior tree implementation is a hybrid between event-driven and polled. There are 3 main states: Software Stop, Tele-Operation, and Autonomous Operation. Software Stop is a fallback state if any of the other states induce a panic, or if requested by the operator. The robot is unable to do anything in this state. Tele-Operation allows for complete control by an operator, and Autonomous Operation pilots the robot on its own. Any user input during that time cancels it.
In the Software Stop and Tele-Operation states, the behavior tree is able to wait for user input without consuming CPU cycles, whilst in the Autonomy state the tree polls itself several times a second to update its behavior depending on the position of the robot, on top of other metrics.
Fundamentally, a behavior tree is composed of logic nodes and leaf nodes. Most if not all the decision making should be performed by logic nodes, which are pre-defined, and actions should be executed by the leaf nodes. For example, there is currently a leaf node called follow_path
which autonomously drives the robot along a path. However, that leaf node does not decide when it should follow a path. That is handled by the parent nodes. A leaf node returns a Status
, which can be Success
, Failure
, or Running
. Logic nodes can consume this status to make a decision (such as an IfElse
node) or transform it (eg. Invert
).
The benefit of this approach is that it converts logic into types that can be analyzed using Rust's Turing complete type system. As such, behavior trees can implement different traits automatically depending on its composition. As an added safety to prove that our behavior tree will never terminate, we require that it implements EternalBehavior
. If someone modifies the tree and it doesn't compile, we'll know that it was that change that introduces a branch that could lead to an unintended exit.