Behavior Trees (BTs) are a powerful way to describe the behavior of autonomous agents with applications in robotics and AI.
This implementation is based on Behavior Trees in Robotics and AI: An Introduction. It was developped by Team L3 to qualify in NASA'Space Robotics Challenge Phase 2 (More details on usage in this paper: Human-Robot Teaming Strategy for Fast Teleoperation of a Lunar Resource Exploration Rover).
Visualization tools depends on graphviz
.
On Ubuntu/Debian:
sudo apt-get install graphviz
With Julia ≥ 1.4 (may work on previous 1.x version but not tested) add package
julia> ]
(v1.4) pkg> add BehaviorTree
Two Primitives are available to build behavior trees: Sequence
and Selector
. They accept a list of tasks, that can be a Sequence, a Selector, or, in the case of a leaf, a function returning one of :success
, :failure
or :running
.
doSuccess(bb=Dict()) = :success
isTrue(bb=Dict()) = :success
doFailure(bb=Dict())= :failure
doRunning(bb=Dict()) = :running
bt = Selector([
doFailure,
Sequence([isTrue, doFailure, doSuccess], "choice"),
doRunning,
doSuccess!
], "head")
Execution of the tree happen via the tick
function, that accepts a shared blackboard
object use to share state between tasks.
blackboard = Dict{Symbol, Any}()
status, results = tick(bt, blackboard)
Ticking usually happens in a loop at at a frequency determined by the needs of the application.
As BehaviorTrees use the AbstractTree interface, it is possible to use D3Trees for visualization:
d3tree = D3Tree(bt)
inbrowser(tree, "firefox")
Utilities to generate graphviz output via the .dot
format are also provided.
dot_graph=toDot(bt)
filename= "example.dot"
open(filename, "w") do dot_file
write(dot_file, dot_graph)
end
filename= "example.png"
png_graph = dot2png(dot_graph)
open(filename, "w") do png_file
write(png_file, png_graph)
end
passing the execution results in the toDot function generates a visualization of the current state:
dot_graph=toDot(bt, results)
filename= "status.png"
png_graph = dot2png(dot_graph)
open(filename, "w") do png_file
write(png_file, png_graph)
end